aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/loggingmanager.lua27
-rw-r--r--plugins/mod_c2s.lua18
-rw-r--r--plugins/mod_component.lua18
-rw-r--r--plugins/mod_mam/mod_mam.lua19
-rw-r--r--plugins/mod_posix.lua9
-rw-r--r--plugins/mod_s2s/mod_s2s.lua18
-rw-r--r--util/format.lua74
7 files changed, 123 insertions, 60 deletions
diff --git a/core/loggingmanager.lua b/core/loggingmanager.lua
index 14305588..6dc1c1d1 100644
--- a/core/loggingmanager.lua
+++ b/core/loggingmanager.lua
@@ -7,7 +7,7 @@
--
-- luacheck: globals log prosody.log
-local format = string.format;
+local format = require "util.format".format;
local setmetatable, rawset, pairs, ipairs, type =
setmetatable, rawset, pairs, ipairs, type;
local stdout = io.stdout;
@@ -15,9 +15,6 @@ local io_open = io.open;
local math_max, rep = math.max, string.rep;
local os_date = os.date;
local getstyle, getstring = require "util.termcolours".getstyle, require "util.termcolours".getstring;
-local tostring = tostring;
-local select = select;
-local unpack = table.unpack or unpack; --luacheck: ignore 113
local config = require "core.configmanager";
local logger = require "util.logger";
@@ -194,23 +191,15 @@ local function log_to_file(sink_config, logfile)
-- Column width for "source" (used by stdout and console)
local sourcewidth = sink_config.source_width;
- return function (name, level, message, ...)
- local n = select('#', ...);
- if n ~= 0 then
- local arg = { ... };
- for i = 1, n do
- arg[i] = tostring(arg[i]);
- end
- message = format(message, unpack(arg, 1, n));
- end
-
- if sourcewidth then
+ if sourcewidth then
+ return function (name, level, message, ...)
sourcewidth = math_max(#name+2, sourcewidth);
- name = name .. rep(" ", sourcewidth-#name);
- else
- name = name .. "\t";
+ write(logfile, timestamps and os_date(timestamps) or "", name, rep(" ", sourcewidth-#name), level, "\t", format(message, ...), "\n");
+ end
+ else
+ return function (name, level, message, ...)
+ write(logfile, timestamps and os_date(timestamps) or "", name, "\t", level, "\t", format(message, ...), "\n");
end
- write(logfile, timestamps and os_date(timestamps) or "", name, level, "\t", message, "\n");
end
end
log_sink_types.file = log_to_file;
diff --git a/plugins/mod_c2s.lua b/plugins/mod_c2s.lua
index 3547fe31..7b82cc5f 100644
--- a/plugins/mod_c2s.lua
+++ b/plugins/mod_c2s.lua
@@ -112,16 +112,14 @@ function stream_callbacks.error(session, error, data)
session:close("not-well-formed");
elseif error == "stream-error" then
local condition, text = "undefined-condition";
- for child in data:children() do
- if child.attr.xmlns == xmlns_xmpp_streams then
- if child.name ~= "text" then
- condition = child.name;
- else
- text = child:get_text();
- end
- if condition ~= "undefined-condition" and text then
- break;
- end
+ for child in data:childtags(nil, xmlns_xmpp_streams) do
+ if child.name ~= "text" then
+ condition = child.name;
+ else
+ text = child:get_text();
+ end
+ if condition ~= "undefined-condition" and text then
+ break;
end
end
text = condition .. (text and (" ("..text..")") or "");
diff --git a/plugins/mod_component.lua b/plugins/mod_component.lua
index 77d8a14d..33b1852b 100644
--- a/plugins/mod_component.lua
+++ b/plugins/mod_component.lua
@@ -170,16 +170,14 @@ function stream_callbacks.error(session, error, data)
session:close("not-well-formed");
elseif error == "stream-error" then
local condition, text = "undefined-condition";
- for child in data:children() do
- if child.attr.xmlns == xmlns_xmpp_streams then
- if child.name ~= "text" then
- condition = child.name;
- else
- text = child:get_text();
- end
- if condition ~= "undefined-condition" and text then
- break;
- end
+ for child in data:childtags(nil, xmlns_xmpp_streams) do
+ if child.name ~= "text" then
+ condition = child.name;
+ else
+ text = child:get_text();
+ end
+ if condition ~= "undefined-condition" and text then
+ break;
end
end
text = condition .. (text and (" ("..text..")") or "");
diff --git a/plugins/mod_mam/mod_mam.lua b/plugins/mod_mam/mod_mam.lua
index 32dd0169..298c770c 100644
--- a/plugins/mod_mam/mod_mam.lua
+++ b/plugins/mod_mam/mod_mam.lua
@@ -56,6 +56,13 @@ local use_total = true;
local cleanup;
+local function schedule_cleanup(username)
+ if cleanup and not cleanup[username] then
+ table.insert(cleanup, username);
+ cleanup[username] = true;
+ end
+end
+
-- Handle prefs.
module:hook("iq/self/"..xmlns_mam..":prefs", function(event)
local origin, stanza = event.origin, event.stanza;
@@ -97,7 +104,7 @@ module:hook("iq-set/self/"..xmlns_mam..":query", function(event)
local query = stanza.tags[1];
local qid = query.attr.queryid;
- if cleanup then cleanup[origin.username] = true; end
+ schedule_cleanup(origin.username);
-- Search query parameters
local qwith, qstart, qend;
@@ -304,7 +311,7 @@ local function message_handler(event, c2s)
local id = ok;
clone_for_other_handlers:tag("stanza-id", { xmlns = xmlns_st_id, by = store_user.."@"..host, id = id }):up();
event.stanza = clone_for_other_handlers;
- if cleanup then cleanup[store_user] = true; end
+ schedule_cleanup(store_user);
module:fire_event("archive-message-added", { origin = origin, stanza = clone_for_storage, for_user = store_user, id = id });
end
else
@@ -326,7 +333,9 @@ module:hook("pre-message/full", strip_stanza_id_after_other_events, -1);
local cleanup_after = module:get_option_string("archive_expires_after", "1w");
local cleanup_interval = module:get_option_number("archive_cleanup_interval", 4 * 60 * 60);
-if cleanup_after ~= "never" then
+if not archive.delete then
+ module:log("debug", "Selected storage driver does not support deletion, archives will not expire");
+elseif cleanup_after ~= "never" then
local day = 86400;
local multipliers = { d = day, w = day * 7, m = 31 * day, y = 365.2425 * day };
local n, m = cleanup_after:lower():match("(%d+)%s*([dwmy]?)");
@@ -353,13 +362,13 @@ if cleanup_after ~= "never" then
pcall(function ()
-- If this works, then we schedule cleanup for all known users on startup
for user in um.users(module.host) do
- cleanup[user] = true;
+ schedule_cleanup(user);
end
end);
-- At odd intervals, delete old messages for one user
module:add_timer(math.random(10, 60), function()
- local user = next(cleanup);
+ local user = table.remove(cleanup, 1);
if user then
module:log("debug", "Removing old messages for user %q", user);
local ok, err = archive:delete(user, { ["end"] = os.time() - cleanup_after; })
diff --git a/plugins/mod_posix.lua b/plugins/mod_posix.lua
index 49addafe..9b7d59f5 100644
--- a/plugins/mod_posix.lua
+++ b/plugins/mod_posix.lua
@@ -20,6 +20,7 @@ if not have_signal then
module:log("warn", "Couldn't load signal library, won't respond to SIGTERM");
end
+local format = require "util.format".format;
local lfs = require "lfs";
local stat = lfs.attributes;
@@ -118,13 +119,9 @@ function syslog_sink_maker(config) -- luacheck: ignore 212/config
pposix.syslog_open("prosody", module:get_option_string("syslog_facility"));
syslog_opened = true;
end
- local syslog, format = pposix.syslog_log, string.format;
+ local syslog = pposix.syslog_log;
return function (name, level, message, ...)
- if ... then
- syslog(level, name, format(message, ...));
- else
- syslog(level, name, message);
- end
+ syslog(level, name, format(message, ...));
end;
end
require "core.loggingmanager".register_sink_type("syslog", syslog_sink_maker);
diff --git a/plugins/mod_s2s/mod_s2s.lua b/plugins/mod_s2s/mod_s2s.lua
index c2dd9900..b46b7e2a 100644
--- a/plugins/mod_s2s/mod_s2s.lua
+++ b/plugins/mod_s2s/mod_s2s.lua
@@ -438,16 +438,14 @@ function stream_callbacks.error(session, error, data)
session:close("not-well-formed");
elseif error == "stream-error" then
local condition, text = "undefined-condition";
- for child in data:children() do
- if child.attr.xmlns == xmlns_xmpp_streams then
- if child.name ~= "text" then
- condition = child.name;
- else
- text = child:get_text();
- end
- if condition ~= "undefined-condition" and text then
- break;
- end
+ for child in data:childtags(nil, xmlns_xmpp_streams) do
+ if child.name ~= "text" then
+ condition = child.name;
+ else
+ text = child:get_text();
+ end
+ if condition ~= "undefined-condition" and text then
+ break;
end
end
text = condition .. (text and (" ("..text..")") or "");
diff --git a/util/format.lua b/util/format.lua
new file mode 100644
index 00000000..5f2b12be
--- /dev/null
+++ b/util/format.lua
@@ -0,0 +1,74 @@
+--
+-- A string.format wrapper that gracefully handles invalid arguments
+--
+
+local tostring = tostring;
+local select = select;
+local assert = assert;
+local unpack = unpack;
+local type = type;
+
+local function format(format, ...)
+ local args, args_length = { ... }, select('#', ...);
+
+ -- format specifier spec:
+ -- 1. Start: '%%'
+ -- 2. Flags: '[%-%+ #0]'
+ -- 3. Width: '%d?%d?'
+ -- 4. Precision: '%.?%d?%d?'
+ -- 5. Option: '[cdiouxXaAeEfgGqs%%]'
+ --
+ -- The options c, d, E, e, f, g, G, i, o, u, X, and x all expect a number as argument, whereas q and s expect a string.
+ -- This function does not accept string values containing embedded zeros, except as arguments to the q option.
+ -- a and A are only in Lua 5.2+
+
+
+ -- process each format specifier
+ local i = 0;
+ format = format:gsub("%%[^cdiouxXaAeEfgGqs%%]*[cdiouxXaAeEfgGqs%%]", function(spec)
+ if spec ~= "%%" then
+ i = i + 1;
+ local arg = args[i];
+ if arg == nil then -- special handling for nil
+ arg = "<nil>"
+ args[i] = "<nil>";
+ end
+
+ local option = spec:sub(-1);
+ if option == "q" or option == "s" then -- arg should be string
+ args[i] = tostring(arg);
+ elseif type(arg) ~= "number" then -- arg isn't number as expected?
+ args[i] = tostring(arg);
+ spec = "[%s]";
+ end
+ end
+ return spec;
+ end);
+
+ -- process extra args
+ while i < args_length do
+ i = i + 1;
+ local arg = args[i];
+ if arg == nil then
+ args[i] = "<nil>";
+ else
+ args[i] = tostring(arg);
+ end
+ format = format .. " [%s]"
+ end
+
+ return format:format(unpack(args));
+end
+
+local function test()
+ assert(format("%s", "hello") == "hello");
+ assert(format("%s") == "<nil>");
+ assert(format("%s", true) == "true");
+ assert(format("%d", true) == "[true]");
+ assert(format("%%", true) == "% [true]");
+end
+
+return {
+ format = format;
+ test = test;
+};