25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-22 16:20:52 +01:00

* src/jlib.hrl: Added declaration of "iq" record

* (all): Updated to use "iq" record

SVN Revision: 186
This commit is contained in:
Alexey Shchepin 2003-12-17 20:13:21 +00:00
parent 4768cd2f26
commit b3b09bcfd8
24 changed files with 605 additions and 578 deletions

View File

@ -1,3 +1,8 @@
2003-12-17 Alexey Shchepin <alexey@sevcom.net>
* src/jlib.hrl: Added declaration of "iq" record
* (all): Updated to use "iq" record
2003-12-14 Alexey Shchepin <alexey@sevcom.net> 2003-12-14 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_local.erl: Replaced register_local_route to * src/ejabberd_local.erl: Replaced register_local_route to

View File

@ -1,7 +1,7 @@
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
%%% File : ejabberd_c2s.erl %%% File : ejabberd_c2s.erl
%%% Author : Alexey Shchepin <alexey@sevcom.net> %%% Author : Alexey Shchepin <alexey@sevcom.net>
%%% Purpose : %%% Purpose : Serve C2S connection
%%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@sevcom.net> %%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
%%% Id : $Id$ %%% Id : $Id$
%%%---------------------------------------------------------------------- %%%----------------------------------------------------------------------
@ -124,7 +124,7 @@ init([{SockMod, Socket}, Opts]) ->
%% {stop, Reason, NewStateData} %% {stop, Reason, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) -> wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
case xml:get_attr_s("xmlns:stream", Attrs) of case xml:get_attr_s("xmlns:stream", Attrs) of
?NS_STREAM -> ?NS_STREAM ->
case xml:get_attr_s("version", Attrs) of case xml:get_attr_s("version", Attrs) of
@ -195,12 +195,12 @@ wait_for_stream(closed, StateData) ->
wait_for_auth({xmlstreamelement, El}, StateData) -> wait_for_auth({xmlstreamelement, El}, StateData) ->
case is_auth_packet(El) of case is_auth_packet(El) of
{auth, ID, get, {"", _, _, _}} -> {auth, _ID, get, {"", _, _, _}} ->
Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST), Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST),
send_element(StateData, Err), send_element(StateData, Err),
{next_state, wait_for_auth, StateData}; {next_state, wait_for_auth, StateData};
{auth, ID, get, {U, _, _, _}} -> {auth, _ID, get, {U, _, _, _}} ->
{xmlelement, Name, Attrs, Els} = jlib:make_result_iq_reply(El), {xmlelement, Name, Attrs, _Els} = jlib:make_result_iq_reply(El),
Res = case ejabberd_auth:plain_password_required() of Res = case ejabberd_auth:plain_password_required() of
false -> false ->
{xmlelement, Name, Attrs, {xmlelement, Name, Attrs,
@ -219,11 +219,11 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
end, end,
send_element(StateData, Res), send_element(StateData, Res),
{next_state, wait_for_auth, StateData}; {next_state, wait_for_auth, StateData};
{auth, ID, set, {U, P, D, ""}} -> {auth, _ID, set, {U, P, D, ""}} ->
Err = jlib:make_error_reply(El, ?ERR_AUTH_NO_RESOURCE_PROVIDED), Err = jlib:make_error_reply(El, ?ERR_AUTH_NO_RESOURCE_PROVIDED),
send_element(StateData, Err), send_element(StateData, Err),
{next_state, wait_for_auth, StateData}; {next_state, wait_for_auth, StateData};
{auth, ID, set, {U, P, D, R}} -> {auth, _ID, set, {U, P, D, R}} ->
io:format("AUTH: ~p~n", [{U, P, D, R}]), io:format("AUTH: ~p~n", [{U, P, D, R}]),
JID = jlib:make_jid(U, StateData#state.server, R), JID = jlib:make_jid(U, StateData#state.server, R),
case (JID /= error) andalso case (JID /= error) andalso
@ -286,10 +286,9 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
end; end;
_ -> _ ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
{iq, ID, Type, ?NS_REGISTER, SubEl} -> #iq{xmlns = ?NS_REGISTER} = IQ ->
ResIQ = mod_register:process_iq( ResIQ = mod_register:process_iq(
{"", "", ""}, {"", ?MYNAME, ""}, {"", "", ""}, {"", ?MYNAME, ""}, IQ),
{iq, ID, Type, ?NS_REGISTER, SubEl}),
Res1 = jlib:replace_from_to({"", ?MYNAME, ""}, Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
{"", "", ""}, {"", "", ""},
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
@ -301,7 +300,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
end end
end; end;
wait_for_auth({xmlstreamend, Name}, StateData) -> wait_for_auth({xmlstreamend, _Name}, StateData) ->
send_text(StateData, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
@ -351,10 +350,9 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
end; end;
_ -> _ ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
{iq, ID, Type, ?NS_REGISTER, SubEl} -> #iq{xmlns = ?NS_REGISTER} = IQ ->
ResIQ = mod_register:process_iq( ResIQ = mod_register:process_iq(
{"", "", ""}, {"", ?MYNAME, ""}, {"", "", ""}, {"", ?MYNAME, ""}, IQ),
{iq, ID, Type, ?NS_REGISTER, SubEl}),
Res1 = jlib:replace_from_to({"", ?MYNAME, ""}, Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
{"", "", ""}, {"", "", ""},
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
@ -366,7 +364,7 @@ wait_for_sasl_auth({xmlstreamelement, El}, StateData) ->
end end
end; end;
wait_for_sasl_auth({xmlstreamend, Name}, StateData) -> wait_for_sasl_auth({xmlstreamend, _Name}, StateData) ->
send_text(StateData, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
@ -414,10 +412,9 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
end; end;
_ -> _ ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
{iq, ID, Type, ?NS_REGISTER, SubEl} -> #iq{xmlns = ?NS_REGISTER} = IQ ->
ResIQ = mod_register:process_iq( ResIQ = mod_register:process_iq(
{"", "", ""}, {"", ?MYNAME, ""}, {"", "", ""}, {"", ?MYNAME, ""}, IQ),
{iq, ID, Type, ?NS_REGISTER, SubEl}),
Res1 = jlib:replace_from_to({"", ?MYNAME, ""}, Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
{"", "", ""}, {"", "", ""},
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
@ -429,7 +426,7 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
end end
end; end;
wait_for_sasl_response({xmlstreamend, Name}, StateData) -> wait_for_sasl_response({xmlstreamend, _Name}, StateData) ->
send_text(StateData, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
@ -444,7 +441,7 @@ wait_for_sasl_response(closed, StateData) ->
wait_for_bind({xmlstreamelement, El}, StateData) -> wait_for_bind({xmlstreamelement, El}, StateData) ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
{iq, ID, set, ?NS_BIND, SubEl} -> #iq{type = set, xmlns = ?NS_BIND, sub_el = SubEl} = IQ ->
U = StateData#state.user, U = StateData#state.user,
R1 = xml:get_path_s(SubEl, [{elem, "resource"}, cdata]), R1 = xml:get_path_s(SubEl, [{elem, "resource"}, cdata]),
R = case jlib:resourceprep(R1) of R = case jlib:resourceprep(R1) of
@ -461,11 +458,12 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
{next_state, wait_for_bind, StateData}; {next_state, wait_for_bind, StateData};
_ -> _ ->
JID = jlib:make_jid(U, StateData#state.server, R), JID = jlib:make_jid(U, StateData#state.server, R),
Res = {iq, ID, result, ?NS_BIND, Res = IQ#iq{type = result,
[{xmlelement, "bind", sub_el = [{xmlelement, "bind",
[{"xmlns", ?NS_BIND}], [{"xmlns", ?NS_BIND}],
[{xmlelement, "jid", [], [{xmlelement, "jid", [],
[{xmlcdata, jlib:jid_to_string(JID)}]}]}]}, [{xmlcdata,
jlib:jid_to_string(JID)}]}]}]},
send_element(StateData, jlib:iq_to_xml(Res)), send_element(StateData, jlib:iq_to_xml(Res)),
{next_state, wait_for_session, {next_state, wait_for_session,
StateData#state{resource = R, jid = JID}} StateData#state{resource = R, jid = JID}}
@ -474,7 +472,7 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
{next_state, wait_for_bind, StateData} {next_state, wait_for_bind, StateData}
end; end;
wait_for_bind({xmlstreamend, Name}, StateData) -> wait_for_bind({xmlstreamend, _Name}, StateData) ->
send_text(StateData, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
@ -489,7 +487,7 @@ wait_for_bind(closed, StateData) ->
wait_for_session({xmlstreamelement, El}, StateData) -> wait_for_session({xmlstreamelement, El}, StateData) ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
{iq, ID, set, ?NS_SESSION, SubEl} -> #iq{type = set, xmlns = ?NS_SESSION} ->
U = StateData#state.user, U = StateData#state.user,
R = StateData#state.resource, R = StateData#state.resource,
io:format("SASLAUTH: ~p~n", [{U, R}]), io:format("SASLAUTH: ~p~n", [{U, R}]),
@ -521,22 +519,11 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
send_element(StateData, Err), send_element(StateData, Err),
{next_state, wait_for_session, StateData} {next_state, wait_for_session, StateData}
end; end;
% TODO: is this needed?
{iq, ID, Type, ?NS_REGISTER, SubEl} ->
ResIQ = mod_register:process_iq(
{"", "", ""}, {"", ?MYNAME, ""},
{iq, ID, Type, ?NS_REGISTER, SubEl}),
Res1 = jlib:replace_from_to({"", ?MYNAME, ""},
{"", "", ""},
jlib:iq_to_xml(ResIQ)),
Res = jlib:remove_attr("to", Res1),
send_element(StateData, Res),
{next_state, wait_for_session, StateData};
_ -> _ ->
{next_state, wait_for_session, StateData} {next_state, wait_for_session, StateData}
end; end;
wait_for_session({xmlstreamend, Name}, StateData) -> wait_for_session({xmlstreamend, _Name}, StateData) ->
send_text(StateData, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
@ -551,7 +538,7 @@ wait_for_session(closed, StateData) ->
session_established({xmlstreamelement, El}, StateData) -> session_established({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El, {xmlelement, Name, Attrs, _Els} = El,
User = StateData#state.user, User = StateData#state.user,
Server = StateData#state.server, Server = StateData#state.server,
%FromJID = {User, %FromJID = {User,
@ -594,13 +581,14 @@ session_established({xmlstreamelement, El}, StateData) ->
none -> none ->
ejabberd_router:route(FromJID, ToJID, El), ejabberd_router:route(FromJID, ToJID, El),
StateData; StateData;
PrivList -> _PrivList ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
{iq, ID, Type, ?NS_PRIVACY = XMLNS, SubEl} = IQ -> #iq{xmlns = ?NS_PRIVACY} = IQ ->
process_privacy_iq( process_privacy_iq(
FromJID, ToJID, IQ, StateData); FromJID, ToJID, IQ, StateData);
_ -> _ ->
ejabberd_router:route(FromJID, ToJID, El), ejabberd_router:route(
FromJID, ToJID, El),
StateData StateData
end end
end; end;
@ -613,7 +601,7 @@ session_established({xmlstreamelement, El}, StateData) ->
end, end,
{next_state, session_established, NewState}; {next_state, session_established, NewState};
session_established({xmlstreamend, Name}, StateData) -> session_established({xmlstreamend, _Name}, StateData) ->
send_text(StateData, ?STREAM_TRAILER), send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData}; {stop, normal, StateData};
@ -645,7 +633,7 @@ session_established(closed, StateData) ->
%% {next_state, NextStateName, NextStateData, Timeout} | %% {next_state, NextStateName, NextStateData, Timeout} |
%% {stop, Reason, NewStateData} %% {stop, Reason, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_event(Event, StateName, StateData) -> handle_event(_Event, StateName, StateData) ->
{next_state, StateName, StateData}. {next_state, StateName, StateData}.
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
@ -657,11 +645,11 @@ handle_event(Event, StateName, StateData) ->
%% {stop, Reason, NewStateData} | %% {stop, Reason, NewStateData} |
%% {stop, Reason, Reply, NewStateData} %% {stop, Reason, Reply, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_sync_event(Event, From, StateName, StateData) -> handle_sync_event(_Event, _From, StateName, StateData) ->
Reply = ok, Reply = ok,
{reply, Reply, StateName, StateData}. {reply, Reply, StateName, StateData}.
code_change(OldVsn, StateName, StateData, Extra) -> code_change(_OldVsn, StateName, StateData, _Extra) ->
{ok, StateName, StateData}. {ok, StateName, StateData}.
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
@ -673,7 +661,7 @@ code_change(OldVsn, StateName, StateData, Extra) ->
handle_info({send_text, Text}, StateName, StateData) -> handle_info({send_text, Text}, StateName, StateData) ->
send_text(StateData, Text), send_text(StateData, Text),
{next_state, StateName, StateData}; {next_state, StateName, StateData};
handle_info(replaced, StateName, StateData) -> handle_info(replaced, _StateName, StateData) ->
% TODO % TODO
%send_text(StateData#state.sender, Text), %send_text(StateData#state.sender, Text),
{stop, normal, StateData#state{authentificated = replaced}}; {stop, normal, StateData#state{authentificated = replaced}};
@ -721,37 +709,37 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
end; end;
"broadcast" -> "broadcast" ->
?DEBUG("broadcast~n~p~n", [Els]), ?DEBUG("broadcast~n~p~n", [Els]),
NewSt = case Els of case Els of
[{item, IJID, ISubscription}] -> [{item, IJID, ISubscription}] ->
{false, Attrs, {false, Attrs,
roster_change(IJID, ISubscription, roster_change(IJID, ISubscription,
StateData)}; StateData)};
[{exit, Reason}] -> [{exit, Reason}] ->
{exit, Attrs, Reason}; {exit, Attrs, Reason};
[{privacy_list, PrivList}] -> [{privacy_list, PrivList}] ->
{false, Attrs, {false, Attrs,
case catch mod_privacy:updated_list( case catch mod_privacy:updated_list(
StateData#state.privacy_list, StateData#state.privacy_list,
PrivList) of PrivList) of
{'EXIT', _} -> {'EXIT', _} ->
{false, Attrs, StateData}; {false, Attrs, StateData};
NewPL -> NewPL ->
StateData#state{privacy_list = NewPL} StateData#state{privacy_list = NewPL}
end}; end};
_ -> _ ->
{false, Attrs, StateData} {false, Attrs, StateData}
end; end;
"iq" -> "iq" ->
IQ = jlib:iq_query_info(Packet), IQ = jlib:iq_query_info(Packet),
case IQ of case IQ of
{iq, ID, Type, ?NS_VCARD, SubEl} -> #iq{xmlns = ?NS_VCARD} ->
ResIQ = mod_vcard:process_sm_iq(From, To, IQ), ResIQ = mod_vcard:process_sm_iq(From, To, IQ),
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
{false, Attrs, StateData}; {false, Attrs, StateData};
%-ifdef(PRIVACY_SUPPORT). %-ifdef(PRIVACY_SUPPORT).
{iq, _ID, Type, _XMLNS, _SubEl} -> #iq{} ->
case catch mod_privacy:check_packet( case catch mod_privacy:check_packet(
StateData#state.user, StateData#state.user,
StateData#state.privacy_list, StateData#state.privacy_list,
@ -808,7 +796,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
%% Purpose: Shutdown the fsm %% Purpose: Shutdown the fsm
%% Returns: any %% Returns: any
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
terminate(Reason, StateName, StateData) -> terminate(_Reason, StateName, StateData) ->
case StateName of case StateName of
session_established -> session_established ->
case StateData#state.authentificated of case StateData#state.authentificated of
@ -870,7 +858,7 @@ new_id() ->
is_auth_packet(El) -> is_auth_packet(El) ->
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
{iq, ID, Type, ?NS_AUTH, SubEl} -> #iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} ->
{xmlelement, _, _, Els} = SubEl, {xmlelement, _, _, Els} = SubEl,
{auth, ID, Type, {auth, ID, Type,
get_auth_tags(Els, "", "", "", "")}; get_auth_tags(Els, "", "", "", "")};
@ -879,7 +867,7 @@ is_auth_packet(El) ->
end. end.
get_auth_tags([{xmlelement, Name, Attrs, Els}| L], U, P, D, R) -> get_auth_tags([{xmlelement, Name, _Attrs, Els}| L], U, P, D, R) ->
CData = xml:get_cdata(Els), CData = xml:get_cdata(Els),
case Name of case Name of
"username" -> "username" ->
@ -947,7 +935,7 @@ process_presence_probe(From, To, StateData) ->
end. end.
presence_update(From, Packet, StateData) -> presence_update(From, Packet, StateData) ->
{xmlelement, Name, Attrs, Els} = Packet, {xmlelement, _Name, Attrs, _Els} = Packet,
case xml:get_attr_s("type", Attrs) of case xml:get_attr_s("type", Attrs) of
"unavailable" -> "unavailable" ->
ejabberd_sm:unset_presence(StateData#state.user, ejabberd_sm:unset_presence(StateData#state.user,
@ -1019,7 +1007,7 @@ presence_update(From, Packet, StateData) ->
end. end.
presence_track(From, To, Packet, StateData) -> presence_track(From, To, Packet, StateData) ->
{xmlelement, Name, Attrs, Els} = Packet, {xmlelement, _Name, Attrs, _Els} = Packet,
LTo = jlib:jid_tolower(To), LTo = jlib:jid_tolower(To),
User = StateData#state.user, User = StateData#state.user,
case xml:get_attr_s("type", Attrs) of case xml:get_attr_s("type", Attrs) of
@ -1245,7 +1233,9 @@ update_priority(El, StateData) ->
process_privacy_iq(From, To, {iq, ID, Type, XMLNS, SubEl} = IQ, StateData) -> process_privacy_iq(From, To,
#iq{type = Type, sub_el = SubEl} = IQ,
StateData) ->
{Res, NewStateData} = {Res, NewStateData} =
case Type of case Type of
get -> get ->
@ -1272,10 +1262,9 @@ process_privacy_iq(From, To, {iq, ID, Type, XMLNS, SubEl} = IQ, StateData) ->
IQRes = IQRes =
case Res of case Res of
{result, Result} -> {result, Result} ->
{iq, ID, result, XMLNS, Result}; IQ#iq{type = result, sub_el = Result};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, Error]}
[SubEl, Error]}
end, end,
ejabberd_router:route( ejabberd_router:route(
To, From, jlib:iq_to_xml(IQRes)), To, From, jlib:iq_to_xml(IQRes)),

View File

@ -106,31 +106,24 @@ do_route(State, From, To, Packet) ->
process_iq(State, From, To, Packet) -> process_iq(State, From, To, Packet) ->
IQ = jlib:iq_query_info(Packet), IQ = jlib:iq_query_info(Packet),
case IQ of case IQ of
{iq, _ID, Type, XMLNS, _SubEl} -> #iq{xmlns = XMLNS} ->
case jlib:is_iq_request_type(Type) of case ets:lookup(State#state.iqtable, XMLNS) of
true -> [{_, Module, Function}] ->
case ets:lookup(State#state.iqtable, XMLNS) of ResIQ = Module:Function(From, To, IQ),
[{_, Module, Function}] -> if
ResIQ = apply(Module, Function, [From, To, IQ]), ResIQ /= ignore ->
if ejabberd_router:route(
ResIQ /= ignore -> To, From, jlib:iq_to_xml(ResIQ));
ejabberd_router ! {route, true ->
To, ok
From,
jlib:iq_to_xml(ResIQ)};
true ->
ok
end;
[{_, Module, Function, Opts}] ->
gen_iq_handler:handle(Module, Function, Opts,
From, To, IQ);
[] ->
Err = jlib:make_error_reply(
Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(To, From, Err)
end; end;
_ -> [{_, Module, Function, Opts}] ->
ok gen_iq_handler:handle(Module, Function, Opts,
From, To, IQ);
[] ->
Err = jlib:make_error_reply(
Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(To, From, Err)
end; end;
reply -> reply ->
ok; ok;

View File

@ -341,7 +341,7 @@ dirty_get_my_sessions_list() ->
process_iq(From, To, Packet) -> process_iq(From, To, Packet) ->
IQ = jlib:iq_query_info(Packet), IQ = jlib:iq_query_info(Packet),
case IQ of case IQ of
{iq, _ID, _Type, XMLNS, _SubEl} -> #iq{xmlns = XMLNS} ->
case ets:lookup(sm_iqtable, XMLNS) of case ets:lookup(sm_iqtable, XMLNS) of
[{_, Module, Function}] -> [{_, Module, Function}] ->
ResIQ = Module:Function(From, To, IQ), ResIQ = Module:Function(From, To, IQ),
@ -366,7 +366,7 @@ process_iq(From, To, Packet) ->
ok; ok;
_ -> _ ->
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
ejabberd_router ! {route, To, From, Err}, ejabberd_router:route(To, From, Err),
ok ok
end. end.

View File

@ -82,7 +82,7 @@ init([File, User, Pid]) ->
%% {stop, Reason, NewStateData} %% {stop, Reason, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
wait_for_xdb({xmlstreamstart, Name, Attrs}, StateData) -> wait_for_xdb({xmlstreamstart, Name, _Attrs}, StateData) ->
case Name of case Name of
"xdb" -> "xdb" ->
{next_state, xdb_data, StateData}; {next_state, xdb_data, StateData};
@ -95,7 +95,7 @@ wait_for_xdb(closed, StateData) ->
xdb_data({xmlstreamelement, El}, StateData) -> xdb_data({xmlstreamelement, El}, StateData) ->
{xmlelement, Name, Attrs, Els} = El, {xmlelement, _Name, Attrs, _Els} = El,
Server = StateData#state.server, Server = StateData#state.server,
From = jlib:make_jid(StateData#state.user, Server, ""), From = jlib:make_jid(StateData#state.user, Server, ""),
NewState = NewState =
@ -107,13 +107,14 @@ xdb_data({xmlstreamelement, El}, StateData) ->
?NS_ROSTER -> ?NS_ROSTER ->
%mod_roster:process_iq(From, %mod_roster:process_iq(From,
% {"", ?MYNAME, ""}, % {"", ?MYNAME, ""},
% {iq, "", set, ?NS_ROSTER, El}), % #iq{type = set, xmlns = ?NS_ROSTER, sub_el = El}),
mod_roster:set_items(StateData#state.user, El), mod_roster:set_items(StateData#state.user, El),
StateData; StateData;
?NS_VCARD -> ?NS_VCARD ->
Res = mod_vcard:process_sm_iq(From, mod_vcard:process_sm_iq(
jlib:make_jid("", ?MYNAME, ""), From,
{iq, "", set, ?NS_VCARD, El}), jlib:make_jid("", ?MYNAME, ""),
#iq{type = set, xmlns = ?NS_VCARD, sub_el = El}),
StateData; StateData;
"jabber:x:offline" -> "jabber:x:offline" ->
process_offline(From, El), process_offline(From, El),
@ -121,7 +122,7 @@ xdb_data({xmlstreamelement, El}, StateData) ->
%?NS_REGISTER -> %?NS_REGISTER ->
% mod_register:process_iq( % mod_register:process_iq(
% {"", "", ""}, {"", ?MYNAME, ""}, % {"", "", ""}, {"", ?MYNAME, ""},
% {iq, "", set, ?NS_REGISTER, El}), % #iq{type =set, xmlns = ?NS_REGISTER, xub_el = El}),
% User = xml:get_path_s(El, [{elem, "username"}, cdata]), % User = xml:get_path_s(El, [{elem, "username"}, cdata]),
% io:format("user ~s~n", [User]), % io:format("user ~s~n", [User]),
% StateData; % StateData;
@ -131,11 +132,11 @@ xdb_data({xmlstreamelement, El}, StateData) ->
mod_private:process_local_iq( mod_private:process_local_iq(
From, From,
jlib:make_jid("", ?MYNAME, ""), jlib:make_jid("", ?MYNAME, ""),
{iq, "", set, ?NS_PRIVATE, #iq{type = set, xmlns = ?NS_PRIVATE,
{xmlelement, "query", [], sub_el = {xmlelement, "query", [],
[jlib:remove_attr( [jlib:remove_attr(
"j_private_flag", "j_private_flag",
jlib:remove_attr("xdbns", El))]}}), jlib:remove_attr("xdbns", El))]}}),
StateData; StateData;
_ -> _ ->
io:format("jd2ejd: Unknown namespace \"~s\"~n", io:format("jd2ejd: Unknown namespace \"~s\"~n",
@ -145,7 +146,7 @@ xdb_data({xmlstreamelement, El}, StateData) ->
end, end,
{next_state, xdb_data, NewState}; {next_state, xdb_data, NewState};
xdb_data({xmlstreamend, Name}, StateData) -> xdb_data({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData}; {stop, normal, StateData};
xdb_data(closed, StateData) -> xdb_data(closed, StateData) ->
@ -172,7 +173,7 @@ xdb_data(closed, StateData) ->
%% {next_state, NextStateName, NextStateData, Timeout} | %% {next_state, NextStateName, NextStateData, Timeout} |
%% {stop, Reason, NewStateData} %% {stop, Reason, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_event(Event, StateName, StateData) -> handle_event(_Event, StateName, StateData) ->
{next_state, StateName, StateData}. {next_state, StateName, StateData}.
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
@ -184,11 +185,11 @@ handle_event(Event, StateName, StateData) ->
%% {stop, Reason, NewStateData} | %% {stop, Reason, NewStateData} |
%% {stop, Reason, Reply, NewStateData} %% {stop, Reason, Reply, NewStateData}
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
handle_sync_event(Event, From, StateName, StateData) -> handle_sync_event(_Event, _From, StateName, StateData) ->
Reply = ok, Reply = ok,
{reply, Reply, StateName, StateData}. {reply, Reply, StateName, StateData}.
code_change(OldVsn, StateName, StateData, Extra) -> code_change(_OldVsn, StateName, StateData, _Extra) ->
{ok, StateName, StateData}. {ok, StateName, StateData}.
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
@ -205,7 +206,7 @@ handle_info(_, StateName, StateData) ->
%% Purpose: Shutdown the fsm %% Purpose: Shutdown the fsm
%% Returns: any %% Returns: any
%%---------------------------------------------------------------------- %%----------------------------------------------------------------------
terminate(Reason, StateName, StateData) -> terminate(Reason, _StateName, StateData) ->
exit(StateData#state.xml_stream_pid, closed), exit(StateData#state.xml_stream_pid, closed),
StateData#state.pid ! {jd2ejd, Reason}, StateData#state.pid ! {jd2ejd, Reason},
% Profiling % Profiling

View File

@ -343,7 +343,8 @@ iq_query_info({xmlelement, Name, Attrs, Els}) when Name == "iq" ->
XMLNS = xml:get_attr_s("xmlns", Attrs2), XMLNS = xml:get_attr_s("xmlns", Attrs2),
if if
XMLNS /= "" -> XMLNS /= "" ->
{iq, ID, Type1, XMLNS, {xmlelement, Name2, Attrs2, Els2}}; #iq{id = ID, type = Type1, xmlns = XMLNS,
sub_el = {xmlelement, Name2, Attrs2, Els2}};
true -> true ->
invalid invalid
end; end;
@ -367,7 +368,7 @@ iq_type_to_string(error) -> "error";
iq_type_to_string(_) -> invalid. iq_type_to_string(_) -> invalid.
iq_to_xml({iq, ID, Type, _, SubEl}) -> iq_to_xml(#iq{id = ID, type = Type, sub_el = SubEl}) ->
if if
ID /= "" -> ID /= "" ->
{xmlelement, "iq", {xmlelement, "iq",

View File

@ -143,3 +143,8 @@
-record(jid, {user, server, resource, -record(jid, {user, server, resource,
luser, lserver, lresource}). luser, lserver, lresource}).
-record(iq, {id = "",
type,
xmlns = "",
sub_el}).

View File

@ -34,24 +34,26 @@ stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_IQDATA). gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_IQDATA).
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(From, _To, #iq{id = ID, type = Type,
xmlns = XMLNS, sub_el = SubEl} = IQ) ->
case acl:match_rule(configure, From) of case acl:match_rule(configure, From) of
deny -> deny ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
allow -> allow ->
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of case Type of
set -> set ->
case xml:get_tag_attr_s("type", SubEl) of case xml:get_tag_attr_s("type", SubEl) of
"cancel" -> "cancel" ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], []}]}; sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}], []}]};
"submit" -> "submit" ->
XData = jlib:parse_xdata_submit(SubEl), XData = jlib:parse_xdata_submit(SubEl),
case XData of case XData of
invalid -> invalid ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_BAD_REQUEST]}; sub_el = [SubEl, ?ERR_BAD_REQUEST]};
_ -> _ ->
Node = Node =
string:tokens( string:tokens(
@ -59,32 +61,34 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
"/"), "/"),
case set_form(Node, Lang, XData) of case set_form(Node, Lang, XData) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el =
[{"xmlns", XMLNS}], [{xmlelement, "query",
Res [{"xmlns", XMLNS}],
}]}; Res
}]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, Error]} sub_el = [SubEl, Error]}
end end
end; end;
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_NOT_ALLOWED]} sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
end; end;
get -> get ->
Node = Node =
string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
case get_form(Node, Lang) of case get_form(Node, Lang) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], sub_el =
Res [{xmlelement, "query", [{"xmlns", XMLNS}],
}]}; Res
}]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, Error]} sub_el = [SubEl, Error]}
end end
end end
end. end.
@ -129,7 +133,7 @@ get_form(["running nodes", ENode, "DB"], Lang) ->
{error, ?ERR_ITEM_NOT_FOUND}; {error, ?ERR_ITEM_NOT_FOUND};
Node -> Node ->
case rpc:call(Node, mnesia, system_info, [tables]) of case rpc:call(Node, mnesia, system_info, [tables]) of
{badrpc, Reason} -> {badrpc, _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
Tables -> Tables ->
STables = lists:sort(Tables), STables = lists:sort(Tables),
@ -163,7 +167,7 @@ get_form(["running nodes", ENode, "modules", "stop"], Lang) ->
{error, ?ERR_ITEM_NOT_FOUND}; {error, ?ERR_ITEM_NOT_FOUND};
Node -> Node ->
case rpc:call(Node, gen_mod, loaded_modules, []) of case rpc:call(Node, gen_mod, loaded_modules, []) of
{badrpc, Reason} -> {badrpc, _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
Modules -> Modules ->
SModules = lists:sort(Modules), SModules = lists:sort(Modules),
@ -698,10 +702,11 @@ search_running_node(SNode, [Node | Nodes]) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_sm_iq(From, To,
#iq{type = Type, xmlns = XMLNS, sub_el = SubEl} = IQ) ->
case acl:match_rule(configure, From) of case acl:match_rule(configure, From) of
deny -> deny ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
allow -> allow ->
#jid{user = User} = To, #jid{user = User} = To,
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
@ -709,14 +714,15 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
set -> set ->
case xml:get_tag_attr_s("type", SubEl) of case xml:get_tag_attr_s("type", SubEl) of
"cancel" -> "cancel" ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], []}]}; sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}], []}]};
"submit" -> "submit" ->
XData = jlib:parse_xdata_submit(SubEl), XData = jlib:parse_xdata_submit(SubEl),
case XData of case XData of
invalid -> invalid ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_BAD_REQUEST]}; sub_el = [SubEl, ?ERR_BAD_REQUEST]};
_ -> _ ->
Node = Node =
string:tokens( string:tokens(
@ -725,32 +731,33 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
case set_sm_form( case set_sm_form(
User, Node, Lang, XData) of User, Node, Lang, XData) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el =
[{"xmlns", XMLNS}], [{xmlelement, "query",
Res [{"xmlns", XMLNS}],
}]}; Res
}]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, Error]} sub_el = [SubEl, Error]}
end end
end; end;
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_NOT_ALLOWED]} sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
end; end;
get -> get ->
Node = Node =
string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
case get_sm_form(User, Node, Lang) of case get_sm_form(User, Node, Lang) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], sub_el =
Res [{xmlelement, "query", [{"xmlns", XMLNS}],
}]}; Res
}]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, Error]}
[SubEl, Error]}
end end
end end
end. end.

