return typeSpec.SubStr(index + 1);
}
-static void IncludeDirRecursive(const String& path)
+static void IncludeZoneDirRecursive(const String& path)
{
- Utility::GlobRecursive(path, "*.conf", &ConfigCompiler::CompileFile, GlobFile);
+ String zoneName = Utility::BaseName(path);
+ Utility::GlobRecursive(path, "*.conf", boost::bind(&ConfigCompiler::CompileFile, _1, zoneName), GlobFile);
}
static void IncludeNonLocalZone(const String& zonePath)
{
String etcPath = Application::GetZonesDir() + "/" + Utility::BaseName(zonePath);
-#ifndef _WIN32
- struct stat statbuf;
- if (lstat(etcPath.CStr(), &statbuf) >= 0)
-#else /* _WIN32 */
- struct _stat statbuf;
- if (_stat(etcPath.CStr(), &statbuf) >= 0)
-#endif /* _WIN32 */
+ if (Utility::PathExists(etcPath))
return;
- IncludeDirRecursive(zonePath);
+ IncludeZoneDirRecursive(zonePath);
}
static bool LoadConfigFiles(const String& appType)
}
}
- IncludeDirRecursive(Application::GetZonesDir());
+ String zonesDir = Application::GetZonesDir();
+
+ Utility::Glob(Application::GetZonesDir() + "/*", &IncludeZoneDirRecursive, GlobDirectory);
Utility::Glob(Application::GetLocalStateDir() + "/lib/icinga2/api/zones/*", &IncludeNonLocalZone, GlobDirectory);
/* Load cluster config files - this should probably be in libremote but
return result;
#endif /* _MSC_VER */
}
+
+bool Utility::PathExists(const String& path)
+{
+#ifndef _WIN32
+ struct stat statbuf;
+ return (lstat(path.CStr(), &statbuf) >= 0);
+#else /* _WIN32 */
+ struct _stat statbuf;
+ return (_stat(path.CStr(), &statbuf) >= 0)
+#endif /* _WIN32 */
+}
static tm LocalTime(time_t ts);
+ static bool PathExists(const String& path);
+
private:
Utility(void);
static ConfigType::Ptr m_Type;
static Dictionary::Ptr m_ModuleScope;
-static String m_Zone;
static int m_StatementNum;
static bool m_Apply;
{
m_ModuleScope = make_shared<Dictionary>();
- String parentZone = m_Zone;
int parentStatementNum = m_StatementNum;
m_StatementNum = 0;
ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
}
- m_Zone = parentZone;
m_StatementNum = parentStatementNum;
}
AExpression::Ptr aexpr = *$2;
delete $2;
- if (!m_Zone.IsEmpty())
+ if (!context->GetZone().IsEmpty())
BOOST_THROW_EXCEPTION(std::invalid_argument("Zone name cannot be changed once it's been set."));
if (m_StatementNum != 0)
BOOST_THROW_EXCEPTION(std::invalid_argument("'zone' directive must be the first statement in a file."));
- m_Zone = aexpr->Evaluate(m_ModuleScope);
+ context->SetZone(aexpr->Evaluate(m_ModuleScope));
}
| T_ZONE rterm
{
AExpression::Ptr aexpr = *$2;
delete $2;
- if (!m_Zone.IsEmpty())
+ if (!context->GetZone().IsEmpty())
BOOST_THROW_EXCEPTION(std::invalid_argument("Zone name cannot be changed once it's been set."));
- m_Zone = aexpr->Evaluate(m_ModuleScope);
+ context->SetZone(aexpr->Evaluate(m_ModuleScope));
}
rterm_scope sep
{
try {
ascope->Evaluate(m_ModuleScope);
- m_Zone = String();
+ context->SetZone(String());
} catch (...) {
- m_Zone = String();
+ context->SetZone(String());
}
}
;
args->Add(filter);
- args->Add(m_Zone);
+ args->Add(context->GetZone());
$$ = new Value(make_shared<AExpression>(&AExpression::OpObject, args, exprl, DebugInfoRange(@2, @5)));
* @param path The path of the configuration file (or another name that
* identifies the source of the configuration text).
* @param input Input stream for the configuration file.
+ * @param zone The zone.
*/
-ConfigCompiler::ConfigCompiler(const String& path, std::istream *input)
- : m_Path(path), m_Input(input)
+ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const String& zone)
+ : m_Path(path), m_Input(input), m_Zone(zone)
{
InitializeScanner();
}
return m_Path;
}
+void ConfigCompiler::SetZone(const String& zone)
+{
+ m_Zone = zone;
+}
+
+String ConfigCompiler::GetZone(void) const
+{
+ return m_Zone;
+}
+
/**
* Handles an include directive.
*
BOOST_FOREACH(const String& dir, m_IncludeSearchDirs) {
String spath = dir + "/" + include;
-#ifndef _WIN32
- struct stat statbuf;
- if (lstat(spath.CStr(), &statbuf) >= 0) {
-#else /* _WIN32 */
- struct _stat statbuf;
- if (_stat(spath.CStr(), &statbuf) >= 0) {
-#endif /* _WIN32 */
+ if (Utility::PathExists(spath)) {
includePath = spath;
break;
}
std::vector<ConfigItem::Ptr> items;
- if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFile, _1), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
+ if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CompileFile, _1, m_Zone), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
std::ostringstream msgbuf;
msgbuf << "Include file '" + include + "' does not exist: " << debuginfo;
BOOST_THROW_EXCEPTION(std::invalid_argument(msgbuf.str()));
else
path = Utility::DirName(GetPath()) + "/" + include;
- Utility::GlobRecursive(path, pattern, boost::bind(&ConfigCompiler::CompileFile, _1), GlobFile);
+ Utility::GlobRecursive(path, pattern, boost::bind(&ConfigCompiler::CompileFile, _1, m_Zone), GlobFile);
}
/**
* @param stream The input stream.
* @returns Configuration items.
*/
-void ConfigCompiler::CompileStream(const String& path, std::istream *stream)
+void ConfigCompiler::CompileStream(const String& path, std::istream *stream, const String& zone)
{
CONTEXT("Compiling configuration stream with name '" + path + "'");
stream->exceptions(std::istream::badbit);
- ConfigCompiler ctx(path, stream);
+ ConfigCompiler ctx(path, stream, zone);
ctx.Compile();
}
* @param path The path.
* @returns Configuration items.
*/
-void ConfigCompiler::CompileFile(const String& path)
+void ConfigCompiler::CompileFile(const String& path, const String& zone)
{
CONTEXT("Compiling configuration file '" + path + "'");
Log(LogInformation, "config", "Compiling config file: " + path);
- return CompileStream(path, &stream);
+ return CompileStream(path, &stream, zone);
}
/**
* @param text The text.
* @returns Configuration items.
*/
-void ConfigCompiler::CompileText(const String& path, const String& text)
+void ConfigCompiler::CompileText(const String& path, const String& text, const String& zone)
{
std::stringstream stream(text);
- return CompileStream(path, &stream);
+ return CompileStream(path, &stream, zone);
}
/**
class I2_CONFIG_API ConfigCompiler
{
public:
- explicit ConfigCompiler(const String& path, std::istream *input);
+ explicit ConfigCompiler(const String& path, std::istream *input, const String& zone = String());
virtual ~ConfigCompiler(void);
void Compile(void);
- static void CompileStream(const String& path, std::istream *stream);
- static void CompileFile(const String& path);
- static void CompileText(const String& path, const String& text);
+ static void CompileStream(const String& path, std::istream *stream, const String& zone = String());
+ static void CompileFile(const String& path, const String& zone = String());
+ static void CompileText(const String& path, const String& text, const String& zone = String());
static void AddIncludeSearchDir(const String& dir);
String GetPath(void) const;
+ void SetZone(const String& zone);
+ String GetZone(void) const;
+
/* internally used methods */
void HandleInclude(const String& include, bool search, const DebugInfo& debuginfo);
void HandleIncludeRecursive(const String& include, const String& pattern, const DebugInfo& debuginfo);
private:
String m_Path;
std::istream *m_Input;
+ String m_Zone;
void *m_Scanner;
bool ApiListener::IsConfigMaster(const Zone::Ptr& zone) const
{
String path = Application::GetZonesDir() + "/" + zone->GetName();
-
-#ifndef _WIN32
- struct stat statbuf;
- return (lstat(path.CStr(), &statbuf) >= 0);
-#else /* _WIN32 */
- struct _stat statbuf;
- return (_stat(path.CStr(), &statbuf) >= 0);
-#endif /* _WIN32 */
+ return Utility::PathExists(path);
}
void ApiListener::ConfigGlobHandler(const Dictionary::Ptr& config, const String& path, const String& file)