aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/modulemanager.lua91
-rw-r--r--core/objectmanager.lua120
-rw-r--r--core/s2smanager.lua9
-rw-r--r--core/sessionmanager.lua5
-rw-r--r--core/stanza_router.lua2
5 files changed, 154 insertions, 73 deletions
diff --git a/core/modulemanager.lua b/core/modulemanager.lua
index 9cd56187..65a38ccb 100644
--- a/core/modulemanager.lua
+++ b/core/modulemanager.lua
@@ -28,7 +28,9 @@ local type = type;
local next = next;
local rawget = rawget;
local error = error;
-local tostring = tostring;
+local tostring, tonumber = tostring, tonumber;
+
+local array, set = require "util.array", require "util.set";
local autoload_modules = {"presence", "message", "iq"};
@@ -156,6 +158,7 @@ function load(host, module_name, config)
log("error", "Error initializing module '%s' on '%s': %s", module_name, host, err or "nil");
end
if success then
+ hosts[host].events.fire_event("module-loaded", { module = module_name, host = host });
return true;
else -- load failed, unloading
unload(api_instance.host, module_name);
@@ -172,7 +175,7 @@ function is_loaded(host, name)
end
function unload(host, name, ...)
- local mod = get_module(host, name);
+ local mod = get_module(host, name);
if not mod then return nil, "module-not-loaded"; end
if module_has_method(mod, "unload") then
@@ -198,6 +201,7 @@ function unload(host, name, ...)
end
hooks:remove(host, name);
modulemap[host][name] = nil;
+ hosts[host].events.fire_event("module-unloaded", { module = name, host = host });
return true;
end
@@ -278,7 +282,7 @@ function module_has_method(module, method)
end
function call_module_method(module, method, ...)
- if module_has_method(module, method) then
+ if module_has_method(module, method) then
local f = module.module[method];
return pcall(f, ...);
else
@@ -287,7 +291,7 @@ function call_module_method(module, method, ...)
end
----- API functions exposed to modules -----------
--- Must all be in api.*
+-- Must all be in api.*
-- Returns the name of the current module
function api:get_name()
@@ -400,6 +404,85 @@ function api:get_option(name, default_value)
return value;
end
+function api:get_option_string(...)
+ local value = self:get_option(...);
+ if type(value) == "table" then
+ if #value > 1 then
+ self:log("error", "Config option '%s' does not take a list, using just the first item", name);
+ end
+ value = value[1];
+ end
+ if value == nil then
+ return nil;
+ end
+ return tostring(value);
+end
+
+function api:get_option_number(name, ...)
+ local value = self:get_option(name, ...);
+ if type(value) == "table" then
+ if #value > 1 then
+ self:log("error", "Config option '%s' does not take a list, using just the first item", name);
+ end
+ value = value[1];
+ end
+ local ret = tonumber(value);
+ if value ~= nil and ret == nil then
+ self:log("error", "Config option '%s' not understood, expecting a number", name);
+ end
+ return ret;
+end
+
+function api:get_option_boolean(name, ...)
+ local value = self:get_option(name, ...);
+ if type(value) == "table" then
+ if #value > 1 then
+ self:log("error", "Config option '%s' does not take a list, using just the first item", name);
+ end
+ value = value[1];
+ end
+ if value == nil then
+ return nil;
+ end
+ local ret = value == true or value == "true" or value == 1 or nil;
+ if ret == nil then
+ ret = (value == false or value == "false" or value == 0);
+ if ret then
+ ret = false;
+ else
+ ret = nil;
+ end
+ end
+ if ret == nil then
+ self:log("error", "Config option '%s' not understood, expecting true/false", name);
+ end
+ return ret;
+end
+
+function api:get_option_array(name, ...)
+ local value = self:get_option(name, ...);
+
+ if value == nil then
+ return nil;
+ end
+
+ if type(value) ~= "table" then
+ return array{ value }; -- Assume any non-list is a single-item list
+ end
+
+ return array():append(value); -- Clone
+end
+
+function api:get_option_set(name, ...)
+ local value = self:get_option_array(name, ...);
+
+ if value == nil then
+ return nil;
+ end
+
+ return set.new(value);
+end
+
local t_remove = _G.table.remove;
local module_items = multitable_new();
function api:add_item(key, value)
diff --git a/core/objectmanager.lua b/core/objectmanager.lua
index e96cbd90..293622c9 100644
--- a/core/objectmanager.lua
+++ b/core/objectmanager.lua
@@ -6,63 +6,63 @@
-- COPYING file in the source package for more information.
--
-
-local new_multitable = require "util.multitable".new;
-local t_insert = table.insert;
-local t_concat = table.concat;
-local tostring = tostring;
-local unpack = unpack;
-local pairs = pairs;
-local error = error;
-local type = type;
-local _G = _G;
-
-local data = new_multitable();
-
-module "objectmanager"
-
-function set(...)
- return data:set(...);
-end
-function remove(...)
- return data:remove(...);
-end
-function get(...)
- return data:get(...);
-end
-
-local function get_path(path)
- if type(path) == "table" then return path; end
- local s = {};
- for part in tostring(path):gmatch("[%w_]+") do
- t_insert(s, part);
- end
- return s;
-end
-
-function get_object(path)
- path = get_path(path)
- return data:get(unpack(path)), path;
-end
-function set_object(path, object)
- path = get_path(path);
- data:set(unpack(path), object);
-end
-
-data:set("ls", function(_dir)
- local obj, dir = get_object(_dir);
- if not obj then error("object not found: " .. t_concat(dir, '/')); end
- local r = {};
- if type(obj) == "table" then
- for key, val in pairs(obj) do
- r[key] = type(val);
- end
- end
- return r;
-end);
-data:set("get", get_object);
-data:set("set", set_object);
-data:set("echo", function(...) return {...}; end);
-data:set("_G", _G);
-
-return _M;
+
+local new_multitable = require "util.multitable".new;
+local t_insert = table.insert;
+local t_concat = table.concat;
+local tostring = tostring;
+local unpack = unpack;
+local pairs = pairs;
+local error = error;
+local type = type;
+local _G = _G;
+
+local data = new_multitable();
+
+module "objectmanager"
+
+function set(...)
+ return data:set(...);
+end
+function remove(...)
+ return data:remove(...);
+end
+function get(...)
+ return data:get(...);
+end
+
+local function get_path(path)
+ if type(path) == "table" then return path; end
+ local s = {};
+ for part in tostring(path):gmatch("[%w_]+") do
+ t_insert(s, part);
+ end
+ return s;
+end
+
+function get_object(path)
+ path = get_path(path)
+ return data:get(unpack(path)), path;
+end
+function set_object(path, object)
+ path = get_path(path);
+ data:set(unpack(path), object);
+end
+
+data:set("ls", function(_dir)
+ local obj, dir = get_object(_dir);
+ if not obj then error("object not found: " .. t_concat(dir, '/')); end
+ local r = {};
+ if type(obj) == "table" then
+ for key, val in pairs(obj) do
+ r[key] = type(val);
+ end
+ end
+ return r;
+end);
+data:set("get", get_object);
+data:set("set", set_object);
+data:set("echo", function(...) return {...}; end);
+data:set("_G", _G);
+
+return _M;
diff --git a/core/s2smanager.lua b/core/s2smanager.lua
index 20d932e8..f4d46802 100644
--- a/core/s2smanager.lua
+++ b/core/s2smanager.lua
@@ -36,13 +36,12 @@ local log = logger_init("s2smanager");
local sha256_hash = require "util.hashes".sha256;
-local dialback_secret = uuid_gen();
-
local adns, dns = require "net.adns", require "net.dns";
local config = require "core.configmanager";
local connect_timeout = config.get("*", "core", "s2s_timeout") or 60;
local dns_timeout = config.get("*", "core", "dns_timeout") or 60;
local max_dns_depth = config.get("*", "core", "dns_max_depth") or 3;
+local dialback_secret = config.get("*", "core", "dialback_secret") or uuid_gen();
incoming_s2s = {};
_G.prosody.incoming_s2s = incoming_s2s;
@@ -132,7 +131,7 @@ function new_incoming(conn)
open_sessions = open_sessions + 1;
local w, log = conn.write, logger_init("s2sin"..tostring(conn):match("[a-f0-9]+$"));
session.log = log;
- session.sends2s = function (t) log("debug", "sending: %s", tostring(t)); w(tostring(t)); end
+ session.sends2s = function (t) log("debug", "sending: %s", t.top_tag and t:top_tag() or t:match("^([^>]*>?)")); w(conn, tostring(t)); end
incoming_s2s[session] = true;
add_task(connect_timeout, function ()
if session.conn ~= conn or
@@ -321,9 +320,9 @@ function make_connect(host_session, connect_host, connect_port)
cl.register_outgoing(conn, host_session);
local w, log = conn.write, host_session.log;
- host_session.sends2s = function (t) log("debug", "sending: %s", tostring(t)); w(tostring(t)); end
+ host_session.sends2s = function (t) log("debug", "sending: %s", (t.top_tag and t:top_tag()) or t:match("^[^>]*>?")); w(conn, tostring(t)); end
- conn.write(format([[<stream:stream xmlns='jabber:server' xmlns:db='jabber:server:dialback' xmlns:stream='http://etherx.jabber.org/streams' from='%s' to='%s' version='1.0' xml:lang='en'>]], from_host, to_host));
+ conn:write(format([[<stream:stream xmlns='jabber:server' xmlns:db='jabber:server:dialback' xmlns:stream='http://etherx.jabber.org/streams' from='%s' to='%s' version='1.0' xml:lang='en'>]], from_host, to_host));
log("debug", "Connection attempt in progress...");
add_task(connect_timeout, function ()
if host_session.conn ~= conn or
diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua
index 5e7fe06d..69160af7 100644
--- a/core/sessionmanager.lua
+++ b/core/sessionmanager.lua
@@ -10,7 +10,6 @@
local tonumber, tostring = tonumber, tostring;
local ipairs, pairs, print, next= ipairs, pairs, print, next;
-local collectgarbage = collectgarbage;
local format = import("string", "format");
local hosts = hosts;
@@ -50,8 +49,8 @@ function new_session(conn)
open_sessions = open_sessions + 1;
log("debug", "open sessions now: ".. open_sessions);
local w = conn.write;
- session.send = function (t) w(tostring(t)); end
- session.ip = conn.ip();
+ session.send = function (t) w(conn, tostring(t)); end
+ session.ip = conn:ip();
local conn_name = "c2s"..tostring(conn):match("[a-f0-9]+$");
session.log = logger.init(conn_name);
diff --git a/core/stanza_router.lua b/core/stanza_router.lua
index 00c37ed7..ad312b85 100644
--- a/core/stanza_router.lua
+++ b/core/stanza_router.lua
@@ -180,7 +180,7 @@ function core_route_stanza(origin, stanza)
local xmlns = stanza.attr.xmlns;
--stanza.attr.xmlns = "jabber:server";
stanza.attr.xmlns = nil;
- log("debug", "sending s2s stanza: %s", tostring(stanza));
+ log("debug", "sending s2s stanza: %s", tostring(stanza.top_tag and stanza:top_tag()) or stanza);
send_s2s(origin.host, host, stanza); -- TODO handle remote routing errors
stanza.attr.xmlns = xmlns; -- reset
else