View File

@ -32,16 +32,16 @@ stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_IQDATA). gen_iq_handler:remove_iq_handler(ejabberd_sm, ?NS_IQDATA).
process_local_iq(From, _To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
case acl:match_rule(configure, From) of case acl:match_rule(configure, From) of
deny -> deny ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
allow -> allow ->
%Lang = xml:get_tag_attr_s("xml:lang", SubEl), %Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]}; sub_el = [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]};
%case xml:get_tag_attr_s("type", SubEl) of %case xml:get_tag_attr_s("type", SubEl) of
% "cancel" -> % "cancel" ->
% {iq, ID, result, XMLNS, % {iq, ID, result, XMLNS,
@ -76,9 +76,9 @@ process_local_iq(From, _To, {iq, ID, Type, XMLNS, SubEl}) ->
get -> get ->
case process_get(SubEl) of case process_get(SubEl) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, [Res]}; IQ#iq{type = result, sub_el = [Res]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, [SubEl, Error]} IQ#iq{type = error, sub_el = [SubEl, Error]}
end end
end end
end. end.

View File

@ -27,9 +27,10 @@
-include("jlib.hrl"). -include("jlib.hrl").
-define(EMPTY_INFO_RESULT, -define(EMPTY_INFO_RESULT,
{iq, ID, result, XMLNS, [{xmlelement, "query", IQ#iq{type = result,
[{"xmlns", ?NS_DISCO_INFO}, sub_el = [{xmlelement, "query",
{"node", SNode}], []}]}). [{"xmlns", ?NS_DISCO_INFO},
{"node", SNode}], []}]}).
start(Opts) -> start(Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
@ -72,44 +73,45 @@ unregister_extra_domain(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). ets:delete(disco_extra_domains, Domain).
process_local_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq_items(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
get -> get ->
SNode = xml:get_tag_attr_s("node", SubEl), SNode = xml:get_tag_attr_s("node", SubEl),
Node = string:tokens(SNode, "/"), Node = string:tokens(SNode, "/"),
case acl:match_rule(configure, From) of case acl:match_rule(configure, From) of
deny when Node /= [] -> deny when Node /= [] ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
deny -> deny ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_DISCO_ITEMS}], [{"xmlns", ?NS_DISCO_ITEMS}],
get_services_only() get_services_only()
}]}; }]};
_ -> _ ->
case get_local_items(Node, jlib:jid_to_string(To), Lang) of case get_local_items(Node, jlib:jid_to_string(To), Lang) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_DISCO_ITEMS}, [{"xmlns", ?NS_DISCO_ITEMS},
{"node", SNode}], {"node", SNode}],
Res Res
}]}; }]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, [SubEl, Error]} IQ#iq{type = error, sub_el = [SubEl, Error]}
end end
end end
end. end.
process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq_info(From, _To, #iq{type = Type, xmlns = XMLNS,
sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
get -> get ->
SNode = xml:get_tag_attr_s("node", SubEl), SNode = xml:get_tag_attr_s("node", SubEl),
Node = string:tokens(SNode, "/"), Node = string:tokens(SNode, "/"),
@ -117,17 +119,18 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
{_, []} -> {_, []} ->
Features = lists:map(fun feature_to_xml/1, Features = lists:map(fun feature_to_xml/1,
ets:tab2list(disco_features)), ets:tab2list(disco_features)),
{iq, ID, result, XMLNS, [{xmlelement, IQ#iq{type = result,
"query", sub_el = [{xmlelement,
[{"xmlns", ?NS_DISCO_INFO}], "query",
[{xmlelement, "identity", [{"xmlns", ?NS_DISCO_INFO}],
[{"category", "service"}, [{xmlelement, "identity",
{"type", "im"}, [{"category", "service"},
{"name", "ejabberd"}], []}] ++ {"type", "im"},
Features {"name", "ejabberd"}], []}] ++
}]}; Features
}]};
{deny, _} -> {deny, _} ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
{allow, ["config"]} -> ?EMPTY_INFO_RESULT; {allow, ["config"]} -> ?EMPTY_INFO_RESULT;
{allow, ["online users"]} -> ?EMPTY_INFO_RESULT; {allow, ["online users"]} -> ?EMPTY_INFO_RESULT;
{allow, ["all users"]} -> ?EMPTY_INFO_RESULT; {allow, ["all users"]} -> ?EMPTY_INFO_RESULT;
@ -136,56 +139,57 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
{allow, ["running nodes"]} -> ?EMPTY_INFO_RESULT; {allow, ["running nodes"]} -> ?EMPTY_INFO_RESULT;
{allow, ["stopped nodes"]} -> ?EMPTY_INFO_RESULT; {allow, ["stopped nodes"]} -> ?EMPTY_INFO_RESULT;
{allow, ["running nodes", ENode]} -> {allow, ["running nodes", ENode]} ->
{iq, ID, result, XMLNS, [{xmlelement, IQ#iq{type = result,
"query", sub_el = [{xmlelement,
[{"xmlns", XMLNS}, "query",
{"node", SNode}], [{"xmlns", XMLNS},
[{xmlelement, "identity", {"node", SNode}],
[{"category", "ejabberd"}, [{xmlelement, "identity",
{"type", "node"}, [{"category", "ejabberd"},
{"name", ENode}], []}, {"type", "node"},
feature_to_xml({?NS_STATS}) {"name", ENode}], []},
] feature_to_xml({?NS_STATS})
}]}; ]
}]};
{allow, ["running nodes", ENode, "DB"]} -> {allow, ["running nodes", ENode, "DB"]} ->
{iq, ID, result, XMLNS, [{xmlelement, IQ#iq{type = result,
"query", sub_el = [{xmlelement,
[{"xmlns", XMLNS}, "query",
{"node", SNode}], [{"xmlns", XMLNS},
[feature_to_xml({?NS_IQDATA})]}]}; {"node", SNode}],
[feature_to_xml({?NS_IQDATA})]}]};
{allow, ["running nodes", ENode, "modules"]} -> {allow, ["running nodes", ENode, "modules"]} ->
?EMPTY_INFO_RESULT; ?EMPTY_INFO_RESULT;
{allow, ["running nodes", ENode, "modules", _]} -> {allow, ["running nodes", ENode, "modules", _]} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}, [{"xmlns", XMLNS},
{"node", SNode}], {"node", SNode}],
[feature_to_xml({?NS_IQDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
{allow, ["running nodes", ENode, "backup"]} -> {allow, ["running nodes", ENode, "backup"]} ->
?EMPTY_INFO_RESULT; ?EMPTY_INFO_RESULT;
{allow, ["running nodes", ENode, "backup", _]} -> {allow, ["running nodes", ENode, "backup", _]} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}, [{"xmlns", XMLNS},
{"node", SNode}], {"node", SNode}],
[feature_to_xml({?NS_IQDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
{allow, ["running nodes", ENode, "import"]} -> {allow, ["running nodes", ENode, "import"]} ->
?EMPTY_INFO_RESULT; ?EMPTY_INFO_RESULT;
{allow, ["running nodes", ENode, "import", _]} -> {allow, ["running nodes", ENode, "import", _]} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}, [{"xmlns", XMLNS},
{"node", SNode}], {"node", SNode}],
[feature_to_xml({?NS_IQDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
{allow, ["config", _]} -> {allow, ["config", _]} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}, [{"xmlns", XMLNS},
{"node", SNode}], {"node", SNode}],
[feature_to_xml({?NS_IQDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
[SubEl, ?ERR_ITEM_NOT_FOUND]}
end end
end. end.
@ -452,42 +456,42 @@ get_stopped_nodes(Lang) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
process_sm_iq_items(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_sm_iq_items(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
#jid{user = User} = To, #jid{user = User} = To,
case {acl:match_rule(configure, From), Type} of case {acl:match_rule(configure, From), Type} of
{deny, _} -> {deny, _} ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
{allow, set} -> {allow, set} ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
{allow, get} -> {allow, get} ->
case xml:get_tag_attr_s("node", SubEl) of case xml:get_tag_attr_s("node", SubEl) of
"" -> "" ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", ?NS_DISCO_ITEMS}], sub_el = [{xmlelement, "query",
get_user_resources(User) [{"xmlns", ?NS_DISCO_ITEMS}],
}]}; get_user_resources(User)
}]};
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
[SubEl, ?ERR_ITEM_NOT_FOUND]}
end end
end. end.
process_sm_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_sm_iq_info(From, To, #iq{type = Type, xmlns = XMLNS,
sub_el = SubEl} = IQ) ->
case {acl:match_rule(configure, From), Type} of case {acl:match_rule(configure, From), Type} of
{deny, _} -> {deny, _} ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
{allow, set} -> {allow, set} ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
{allow, get} -> {allow, get} ->
case xml:get_tag_attr_s("node", SubEl) of case xml:get_tag_attr_s("node", SubEl) of
"" -> "" ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], sub_el = [{xmlelement, "query", [{"xmlns", XMLNS}],
[feature_to_xml({?NS_IQDATA})]}]}; [feature_to_xml({?NS_IQDATA})]}]};
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
[SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]}
end end
end. end.

