mirror of https://github.com/Icinga/icinga2.git
parent
fd5d6de52e
commit
74ef3e3ce6
|
@ -443,39 +443,30 @@ lterm: T_LIBRARY rterm
|
|||
{
|
||||
$$ = new SetExpression($1, $2, $3, @$);
|
||||
}
|
||||
| T_INCLUDE T_STRING
|
||||
| T_INCLUDE rterm
|
||||
{
|
||||
$$ = context->HandleInclude(*$2, false, @$);
|
||||
delete $2;
|
||||
$$ = new IncludeExpression(Utility::DirName(context->GetPath()), $2, NULL, NULL, IncludeRegular, false, context->GetZone(), context->GetPackage(), @$);
|
||||
}
|
||||
| T_INCLUDE T_STRING_ANGLE
|
||||
{
|
||||
$$ = context->HandleInclude(*$2, true, @$);
|
||||
$$ = new IncludeExpression(Utility::DirName(context->GetPath()), MakeLiteral(*$2), NULL, NULL, IncludeRegular, true, context->GetZone(), context->GetPackage(), @$);
|
||||
delete $2;
|
||||
}
|
||||
| T_INCLUDE_RECURSIVE T_STRING
|
||||
| T_INCLUDE_RECURSIVE rterm
|
||||
{
|
||||
$$ = context->HandleIncludeRecursive(*$2, "*.conf", @$);
|
||||
delete $2;
|
||||
$$ = new IncludeExpression(Utility::DirName(context->GetPath()), $2, MakeLiteral("*.conf"), NULL, IncludeRecursive, false, context->GetZone(), context->GetPackage(), @$);
|
||||
}
|
||||
| T_INCLUDE_RECURSIVE T_STRING ',' T_STRING
|
||||
| T_INCLUDE_RECURSIVE rterm ',' rterm
|
||||
{
|
||||
$$ = context->HandleIncludeRecursive(*$2, *$4, @$);
|
||||
delete $2;
|
||||
delete $4;
|
||||
$$ = new IncludeExpression(Utility::DirName(context->GetPath()), $2, $4, NULL, IncludeRecursive, false, context->GetZone(), context->GetPackage(), @$);
|
||||
}
|
||||
| T_INCLUDE_ZONES T_STRING ',' T_STRING
|
||||
| T_INCLUDE_ZONES rterm ',' rterm
|
||||
{
|
||||
$$ = context->HandleIncludeZones(*$2, *$4, "*.conf", @$);
|
||||
delete $2;
|
||||
delete $4;
|
||||
$$ = new IncludeExpression(Utility::DirName(context->GetPath()), $4, MakeLiteral("*.conf"), $2, IncludeZones, false, context->GetZone(), context->GetPackage(), @$);
|
||||
}
|
||||
| T_INCLUDE_ZONES T_STRING ',' T_STRING ',' T_STRING
|
||||
| T_INCLUDE_ZONES rterm ',' rterm ',' rterm
|
||||
{
|
||||
$$ = context->HandleIncludeZones(*$2, *$4, *$6, @$);
|
||||
delete $2;
|
||||
delete $4;
|
||||
delete $6;
|
||||
$$ = new IncludeExpression(Utility::DirName(context->GetPath()), $4, $6, $2, IncludeZones, false, context->GetZone(), context->GetPackage(), @$);
|
||||
}
|
||||
| T_IMPORT rterm
|
||||
{
|
||||
|
|
|
@ -119,24 +119,26 @@ void ConfigCompiler::CollectIncludes(std::vector<Expression *>& expressions,
|
|||
/**
|
||||
* Handles an include directive.
|
||||
*
|
||||
* @param include The path from the include directive.
|
||||
* @param relativeBath The path this include is relative to.
|
||||
* @param path The path from the include directive.
|
||||
* @param search Whether to search global include dirs.
|
||||
* @param debuginfo Debug information.
|
||||
*/
|
||||
Expression *ConfigCompiler::HandleInclude(const String& include, bool search, const DebugInfo& debuginfo)
|
||||
Expression *ConfigCompiler::HandleInclude(const String& relativeBase, const String& path,
|
||||
bool search, const String& zone, const String& package, const DebugInfo& debuginfo)
|
||||
{
|
||||
String path;
|
||||
String upath;
|
||||
|
||||
if (search || (include.GetLength() > 0 && include[0] == '/'))
|
||||
path = include;
|
||||
if (search || (path.GetLength() > 0 && path[0] == '/'))
|
||||
upath = path;
|
||||
else
|
||||
path = Utility::DirName(GetPath()) + "/" + include;
|
||||
upath = relativeBase + "/" + path;
|
||||
|
||||
String includePath = path;
|
||||
String includePath = upath;
|
||||
|
||||
if (search) {
|
||||
BOOST_FOREACH(const String& dir, m_IncludeSearchDirs) {
|
||||
String spath = dir + "/" + include;
|
||||
String spath = dir + "/" + path;
|
||||
|
||||
if (Utility::PathExists(spath)) {
|
||||
includePath = spath;
|
||||
|
@ -147,9 +149,9 @@ Expression *ConfigCompiler::HandleInclude(const String& include, bool search, co
|
|||
|
||||
std::vector<Expression *> expressions;
|
||||
|
||||
if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, m_Zone, m_Package), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
|
||||
if (!Utility::Glob(includePath, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zone, package), GlobFile) && includePath.FindFirstOf("*?") == String::NPos) {
|
||||
std::ostringstream msgbuf;
|
||||
msgbuf << "Include file '" + include + "' does not exist";
|
||||
msgbuf << "Include file '" + path + "' does not exist";
|
||||
BOOST_THROW_EXCEPTION(ScriptError(msgbuf.str(), debuginfo));
|
||||
}
|
||||
|
||||
|
@ -161,25 +163,27 @@ Expression *ConfigCompiler::HandleInclude(const String& include, bool search, co
|
|||
/**
|
||||
* Handles recursive includes.
|
||||
*
|
||||
* @param relativeBase The path this include is relative to.
|
||||
* @param path The directory path.
|
||||
* @param pattern The file pattern.
|
||||
* @param debuginfo Debug information.
|
||||
*/
|
||||
Expression *ConfigCompiler::HandleIncludeRecursive(const String& path, const String& pattern, const DebugInfo&)
|
||||
Expression *ConfigCompiler::HandleIncludeRecursive(const String& relativeBase, const String& path,
|
||||
const String& pattern, const String& zone, const String& package, const DebugInfo&)
|
||||
{
|
||||
String ppath;
|
||||
|
||||
if (path.GetLength() > 0 && path[0] == '/')
|
||||
ppath = path;
|
||||
else
|
||||
ppath = Utility::DirName(GetPath()) + "/" + path;
|
||||
ppath = relativeBase + "/" + path;
|
||||
|
||||
std::vector<Expression *> expressions;
|
||||
Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, m_Zone, m_Package), GlobFile);
|
||||
Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zone, package), GlobFile);
|
||||
return new DictExpression(expressions);
|
||||
}
|
||||
|
||||
void ConfigCompiler::HandleIncludeZone(const String& tag, const String& path, const String& pattern, std::vector<Expression *>& expressions)
|
||||
void ConfigCompiler::HandleIncludeZone(const String& relativeBase, const String& tag, const String& path, const String& pattern, const String& package, std::vector<Expression *>& expressions)
|
||||
{
|
||||
String zoneName = Utility::BaseName(path);
|
||||
|
||||
|
@ -188,32 +192,34 @@ void ConfigCompiler::HandleIncludeZone(const String& tag, const String& path, co
|
|||
if (path.GetLength() > 0 && path[0] == '/')
|
||||
ppath = path;
|
||||
else
|
||||
ppath = Utility::DirName(GetPath()) + "/" + path;
|
||||
ppath = relativeBase + "/" + path;
|
||||
|
||||
RegisterZoneDir(tag, ppath, zoneName);
|
||||
|
||||
Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zoneName, m_Package), GlobFile);
|
||||
Utility::GlobRecursive(ppath, pattern, boost::bind(&ConfigCompiler::CollectIncludes, boost::ref(expressions), _1, zoneName, package), GlobFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles zone includes.
|
||||
*
|
||||
* @param relativeBase The path this include is relative to.
|
||||
* @param tag The tag name.
|
||||
* @param path The directory path.
|
||||
* @param pattern The file pattern.
|
||||
* @param debuginfo Debug information.
|
||||
*/
|
||||
Expression *ConfigCompiler::HandleIncludeZones(const String& tag, const String& path, const String& pattern, const DebugInfo&)
|
||||
Expression *ConfigCompiler::HandleIncludeZones(const String& relativeBase, const String& tag,
|
||||
const String& path, const String& pattern, const String& package, const DebugInfo&)
|
||||
{
|
||||
String ppath;
|
||||
|
||||
if (path.GetLength() > 0 && path[0] == '/')
|
||||
ppath = path;
|
||||
else
|
||||
ppath = Utility::DirName(GetPath()) + "/" + path;
|
||||
ppath = relativeBase + "/" + path;
|
||||
|
||||
std::vector<Expression *> expressions;
|
||||
Utility::Glob(ppath + "/*", boost::bind(&ConfigCompiler::HandleIncludeZone, this, tag, _1, pattern, boost::ref(expressions)), GlobDirectory);
|
||||
Utility::Glob(ppath + "/*", boost::bind(&ConfigCompiler::HandleIncludeZone, relativeBase, tag, _1, pattern, package, boost::ref(expressions)), GlobDirectory);
|
||||
return new DictExpression(expressions);
|
||||
}
|
||||
|
||||
|
|
|
@ -105,10 +105,12 @@ public:
|
|||
static void CollectIncludes(std::vector<Expression *>& expressions,
|
||||
const String& file, const String& zone, const String& package);
|
||||
|
||||
/* internally used methods */
|
||||
Expression *HandleInclude(const String& include, bool search, const DebugInfo& debuginfo = DebugInfo());
|
||||
Expression *HandleIncludeRecursive(const String& path, const String& pattern, const DebugInfo& debuginfo = DebugInfo());
|
||||
Expression *HandleIncludeZones(const String& tag, const String& path, const String& pattern, const DebugInfo& debuginfo = DebugInfo());
|
||||
static Expression *HandleInclude(const String& relativeBase, const String& path, bool search,
|
||||
const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo());
|
||||
static Expression *HandleIncludeRecursive(const String& relativeBase, const String& path,
|
||||
const String& pattern, const String& zone, const String& package, const DebugInfo& debuginfo = DebugInfo());
|
||||
static Expression *HandleIncludeZones(const String& relativeBase, const String& tag,
|
||||
const String& path, const String& pattern, const String& package, const DebugInfo& debuginfo = DebugInfo());
|
||||
|
||||
size_t ReadInput(char *buffer, size_t max_bytes);
|
||||
void *GetScanner(void) const;
|
||||
|
@ -135,7 +137,7 @@ private:
|
|||
void InitializeScanner(void);
|
||||
void DestroyScanner(void);
|
||||
|
||||
void HandleIncludeZone(const String& tag, const String& path, const String& pattern, std::vector<Expression *>& expressions);
|
||||
static void HandleIncludeZone(const String& relativeBase, const String& tag, const String& path, const String& pattern, const String& package, std::vector<Expression *>& expressions);
|
||||
|
||||
public:
|
||||
bool m_Eof;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "config/expression.hpp"
|
||||
#include "config/configitem.hpp"
|
||||
#include "config/configcompiler.hpp"
|
||||
#include "config/vmops.hpp"
|
||||
#include "base/array.hpp"
|
||||
#include "base/json.hpp"
|
||||
|
@ -783,3 +784,74 @@ ExpressionResult LibraryExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dh
|
|||
return Empty;
|
||||
}
|
||||
|
||||
ExpressionResult IncludeExpression::DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const
|
||||
{
|
||||
if (frame.Sandboxed)
|
||||
BOOST_THROW_EXCEPTION(ScriptError("Includes are not allowed in sandbox mode.", m_DebugInfo));
|
||||
|
||||
Expression *expr;
|
||||
String name, path, pattern;
|
||||
|
||||
switch (m_Type) {
|
||||
case IncludeRegular:
|
||||
{
|
||||
ExpressionResult pathres = m_Path->Evaluate(frame, dhint);
|
||||
CHECK_RESULT(pathres);
|
||||
path = pathres.GetValue();
|
||||
}
|
||||
|
||||
expr = ConfigCompiler::HandleInclude(m_RelativeBase, path, m_SearchIncludes, m_Zone, m_Package, m_DebugInfo);
|
||||
break;
|
||||
|
||||
case IncludeRecursive:
|
||||
{
|
||||
ExpressionResult pathres = m_Path->Evaluate(frame, dhint);
|
||||
CHECK_RESULT(pathres);
|
||||
path = pathres.GetValue();
|
||||
}
|
||||
|
||||
{
|
||||
ExpressionResult patternres = m_Pattern->Evaluate(frame, dhint);
|
||||
CHECK_RESULT(patternres);
|
||||
pattern = patternres.GetValue();
|
||||
}
|
||||
|
||||
expr = ConfigCompiler::HandleIncludeRecursive(m_RelativeBase, path, pattern, m_Zone, m_Package, m_DebugInfo);
|
||||
break;
|
||||
|
||||
case IncludeZones:
|
||||
{
|
||||
ExpressionResult nameres = m_Name->Evaluate(frame, dhint);
|
||||
CHECK_RESULT(nameres);
|
||||
name = nameres.GetValue();
|
||||
}
|
||||
|
||||
{
|
||||
ExpressionResult pathres = m_Path->Evaluate(frame, dhint);
|
||||
CHECK_RESULT(pathres);
|
||||
path = pathres.GetValue();
|
||||
}
|
||||
|
||||
{
|
||||
ExpressionResult patternres = m_Pattern->Evaluate(frame, dhint);
|
||||
CHECK_RESULT(patternres);
|
||||
pattern = patternres.GetValue();
|
||||
}
|
||||
|
||||
expr = ConfigCompiler::HandleIncludeZones(m_RelativeBase, name, path, pattern, m_Package, m_DebugInfo);
|
||||
break;
|
||||
}
|
||||
|
||||
ExpressionResult res(Empty);
|
||||
|
||||
try {
|
||||
res = expr->Evaluate(frame, dhint);
|
||||
} catch (const std::exception&) {
|
||||
delete expr;
|
||||
throw;
|
||||
}
|
||||
|
||||
delete expr;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -899,6 +899,43 @@ protected:
|
|||
virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||
};
|
||||
|
||||
enum IncludeType
|
||||
{
|
||||
IncludeRegular,
|
||||
IncludeRecursive,
|
||||
IncludeZones
|
||||
};
|
||||
|
||||
class I2_CONFIG_API IncludeExpression : public DebuggableExpression
|
||||
{
|
||||
public:
|
||||
IncludeExpression(const String& relativeBase, Expression *path, Expression *pattern, Expression *name,
|
||||
IncludeType type, bool searchIncludes, const String& zone, const String& package, const DebugInfo& debugInfo = DebugInfo())
|
||||
: DebuggableExpression(debugInfo), m_RelativeBase(relativeBase), m_Path(path), m_Pattern(pattern),
|
||||
m_Name(name), m_Type(type), m_SearchIncludes(searchIncludes), m_Zone(zone), m_Package(package)
|
||||
{ }
|
||||
|
||||
~IncludeExpression(void)
|
||||
{
|
||||
delete m_Path;
|
||||
delete m_Pattern;
|
||||
delete m_Name;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
|
||||
|
||||
private:
|
||||
String m_RelativeBase;
|
||||
Expression *m_Path;
|
||||
Expression *m_Pattern;
|
||||
Expression *m_Name;
|
||||
IncludeType m_Type;
|
||||
bool m_SearchIncludes;
|
||||
String m_Zone;
|
||||
String m_Package;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* EXPRESSION_H */
|
||||
|
|
Loading…
Reference in New Issue