diff options
author | Matthew Wild <mwild1@gmail.com> | 2020-06-01 15:42:19 +0100 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2020-06-01 15:42:19 +0100 |
commit | 4c6992a00e582dc2c9c6a7ad721cd7e831202a1e (patch) | |
tree | 80b6f729c4bba52b4bf8de06b658c03048a6abd1 /plugins | |
parent | 6ccd66e347747b0fd7b2a193a777b46d913c38ee (diff) | |
download | prosody-4c6992a00e582dc2c9c6a7ad721cd7e831202a1e.tar.gz prosody-4c6992a00e582dc2c9c6a7ad721cd7e831202a1e.zip |
mod_admin_socket, util.adminstream: New module to manage a local unix domain socket for admin functionality
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/mod_admin_socket.lua | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/plugins/mod_admin_socket.lua b/plugins/mod_admin_socket.lua new file mode 100644 index 00000000..c094aad2 --- /dev/null +++ b/plugins/mod_admin_socket.lua @@ -0,0 +1,69 @@ +module:set_global(); + +local have_unix, unix = pcall(require, "socket.unix"); + +if not have_unix or type(unix) ~= "table" then + module:log_status("error", "LuaSocket unix socket support not available or incompatible, ensure it is up to date"); + return; +end + +local server = require "net.server"; + +local adminstream = require "util.adminstream"; + +local socket_path = module:get_option_string("admin_socket", prosody.paths.data.."/prosody.sock"); + +local sessions = module:shared("sessions"); + +local function fire_admin_event(session, stanza) + local event_data = { + origin = session, stanza = stanza; + }; + local event_name; + if stanza.attr.xmlns then + event_name = "admin/"..stanza.attr.xmlns..":"..stanza.name; + else + event_name = "admin/"..stanza.name; + end + module:log("debug", "Firing %s", event_name); + return module:fire_event(event_name, event_data); +end + +module:hook("server-stopping", function () + for _, session in pairs(sessions) do + session:close("system-shutdown"); + end + os.remove(socket_path); +end); + +--- Unix domain socket management + +local conn, sock; + +local listeners = adminstream.server(sessions, fire_admin_event).listeners; + +local function accept_connection() + module:log("debug", "accepting..."); + local client = sock:accept(); + if not client then return; end + server.wrapclient(client, "unix", 0, listeners, "*a"); +end + +function module.load() + sock = unix.stream(); + sock:settimeout(0); + os.remove(socket_path); + assert(sock:bind(socket_path)); + assert(sock:listen()); + conn = server.watchfd(sock:getfd(), accept_connection); +end + +function module.unload() + if conn then + conn:close(); + end + if sock then + sock:close(); + end + os.remove(socket_path); +end |