aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jlib.hrl1
-rw-r--r--src/mod_disco.erl65
-rw-r--r--src/mod_irc/mod_irc.erl5
-rw-r--r--src/mod_muc/mod_muc.erl6
-rw-r--r--src/mod_proxy65/mod_proxy65_service.erl8
-rw-r--r--src/mod_pubsub/mod_pubsub.erl5
-rw-r--r--src/mod_vcard.erl5
-rw-r--r--src/mod_vcard_ldap.erl6
-rw-r--r--src/mod_vcard_odbc.erl5
9 files changed, 97 insertions, 9 deletions
diff --git a/src/jlib.hrl b/src/jlib.hrl
index 32765e08a..955670e33 100644
--- a/src/jlib.hrl
+++ b/src/jlib.hrl
@@ -57,6 +57,7 @@
-define(NS_COMMANDS, "http://jabber.org/protocol/commands").
-define(NS_BYTESTREAMS, "http://jabber.org/protocol/bytestreams").
-define(NS_ADMIN, "http://jabber.org/protocol/admin").
+-define(NS_SERVERINFO, "http://jabber.org/network/serverinfo").
-define(NS_RSM, "http://jabber.org/protocol/rsm").
-define(NS_EJABBERD_CONFIG, "ejabberd:config").
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index b688427b6..ad9975b15 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -1,7 +1,7 @@
%%%----------------------------------------------------------------------
%%% File : mod_disco.erl
%%% Author : Alexey Shchepin <alexey@process-one.net>
-%%% Purpose : Service Discovery (JEP-0030) support
+%%% Purpose : Service Discovery (XEP-0030) support
%%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
@@ -41,6 +41,7 @@
get_sm_identity/5,
get_sm_features/5,
get_sm_items/5,
+ get_info/5,
register_feature/2,
unregister_feature/2,
register_extra_domain/2,
@@ -79,6 +80,7 @@ start(Host, Opts) ->
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 100),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 100),
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100),
+ ejabberd_hooks:add(disco_info, Host, ?MODULE, get_info, 100),
ok.
stop(Host) ->
@@ -88,6 +90,7 @@ stop(Host) ->
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 100),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_services, 100),
+ ejabberd_hooks:delete(disco_info, Host, ?MODULE, get_info, 100),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
@@ -153,6 +156,8 @@ process_local_iq_info(From, To, #iq{type = Type, lang = Lang,
Host,
[],
[From, To, Node, Lang]),
+ Info = ejabberd_hooks:run_fold(disco_info, Host, [],
+ [Host, ?MODULE, Node, Lang]),
case ejabberd_hooks:run_fold(disco_local_features,
Host,
empty,
@@ -166,6 +171,7 @@ process_local_iq_info(From, To, #iq{type = Type, lang = Lang,
sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_DISCO_INFO} | ANode],
Identity ++
+ Info ++
lists:map(fun feature_to_xml/1, Features)
}]};
{error, Error} ->
@@ -362,3 +368,60 @@ get_user_resources(User, Server) ->
[{"jid", User ++ "@" ++ Server ++ "/" ++ R},
{"name", User}], []}
end, lists:sort(Rs)).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%% Support for: XEP-0157 Contact Addresses for XMPP Services
+
+get_info(_A, Host, Module, Node, _Lang) when Node == [] ->
+ Serverinfo_fields = get_fields_xml(Host, Module),
+ [{xmlelement, "x",
+ [{"xmlns", ?NS_XDATA}, {"type", "result"}],
+ [{xmlelement, "field",
+ [{"var", "FORM_TYPE"}, {"type", "hidden"}],
+ [{xmlelement, "value",
+ [],
+ [{xmlcdata, ?NS_SERVERINFO}]
+ }]
+ }]
+ ++ Serverinfo_fields
+ }];
+
+get_info(_, _, _, _Node, _) ->
+ [].
+
+get_fields_xml(Host, Module) ->
+ Fields = gen_mod:get_module_opt(Host, ?MODULE, server_info, []),
+
+ %% filter, and get only the ones allowed for this module
+ Fields_good = lists:filter(
+ fun({Modules, _, _}) ->
+ case Modules of
+ all -> true;
+ Modules -> lists:member(Module, Modules)
+ end
+ end,
+ Fields),
+
+ fields_to_xml(Fields_good).
+
+fields_to_xml(Fields) ->
+ [ field_to_xml(Field) || Field <- Fields].
+
+field_to_xml({_, Var, Values}) ->
+ Values_xml = values_to_xml(Values),
+ {xmlelement, "field",
+ [{"var", Var}],
+ Values_xml
+ }.
+
+values_to_xml(Values) ->
+ lists:map(
+ fun(Value) ->
+ {xmlelement, "value",
+ [],
+ [{xmlcdata, Value}]
+ }
+ end,
+ Values
+ ).
diff --git a/src/mod_irc/mod_irc.erl b/src/mod_irc/mod_irc.erl
index 256b767e8..f73ebde89 100644
--- a/src/mod_irc/mod_irc.erl
+++ b/src/mod_irc/mod_irc.erl
@@ -214,6 +214,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
#iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
sub_el = SubEl, lang = Lang} = IQ ->
Node = xml:get_tag_attr_s("node", SubEl),
+ Info = ejabberd_hooks:run_fold(
+ disco_info, ServerHost, [],
+ [ServerHost, ?MODULE, "", ""]),
case iq_disco(Node, Lang) of
[] ->
Res = IQ#iq{type = result,
@@ -227,7 +230,7 @@ do_route1(Host, ServerHost, From, To, Packet) ->
Res = IQ#iq{type = result,
sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}],
- DiscoInfo}]},
+ DiscoInfo ++ Info}]},
ejabberd_router:route(To,
From,
jlib:iq_to_xml(Res))
diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl
index 2a7242fdf..69f1983fb 100644
--- a/src/mod_muc/mod_muc.erl
+++ b/src/mod_muc/mod_muc.erl
@@ -353,10 +353,14 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
case jlib:iq_query_info(Packet) of
#iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
sub_el = _SubEl, lang = Lang} = IQ ->
+ Info = ejabberd_hooks:run_fold(
+ disco_info, ServerHost, [],
+ [ServerHost, ?MODULE, "", ""]),
Res = IQ#iq{type = result,
sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}],
- iq_disco_info(Lang)}]},
+ iq_disco_info(Lang)
+ ++Info}]},
ejabberd_router:route(To,
From,
jlib:iq_to_xml(Res));
diff --git a/src/mod_proxy65/mod_proxy65_service.erl b/src/mod_proxy65/mod_proxy65_service.erl
index 901b5261c..c832b1a0d 100644
--- a/src/mod_proxy65/mod_proxy65_service.erl
+++ b/src/mod_proxy65/mod_proxy65_service.erl
@@ -120,9 +120,13 @@ delete_listener(Host) ->
%%%------------------------
%% disco#info request
-process_iq(_, #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} = IQ, #state{name=Name}) ->
+process_iq(_, #iq{type = get, xmlns = ?NS_DISCO_INFO, lang = Lang} = IQ,
+ #state{name=Name, serverhost=ServerHost}) ->
+ Info = ejabberd_hooks:run_fold(
+ disco_info, ServerHost, [], [ServerHost, ?MODULE, "", ""]),
IQ#iq{type = result, sub_el =
- [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}], iq_disco_info(Lang, Name)}]};
+ [{xmlelement, "query", [{"xmlns", ?NS_DISCO_INFO}],
+ iq_disco_info(Name, Lang) ++ Info}]};
%% disco#items request
process_iq(_, #iq{type = get, xmlns = ?NS_DISCO_ITEMS} = IQ, _) ->
diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl
index e97bf69b9..58e571509 100644
--- a/src/mod_pubsub/mod_pubsub.erl
+++ b/src/mod_pubsub/mod_pubsub.erl
@@ -888,12 +888,15 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
sub_el = SubEl, lang = Lang} = IQ ->
{xmlelement, _, QAttrs, _} = SubEl,
Node = xml:get_attr_s("node", QAttrs),
+ Info = ejabberd_hooks:run_fold(
+ disco_info, ServerHost, [],
+ [ServerHost, ?MODULE, "", ""]),
Res = case iq_disco_info(Host, Node, From, Lang) of
{result, IQRes} ->
jlib:iq_to_xml(
IQ#iq{type = result,
sub_el = [{xmlelement, "query",
- QAttrs, IQRes}]});
+ QAttrs, IQRes++Info}]});
{error, Error} ->
jlib:make_error_reply(Packet, Error)
end,
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 7886163b1..ee109e598 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -367,6 +367,9 @@ do_route(ServerHost, From, To, Packet) ->
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err);
get ->
+ Info = ejabberd_hooks:run_fold(
+ disco_info, ServerHost, [],
+ [ServerHost, ?MODULE, "", ""]),
ResIQ =
IQ#iq{type = result,
sub_el = [{xmlelement,
@@ -384,7 +387,7 @@ do_route(ServerHost, From, To, Packet) ->
[{"var", ?NS_SEARCH}], []},
{xmlelement, "feature",
[{"var", ?NS_VCARD}], []}
- ]
+ ] ++ Info
}]},
ejabberd_router:route(To,
From,
diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl
index 68faa97da..0e8541067 100644
--- a/src/mod_vcard_ldap.erl
+++ b/src/mod_vcard_ldap.erl
@@ -406,6 +406,7 @@ do_route(State, From, To, Packet) ->
route(State, From, To, Packet) ->
#jid{user = User, resource = Resource} = To,
+ ServerHost = State#state.serverhost,
if
(User /= "") or (Resource /= "") ->
Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
@@ -467,6 +468,9 @@ route(State, From, To, Packet) ->
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err);
get ->
+ Info = ejabberd_hooks:run_fold(
+ disco_info, ServerHost, [],
+ [ServerHost, ?MODULE, "", ""]),
ResIQ =
IQ#iq{type = result,
sub_el = [{xmlelement,
@@ -482,7 +486,7 @@ route(State, From, To, Packet) ->
[{"var", ?NS_SEARCH}], []},
{xmlelement, "feature",
[{"var", ?NS_VCARD}], []}
- ]
+ ] ++ Info
}]},
ejabberd_router:route(To,
From,
diff --git a/src/mod_vcard_odbc.erl b/src/mod_vcard_odbc.erl
index 3f74f71ba..44d8eacd6 100644
--- a/src/mod_vcard_odbc.erl
+++ b/src/mod_vcard_odbc.erl
@@ -344,6 +344,9 @@ do_route(ServerHost, From, To, Packet) ->
Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err);
get ->
+ Info = ejabberd_hooks:run_fold(
+ disco_info, ServerHost, [],
+ [ServerHost, ?MODULE, "", ""]),
ResIQ =
IQ#iq{type = result,
sub_el = [{xmlelement,
@@ -359,7 +362,7 @@ do_route(ServerHost, From, To, Packet) ->
[{"var", ?NS_SEARCH}], []},
{xmlelement, "feature",
[{"var", ?NS_VCARD}], []}
- ]
+ ] ++ Info
}]},
ejabberd_router:route(To,
From,