- return true;
- end
- return ok, err;
-end
-
-function handle_stanza(host, origin, stanza)
- local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns or "jabber:client", origin.type;
- if name == "iq" and xmlns == "jabber:client" then
- if stanza.attr.type == "get" or stanza.attr.type == "set" then
- xmlns = stanza.tags[1].attr.xmlns or "jabber:client";
- log("debug", "Stanza of type %s from %s has xmlns: %s", name, origin_type, xmlns);
- else
- log("debug", "Discarding %s from %s of type: %s", name, origin_type, stanza.attr.type);
- return true;
- end
- end
- local handlers = stanza_handlers:get(host, origin_type, name, xmlns);
- if not handlers then handlers = stanza_handlers:get("*", origin_type, name, xmlns); end
- if handlers then
- log("debug", "Passing stanza to mod_%s", handler_info[handlers[1]].name);
- (handlers[1])(origin, stanza);
- return true;
- else
- log("debug", "Unhandled %s stanza: %s; xmlns=%s", origin.type, stanza.name, xmlns); -- we didn't handle it
- if stanza.attr.xmlns == "jabber:client" then
- if stanza.attr.type ~= "error" and stanza.attr.type ~= "result" then
- origin.send(st.error_reply(stanza, "cancel", "service-unavailable"));
- end
- elseif not((name == "features" or name == "error") and xmlns == "http://etherx.jabber.org/streams") then -- FIXME remove check once we handle S2S features
- origin:close("unsupported-stanza-type");
- end
- end
-end
-
-function module_has_method(module, method)
- return type(module.module[method]) == "function";
-end
-
-function call_module_method(module, method, ...)
- if module_has_method(module, method) then
- local f = module.module[method];
- return pcall(f, ...);
- else
- return false, "no-such-method";
- end
-end
-
------ API functions exposed to modules -----------
--- Must all be in api.*
-
--- Returns the name of the current module
-function api:get_name()
- return self.name;
-end
-
--- Returns the host that the current module is serving
-function api:get_host()
- return self.host;
-end
-
-function api:get_host_type()
- return hosts[self.host].type;
-end
-
-function api:set_global()
- self.host = "*";
- -- Update the logger
- local _log = logger.init("mod_"..self.name);
- self.log = function (self, ...) return _log(...); end;
- self._log = _log;
-end
-
-local function _add_handler(module, origin_type, tag, xmlns, handler)
- local handlers = stanza_handlers:get(module.host, origin_type, tag, xmlns);
- local msg = (tag == "iq") and "namespace" or "payload namespace";
- if not handlers then
- stanza_handlers:add(module.host, origin_type, tag, xmlns, handler);
- handler_info[handler] = module;
- handler_table:add(module.host, module.name, {module.host, origin_type, tag, xmlns});
- --module:log("debug", "I now handle tag '%s' [%s] with %s '%s'", tag, origin_type, msg, xmlns);
- else
- module:log("warn", "I wanted to handle tag '%s' [%s] with %s '%s' but mod_%s already handles that", tag, origin_type, msg, xmlns, handler_info[handlers[1]].module.name);
- end
-end
-
-function api:add_handler(origin_type, tag, xmlns, handler)
- if not (origin_type and tag and xmlns and handler) then return false; end
- if type(origin_type) == "table" then
- for _, origin_type in ipairs(origin_type) do
- _add_handler(self, origin_type, tag, xmlns, handler);
- end
- else
- _add_handler(self, origin_type, tag, xmlns, handler);