]> git.ipfire.org Git - thirdparty/pdns.git/blame - modules/luabackend/lua_functions.cc
Logging: have a global g_log
[thirdparty/pdns.git] / modules / luabackend / lua_functions.cc
CommitLineData
e18dbde1 1/*
12471842
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 * originally authored by Fredrik Danerklint
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
9 *
10 * In addition, for the avoidance of any doubt, permission is granted to
11 * link this program with OpenSSL and to (re)distribute the binaries
12 * produced as the result of such linking.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
e18dbde1
BH
23#define LUABACKEND_EXTERN_F_HH
24
870a0fe4
AT
25#ifdef HAVE_CONFIG_H
26#include "config.h"
27#endif
e18dbde1
BH
28#include "luabackend.hh"
29
30#include "pdns/logger.hh"
31#include "pdns/arguments.hh"
32#include "pdns/dnspacket.hh"
33
34#include <iostream>
35#include <sstream>
36using namespace std;
37
c03d545e
WO
38// It seems we don't want the coroutine standard library so we can't use
39// luaL_openlibs(). FIXME: is the coroutine library really that bad?
e18dbde1 40const luaL_Reg lualibs[] = {
c03d545e 41#if LUA_VERSION_NUM < 502
e18dbde1 42 {"", luaopen_base},
c03d545e
WO
43#else
44 {"_G", luaopen_base},
45#endif
e18dbde1
BH
46 {LUA_LOADLIBNAME, luaopen_package},
47 {LUA_TABLIBNAME, luaopen_table},
48 {LUA_IOLIBNAME, luaopen_io},
49 {LUA_OSLIBNAME, luaopen_os},
50 {LUA_STRLIBNAME, luaopen_string},
51 {LUA_MATHLIBNAME, luaopen_math},
52 {LUA_DBLIBNAME, luaopen_debug},
c03d545e
WO
53#if LUA_VERSION_NUM == 502 || defined(LUA_COMPAT_BITLIB)
54 {LUA_BITLIBNAME, luaopen_bit32},
55#endif
56#if LUA_VERSION_NUM == 503
57 {LUA_UTF8LIBNAME, luaopen_utf8},
58#endif
e18dbde1 59// {LUA_COLIBNAME, luaopen_coroutine},
119bcf6c 60#ifdef USE_LUAJIT
e18dbde1
BH
61 {"bit", luaopen_bit},
62 {"jit", luaopen_jit},
63#endif
64 {NULL, NULL}
65};
66
67int my_lua_panic (lua_State *lua) {
119bcf6c 68 lua_getfield(lua, LUA_REGISTRYINDEX, "__LUABACKEND");
e18dbde1 69 LUABackend* lb = (LUABackend*)lua_touserdata(lua, -1);
119bcf6c 70
e18dbde1 71 assert(lua == lb->lua);
119bcf6c 72
e18dbde1 73 stringstream e;
119bcf6c 74
e18dbde1 75 e << lb->backend_name << "LUA PANIC! '" << lua_tostring(lua,-1) << "'" << endl;
119bcf6c 76
e18dbde1 77 throw LUAException (e.str());
119bcf6c 78
e18dbde1
BH
79 return 0;
80}
81
82int l_arg_get (lua_State *lua) {
83 int i = lua_gettop(lua);
84 if (i < 1)
85 return 0;
119bcf6c
PD
86
87 lua_getfield(lua, LUA_REGISTRYINDEX, "__LUABACKEND");
e18dbde1
BH
88 LUABackend* lb = (LUABackend*)lua_touserdata(lua, -1);
89
90 string a = lua_tostring(lua, 1);
91
92 if (::arg().isEmpty(a))
93 lua_pushnil(lua);
119bcf6c 94 else
e18dbde1
BH
95 lua_pushstring(lua, lb->my_getArg(a).c_str());
96
97 return 1;
98}
99
100int l_arg_mustdo (lua_State *lua) {
101 int i = lua_gettop(lua);
102 if (i < 1)
103 return 0;
119bcf6c
PD
104
105 lua_getfield(lua, LUA_REGISTRYINDEX, "__LUABACKEND");
e18dbde1 106 LUABackend* lb = (LUABackend*)lua_touserdata(lua, -1);
119bcf6c 107
e18dbde1
BH
108 string a = lua_tostring(lua, 1);
109
110 if (::arg().isEmpty(a))
111 lua_pushnil(lua);
119bcf6c 112 else
e18dbde1
BH
113 lua_pushboolean(lua, lb->my_mustDo(a));
114
115 return 1;
116}
117
118int l_dnspacket (lua_State *lua) {
119bcf6c 119 lua_getfield(lua, LUA_REGISTRYINDEX, "__LUABACKEND");
e18dbde1
BH
120 LUABackend* lb = (LUABackend*)lua_touserdata(lua, -1);
121
122 if (lb->dnspacket == NULL) {
123 lua_pushnil(lua);
119bcf6c 124
e18dbde1
BH
125 return 1;
126 }
127
ded6b08d 128 lua_pushstring(lua, lb->dnspacket->getRemote().toString().c_str());
c03d545e 129 lua_pushinteger(lua, lb->dnspacket->getRemotePort());
ded6b08d 130 lua_pushstring(lua, lb->dnspacket->getLocal().toString().c_str());
25d96f49 131 lua_pushstring(lua, lb->dnspacket->getRealRemote().toString().c_str());
119bcf6c 132
25d96f49 133 return 4;
e18dbde1
BH
134}
135
136int l_logger (lua_State *lua) {
137// assert(lua == lb->lua);
119bcf6c 138
e18dbde1
BH
139 int i = lua_gettop(lua);
140 if (i < 1)
d1d5e3de
PD
141 return 0;
142
143 lua_getfield(lua, LUA_REGISTRYINDEX, "__LUABACKEND");
144 LUABackend* lb = (LUABackend*)lua_touserdata(lua, -1);
e18dbde1
BH
145
146 int log_level = 0;
147 stringstream s;
148 int j;
149 const char *ss;
150
151 log_level = lua_tointeger(lua, 1);
119bcf6c 152
e18dbde1 153 string space = "";
119bcf6c 154
e18dbde1
BH
155 for(j=2; j<=i; j++) {
156 ss = lua_tostring(lua, j);
157 s << space << ss;
158 space = " ";
159 }
119bcf6c 160
e6a9dde5 161 g_log.log(lb->backend_name + s.str(), (Logger::Urgency) log_level);
119bcf6c 162
e18dbde1
BH
163 return 0;
164}
165
166void register_lua_functions(lua_State *lua) {
119bcf6c 167 lua_gc(lua, LUA_GCSTOP, 0); // stop collector during initialization
e18dbde1
BH
168
169 const luaL_Reg *lib = lualibs;
170 for (; lib->func; lib++) {
c03d545e 171#if LUA_VERSION_NUM < 502
e18dbde1
BH
172 lua_pushcfunction(lua, lib->func);
173 lua_pushstring(lua, lib->name);
174 lua_call(lua, 1, 0);
c03d545e
WO
175#else
176 luaL_requiref(lua, lib->name, lib->func, 1);
177 lua_pop(lua, 1); /* remove lib */
178#endif
e18dbde1
BH
179 }
180
181 lua_gc(lua, LUA_GCRESTART, 0);
182
183 lua_pushinteger(lua, Logger::All);
184 lua_setglobal(lua, "log_all");
185
e18dbde1
BH
186 lua_pushinteger(lua, Logger::Alert);
187 lua_setglobal(lua, "log_alert");
188
189 lua_pushinteger(lua, Logger::Critical);
190 lua_setglobal(lua, "log_critical");
191
192 lua_pushinteger(lua, Logger::Error);
193 lua_setglobal(lua, "log_error");
194
195 lua_pushinteger(lua, Logger::Warning);
196 lua_setglobal(lua, "log_warning");
197
198 lua_pushinteger(lua, Logger::Notice);
199 lua_setglobal(lua, "log_notice");
200
201 lua_pushinteger(lua, Logger::Info);
202 lua_setglobal(lua, "log_info");
119bcf6c 203
e18dbde1
BH
204 lua_pushinteger(lua, Logger::Debug);
205 lua_setglobal(lua, "log_debug");
206
207 lua_pushinteger(lua, Logger::None);
208 lua_setglobal(lua, "log_none");
119bcf6c 209
e18dbde1
BH
210 lua_pushcfunction(lua, l_dnspacket);
211 lua_setglobal(lua, "dnspacket");
119bcf6c 212
e18dbde1
BH
213 lua_pushcfunction(lua, l_logger);
214 lua_setglobal(lua, "logger");
215
216 lua_pushcfunction(lua, l_arg_get);
217 lua_setglobal(lua, "getarg");
218
219 lua_pushcfunction(lua, l_arg_mustdo);
220 lua_setglobal(lua, "mustdo");
119bcf6c 221
e18dbde1
BH
222 lua_newtable(lua);
223 for(vector<QType::namenum>::const_iterator iter = QType::names.begin(); iter != QType::names.end(); ++iter) {
c03d545e 224 lua_pushinteger(lua, iter->second);
e18dbde1
BH
225 lua_setfield(lua, -2, iter->first.c_str());
226 }
c03d545e 227 lua_pushinteger(lua, 3);
e18dbde1
BH
228 lua_setfield(lua, -2, "NXDOMAIN");
229 lua_setglobal(lua, "QTypes");
230}
231
232bool LUABackend::getValueFromTable(lua_State *lua, const std::string& key, string& value) {
119bcf6c
PD
233 lua_pushstring(lua, key.c_str());
234 lua_gettable(lua, -2);
e18dbde1
BH
235
236 bool ret = false;
119bcf6c 237
e18dbde1
BH
238 if(!lua_isnil(lua, -1)) {
239 value = lua_tostring(lua, -1);
240 ret = true;
241 }
119bcf6c
PD
242
243 lua_pop(lua, 1);
244
245 return ret;
246}
247
248bool LUABackend::getValueFromTable(lua_State *lua, const std::string& key, DNSName& value) {
249 lua_pushstring(lua, key.c_str());
250 lua_gettable(lua, -2);
251
252 bool ret = false;
253
254 if(!lua_isnil(lua, -1)) {
255 value = DNSName(lua_tostring(lua, -1));
256 ret = true;
257 }
258
e18dbde1 259 lua_pop(lua, 1);
119bcf6c 260
e18dbde1
BH
261 return ret;
262}
263
264bool LUABackend::getValueFromTable(lua_State *lua, uint32_t key, string& value) {
c03d545e 265 lua_pushinteger(lua, key);
119bcf6c 266 lua_gettable(lua, -2);
e18dbde1
BH
267
268 bool ret = false;
119bcf6c 269
e18dbde1
BH
270 if(!lua_isnil(lua, -1)) {
271 value = lua_tostring(lua, -1);
272 ret = true;
273 }
119bcf6c 274
e18dbde1 275 lua_pop(lua, 1);
119bcf6c 276
e18dbde1
BH
277 return ret;
278}
279
5bccee1c 280#if !(defined(__i386__) && defined(__FreeBSD__))
e18dbde1 281bool LUABackend::getValueFromTable(lua_State *lua, const std::string& key, time_t& value) {
119bcf6c
PD
282 lua_pushstring(lua, key.c_str());
283 lua_gettable(lua, -2);
e18dbde1
BH
284
285 bool ret = false;
119bcf6c 286
e18dbde1
BH
287 if(!lua_isnil(lua, -1)) {
288 value = (time_t)lua_tonumber(lua, -1);
289 ret = true;
290 }
119bcf6c 291
e18dbde1 292 lua_pop(lua, 1);
119bcf6c 293
e18dbde1
BH
294 return ret;
295}
2d2eb2a6 296#endif
e18dbde1
BH
297
298bool LUABackend::getValueFromTable(lua_State *lua, const std::string& key, uint32_t& value) {
119bcf6c
PD
299 lua_pushstring(lua, key.c_str());
300 lua_gettable(lua, -2);
e18dbde1
BH
301
302 bool ret = false;
119bcf6c 303
e18dbde1 304 if(!lua_isnil(lua, -1)) {
7b7f06d7 305 value = (uint32_t)lua_tointeger(lua, -1);
e18dbde1
BH
306 ret = true;
307 }
119bcf6c 308
e18dbde1 309 lua_pop(lua, 1);
119bcf6c 310
e18dbde1
BH
311 return ret;
312}
313
314bool LUABackend::getValueFromTable(lua_State *lua, const std::string& key, uint16_t& value) {
119bcf6c
PD
315 lua_pushstring(lua, key.c_str());
316 lua_gettable(lua, -2);
e18dbde1
BH
317
318 bool ret = false;
119bcf6c 319
e18dbde1 320 if(!lua_isnil(lua, -1)) {
7b7f06d7 321 value = (uint16_t)lua_tointeger(lua, -1);
e18dbde1
BH
322 ret = true;
323 }
119bcf6c 324
e18dbde1 325 lua_pop(lua, 1);
119bcf6c 326
e18dbde1
BH
327 return ret;
328}
329
25d96f49
M
330bool LUABackend::getValueFromTable(lua_State *lua, const std::string& key, uint8_t& value) {
331 lua_pushstring(lua, key.c_str());
332 lua_gettable(lua, -2);
333
334 bool ret = false;
335
336 if(!lua_isnil(lua, -1)) {
7b7f06d7 337 value = (uint8_t)lua_tointeger(lua, -1);
25d96f49
M
338 ret = true;
339 }
340
341 lua_pop(lua, 1);
342
343 return ret;
344}
345
e18dbde1 346bool LUABackend::getValueFromTable(lua_State *lua, const std::string& key, int& value) {
119bcf6c
PD
347 lua_pushstring(lua, key.c_str());
348 lua_gettable(lua, -2);
e18dbde1
BH
349
350 bool ret = false;
119bcf6c 351
e18dbde1 352 if(!lua_isnil(lua, -1)) {
7b7f06d7 353 value = (int)lua_tointeger(lua, -1);
e18dbde1
BH
354 ret = true;
355 }
119bcf6c 356
e18dbde1 357 lua_pop(lua, 1);
119bcf6c 358
e18dbde1
BH
359 return ret;
360}
361
362bool LUABackend::getValueFromTable(lua_State *lua, const std::string& key, bool& value) {
119bcf6c
PD
363 lua_pushstring(lua, key.c_str());
364 lua_gettable(lua, -2);
e18dbde1
BH
365
366 bool ret = false;
119bcf6c 367
e18dbde1
BH
368 if(!lua_isnil(lua, -1)) {
369 value = lua_toboolean(lua, -1);
370 ret = true;
371 }
119bcf6c 372
e18dbde1 373 lua_pop(lua, 1);
119bcf6c 374
e18dbde1
BH
375 return ret;
376}