View File

@ -63,20 +63,24 @@ do_route(Host, From, To, Packet) ->
case Resource of case Resource of
"" -> "" ->
case jlib:iq_query_info(Packet) of case jlib:iq_query_info(Packet) of
{iq, ID, get, ?NS_DISCO_INFO = XMLNS, SubEl} -> #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
Res = {iq, ID, result, XMLNS, sub_el = SubEl} = IQ ->
[{xmlelement, "query", Res = IQ#iq{type = result,
[{"xmlns", XMLNS}], sub_el = [{xmlelement, "query",
iq_disco()}]}, [{"xmlns", XMLNS}],
iq_disco()}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(Res)); jlib:iq_to_xml(Res));
{iq, ID, Type, ?NS_IQDATA = XMLNS, SubEl} -> #iq{type = Type, xmlns = ?NS_IQDATA,
iq_data(From, To, ID, XMLNS, Type, SubEl); sub_el = SubEl} = IQ ->
_ -> iq_data(From, To, IQ);
#iq{} = IQ ->
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
Packet, ?ERR_SERVICE_UNAVAILABLE), Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(To, From, Err) ejabberd_router:route(To, From, Err);
_ ->
ok
end; end;
_ -> _ ->
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
@ -155,8 +159,8 @@ iq_disco() ->
iq_data(From, To, ID, XMLNS, Type, SubEl) -> iq_data(From, To, #iq{type = Type} = IQ) ->
case catch process_iq_data(From, To, ID, XMLNS, Type, SubEl) of case catch process_iq_data(From, To, IQ) of
{'EXIT', Reason} -> {'EXIT', Reason} ->
?ERROR_MSG("~p", [Reason]); ?ERROR_MSG("~p", [Reason]);
ResIQ -> ResIQ ->
@ -170,20 +174,22 @@ iq_data(From, To, ID, XMLNS, Type, SubEl) ->
end. end.
process_iq_data(From, To, ID, XMLNS, Type, SubEl) -> process_iq_data(From, To,
#iq{type = Type, xmlns = XMLNS, sub_el = SubEl} = IQ) ->
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of case Type of
set -> set ->
case xml:get_tag_attr_s("type", SubEl) of case xml:get_tag_attr_s("type", SubEl) of
"cancel" -> "cancel" ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], []}]}; sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}], []}]};
"submit" -> "submit" ->
XData = jlib:parse_xdata_submit(SubEl), XData = jlib:parse_xdata_submit(SubEl),
case XData of case XData of
invalid -> invalid ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_BAD_REQUEST]}; sub_el = [SubEl, ?ERR_BAD_REQUEST]};
_ -> _ ->
Node = Node =
string:tokens( string:tokens(
@ -191,32 +197,32 @@ process_iq_data(From, To, ID, XMLNS, Type, SubEl) ->
"/"), "/"),
case set_form(From, Node, Lang, XData) of case set_form(From, Node, Lang, XData) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}], [{"xmlns", XMLNS}],
Res Res
}]}; }]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, Error]} sub_el = [SubEl, Error]}
end end
end; end;
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
[SubEl, ?ERR_NOT_ALLOWED]}
end; end;
get -> get ->
Node = Node =
string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
case get_form(From, Node, Lang) of case get_form(From, Node, Lang) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], sub_el = [{xmlelement, "query",
Res [{"xmlns", XMLNS}],
}]}; Res
}]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, Error]} sub_el = [SubEl, Error]}
end end
end. end.

View File

@ -294,29 +294,28 @@ handle_info({route_chan, Channel, Resource,
To = {lists:concat([Channel, "%", StateData#state.server]), To = {lists:concat([Channel, "%", StateData#state.server]),
StateData#state.myname, StateData#state.nick}, StateData#state.myname, StateData#state.nick},
case jlib:iq_query_info(El) of case jlib:iq_query_info(El) of
{iq, ID, Type, ?NS_MUC_ADMIN = XMLNS, SubEl} -> #iq{xmlns = ?NS_MUC_ADMIN} = IQ ->
iq_admin(StateData, Channel, iq_admin(StateData, Channel, From, To, IQ);
From, #iq{xmlns = ?NS_VERSION} ->
To,
ID, XMLNS, Type, SubEl);
{iq, ID, get, ?NS_VERSION = XMLNS, SubEl} ->
Res = io_lib:format("PRIVMSG ~s :\001VERSION\001\r\n", Res = io_lib:format("PRIVMSG ~s :\001VERSION\001\r\n",
[Resource]), [Resource]),
?SEND(Res), ?SEND(Res),
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
El, ?ERR_FEATURE_NOT_IMPLEMENTED), El, ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
{iq, ID, get, ?NS_TIME = XMLNS, SubEl} -> #iq{xmlns = ?NS_TIME} ->
Res = io_lib:format("PRIVMSG ~s :\001TIME\001\r\n", Res = io_lib:format("PRIVMSG ~s :\001TIME\001\r\n",
[Resource]), [Resource]),
?SEND(Res), ?SEND(Res),
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
El, ?ERR_FEATURE_NOT_IMPLEMENTED), El, ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
_ -> #iq{} ->
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
El, ?ERR_FEATURE_NOT_IMPLEMENTED), El, ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(To, From, Err) ejabberd_router:route(To, From, Err);
_ ->
ok
end, end,
{next_state, StateName, StateData}; {next_state, StateName, StateData};
@ -976,7 +975,8 @@ remove_element(E, Set) ->
iq_admin(StateData, Channel, From, To, ID, XMLNS, Type, SubEl) -> iq_admin(StateData, Channel, From, To,
#iq{type = Type, xmlns = XMLNS, sub_el = SubEl} = IQ) ->
case catch process_iq_admin(StateData, Channel, Type, SubEl) of case catch process_iq_admin(StateData, Channel, Type, SubEl) of
{'EXIT', Reason} -> {'EXIT', Reason} ->
?ERROR_MSG("~p", [Reason]); ?ERROR_MSG("~p", [Reason]);
@ -985,14 +985,14 @@ iq_admin(StateData, Channel, From, To, ID, XMLNS, Type, SubEl) ->
Res /= ignore -> Res /= ignore ->
ResIQ = case Res of ResIQ = case Res of
{result, ResEls} -> {result, ResEls} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}], [{"xmlns", XMLNS}],
ResEls ResEls
}]}; }]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, Error]} sub_el = [SubEl, Error]}
end, end,
ejabberd_router:route(To, From, ejabberd_router:route(To, From,
jlib:iq_to_xml(ResIQ)); jlib:iq_to_xml(ResIQ));

