aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/eventmanager.lua25
-rw-r--r--core/hostmanager.lua49
-rw-r--r--core/modulemanager.lua25
-rw-r--r--core/sessionmanager.lua10
-rwxr-xr-xprosody79
-rw-r--r--tests/test.lua25
6 files changed, 151 insertions, 62 deletions
diff --git a/core/eventmanager.lua b/core/eventmanager.lua
new file mode 100644
index 00000000..169be8e9
--- /dev/null
+++ b/core/eventmanager.lua
@@ -0,0 +1,25 @@
+
+local t_insert = table.insert;
+local ipairs = ipairs;
+
+module "eventmanager"
+
+local event_handlers = {};
+
+function add_event_hook(name, handler)
+ if not event_handlers[name] then
+ event_handlers[name] = {};
+ end
+ t_insert(event_handlers[name] , handler);
+end
+
+function fire_event(name, ...)
+ local event_handlers = event_handlers[name];
+ if event_handlers then
+ for name, handler in ipairs(event_handlers) do
+ handler(...);
+ end
+ end
+end
+
+return _M; \ No newline at end of file
diff --git a/core/hostmanager.lua b/core/hostmanager.lua
new file mode 100644
index 00000000..a46da058
--- /dev/null
+++ b/core/hostmanager.lua
@@ -0,0 +1,49 @@
+
+hosts = {};
+
+local hosts = hosts;
+local configmanager = require "core.configmanager";
+local eventmanager = require "core.eventmanager";
+
+local pairs = pairs;
+
+module "hostmanager"
+
+local function load_enabled_hosts(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) then
+ activate(host, host_config);
+ end
+ end
+end
+
+eventmanager.add_event_hook("server-starting", load_enabled_hosts);
+
+function activate(host, host_config)
+ hosts[host] = {type = "local", connected = true, sessions = {}, host = host, s2sout = {} };
+
+ eventmanager.fire_event("host-activated", host, host_config);
+end
+
+function deactivate(host)
+ local host_session = hosts[host];
+
+ eventmanager.fire_event("host-deactivating", host, host_session);
+
+ -- Disconnect local users, s2s connections
+ for user, session_list in pairs(host_session.sessions) do
+ for resource, session in pairs(session_list) do
+ session:close("host-gone");
+ end
+ end
+ -- Components?
+
+ hosts[host] = nil;
+ eventmanager.fire_event("host-deactivated", host);
+end
+
+function getconfig(name)
+end
+
diff --git a/core/modulemanager.lua b/core/modulemanager.lua
index 532a0f86..aa59b9da 100644
--- a/core/modulemanager.lua
+++ b/core/modulemanager.lua
@@ -24,6 +24,8 @@ local plugin_dir = CFG_PLUGINDIR or "./plugins/";
local logger = require "util.logger";
local log = logger.init("modulemanager");
local addDiscoInfoHandler = require "core.discomanager".addDiscoInfoHandler;
+local eventmanager = require "core.eventmanager";
+
local loadfile, pcall = loadfile, pcall;
local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv;
@@ -182,28 +184,7 @@ function api:add_feature(xmlns)
end);
end
-
-do
- local event_handlers = {};
-
- function api:add_event_hook(name, handler)
- if not event_handlers[name] then
- event_handlers[name] = {};
- end
- t_insert(event_handlers[name] , handler);
- self:log("debug", "Subscribed to %s", name);
- end
-
- function fire_event(name, ...)
- local event_handlers = event_handlers[name];
- if event_handlers then
- for name, handler in ipairs(event_handlers) do
- handler(...);
- end
- end
- end
-end
-
+api.add_event_hook = eventmanager.add_event_hook;
local function _add_handler(module, origin_type, tag, xmlns, handler)
local handlers = stanza_handlers[module.host];
diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua
index 36111633..74a17fe5 100644
--- a/core/sessionmanager.lua
+++ b/core/sessionmanager.lua
@@ -35,6 +35,10 @@ local uuid_generate = require "util.uuid".generate;
local rm_load_roster = require "core.rostermanager".load_roster;
local config_get = require "core.configmanager".get;
+local fire_event = require "core.eventmanager".fire_event;
+
+local gettime = require "socket".gettime;
+
local st = require "util.stanza";
local newproxy = newproxy;
@@ -45,7 +49,7 @@ module "sessionmanager"
local open_sessions = 0;
function new_session(conn)
- local session = { conn = conn, priority = 0, type = "c2s_unauthed" };
+ local session = { conn = conn, priority = 0, type = "c2s_unauthed", conntime = gettime() };
if true then
session.trace = newproxy(true);
getmetatable(session.trace).__gc = function () open_sessions = open_sessions - 1; print("Session got collected, now "..open_sessions.." sessions are allocated") end;
@@ -109,6 +113,8 @@ function bind_resource(session, resource)
if session.resource then return nil, "cancel", "already-bound", "Cannot bind multiple resources on a single connection"; end
-- We don't support binding multiple resources
+ session.conntimetotal = gettime()-session.conntime;
+
resource = resource or uuid_generate();
--FIXME: Randomly-generated resources must be unique per-user, and never conflict with existing
@@ -175,7 +181,7 @@ function streamopened(session, attr)
local features = st.stanza("stream:features");
- modulemanager.fire_event("stream-features", session, features);
+ fire_event("stream-features", session, features);
send(features);
diff --git a/prosody b/prosody
index 08b0d936..9fd5e4ff 100755
--- a/prosody
+++ b/prosody
@@ -68,29 +68,6 @@ do
end
end
-local data_path = config.get("*", "core", "data_path") or CFG_DATADIR or "data";
-local path_separator = "/"; if os.getenv("WINDIR") then path_separator = "\\" end
-local _mkdir = {}
-function mkdir(path)
- path = path:gsub("/", path_separator);
- --print("mkdir",path);
- local x = io.popen("mkdir \""..path.."\" 2>&1"):read("*a");
-end
-function encode(s) return s and (s:gsub("%W", function (c) return string.format("%%%x", c:byte()); end)); end
-function mkdirs(host)
- if not _mkdir[host] then
- local host_dir = string.format("%s/%s", data_path, encode(host));
- mkdir(host_dir);
- mkdir(host_dir.."/accounts");
- mkdir(host_dir.."/vcard");
- mkdir(host_dir.."/roster");
- mkdir(host_dir.."/private");
- mkdir(host_dir.."/offline");
- _mkdir[host] = true;
- end
-end
-mkdir(data_path);
-
require "util.datamanager".set_data_path(data_path);
local server = require "net.server"
@@ -101,14 +78,6 @@ require "util.dependencies"
sessions = {};
hosts = {};
-local defined_hosts = config.getconfig();
-
-for host, host_config in pairs(defined_hosts) do
- if host ~= "*" and (host_config.core.enabled == nil or host_config.core.enabled) then
- hosts[host] = {type = "local", connected = true, sessions = {}, host = host, s2sout = {} };
- mkdirs(host);
- end
-end
-- Load and initialise core modules --
@@ -116,6 +85,8 @@ require "util.import"
require "core.xmlhandlers"
require "core.rostermanager"
require "core.offlinemessage"
+require "core.eventmanager"
+require "core.hostmanager"
require "core.modulemanager"
require "core.usermanager"
require "core.sessionmanager"
@@ -126,12 +97,44 @@ pcall(require, "remdebug.engine");
if remdebug then remdebug.engine.start() end
]]
-local start = require "net.connlisteners".start;
+local cl = require "net.connlisteners";
+
require "util.stanza"
require "util.jid"
------------------------------------------------------------------------
+------------- Begin code without a home ---------------------
+
+local data_path = config.get("*", "core", "data_path") or CFG_DATADIR or "data";
+local path_separator = "/"; if os.getenv("WINDIR") then path_separator = "\\" end
+local _mkdir = {}
+function mkdir(path)
+ path = path:gsub("/", path_separator);
+ --print("mkdir",path);
+ local x = io.popen("mkdir \""..path.."\" 2>&1"):read("*a");
+end
+function encode(s) return s and (s:gsub("%W", function (c) return string.format("%%%x", c:byte()); end)); end
+function mkdirs(host)
+ if not _mkdir[host] then
+ local host_dir = string.format("%s/%s", data_path, encode(host));
+ mkdir(host_dir);
+ mkdir(host_dir.."/accounts");
+ mkdir(host_dir.."/vcard");
+ mkdir(host_dir.."/roster");
+ mkdir(host_dir.."/private");
+ mkdir(host_dir.."/offline");
+ _mkdir[host] = true;
+ end
+end
+mkdir(data_path);
+
+eventmanager.add_event_hook("host-activated", mkdirs);
+
+----------- End of out-of-place code --------------
+
+eventmanager.fire_event("server-starting");
+
-- Initialise modules
for host in pairs(hosts) do
@@ -159,13 +162,17 @@ if global_ssl_ctx then
end
-- start listening on sockets
-start("xmppclient", { ssl = global_ssl_ctx })
-start("xmppserver", { ssl = global_ssl_ctx })
+cl.start("xmppclient", { ssl = global_ssl_ctx })
+cl.start("xmppserver", { ssl = global_ssl_ctx })
if config.get("*", "core", "console_enabled") then
- start("console")
+ if cl.get("console") then
+ cl.start("console")
+ else
+ log("error", "Console is enabled, but the console module appears not to be loaded");
+ end
end
-modulemanager.fire_event("server-started");
+eventmanager.fire_event("server-started");
server.loop();
diff --git a/tests/test.lua b/tests/test.lua
index 0d69d08b..503ac4a1 100644
--- a/tests/test.lua
+++ b/tests/test.lua
@@ -21,6 +21,7 @@
function run_all_tests()
dotest "util.jid"
+ dotest "util.multitable"
dotest "core.stanza_router"
dotest "core.s2smanager"
dotest "core.configmanager"
@@ -40,14 +41,34 @@ function testlib_new_env(t)
return setmetatable(t or {}, env_mt);
end
-function assert_equal(a, b, message)
+function assert_equal(a, b, message, level)
if not (a == b) then
- error("\n assert_equal failed: "..tostring(a).." ~= "..tostring(b)..(message and ("\n Message: "..message) or ""), 2);
+ error("\n assert_equal failed: "..tostring(a).." ~= "..tostring(b)..(message and ("\n Message: "..message) or ""), (level or 1) + 1);
elseif verbosity >= 4 then
print("assert_equal succeeded: "..tostring(a).." == "..tostring(b));
end
end
+function assert_table(a, message, level)
+ assert_equal(type(a), "table", message, (level or 1) + 1);
+end
+function assert_function(a, message, level)
+ assert_equal(type(a), "function", message, (level or 1) + 1);
+end
+function assert_string(a, message, level)
+ assert_equal(type(a), "string", message, (level or 1) + 1);
+end
+function assert_boolean(a, message)
+ assert_equal(type(a), "boolean", message);
+end
+function assert_is(a, message)
+ assert_equal(not not a, true, message);
+end
+function assert_is_not(a, message)
+ assert_equal(not not a, false, message);
+end
+
+
function dosingletest(testname, fname)
local tests = setmetatable({}, { __index = _G });
tests.__unit = testname;