diff options
author | Badlop <badlop@process-one.net> | 2013-03-14 10:33:02 +0100 |
---|---|---|
committer | Badlop <badlop@process-one.net> | 2013-03-14 10:33:02 +0100 |
commit | 9deb294328bb3f9eb6bd2c0e7cd500732e9b5830 (patch) | |
tree | 7e1066c130250627ee0abab44a135f583a28d07f /src/mod_disco.erl | |
parent | list_to_integer/2 only works in OTP R14 and newer (diff) |
Accumulated patch to binarize and indent code
Diffstat (limited to '')
-rw-r--r-- | src/mod_disco.erl | 683 |
1 files changed, 353 insertions, 330 deletions
diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 3d623e2b6..c883e0782 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -25,446 +25,469 @@ %%%---------------------------------------------------------------------- -module(mod_disco). + -author('alexey@process-one.net'). -behaviour(gen_mod). --export([start/2, - stop/1, - process_local_iq_items/3, - process_local_iq_info/3, - get_local_identity/5, - get_local_features/5, - get_local_services/5, - process_sm_iq_items/3, - process_sm_iq_info/3, - 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, - unregister_extra_domain/2]). +-export([start/2, stop/1, process_local_iq_items/3, + process_local_iq_info/3, get_local_identity/5, + get_local_features/5, get_local_services/5, + process_sm_iq_items/3, process_sm_iq_info/3, + 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, unregister_extra_domain/2]). -include("ejabberd.hrl"). + -include("jlib.hrl"). + -include("mod_roster.hrl"). start(Host, Opts) -> ejabberd_local:refresh_iq_handlers(), - - IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS, - ?MODULE, process_local_iq_items, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO, - ?MODULE, process_local_iq_info, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS, - ?MODULE, process_sm_iq_items, IQDisc), - gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO, - ?MODULE, process_sm_iq_info, IQDisc), - - catch ets:new(disco_features, [named_table, ordered_set, public]), - register_feature(Host, "iq"), - register_feature(Host, "presence"), - register_feature(Host, "presence-invisible"), - - catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), - ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []), - lists:foreach(fun(Domain) -> register_extra_domain(Host, Domain) end, + IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, + one_queue), + gen_iq_handler:add_iq_handler(ejabberd_local, Host, + ?NS_DISCO_ITEMS, ?MODULE, + process_local_iq_items, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_local, Host, + ?NS_DISCO_INFO, ?MODULE, + process_local_iq_info, IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, + ?NS_DISCO_ITEMS, ?MODULE, process_sm_iq_items, + IQDisc), + gen_iq_handler:add_iq_handler(ejabberd_sm, Host, + ?NS_DISCO_INFO, ?MODULE, process_sm_iq_info, + IQDisc), + catch ets:new(disco_features, + [named_table, ordered_set, public]), + register_feature(Host, <<"iq">>), + register_feature(Host, <<"presence">>), + catch ets:new(disco_extra_domains, + [named_table, ordered_set, public]), + ExtraDomains = gen_mod:get_opt(extra_domains, Opts, + fun(Hs) -> + [iolist_to_binary(H) || H <- Hs] + end, []), + lists:foreach(fun (Domain) -> + register_extra_domain(Host, Domain) + end, ExtraDomains), - catch ets:new(disco_sm_features, [named_table, ordered_set, public]), - catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]), - ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_services, 100), - ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 100), - ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 100), - 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), + catch ets:new(disco_sm_features, + [named_table, ordered_set, public]), + catch ets:new(disco_sm_nodes, + [named_table, ordered_set, public]), + ejabberd_hooks:add(disco_local_items, Host, ?MODULE, + get_local_services, 100), + ejabberd_hooks:add(disco_local_features, Host, ?MODULE, + get_local_features, 100), + ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, + get_local_identity, 100), + 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) -> - ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100), - ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 100), - ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 100), - 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), - gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO), + ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, + get_sm_identity, 100), + ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, + get_sm_features, 100), + ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, + get_sm_items, 100), + 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), + gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, + ?NS_DISCO_INFO), catch ets:match_delete(disco_features, {{'_', Host}}), - catch ets:match_delete(disco_extra_domains, {{'_', Host}}), + catch ets:match_delete(disco_extra_domains, + {{'_', Host}}), ok. - register_feature(Host, Feature) -> - catch ets:new(disco_features, [named_table, ordered_set, public]), + catch ets:new(disco_features, + [named_table, ordered_set, public]), ets:insert(disco_features, {{Feature, Host}}). unregister_feature(Host, Feature) -> - catch ets:new(disco_features, [named_table, ordered_set, public]), + catch ets:new(disco_features, + [named_table, ordered_set, public]), ets:delete(disco_features, {Feature, Host}). register_extra_domain(Host, Domain) -> - catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), + catch ets:new(disco_extra_domains, + [named_table, ordered_set, public]), ets:insert(disco_extra_domains, {{Domain, Host}}). unregister_extra_domain(Host, Domain) -> - catch ets:new(disco_extra_domains, [named_table, ordered_set, public]), + catch ets:new(disco_extra_domains, + [named_table, ordered_set, public]), ets:delete(disco_extra_domains, {Domain, Host}). -process_local_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> +process_local_iq_items(From, To, + #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of - set -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; - get -> - Node = xml:get_tag_attr_s("node", SubEl), - Host = To#jid.lserver, - - case ejabberd_hooks:run_fold(disco_local_items, - Host, - empty, - [From, To, Node, Lang]) of - {result, Items} -> - ANode = case Node of - "" -> []; - _ -> [{"node", Node}] - end, - IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", ?NS_DISCO_ITEMS} | ANode], - Items - }]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end + set -> + IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; + get -> + Node = xml:get_tag_attr_s(<<"node">>, SubEl), + Host = To#jid.lserver, + case ejabberd_hooks:run_fold(disco_local_items, Host, + empty, [From, To, Node, Lang]) + of + {result, Items} -> + ANode = case Node of + <<"">> -> []; + _ -> [{<<"node">>, Node}] + end, + IQ#iq{type = result, + sub_el = + [#xmlel{name = <<"query">>, + attrs = + [{<<"xmlns">>, ?NS_DISCO_ITEMS} | ANode], + children = Items}]}; + {error, Error} -> + IQ#iq{type = error, sub_el = [SubEl, Error]} + end end. - -process_local_iq_info(From, To, #iq{type = Type, lang = Lang, - sub_el = SubEl} = IQ) -> +process_local_iq_info(From, To, + #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of - set -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; - get -> - Host = To#jid.lserver, - Node = xml:get_tag_attr_s("node", SubEl), - Identity = ejabberd_hooks:run_fold(disco_local_identity, - 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, - [From, To, Node, Lang]) of - {result, Features} -> - ANode = case Node of - "" -> []; - _ -> [{"node", Node}] - end, - IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", ?NS_DISCO_INFO} | ANode], - Identity ++ - Info ++ - features_to_xml(Features) - }]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end + set -> + IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; + get -> + Host = To#jid.lserver, + Node = xml:get_tag_attr_s(<<"node">>, SubEl), + Identity = ejabberd_hooks:run_fold(disco_local_identity, + 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, [From, To, Node, Lang]) + of + {result, Features} -> + ANode = case Node of + <<"">> -> []; + _ -> [{<<"node">>, Node}] + end, + IQ#iq{type = result, + sub_el = + [#xmlel{name = <<"query">>, + attrs = + [{<<"xmlns">>, ?NS_DISCO_INFO} | ANode], + children = + Identity ++ + Info ++ features_to_xml(Features)}]}; + {error, Error} -> + IQ#iq{type = error, sub_el = [SubEl, Error]} + end end. -get_local_identity(Acc, _From, _To, [], _Lang) -> - Acc ++ [{xmlelement, "identity", - [{"category", "server"}, - {"type", "im"}, - {"name", "ejabberd"}], []}]; - +get_local_identity(Acc, _From, _To, <<>>, _Lang) -> + Acc ++ + [#xmlel{name = <<"identity">>, + attrs = + [{<<"category">>, <<"server">>}, {<<"type">>, <<"im">>}, + {<<"name">>, <<"ejabberd">>}], + children = []}]; get_local_identity(Acc, _From, _To, _Node, _Lang) -> Acc. -get_local_features({error, _Error} = Acc, _From, _To, _Node, _Lang) -> +get_local_features({error, _Error} = Acc, _From, _To, + _Node, _Lang) -> Acc; - -get_local_features(Acc, _From, To, [], _Lang) -> +get_local_features(Acc, _From, To, <<>>, _Lang) -> Feats = case Acc of - {result, Features} -> Features; - empty -> [] + {result, Features} -> Features; + empty -> [] end, Host = To#jid.lserver, {result, - ets:select(disco_features, [{{{'_', Host}}, [], ['$_']}]) ++ Feats}; - + ets:select(disco_features, + [{{{'_', Host}}, [], ['$_']}]) + ++ Feats}; get_local_features(Acc, _From, _To, _Node, _Lang) -> case Acc of - {result, _Features} -> - Acc; - empty -> - {error, ?ERR_ITEM_NOT_FOUND} + {result, _Features} -> Acc; + empty -> {error, ?ERR_ITEM_NOT_FOUND} end. - features_to_xml(FeatureList) -> - %% Avoid duplicating features - [{xmlelement, "feature", [{"var", Feat}], []} || - Feat <- lists:usort( - lists:map( - fun({{Feature, _Host}}) -> - Feature; - (Feature) when is_list(Feature) -> - Feature - end, FeatureList))]. + [#xmlel{name = <<"feature">>, + attrs = [{<<"var">>, Feat}], children = []} + || Feat + <- lists:usort(lists:map(fun ({{Feature, _Host}}) -> + Feature; + (Feature) when is_binary(Feature) -> + Feature + end, + FeatureList))]. domain_to_xml({Domain}) -> - {xmlelement, "item", [{"jid", Domain}], []}; + #xmlel{name = <<"item">>, attrs = [{<<"jid">>, Domain}], + children = []}; domain_to_xml(Domain) -> - {xmlelement, "item", [{"jid", Domain}], []}. + #xmlel{name = <<"item">>, attrs = [{<<"jid">>, Domain}], + children = []}. -get_local_services({error, _Error} = Acc, _From, _To, _Node, _Lang) -> +get_local_services({error, _Error} = Acc, _From, _To, + _Node, _Lang) -> Acc; - -get_local_services(Acc, _From, To, [], _Lang) -> +get_local_services(Acc, _From, To, <<>>, _Lang) -> Items = case Acc of - {result, Its} -> Its; - empty -> [] + {result, Its} -> Its; + empty -> [] end, Host = To#jid.lserver, {result, - lists:usort( - lists:map(fun domain_to_xml/1, - get_vh_services(Host) ++ - ets:select(disco_extra_domains, - [{{{'$1', Host}}, [], ['$1']}])) - ) ++ Items}; - -get_local_services({result, _} = Acc, _From, _To, _Node, _Lang) -> + lists:usort(lists:map(fun domain_to_xml/1, + get_vh_services(Host) ++ + ets:select(disco_extra_domains, + [{{{'$1', Host}}, [], ['$1']}]))) + ++ Items}; +get_local_services({result, _} = Acc, _From, _To, _Node, + _Lang) -> Acc; - get_local_services(empty, _From, _To, _Node, _Lang) -> {error, ?ERR_ITEM_NOT_FOUND}. get_vh_services(Host) -> - Hosts = lists:sort(fun(H1, H2) -> length(H1) >= length(H2) end, ?MYHOSTS), - lists:filter(fun(H) -> - case lists:dropwhile( - fun(VH) -> - not lists:suffix("." ++ VH, H) - end, Hosts) of - [] -> - false; - [VH | _] -> - VH == Host + Hosts = lists:sort(fun (H1, H2) -> + byte_size(H1) >= byte_size(H2) + end, + ?MYHOSTS), + lists:filter(fun (H) -> + case lists:dropwhile(fun (VH) -> + not + str:suffix( + <<".", VH/binary>>, + H) + end, + Hosts) + of + [] -> false; + [VH | _] -> VH == Host end - end, ejabberd_router:dirty_get_all_routes()). + end, + ejabberd_router:dirty_get_all_routes()). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -process_sm_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> +process_sm_iq_items(From, To, + #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of - set -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; - get -> - case is_presence_subscribed(From, To) of - true -> - Host = To#jid.lserver, - Node = xml:get_tag_attr_s("node", SubEl), - case ejabberd_hooks:run_fold(disco_sm_items, - Host, - empty, - [From, To, Node, Lang]) of - {result, Items} -> - ANode = case Node of - "" -> []; - _ -> [{"node", Node}] - end, - IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", ?NS_DISCO_ITEMS} | ANode], - Items - }]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end; - false -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]} - end + set -> + IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; + get -> + case is_presence_subscribed(From, To) of + true -> + Host = To#jid.lserver, + Node = xml:get_tag_attr_s(<<"node">>, SubEl), + case ejabberd_hooks:run_fold(disco_sm_items, Host, + empty, [From, To, Node, Lang]) + of + {result, Items} -> + ANode = case Node of + <<"">> -> []; + _ -> [{<<"node">>, Node}] + end, + IQ#iq{type = result, + sub_el = + [#xmlel{name = <<"query">>, + attrs = + [{<<"xmlns">>, ?NS_DISCO_ITEMS} + | ANode], + children = Items}]}; + {error, Error} -> + IQ#iq{type = error, sub_el = [SubEl, Error]} + end; + false -> + IQ#iq{type = error, + sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]} + end end. -get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) -> +get_sm_items({error, _Error} = Acc, _From, _To, _Node, + _Lang) -> Acc; - get_sm_items(Acc, From, - #jid{user = User, server = Server} = To, - [], _Lang) -> + #jid{user = User, server = Server} = To, <<>>, _Lang) -> Items = case Acc of - {result, Its} -> Its; - empty -> [] + {result, Its} -> Its; + empty -> [] end, Items1 = case is_presence_subscribed(From, To) of - true -> - get_user_resources(User, Server); - _ -> - [] - end, + true -> get_user_resources(User, Server); + _ -> [] + end, {result, Items ++ Items1}; - -get_sm_items({result, _} = Acc, _From, _To, _Node, _Lang) -> +get_sm_items({result, _} = Acc, _From, _To, _Node, + _Lang) -> Acc; - get_sm_items(empty, From, To, _Node, _Lang) -> #jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LTo, lserver = LSTo} = To, case {LFrom, LSFrom} of - {LTo, LSTo} -> - {error, ?ERR_ITEM_NOT_FOUND}; - _ -> - {error, ?ERR_NOT_ALLOWED} + {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND}; + _ -> {error, ?ERR_NOT_ALLOWED} end. -is_presence_subscribed(#jid{luser=User, lserver=Server}, #jid{luser=LUser, lserver=LServer}) -> - lists:any(fun(#roster{jid = {TUser, TServer, _}, subscription = S}) -> - if - LUser == TUser, LServer == TServer, S/=none -> - true; - true -> - false - end - end, - ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}])) - orelse User == LUser andalso Server == LServer. - -process_sm_iq_info(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> +is_presence_subscribed(#jid{luser = User, + lserver = Server}, + #jid{luser = LUser, lserver = LServer}) -> + lists:any(fun (#roster{jid = {TUser, TServer, _}, + subscription = S}) -> + if LUser == TUser, LServer == TServer, S /= none -> + true; + true -> false + end + end, + ejabberd_hooks:run_fold(roster_get, Server, [], + [{User, Server}])) + orelse User == LUser andalso Server == LServer. + +process_sm_iq_info(From, To, + #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> case Type of - set -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; - get -> - case is_presence_subscribed(From, To) of - true -> - Host = To#jid.lserver, - Node = xml:get_tag_attr_s("node", SubEl), - Identity = ejabberd_hooks:run_fold(disco_sm_identity, - Host, - [], - [From, To, Node, Lang]), - case ejabberd_hooks:run_fold(disco_sm_features, - Host, - empty, - [From, To, Node, Lang]) of - {result, Features} -> - ANode = case Node of - "" -> []; - _ -> [{"node", Node}] - end, - IQ#iq{type = result, - sub_el = [{xmlelement, "query", - [{"xmlns", ?NS_DISCO_INFO} | ANode], - Identity ++ - features_to_xml(Features) - }]}; - {error, Error} -> - IQ#iq{type = error, sub_el = [SubEl, Error]} - end; - false -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]} - end - end. - -get_sm_identity(Acc, _From, #jid{luser = LUser, lserver=LServer}, _Node, _Lang) -> - Acc ++ case ejabberd_auth:is_user_exists(LUser, LServer) of - true -> - [{xmlelement, "identity", [{"category", "account"}, - {"type", "registered"}], []}]; - _ -> - [] + set -> + IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; + get -> + case is_presence_subscribed(From, To) of + true -> + Host = To#jid.lserver, + Node = xml:get_tag_attr_s(<<"node">>, SubEl), + Identity = ejabberd_hooks:run_fold(disco_sm_identity, + Host, [], + [From, To, Node, Lang]), + case ejabberd_hooks:run_fold(disco_sm_features, Host, + empty, [From, To, Node, Lang]) + of + {result, Features} -> + ANode = case Node of + <<"">> -> []; + _ -> [{<<"node">>, Node}] + end, + IQ#iq{type = result, + sub_el = + [#xmlel{name = <<"query">>, + attrs = + [{<<"xmlns">>, ?NS_DISCO_INFO} + | ANode], + children = + Identity ++ + features_to_xml(Features)}]}; + {error, Error} -> + IQ#iq{type = error, sub_el = [SubEl, Error]} + end; + false -> + IQ#iq{type = error, + sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]} + end end. +get_sm_identity(Acc, _From, + #jid{luser = LUser, lserver = LServer}, _Node, _Lang) -> + Acc ++ + case ejabberd_auth:is_user_exists(LUser, LServer) of + true -> + [#xmlel{name = <<"identity">>, + attrs = + [{<<"category">>, <<"account">>}, + {<<"type">>, <<"registered">>}], + children = []}]; + _ -> [] + end. get_sm_features(empty, From, To, _Node, _Lang) -> #jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LTo, lserver = LSTo} = To, case {LFrom, LSFrom} of - {LTo, LSTo} -> - {error, ?ERR_ITEM_NOT_FOUND}; - _ -> - {error, ?ERR_NOT_ALLOWED} + {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND}; + _ -> {error, ?ERR_NOT_ALLOWED} end; - -get_sm_features(Acc, _From, _To, _Node, _Lang) -> - Acc. +get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. get_user_resources(User, Server) -> Rs = ejabberd_sm:get_user_resources(User, Server), - lists:map(fun(R) -> - {xmlelement, "item", - [{"jid", User ++ "@" ++ Server ++ "/" ++ R}, - {"name", User}], []} - end, lists:sort(Rs)). + lists:map(fun (R) -> + #xmlel{name = <<"item">>, + attrs = + [{<<"jid">>, + <<User/binary, "@", Server/binary, "/", + R/binary>>}, + {<<"name">>, User}], + children = []} + end, + lists:sort(Rs)). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% Support for: XEP-0157 Contact Addresses for XMPP Services -get_info(_A, Host, Mod, Node, _Lang) when Node == [] -> +get_info(_A, Host, Mod, Node, _Lang) when Node == <<>> -> Module = case Mod of - undefined -> - ?MODULE; - _ -> - Mod + undefined -> ?MODULE; + _ -> Mod end, 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(Acc, _, _, _Node, _) -> - Acc. + [#xmlel{name = <<"x">>, + attrs = + [{<<"xmlns">>, ?NS_XDATA}, {<<"type">>, <<"result">>}], + children = + [#xmlel{name = <<"field">>, + attrs = + [{<<"var">>, <<"FORM_TYPE">>}, + {<<"type">>, <<"hidden">>}], + children = + [#xmlel{name = <<"value">>, attrs = [], + children = [{xmlcdata, ?NS_SERVERINFO}]}]}] + ++ Serverinfo_fields}]; +get_info(Acc, _, _, _Node, _) -> Acc. 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 = gen_mod:get_module_opt(Host, ?MODULE, server_info, + fun(L) when is_list(L) -> L end, + []), + 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(Field) || Field <- Fields]. field_to_xml({_, Var, Values}) -> Values_xml = values_to_xml(Values), - {xmlelement, "field", - [{"var", Var}], - Values_xml - }. + #xmlel{name = <<"field">>, attrs = [{<<"var">>, Var}], + children = Values_xml}. values_to_xml(Values) -> - lists:map( - fun(Value) -> - {xmlelement, "value", - [], - [{xmlcdata, Value}] - } - end, - Values - ). + lists:map(fun (Value) -> + #xmlel{name = <<"value">>, attrs = [], + children = [{xmlcdata, Value}]} + end, + Values). |