View File

@ -38,25 +38,24 @@ start(Opts) ->
stop() -> stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_LAST). gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_LAST).
process_local_iq(_From, _To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
[SubEl, ?ERR_NOT_ALLOWED]};
get -> get ->
Sec = trunc(element(1, erlang:statistics(wall_clock))/1000), Sec = trunc(element(1, erlang:statistics(wall_clock))/1000),
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_LAST}, [{"xmlns", ?NS_LAST},
{"seconds", integer_to_list(Sec)}], {"seconds", integer_to_list(Sec)}],
[]}]} []}]}
end. end.
process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
get -> get ->
User = To#jid.luser, User = To#jid.luser,
{Subscription, _Groups} = {Subscription, _Groups} =
@ -65,7 +64,7 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
(Subscription == both) or (Subscription == from) -> (Subscription == both) or (Subscription == from) ->
case catch mod_privacy:get_user_list(User) of case catch mod_privacy:get_user_list(User) of
{'EXIT', _Reason} -> {'EXIT', _Reason} ->
get_last(ID, XMLNS, SubEl, User); get_last(IQ, SubEl, User);
List -> List ->
case mod_privacy:check_packet( case mod_privacy:check_packet(
User, List, User, List,
@ -73,32 +72,33 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
{xmlelement, "presence", [], []}}, {xmlelement, "presence", [], []}},
out) of out) of
allow -> allow ->
get_last(ID, XMLNS, SubEl, User); get_last(IQ, SubEl, User);
deny -> deny ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_NOT_ALLOWED]} sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
end end
end; end;
true -> true ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]} IQ#iq{type = error,
sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
end end
end. end.
get_last(ID, XMLNS, SubEl, LUser) -> get_last(IQ, SubEl, LUser) ->
case catch mnesia:dirty_read(last_activity, LUser) of case catch mnesia:dirty_read(last_activity, LUser) of
{'EXIT', _Reason} -> {'EXIT', _Reason} ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
[] -> [] ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_SERVICE_UNAVAILABLE]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
[#last_activity{timestamp = TimeStamp}] -> [#last_activity{timestamp = TimeStamp}] ->
{MegaSecs, Secs, _MicroSecs} = now(), {MegaSecs, Secs, _MicroSecs} = now(),
TimeStamp2 = MegaSecs * 1000000 + Secs, TimeStamp2 = MegaSecs * 1000000 + Secs,
Sec = TimeStamp2 - TimeStamp, Sec = TimeStamp2 - TimeStamp,
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_LAST}, [{"xmlns", ?NS_LAST},
{"seconds", integer_to_list(Sec)}], {"seconds", integer_to_list(Sec)}],
[]}]} []}]}
end. end.

View File

@ -19,7 +19,7 @@
store_room/2, store_room/2,
restore_room/1, restore_room/1,
forget_room/1, forget_room/1,
process_iq_disco_items/5, process_iq_disco_items/4,
can_use_nick/2]). can_use_nick/2]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
@ -84,36 +84,44 @@ do_route(Host, From, To, Packet) ->
case Name of case Name of
"iq" -> "iq" ->
case jlib:iq_query_info(Packet) of case jlib:iq_query_info(Packet) of
{iq, ID, get, ?NS_DISCO_INFO = XMLNS, SubEl} -> #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
Res = {iq, ID, result, XMLNS, sub_el = SubEl} = IQ ->
[{xmlelement, "query", Res = IQ#iq{type = result,
[{"xmlns", XMLNS}], sub_el = [{xmlelement, "query",
iq_disco_info()}]}, [{"xmlns", XMLNS}],
iq_disco_info()}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(Res)); jlib:iq_to_xml(Res));
{iq, ID, get, ?NS_DISCO_ITEMS = XMLNS, SubEl} -> #iq{type = get,
xmlns = ?NS_DISCO_ITEMS} = IQ ->
spawn(?MODULE, spawn(?MODULE,
process_iq_disco_items, process_iq_disco_items,
[Host, From, To, ID, SubEl]); [Host, From, To, IQ]);
{iq, ID, get, ?NS_REGISTER = XMLNS, SubEl} -> #iq{type = get,
xmlns = ?NS_REGISTER = XMLNS,
sub_el = SubEl} = IQ ->
Lang = xml:get_tag_attr_s( Lang = xml:get_tag_attr_s(
"xml:lang", SubEl), "xml:lang", SubEl),
Res = {iq, ID, result, XMLNS, Res = IQ#iq{type = result,
[{xmlelement, "query", sub_el =
[{"xmlns", XMLNS}], [{xmlelement, "query",
iq_get_register_info( [{"xmlns", XMLNS}],
From, Lang)}]}, iq_get_register_info(
From, Lang)}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(Res)); jlib:iq_to_xml(Res));
{iq, ID, set, ?NS_REGISTER = XMLNS, SubEl} -> #iq{type = set,
xmlns = ?NS_REGISTER = XMLNS,
sub_el = SubEl} = IQ ->
case process_iq_register_set(From, SubEl) of case process_iq_register_set(From, SubEl) of
{result, IQRes} -> {result, IQRes} ->
Res = {iq, ID, result, XMLNS, Res = IQ#iq{type = result,
[{xmlelement, "query", sub_el =
[{"xmlns", XMLNS}], [{xmlelement, "query",
IQRes}]}, [{"xmlns", XMLNS}],
IQRes}]},
ejabberd_router:route( ejabberd_router:route(
To, From, jlib:iq_to_xml(Res)); To, From, jlib:iq_to_xml(Res));
{error, Error} -> {error, Error} ->
@ -122,23 +130,26 @@ do_route(Host, From, To, Packet) ->
ejabberd_router:route( ejabberd_router:route(
To, From, Err) To, From, Err)
end; end;
{iq, ID, get, ?NS_VCARD = XMLNS, SubEl} -> #iq{type = get,
xmlns = ?NS_VCARD = XMLNS,
sub_el = SubEl} = IQ ->
Lang = xml:get_tag_attr_s( Lang = xml:get_tag_attr_s(
"xml:lang", SubEl), "xml:lang", SubEl),
Res = {iq, ID, result, XMLNS, Res = IQ#iq{type = result,
[{xmlelement, "query", sub_el =
[{"xmlns", XMLNS}], [{xmlelement, "query",
iq_get_vcard(Lang)}]}, [{"xmlns", XMLNS}],
iq_get_vcard(Lang)}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(Res)); jlib:iq_to_xml(Res));
reply -> #iq{} ->
ok;
_ ->
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
Packet, Packet,
?ERR_FEATURE_NOT_IMPLEMENTED), ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(To, From, Err) ejabberd_router:route(To, From, Err);
_ ->
ok
end; end;
"message" -> "message" ->
case xml:get_attr_s("type", Attrs) of case xml:get_attr_s("type", Attrs) of
@ -265,11 +276,11 @@ iq_disco_info() ->
{xmlelement, "feature", [{"var", ?NS_VCARD}], []}]. {xmlelement, "feature", [{"var", ?NS_VCARD}], []}].
process_iq_disco_items(Host, From, To, ID, SubEl) -> process_iq_disco_items(Host, From, To, IQ) ->
Res = {iq, ID, result, ?NS_DISCO_ITEMS, Res = IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_DISCO_ITEMS}], [{"xmlns", ?NS_DISCO_ITEMS}],
iq_disco_items(Host, From)}]}, iq_disco_items(Host, From)}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(Res)). jlib:iq_to_xml(Res)).

