diff options
-rw-r--r-- | Makefile | 26 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | core/configmanager.lua | 10 | ||||
-rw-r--r-- | core/modulemanager.lua | 5 | ||||
-rw-r--r-- | core/presencemanager.lua | 92 | ||||
-rw-r--r-- | core/stanza_router.lua | 72 | ||||
-rw-r--r-- | net/connlisteners.lua | 5 | ||||
-rwxr-xr-x | prosody | 23 | ||||
-rw-r--r-- | prosody.cfg.lua.dist (renamed from lxmppd.cfg.lua.dist) | 11 | ||||
-rw-r--r-- | tests/test.lua | 1 |
10 files changed, 153 insertions, 94 deletions
@@ -4,18 +4,32 @@ include config.unix BIN = $(DESTDIR)$(PREFIX)/bin CONFIG = $(DESTDIR)$(SYSCONFDIR) MODULES = $(DESTDIR)$(PREFIX)/lib/prosody/modules - -SOURCEDIR = $(DESTDIR)$(PREFIX)/lib/prosody +SOURCE = $(DESTDIR)$(PREFIX)/lib/prosody all: $(MAKE) all -C util-src -install: prosody - install -d $(BIN) $(CONFIG) $(MODULES) - install ./prosody $(BIN) +install: prosody.install util/encodings.so util/encodings.so + install -d $(BIN) $(CONFIG) $(MODULES) $(SOURCE) + install -d $(SOURCE)/core $(SOURCE)/net $(SOURCE)/util + install ./prosody.install $(BIN)/prosody + install -m644 core/* $(SOURCE)/core + install -m644 net/* $(SOURCE)/net + install -m644 util/* $(SOURCE)/util install -m644 plugins/* $(MODULES) - install -m644 prosody.cfg.lua $(CONFIG) + install -m644 prosody.cfg.lua.dist $(CONFIG)/prosody.cfg.lua $(MAKE) install -C util-src clean: + rm -f prosody.install $(MAKE) clean -C util-src + +util/encodings.so: + $(MAKE) install -C util-src + +util/hashes.so: + $(MAKE) install -C util-src + +prosody.install: prosody + sed "s|^CFG_SOURCEDIR=.*;$$|CFG_SOURCEDIR='$(SOURCE)';|;s|^CFG_CONFIGDIR=.*;$$|CFG_CONFIGDIR='$(CONFIG)';|;s|^CFG_PLUGINDIR=.*;$$|CFG_PLUGINDIR='$(MODULES)/';|;" prosody > prosody.install + @@ -125,7 +125,7 @@ find_program() { if [ "$LUA_SUFFIX_SET" != "yes" ] then - for suffix in "" "5.1" "51" "" + for suffix in "5.1" "51" "" do LUA_SUFFIX="$suffix" if [ "$LUA_DIR_SET" = "yes" ] diff --git a/core/configmanager.lua b/core/configmanager.lua index 5f5648b9..a4a24fad 100644 --- a/core/configmanager.lua +++ b/core/configmanager.lua @@ -2,6 +2,7 @@ local _G = _G; local setmetatable, loadfile, pcall, rawget, rawset, io = setmetatable, loadfile, pcall, rawget, rawset, io; + module "configmanager" local parsers = {}; @@ -52,18 +53,21 @@ end function load(filename, format) format = format or filename:match("%w+$"); + if parsers[format] and parsers[format].load then - local f = io.open(filename); + local f, err = io.open(filename); if f then local ok, err = parsers[format].load(f:read("*a")); f:close(); return ok, err; end + return f, err; end + if not format then return nil, "no parser specified"; else - return false, "no parser"; + return nil, "no parser for "..(format); end end @@ -118,4 +122,4 @@ do end -return _M;
\ No newline at end of file +return _M; diff --git a/core/modulemanager.lua b/core/modulemanager.lua index ce34f3e6..31059512 100644 --- a/core/modulemanager.lua +++ b/core/modulemanager.lua @@ -1,4 +1,5 @@ +local plugin_dir = CFG_PLUGINDIR or "./plugins/"; local logger = require "util.logger"; local log = logger.init("modulemanager") @@ -11,8 +12,8 @@ local type = type; local tostring, print = tostring, print; +-- We need this to let modules access the real global namespace local _G = _G; -local debug = debug; module "modulemanager" @@ -30,7 +31,7 @@ function load(host, module_name, config) if not (host and module_name) then return nil, "insufficient-parameters"; end - local mod, err = loadfile("plugins/mod_"..module_name..".lua"); + local mod, err = loadfile(plugin_dir.."mod_"..module_name..".lua"); if not mod then log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil"); return nil, err; diff --git a/core/presencemanager.lua b/core/presencemanager.lua index c6619fea..bf62d78d 100644 --- a/core/presencemanager.lua +++ b/core/presencemanager.lua @@ -2,7 +2,10 @@ local log = require "util.logger".init("presencemanager")
local require = require;
-local pairs = pairs;
+local pairs, ipairs = pairs, ipairs;
+local t_concat = table.concat;
+local s_find = string.find;
+local tonumber = tonumber;
local st = require "util.stanza";
local jid_split = require "util.jid".split;
@@ -10,9 +13,96 @@ local hosts = hosts; local rostermanager = require "core.rostermanager";
local sessionmanager = require "core.sessionmanager";
+local offlinemanager = require "core.offlinemanager";
module "presencemanager"
+function handle_presence(origin, stanza, from_bare, to_bare, core_route_stanza, inbound)
+ local type = stanza.attr.type;
+ if type and type ~= "unavailable" then
+ if inbound then
+ handle_inbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza);
+ else
+ handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza);
+ end
+ elseif not inbound and not stanza.attr.to then
+ handle_normal_presence(origin, stanza, core_route_stanza);
+ else
+ core_route_stanza(origin, stanza);
+ end
+end
+
+function handle_normal_presence(origin, stanza, core_route_stanza)
+ if origin.roster then
+ for jid in pairs(origin.roster) do -- broadcast to all interested contacts
+ local subscription = origin.roster[jid].subscription;
+ if subscription == "both" or subscription == "from" then
+ stanza.attr.to = jid;
+ core_route_stanza(origin, stanza);
+ end
+ end
+ local node, host = jid_split(stanza.attr.from);
+ for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast to all resources
+ if res ~= origin and res.full_jid then -- to resource. FIXME is res.full_jid the correct check? Maybe it should be res.presence
+ stanza.attr.to = res.full_jid;
+ core_route_stanza(origin, stanza);
+ end
+ end
+ if stanza.attr.type == nil and not origin.presence then -- initial presence
+ local probe = st.presence({from = origin.full_jid, type = "probe"});
+ for jid in pairs(origin.roster) do -- probe all contacts we are subscribed to
+ local subscription = origin.roster[jid].subscription;
+ if subscription == "both" or subscription == "to" then
+ probe.attr.to = jid;
+ core_route_stanza(origin, probe);
+ end
+ end
+ for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast from all available resources
+ if res ~= origin and res.presence then
+ res.presence.attr.to = origin.full_jid;
+ core_route_stanza(res, res.presence);
+ res.presence.attr.to = nil;
+ end
+ end
+ if origin.roster.pending then -- resend incoming subscription requests
+ for jid in pairs(origin.roster.pending) do
+ origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original?
+ end
+ end
+ local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host});
+ for jid, item in pairs(origin.roster) do -- resend outgoing subscription requests
+ if item.ask then
+ request.attr.to = jid;
+ core_route_stanza(origin, request);
+ end
+ end
+ for _, msg in ipairs(offlinemanager.load(node, host) or {}) do
+ origin.send(msg); -- FIXME do we need to modify to/from in any way?
+ end
+ offlinemanager.deleteAll(node, host);
+ end
+ origin.priority = 0;
+ if stanza.attr.type == "unavailable" then
+ origin.presence = nil;
+ else
+ origin.presence = stanza;
+ local priority = stanza:child_with_name("priority");
+ if priority and #priority > 0 then
+ priority = t_concat(priority);
+ if s_find(priority, "^[+-]?[0-9]+$") then
+ priority = tonumber(priority);
+ if priority < -128 then priority = -128 end
+ if priority > 127 then priority = 127 end
+ origin.priority = priority;
+ end
+ end
+ end
+ stanza.attr.to = nil; -- reset it
+ else
+ log("error", "presence recieved from client with no roster");
+ end
+end
+
function send_presence_of_available_resources(user, host, jid, recipient_session, core_route_stanza)
local h = hosts[host];
local count = 0;
diff --git a/core/stanza_router.lua b/core/stanza_router.lua index 308ae2f4..ca35b38a 100644 --- a/core/stanza_router.lua +++ b/core/stanza_router.lua @@ -17,6 +17,7 @@ local component_handle_stanza = require "core.componentmanager".handle_stanza; local handle_outbound_presence_subscriptions_and_probes = require "core.presencemanager".handle_outbound_presence_subscriptions_and_probes; local handle_inbound_presence_subscriptions_and_probes = require "core.presencemanager".handle_inbound_presence_subscriptions_and_probes; +local handle_normal_presence = require "core.presencemanager".handle_normal_presence; local format = string.format; local tostring = tostring; @@ -105,70 +106,7 @@ function core_handle_stanza(origin, stanza) if stanza.name == "presence" and origin.roster then if stanza.attr.type == nil or stanza.attr.type == "unavailable" then - for jid in pairs(origin.roster) do -- broadcast to all interested contacts - local subscription = origin.roster[jid].subscription; - if subscription == "both" or subscription == "from" then - stanza.attr.to = jid; - core_route_stanza(origin, stanza); - end - end - local node, host = jid_split(stanza.attr.from); - for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast to all resources - if res ~= origin and res.full_jid then -- to resource. FIXME is res.full_jid the correct check? Maybe it should be res.presence - stanza.attr.to = res.full_jid; - core_route_stanza(origin, stanza); - end - end - if stanza.attr.type == nil and not origin.presence then -- initial presence - local probe = st.presence({from = origin.full_jid, type = "probe"}); - for jid in pairs(origin.roster) do -- probe all contacts we are subscribed to - local subscription = origin.roster[jid].subscription; - if subscription == "both" or subscription == "to" then - probe.attr.to = jid; - core_route_stanza(origin, probe); - end - end - for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast from all available resources - if res ~= origin and res.presence then - res.presence.attr.to = origin.full_jid; - core_route_stanza(res, res.presence); - res.presence.attr.to = nil; - end - end - if origin.roster.pending then -- resend incoming subscription requests - for jid in pairs(origin.roster.pending) do - origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original? - end - end - local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); - for jid, item in pairs(origin.roster) do -- resend outgoing subscription requests - if item.ask then - request.attr.to = jid; - core_route_stanza(origin, request); - end - end - for _, msg in ipairs(offlinemanager.load(node, host) or {}) do - origin.send(msg); -- FIXME do we need to modify to/from in any way? - end - offlinemanager.deleteAll(node, host); - end - origin.priority = 0; - if stanza.attr.type == "unavailable" then - origin.presence = nil; - else - origin.presence = stanza; - local priority = stanza:child_with_name("priority"); - if priority and #priority > 0 then - priority = t_concat(priority); - if s_find(priority, "^[+-]?[0-9]+$") then - priority = tonumber(priority); - if priority < -128 then priority = -128 end - if priority > 127 then priority = 127 end - origin.priority = priority; - end - end - end - stanza.attr.to = nil; -- reset it + handle_normal_presence(origin, stanza, core_route_stanza); else log("warn", "Unhandled c2s presence: %s", tostring(stanza)); if (stanza.attr.xmlns == "jabber:client" or stanza.attr.xmlns == "jabber:server") and stanza.attr.type ~= "error" then @@ -304,9 +242,3 @@ function core_route_stanza(origin, stanza) end stanza.attr.to = to; -- reset end - -function handle_stanza_toremote(stanza) - log("error", "Stanza bound for remote host, but s2s is not implemented"); -end - - diff --git a/net/connlisteners.lua b/net/connlisteners.lua index 2b95331c..a02dd2a6 100644 --- a/net/connlisteners.lua +++ b/net/connlisteners.lua @@ -1,4 +1,5 @@ +local listeners_dir = (CFG_SOURCEDIR or ".").."/net/"; local server_add = require "net.server".add; local log = require "util.logger".init("connlisteners"); @@ -26,7 +27,7 @@ end function get(name) local h = listeners[name]; if not h then - pcall(dofile, "net/"..name:gsub("[^%w%-]", "_").."_listener.lua"); + pcall(dofile, listeners_dir..name:gsub("[^%w%-]", "_").."_listener.lua"); h = listeners[name]; end return h; @@ -42,4 +43,4 @@ function start(name, udata) (udata and udata.interface) or "*", (udata and udata.mode) or h.default_mode or 1, (udata and udata.ssl) or nil ); end -return _M;
\ No newline at end of file +return _M; @@ -2,15 +2,32 @@ -- Config here -- - +CFG_SOURCEDIR=nil; +CFG_CONFIGDIR=nil; +CFG_PLUGINDIR=nil; -- -- -- -- -- -- if CFG_SOURCEDIR then + if os.getenv("HOME") then + CFG_SOURCEDIR = CFG_SOURCEDIR:gsub("^~", os.getenv("HOME")); + end package.path = CFG_SOURCEDIR.."/?.lua;"..package.path - package.cpath = CFG_SOURCEDIR.."/?.lua;"..package.cpath + package.cpath = CFG_SOURCEDIR.."/?.so;"..package.cpath end +if CFG_CONFIGDIR then + if os.getenv("HOME") then + CFG_CONFIGDIR = CFG_CONFIGDIR:gsub("^~", os.getenv("HOME")); + end +end + +if CFG_PLUGINDIR then + if os.getenv("HOME") then + CFG_PLUGINDIR = CFG_PLUGINDIR:gsub("^~", os.getenv("HOME")); + end +end + -- Required to be able to find packages installed with luarocks pcall(require, "luarocks.require") @@ -21,7 +38,7 @@ log = require "util.logger".init("general"); do -- TODO: Check for other formats when we add support for them -- Use lfs? Make a new conf/ dir? - local ok, err = config.load("lxmppd.cfg.lua"); + local ok, err = config.load((CFG_CONFIGDIR or ".").."/prosody.cfg.lua"); if not ok then log("error", "Couldn't load config file: %s", err); log("info", "Falling back to old config file format...") diff --git a/lxmppd.cfg.lua.dist b/prosody.cfg.lua.dist index d2c6d3ff..7b9fe4dd 100644 --- a/lxmppd.cfg.lua.dist +++ b/prosody.cfg.lua.dist @@ -1,7 +1,7 @@ --- lxmppd Example Configuration File +-- Prosody Example Configuration File -- -- If it wasn't already obvious, -- starts a comment, and all --- text after it is ignored by lxmppd. +-- text after it is ignored by Prosody. -- -- The config is split into sections, a global section, and one -- for each defined host that we serve. You can add as many host @@ -23,7 +23,7 @@ --sonsIdon'trecommendit. -- -- Tip: You can check that the syntax of this file is correct when you have finished --- by running: luac -p lxmppd.cfg.lua +-- by running: luac -p prosody.cfg.lua -- If there are any errors, it will let you know what and where they are, otherwise it -- will keep quiet. -- @@ -33,8 +33,8 @@ -- Global settings go in this section Host "*" - -- This is the list of modules lxmppd will load on startup. - -- It looks for plugins/mod_modulename.lua, so make sure that exists too. + -- This is the list of modules Prosody will load on startup. + -- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too. modules_enabled = { "saslauth"; -- Authentication for clients and servers. Recommended if you want to log in. "legacyauth"; -- Legacy authentication. Only used by some old clients and bots. @@ -69,6 +69,5 @@ Host "example.com" certificate = "certs/example.com.crt"; } -Host "example.org" enabled = false -- This will disable the host, preserving the config, but denying connections diff --git a/tests/test.lua b/tests/test.lua index 33af3e98..19aa8389 100644 --- a/tests/test.lua +++ b/tests/test.lua @@ -9,6 +9,7 @@ end local verbosity = tonumber(arg[1]) or 2; package.path = package.path..";../?.lua"; +package.cpath = package.cpath..";../?.so"; require "util.import" |