Software /
code /
prosody
File
plugins/mod_scansion_record.lua @ 13452:69faf3552d52
mod_posix: Move POSIX signal handling into util.startup to avoid race
When libunbound is initialized, it spawns a thread to work in.
In case a module initializes libunbound, e.g. by triggering a s2s
connection, Prosody would not handle signals, instead immediately quit
on e.g. the reload (SIGHUP) signal. Likely because the libunbound thread
would not have inherited the signal mask from the main Prosody thread.
Thanks Menel, riau and franck-x for reporting and help narrowing down
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 02 Mar 2024 13:23:24 +0100 |
parent | 12977:74b9e05af71e |
line wrap: on
line source
local names = { "Romeo", "Juliet", "Mercutio", "Tybalt", "Benvolio" }; local devices = { "", "phone", "laptop", "tablet", "toaster", "fridge", "shoe" }; local users = {}; local filters = require "prosody.util.filters"; local id = require "prosody.util.id"; local dt = require "prosody.util.datetime"; local dm = require "prosody.util.datamanager"; local st = require "prosody.util.stanza"; local record_id = id.short():lower(); local record_date = os.date("%Y%b%d"):lower(); local header_file = dm.getpath(record_id, "scansion", record_date, "scs", true); local record_file = dm.getpath(record_id, "scansion", record_date, "log", true); local head = io.open(header_file, "w"); local scan = io.open(record_file, "w+"); local function record(string) scan:write(string); scan:flush(); end local function record_header(string) head:write(string); head:flush(); end local function record_object(class, name, props) head:write(("[%s] %s\n"):format(class, name)); for k,v in pairs(props) do head:write(("\t%s: %s\n"):format(k, v)); end head:write("\n"); head:flush(); end local function record_event(session, event) record(session.scansion_id.." "..event.."\n\n"); end local function record_stanza(stanza, session, verb) local flattened = tostring(stanza:indent(2, "\t")); record(session.scansion_id.." "..verb..":\n\t"..flattened.."\n\n"); end local function record_stanza_in(stanza, session) if stanza.attr.xmlns == nil then local copy = st.clone(stanza); copy.attr.from = nil; record_stanza(copy, session, "sends") end return stanza; end local function record_stanza_out(stanza, session) if stanza.attr.xmlns == nil then if not (stanza.name == "iq" and stanza:get_child("bind", "urn:ietf:params:xml:ns:xmpp-bind")) then local copy = st.clone(stanza); if copy.attr.to == session.full_jid then copy.attr.to = nil; end record_stanza(copy, session, "receives"); end end return stanza; end module:hook("resource-bind", function (event) local session = event.session; if not users[session.username] then users[session.username] = { character = table.remove(names, 1) or id.short(); devices = {}; n_devices = 0; }; end local user = users[session.username]; local device = user.devices[session.resource]; if not device then user.n_devices = user.n_devices + 1; device = devices[user.n_devices] or ("device"..id.short()); user.devices[session.resource] = device; end session.scansion_character = user.character; session.scansion_device = device; session.scansion_id = user.character..(device ~= "" and "'s "..device or device); record_object("Client", session.scansion_id, { jid = session.full_jid, password = "password", }); module:log("info", "Connected: %s", session.scansion_id); record_event(session, "connects"); filters.add_filter(session, "stanzas/in", record_stanza_in); filters.add_filter(session, "stanzas/out", record_stanza_out); end); module:hook("resource-unbind", function (event) local session = event.session; if session.scansion_id then record_event(session, "disconnects"); end end) record_header("# mod_scansion_record on host '"..module.host.."' recording started "..dt.datetime().."\n\n"); record[[ ----- ]] module:hook_global("server-stopping", function () record("# recording ended on "..dt.datetime().."\n"); module:log("info", "Scansion recording available in %s", header_file); end); prosody.events.add_handler("server-cleanup", function () scan:seek("set", 0); for line in scan:lines() do head:write(line, "\n"); end scan:close(); os.remove(record_file); head:close() end);