mirror of https://github.com/Icinga/icinga2.git
parent
705447ce18
commit
c1ac548a77
|
@ -26,6 +26,7 @@
|
|||
#include "base/utility.hpp"
|
||||
#include "base/json.hpp"
|
||||
#include "base/objectlock.hpp"
|
||||
#include "base/scriptfunction.hpp"
|
||||
#include <mmatch.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -57,6 +58,9 @@ using namespace icinga;
|
|||
boost::thread_specific_ptr<String> Utility::m_ThreadName;
|
||||
boost::thread_specific_ptr<unsigned int> Utility::m_RandSeed;
|
||||
|
||||
REGISTER_SCRIPTFUNCTION(escape, &Utility::EscapeString);
|
||||
REGISTER_SCRIPTFUNCTION(unescape, &Utility::UnescapeString);
|
||||
|
||||
/**
|
||||
* Demangles a symbol name.
|
||||
*
|
||||
|
@ -1201,3 +1205,58 @@ void Utility::SaveJsonFile(const String& path, const Value& value)
|
|||
<< boost::errinfo_file_name(tempPath));
|
||||
}
|
||||
}
|
||||
|
||||
static void HexEncode(char ch, std::ostream& os)
|
||||
{
|
||||
const char *hex_chars = "0123456789ABCDEF";
|
||||
|
||||
os << hex_chars[ch >> 4 & 0x0f];
|
||||
os << hex_chars[ch & 0x0f];
|
||||
}
|
||||
|
||||
static int HexDecode(char hc)
|
||||
{
|
||||
if (hc >= '0' && hc <= '9')
|
||||
return hc - '0';
|
||||
else if (hc >= 'a' && hc <= 'f')
|
||||
return hc - 'a' + 10;
|
||||
else if (hc >= 'A' && hc <= 'F')
|
||||
return hc - 'A' + 10;
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid hex character."));
|
||||
}
|
||||
|
||||
String Utility::EscapeString(const String& s, const String& chars)
|
||||
{
|
||||
std::ostringstream result;
|
||||
|
||||
BOOST_FOREACH(char ch, s) {
|
||||
if (chars.FindFirstOf(ch) != String::NPos || ch == '%') {
|
||||
result << '%';
|
||||
HexEncode(ch, result);
|
||||
} else
|
||||
result << ch;
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
String Utility::UnescapeString(const String& s)
|
||||
{
|
||||
std::ostringstream result;
|
||||
|
||||
for (String::SizeType i = 0; i < s.GetLength(); i++) {
|
||||
if (s[i] == '%') {
|
||||
if (i + 2 > s.GetLength() - 1)
|
||||
BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid escape sequence."));
|
||||
|
||||
char ch = HexDecode(s[i + 1]) * 16 + HexDecode(s[i + 2]);
|
||||
result << ch;
|
||||
|
||||
i += 2;
|
||||
} else
|
||||
result << s[i];
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
|
|
@ -115,6 +115,9 @@ public:
|
|||
static String EscapeShellCmd(const String& s);
|
||||
static String EscapeShellArg(const String& s);
|
||||
|
||||
static String EscapeString(const String& s, const String& chars);
|
||||
static String UnescapeString(const String& s);
|
||||
|
||||
static void SetThreadName(const String& name, bool os = true);
|
||||
static String GetThreadName(void);
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ String RepositoryUtility::GetRepositoryObjectConfigPath(const String& type, cons
|
|||
if (type == "Host")
|
||||
path += "hosts";
|
||||
else if (type == "Service")
|
||||
path += "hosts/" + object->Get("host_name");
|
||||
path += "hosts/" + EscapeName(object->Get("host_name"));
|
||||
else if (type == "Zone")
|
||||
path += "zones";
|
||||
else if (type == "Endpoint")
|
||||
|
@ -116,7 +116,7 @@ String RepositoryUtility::GetRepositoryObjectConfigFilePath(const String& type,
|
|||
{
|
||||
String path = GetRepositoryObjectConfigPath(type, object);
|
||||
|
||||
path += "/" + object->Get("name") + ".conf";
|
||||
path += "/" + EscapeName(object->Get("name")) + ".conf";
|
||||
|
||||
return path;
|
||||
}
|
||||
|
@ -154,6 +154,7 @@ void RepositoryUtility::PrintObjects(std::ostream& fp, const String& type)
|
|||
|
||||
String file = Utility::BaseName(object);
|
||||
boost::algorithm::replace_all(file, ".conf", "");
|
||||
file = UnescapeName(file);
|
||||
|
||||
fp << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << type << ConsoleColorTag(Console_Normal)
|
||||
<< " '" << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << file << ConsoleColorTag(Console_Normal) << "'";
|
||||
|
@ -164,7 +165,7 @@ void RepositoryUtility::PrintObjects(std::ostream& fp, const String& type)
|
|||
std::vector<String> tokens;
|
||||
boost::algorithm::split(tokens, prefix, boost::is_any_of("/"));
|
||||
|
||||
String host_name = tokens[tokens.size()-1];
|
||||
String host_name = UnescapeName(tokens[tokens.size()-1]);
|
||||
fp << " (on " << ConsoleColorTag(Console_ForegroundMagenta | Console_Bold) << "Host" << ConsoleColorTag(Console_Normal)
|
||||
<< " '" << ConsoleColorTag(Console_ForegroundBlue | Console_Bold) << host_name << ConsoleColorTag(Console_Normal) << "')";
|
||||
|
||||
|
@ -205,9 +206,9 @@ bool RepositoryUtility::AddObject(const String& name, const String& type, const
|
|||
String pattern;
|
||||
|
||||
if (type == "Service")
|
||||
pattern = attrs->Get("host_name") + "/" + name + ".conf";
|
||||
pattern = EscapeName(attrs->Get("host_name")) + "/" + EscapeName(name) + ".conf";
|
||||
else
|
||||
pattern = name + ".conf";
|
||||
pattern = EscapeName(name) + ".conf";
|
||||
|
||||
BOOST_FOREACH(const String& object_path, object_paths) {
|
||||
if (object_path.Contains(pattern)) {
|
||||
|
@ -421,14 +422,14 @@ Dictionary::Ptr RepositoryUtility::GetObjectFromRepositoryChangeLog(const String
|
|||
/* internal implementation when changes are committed */
|
||||
bool RepositoryUtility::AddObjectInternal(const String& name, const String& type, const Dictionary::Ptr& attrs)
|
||||
{
|
||||
String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + name + ".conf";
|
||||
String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + EscapeName(name) + ".conf";
|
||||
|
||||
return WriteObjectToRepository(path, name, type, attrs);
|
||||
}
|
||||
|
||||
bool RepositoryUtility::RemoveObjectInternal(const String& name, const String& type, const Dictionary::Ptr& attrs)
|
||||
{
|
||||
String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + name + ".conf";
|
||||
String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + EscapeName(name) + ".conf";
|
||||
|
||||
if (!Utility::PathExists(path)) {
|
||||
Log(LogWarning, "cli")
|
||||
|
@ -492,7 +493,7 @@ bool RepositoryUtility::RemoveObjectFileInternal(const String& path)
|
|||
bool RepositoryUtility::SetObjectAttributeInternal(const String& name, const String& type, const String& key, const Value& val, const Dictionary::Ptr& attrs)
|
||||
{
|
||||
//TODO
|
||||
String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + name + ".conf";
|
||||
String path = GetRepositoryObjectConfigPath(type, attrs) + "/" + EscapeName(name) + ".conf";
|
||||
|
||||
Dictionary::Ptr obj = GetObjectFromRepository(path); //TODO
|
||||
|
||||
|
@ -550,6 +551,15 @@ Dictionary::Ptr RepositoryUtility::GetObjectFromRepository(const String& filenam
|
|||
return Dictionary::Ptr();
|
||||
}
|
||||
|
||||
String RepositoryUtility::EscapeName(const String& name)
|
||||
{
|
||||
return Utility::EscapeString(name, "<>:\"/\\|?*");
|
||||
}
|
||||
|
||||
String RepositoryUtility::UnescapeName(const String& name)
|
||||
{
|
||||
return Utility::UnescapeString(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* collect functions
|
||||
|
|
|
@ -95,6 +95,9 @@ private:
|
|||
static void SerializeObject(std::ostream& fp, const String& name, const String& type, const Dictionary::Ptr& object);
|
||||
static void FormatValue(std::ostream& fp, const Value& val);
|
||||
static void FormatArray(std::ostream& fp, const Array::Ptr& arr);
|
||||
|
||||
static String EscapeName(const String& name);
|
||||
static String UnescapeName(const String& name);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue