aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/componentmanager.lua39
-rw-r--r--core/configmanager.lua14
-rw-r--r--core/hostmanager.lua1
-rw-r--r--core/modulemanager.lua78
-rw-r--r--core/s2smanager.lua4
5 files changed, 110 insertions, 26 deletions
diff --git a/core/componentmanager.lua b/core/componentmanager.lua
index f8db2d2c..0c33e7f6 100644
--- a/core/componentmanager.lua
+++ b/core/componentmanager.lua
@@ -21,14 +21,43 @@
local log = require "util.logger".init("componentmanager");
-local module_load = require "core.modulemanager".load;
-local module_unload = require "core.modulemanager".unload;
+local configmanager = require "core.configmanager";
+local eventmanager = require "core.eventmanager";
+local modulemanager = require "core.modulemanager";
local jid_split = require "util.jid".split;
-local hosts = hosts;
+local hosts = hosts;
+
+local pairs, type, tostring = pairs, type, tostring;
local components = {};
module "componentmanager"
+
+function load_enabled_components(config)
+ local defined_hosts = config or configmanager.getconfig();
+
+ for host, host_config in pairs(defined_hosts) do
+ if host ~= "*" and ((host_config.core.enabled == nil or host_config.core.enabled) and type(host_config.core.component_module) == "string") then
+ hosts[host] = { type = "component", host = host, connected = true, s2sout = {} };
+ modulemanager.load(host, "dialback");
+ local ok, err = modulemanager.load(host, host_config.core.component_module);
+ if not ok then
+ log("error", "Error loading %s component %s: %s", tostring(host_config.core.component_module), tostring(host), tostring(err));
+ else
+ log("info", "Activated %s component: %s", host_config.core.component_module, host);
+ end
+
+ local ok, component_handler = modulemanager.call_module_method(modulemanager.get_module(host, host_config.core.component_module), "load_component");
+ if not ok then
+ log("error", "Error loading %s component %s: %s", tostring(host_config.core.component_module), tostring(host), tostring(component_handler));
+ else
+ components[host] = component_handler;
+ end
+ end
+ end
+end
+
+eventmanager.add_event_hook("server-starting", load_enabled_components);
function handle_stanza(origin, stanza)
local node, host = jid_split(stanza.attr.to);
@@ -50,7 +79,7 @@ function register_component(host, component)
components[host] = component;
hosts[host] = { type = "component", host = host, connected = true, s2sout = {} };
-- FIXME only load for a.b.c if b.c has dialback, and/or check in config
- module_load(host, "dialback");
+ modulemanager.load(host, "dialback");
log("debug", "component added: "..host);
return hosts[host];
else
@@ -60,7 +89,7 @@ end
function deregister_component(host)
if components[host] then
- module_unload(host, "dialback");
+ modulemanager.unload(host, "dialback");
components[host] = nil;
hosts[host] = nil;
log("debug", "component removed: "..host);
diff --git a/core/configmanager.lua b/core/configmanager.lua
index a6e86347..a50e7223 100644
--- a/core/configmanager.lua
+++ b/core/configmanager.lua
@@ -107,7 +107,8 @@ do
parsers.lua = {};
function parsers.lua.load(data)
local env;
- env = setmetatable({ Host = true; host = true; }, { __index = function (t, k)
+ -- The ' = true' are needed so as not to set off __newindex when we assign the functions below
+ env = setmetatable({ Host = true; host = true; Component = true, component = true }, { __index = function (t, k)
return rawget(_G, k) or
function (settings_table)
config[__currenthost or "*"][k] = settings_table;
@@ -119,10 +120,21 @@ do
function env.Host(name)
rawset(env, "__currenthost", name);
+ -- Needs at least one setting to logically exist :)
set(name or "*", "core", "defined", true);
end
env.host = env.Host;
+ function env.Component(name)
+ return function (module)
+ set(name, "core", "component_module", module);
+ -- Don't load the global modules by default
+ set(name, "core", "modules_enable", false);
+ rawset(env, "__currenthost", name);
+ end
+ end
+ env.component = env.Component;
+
local chunk, err = loadstring(data);
if not chunk then
diff --git a/core/hostmanager.lua b/core/hostmanager.lua
index 64bb13f7..1fec9799 100644
--- a/core/hostmanager.lua
+++ b/core/hostmanager.lua
@@ -17,6 +17,7 @@ local function load_enabled_hosts(config)
activate(host, host_config);
end
end
+ eventmanager.fire_event("hosts-activated", defined_hosts);
end
eventmanager.add_event_hook("server-starting", load_enabled_hosts);
diff --git a/core/modulemanager.lua b/core/modulemanager.lua
index e783e9b4..8292eaa5 100644
--- a/core/modulemanager.lua
+++ b/core/modulemanager.lua
@@ -29,10 +29,12 @@ local config = require "core.configmanager";
local multitable_new = require "util.multitable".new;
local register_actions = require "core.actions".register;
+local hosts = hosts;
+
local loadfile, pcall = loadfile, pcall;
local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv;
local pairs, ipairs = pairs, ipairs;
-local t_insert = table.insert;
+local t_insert, t_concat = table.insert, table.concat;
local type = type;
local next = next;
local rawget = rawget;
@@ -107,7 +109,7 @@ function load(host, module_name, config)
end
- local mod, err = loadfile(plugin_dir.."mod_"..module_name..".lua");
+ local mod, err = loadfile(get_module_filename(module_name));
if not mod then
log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
return nil, err;
@@ -132,18 +134,22 @@ function load(host, module_name, config)
return true;
end
+function get_module(host, name)
+ return modulemap[host] and modulemap[host][name];
+end
+
function is_loaded(host, name)
return modulemap[host] and modulemap[host][name] and true;
end
function unload(host, name, ...)
- local mod = modulemap[host] and modulemap[host][name];
+ local mod = get_module(host, name);
if not mod then return nil, "module-not-loaded"; end
- if type(mod.module.unload) == "function" then
- local ok, err = pcall(mod.module.unload, ...)
+ if module_has_method(mod, "unload") then
+ local ok, err = call_module_method(mod, "unload");
if (not ok) and err then
- log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+ log("warn", "Non-fatal error unloading module '%s' on '%s': %s", name, host, err);
end
end
modulemap[host][name] = nil;
@@ -161,36 +167,45 @@ function unload(host, name, ...)
end
function reload(host, name, ...)
- local mod = modulemap[host] and modulemap[host][name];
+ local mod = get_module(host, name);
if not mod then return nil, "module-not-loaded"; end
- local _mod, err = loadfile(plugin_dir.."mod_"..name..".lua"); -- checking for syntax errors
+ local _mod, err = loadfile(get_module_filename(name)); -- checking for syntax errors
if not _mod then
log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
return nil, err;
end
local saved;
- if type(mod.module.save) == "function" then
- local ok, err = pcall(mod.module.save)
- if (not ok) and err then
- log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+
+ if module_has_method(mod, "save") then
+ local ok, ret, err = call_module_method(mod, "save");
+ if ok then
+ saved = ret;
else
- saved = err;
+ log("warn", "Error saving module '%s:%s' state: %s", host, module, ret);
+ if not config.get(host, "core", "force_module_reload") then
+ log("warn", "Aborting reload due to error, set force_module_reload to ignore this");
+ return nil, "save-state-failed";
+ else
+ log("warn", "Continuing with reload (using the force)");
+ end
end
end
unload(host, name, ...);
- if load(host, name, ...) then
- mod = modulemap[host] and modulemap[host][name];
- if type(mod.module.restore) == "function" then
- local ok, err = pcall(mod.module.restore, saved or {})
+ local ok, err = load(host, name, ...);
+ if ok then
+ mod = get_module(host, name);
+ if module_has_method(mod, "restore") then
+ local ok, err = call_module_method(mod, "restore", saved or {})
if (not ok) and err then
- log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+ log("warn", "Error restoring module '%s' from '%s': %s", name, host, err);
end
end
return true;
end
+ return ok, err;
end
function handle_stanza(host, origin, stanza)
@@ -214,6 +229,25 @@ function handle_stanza(host, origin, stanza)
end
end
+function module_has_method(module, method)
+ return type(module.module[method]) == "function";
+end
+
+function call_module_method(module, method, ...)
+ if module_has_method(module, method) then
+ local f = module.module[method];
+ return pcall(f, ...);
+ else
+ return false, "no-such-method";
+ end
+end
+
+local _modulepath = { plugin_dir, "mod_", nil, ".lua"};
+function get_module_filename(name)
+ _modulepath[3] = name;
+ return t_concat(_modulepath);
+end
+
----- API functions exposed to modules -----------
-- Must all be in api.*
@@ -227,6 +261,14 @@ function api:get_host()
return self.host;
end
+function api:get_host_type()
+ return hosts[self.host].type;
+end
+
+function api:set_global()
+ self.host = "*";
+end
+
local function _add_handler(module, origin_type, tag, xmlns, handler)
local handlers = stanza_handlers:get(module.host, origin_type, tag, xmlns);
local msg = (tag == "iq") and "namespace" or "payload namespace";
diff --git a/core/s2smanager.lua b/core/s2smanager.lua
index bc1abfe8..5243085c 100644
--- a/core/s2smanager.lua
+++ b/core/s2smanager.lua
@@ -31,7 +31,7 @@ local tostring, pairs, ipairs, getmetatable, print, newproxy, error, tonumber
local idna_to_ascii = require "util.encodings".idna.to_ascii;
local connlisteners_get = require "net.connlisteners".get;
-local wraptlsclient = require "net.server".wraptlsclient;
+local wrapclient = require "net.server".wrapclient;
local modulemanager = require "core.modulemanager";
local st = require "stanza";
local stanza = st.stanza;
@@ -196,7 +196,7 @@ function attempt_connection(host_session, err)
end
local cl = connlisteners_get("xmppserver");
- conn = wraptlsclient(cl, conn, connect_host, connect_port, 0, cl.default_mode or 1, hosts[from_host].ssl_ctx );
+ conn = wrapclient(conn, connect_host, connect_port, cl, cl.default_mode or 1, hosts[from_host].ssl_ctx, false );
host_session.conn = conn;
-- Register this outgoing connection so that xmppserver_listener knows about it