From: <ale...@us...> - 2013-03-27 11:45:05
|
Revision: 57841 http://sourceforge.net/p/firebird/code/57841 Author: alexpeshkoff Date: 2013-03-27 11:45:02 +0000 (Wed, 27 Mar 2013) Log Message: ----------- Added operator include to config files Modified Paths: -------------- firebird/trunk/lang_helpers/gds_codes.ftn firebird/trunk/lang_helpers/gds_codes.pas firebird/trunk/src/common/config/ConfigCache.cpp firebird/trunk/src/common/config/ConfigCache.h firebird/trunk/src/common/config/config.cpp firebird/trunk/src/common/config/config.h firebird/trunk/src/common/config/config_file.cpp firebird/trunk/src/common/config/config_file.h firebird/trunk/src/common/db_alias.cpp firebird/trunk/src/common/os/path_utils.h firebird/trunk/src/common/os/posix/path_utils.cpp firebird/trunk/src/include/gen/codetext.h firebird/trunk/src/include/gen/iberror.h firebird/trunk/src/include/gen/msgs.h firebird/trunk/src/include/gen/sql_code.h firebird/trunk/src/include/gen/sql_state.h firebird/trunk/src/msgs/facilities2.sql firebird/trunk/src/msgs/messages2.sql firebird/trunk/src/msgs/system_errors2.sql firebird/trunk/src/remote/server/os/posix/inet_server.cpp firebird/trunk/src/remote/server/os/win32/srvr_w32.cpp firebird/trunk/src/utilities/ntrace/TraceConfiguration.cpp Modified: firebird/trunk/lang_helpers/gds_codes.ftn =================================================================== --- firebird/trunk/lang_helpers/gds_codes.ftn 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/lang_helpers/gds_codes.ftn 2013-03-27 11:45:02 UTC (rev 57841) @@ -1516,6 +1516,16 @@ PARAMETER (GDS__no_output_format = 335545051) INTEGER*4 GDS__item_finish PARAMETER (GDS__item_finish = 335545052) + INTEGER*4 GDS__miss_config + PARAMETER (GDS__miss_config = 335545053) + INTEGER*4 GDS__conf_line + PARAMETER (GDS__conf_line = 335545054) + INTEGER*4 GDS__conf_include + PARAMETER (GDS__conf_include = 335545055) + INTEGER*4 GDS__include_depth + PARAMETER (GDS__include_depth = 335545056) + INTEGER*4 GDS__include_miss + PARAMETER (GDS__include_miss = 335545057) INTEGER*4 GDS__gfix_db_name PARAMETER (GDS__gfix_db_name = 335740929) INTEGER*4 GDS__gfix_invalid_sw Modified: firebird/trunk/lang_helpers/gds_codes.pas =================================================================== --- firebird/trunk/lang_helpers/gds_codes.pas 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/lang_helpers/gds_codes.pas 2013-03-27 11:45:02 UTC (rev 57841) @@ -765,6 +765,11 @@ gds_wrong_message_length = 335545050; gds_no_output_format = 335545051; gds_item_finish = 335545052; + gds_miss_config = 335545053; + gds_conf_line = 335545054; + gds_conf_include = 335545055; + gds_include_depth = 335545056; + gds_include_miss = 335545057; gds_gfix_db_name = 335740929; gds_gfix_invalid_sw = 335740930; gds_gfix_incmp_sw = 335740932; Modified: firebird/trunk/src/common/config/ConfigCache.cpp =================================================================== --- firebird/trunk/src/common/config/ConfigCache.cpp 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/config/ConfigCache.cpp 2013-03-27 11:45:02 UTC (rev 57841) @@ -28,6 +28,8 @@ #include "../common/config/ConfigCache.h" #include "../common/config/config_file.h" +#include "gen/iberror.h" + #include <sys/types.h> #include <sys/stat.h> @@ -37,39 +39,50 @@ #include <errno.h> #endif -ConfigCache::ConfigCache(Firebird::MemoryPool& p, const Firebird::PathName& fName) - : PermanentStorage(p), fileName(getPool(), fName), fileTime(0) -{ -} +using namespace Firebird; +ConfigCache::ConfigCache(MemoryPool& p, const PathName& fName) + : PermanentStorage(p), files(FB_NEW(getPool()) ConfigCache::File(getPool(), fName)) +{ } + ConfigCache::~ConfigCache() { + delete files; } void ConfigCache::checkLoadConfig() { - time_t newTime = getTime(); - if (fileTime == newTime) - { - return; + { // scope + ReadLockGuard guard(rwLock, "ConfigCache::checkLoadConfig"); + if (files->checkLoadConfig(false)) + { + return; + } } - Firebird::WriteLockGuard guard(rwLock, "ConfigCache::checkLoadConfig"); - + WriteLockGuard guard(rwLock, "ConfigCache::checkLoadConfig"); // may be someone already reloaded? - newTime = getTime(); - if (fileTime == newTime) + if (files->checkLoadConfig(true)) { return; } - fileTime = newTime; - + files->trim(); loadConfig(); } -time_t ConfigCache::getTime() +void ConfigCache::addFile(const Firebird::PathName& fName) { + files->add(fName); +} + +Firebird::PathName ConfigCache::getFileName() +{ + return files->fileName; +} + +time_t ConfigCache::File::getTime() +{ struct stat st; if (stat(fileName.c_str(), &st) != 0) { @@ -78,7 +91,58 @@ // config file is missing, but this is not our problem return 0; } - Firebird::system_call_failed::raise("stat"); + system_call_failed::raise("stat"); } return st.st_mtime; } + +ConfigCache::File::File(MemoryPool& p, const PathName& fName) + : PermanentStorage(p), fileName(getPool(), fName), fileTime(0), next(NULL) +{ } + +ConfigCache::File::~File() +{ + delete next; +} + +bool ConfigCache::File::checkLoadConfig(bool set) +{ + time_t newTime = getTime(); + if (fileTime == newTime) + { + return next ? next->checkLoadConfig(set) : true; + } + + if (set) + { + fileTime = newTime; + if (next) + { + next->checkLoadConfig(set); + } + } + return false; +} + +void ConfigCache::File::add(const PathName& fName) +{ + if (fName == fileName) + { + return; + } + + if (next) + { + next->add(fName); + } + else + { + next = FB_NEW(getPool()) ConfigCache::File(getPool(), fName); + } +} + +void ConfigCache::File::trim() +{ + delete next; + next = NULL; +} Modified: firebird/trunk/src/common/config/ConfigCache.h =================================================================== --- firebird/trunk/src/common/config/ConfigCache.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/config/ConfigCache.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -39,19 +39,35 @@ virtual ~ConfigCache(); void checkLoadConfig(); + void addFile(const Firebird::PathName& fName); + Firebird::PathName getFileName(); protected: virtual void loadConfig() = 0; private: - time_t getTime(); + class File : public Firebird::PermanentStorage + { + public: + File(Firebird::MemoryPool& p, const Firebird::PathName& fName); + ~File(); + bool checkLoadConfig(bool set); + void add(const Firebird::PathName& fName); + void trim(); + + public: + Firebird::PathName fileName; + + private: + volatile time_t fileTime; + File* next; + time_t getTime(); + }; + File* files; + public: Firebird::RWLock rwLock; - Firebird::PathName fileName; - -private: - volatile time_t fileTime; }; #endif // COMMON_CONFIG_CASHE_H Modified: firebird/trunk/src/common/config/config.cpp =================================================================== --- firebird/trunk/src/common/config/config.cpp 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/config/config.cpp 2013-03-27 11:45:02 UTC (rev 57841) @@ -45,15 +45,25 @@ { public: explicit ConfigImpl(Firebird::MemoryPool& p) - : Firebird::PermanentStorage(p), confMessage(getPool()) + : Firebird::PermanentStorage(p), missConf(false) { - ConfigFile file(fb_utils::getPrefix(fb_utils::FB_DIR_CONF, CONFIG_FILE)); - defaultConfig = new Config(file); - - if (file.getMessage()) + try { - confMessage = file.getMessage(); + ConfigFile file(fb_utils::getPrefix(fb_utils::FB_DIR_CONF, CONFIG_FILE)); + defaultConfig = new Config(file); } + catch (const Firebird::status_exception& ex) + { + if (ex.value()[1] != isc_miss_config) + { + throw; + } + + missConf = true; + + ConfigFile file(ConfigFile::USE_TEXT, ""); + defaultConfig = new Config(file); + } } /* void changeDefaultConfig(Config* newConfig) @@ -66,9 +76,9 @@ return defaultConfig; } - const char* getMessage() + bool missFirebirdConf() { - return confMessage.nullStr(); + return missConf; } private: @@ -77,7 +87,7 @@ ConfigImpl(const ConfigImpl&); void operator=(const ConfigImpl&); - Firebird::string confMessage; + bool missConf; }; /****************************************************************************** @@ -196,7 +206,7 @@ if (entries[i].data_type == TYPE_STRING && values[i]) { ConfigFile::String expand((const char*)values[i]); - if (file.macroParse(expand) && expand != (const char*) values[i]) + if (file.macroParse(expand, NULL) && expand != (const char*) values[i]) { ConfigFile::String& saved(tempStrings.add()); saved = expand; @@ -313,9 +323,9 @@ return firebirdConf().getDefaultConfig(); } -const char* Config::getMessage() +bool Config::missFirebirdConf() { - return firebirdConf().getMessage(); + return firebirdConf().missFirebirdConf(); } const char* Config::getInstallDirectory() Modified: firebird/trunk/src/common/config/config.h =================================================================== --- firebird/trunk/src/common/config/config.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/config/config.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -185,9 +185,9 @@ Config(const ConfigFile& file, const Config& base); // use to build db-specific config ~Config(); - // Check for errors in .conf file + // Check for missing firebird.conf - static const char* getMessage(); + static bool missFirebirdConf(); // Interface to support command line root specification. // This ugly solution was required to make it possible to specify root Modified: firebird/trunk/src/common/config/config_file.cpp =================================================================== --- firebird/trunk/src/common/config/config_file.cpp 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/config/config_file.cpp 2013-03-27 11:45:02 UTC (rev 57841) @@ -26,7 +26,9 @@ #include "../common/classes/auto.h" #include "../common/config/config_file.h" #include "../common/config/config.h" +#include "../common/config/ConfigCache.h" #include "../common/os/path_utils.h" +#include "../common/ScanDir.h" #include <stdio.h> #ifdef HAVE_STDLIB_H @@ -37,16 +39,36 @@ namespace { +bool hasWildCards(const PathName& s) +{ + return s.find_first_of("?*") != PathName::npos; +} + +void strip2slashes(ConfigFile::String& to) +{ + // strip double slashes + char sep2[3]; + sep2[0] = PathUtils::dir_sep; + sep2[1] = sep2[0]; + sep2[2] = 0; + + size_t pos = 0; + while((pos = to.find(sep2, pos)) != PathName::npos) + { + to.erase(pos, 1); + } +} + class MainStream : public ConfigFile::Stream { public: - MainStream(const char* fname, PathName& errString) - : file(fopen(fname, "rt")), l(0) + MainStream(const char* fname) + : file(fopen(fname, "rt")), fileName(fname), l(0) { if (!file) { // config file does not exist - errString.printf("Missing configuration file: %s", fname); + (Arg::Gds(isc_miss_config) << fname << Arg::OsError()).raise(); } } @@ -65,7 +87,10 @@ { return false; } - input.LoadFromFile(file); + if (!input.LoadFromFile(file)) + { + return false; + } ++l; input.alltrim(" \t\r"); } while (input.isEmpty() || input[0] == '#'); @@ -74,8 +99,19 @@ return true; } + bool active() + { + return file.hasData(); + } + + const char* getFileName() const + { + return fileName.c_str(); + } + private: AutoPtr<FILE, FileClose> file; + Firebird::PathName fileName; unsigned int l; }; @@ -125,6 +161,11 @@ return true; } + const char* getFileName() const + { + return NULL; + } + private: const char* s; unsigned int l; @@ -133,8 +174,8 @@ class SubStream : public ConfigFile::Stream { public: - SubStream() - : cnt(0) + SubStream(const char* fName) + : fileName(fName), cnt(0) { } bool getLine(ConfigFile::String& input, unsigned int& line) @@ -157,65 +198,71 @@ data.push(Line(input, line)); } + const char* getFileName() const + { + return fileName; + } + private: typedef Pair<Left<ConfigFile::String, unsigned int> > Line; ObjectsArray<Line> data; + const char* fileName; size_t cnt; }; } // anonymous namespace -ConfigFile::ConfigFile(const Firebird::PathName& file, USHORT fl) +ConfigFile::ConfigFile(const Firebird::PathName& file, USHORT fl, ConfigCache* cache) : AutoStorage(), - configFile(getPool(), file), parameters(getPool()), flags(fl), - lastMessage(getPool()) + includeLimit(0), + filesCache(cache) { - MainStream s(configFile.c_str(), lastMessage); + MainStream s(file.c_str()); parse(&s); } -ConfigFile::ConfigFile(const char* file, USHORT fl) +ConfigFile::ConfigFile(const char* file, USHORT fl, ConfigCache* cache) : AutoStorage(), - configFile(getPool(), String(file)), parameters(getPool()), flags(fl), - lastMessage(getPool()) + includeLimit(0), + filesCache(cache) { - MainStream s(configFile.c_str(), lastMessage); + MainStream s(file); parse(&s); } ConfigFile::ConfigFile(UseText, const char* configText, USHORT fl) : AutoStorage(), - configFile(getPool()), parameters(getPool()), flags(fl), - lastMessage(getPool()) + includeLimit(0), + filesCache(NULL) { TextStream s(configText); parse(&s); } -ConfigFile::ConfigFile(MemoryPool& p, const Firebird::PathName& file, USHORT fl) +ConfigFile::ConfigFile(MemoryPool& p, const Firebird::PathName& file, USHORT fl, ConfigCache* cache) : AutoStorage(p), - configFile(getPool(), file), parameters(getPool()), flags(fl), - lastMessage(getPool()) + includeLimit(0), + filesCache(cache) { - MainStream s(configFile.c_str(), lastMessage); + MainStream s(file.c_str()); parse(&s); } -ConfigFile::ConfigFile(MemoryPool& p, ConfigFile::Stream* s, USHORT fl, const Firebird::PathName& file) +ConfigFile::ConfigFile(MemoryPool& p, ConfigFile::Stream* s, USHORT fl) : AutoStorage(p), - configFile(getPool(), file), parameters(getPool()), flags(fl), - lastMessage(getPool()) + includeLimit(0), + filesCache(NULL) { parse(s); } @@ -229,12 +276,14 @@ * Parse line, taking quotes into account */ -ConfigFile::LineType ConfigFile::parseLine(const String& input, KeyType& key, String& value) +ConfigFile::LineType ConfigFile::parseLine(const char* fileName, const String& input, KeyType& key, String& value) { int inString = 0; String::size_type valStart = 0; String::size_type eol = String::npos; bool hasSub = false; + const char* include = "include"; + const unsigned incLen = strlen(include); for (String::size_type n = 0; n < input.length(); ++n) { @@ -271,6 +320,22 @@ case ' ': case '\t': + if (n == incLen && key.isEmpty()) + { + KeyType inc = input.substr(0, n).ToNoCaseString(); + if (inc == include) + { + value = input.substr(n); + value.alltrim(" \t\r"); + + if (!macroParse(value, fileName)) + { + return LINE_BAD; + } + return LINE_INCLUDE; + } + } + // fall down ... case '\r': break; @@ -317,7 +382,7 @@ } // Now expand macros in value - if (!macroParse(value)) + if (!macroParse(value, fileName)) { return LINE_BAD; } @@ -330,7 +395,7 @@ * Substitute macro values in a string */ -bool ConfigFile::macroParse(String& value) const +bool ConfigFile::macroParse(String& value, const char* fileName) const { String::size_type subFrom; @@ -341,7 +406,7 @@ { String macro; String m = value.substr(subFrom + 2, subTo - (subFrom + 2)); - if (! translate(m, macro)) + if (! translate(fileName, m, macro)) { return false; } @@ -353,6 +418,7 @@ } } + strip2slashes(value); return true; } @@ -361,7 +427,7 @@ * Find macro value */ -bool ConfigFile::translate(const String& from, String& to) const +bool ConfigFile::translate(const char* fileName, const String& from, String& to) const { if (from == "root") { @@ -373,28 +439,28 @@ } else if (from == "this") { - if (configFile.isEmpty()) + if (!fileName) { return false; } - PathName tempPath = configFile; + PathName tempPath(fileName); #ifdef UNIX if (PathUtils::isSymLink(tempPath)) { // If $(this) is a symlink, expand it. TEXT temp[MAXPATHLEN]; - const int n = readlink(configFile.c_str(), temp, sizeof(temp)); + const int n = readlink(fileName, temp, sizeof(temp)); - if (n != -1 && n < sizeof(temp)) + if (n != -1 && unsigned(n) < sizeof(temp)) { tempPath = temp; if (PathUtils::isRelative(tempPath)) { PathName parent; - PathUtils::splitLastComponent(parent, tempPath, configFile); + PathUtils::splitLastComponent(parent, tempPath, fileName); PathUtils::concatPath(tempPath, parent, temp); } } @@ -460,10 +526,9 @@ * Take into an account fault line */ -void ConfigFile::badLine(const String& line) +void ConfigFile::badLine(const char* fileName, const String& line) { - lastMessage.printf("%s: illegal line <%s>", - (configFile.hasData() ? configFile.c_str() : "Passed text"), line.c_str()); + (Arg::Gds(isc_conf_line) << (fileName ? fileName : "Passed text") << line).raise(); } /****************************************************************************** @@ -476,28 +541,33 @@ String inputLine; Parameter* previous = NULL; unsigned int line; + const char* streamName = stream->getFileName(); while (stream->getLine(inputLine, line)) { Parameter current; current.line = line; - switch (parseLine(inputLine, current.name, current.value)) + switch (parseLine(streamName, inputLine, current.name, current.value)) { case LINE_BAD: - badLine(inputLine); + badLine(streamName, inputLine); return; case LINE_REGULAR: if (current.name.isEmpty()) { - badLine(inputLine); + badLine(streamName, inputLine); return; } previous = ¶meters[parameters.add(current)]; break; + case LINE_INCLUDE: + include(streamName, current.value.ToPathName()); + break; + case LINE_START_SUB: if (current.name.hasData()) { @@ -506,7 +576,7 @@ } { // subconf scope - SubStream subStream; + SubStream subStream(stream->getFileName()); while (stream->getLine(inputLine, line)) { if (inputLine[0] == '}') @@ -515,7 +585,7 @@ s.ltrim(" \t\r"); if (s.hasData() && s[0] != '#') { - badLine(s); + badLine(streamName, s); return; } break; @@ -523,20 +593,128 @@ subStream.putLine(inputLine, line); } - previous->sub = FB_NEW(getPool()) ConfigFile(getPool(), &subStream, - flags & ~HAS_SUB_CONF, configFile); + previous->sub = FB_NEW(getPool()) + ConfigFile(getPool(), &subStream, flags & ~HAS_SUB_CONF); } break; } } } +//#define DEBUG_INCLUDES + /****************************************************************************** * - * Check for parse/load error + * Parse include operator */ -const char* ConfigFile::getMessage() const +void ConfigFile::include(const char* currentFileName, const PathName& parPath) { - return lastMessage.nullStr(); + // We should better limit include depth + AutoSetRestore<unsigned> depth(&includeLimit, includeLimit + 1); + if (includeLimit > INCLUDE_LIMIT) + { + (Arg::Gds(isc_conf_include) << currentFileName << parPath << Arg::Gds(isc_include_depth)).raise(); + } + + // for relative paths first of all prepend with current path (i.e. path of current conf file) + PathName path; + if (PathUtils::isRelative(parPath)) + { + PathName curPath; + PathUtils::splitLastComponent(curPath, path /*dummy*/, currentFileName); + PathUtils::concatPath(path, curPath, parPath); + } + else + { + path = parPath; + } + + // split path into components + PathName pathPrefix; + PathUtils::splitPrefix(path, pathPrefix); + PathName savedPath(path); // Expect no *? in prefix + FilesArray components; + while (path.hasData()) + { + PathName cur, tmp; + PathUtils::splitLastComponent(tmp, cur, path); + +#ifdef DEBUG_INCLUDES + fprintf(stderr, "include: path=%s cur=%s tmp=%s\n", path.c_str(), cur.c_str(), tmp.c_str()); +#endif + + components.push(cur); + path = tmp; + } + + // analyze components for wildcards + if (!wildCards(currentFileName, pathPrefix, components)) + { + // no matches found - check for presence of wild symbols in path + if (!hasWildCards(savedPath)) + { + (Arg::Gds(isc_conf_include) << currentFileName << parPath << Arg::Gds(isc_include_miss)).raise(); + } + } } + +/****************************************************************************** + * + * Parse wildcards + * - calls parse for found files + * - fills filesCache + * - returns true if some match was found + */ + +bool ConfigFile::wildCards(const char* currentFileName, const PathName& pathPrefix, FilesArray& components) +{ + // Any change in directory can cause config change + PathName prefix(pathPrefix); + if(!pathPrefix.hasData()) + prefix = "."; + + bool found = false; + PathName next(components.pop()); + +#ifdef DEBUG_INCLUDES + fprintf(stderr, "wildCards: prefix=%s next=%s left=%d\n", + prefix.c_str(), next.c_str(), components.getCount()); +#endif + + ScanDir list(prefix.c_str(), next.c_str()); + while (list.next()) + { + PathName name; + const PathName fileName = list.getFileName(); + if (fileName == ".") + continue; + if (fileName[0] == '.' && next[0] != '.') + continue; + PathUtils::concatPath(name, pathPrefix, fileName); + +#ifdef DEBUG_INCLUDES + fprintf(stderr, "in Scan: name=%s pathPrefix=%s list.fileName=%s\n", + name.c_str(), pathPrefix.c_str(), fileName.c_str()); +#endif + + if (filesCache) + filesCache->addFile(name); + + if (components.hasData()) // should be directory + { + found = found || wildCards(currentFileName, name, components); + } + else + { + MainStream include(name.c_str()); + if (include.active()) + { + found = true; + parse(&include); + } + } + } + + return found; +} Modified: firebird/trunk/src/common/config/config_file.h =================================================================== --- firebird/trunk/src/common/config/config_file.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/config/config_file.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -46,6 +46,8 @@ (common/config/config.cpp) and server-side alias manager (common/db_alias.cpp). **/ +class ConfigCache; + class ConfigFile : public Firebird::AutoStorage, public Firebird::RefCounted { public: @@ -65,6 +67,7 @@ public: virtual ~Stream(); virtual bool getLine(String&, unsigned int&) = 0; + virtual const char* getFileName() const = 0; }; struct Parameter : public AutoStorage @@ -90,15 +93,16 @@ typedef Firebird::SortedObjectsArray<Parameter, Firebird::InlineStorage<Parameter*, 100>, KeyType, Parameter> Parameters; + typedef Firebird::ObjectsArray<Firebird::PathName> FilesArray; - ConfigFile(const Firebird::PathName& file, USHORT fl = 0); - ConfigFile(const char* file, USHORT fl = 0); + ConfigFile(const Firebird::PathName& file, USHORT fl = 0, ConfigCache* cache = NULL); + ConfigFile(const char* file, USHORT fl = 0, ConfigCache* cache = NULL); ConfigFile(UseText, const char* configText, USHORT fl = 0); - ConfigFile(MemoryPool& p, const Firebird::PathName& file, USHORT fl = 0); + ConfigFile(MemoryPool& p, const Firebird::PathName& file, USHORT fl = 0, ConfigCache* cache = NULL); private: - ConfigFile(MemoryPool& p, ConfigFile::Stream* s, USHORT fl, const Firebird::PathName& file); + ConfigFile(MemoryPool& p, ConfigFile::Stream* s, USHORT fl); public: // key and value management @@ -111,26 +115,25 @@ return parameters; } - // was there some error parsing config file? - const char* getMessage() const; - // Substitute macro values in a string - bool macroParse(String& value) const; + bool macroParse(String& value, const char* fileName) const; private: - enum LineType {LINE_BAD, LINE_REGULAR, LINE_START_SUB}; + enum LineType {LINE_BAD, LINE_REGULAR, LINE_START_SUB, LINE_INCLUDE}; - Firebird::PathName configFile; Parameters parameters; USHORT flags; - USHORT badLinesCount; - Firebird::PathName lastMessage; + unsigned includeLimit; + ConfigCache* filesCache; + static const unsigned INCLUDE_LIMIT = 64; // utilities void parse(Stream* stream); - LineType parseLine(const String& input, KeyType& key, String& value); - bool translate(const String& from, String& to) const; - void badLine(const String& line); + LineType parseLine(const char* fileName, const String& input, KeyType& key, String& value); + bool translate(const char* fileName, const String& from, String& to) const; + void badLine(const char* fileName, const String& line); + void include(const char* currentFileName, const Firebird::PathName& path); + bool wildCards(const char* currentFileName, const Firebird::PathName& pathPrefix, FilesArray& components); }; #endif // CONFIG_CONFIG_FILE_H Modified: firebird/trunk/src/common/db_alias.cpp =================================================================== --- firebird/trunk/src/common/db_alias.cpp 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/db_alias.cpp 2013-03-27 11:45:02 UTC (rev 57841) @@ -198,7 +198,7 @@ } databases.clear(); - ConfigFile aliasConfig(fileName, ConfigFile::HAS_SUB_CONF); + ConfigFile aliasConfig(getFileName(), ConfigFile::HAS_SUB_CONF, this); const ConfigFile::Parameters& params = aliasConfig.getParameters(); for (n = 0; n < params.getCount(); ++n) Modified: firebird/trunk/src/common/os/path_utils.h =================================================================== --- firebird/trunk/src/common/os/path_utils.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/os/path_utils.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -147,6 +147,13 @@ static void splitLastComponent(Firebird::PathName&, Firebird::PathName&, const Firebird::PathName&); + /** splitPrefix takes a path as the first argument, splits OS-dependent prefix + from it (something like C:\, D: or \ in windows or / in posix), + and returns stripped path inplace, i.e. as first argument. + Prefix is returned as the second argument. + **/ + static void splitPrefix(Firebird::PathName& path, Firebird::PathName& prefix); + /** This is the factory method for allocating dir_iterator objects. It takes a reference to a memory pool to use for all heap allocations, and the path of the directory to iterate (in that order). It is the Modified: firebird/trunk/src/common/os/posix/path_utils.cpp =================================================================== --- firebird/trunk/src/common/os/posix/path_utils.cpp 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/common/os/posix/path_utils.cpp 2013-03-27 11:45:02 UTC (rev 57841) @@ -118,6 +118,16 @@ file.append(orgPath, pos + 1, orgPath.length() - pos - 1); } +void PathUtils::splitPrefix(Firebird::PathName& path, Firebird::PathName& prefix) +{ + prefix.erase(); + while (path[0] == dir_sep) + { + prefix = dir_sep; + path.erase(0, 1); + } +} + void PathUtils::concatPath(Firebird::PathName& result, const Firebird::PathName& first, const Firebird::PathName& second) Modified: firebird/trunk/src/include/gen/codetext.h =================================================================== --- firebird/trunk/src/include/gen/codetext.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/include/gen/codetext.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -754,6 +754,11 @@ {"wrong_message_length", 335545050}, {"no_output_format", 335545051}, {"item_finish", 335545052}, + {"miss_config", 335545053}, + {"conf_line", 335545054}, + {"conf_include", 335545055}, + {"include_depth", 335545056}, + {"include_miss", 335545057}, {"gfix_db_name", 335740929}, {"gfix_invalid_sw", 335740930}, {"gfix_incmp_sw", 335740932}, Modified: firebird/trunk/src/include/gen/iberror.h =================================================================== --- firebird/trunk/src/include/gen/iberror.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/include/gen/iberror.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -788,6 +788,11 @@ const ISC_STATUS isc_wrong_message_length = 335545050L; const ISC_STATUS isc_no_output_format = 335545051L; const ISC_STATUS isc_item_finish = 335545052L; +const ISC_STATUS isc_miss_config = 335545053L; +const ISC_STATUS isc_conf_line = 335545054L; +const ISC_STATUS isc_conf_include = 335545055L; +const ISC_STATUS isc_include_depth = 335545056L; +const ISC_STATUS isc_include_miss = 335545057L; const ISC_STATUS isc_gfix_db_name = 335740929L; const ISC_STATUS isc_gfix_invalid_sw = 335740930L; const ISC_STATUS isc_gfix_incmp_sw = 335740932L; @@ -1232,7 +1237,7 @@ const ISC_STATUS isc_trace_switch_param_miss = 337182758L; const ISC_STATUS isc_trace_param_act_notcompat = 337182759L; const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L; -const ISC_STATUS isc_err_max = 1176; +const ISC_STATUS isc_err_max = 1181; #else /* c definitions */ @@ -1990,6 +1995,11 @@ #define isc_wrong_message_length 335545050L #define isc_no_output_format 335545051L #define isc_item_finish 335545052L +#define isc_miss_config 335545053L +#define isc_conf_line 335545054L +#define isc_conf_include 335545055L +#define isc_include_depth 335545056L +#define isc_include_miss 335545057L #define isc_gfix_db_name 335740929L #define isc_gfix_invalid_sw 335740930L #define isc_gfix_incmp_sw 335740932L @@ -2434,7 +2444,7 @@ #define isc_trace_switch_param_miss 337182758L #define isc_trace_param_act_notcompat 337182759L #define isc_trace_mandatory_switch_miss 337182760L -#define isc_err_max 1176 +#define isc_err_max 1181 #endif Modified: firebird/trunk/src/include/gen/msgs.h =================================================================== --- firebird/trunk/src/include/gen/msgs.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/include/gen/msgs.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -757,6 +757,11 @@ {335545050, "Message length passed from user application does not match set of columns"}, /* wrong_message_length */ {335545051, "Resultset is missing output format information"}, /* no_output_format */ {335545052, "Message metadata not ready - item @1 is not finished"}, /* item_finish */ + {335545053, "Missing configuration file: @1"}, /* miss_config */ + {335545054, "@1: illegal line <@2>"}, /* conf_line */ + {335545055, "Invalid include operator in @1 for <@2>"}, /* conf_include */ + {335545056, "Include depth too big"}, /* include_depth */ + {335545057, "File to include not found"}, /* include_miss */ {335740929, "data base file name (@1) already given"}, /* gfix_db_name */ {335740930, "invalid switch @1"}, /* gfix_invalid_sw */ {335740932, "incompatible switch combination"}, /* gfix_incmp_sw */ Modified: firebird/trunk/src/include/gen/sql_code.h =================================================================== --- firebird/trunk/src/include/gen/sql_code.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/include/gen/sql_code.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -753,6 +753,11 @@ {335545050, -804}, /* 730 wrong_message_length */ {335545051, -804}, /* 731 no_output_format */ {335545052, -804}, /* 732 item_finish */ + {335545053, -902}, /* 733 miss_config */ + {335545054, -902}, /* 734 conf_line */ + {335545055, -902}, /* 735 conf_include */ + {335545056, -902}, /* 736 include_depth */ + {335545057, -902}, /* 737 include_miss */ {335740929, -901}, /* 1 gfix_db_name */ {335740930, -901}, /* 2 gfix_invalid_sw */ {335740932, -901}, /* 4 gfix_incmp_sw */ Modified: firebird/trunk/src/include/gen/sql_state.h =================================================================== --- firebird/trunk/src/include/gen/sql_state.h 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/include/gen/sql_state.h 2013-03-27 11:45:02 UTC (rev 57841) @@ -753,6 +753,11 @@ {335545050, "07000"}, // 730 wrong_message_length {335545051, "07000"}, // 731 no_output_format {335545052, "HY021"}, // 732 item_finish + {335545053, "XX000"}, // 733 miss_config + {335545054, "XX000"}, // 734 conf_line + {335545055, "XX000"}, // 735 conf_include + {335545056, "XX000"}, // 736 include_depth + {335545057, "XX000"}, // 737 include_miss {335740929, "00000"}, // 1 gfix_db_name {335740930, "00000"}, // 2 gfix_invalid_sw {335740932, "00000"}, // 4 gfix_incmp_sw Modified: firebird/trunk/src/msgs/facilities2.sql =================================================================== --- firebird/trunk/src/msgs/facilities2.sql 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/msgs/facilities2.sql 2013-03-27 11:45:02 UTC (rev 57841) @@ -1,7 +1,7 @@ /* MAX_NUMBER is the next number to be used, always one more than the highest message number. */ set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?); -- -('2013-02-21 18:12:38', 'JRD', 0, 733) +('2013-03-26 17:52:41', 'JRD', 0, 738) ('2012-01-23 20:10:30', 'QLI', 1, 532) ('2009-07-16 05:26:11', 'GFIX', 3, 121) ('1996-11-07 13:39:40', 'GPRE', 4, 1) Modified: firebird/trunk/src/msgs/messages2.sql =================================================================== --- firebird/trunk/src/msgs/messages2.sql 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/msgs/messages2.sql 2013-03-27 11:45:02 UTC (rev 57841) @@ -840,6 +840,11 @@ ('wrong_message_length', NULL, 'why.cpp', NULL, 0, 730, NULL, 'Message length passed from user application does not match set of columns', NULL, NULL); ('no_output_format', NULL, 'why.cpp', NULL, 0, 731, NULL, 'Resultset is missing output format information', NULL, NULL); ('item_finish', NULL, 'MsgMetadata.cpp', NULL, 0, 732, NULL, 'Message metadata not ready - item @1 is not finished', NULL, NULL); +('miss_config', NULL, 'config_file.cpp', NULL, 0, 733, NULL, 'Missing configuration file: @1', NULL, NULL); +('conf_line', NULL, 'config_file.cpp', NULL, 0, 734, NULL, '@1: illegal line <@2>', NULL, NULL); +('conf_include', NULL, 'config_file.cpp', NULL, 0, 735, NULL, 'Invalid include operator in @1 for <@2>', NULL, NULL); +('include_depth', NULL, 'config_file.cpp', NULL, 0, 736, NULL, 'Include depth too big', NULL, NULL); +('include_miss', NULL, 'config_file.cpp', NULL, 0, 737, NULL, 'File to include not found', NULL, NULL); -- QLI (NULL, NULL, NULL, NULL, 1, 0, NULL, 'expected type', NULL, NULL); (NULL, NULL, NULL, NULL, 1, 1, NULL, 'bad block type', NULL, NULL); Modified: firebird/trunk/src/msgs/system_errors2.sql =================================================================== --- firebird/trunk/src/msgs/system_errors2.sql 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/msgs/system_errors2.sql 2013-03-27 11:45:02 UTC (rev 57841) @@ -739,6 +739,11 @@ (-804, '07', '000', 0, 730, 'wrong_message_length', NULL, NULL) (-804, '07', '000', 0, 731, 'no_output_format', NULL, NULL) (-804, 'HY', '021', 0, 732, 'item_finish', NULL, NULL) +(-902, 'XX', '000', 0, 733, 'miss_config', NULL, NULL) +(-902, 'XX', '000', 0, 734, 'conf_line', NULL, NULL) +(-902, 'XX', '000', 0, 735, 'conf_include', NULL, NULL) +(-902, 'XX', '000', 0, 736, 'include_depth', NULL, NULL) +(-902, 'XX', '000', 0, 737, 'include_miss', NULL, NULL) -- GFIX (-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL) (-901, '00', '000', 3, 2, 'gfix_invalid_sw', NULL, NULL) Modified: firebird/trunk/src/remote/server/os/posix/inet_server.cpp =================================================================== --- firebird/trunk/src/remote/server/os/posix/inet_server.cpp 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/remote/server/os/posix/inet_server.cpp 2013-03-27 11:45:02 UTC (rev 57841) @@ -39,6 +39,7 @@ #include "../jrd/ibase.h" #include "../common/classes/init.h" #include "../common/config/config.h" +#include "../common/os/fbsyslog.h" #include <sys/param.h> #ifdef HAVE_SYS_TYPES_H @@ -156,6 +157,8 @@ * Run the server with apollo mailboxes. * **************************************/ + try + { RemPortPtr port; // 01 Sept 2003, Nickolay Samofatov @@ -339,6 +342,13 @@ divorce_terminal(mask); } + // check firebird.conf presence - must be for server + if (Config::missFirebirdConf()) + { + Firebird::Syslog::Record(Firebird::Syslog::Error, "Missing master config file firebird.conf"); + exit(STARTUP_ERROR); + } + if (super || standaloneClassic) { try @@ -424,6 +434,21 @@ fb_shutdown(10000, fb_shutrsn_exit_called); return FINI_OK; + } + catch(const Firebird::Exception& ex) + { + ISC_STATUS_ARRAY status; + ex.stuff_exception(status); + + char s[100]; + const ISC_STATUS* st = status; + fb_interpret(s, sizeof(s), &st); + + Firebird::Syslog::Record(Firebird::Syslog::Error, "Firebird startup error"); + Firebird::Syslog::Record(Firebird::Syslog::Error, s); + + exit(STARTUP_ERROR); + } } } // extern "C" Modified: firebird/trunk/src/remote/server/os/win32/srvr_w32.cpp =================================================================== --- firebird/trunk/src/remote/server/os/win32/srvr_w32.cpp 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/remote/server/os/win32/srvr_w32.cpp 2013-03-27 11:45:02 UTC (rev 57841) @@ -206,10 +206,10 @@ return STARTUP_ERROR; // see /common/common.h } - // Check for errors/missing firebird.conf - const char* anyError = Config::getMessage(); - if (anyError) + // Check for missing firebird.conf + if (Config::missFirebirdConf()) { + const char* anyError = "Missing master config file firebird.conf"; Syslog::Record(Syslog::Error, anyError); MessageBox(NULL, anyError, "Firebird server failure", MB_OK | MB_ICONHAND | MB_SYSTEMMODAL | MB_DEFAULT_DESKTOP_ONLY); Modified: firebird/trunk/src/utilities/ntrace/TraceConfiguration.cpp =================================================================== --- firebird/trunk/src/utilities/ntrace/TraceConfiguration.cpp 2013-03-27 01:34:44 UTC (rev 57840) +++ firebird/trunk/src/utilities/ntrace/TraceConfiguration.cpp 2013-03-27 11:45:02 UTC (rev 57841) @@ -92,10 +92,6 @@ void TraceCfgReader::readConfig() { ConfigFile cfgFile(ConfigFile::USE_TEXT, m_text, ConfigFile::HAS_SUB_CONF); - if (cfgFile.getMessage()) - { - fatal_exception::raiseFmt(ERROR_PREFIX"%s", cfgFile.getMessage()); - } m_subpatterns[0].start = 0; m_subpatterns[0].end = m_databaseName.length(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |