mirror of
				https://github.com/Icinga/icinga2.git
				synced 2025-11-03 21:25:56 +01:00 
			
		
		
		
	
							parent
							
								
									b61f803d60
								
							
						
					
					
						commit
						ab63fca3d5
					
				@ -69,6 +69,8 @@ void ThreadPool::Stop(void)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_ThreadGroup.join_all();
 | 
			
		||||
 | 
			
		||||
	m_Stopped = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -201,6 +201,8 @@ static void SigHupHandler(int)
 | 
			
		||||
static bool Daemonize(void)
 | 
			
		||||
{
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
	Application::GetTP().Stop();
 | 
			
		||||
 | 
			
		||||
	pid_t pid = fork();
 | 
			
		||||
	if (pid == -1) {
 | 
			
		||||
		return false;
 | 
			
		||||
@ -231,6 +233,8 @@ static bool Daemonize(void)
 | 
			
		||||
 | 
			
		||||
		Application::Exit(0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Application::GetTP().Start();
 | 
			
		||||
#endif /* _WIN32 */
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
 | 
			
		||||
@ -60,54 +60,6 @@ do {							\
 | 
			
		||||
do {							\
 | 
			
		||||
	result = yyextra->ReadInput(buf, max_size);	\
 | 
			
		||||
} while (0)
 | 
			
		||||
 | 
			
		||||
extern int ignore_newlines;
 | 
			
		||||
 | 
			
		||||
struct lex_buf {
 | 
			
		||||
	char *buf;
 | 
			
		||||
	size_t size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void lb_init(lex_buf *lb)
 | 
			
		||||
{
 | 
			
		||||
	lb->buf = NULL;
 | 
			
		||||
	lb->size = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*static void lb_cleanup(lex_buf *lb)
 | 
			
		||||
{
 | 
			
		||||
	free(lb->buf);
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
static void lb_append_char(lex_buf *lb, char new_char)
 | 
			
		||||
{
 | 
			
		||||
	const size_t block_size = 64;
 | 
			
		||||
 | 
			
		||||
	size_t old_blocks = (lb->size + (block_size - 1)) / block_size;
 | 
			
		||||
	size_t new_blocks = ((lb->size + 1) + (block_size - 1)) / block_size;
 | 
			
		||||
 | 
			
		||||
	if (old_blocks != new_blocks) {
 | 
			
		||||
		char *new_buf = (char *)realloc(lb->buf, new_blocks * block_size);
 | 
			
		||||
 | 
			
		||||
		if (new_buf == NULL && new_blocks > 0)
 | 
			
		||||
			throw std::bad_alloc();
 | 
			
		||||
 | 
			
		||||
		lb->buf = new_buf;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lb->size++;
 | 
			
		||||
	lb->buf[lb->size - 1] = new_char;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *lb_steal(lex_buf *lb)
 | 
			
		||||
{
 | 
			
		||||
	lb_append_char(lb, '\0');
 | 
			
		||||
 | 
			
		||||
	char *buf = lb->buf;
 | 
			
		||||
	lb->buf = NULL;
 | 
			
		||||
	lb->size = 0;
 | 
			
		||||
	return buf;
 | 
			
		||||
}
 | 
			
		||||
%}
 | 
			
		||||
 | 
			
		||||
%option reentrant noyywrap yylineno
 | 
			
		||||
@ -120,25 +72,19 @@ static char *lb_steal(lex_buf *lb)
 | 
			
		||||
%x HEREDOC
 | 
			
		||||
 | 
			
		||||
%%
 | 
			
		||||
	lex_buf string_buf;
 | 
			
		||||
 | 
			
		||||
\"				{ lb_init(&string_buf); BEGIN(STRING); }
 | 
			
		||||
\"				{ yyextra->m_LexBuffer.str(""); yyextra->m_LexBuffer.clear(); BEGIN(STRING); }
 | 
			
		||||
 | 
			
		||||
<STRING>\"			{
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
 | 
			
		||||
	lb_append_char(&string_buf, '\0');
 | 
			
		||||
 | 
			
		||||
	yylval->text = lb_steal(&string_buf);
 | 
			
		||||
	std::string str = yyextra->m_LexBuffer.str();
 | 
			
		||||
	yylval->text = strdup(str.c_str());
 | 
			
		||||
 | 
			
		||||
	return T_STRING;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
<STRING>\n			{
 | 
			
		||||
	std::ostringstream msgbuf;
 | 
			
		||||
	msgbuf << "Unterminated string found: " << *yylloc;
 | 
			
		||||
	ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
	BOOST_THROW_EXCEPTION(ConfigError("Unterminated string literal") << errinfo_debuginfo(*yylloc));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
<STRING>\\[0-7]{1,3}		{
 | 
			
		||||
@ -149,50 +95,45 @@ static char *lb_steal(lex_buf *lb)
 | 
			
		||||
 | 
			
		||||
	if (result > 0xff) {
 | 
			
		||||
		/* error, constant is out-of-bounds */
 | 
			
		||||
		std::ostringstream msgbuf;
 | 
			
		||||
		msgbuf << "Constant is out-of-bounds: " << yytext << " " << *yylloc;
 | 
			
		||||
		ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
 | 
			
		||||
		BOOST_THROW_EXCEPTION(ConfigError("Constant is out of bounds: " + String(yytext)) << errinfo_debuginfo(*yylloc));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lb_append_char(&string_buf, result);
 | 
			
		||||
	yyextra->m_LexBuffer << static_cast<char>(result);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
<STRING>\\[0-9]+		{
 | 
			
		||||
	/* generate error - bad escape sequence; something
 | 
			
		||||
	 * like '\48' or '\0777777'
 | 
			
		||||
	 */
 | 
			
		||||
	std::ostringstream msgbuf;
 | 
			
		||||
	msgbuf << "Bad escape sequence found: " << yytext << " " << *yylloc;
 | 
			
		||||
	ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
 | 
			
		||||
	BOOST_THROW_EXCEPTION(ConfigError("Bad escape sequence found: " + String(yytext)) << errinfo_debuginfo(*yylloc));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
<STRING>\\n			{ lb_append_char(&string_buf, '\n'); }
 | 
			
		||||
<STRING>\\t			{ lb_append_char(&string_buf, '\t'); }
 | 
			
		||||
<STRING>\\r			{ lb_append_char(&string_buf, '\r'); }
 | 
			
		||||
<STRING>\\b			{ lb_append_char(&string_buf, '\b'); }
 | 
			
		||||
<STRING>\\f			{ lb_append_char(&string_buf, '\f'); }
 | 
			
		||||
<STRING>\\(.|\n)		{ lb_append_char(&string_buf, yytext[1]); }
 | 
			
		||||
<STRING>\\n			{ yyextra->m_LexBuffer << "\n"; }
 | 
			
		||||
<STRING>\\t			{ yyextra->m_LexBuffer << "\t"; }
 | 
			
		||||
<STRING>\\r			{ yyextra->m_LexBuffer << "\r"; }
 | 
			
		||||
<STRING>\\b			{ yyextra->m_LexBuffer << "\b"; }
 | 
			
		||||
<STRING>\\f			{ yyextra->m_LexBuffer << "\f"; }
 | 
			
		||||
<STRING>\\(.|\n)		{ yyextra->m_LexBuffer << yytext[1]; }
 | 
			
		||||
 | 
			
		||||
<STRING>[^\\\n\"]+		{
 | 
			
		||||
	char *yptr = yytext;
 | 
			
		||||
 | 
			
		||||
	while (*yptr)
 | 
			
		||||
		lb_append_char(&string_buf, *yptr++);
 | 
			
		||||
		yyextra->m_LexBuffer << *yptr++;
 | 
			
		||||
		       	       }
 | 
			
		||||
 | 
			
		||||
\{\{\{				{ lb_init(&string_buf); BEGIN(HEREDOC); }
 | 
			
		||||
\{\{\{				{ yyextra->m_LexBuffer.str(""); yyextra->m_LexBuffer.clear(); BEGIN(HEREDOC); }
 | 
			
		||||
 | 
			
		||||
<HEREDOC>\}\}\}			{
 | 
			
		||||
	BEGIN(INITIAL);
 | 
			
		||||
 | 
			
		||||
	lb_append_char(&string_buf, '\0');
 | 
			
		||||
 | 
			
		||||
	yylval->text = lb_steal(&string_buf);
 | 
			
		||||
	std::string str = yyextra->m_LexBuffer.str();
 | 
			
		||||
	yylval->text = strdup(str.c_str());
 | 
			
		||||
 | 
			
		||||
	return T_STRING;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
<HEREDOC>(.|\n)			{ lb_append_char(&string_buf, yytext[0]); }
 | 
			
		||||
<HEREDOC>(.|\n)			{ yyextra->m_LexBuffer << yytext[0]; }
 | 
			
		||||
 | 
			
		||||
<INITIAL>{
 | 
			
		||||
"/*"				BEGIN(C_COMMENT);
 | 
			
		||||
@ -205,10 +146,7 @@ static char *lb_steal(lex_buf *lb)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<C_COMMENT><<EOF>>              {
 | 
			
		||||
		std::ostringstream msgbuf;
 | 
			
		||||
		msgbuf << "End-of-file while in comment: " << yytext << " " << *yylloc;
 | 
			
		||||
		ConfigCompilerContext::GetInstance()->AddMessage(true, msgbuf.str());
 | 
			
		||||
		yyterminate();
 | 
			
		||||
		BOOST_THROW_EXCEPTION(ConfigError("End-of-file while in comment") << errinfo_debuginfo(*yylloc));
 | 
			
		||||
		       	        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -294,7 +232,7 @@ in				return T_IN;
 | 
			
		||||
\>				return T_GREATER_THAN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[\r\n]+				{ yycolumn -= strlen(yytext) - 1; if (!ignore_newlines) return T_NEWLINE; }
 | 
			
		||||
[\r\n]+				{ yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines) return T_NEWLINE; }
 | 
			
		||||
<<EOF>>				{ if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } }
 | 
			
		||||
.				return yytext[0];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -69,8 +69,6 @@ do {							\
 | 
			
		||||
 | 
			
		||||
using namespace icinga;
 | 
			
		||||
 | 
			
		||||
int ignore_newlines = 0;
 | 
			
		||||
 | 
			
		||||
template<typename T>
 | 
			
		||||
static void MakeRBinaryOp(Expression** result, Expression *left, Expression *right, DebugInfo& diLeft, DebugInfo& diRight)
 | 
			
		||||
{
 | 
			
		||||
@ -230,16 +228,13 @@ int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
 | 
			
		||||
 | 
			
		||||
void yyerror(YYLTYPE *locp, std::vector<Expression *> *, ConfigCompiler *, const char *err)
 | 
			
		||||
{
 | 
			
		||||
	std::ostringstream message;
 | 
			
		||||
	message << *locp << ": " << err;
 | 
			
		||||
	ConfigCompilerContext::GetInstance()->AddMessage(true, message.str(), *locp);
 | 
			
		||||
	BOOST_THROW_EXCEPTION(ConfigError(err) << errinfo_debuginfo(*locp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int yyparse(std::vector<Expression *> *elist, ConfigCompiler *context);
 | 
			
		||||
 | 
			
		||||
Expression *ConfigCompiler::Compile(void)
 | 
			
		||||
{
 | 
			
		||||
	try {
 | 
			
		||||
	std::vector<Expression *> elist;
 | 
			
		||||
 | 
			
		||||
	if (yyparse(&elist, this) != 0)
 | 
			
		||||
@ -248,14 +243,6 @@ Expression *ConfigCompiler::Compile(void)
 | 
			
		||||
	DictExpression *expr = new DictExpression(elist);
 | 
			
		||||
	expr->MakeInline();
 | 
			
		||||
	return expr;
 | 
			
		||||
	} catch (const ConfigError& ex) {
 | 
			
		||||
		const DebugInfo *di = boost::get_error_info<errinfo_debuginfo>(ex);
 | 
			
		||||
		ConfigCompilerContext::GetInstance()->AddMessage(true, ex.what(), di ? *di : DebugInfo());
 | 
			
		||||
	} catch (const std::exception& ex) {
 | 
			
		||||
		ConfigCompilerContext::GetInstance()->AddMessage(true, DiagnosticInformation(ex));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define scanner (context->GetScanner())
 | 
			
		||||
@ -788,11 +775,11 @@ rterm_without_indexer: T_STRING
 | 
			
		||||
	}
 | 
			
		||||
	| '('
 | 
			
		||||
	{
 | 
			
		||||
		ignore_newlines++;
 | 
			
		||||
		context->m_IgnoreNewlines++;
 | 
			
		||||
	}
 | 
			
		||||
	rterm ')'
 | 
			
		||||
	{
 | 
			
		||||
		ignore_newlines--;
 | 
			
		||||
		context->m_IgnoreNewlines--;
 | 
			
		||||
		$$ = $3;
 | 
			
		||||
	}
 | 
			
		||||
	| rterm T_LOGICAL_OR rterm { MakeRBinaryOp<LogicalOrExpression>(&$$, $1, $3, @1, @3); }
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ std::vector<String> ConfigCompiler::m_IncludeSearchDirs;
 | 
			
		||||
 * @param zone The zone.
 | 
			
		||||
 */
 | 
			
		||||
ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const String& zone)
 | 
			
		||||
	: m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false)
 | 
			
		||||
	: m_Path(path), m_Input(input), m_Zone(zone), m_Eof(false), m_IgnoreNewlines(0)
 | 
			
		||||
{
 | 
			
		||||
	InitializeScanner();
 | 
			
		||||
}
 | 
			
		||||
@ -52,6 +52,7 @@ ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, const St
 | 
			
		||||
ConfigCompiler::~ConfigCompiler(void)
 | 
			
		||||
{
 | 
			
		||||
	DestroyScanner();
 | 
			
		||||
	delete m_Input;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -173,6 +174,17 @@ void ConfigCompiler::HandleLibrary(const String& library)
 | 
			
		||||
	(void) Utility::LoadExtensionLibrary(library);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ConfigCompiler::CompileHelper(void)
 | 
			
		||||
{
 | 
			
		||||
	try {
 | 
			
		||||
		m_Promise.set_value(boost::shared_ptr<Expression>(Compile()));
 | 
			
		||||
	} catch (...) {
 | 
			
		||||
		m_Promise.set_exception(boost::current_exception());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	delete this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compiles a stream.
 | 
			
		||||
 *
 | 
			
		||||
@ -186,8 +198,12 @@ Expression *ConfigCompiler::CompileStream(const String& path, std::istream *stre
 | 
			
		||||
 | 
			
		||||
	stream->exceptions(std::istream::badbit);
 | 
			
		||||
 | 
			
		||||
	ConfigCompiler ctx(path, stream, zone);
 | 
			
		||||
	return ctx.Compile();
 | 
			
		||||
	ConfigCompiler* ctx = new ConfigCompiler(path, stream, zone);
 | 
			
		||||
 | 
			
		||||
	boost::shared_future<boost::shared_ptr<Expression> > ftr = boost::shared_future<boost::shared_ptr<Expression> >(ctx->m_Promise.get_future());
 | 
			
		||||
 | 
			
		||||
	Utility::QueueAsyncCallback(boost::bind(&ConfigCompiler::CompileHelper, ctx));
 | 
			
		||||
	return new FutureExpression(ftr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -200,10 +216,10 @@ Expression *ConfigCompiler::CompileFile(const String& path, const String& zone)
 | 
			
		||||
{
 | 
			
		||||
	CONTEXT("Compiling configuration file '" + path + "'");
 | 
			
		||||
 | 
			
		||||
	std::ifstream stream;
 | 
			
		||||
	stream.open(path.CStr(), std::ifstream::in);
 | 
			
		||||
	std::ifstream *stream = new std::ifstream();
 | 
			
		||||
	stream->open(path.CStr(), std::ifstream::in);
 | 
			
		||||
 | 
			
		||||
	if (!stream)
 | 
			
		||||
	if (!*stream)
 | 
			
		||||
		BOOST_THROW_EXCEPTION(posix_error()
 | 
			
		||||
			<< boost::errinfo_api_function("std::ifstream::open")
 | 
			
		||||
			<< boost::errinfo_errno(errno)
 | 
			
		||||
@ -212,7 +228,7 @@ Expression *ConfigCompiler::CompileFile(const String& path, const String& zone)
 | 
			
		||||
	Log(LogInformation, "ConfigCompiler")
 | 
			
		||||
	    << "Compiling config file: " << path;
 | 
			
		||||
 | 
			
		||||
	return CompileStream(path, &stream, zone);
 | 
			
		||||
	return CompileStream(path, stream, zone);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -224,8 +240,8 @@ Expression *ConfigCompiler::CompileFile(const String& path, const String& zone)
 | 
			
		||||
 */
 | 
			
		||||
Expression *ConfigCompiler::CompileText(const String& path, const String& text, const String& zone)
 | 
			
		||||
{
 | 
			
		||||
	std::stringstream stream(text);
 | 
			
		||||
	return CompileStream(path, &stream, zone);
 | 
			
		||||
	std::stringstream *stream = new std::stringstream(text);
 | 
			
		||||
	return CompileStream(path, stream, zone);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -81,6 +81,8 @@ public:
 | 
			
		||||
	void *GetScanner(void) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	boost::promise<boost::shared_ptr<Expression> > m_Promise;
 | 
			
		||||
 | 
			
		||||
	String m_Path;
 | 
			
		||||
	std::istream *m_Input;
 | 
			
		||||
	String m_Zone;
 | 
			
		||||
@ -88,6 +90,9 @@ private:
 | 
			
		||||
	void *m_Scanner;
 | 
			
		||||
	bool m_Eof;
 | 
			
		||||
 | 
			
		||||
	int m_IgnoreNewlines;
 | 
			
		||||
	std::ostringstream m_LexBuffer;
 | 
			
		||||
 | 
			
		||||
	std::stack<TypeRuleList::Ptr> m_RuleLists;
 | 
			
		||||
	ConfigType::Ptr m_Type;
 | 
			
		||||
 | 
			
		||||
@ -105,6 +110,8 @@ private:
 | 
			
		||||
	void InitializeScanner(void);
 | 
			
		||||
	void DestroyScanner(void);
 | 
			
		||||
 | 
			
		||||
	void CompileHelper(void);
 | 
			
		||||
 | 
			
		||||
	friend int ::yylex(YYSTYPE *context, icinga::DebugInfo *di, yyscan_t scanner);
 | 
			
		||||
	friend int ::yyparse(std::vector<icinga::Expression *> *elist, ConfigCompiler *context);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@
 | 
			
		||||
#include "base/configerror.hpp"
 | 
			
		||||
#include "base/convert.hpp"
 | 
			
		||||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <boost/thread/future.hpp>
 | 
			
		||||
#include <map>
 | 
			
		||||
 | 
			
		||||
namespace icinga
 | 
			
		||||
@ -164,6 +165,28 @@ private:
 | 
			
		||||
	boost::shared_ptr<Expression> m_Expression;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class I2_CONFIG_API FutureExpression : public Expression
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	FutureExpression(const boost::shared_future<boost::shared_ptr<Expression> >& future)
 | 
			
		||||
		: m_Future(future)
 | 
			
		||||
	{ }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	virtual Value DoEvaluate(VMFrame& frame, DebugHint *dhint) const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Future.get()->DoEvaluate(frame, dhint);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	virtual const DebugInfo& GetDebugInfo(void) const
 | 
			
		||||
	{
 | 
			
		||||
		return m_Future.get()->GetDebugInfo();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	mutable boost::shared_future<boost::shared_ptr<Expression> > m_Future;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class I2_CONFIG_API LiteralExpression : public Expression
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user