mod_pep: Fix undefined global access
[prosody.git] / plugins / mod_presence.lua
index 2fb976b50f634fca8536954ca1689ababdfcf61f..623000625d78276b55f67afe7d076118f6bc6ad1 100644 (file)
@@ -6,9 +6,7 @@
 -- COPYING file in the source package for more information.\r
 --\r
 \r
-\r
-\r
-local log = require "util.logger".init("mod_presence")\r
+local log = module._log;\r
 \r
 local require = require;\r
 local pairs, ipairs = pairs, ipairs;\r
@@ -134,7 +132,7 @@ function handle_normal_presence(origin, stanza, core_route_stanza)
                end\r
                stanza.attr.to = nil; -- reset it\r
        else\r
-               log("error", "presence recieved from client with no roster");\r
+               log("warn", "presence recieved from client with no roster");\r
        end\r
 end\r
 \r
@@ -148,16 +146,14 @@ function send_presence_of_available_resources(user, host, jid, recipient_session
                                local pres = session.presence;\r
                                if pres then\r
                                        pres.attr.to = jid;\r
-                                       pres.attr.from = session.full_jid;\r
                                        core_route_stanza(session, pres);\r
                                        pres.attr.to = nil;\r
-                                       pres.attr.from = nil;\r
                                        count = count + 1;\r
                                end\r
                        end\r
                end\r
        end\r
-       log("info", "broadcasted presence of "..count.." resources from "..user.."@"..host.." to "..jid);\r
+       log("debug", "broadcasted presence of "..count.." resources from "..user.."@"..host.." to "..jid);\r
        return count;\r
 end\r
 \r
@@ -252,7 +248,7 @@ local function presence_handler(data)
        if origin.type == "c2s" then\r
                if to ~= nil and not(origin.roster[to_bare] and (origin.roster[to_bare].subscription == "both" or origin.roster[to_bare].subscription == "from")) then -- directed presence\r
                        origin.directed = origin.directed or {};\r
-                       origin.directed[to] = true;\r
+                       origin.directed[to] = true; -- FIXME does it make more sense to add to_bare rather than to?\r
                end\r
                if stanza.attr.type ~= nil and stanza.attr.type ~= "unavailable" and stanza.attr.type ~= "error" then\r
                        handle_outbound_presence_subscriptions_and_probes(origin, stanza, from_bare, to_bare, core_route_stanza);\r
@@ -268,12 +264,81 @@ local function presence_handler(data)
                        core_route_stanza(origin, stanza);\r
                end\r
        end\r
+       return true;\r
 end\r
 \r
-local add_handler = require "core.eventmanager2".add_handler;\r
-local remove_handler = require "core.eventmanager2".remove_handler;\r
-\r
-add_handler(module:get_host().."/presence", presence_handler);\r
+prosody.events.add_handler(module:get_host().."/presence", presence_handler);\r
 module.unload = function()\r
-       remove_handler(module:get_host().."/presence", presence_handler);\r
+       prosody.events.remove_handler(module:get_host().."/presence", presence_handler);\r
+end\r
+\r
+local outbound_presence_handler = function(data)\r
+       -- outbound presence recieved\r
+       local origin, stanza = data.origin, data.stanza;\r
+\r
+       local to = stanza.attr.to;\r
+       if to then\r
+               local t = stanza.attr.type;\r
+               if t ~= nil and t ~= "unavailable" and t ~= "error" then -- check for subscriptions and probes\r
+                       handle_outbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to), core_route_stanza);\r
+                       return true;\r
+               end\r
+\r
+               local to_bare = jid_bare(to);\r
+               if not(origin.roster[to_bare] and (origin.roster[to_bare].subscription == "both" or origin.roster[to_bare].subscription == "from")) then -- directed presence\r
+                       origin.directed = origin.directed or {};\r
+                       if t then -- removing from directed presence list on sending an error or unavailable\r
+                               origin.directed[to] = nil; -- FIXME does it make more sense to add to_bare rather than to?\r
+                       else\r
+                               origin.directed[to] = true; -- FIXME does it make more sense to add to_bare rather than to?\r
+                       end\r
+               end\r
+       end -- TODO maybe handle normal presence here, instead of letting it pass to incoming handlers?\r
 end\r
+\r
+module:hook("pre-presence/full", outbound_presence_handler);\r
+module:hook("pre-presence/bare", outbound_presence_handler);\r
+module:hook("pre-presence/host", outbound_presence_handler);\r
+\r
+module:hook("presence/bare", function(data)\r
+       -- inbound presence to bare JID recieved\r
+       local origin, stanza = data.origin, data.stanza;\r
+\r
+       local to = stanza.attr.to;\r
+       local t = stanza.attr.type;\r
+       if to then\r
+               if t ~= nil and t ~= "unavailable" and t ~= "error" then -- check for subscriptions and probes sent to bare JID\r
+                       handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to), core_route_stanza);\r
+                       return true;\r
+               end\r
+       \r
+               local user = bare_sessions[to];\r
+               if user then\r
+                       for _, session in pairs(user.sessions) do\r
+                               if session.presence then -- only send to available resources\r
+                                       session.send(stanza);\r
+                               end\r
+                       end\r
+               end -- no resources not online, discard\r
+       elseif not t or t == "unavailable" then\r
+               handle_normal_presence(origin, stanza, core_route_stanza);\r
+       end\r
+       return true;\r
+end);\r
+module:hook("presence/full", function(data)\r
+       -- inbound presence to full JID recieved\r
+       local origin, stanza = data.origin, data.stanza;\r
+\r
+       local t = stanza.attr.type;\r
+       if t ~= nil and t ~= "unavailable" and t ~= "error" then -- check for subscriptions and probes sent to full JID\r
+               handle_inbound_presence_subscriptions_and_probes(origin, stanza, jid_bare(stanza.attr.from), jid_bare(stanza.attr.to), core_route_stanza);\r
+               return true;\r
+       end\r
+\r
+       local session = full_sessions[stanza.attr.to];\r
+       if session then\r
+               -- TODO fire post processing event\r
+               session.send(stanza);\r
+       end -- resource not online, discard\r
+       return true;\r
+end);\r