diff options
-rw-r--r-- | core/eventmanager.lua | 25 | ||||
-rw-r--r-- | core/hostmanager.lua | 49 | ||||
-rw-r--r-- | core/modulemanager.lua | 25 | ||||
-rw-r--r-- | core/sessionmanager.lua | 10 | ||||
-rwxr-xr-x | prosody | 79 | ||||
-rw-r--r-- | tests/test.lua | 25 |
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); @@ -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; |