3 Copyright (C) 2013 PilzAdam <pilzadam@minetest.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "lua_api/l_settings.h"
21 #include "lua_api/l_internal.h"
22 #include "cpp_api/s_security.h"
28 #define SET_SECURITY_CHECK(L, name) \
29 if (o->m_settings == g_settings && ScriptApiSecurity::isSecure(L) && \
30 name.compare(0, 7, "secure.") == 0) { \
31 throw LuaError("Attempt to set secure setting."); \
34 LuaSettings::LuaSettings(Settings *settings, const std::string &filename) :
40 LuaSettings::LuaSettings(const std::string &filename, bool write_allowed) :
42 m_is_own_settings(true),
43 m_write_allowed(write_allowed)
45 m_settings = new Settings();
46 m_settings->readConfigFile(filename.c_str());
49 LuaSettings::~LuaSettings()
51 if (m_is_own_settings)
56 void LuaSettings::create(lua_State *L, Settings *settings,
57 const std::string &filename)
59 LuaSettings *o = new LuaSettings(settings, filename);
60 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
61 luaL_getmetatable(L, className);
62 lua_setmetatable(L, -2);
67 int LuaSettings::gc_object(lua_State* L)
69 LuaSettings* o = *(LuaSettings **)(lua_touserdata(L, 1));
75 // get(self, key) -> value
76 int LuaSettings::l_get(lua_State* L)
79 LuaSettings* o = checkobject(L, 1);
81 std::string key = std::string(luaL_checkstring(L, 2));
82 if (o->m_settings->exists(key)) {
83 std::string value = o->m_settings->get(key);
84 lua_pushstring(L, value.c_str());
92 // get_bool(self, key) -> boolean
93 int LuaSettings::l_get_bool(lua_State* L)
96 LuaSettings* o = checkobject(L, 1);
98 std::string key = std::string(luaL_checkstring(L, 2));
99 if (o->m_settings->exists(key)) {
100 bool value = o->m_settings->getBool(key);
101 lua_pushboolean(L, value);
103 // Push default value
104 if (lua_isboolean(L, 3))
105 lua_pushboolean(L, readParam<bool>(L, 3));
113 // get_np_group(self, key) -> value
114 int LuaSettings::l_get_np_group(lua_State *L)
116 NO_MAP_LOCK_REQUIRED;
117 LuaSettings *o = checkobject(L, 1);
119 std::string key = std::string(luaL_checkstring(L, 2));
120 if (o->m_settings->exists(key)) {
122 o->m_settings->getNoiseParams(key, np);
123 push_noiseparams(L, &np);
131 // set(self, key, value)
132 int LuaSettings::l_set(lua_State* L)
134 NO_MAP_LOCK_REQUIRED;
135 LuaSettings* o = checkobject(L, 1);
137 std::string key = std::string(luaL_checkstring(L, 2));
138 const char* value = luaL_checkstring(L, 3);
140 SET_SECURITY_CHECK(L, key);
142 if (!o->m_settings->set(key, value))
143 throw LuaError("Invalid sequence found in setting parameters");
148 // set_bool(self, key, value)
149 int LuaSettings::l_set_bool(lua_State* L)
151 NO_MAP_LOCK_REQUIRED;
152 LuaSettings* o = checkobject(L, 1);
154 std::string key = std::string(luaL_checkstring(L, 2));
155 bool value = readParam<bool>(L, 3);
157 SET_SECURITY_CHECK(L, key);
159 o->m_settings->setBool(key, value);
164 // set(self, key, value)
165 int LuaSettings::l_set_np_group(lua_State *L)
167 NO_MAP_LOCK_REQUIRED;
168 LuaSettings *o = checkobject(L, 1);
170 std::string key = std::string(luaL_checkstring(L, 2));
172 read_noiseparams(L, 3, &value);
174 SET_SECURITY_CHECK(L, key);
176 o->m_settings->setNoiseParams(key, value, false);
181 // remove(self, key) -> success
182 int LuaSettings::l_remove(lua_State* L)
184 NO_MAP_LOCK_REQUIRED;
185 LuaSettings* o = checkobject(L, 1);
187 std::string key = std::string(luaL_checkstring(L, 2));
189 SET_SECURITY_CHECK(L, key);
191 bool success = o->m_settings->remove(key);
192 lua_pushboolean(L, success);
197 // get_names(self) -> {key1, ...}
198 int LuaSettings::l_get_names(lua_State* L)
200 NO_MAP_LOCK_REQUIRED;
201 LuaSettings* o = checkobject(L, 1);
203 std::vector<std::string> keys = o->m_settings->getNames();
206 for (unsigned int i=0; i < keys.size(); i++)
208 lua_pushstring(L, keys[i].c_str());
209 lua_rawseti(L, -2, i + 1);
215 // write(self) -> success
216 int LuaSettings::l_write(lua_State* L)
218 NO_MAP_LOCK_REQUIRED;
219 LuaSettings* o = checkobject(L, 1);
221 if (!o->m_write_allowed) {
222 throw LuaError("Settings: writing " + o->m_filename +
223 " not allowed with mod security on.");
226 bool success = o->m_settings->updateConfigFile(o->m_filename.c_str());
227 lua_pushboolean(L, success);
232 // to_table(self) -> {[key1]=value1,...}
233 int LuaSettings::l_to_table(lua_State* L)
235 NO_MAP_LOCK_REQUIRED;
236 LuaSettings* o = checkobject(L, 1);
238 std::vector<std::string> keys = o->m_settings->getNames();
241 for (const std::string &key : keys) {
242 lua_pushstring(L, o->m_settings->get(key).c_str());
243 lua_setfield(L, -2, key.c_str());
250 void LuaSettings::Register(lua_State* L)
253 int methodtable = lua_gettop(L);
254 luaL_newmetatable(L, className);
255 int metatable = lua_gettop(L);
257 lua_pushliteral(L, "__metatable");
258 lua_pushvalue(L, methodtable);
259 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
261 lua_pushliteral(L, "__index");
262 lua_pushvalue(L, methodtable);
263 lua_settable(L, metatable);
265 lua_pushliteral(L, "__gc");
266 lua_pushcfunction(L, gc_object);
267 lua_settable(L, metatable);
269 lua_pop(L, 1); // drop metatable
271 luaL_openlib(L, 0, methods, 0); // fill methodtable
272 lua_pop(L, 1); // drop methodtable
274 // Can be created from Lua (Settings(filename))
275 lua_register(L, className, create_object);
278 // LuaSettings(filename)
279 // Creates a LuaSettings and leaves it on top of the stack
280 int LuaSettings::create_object(lua_State* L)
282 NO_MAP_LOCK_REQUIRED;
283 bool write_allowed = true;
284 const char* filename = luaL_checkstring(L, 1);
285 CHECK_SECURE_PATH_POSSIBLE_WRITE(L, filename, &write_allowed);
286 LuaSettings* o = new LuaSettings(filename, write_allowed);
287 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
288 luaL_getmetatable(L, className);
289 lua_setmetatable(L, -2);
293 LuaSettings* LuaSettings::checkobject(lua_State* L, int narg)
295 NO_MAP_LOCK_REQUIRED;
296 luaL_checktype(L, narg, LUA_TUSERDATA);
297 void *ud = luaL_checkudata(L, narg, className);
299 luaL_typerror(L, narg, className);
300 return *(LuaSettings**) ud; // unbox pointer
303 const char LuaSettings::className[] = "Settings";
304 const luaL_Reg LuaSettings::methods[] = {
305 luamethod(LuaSettings, get),
306 luamethod(LuaSettings, get_bool),
307 luamethod(LuaSettings, get_np_group),
308 luamethod(LuaSettings, set),
309 luamethod(LuaSettings, set_bool),
310 luamethod(LuaSettings, set_np_group),
311 luamethod(LuaSettings, remove),
312 luamethod(LuaSettings, get_names),
313 luamethod(LuaSettings, write),
314 luamethod(LuaSettings, to_table),