static void filter_wrapper(struct thread_state *state, struct packet *pkt) { int h; LUA_STACK_MARK(state->lua->L); packet_addref(pkt); lua_pushcfunction(state->lua->L, lua_state_error_formater); h = lua_gettop(state->lua->L); lua_getglobal(state->lua->L, "haka"); lua_getfield(state->lua->L, -1, "filter"); if (!lua_isnil(state->lua->L, -1)) { if (!lua_pushppacket(state->lua->L, pkt)) { LOG_ERROR(core, "packet internal error"); packet_drop(pkt); } else { if (lua_pcall(state->lua->L, 1, 0, h)) { lua_state_print_error(state->lua->L, "filter"); packet_drop(pkt); } } } else { lua_pop(state->lua->L, 1); packet_drop(pkt); } lua_pop(state->lua->L, 2); LUA_STACK_CHECK(state->lua->L, 0); packet_release(pkt); }
static bool init_thread_lua_state(struct thread_state *state) { int h; LUA_STACK_MARK(state->lua->L); if (state->pool->attach_debugger > state->attach_debugger) { luadebug_debugger_start(state->lua->L, false); } state->pool->attach_debugger = state->attach_debugger; lua_pushcfunction(state->lua->L, lua_state_error_formater); h = lua_gettop(state->lua->L); lua_getglobal(state->lua->L, "require"); lua_pushstring(state->lua->L, "rule"); if (lua_pcall(state->lua->L, 1, 0, h)) { lua_state_print_error(state->lua->L, "init"); lua_pop(state->lua->L, 1); LUA_STACK_CHECK(state->lua->L, 0); return false; } if (!lua_state_run_file(state->lua, get_configuration_script(), 0, NULL)) { lua_pop(state->lua->L, 1); return false; } lua_getglobal(state->lua->L, "haka"); lua_getfield(state->lua->L, -1, "rule_summary"); if (lua_pcall(state->lua->L, 0, 0, h)) { lua_state_print_error(state->lua->L, "init"); lua_pop(state->lua->L, 1); LUA_STACK_CHECK(state->lua->L, 0); return false; } lua_pop(state->lua->L, 2); LUA_STACK_CHECK(state->lua->L, 0); return true; }
int execute_print(lua_State *L, struct luadebug_user *user) { int i, g, h, status; LUA_STACK_MARK(L); g = lua_gettop(L); status = execute_call(L, 0); h = lua_gettop(L) - g + 1; for (i = h; i > 0; --i) { user->print(user, " #%d\t", h-i+1); pprint(L, user, -i, true, "hide_underscore"); } lua_settop(L, g); LUA_STACK_CHECK(L, 0); return status; }
int capture_env(struct lua_State *L, int frame) { int i; const char *local; lua_Debug ar; LUA_STACK_MARK(L); if (!lua_getstack(L, frame, &ar)) { return -1; } lua_getinfo(L, "f", &ar); lua_newtable(L); for (i=1; (local = lua_getlocal(L, &ar, i)); ++i) { lua_setfield(L, -2, local); } for (i=1; (local = lua_getupvalue(L, -2, i)); ++i) { lua_setfield(L, -2, local); } lua_newtable(L); lua_getfenv(L, -3); lua_setfield(L, -2, "__index"); lua_getfenv(L, -3); lua_setfield(L, -2, "__newindex"); lua_setmetatable(L, -2); lua_remove(L, -2); LUA_STACK_CHECK(L, 1); return lua_gettop(L); }
void luadebug_interactive_enter(struct lua_State *L, const char *single, const char *multi, const char *msg) { char *line, *full_line = NULL; bool multiline = false; bool stop = false; struct luadebug_interactive session; { mutex_lock(¤t_user_mutex); session.user = current_user; if (!session.user) { message(HAKA_LOG_ERROR, L"interactive", L"no input/output handler"); mutex_unlock(¤t_user_mutex); return; } luadebug_user_addref(session.user); mutex_unlock(¤t_user_mutex); } mutex_lock(&active_session_mutex); if (!single) single = "> "; if (!multi) multi = ">> "; session.user->completion = completion; if (!session.user->start(session.user, "haka")) { on_user_error(); luadebug_user_release(&session.user); mutex_unlock(&active_session_mutex); return; } current_session = &session; LUA_STACK_MARK(L); session.user->print(session.user, GREEN "entering interactive session" CLEAR ": %s\n", msg); session.L = L; session.env_index = capture_env(L, 1); assert(session.env_index != -1); session.complete.stack_env = session.env_index; while (!stop && (line = session.user->readline(session.user, multiline ? multi : single))) { int status = -1; bool is_return = false; char *current_line; if (multiline) { const size_t full_line_size = strlen(full_line); assert(full_line); full_line = realloc(full_line, full_line_size + 1 + strlen(line) + 1); full_line[full_line_size] = ' '; strcpy(full_line + full_line_size + 1, line); current_line = full_line; } else { session.user->addhistory(session.user, line); current_line = line; } while (*current_line == ' ' || *current_line == '\t') { ++current_line; } is_return = (strncmp(current_line, "return ", 7) == 0) || (strcmp(current_line, "return") == 0); if (!multiline && !is_return) { char *return_line = malloc(7 + strlen(current_line) + 1); strcpy(return_line, "return "); strcpy(return_line+7, current_line); status = luaL_loadbuffer(L, return_line, strlen(return_line), "stdin"); if (status) { lua_pop(L, 1); status = -1; } free(return_line); } if (status == -1) { status = luaL_loadbuffer(L, current_line, strlen(current_line), "stdin"); } multiline = false; /* Change the chunk environment */ lua_pushvalue(L, session.env_index); lua_setfenv(L, -2); if (status == LUA_ERRSYNTAX) { const char *message; const int k = sizeof(EOF_MARKER) / sizeof(char) - 1; size_t n; message = lua_tolstring(L, -1, &n); if (n > k && !strncmp(message + n - k, EOF_MARKER, k) && strlen(line) > 0) { multiline = true; } else { session.user->print(session.user, RED "%s" CLEAR "\n", lua_tostring(L, -1)); } lua_pop(L, 1); } else if (status == LUA_ERRMEM) { session.user->print(session.user, RED "%s" CLEAR "\n", lua_tostring(L, -1)); lua_pop(L, 1); } else { execute_print(L, session.user); lua_pop(L, 1); if (is_return) { stop = true; } } if (!multiline) { free(full_line); full_line = NULL; } else if (!full_line) { full_line = strdup(line); } free(line); } free(full_line); session.user->print(session.user, "\n"); session.user->print(session.user, GREEN "continue" CLEAR "\n"); lua_pop(L, 1); LUA_STACK_CHECK(L, 0); if (!session.user->stop(session.user)) { on_user_error(); } luadebug_user_release(&session.user); current_session = NULL; mutex_unlock(&active_session_mutex); }
void pprint(lua_State *L, struct luadebug_user *user, int index, bool full, const char *hide) { int h; LUA_STACK_MARK(L); lua_getglobal(L, "haka"); lua_getfield(L, -1, "debug"); h = lua_gettop(L); if (user) { lua_getfield(L, h, "__printwrapper"); lua_pushcfunction(L, lua_user_print); lua_pushlightuserdata(L, user); if (lua_pcall(L, 2, 1, 0)) { user->print(user, CLEAR RED "error: %s\n" CLEAR, lua_tostring(L, -1)); lua_settop(L, h-2); LUA_STACK_CHECK(L, 0); return; } } lua_getfield(L, h, "pprint"); /* obj */ if (index < 0) { lua_pushvalue(L, h-1+index); } else { lua_pushvalue(L, index); } /* indent */ lua_pushstring(L, " \t"); /* depth */ if (!full) { lua_pushnumber(L, 1); } else { lua_pushnil(L); } /* hide */ if (hide) { lua_getfield(L, h, "hide_underscore"); } else { lua_pushnil(L); } /* out */ if (user) { lua_pushvalue(L, h+1); } else { lua_pushnil(L); } if (lua_pcall(L, 5, 0, 0)) { user->print(user, CLEAR RED "error: %s\n" CLEAR, lua_tostring(L, -1)); lua_pop(L, 1); } lua_settop(L, h-2); LUA_STACK_CHECK(L, 0); }