aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/certmanager.lua1
-rw-r--r--core/configmanager.lua42
-rw-r--r--core/hostmanager.lua12
-rw-r--r--core/loggingmanager.lua11
-rw-r--r--core/moduleapi.lua103
-rw-r--r--core/modulemanager.lua20
-rw-r--r--core/portmanager.lua1
-rw-r--r--core/rostermanager.lua3
-rw-r--r--core/s2smanager.lua6
-rw-r--r--core/sessionmanager.lua10
-rw-r--r--core/stanza_router.lua2
-rw-r--r--core/storagemanager.lua37
-rw-r--r--core/usermanager.lua3
13 files changed, 137 insertions, 114 deletions
diff --git a/core/certmanager.lua b/core/certmanager.lua
index dac4baa4..5282a6f5 100644
--- a/core/certmanager.lua
+++ b/core/certmanager.lua
@@ -55,6 +55,7 @@ local luasec_has = softreq"ssl.config" or {
};
local _ENV = nil;
+-- luacheck: std none
-- Global SSL options if not overridden per-host
local global_ssl_config = configmanager.get("*", "ssl");
diff --git a/core/configmanager.lua b/core/configmanager.lua
index 5a544375..1e67da9b 100644
--- a/core/configmanager.lua
+++ b/core/configmanager.lua
@@ -7,12 +7,10 @@
--
local _G = _G;
-local setmetatable, rawget, rawset, io, error, dofile, type, pairs, table =
- setmetatable, rawget, rawset, io, error, dofile, type, pairs, table;
+local setmetatable, rawget, rawset, io, os, error, dofile, type, pairs =
+ setmetatable, rawget, rawset, io, os, error, dofile, type, pairs;
local format, math_max = string.format, math.max;
-local fire_event = prosody and prosody.events.fire_event or function () end;
-
local envload = require"util.envload".envload;
local deps = require"util.dependencies";
local resolve_relative_path = require"util.paths".resolve_relative_path;
@@ -24,10 +22,11 @@ local nameprep = encodings and encodings.stringprep.nameprep or function (host)
local _M = {};
local _ENV = nil;
+-- luacheck: std none
_M.resolve_relative_path = resolve_relative_path; -- COMPAT
-local parsers = {};
+local parser = nil;
local config_mt = { __index = function (t, _) return rawget(t, "*"); end};
local config = setmetatable({ ["*"] = { } }, config_mt);
@@ -77,19 +76,14 @@ end
function _M.load(filename, config_format)
config_format = config_format or filename:match("%w+$");
- if parsers[config_format] and parsers[config_format].load then
+ if config_format == "lua" then
local f, err = io.open(filename);
if f then
local new_config = setmetatable({ ["*"] = { } }, config_mt);
- local ok, err = parsers[config_format].load(f:read("*a"), filename, new_config);
+ local ok, err = parser.load(f:read("*a"), filename, new_config);
f:close();
if ok then
config = new_config;
- fire_event("config-reloaded", {
- filename = filename,
- format = config_format,
- config = config
- });
end
return ok, "parser", err;
end
@@ -103,26 +97,11 @@ function _M.load(filename, config_format)
end
end
-function _M.addparser(config_format, parser)
- if config_format and parser then
- parsers[config_format] = parser;
- end
-end
-
--- _M needed to avoid name clash with local 'parsers'
-function _M.parsers()
- local p = {};
- for config_format in pairs(parsers) do
- table.insert(p, config_format);
- end
- return p;
-end
-
-- Built-in Lua parser
do
local pcall = _G.pcall;
- parsers.lua = {};
- function parsers.lua.load(data, config_file, config_table)
+ parser = {};
+ function parser.load(data, config_file, config_table)
local env;
-- The ' = true' are needed so as not to set off __newindex when we assign the functions below
env = setmetatable({
@@ -130,6 +109,9 @@ do
Component = true, component = true,
Include = true, include = true, RunScript = true }, {
__index = function (_, k)
+ if k:match("^ENV_") then
+ return os.getenv(k:sub(5));
+ end
return rawget(_G, k);
end,
__newindex = function (_, k, v)
@@ -211,7 +193,7 @@ do
file = resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), file);
local f, err = io.open(file);
if f then
- local ret, err = parsers.lua.load(f:read("*a"), file, config_table);
+ local ret, err = parser.load(f:read("*a"), file, config_table);
if not ret then error(err:gsub("%[string.-%]", file), 0); end
end
if not f then error("Error loading included "..file..": "..err, 0); end
diff --git a/core/hostmanager.lua b/core/hostmanager.lua
index 106a8ef2..9acca517 100644
--- a/core/hostmanager.lua
+++ b/core/hostmanager.lua
@@ -12,8 +12,6 @@ local events_new = require "util.events".new;
local disco_items = require "util.multitable".new();
local NULL = {};
-local jid_split = require "util.jid".split;
-
local log = require "util.logger".init("hostmanager");
local hosts = prosody.hosts;
@@ -24,11 +22,12 @@ end
local incoming_s2s = _G.prosody.incoming_s2s;
local core_route_stanza = _G.prosody.core_route_stanza;
-local pairs, select, rawget = pairs, select, rawget;
+local pairs, rawget = pairs, rawget;
local tostring, type = tostring, type;
local setmetatable = setmetatable;
local _ENV = nil;
+-- luacheck: std none
local host_mt = { }
function host_mt:__tostring()
@@ -71,13 +70,6 @@ end
prosody_events.add_handler("server-starting", load_enabled_hosts);
local function host_send(stanza)
- local name, stanza_type = stanza.name, stanza.attr.type;
- if stanza_type == "error" or (name == "iq" and stanza_type == "result") then
- local dest_host_name = select(2, jid_split(stanza.attr.to));
- local dest_host = hosts[dest_host_name] or { type = "unknown" };
- log("warn", "Unhandled response sent to %s host %s: %s", dest_host.type, dest_host_name, tostring(stanza));
- return;
- end
core_route_stanza(nil, stanza);
end
diff --git a/core/loggingmanager.lua b/core/loggingmanager.lua
index 004f4c3b..cfa8246a 100644
--- a/core/loggingmanager.lua
+++ b/core/loggingmanager.lua
@@ -5,7 +5,6 @@
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
--- luacheck: globals log prosody.log
local format = require "util.format".format;
local setmetatable, rawset, pairs, ipairs, type =
@@ -18,12 +17,9 @@ local getstyle, getstring = require "util.termcolours".getstyle, require "util.t
local config = require "core.configmanager";
local logger = require "util.logger";
-local prosody = prosody;
-
-_G.log = logger.init("general");
-prosody.log = logger.init("general");
local _ENV = nil;
+-- luacheck: std none
-- The log config used if none specified in the config file (see reload_logging for initialization)
local default_logging;
@@ -154,13 +150,8 @@ local function reload_logging()
for name, sink_maker in pairs(old_sink_types) do
log_sink_types[name] = sink_maker;
end
-
- prosody.events.fire_event("logging-reloaded");
end
-reload_logging();
-prosody.events.add_handler("config-reloaded", reload_logging);
-
--- Definition of built-in logging sinks ---
-- Null sink, must enter log_sink_types *first*
diff --git a/core/moduleapi.lua b/core/moduleapi.lua
index 7d954c1f..76d9d958 100644
--- a/core/moduleapi.lua
+++ b/core/moduleapi.lua
@@ -6,7 +6,6 @@
-- COPYING file in the source package for more information.
--
-local config = require "core.configmanager";
local array = require "util.array";
local set = require "util.set";
local it = require "util.iterators";
@@ -14,15 +13,15 @@ local logger = require "util.logger";
local pluginloader = require "util.pluginloader";
local timer = require "util.timer";
local resolve_relative_path = require"util.paths".resolve_relative_path;
-local measure = require "core.statsmanager".measure;
local st = require "util.stanza";
local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat;
local error, setmetatable, type = error, setmetatable, type;
local ipairs, pairs, select = ipairs, pairs, select;
-local unpack = table.unpack or unpack; --luacheck: ignore 113
local tonumber, tostring = tonumber, tostring;
local require = require;
+local pack = table.pack or function(...) return {n=select("#",...), ...}; end -- table.pack is only in 5.2
+local unpack = table.unpack or unpack; --luacheck: ignore 113 -- renamed in 5.2
local prosody = prosody;
local hosts = prosody.hosts;
@@ -70,20 +69,6 @@ end
function api:add_extension(data)
self:add_item("extension", data);
end
-function api:has_feature(xmlns)
- for _, feature in ipairs(self:get_host_items("feature")) do
- if feature == xmlns then return true; end
- end
- return false;
-end
-function api:has_identity(category, identity_type, name)
- for _, id in ipairs(self:get_host_items("identity")) do
- if id.category == category and id.type == identity_type and id.name == name then
- return true;
- end
- end
- return false;
-end
function api:fire_event(...)
return (hosts[self.host] or prosody).events.fire_event(...);
@@ -160,6 +145,9 @@ function api:depends(name)
end
end);
end
+ if self:get_option_inherited_set("modules_disabled", {}):contains(name) then
+ self:log("warn", "Loading prerequisite mod_%s despite it being disabled", name);
+ end
local mod = modulemanager.get_module(self.host, name) or modulemanager.get_module("*", name);
if mod and mod.module.host == "*" and self.host ~= "*"
and modulemanager.module_has_method(mod, "add_host") then
@@ -176,36 +164,36 @@ function api:depends(name)
return mod;
end
--- Returns one or more shared tables at the specified virtual paths
--- Intentionally does not allow the table at a path to be _set_, it
--- is auto-created if it does not exist.
-function api:shared(...)
- if not self.shared_data then self.shared_data = {}; end
- local paths = { n = select("#", ...), ... };
- local data_array = {};
- local default_path_components = { self.host, self.name };
- for i = 1, paths.n do
- local path = paths[i];
- if path:sub(1,1) ~= "/" then -- Prepend default components
- local n_components = select(2, path:gsub("/", "%1"));
- path = (n_components<#default_path_components and "/" or "")
- ..t_concat(default_path_components, "/", 1, #default_path_components-n_components).."/"..path;
- end
- local shared = shared_data[path];
- if not shared then
- shared = {};
- if path:match("%-cache$") then
- setmetatable(shared, { __mode = "kv" });
- end
- shared_data[path] = shared;
+local function get_shared_table_from_path(module, tables, path)
+ if path:sub(1,1) ~= "/" then -- Prepend default components
+ local default_path_components = { module.host, module.name };
+ local n_components = select(2, path:gsub("/", "%1"));
+ path = (n_components<#default_path_components and "/" or "")
+ ..t_concat(default_path_components, "/", 1, #default_path_components-n_components).."/"..path;
+ end
+ local shared = tables[path];
+ if not shared then
+ shared = {};
+ if path:match("%-cache$") then
+ setmetatable(shared, { __mode = "kv" });
end
- t_insert(data_array, shared);
- self.shared_data[path] = shared;
+ tables[path] = shared;
end
- return unpack(data_array);
+ return shared;
+end
+
+-- Returns a shared table at the specified virtual path
+-- Intentionally does not allow the table to be _set_, it
+-- is auto-created if it does not exist.
+function api:shared(path)
+ if not self.shared_data then self.shared_data = {}; end
+ local shared = get_shared_table_from_path(self, shared_data, path);
+ self.shared_data[path] = shared;
+ return shared;
end
function api:get_option(name, default_value)
+ local config = require "core.configmanager";
local value = config.get(self.host, name);
if value == nil then
value = default_value;
@@ -377,15 +365,33 @@ function api:broadcast(jids, stanza, iter)
for jid in (iter or it.values)(jids) do
local new_stanza = st.clone(stanza);
new_stanza.attr.to = jid;
- core_post_stanza(hosts[self.host], new_stanza);
+ self:send(new_stanza);
end
end
-function api:add_timer(delay, callback)
- return timer.add_task(delay, function (t)
- if self.loaded == false then return; end
- return callback(t);
- end);
+local timer_methods = { }
+local timer_mt = {
+ __index = timer_methods;
+}
+function timer_methods:stop( )
+ timer.stop(self.id);
+end
+timer_methods.disarm = timer_methods.stop
+function timer_methods:reschedule(delay)
+ timer.reschedule(self.id, delay)
+end
+
+local function timer_callback(now, id, t) --luacheck: ignore 212/id
+ if t.module_env.loaded == false then return; end
+ return t.callback(now, unpack(t, 1, t.n));
+end
+
+function api:add_timer(delay, callback, ...)
+ local t = pack(...)
+ t.module_env = self;
+ t.callback = callback;
+ t.id = timer.add_task(delay, timer_callback, t);
+ return setmetatable(t, timer_mt);
end
local path_sep = package.config:sub(1,1);
@@ -403,6 +409,7 @@ function api:open_store(name, store_type)
end
function api:measure(name, stat_type)
+ local measure = require "core.statsmanager".measure;
return measure(stat_type, "/"..self.host.."/mod_"..self.name.."/"..name);
end
diff --git a/core/modulemanager.lua b/core/modulemanager.lua
index 771f6fb1..81c28aa0 100644
--- a/core/modulemanager.lua
+++ b/core/modulemanager.lua
@@ -15,8 +15,8 @@ local set = require "util.set";
local new_multitable = require "util.multitable".new;
local api = require "core.moduleapi"; -- Module API container
-local hosts = hosts;
local prosody = prosody;
+local hosts = prosody.hosts;
local xpcall = xpcall;
local setmetatable, rawget = setmetatable, rawget;
@@ -38,6 +38,7 @@ local component_inheritable_modules = {"tls", "saslauth", "dialback", "iq", "s2s
local _G = _G;
local _ENV = nil;
+-- luacheck: std none
local load_modules_for_host, load, unload, reload, get_module, get_items;
local get_modules, is_loaded, module_has_method, call_module_method;
@@ -45,8 +46,8 @@ local get_modules, is_loaded, module_has_method, call_module_method;
-- [host] = { [module] = module_env }
local modulemap = { ["*"] = {} };
--- Load modules when a host is activated
-function load_modules_for_host(host)
+-- Get the list of modules to be loaded on a host
+local function get_modules_for_host(host)
local component = config.get(host, "component_module");
local global_modules_enabled = config.get("*", "modules_enabled");
@@ -70,8 +71,16 @@ function load_modules_for_host(host)
modules:add("admin_telnet");
end
- if component then
- load(host, component);
+ return modules, component;
+end
+
+-- Load modules when a host is activated
+function load_modules_for_host(host)
+ local modules, component_module = get_modules_for_host(host);
+
+ -- Ensure component module is loaded first
+ if component_module then
+ load(host, component_module);
end
for module in modules do
load(host, module);
@@ -323,6 +332,7 @@ function call_module_method(module, method, ...)
end
return {
+ get_modules_for_host = get_modules_for_host;
load_modules_for_host = load_modules_for_host;
load = load;
unload = unload;
diff --git a/core/portmanager.lua b/core/portmanager.lua
index 5b6476f3..1ed37da0 100644
--- a/core/portmanager.lua
+++ b/core/portmanager.lua
@@ -15,6 +15,7 @@ local prosody = prosody;
local fire_event = prosody.events.fire_event;
local _ENV = nil;
+-- luacheck: std none
--- Config
diff --git a/core/rostermanager.lua b/core/rostermanager.lua
index 65be0de0..aa1ba9f3 100644
--- a/core/rostermanager.lua
+++ b/core/rostermanager.lua
@@ -15,7 +15,7 @@ local pairs = pairs;
local tostring = tostring;
local type = type;
-local hosts = hosts;
+local hosts = prosody.hosts;
local bare_sessions = prosody.bare_sessions;
local um_user_exists = require "core.usermanager".user_exists;
@@ -23,6 +23,7 @@ local st = require "util.stanza";
local storagemanager = require "core.storagemanager";
local _ENV = nil;
+-- luacheck: std none
local save_roster; -- forward declaration
diff --git a/core/s2smanager.lua b/core/s2smanager.lua
index d84572f3..58269c49 100644
--- a/core/s2smanager.lua
+++ b/core/s2smanager.lua
@@ -17,12 +17,13 @@ local logger_init = require "util.logger".init;
local log = logger_init("s2smanager");
local prosody = _G.prosody;
-incoming_s2s = {};
+local incoming_s2s = {};
+_G.incoming_s2s = incoming_s2s;
prosody.incoming_s2s = incoming_s2s;
-local incoming_s2s = incoming_s2s;
local fire_event = prosody.events.fire_event;
local _ENV = nil;
+-- luacheck: std none
local function new_incoming(conn)
local session = { conn = conn, type = "s2sin_unauthed", direction = "incoming", hosts = {} };
@@ -64,6 +65,7 @@ local function retire_session(session, reason)
function session.send(data) log("debug", "Discarding data sent to resting session: %s", tostring(data)); end
function session.data(data) log("debug", "Discarding data received from resting session: %s", tostring(data)); end
+ session.thread = { run = function (_, data) return session.data(data) end };
session.sends2s = session.send;
return setmetatable(session, resting_session);
end
diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua
index bdaafcb6..2843001a 100644
--- a/core/sessionmanager.lua
+++ b/core/sessionmanager.lua
@@ -10,7 +10,7 @@
local tostring, setmetatable = tostring, setmetatable;
local pairs, next= pairs, next;
-local hosts = hosts;
+local hosts = prosody.hosts;
local full_sessions = prosody.full_sessions;
local bare_sessions = prosody.bare_sessions;
@@ -20,12 +20,13 @@ local rm_load_roster = require "core.rostermanager".load_roster;
local config_get = require "core.configmanager".get;
local resourceprep = require "util.encodings".stringprep.resourceprep;
local nodeprep = require "util.encodings".stringprep.nodeprep;
-local uuid_generate = require "util.uuid".generate;
+local generate_identifier = require "util.id".short;
local initialize_filters = require "util.filters".initialize;
local gettime = require "socket".gettime;
local _ENV = nil;
+-- luacheck: std none
local function new_session(conn)
local session = { conn = conn, type = "c2s_unauthed", conntime = gettime() };
@@ -74,6 +75,7 @@ local function retire_session(session)
function session.send(data) log("debug", "Discarding data sent to resting session: %s", tostring(data)); return false; end
function session.data(data) log("debug", "Discarding data received from resting session: %s", tostring(data)); end
+ session.thread = { run = function (_, data) return session.data(data) end };
return setmetatable(session, resting_session);
end
@@ -137,7 +139,7 @@ local function bind_resource(session, resource)
end
resource = resourceprep(resource);
- resource = resource ~= "" and resource or uuid_generate();
+ resource = resource ~= "" and resource or generate_identifier();
--FIXME: Randomly-generated resources must be unique per-user, and never conflict with existing
if not hosts[session.host].sessions[session.username] then
@@ -151,7 +153,7 @@ local function bind_resource(session, resource)
local policy = config_get(session.host, "conflict_resolve");
local increment;
if policy == "random" then
- resource = uuid_generate();
+ resource = generate_identifier();
increment = true;
elseif policy == "increment" then
increment = true; -- TODO ping old resource
diff --git a/core/stanza_router.lua b/core/stanza_router.lua
index 4caa89b6..5caa22f6 100644
--- a/core/stanza_router.lua
+++ b/core/stanza_router.lua
@@ -19,7 +19,7 @@ local bare_sessions = _G.prosody.bare_sessions;
local core_post_stanza, core_process_stanza, core_route_stanza;
-function deprecated_warning(f)
+local function deprecated_warning(f)
_G[f] = function(...)
log("warn", "Using the global %s() is deprecated, use module:send() or prosody.%s(). %s", f, f, debug.traceback());
return prosody[f](...);
diff --git a/core/storagemanager.lua b/core/storagemanager.lua
index c93438af..dea71733 100644
--- a/core/storagemanager.lua
+++ b/core/storagemanager.lua
@@ -1,17 +1,21 @@
local type, pairs = type, pairs;
local setmetatable = setmetatable;
+local rawset = rawset;
local config = require "core.configmanager";
local datamanager = require "util.datamanager";
local modulemanager = require "core.modulemanager";
local multitable = require "util.multitable";
-local hosts = hosts;
local log = require "util.logger".init("storagemanager");
+local async = require "util.async";
+local debug = debug;
local prosody = prosody;
+local hosts = prosody.hosts;
local _ENV = nil;
+-- luacheck: std none
local olddm = {}; -- maintain old datamanager, for backwards compatibility
for k,v in pairs(datamanager) do olddm[k] = v; end
@@ -28,8 +32,34 @@ local null_storage_driver = setmetatable(
}
);
+local async_check = config.get("*", "storage_async_check") == true;
+
local stores_available = multitable.new();
+local function check_async_wrapper(event)
+ local store = event.store;
+ event.store = setmetatable({}, {
+ __index = function (t, method_name)
+ local original_method = store[method_name];
+ if type(original_method) ~= "function" then
+ if original_method then
+ rawset(t, method_name, original_method);
+ end
+ return original_method;
+ end
+ local wrapped_method = function (...)
+ if not async.ready() then
+ log("warn", "ASYNC-01: Attempt to access storage outside async context, "
+ .."see https://prosody.im/doc/developers/async - %s", debug.traceback());
+ end
+ return original_method(...);
+ end
+ rawset(t, method_name, wrapped_method);
+ return wrapped_method;
+ end;
+ });
+end
+
local function initialize_host(host)
local host_session = hosts[host];
host_session.events.add_handler("item-added/storage-provider", function (event)
@@ -41,6 +71,9 @@ local function initialize_host(host)
local item = event.item;
stores_available:set(host, item.name, nil);
end);
+ if async_check then
+ host_session.events.add_handler("store-opened", check_async_wrapper);
+ end
end
prosody.events.add_handler("host-activated", initialize_host, 101);
@@ -137,7 +170,7 @@ local map_shim_mt = {
};
}
-local open;
+local open; -- forward declaration
local function create_map_shim(host, store)
local keyval_store, err = open(host, store, "keyval");
diff --git a/core/usermanager.lua b/core/usermanager.lua
index f795e8ae..bb5669cf 100644
--- a/core/usermanager.lua
+++ b/core/usermanager.lua
@@ -13,17 +13,18 @@ local ipairs = ipairs;
local jid_bare = require "util.jid".bare;
local jid_prep = require "util.jid".prep;
local config = require "core.configmanager";
-local hosts = hosts;
local sasl_new = require "util.sasl".new;
local storagemanager = require "core.storagemanager";
local prosody = _G.prosody;
+local hosts = prosody.hosts;
local setmetatable = setmetatable;
local default_provider = "internal_plain";
local _ENV = nil;
+-- luacheck: std none
local function new_null_provider()
local function dummy() return nil, "method not implemented"; end;