degesch: refactor Lua
And fix handling of nil returns from filter callbacks.
This commit is contained in:
parent
e1c7b8dcaf
commit
a7be2bf160
149
degesch.c
149
degesch.c
|
@ -7601,7 +7601,7 @@ static luaL_Reg lua_hook_table[] =
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
// Append a traceback to all errors so that we can later extract it
|
/// Append a traceback to all errors so that we can later extract it
|
||||||
static int
|
static int
|
||||||
lua_plugin_error_handler (lua_State *L)
|
lua_plugin_error_handler (lua_State *L)
|
||||||
{
|
{
|
||||||
|
@ -7632,16 +7632,33 @@ lua_plugin_process_error (struct lua_plugin *self, const char *message,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience function; replaces the "original" string or produces an error
|
/// Call a Lua function and process errors using our special error handler
|
||||||
static bool
|
static bool
|
||||||
lua_plugin_handle_string_filter_result (struct lua_plugin *self,
|
lua_plugin_call (struct lua_plugin *self,
|
||||||
int result, char **original, bool utf8, struct error **e)
|
int n_params, int n_results, struct error **e)
|
||||||
|
{
|
||||||
|
lua_State *L = self->L;
|
||||||
|
lua_pushcfunction (L, lua_plugin_error_handler);
|
||||||
|
|
||||||
|
int error_handler_idx = -n_params - 2;
|
||||||
|
lua_insert (L, error_handler_idx);
|
||||||
|
|
||||||
|
if (!lua_pcall (L, n_params, n_results, error_handler_idx))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
(void) lua_plugin_process_error (self, lua_tostring (L, -1), e);
|
||||||
|
lua_pop (L, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience function; replaces the "original" string or produces an error
|
||||||
|
static bool
|
||||||
|
lua_plugin_handle_string_filter_result (struct lua_plugin *self,
|
||||||
|
char **original, bool utf8, struct error **e)
|
||||||
{
|
{
|
||||||
lua_State *L = self->L;
|
lua_State *L = self->L;
|
||||||
if (result)
|
|
||||||
return lua_plugin_process_error (self, lua_tostring (L, -1), e);
|
|
||||||
if (lua_isnil (L, -1))
|
if (lua_isnil (L, -1))
|
||||||
return NULL;
|
return true;
|
||||||
if (!lua_isstring (L, -1))
|
if (!lua_isstring (L, -1))
|
||||||
FAIL ("must return either a string or nil");
|
FAIL ("must return either a string or nil");
|
||||||
|
|
||||||
|
@ -7659,6 +7676,15 @@ lua_plugin_handle_string_filter_result (struct lua_plugin *self,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
lua_plugin_log_error
|
||||||
|
(struct lua_plugin *self, const char *where, struct error *error)
|
||||||
|
{
|
||||||
|
log_global_error (self->ctx, "Lua: plugin \"#s\": #s: #s",
|
||||||
|
self->super.name, where, error->message);
|
||||||
|
error_free (error);
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
|
@ -7670,24 +7696,19 @@ lua_input_hook_filter (struct input_hook *self, struct buffer *buffer,
|
||||||
struct lua_plugin *plugin = hook->plugin;
|
struct lua_plugin *plugin = hook->plugin;
|
||||||
lua_State *L = plugin->L;
|
lua_State *L = plugin->L;
|
||||||
|
|
||||||
lua_pushcfunction (L, lua_plugin_error_handler);
|
|
||||||
|
|
||||||
lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback);
|
lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback);
|
||||||
lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook
|
lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook
|
||||||
lua_plugin_push_buffer (plugin, buffer); // 2: buffer
|
lua_plugin_push_buffer (plugin, buffer); // 2: buffer
|
||||||
lua_pushstring (L, input); // 3: input
|
lua_pushstring (L, input); // 3: input
|
||||||
|
|
||||||
struct error *e = NULL;
|
struct error *e = NULL;
|
||||||
bool failed = !lua_plugin_handle_string_filter_result
|
if (lua_plugin_call (plugin, 3, 1, &e))
|
||||||
(plugin, lua_pcall (L, 3, 1, -5), &input, true, &e);
|
|
||||||
lua_pop (L, 1);
|
|
||||||
|
|
||||||
if (failed)
|
|
||||||
{
|
{
|
||||||
log_global_error (plugin->ctx, "Lua: plugin \"#s\": #s: #s",
|
lua_plugin_handle_string_filter_result (plugin, &input, true, &e);
|
||||||
plugin->super.name, "input hook", e->message);
|
lua_pop (L, 1);
|
||||||
error_free (e);
|
|
||||||
}
|
}
|
||||||
|
if (e)
|
||||||
|
lua_plugin_log_error (plugin, "input hook", e);
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7706,24 +7727,19 @@ lua_irc_hook_filter (struct irc_hook *self, struct server *s, char *message)
|
||||||
struct lua_plugin *plugin = hook->plugin;
|
struct lua_plugin *plugin = hook->plugin;
|
||||||
lua_State *L = plugin->L;
|
lua_State *L = plugin->L;
|
||||||
|
|
||||||
lua_pushcfunction (L, lua_plugin_error_handler);
|
|
||||||
|
|
||||||
lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback);
|
lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback);
|
||||||
lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook
|
lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook
|
||||||
lua_plugin_push_server (plugin, s); // 2: server
|
lua_plugin_push_server (plugin, s); // 2: server
|
||||||
lua_pushstring (L, message); // 3: message
|
lua_pushstring (L, message); // 3: message
|
||||||
|
|
||||||
struct error *e = NULL;
|
struct error *e = NULL;
|
||||||
bool failed = !lua_plugin_handle_string_filter_result
|
if (lua_plugin_call (plugin, 3, 1, &e))
|
||||||
(plugin, lua_pcall (L, 3, 1, -5), &message, false, &e);
|
|
||||||
lua_pop (L, 1);
|
|
||||||
|
|
||||||
if (failed)
|
|
||||||
{
|
{
|
||||||
log_global_error (plugin->ctx, "Lua: plugin \"#s\": #s: #s",
|
lua_plugin_handle_string_filter_result (plugin, &message, false, &e);
|
||||||
plugin->super.name, "IRC hook", e->message);
|
lua_pop (L, 1);
|
||||||
error_free (e);
|
|
||||||
}
|
}
|
||||||
|
if (e)
|
||||||
|
lua_plugin_log_error (plugin, "IRC hook", e);
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7741,21 +7757,12 @@ lua_timer_hook_dispatch (void *user_data)
|
||||||
struct lua_plugin *plugin = hook->plugin;
|
struct lua_plugin *plugin = hook->plugin;
|
||||||
lua_State *L = plugin->L;
|
lua_State *L = plugin->L;
|
||||||
|
|
||||||
lua_pushcfunction (L, lua_plugin_error_handler);
|
|
||||||
|
|
||||||
lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback);
|
lua_rawgeti (L, LUA_REGISTRYINDEX, hook->ref_callback);
|
||||||
lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook
|
lua_rawgetp (L, LUA_REGISTRYINDEX, hook); // 1: hook
|
||||||
|
|
||||||
if (lua_pcall (L, 1, 0, -3))
|
|
||||||
{
|
|
||||||
struct error *e = NULL;
|
struct error *e = NULL;
|
||||||
(void) lua_plugin_process_error (plugin, lua_tostring (L, -1), &e);
|
if (!lua_plugin_call (plugin, 1, 0, &e))
|
||||||
lua_pop (L, 1);
|
lua_plugin_log_error (plugin, "timer hook", e);
|
||||||
|
|
||||||
log_global_error (plugin->ctx, "Lua: plugin \"#s\": #s: #s",
|
|
||||||
plugin->super.name, "timer hook", e->message);
|
|
||||||
error_free (e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// There's no need to keep the hook around once the timer is dispatched
|
// There's no need to keep the hook around once the timer is dispatched
|
||||||
lua_cache_invalidate (L, hook);
|
lua_cache_invalidate (L, hook);
|
||||||
|
@ -7929,21 +7936,12 @@ lua_schema_item_validate (const struct config_item *item, struct error **e)
|
||||||
if (self->ref_validate == LUA_REFNIL)
|
if (self->ref_validate == LUA_REFNIL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
struct lua_plugin *plugin = self->plugin;
|
lua_State *L = self->plugin->L;
|
||||||
lua_State *L = plugin->L;
|
|
||||||
|
|
||||||
lua_pushcfunction (L, lua_plugin_error_handler);
|
|
||||||
lua_rawgeti (L, LUA_REGISTRYINDEX, self->ref_validate);
|
lua_rawgeti (L, LUA_REGISTRYINDEX, self->ref_validate);
|
||||||
lua_plugin_push_config_item (L, item);
|
lua_plugin_push_config_item (L, item);
|
||||||
|
|
||||||
// The callback can make use of error("...", 0) to produce nice messages
|
// The callback can make use of error("...", 0) to produce nice messages
|
||||||
if (lua_pcall (L, 1, 0, -3))
|
return lua_plugin_call (self->plugin, 1, 0, e);
|
||||||
{
|
|
||||||
(void) lua_plugin_process_error (plugin, lua_tostring (L, -1), e);
|
|
||||||
lua_pop (L, 1);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -7953,23 +7951,13 @@ lua_schema_item_on_change (struct config_item *item)
|
||||||
if (self->ref_on_change == LUA_REFNIL)
|
if (self->ref_on_change == LUA_REFNIL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
struct lua_plugin *plugin = self->plugin;
|
lua_State *L = self->plugin->L;
|
||||||
lua_State *L = plugin->L;
|
|
||||||
|
|
||||||
lua_pushcfunction (L, lua_plugin_error_handler);
|
|
||||||
lua_rawgeti (L, LUA_REGISTRYINDEX, self->ref_on_change);
|
lua_rawgeti (L, LUA_REGISTRYINDEX, self->ref_on_change);
|
||||||
lua_plugin_push_config_item (L, item);
|
lua_plugin_push_config_item (L, item);
|
||||||
|
|
||||||
if (lua_pcall (L, 1, 0, -3))
|
|
||||||
{
|
|
||||||
struct error *e = NULL;
|
struct error *e = NULL;
|
||||||
(void) lua_plugin_process_error (plugin, lua_tostring (L, -1), &e);
|
if (!lua_plugin_call (self->plugin, 1, 0, &e))
|
||||||
lua_pop (L, 1);
|
lua_plugin_log_error (self->plugin, "schema on_change", e);
|
||||||
|
|
||||||
log_global_error (plugin->ctx, "Lua: plugin \"#s\": #s: #s",
|
|
||||||
plugin->super.name, "schema on_change", e->message);
|
|
||||||
error_free (e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -8244,30 +8232,21 @@ static void
|
||||||
lua_connector_on_connected (void *user_data, int socket, const char *hostname)
|
lua_connector_on_connected (void *user_data, int socket, const char *hostname)
|
||||||
{
|
{
|
||||||
struct lua_connector *self = user_data;
|
struct lua_connector *self = user_data;
|
||||||
struct lua_plugin *plugin = self->plugin;
|
|
||||||
lua_State *L = plugin->L;
|
|
||||||
|
|
||||||
// TODO: use this for SNI once TLS is implemented
|
// TODO: use this for SNI once TLS is implemented
|
||||||
(void) hostname;
|
(void) hostname;
|
||||||
|
|
||||||
if (self->ref_on_success != LUA_REFNIL)
|
if (self->ref_on_success != LUA_REFNIL)
|
||||||
{
|
{
|
||||||
lua_pushcfunction (L, lua_plugin_error_handler);
|
lua_State *L = self->plugin->L;
|
||||||
|
|
||||||
lua_rawgeti (L, LUA_REGISTRYINDEX, self->ref_on_success);
|
lua_rawgeti (L, LUA_REGISTRYINDEX, self->ref_on_success);
|
||||||
lua_plugin_push_connection (plugin, socket); // 1: connection
|
lua_plugin_push_connection (self->plugin, socket); // 1: connection
|
||||||
|
|
||||||
if (lua_pcall (L, 1, 0, -3))
|
|
||||||
{
|
|
||||||
struct error *e = NULL;
|
struct error *e = NULL;
|
||||||
(void) lua_plugin_process_error (plugin, lua_tostring (L, -1), &e);
|
if (!lua_plugin_call (self->plugin, 1, 0, &e))
|
||||||
lua_pop (L, 1);
|
lua_plugin_log_error (self->plugin, "connector on_success", e);
|
||||||
|
}
|
||||||
|
|
||||||
log_global_error (plugin->ctx, "Lua: plugin \"#s\": #s: #s",
|
|
||||||
plugin->super.name, "connector on_success", e->message);
|
|
||||||
error_free (e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lua_connector_discard (self);
|
lua_connector_discard (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8275,27 +8254,17 @@ static void
|
||||||
lua_connector_on_failure (void *user_data)
|
lua_connector_on_failure (void *user_data)
|
||||||
{
|
{
|
||||||
struct lua_connector *self = user_data;
|
struct lua_connector *self = user_data;
|
||||||
struct lua_plugin *plugin = self->plugin;
|
|
||||||
lua_State *L = plugin->L;
|
|
||||||
|
|
||||||
if (self->ref_on_error != LUA_REFNIL)
|
if (self->ref_on_error != LUA_REFNIL)
|
||||||
{
|
{
|
||||||
lua_pushcfunction (L, lua_plugin_error_handler);
|
lua_State *L = self->plugin->L;
|
||||||
|
|
||||||
lua_rawgeti (L, LUA_REGISTRYINDEX, self->ref_on_error);
|
lua_rawgeti (L, LUA_REGISTRYINDEX, self->ref_on_error);
|
||||||
lua_pushstring (L, self->last_error); // 1: error string
|
lua_pushstring (L, self->last_error); // 1: error string
|
||||||
|
|
||||||
if (lua_pcall (L, 1, 0, -3))
|
|
||||||
{
|
|
||||||
struct error *e = NULL;
|
struct error *e = NULL;
|
||||||
(void) lua_plugin_process_error (plugin, lua_tostring (L, -1), &e);
|
if (!lua_plugin_call (self->plugin, 1, 0, &e))
|
||||||
lua_pop (L, 1);
|
lua_plugin_log_error (self->plugin, "connector on_error", e);
|
||||||
|
}
|
||||||
|
|
||||||
log_global_error (plugin->ctx, "Lua: plugin \"#s\": #s: #s",
|
|
||||||
plugin->super.name, "connector on_error", e->message);
|
|
||||||
error_free (e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lua_connector_discard (self);
|
lua_connector_discard (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue