From 319c52ad8f68381449218269305814b9c296c7af Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Fri, 10 Jan 2003 19:44:35 +0000 Subject: [PATCH] *** empty log message *** SVN Revision: 35 --- src/Makefile | 2 +- src/ejabberd_c2s.erl | 42 +++++++++++++++++++------ src/ejabberd_s2s.erl | 8 ++++- src/mod_disco.erl | 74 ++++++++++++++++++++++++++++++++++++++------ src/mod_roster.erl | 5 +++ src/msgs/ru.msg | 3 ++ 6 files changed, 112 insertions(+), 22 deletions(-) diff --git a/src/Makefile b/src/Makefile index 12ff0b40d..6bee2bb33 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,7 @@ INCLUDES = -I/usr/lib/erlang/usr/include \ LIBDIRS = -L/usr/lib/erlang/lib/erl_interface-3.3.0/lib -ERLSHLIBS = expat_erl.so sha_erl.so +ERLSHLIBS = expat_erl.so all: $(ERLSHLIBS) erl -make diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index 0d7a864d7..725390ccf 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -298,6 +298,9 @@ handle_info({route, From, To, Packet}, StateName, StateData) -> From, jlib:iq_to_xml(ResIQ)), {false, Attrs, StateData}; + %{iq, ID, Type, ?NS_VCARD, SubEl} -> + % TODO: don't pass packets until roster loaded + %{true, Attrs, StateData}; _ -> {true, Attrs, StateData} end; @@ -605,37 +608,56 @@ remove_element(E, Set) -> roster_change(IJID, ISubscription, StateData) -> LIJID = jlib:jid_tolower(IJID), + IsFrom = (ISubscription == both) or (ISubscription == from), + IsTo = (ISubscription == both) or (ISubscription == to), + FSet = if + IsFrom -> + ?SETS:add_element(LIJID, StateData#state.pres_f); + true -> + remove_element(LIJID, StateData#state.pres_f) + end, + TSet = if + IsTo -> + ?SETS:add_element(LIJID, StateData#state.pres_t); + true -> + remove_element(LIJID, StateData#state.pres_t) + end, case StateData#state.pres_last of unknown -> - StateData; + StateData#state{pres_f = FSet, pres_t = TSet}; P -> ?DEBUG("roster changed for ~p~n", [StateData#state.user]), From = {StateData#state.user, StateData#state.server, StateData#state.resource}, - Cond1 = (not StateData#state.pres_invis) - and ((ISubscription == both) or (ISubscription == from)), - Cond2 = ((ISubscription == none) or (ISubscription == to)) - and (?SETS:is_element(From, StateData#state.pres_a) or - ?SETS:is_element(From, StateData#state.pres_i)), + Cond1 = (not StateData#state.pres_invis) and IsFrom, + Cond2 = (not IsFrom) + and (?SETS:is_element(LIJID, StateData#state.pres_a) or + ?SETS:is_element(LIJID, StateData#state.pres_i)), if Cond1 -> ?DEBUG("C1: ~p~n", [LIJID]), ejabberd_router:route(From, IJID, P), A = ?SETS:add_element(LIJID, StateData#state.pres_a), - StateData#state{pres_a = A}; + StateData#state{pres_a = A, + pres_f = FSet, + pres_t = TSet}; Cond2 -> ?DEBUG("C2: ~p~n", [LIJID]), - ejabberd_router:route(From, IJID, P), + ejabberd_router:route(From, IJID, + {xmlelement, "presence", + [{"type", "unavailable"}], []}), I = remove_element(LIJID, StateData#state.pres_i), A = remove_element(LIJID, StateData#state.pres_a), StateData#state{pres_i = I, - pres_a = A}; + pres_a = A, + pres_f = FSet, + pres_t = TSet}; true -> - StateData + StateData#state{pres_f = FSet, pres_t = TSet} end end. diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index 87c111393..a597a6247 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -13,7 +13,8 @@ -export([start/0, init/0, have_connection/1, get_key/1, - try_register/1]). + try_register/1, + dirty_get_connections/0]). -include_lib("mnemosyne/include/mnemosyne.hrl"). -include("ejabberd.hrl"). @@ -193,3 +194,8 @@ do_route(From, To, Packet) -> send_element(Pid, El) -> Pid ! {send_element, El}. + + +dirty_get_connections() -> + mnesia:dirty_all_keys(s2s). + diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 4c05791ca..9284e1419 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -53,8 +53,8 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) -> [{"code", "405"}], [{xmlcdata, "Not Allowed"}]}]}; get -> - case xml:get_tag_attr_s("node", SubEl) of - "" -> + case string:tokens(xml:get_tag_attr_s("node", SubEl), "/") of + [] -> Domains = lists:map(fun domain_to_xml/1, ejabberd_router:dirty_get_all_routes()), @@ -70,18 +70,33 @@ process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) -> {xmlelement, "item", [{"jid", jlib:jid_to_string(To)}, {"name", translate:translate(Lang, "All Users")}, - {"node", "all users"}], []}] - }]}; - "online users" -> + {"node", "all users"}], []}, + {xmlelement, "item", + [{"jid", jlib:jid_to_string(To)}, + {"name", translate:translate( + Lang, "Outgoing S2S connections")}, + {"node", "outgoing s2s"}], []} + ]}]}; + ["online users"] -> {iq, ID, result, XMLNS, [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], get_online_users() }]}; - "all users" -> + ["all users"] -> {iq, ID, result, XMLNS, [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], get_all_users() }]}; + ["outgoing s2s"] -> + {iq, ID, result, XMLNS, + [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], + get_outgoing_s2s(Lang) + }]}; + ["outgoing s2s", Host] -> + {iq, ID, result, XMLNS, + [{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], + get_outgoing_s2s(Lang, Host) + }]}; _ -> {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error", @@ -98,8 +113,8 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) -> [{"code", "405"}], [{xmlcdata, "Not Allowed"}]}]}; get -> - case xml:get_tag_attr_s("node", SubEl) of - "" -> + case string:tokens(xml:get_tag_attr_s("node", SubEl), "/") of + [] -> Features = lists:map(fun feature_to_xml/1, ets:tab2list(disco_features)), {iq, ID, result, XMLNS, [{xmlelement, @@ -111,8 +126,9 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) -> {"name", "ejabberd"}], []}] ++ Features }]}; - "online users" -> ?EMPTY_INFO_RESULT; - "all users" -> ?EMPTY_INFO_RESULT; + ["online users"] -> ?EMPTY_INFO_RESULT; + ["all users"] -> ?EMPTY_INFO_RESULT; + ["outgoing s2s" | _] -> ?EMPTY_INFO_RESULT; _ -> {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error", @@ -153,6 +169,44 @@ get_all_users() -> end, lists:sort(Users)) end. +get_outgoing_s2s(Lang) -> + case catch ejabberd_s2s:dirty_get_connections() of + {'EXIT', Reason} -> + []; + Connections -> + lists:map( + fun({F, T}) -> + {xmlelement, "item", + [{"jid", ?MYNAME}, + {"node", "outgoing s2s/" ++ T}, + {"name", + lists:flatten( + io_lib:format( + translate:translate(Lang, "To ~s"), [T]))}], + []} + end, lists:keysort(2, Connections)) + end. + +get_outgoing_s2s(Lang, To) -> + case catch ejabberd_s2s:dirty_get_connections() of + {'EXIT', Reason} -> + []; + Connections -> + lists:map( + fun({F, T}) -> + {xmlelement, "item", + [{"jid", ?MYNAME}, + {"node", "outgoing s2s/" ++ To ++ "/" ++ F}, + {"name", + lists:flatten( + io_lib:format( + translate:translate(Lang, "From ~s"), [F]))}], + []} + end, lists:keysort(1, lists:filter(fun(E) -> + element(2, E) == To + end, Connections))) + end. + process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) -> {User, _, _} = To, diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 281a70945..5de590f4b 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -239,6 +239,11 @@ process_item_els(Item, []) -> push_item(User, From, Item) -> + ejabberd_sm ! {route, {"", "", ""}, {User, "", ""}, + {xmlelement, "broadcast", [], + [{item, + Item#roster.jid, + Item#roster.subscription}]}}, lists:foreach(fun(Resource) -> push_item(User, Resource, From, Item) end, ejabberd_sm:get_user_resources(User)). diff --git a/src/msgs/ru.msg b/src/msgs/ru.msg index 27b837caf..429a6cb78 100644 --- a/src/msgs/ru.msg +++ b/src/msgs/ru.msg @@ -3,6 +3,9 @@ % mod_disco.erl {"Online Users", "Подключённые пользователи"}. {"All Users", "Все пользователи"}. +{"Outgoing S2S connections", "Исходящие S2S-соединения"}. +{"To ~s", "К ~s"}. +{"From ~s", "От ~s"}. % mod_vcard.erl