View File

@ -271,7 +271,7 @@ normal_state({route, From, "",
{xmlelement, "iq", Attrs, Els} = Packet}, {xmlelement, "iq", Attrs, Els} = Packet},
StateData) -> StateData) ->
case jlib:iq_query_info(Packet) of case jlib:iq_query_info(Packet) of
{iq, ID, Type, XMLNS, SubEl} when #iq{type = Type, xmlns = XMLNS, sub_el = SubEl} = IQ when
(XMLNS == ?NS_MUC_ADMIN) or (XMLNS == ?NS_MUC_ADMIN) or
(XMLNS == ?NS_MUC_OWNER) or (XMLNS == ?NS_MUC_OWNER) or
(XMLNS == ?NS_DISCO_INFO) or (XMLNS == ?NS_DISCO_INFO) or
@ -289,14 +289,15 @@ normal_state({route, From, "",
{IQRes, NewStateData} = {IQRes, NewStateData} =
case Res1 of case Res1 of
{result, Res, SD} -> {result, Res, SD} ->
{{iq, ID, result, XMLNS, {IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], sub_el = [{xmlelement, "query",
Res [{"xmlns", XMLNS}],
}]}, Res
}]},
SD}; SD};
{error, Error} -> {error, Error} ->
{{iq, ID, error, XMLNS, {IQ#iq{type = error,
[SubEl, Error]}, sub_el = [SubEl, Error]},
StateData} StateData}
end, end,
ejabberd_router:route(StateData#state.jid, ejabberd_router:route(StateData#state.jid,

View File

@ -49,18 +49,9 @@ start(Opts) ->
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_PRIVACY, gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_PRIVACY,
?MODULE, process_iq, IQDisc). ?MODULE, process_iq, IQDisc).
%process_local_iq(From, To, {iq, _, Type, _, _} = IQ) ->
% case Type of process_iq(From, _To, IQ) ->
% set -> #iq{type = Type, sub_el = SubEl} = IQ,
% process_iq_set(From, To, IQ);
% get ->
% process_iq_get(From, To, IQ)
% end.
%
%
%
process_iq(From, To, IQ) ->
{iq, ID, Type, XMLNS, SubEl} = IQ,
#jid{lserver = Server} = From, #jid{lserver = Server} = From,
Res = Res =
case ?MYNAME of case ?MYNAME of
@ -77,20 +68,20 @@ process_iq(From, To, IQ) ->
end, end,
case Res of case Res of
{result, IQRes} -> {result, IQRes} ->
{iq, ID, result, XMLNS, IQRes}; IQ#iq{type = result, sub_el = IQRes};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, [SubEl, Error]} IQ#iq{type = error, sub_el = [SubEl, Error]}
end. end.
process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl}, process_iq_get(From, _To, #iq{sub_el = SubEl},
#userlist{name = Active}) -> #userlist{name = Active}) ->
#jid{luser = LUser} = From, #jid{luser = LUser} = From,
{xmlelement, _, _, Els} = SubEl, {xmlelement, _, _, Els} = SubEl,
case xml:remove_cdata(Els) of case xml:remove_cdata(Els) of
[] -> [] ->
process_lists_get(LUser, Active); process_lists_get(LUser, Active);
[{xmlelement, Name, Attrs, SubEls}] -> [{xmlelement, Name, Attrs, _SubEls}] ->
case Name of case Name of
"list" -> "list" ->
ListName = xml:get_attr("name", Attrs), ListName = xml:get_attr("name", Attrs),
@ -105,7 +96,7 @@ process_iq_get(From, To, {iq, ID, Type, XMLNS, SubEl},
process_lists_get(LUser, Active) -> process_lists_get(LUser, Active) ->
case catch mnesia:dirty_read(privacy, LUser) of case catch mnesia:dirty_read(privacy, LUser) of
{'EXIT', Reason} -> {'EXIT', _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
[] -> [] ->
{result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]}; {result, [{xmlelement, "query", [{"xmlns", ?NS_PRIVACY}], []}]};
@ -144,7 +135,7 @@ process_lists_get(LUser, Active) ->
process_list_get(LUser, {value, Name}) -> process_list_get(LUser, {value, Name}) ->
case catch mnesia:dirty_read(privacy, LUser) of case catch mnesia:dirty_read(privacy, LUser) of
{'EXIT', Reason} -> {'EXIT', _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
[] -> [] ->
{error, ?ERR_ITEM_NOT_FOUND}; {error, ?ERR_ITEM_NOT_FOUND};
@ -248,7 +239,7 @@ list_to_action(S) ->
process_iq_set(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_iq_set(From, _To, #iq{sub_el = SubEl}) ->
#jid{luser = LUser} = From, #jid{luser = LUser} = From,
{xmlelement, _, _, Els} = SubEl, {xmlelement, _, _, Els} = SubEl,
case xml:remove_cdata(Els) of case xml:remove_cdata(Els) of
@ -318,7 +309,7 @@ process_active_set(LUser, {value, Name}) ->
case catch mnesia:dirty_read(privacy, LUser) of case catch mnesia:dirty_read(privacy, LUser) of
[] -> [] ->
{error, ?ERR_ITEM_NOT_FOUND}; {error, ?ERR_ITEM_NOT_FOUND};
[#privacy{lists = Lists} = P] -> [#privacy{lists = Lists}] ->
case lists:keysearch(Name, 1, Lists) of case lists:keysearch(Name, 1, Lists) of
{value, {_, List}} -> {value, {_, List}} ->
{result, [], #userlist{name = Name, list = List}}; {result, [], #userlist{name = Name, list = List}};
@ -327,7 +318,7 @@ process_active_set(LUser, {value, Name}) ->
end end
end; end;
process_active_set(LUser, false) -> process_active_set(_LUser, false) ->
{result, [], #userlist{}}. {result, [], #userlist{}}.
@ -490,7 +481,7 @@ parse_items([{xmlelement, "item", Attrs, SubEls} | Els], Res) ->
false false
end; end;
parse_items(_, Res) -> parse_items(_, _Res) ->
false. false.
@ -509,7 +500,7 @@ parse_matches1(Item, [{xmlelement, "presence-in", _, _} | Els]) ->
parse_matches1(Item#listitem{match_presence_in = true}, Els); parse_matches1(Item#listitem{match_presence_in = true}, Els);
parse_matches1(Item, [{xmlelement, "presence-out", _, _} | Els]) -> parse_matches1(Item, [{xmlelement, "presence-out", _, _} | Els]) ->
parse_matches1(Item#listitem{match_presence_out = true}, Els); parse_matches1(Item#listitem{match_presence_out = true}, Els);
parse_matches1(Item, [{xmlelement, _, _, _} | Els]) -> parse_matches1(_Item, [{xmlelement, _, _, _} | _Els]) ->
false. false.
@ -584,7 +575,7 @@ check_packet(User,
end end
end. end.
check_packet_aux([], PType, JID, Subscription, Groups) -> check_packet_aux([], _PType, _JID, _Subscription, _Groups) ->
allow; allow;
check_packet_aux([Item | List], PType, JID, Subscription, Groups) -> check_packet_aux([Item | List], PType, JID, Subscription, Groups) ->
#listitem{type = Type, value = Value, action = Action} = Item, #listitem{type = Type, value = Value, action = Action} = Item,

View File

@ -34,10 +34,10 @@ stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_PRIVATE). gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_PRIVATE).
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
#jid{luser = LUser, lserver = LServer} = From, #jid{luser = LUser, lserver = LServer} = From,
case ?MYNAME of case ?MYNAME of
Server -> LServer ->
{xmlelement, Name, Attrs, Els} = SubEl, {xmlelement, Name, Attrs, Els} = SubEl,
case Type of case Type of
set -> set ->
@ -48,24 +48,26 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
end, Els) end, Els)
end, end,
mnesia:transaction(F), mnesia:transaction(F),
{iq, ID, result, XMLNS, [{xmlelement, Name, Attrs, []}]}; IQ#iq{type = result,
sub_el = [{xmlelement, Name, Attrs, []}]};
get -> get ->
case catch get_data(LUser, Els) of case catch get_data(LUser, Els) of
{'EXIT', Reason} -> {'EXIT', _Reason} ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_INTERNAL_SERVER_ERROR]}; sub_el = [SubEl,
?ERR_INTERNAL_SERVER_ERROR]};
Res -> Res ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, Name, Attrs, Res}]} sub_el = [{xmlelement, Name, Attrs, Res}]}
end end
end; end;
_ -> _ ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]} IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
end. end.
set_data(LUser, El) -> set_data(LUser, El) ->
case El of case El of
{xmlelement, Name, Attrs, Els} -> {xmlelement, _Name, Attrs, _Els} ->
XMLNS = xml:get_attr_s("xmlns", Attrs), XMLNS = xml:get_attr_s("xmlns", Attrs),
case XMLNS of case XMLNS of
"" -> "" ->
@ -81,11 +83,11 @@ set_data(LUser, El) ->
get_data(LUser, Els) -> get_data(LUser, Els) ->
get_data(LUser, Els, []). get_data(LUser, Els, []).
get_data(LUser, [], Res) -> get_data(_LUser, [], Res) ->
lists:reverse(Res); lists:reverse(Res);
get_data(LUser, [El | Els], Res) -> get_data(LUser, [El | Els], Res) ->
case El of case El of
{xmlelement, Name, Attrs, _} -> {xmlelement, _Name, Attrs, _} ->
XMLNS = xml:get_attr_s("xmlns", Attrs), XMLNS = xml:get_attr_s("xmlns", Attrs),
case mnesia:dirty_read(private_storage, {LUser, XMLNS}) of case mnesia:dirty_read(private_storage, {LUser, XMLNS}) of
[R] -> [R] ->

View File

@ -92,27 +92,29 @@ do_route(Host, From, To, Packet) ->
case Name of case Name of
"iq" -> "iq" ->
case jlib:iq_query_info(Packet) of case jlib:iq_query_info(Packet) of
{iq, ID, get, ?NS_DISCO_INFO = XMLNS, SubEl} -> #iq{type = get, xmlns = ?NS_DISCO_INFO = XMLNS,
sub_el = SubEl} = IQ ->
{xmlelement, _, QAttrs, _} = SubEl, {xmlelement, _, QAttrs, _} = SubEl,
Node = xml:get_attr_s("node", QAttrs), Node = xml:get_attr_s("node", QAttrs),
Res = {iq, ID, result, XMLNS, Res = IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
QAttrs, QAttrs,
iq_disco_info(Node)}]}, iq_disco_info(Node)}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(Res)); jlib:iq_to_xml(Res));
{iq, ID, get, ?NS_DISCO_ITEMS = XMLNS, SubEl} -> #iq{type = get, xmlns = ?NS_DISCO_ITEMS = XMLNS,
sub_el = SubEl} = IQ ->
{xmlelement, _, QAttrs, _} = SubEl, {xmlelement, _, QAttrs, _} = SubEl,
Node = xml:get_attr_s("node", QAttrs), Node = xml:get_attr_s("node", QAttrs),
Res = Res =
case iq_disco_items(Host, From, Node) of case iq_disco_items(Host, From, Node) of
{result, IQRes} -> {result, IQRes} ->
jlib:iq_to_xml( jlib:iq_to_xml(
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
QAttrs, QAttrs,
IQRes}]}); IQRes}]});
{error, Error} -> {error, Error} ->
jlib:make_error_reply( jlib:make_error_reply(
Packet, Error) Packet, Error)
@ -144,35 +146,37 @@ do_route(Host, From, To, Packet) ->
% ejabberd_router:route( % ejabberd_router:route(
% To, From, Err) % To, From, Err)
% end; % end;
{iq, ID, Type, ?NS_PUBSUB = XMLNS, SubEl} -> #iq{type = Type, xmlns = ?NS_PUBSUB = XMLNS,
sub_el = SubEl} = IQ ->
Res = Res =
case iq_pubsub(Host, From, Type, SubEl) of case iq_pubsub(Host, From, Type, SubEl) of
{result, IQRes} -> {result, IQRes} ->
jlib:iq_to_xml( jlib:iq_to_xml(
{iq, ID, result, XMLNS, IQ#iq{type = result,
IQRes}); sub_el = IQRes});
{error, Error} -> {error, Error} ->
jlib:make_error_reply( jlib:make_error_reply(
Packet, Error) Packet, Error)
end, end,
ejabberd_router:route(To, From, Res); ejabberd_router:route(To, From, Res);
{iq, ID, get, ?NS_VCARD = XMLNS, SubEl} -> #iq{type = get, xmlns = ?NS_VCARD = XMLNS,
sub_el = SubEl} = IQ ->
Lang = xml:get_tag_attr_s( Lang = xml:get_tag_attr_s(
"xml:lang", SubEl), "xml:lang", SubEl),
Res = {iq, ID, result, XMLNS, Res = IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}], [{"xmlns", XMLNS}],
iq_get_vcard(Lang)}]}, iq_get_vcard(Lang)}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(Res)); jlib:iq_to_xml(Res));
reply -> #iq{} ->
ok;
_ ->
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
Packet, Packet,
?ERR_FEATURE_NOT_IMPLEMENTED), ?ERR_FEATURE_NOT_IMPLEMENTED),
ejabberd_router:route(To, From, Err) ejabberd_router:route(To, From, Err);
_ ->
ok
end; end;
_ -> _ ->
ok ok

View File

@ -28,7 +28,7 @@ start(Opts) ->
init() -> init() ->
ok. ok.
process_iq(From, _To, {iq, ID, Type, XMLNS, SubEl}) -> process_iq(From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
UTag = xml:get_subtag(SubEl, "username"), UTag = xml:get_subtag(SubEl, "username"),
@ -41,7 +41,7 @@ process_iq(From, _To, {iq, ID, Type, XMLNS, SubEl}) ->
case From of case From of
#jid{user = User, lserver = Server} -> #jid{user = User, lserver = Server} ->
ejabberd_auth:remove_user(User), ejabberd_auth:remove_user(User),
{iq, ID, result, XMLNS, [SubEl]}; IQ#iq{type = result, sub_el = [SubEl]};
_ -> _ ->
if if
PTag /= false -> PTag /= false ->
@ -49,34 +49,35 @@ process_iq(From, _To, {iq, ID, Type, XMLNS, SubEl}) ->
case ejabberd_auth:remove_user(User, case ejabberd_auth:remove_user(User,
Password) of Password) of
ok -> ok ->
{iq, ID, result, XMLNS, [SubEl]}; IQ#iq{type = result,
sub_el = [SubEl]};
not_allowed -> not_allowed ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_NOT_ALLOWED]}; sub_el =
[SubEl, ?ERR_NOT_ALLOWED]};
not_exists -> not_exists ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, {xmlelement, sub_el =
"error", [SubEl, ?ERR_ITEM_NOT_FOUND]};
[{"code", "404"}],
[{xmlcdata,
"Not Found"}]}]};
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, sub_el =
?ERR_INTERNAL_SERVER_ERROR]} [SubEl,
?ERR_INTERNAL_SERVER_ERROR]}
end; end;
true -> true ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_BAD_REQUEST]} sub_el = [SubEl, ?ERR_BAD_REQUEST]}
end end
end; end;
(UTag == false) and (RTag /= false) -> (UTag == false) and (RTag /= false) ->
case From of case From of
#jid{user = User, lserver = Server} -> #jid{user = User, lserver = Server} ->
ejabberd_auth:remove_user(User), ejabberd_auth:remove_user(User),
{iq, ID, result, XMLNS, [SubEl]}; IQ#iq{type = result, sub_el = [SubEl]};
_ -> _ ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]} IQ#iq{type = error,
sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
end; end;
(UTag /= false) and (PTag /= false) -> (UTag /= false) and (PTag /= false) ->
User = xml:get_tag_cdata(UTag), User = xml:get_tag_cdata(UTag),
@ -84,32 +85,34 @@ process_iq(From, _To, {iq, ID, Type, XMLNS, SubEl}) ->
case From of case From of
#jid{user = User, lserver = Server} -> #jid{user = User, lserver = Server} ->
ejabberd_auth:set_password(User, Password), ejabberd_auth:set_password(User, Password),
{iq, ID, result, XMLNS, [SubEl]}; IQ#iq{type = result, sub_el = [SubEl]};
_ -> _ ->
case try_register(User, Password) of case try_register(User, Password) of
ok -> ok ->
{iq, ID, result, XMLNS, [SubEl]}; IQ#iq{type = result, sub_el = [SubEl]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, Error]} sub_el = [SubEl, Error]}
end end
end; end;
true -> true ->
{iq, ID, error, XMLNS, IQ#iq{type = error,
[SubEl, ?ERR_BAD_REQUEST]} sub_el = [SubEl, ?ERR_BAD_REQUEST]}
end; end;
get -> get ->
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
{iq, ID, result, XMLNS, [{xmlelement, IQ#iq{type = result,
"query", sub_el = [{xmlelement,
[{"xmlns", "jabber:iq:register"}], "query",
[{xmlelement, "instructions", [], [{"xmlns", "jabber:iq:register"}],
[{xmlcdata, [{xmlelement, "instructions", [],
translate:translate(Lang, [{xmlcdata,
"Choose a username and password " translate:translate(
"to register with this server.")}]}, Lang,
{xmlelement, "username", [], []}, "Choose a username and password "
{xmlelement, "password", [], []}]}]} "to register with this server.")}]},
{xmlelement, "username", [], []},
{xmlelement, "password", [], []}]}]}
end. end.

View File

@ -49,7 +49,7 @@ start(Opts) ->
-ifdef(PSI_ROSTER_WORKAROUND). -ifdef(PSI_ROSTER_WORKAROUND).
process_iq(From, To, IQ) -> process_iq(From, To, IQ) ->
{iq, ID, _Type, XMLNS, SubEl} = IQ, #iq{sub_el = SubEl} = IQ,
#jid{lserver = LServer} = From, #jid{lserver = LServer} = From,
case ?MYNAME of case ?MYNAME of
LServer -> LServer ->
@ -58,26 +58,24 @@ process_iq(From, To, IQ) ->
jlib:iq_to_xml(ResIQ)), jlib:iq_to_xml(ResIQ)),
ignore; ignore;
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
[SubEl, ?ERR_ITEM_NOT_FOUND]}
end. end.
-else. -else.
process_iq(From, To, IQ) -> process_iq(From, To, IQ) ->
{iq, ID, _Type, XMLNS, SubEl} = IQ, #iq{sub_el = SubEl} = IQ,
#jid{lserver = LServer} = From, #jid{lserver = LServer} = From,
case ?MYNAME of case ?MYNAME of
LServer -> LServer ->
process_local_iq(From, To, IQ); process_local_iq(From, To, IQ);
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
[SubEl, ?ERR_ITEM_NOT_FOUND]}
end. end.
-endif. -endif.
process_local_iq(From, To, {iq, _, Type, _, _} = IQ) -> process_local_iq(From, To, #iq{type = Type} = IQ) ->
case Type of case Type of
set -> set ->
process_iq_set(From, To, IQ); process_iq_set(From, To, IQ);
@ -87,7 +85,7 @@ process_local_iq(From, To, {iq, _, Type, _, _} = IQ) ->
process_iq_get(From, _To, {iq, ID, _Type, XMLNS, SubEl}) -> process_iq_get(From, _To, #iq{sub_el = SubEl} = IQ) ->
#jid{luser = LUser} = From, #jid{luser = LUser} = From,
F = fun() -> F = fun() ->
mnesia:index_read(roster, LUser, #roster.user) mnesia:index_read(roster, LUser, #roster.user)
@ -95,12 +93,12 @@ process_iq_get(From, _To, {iq, ID, _Type, XMLNS, SubEl}) ->
case mnesia:transaction(F) of case mnesia:transaction(F) of
{atomic, Items} -> {atomic, Items} ->
XItems = lists:map(fun item_to_xml/1, Items), XItems = lists:map(fun item_to_xml/1, Items),
{iq, ID, result, XMLNS, [{xmlelement, "query", IQ#iq{type = result,
[{"xmlns", ?NS_ROSTER}], sub_el = [{xmlelement, "query",
XItems}]}; [{"xmlns", ?NS_ROSTER}],
XItems}]};
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
[SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
end. end.
item_to_xml(Item) -> item_to_xml(Item) ->
@ -139,10 +137,10 @@ item_to_xml(Item) ->
{xmlelement, "item", Attrs, SubEls}. {xmlelement, "item", Attrs, SubEls}.
process_iq_set(From, To, {iq, ID, _Type, XMLNS, SubEl}) -> process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
{xmlelement, _Name, _Attrs, Els} = SubEl, {xmlelement, _Name, _Attrs, Els} = SubEl,
lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els), lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els),
{iq, ID, result, XMLNS, []}. IQ#iq{type = result, sub_el = []}.
process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) -> process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)), JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
@ -287,27 +285,27 @@ push_item(User, From, Item) ->
% TODO: don't push to those who not load roster % TODO: don't push to those who not load roster
-ifdef(PSI_ROSTER_WORKAROUND). -ifdef(PSI_ROSTER_WORKAROUND).
push_item(User, Resource, From, Item) -> push_item(User, Resource, _From, Item) ->
ResIQ = {iq, "", set, ?NS_ROSTER, ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_ROSTER}], [{"xmlns", ?NS_ROSTER}],
[item_to_xml(Item)]}]}, [item_to_xml(Item)]}]},
ejabberd_router ! {route, ejabberd_router:route(
jlib:make_jid(User, ?MYNAME, Resource), jlib:make_jid(User, ?MYNAME, Resource),
jlib:make_jid(User, ?MYNAME, Resource), jlib:make_jid(User, ?MYNAME, Resource),
jlib:iq_to_xml(ResIQ)}. jlib:iq_to_xml(ResIQ)).
-else. -else.
push_item(User, Resource, From, Item) -> push_item(User, Resource, From, Item) ->
ResIQ = {iq, "", set, ?NS_ROSTER, ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_ROSTER}], [{"xmlns", ?NS_ROSTER}],
[item_to_xml(Item)]}]}, [item_to_xml(Item)]}]},
ejabberd_router ! {route, ejabberd_router:route(
From, From,
jlib:make_jid(User, ?MYNAME, Resource), jlib:make_jid(User, ?MYNAME, Resource),
jlib:iq_to_xml(ResIQ)}. jlib:iq_to_xml(ResIQ)).
-endif. -endif.

View File

@ -27,11 +27,12 @@ stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_STATS). gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_STATS).
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(From, To, #iq{id = ID, type = Type,
xmlns = XMLNS, sub_el = SubEl} = IQ) ->
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
get -> get ->
{xmlelement, _, Attrs, Els} = SubEl, {xmlelement, _, Attrs, Els} = SubEl,
Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"), Node = string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
@ -39,11 +40,12 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
case get_local_stats(Node, Names) of case get_local_stats(Node, Names) of
{result, Res} -> {result, Res} ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", [{"xmlns", XMLNS}], Res}]}; sub_el = [{xmlelement, "query",
[{"xmlns", XMLNS}],
Res}]};
{error, Error} -> {error, Error} ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, Error]}
[SubEl, Error]}
end end
end. end.

View File

@ -28,19 +28,17 @@ start(Opts) ->
stop() -> stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_TIME). gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_TIME).
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
[SubEl, ?ERR_NOT_ALLOWED]};
get -> get ->
UTC = jlib:timestamp_to_iso(calendar:universal_time()), UTC = jlib:timestamp_to_iso(calendar:universal_time()),
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_TIME}], [{"xmlns", ?NS_TIME}],
[{xmlelement, "utc", [], [{xmlelement, "utc", [],
[{xmlcdata, UTC}]} [{xmlcdata, UTC}]}]}]}
]}]}
end. end.

View File

@ -86,39 +86,38 @@ loop() ->
end. end.
process_local_iq(_From, _To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, [SubEl, ?ERR_NOT_ALLOWED]}; IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
get -> get ->
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "vCard", sub_el = [{xmlelement, "vCard",
[{"xmlns", ?NS_VCARD}], [{"xmlns", ?NS_VCARD}],
[{xmlelement, "FN", [], [{xmlelement, "FN", [],
[{xmlcdata, "ejabberd"}]}, [{xmlcdata, "ejabberd"}]},
{xmlelement, "URL", [], {xmlelement, "URL", [],
[{xmlcdata, [{xmlcdata,
"http://ejabberd.jabberstudio.org/"}]}, "http://ejabberd.jabberstudio.org/"}]},
{xmlelement, "DESC", [], {xmlelement, "DESC", [],
[{xmlcdata, "Erlang Jabber Server\n" [{xmlcdata, "Erlang Jabber Server\n"
"Copyright (c) 2002, 2003 Alexey Shchepin"}]}, "Copyright (c) 2002, 2003 Alexey Shchepin"}]},
{xmlelement, "BDAY", [], {xmlelement, "BDAY", [],
[{xmlcdata, "2002-11-16"}]} [{xmlcdata, "2002-11-16"}]}
]}]} ]}]}
end. end.
process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
#jid{user = User, lserver = LServer, luser = LUser} = From, #jid{user = User, lserver = LServer, luser = LUser} = From,
case ?MYNAME of case ?MYNAME of
LServer -> LServer ->
set_vcard(User, SubEl), set_vcard(User, SubEl),
{iq, ID, result, XMLNS, []}; IQ#iq{type = result, sub_el = []};
_ -> _ ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
[SubEl, ?ERR_NOT_ALLOWED]}
end; end;
get -> get ->
#jid{luser = LUser} = To, #jid{luser = LUser} = To,
@ -133,7 +132,7 @@ process_sm_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
{aborted, _Reason} -> {aborted, _Reason} ->
[] []
end, end,
{iq, ID, result, XMLNS, Els} IQ#iq{type = result, sub_el = Els}
end. end.
set_vcard(User, VCARD) -> set_vcard(User, VCARD) ->
@ -238,7 +237,7 @@ do_route(From, To, Packet) ->
true -> true ->
IQ = jlib:iq_query_info(Packet), IQ = jlib:iq_query_info(Packet),
case IQ of case IQ of
{iq, ID, Type, ?NS_SEARCH, SubEl} -> #iq{type = Type, xmlns = ?NS_SEARCH, sub_el = SubEl} ->
Lang = xml:get_tag_attr_s("xml:lang", SubEl), Lang = xml:get_tag_attr_s("xml:lang", SubEl),
case Type of case Type of
set -> set ->
@ -259,64 +258,71 @@ do_route(From, To, Packet) ->
Err); Err);
_ -> _ ->
ResIQ = ResIQ =
{iq, ID, result, ?NS_SEARCH, IQ#iq{
[{xmlelement, type = result,
"query", sub_el =
[{"xmlns", ?NS_SEARCH}], [{xmlelement,
[{xmlelement, "x", "query",
[{"xmlns", ?NS_XDATA}, [{"xmlns", ?NS_SEARCH}],
{"type", "result"}], [{xmlelement, "x",
search_result(Lang, XData) [{"xmlns", ?NS_XDATA},
}]}]}, {"type", "result"}],
search_result(Lang, XData)
}]}]},
ejabberd_router:route( ejabberd_router:route(
To, From, jlib:iq_to_xml(ResIQ)) To, From, jlib:iq_to_xml(ResIQ))
end end
end; end;
get -> get ->
ResIQ = {iq, ID, result, ?NS_SEARCH, ResIQ = IQ#iq{type = result,
[{xmlelement, sub_el = [{xmlelement,
"query", "query",
[{"xmlns", ?NS_SEARCH}], [{"xmlns", ?NS_SEARCH}],
?FORM ?FORM
}]}, }]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(ResIQ)) jlib:iq_to_xml(ResIQ))
end; end;
{iq, ID, Type, ?NS_DISCO_INFO, SubEl} -> #iq{type = Type, xmlns = ?NS_DISCO_INFO, sub_el = SubEl} ->
case Type of case Type of
set -> set ->
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED), Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
get -> get ->
ResIQ = {iq, ID, result, ?NS_DISCO_INFO, ResIQ =
[{xmlelement, IQ#iq{type = result,
"query", sub_el = [{xmlelement,
[{"xmlns", ?NS_DISCO_INFO}], "query",
[{xmlelement, "identity", [{"xmlns", ?NS_DISCO_INFO}],
[{"category", "directory"}, [{xmlelement, "identity",
{"type", "user"}, [{"category", "directory"},
{"name", "vCard User Search"}], []}, {"type", "user"},
{xmlelement, "feature", {"name",
[{"var", ?NS_SEARCH}], []} "vCard User Search"}],
] []},
}]}, {xmlelement, "feature",
[{"var", ?NS_SEARCH}], []}
]
}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(ResIQ)) jlib:iq_to_xml(ResIQ))
end; end;
{iq, ID, Type, ?NS_DISCO_ITEMS, SubEl} -> #iq{type = Type, xmlns = ?NS_DISCO_ITEMS, sub_el = SubEl} ->
case Type of case Type of
set -> set ->
Err = jlib:make_error_reply( Err = jlib:make_error_reply(
Packet, ?ERR_NOT_ALLOWED), Packet, ?ERR_NOT_ALLOWED),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
get -> get ->
ResIQ = {iq, ID, result, ?NS_DISCO_INFO, ResIQ =
[{xmlelement, IQ#iq{type = result,
"query", sub_el = [{xmlelement,
[{"xmlns", ?NS_DISCO_INFO}], []}]}, "query",
[{"xmlns", ?NS_DISCO_INFO}],
[]}]},
ejabberd_router:route(To, ejabberd_router:route(To,
From, From,
jlib:iq_to_xml(ResIQ)) jlib:iq_to_xml(ResIQ))

View File

@ -30,11 +30,11 @@ stop() ->
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_VERSION). gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_VERSION).
process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) -> process_local_iq(From, To, #iq{id = ID, type = Type,
xmlns = XMLNS, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
{iq, ID, error, XMLNS, IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
[SubEl, ?ERR_NOT_ALLOWED]};
get -> get ->
OSType = case os:type() of OSType = case os:type() of
{Osfamily, Osname} -> {Osfamily, Osname} ->
@ -52,16 +52,16 @@ process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
VersionString VersionString
end, end,
OS = OSType ++ " " ++ OSVersion, OS = OSType ++ " " ++ OSVersion,
{iq, ID, result, XMLNS, IQ#iq{type = result,
[{xmlelement, "query", sub_el = [{xmlelement, "query",
[{"xmlns", ?NS_VERSION}], [{"xmlns", ?NS_VERSION}],
[{xmlelement, "name", [], [{xmlelement, "name", [],
[{xmlcdata, "ejabberd"}]}, [{xmlcdata, "ejabberd"}]},
{xmlelement, "version", [], {xmlelement, "version", [],
[{xmlcdata, ?VERSION}]}, [{xmlcdata, ?VERSION}]},
{xmlelement, "os", [], {xmlelement, "os", [],
[{xmlcdata, OS}]} [{xmlcdata, OS}]}
]}]} ]}]}
end. end.