}
+void pushLuaTable(lua_State* lua, const vector<pair<string,string>>& table)
+{
+ lua_newtable(lua);
+ int pos=0;
+ for(const auto& e : table) {
+ lua_pushstring(lua, e.second.c_str());
+ lua_setfield(lua, -2, e.first.c_str());
+ }
+}
+
+vector<pair<string,string>> getLuaTable(lua_State* lua, int index)
+{
+ vector<pair<string,string>> ret;
+ // Push another reference to the table on top of the stack (so we know
+ // where it is, and this function can work for negative, positive and
+ // pseudo indices
+ lua_pushvalue(lua, index);
+ // stack now contains: -1 => table
+ lua_pushnil(lua);
+ // stack now contains: -1 => nil; -2 => table
+ while (lua_next(lua, -2)) {
+ // stack now contains: -1 => value; -2 => key; -3 => table
+ // copy the key so that lua_tostring does not modify the original
+ lua_pushvalue(lua, -2);
+ // stack now contains: -1 => key; -2 => value; -3 => key; -4 => table
+ const char *key = lua_tostring(lua, -1);
+ const char *value = lua_tostring(lua, -2);
+ ret.push_back({key,value});
+ // pop value + copy of key, leaving original key
+ lua_pop(lua, 2);
+ // stack now contains: -1 => key; -2 => table
+ }
+ // stack now contains: -1 => table (when lua_next returns 0 it pops the key
+ // but does not push anything.)
+ // Pop table
+ lua_pop(lua, 1);
+ // Stack is now the same as it was on entry to this function
+ return ret;
+}
+
void pushResourceRecordsTable(lua_State* lua, const vector<DNSRecord>& records)
{
void popResourceRecordsTable(lua_State *lua, const DNSName &query, vector<DNSRecord>& ret);
void pushSyslogSecurityLevelTable(lua_State *lua);
int getLuaTableLength(lua_State* lua, int depth);
+std::vector<std::pair<std::string, std::string>> getLuaTable(lua_State* lua, int index=0);
+void pushLuaTable(lua_State* lua, const vector<pair<string,string>>& table);
void luaStackDump (lua_State *lua);
extern "C" int luaopen_iputils(lua_State*);
#endif
string callback;
getFromTable("callback", callback);
- lua_remove(d_lua, -2);
-
- // XXX THIS IS PLAIN WRONG - WE LEAVE STUFF ON THE LUA STACK AND EXPECT IT TO STILL BE HERE WHEN WE GET BACK!
+ auto table = getLuaTable(d_lua, -1);
+ lua_pop(d_lua, 2);
string answer = GenUDPQueryResponse(ComboAddress(dest), uquery);
lua_getglobal(d_lua, callback.c_str());
lua_pushstring(d_lua, remote.toString().c_str() );
lua_pushstring(d_lua, query.toString().c_str() );
lua_pushnumber(d_lua, qtype.getCode() );
-
- lua_pushvalue(d_lua, -5);
- lua_remove(d_lua, -6);
-
- lua_pushstring(d_lua, answer.c_str());
- lua_setfield(d_lua, -2, "response");
+ table.push_back({"response", answer});
+ pushLuaTable(d_lua, table);
if(lua_pcall(d_lua, 4, 3, 0)) { // NOTE! Means we always get 3 stack entries back, no matter what our lua hook returned!
string error=string("lua error in '"+func+"' while callback for '"+query.toString()+"|"+qtype.getName()+": ")+lua_tostring(d_lua, -1);