]> granicus.if.org Git - icinga2/blob - lib/base/scriptglobal.cpp
Remove unused includes
[icinga2] / lib / base / scriptglobal.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "base/scriptglobal.hpp"
21 #include "base/singleton.hpp"
22 #include "base/logger.hpp"
23 #include "base/stdiostream.hpp"
24 #include "base/netstring.hpp"
25 #include "base/json.hpp"
26 #include "base/convert.hpp"
27 #include "base/objectlock.hpp"
28 #include "base/exception.hpp"
29 #include <boost/algorithm/string/split.hpp>
30 #include <fstream>
31
32 using namespace icinga;
33
34 Dictionary::Ptr ScriptGlobal::m_Globals = new Dictionary();
35
36 Value ScriptGlobal::Get(const String& name, const Value *defaultValue)
37 {
38         Value result;
39
40         if (!m_Globals->Get(name, &result)) {
41                 if (defaultValue)
42                         return *defaultValue;
43
44                 BOOST_THROW_EXCEPTION(std::invalid_argument("Tried to access undefined script variable '" + name + "'"));
45         }
46
47         return result;
48 }
49
50 void ScriptGlobal::Set(const String& name, const Value& value)
51 {
52         std::vector<String> tokens = name.Split(".");
53
54         if (tokens.empty())
55                 BOOST_THROW_EXCEPTION(std::invalid_argument("Name must not be empty"));
56
57         {
58                 ObjectLock olock(m_Globals);
59
60                 Dictionary::Ptr parent = m_Globals;
61
62                 for (std::vector<String>::size_type i = 0; i < tokens.size(); i++) {
63                         const String& token = tokens[i];
64
65                         if (i + 1 != tokens.size()) {
66                                 Value vparent;
67
68                                 if (!parent->Get(token, &vparent)) {
69                                         Dictionary::Ptr dict = new Dictionary();
70                                         parent->Set(token, dict);
71                                         parent = dict;
72                                 } else {
73                                         parent = vparent;
74                                 }
75                         }
76                 }
77
78                 parent->Set(tokens[tokens.size() - 1], value);
79         }
80 }
81
82 bool ScriptGlobal::Exists(const String& name)
83 {
84         return m_Globals->Contains(name);
85 }
86
87 Dictionary::Ptr ScriptGlobal::GetGlobals()
88 {
89         return m_Globals;
90 }
91
92 void ScriptGlobal::WriteToFile(const String& filename)
93 {
94         Log(LogInformation, "ScriptGlobal")
95                 << "Dumping variables to file '" << filename << "'";
96
97         std::fstream fp;
98         String tempFilename = Utility::CreateTempFile(filename + ".XXXXXX", 0600, fp);
99
100         if (!fp)
101                 BOOST_THROW_EXCEPTION(std::runtime_error("Could not open '" + tempFilename + "' file"));
102
103         StdioStream::Ptr sfp = new StdioStream(&fp, false);
104
105         ObjectLock olock(m_Globals);
106         for (const Dictionary::Pair& kv : m_Globals) {
107                 Value value = kv.second;
108
109                 if (value.IsObject())
110                         value = Convert::ToString(value);
111
112                 Dictionary::Ptr persistentVariable = new Dictionary({
113                         { "name", kv.first },
114                         { "value", value }
115                 });
116
117                 String json = JsonEncode(persistentVariable);
118
119                 NetString::WriteStringToStream(sfp, json);
120         }
121
122         sfp->Close();
123
124         fp.close();
125
126 #ifdef _WIN32
127         _unlink(filename.CStr());
128 #endif /* _WIN32 */
129
130         if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
131                 BOOST_THROW_EXCEPTION(posix_error()
132                         << boost::errinfo_api_function("rename")
133                         << boost::errinfo_errno(errno)
134                         << boost::errinfo_file_name(tempFilename));
135         }
136 }
137