30
|
1
|
|
2 local log = require "util.logger".init("modulemanager")
|
|
3
|
|
4 local loadfile, pcall = loadfile, pcall;
|
|
5 local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv;
|
|
6 local pairs, ipairs = pairs, ipairs;
|
|
7 local type = type;
|
|
8
|
|
9 local tostring, print = tostring, print;
|
|
10
|
|
11 local _G = _G;
|
|
12
|
|
13 module "modulemanager"
|
|
14
|
|
15 local handler_info = {};
|
|
16 local handlers = {};
|
|
17
|
|
18 local modulehelpers = setmetatable({}, { __index = _G });
|
|
19
|
|
20 function modulehelpers.add_iq_handler(origin_type, xmlns, handler)
|
|
21 handlers[origin_type] = handlers[origin_type] or {};
|
|
22 handlers[origin_type].iq = handlers[origin_type].iq or {};
|
|
23 if not handlers[origin_type].iq[xmlns] then
|
|
24 handlers[origin_type].iq[xmlns]= handler;
|
|
25 handler_info[handler] = getfenv(2).module;
|
38
|
26 log("debug", "mod_%s now handles tag 'iq' with query namespace '%s'", getfenv(2).module.name, xmlns);
|
30
|
27 else
|
38
|
28 log("warning", "mod_%s wants to handle tag 'iq' with query namespace '%s' but mod_%s already handles that", getfenv(2).module.name, xmlns, handler_info[handlers[origin_type].iq[xmlns]].module.name);
|
30
|
29 end
|
|
30 end
|
|
31
|
38
|
32 function modulehelpers.add_handler(origin_type, tag, handler)
|
|
33 handlers[origin_type] = handlers[origin_type] or {};
|
|
34 if not handlers[origin_type][tag] then
|
|
35 handlers[origin_type][tag]= handler;
|
|
36 handler_info[handler] = getfenv(2).module;
|
|
37 log("debug", "mod_%s now handles tag '%s'", getfenv(2).module.name, tag);
|
|
38 elseif handler_info[handlers[origin_type][tag]] then
|
|
39 log("warning", "mod_%s wants to handle tag '%s' but mod_%s already handles that", getfenv(2).module.name, tag, handler_info[handlers[origin_type][tag]].module.name);
|
|
40 end
|
30
|
41 end
|
|
42
|
|
43 function loadall()
|
38
|
44 load("saslauth");
|
30
|
45 load("legacyauth");
|
|
46 load("roster");
|
|
47 end
|
|
48
|
|
49 function load(name)
|
|
50 local mod, err = loadfile("plugins/mod_"..name..".lua");
|
|
51 if not mod then
|
|
52 log("error", "Unable to load module '%s': %s", name or "nil", err or "nil");
|
|
53 return;
|
|
54 end
|
|
55
|
|
56 local pluginenv = setmetatable({ module = { name = name } }, { __index = modulehelpers });
|
|
57
|
|
58 setfenv(mod, pluginenv);
|
|
59 local success, ret = pcall(mod);
|
|
60 if not success then
|
|
61 log("error", "Error initialising module '%s': %s", name or "nil", ret or "nil");
|
|
62 return;
|
|
63 end
|
|
64 end
|
|
65
|
|
66 function handle_stanza(origin, stanza)
|
38
|
67 local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns, origin.type;
|
30
|
68
|
38
|
69 if name == "iq" and xmlns == "jabber:client" and handlers[origin_type] then
|
30
|
70 log("debug", "Stanza is an <iq/>");
|
|
71 local child = stanza.tags[1];
|
|
72 if child then
|
|
73 local xmlns = child.attr.xmlns;
|
|
74 log("debug", "Stanza has xmlns: %s", xmlns);
|
|
75 local handler = handlers[origin_type][name][xmlns];
|
|
76 if handler then
|
|
77 log("debug", "Passing stanza to mod_%s", handler_info[handler].name);
|
|
78 return handler(origin, stanza) or true;
|
|
79 end
|
|
80
|
|
81 end
|
38
|
82 --FIXME: All iq's must be replied to, here we should return service-unavailable I think
|
|
83 elseif handlers[origin_type] then
|
|
84 local handler = handlers[origin_type][name];
|
|
85 if handler then
|
|
86 log("debug", "Passing stanza to mod_%s", handler_info[handler].name);
|
|
87 return handler(origin, stanza) or true;
|
|
88 end
|
30
|
89 end
|
|
90 log("debug", "Stanza unhandled by any modules");
|
|
91 return false; -- we didn't handle it
|
|
92 end
|