summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--src/ejabberd_s2s_in.erl46
-rw-r--r--src/ejabberd_s2s_out.erl71
-rw-r--r--src/mod_muc/mod_muc.erl44
-rw-r--r--src/mod_register.erl6
-rw-r--r--src/msgs/ru.msg11
6 files changed, 137 insertions, 56 deletions
diff --git a/ChangeLog b/ChangeLog
index f313d3ea..5ed445ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2003-12-06 Alexey Shchepin <alexey@sevcom.net>
+
+ * src/ejabberd_s2s_in.erl: Changed timeout processing, bugfix
+
+ * src/ejabberd_s2s_out.erl: Changed timeout processing
+
+ * src/msgs/ru.msg: Updated (thanks to Sergei Golovan)
+
+ * src/mod_muc/mod_muc.erl: Better i18n support, added support for
+ <registered/> field in iq:register replies (thanks to Sergei
+ Golovan)
+
+ * src/mod_register.erl: More i18n support (thanks to Sergei
+ Golovan)
+
2003-12-02 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_c2s.erl: Bugfix in processing of connection
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 7c52dc02..4da98478 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -37,7 +37,8 @@
receiver,
streamid,
shaper,
- connections = ?DICT:new()}).
+ connections = ?DICT:new(),
+ timer}).
%-define(DBGFSM, true).
@@ -95,12 +96,13 @@ init([{SockMod, Socket}, Opts]) ->
{value, {_, S}} -> S;
_ -> none
end,
+ Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
{ok, wait_for_stream,
#state{socket = Socket,
receiver = ReceiverPid,
streamid = new_id(),
- shaper = Shaper},
- ?S2STIMEOUT}.
+ shaper = Shaper,
+ timer = Timer}}.
%%----------------------------------------------------------------------
%% Func: StateName/2
@@ -114,7 +116,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
case {xml:get_attr_s("xmlns", Attrs), xml:get_attr_s("xmlns:db", Attrs)} of
{"jabber:server", "jabber:server:dialback"} ->
send_text(StateData#state.socket, ?STREAM_HEADER),
- {next_state, stream_established, StateData#state{}, ?S2STIMEOUT};
+ {next_state, stream_established, StateData#state{}};
_ ->
send_text(StateData#state.socket, ?INVALID_NAMESPACE_ERR),
{stop, normal, StateData}
@@ -132,6 +134,8 @@ wait_for_stream(closed, StateData) ->
{stop, normal, StateData}.
stream_established({xmlstreamelement, El}, StateData) ->
+ cancel_timer(StateData#state.timer),
+ Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
case is_key_packet(El) of
{key, To, From, Id, Key} ->
?INFO_MSG("GET KEY: ~p", [{To, From, Id, Key}]),
@@ -147,8 +151,8 @@ stream_established({xmlstreamelement, El}, StateData) ->
change_shaper(StateData, jlib:make_jid("", LFrom, "")),
{next_state,
stream_established,
- StateData#state{connections = Conns},
- ?S2STIMEOUT};
+ StateData#state{connections = Conns,
+ timer = Timer}};
_ ->
send_text(StateData#state.socket, ?HOST_UNKNOWN_ERR),
{stop, normal, StateData}
@@ -169,7 +173,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
{"id", Id},
{"type", Type}],
[]}),
- {next_state, wait_for_key, StateData, ?S2STIMEOUT};
+ {next_state, stream_established, StateData#state{timer = Timer}};
_ ->
{xmlelement, Name, Attrs, _Els} = El,
From_s = xml:get_attr_s("from", Attrs),
@@ -195,9 +199,9 @@ stream_established({xmlstreamelement, El}, StateData) ->
end;
true ->
error
- end
- end,
- {next_state, stream_established, StateData, ?S2STIMEOUT};
+ end,
+ {next_state, stream_established, StateData#state{timer = Timer}}
+ end;
stream_established({valid, From, To}, StateData) ->
send_element(StateData#state.socket,
@@ -212,7 +216,7 @@ stream_established({valid, From, To}, StateData) ->
NSD = StateData#state{
connections = ?DICT:store({LFrom, LTo}, established,
StateData#state.connections)},
- {next_state, stream_established, NSD, ?S2STIMEOUT};
+ {next_state, stream_established, NSD};
stream_established({invalid, From, To}, StateData) ->
send_element(StateData#state.socket,
@@ -225,9 +229,9 @@ stream_established({invalid, From, To}, StateData) ->
LFrom = jlib:nameprep(From),
LTo = jlib:nameprep(To),
NSD = StateData#state{
- connections = ?DICT:store({LFrom, LTo}, established,
+ connections = ?DICT:erase({LFrom, LTo},
StateData#state.connections)},
- {next_state, stream_established, NSD, ?S2STIMEOUT};
+ {next_state, stream_established, NSD};
stream_established({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
@@ -265,7 +269,7 @@ stream_established(closed, StateData) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
handle_event(_Event, StateName, StateData) ->
- {next_state, StateName, StateData, ?S2STIMEOUT}.
+ {next_state, StateName, StateData}.
%%----------------------------------------------------------------------
%% Func: handle_sync_event/4
@@ -292,6 +296,11 @@ code_change(_OldVsn, StateName, StateData, _Extra) ->
handle_info({send_text, Text}, StateName, StateData) ->
send_text(StateData#state.socket, Text),
{next_state, StateName, StateData};
+
+handle_info({timeout, Timer, _}, StateName,
+ #state{timer = Timer} = StateData) ->
+ {stop, normal, StateData};
+
handle_info(_, StateName, StateData) ->
{next_state, StateName, StateData}.
@@ -333,6 +342,15 @@ change_shaper(StateData, JID) ->
new_id() ->
randoms:get_string().
+cancel_timer(Timer) ->
+ erlang:cancel_timer(Timer),
+ receive
+ {timeout, Timer, _} ->
+ ok
+ after 0 ->
+ ok
+ end.
+
is_key_packet({xmlelement, Name, Attrs, Els}) when Name == "db:result" ->
{key,
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index da2c93c5..8e4394d6 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -32,7 +32,8 @@
-record(state, {socket, receiver, streamid,
myname, server, xmlpid, queue,
- new = false, verify = false}).
+ new = false, verify = false,
+ timer}).
%-define(DBGFSM, true).
@@ -91,12 +92,13 @@ init([From, Server, Type]) ->
{verify, Pid, Key, SID} ->
{false, {Pid, Key, SID}}
end,
+ Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
{ok, open_socket, #state{queue = queue:new(),
myname = From,
server = Server,
new = New,
- verify = Verify},
- ?S2STIMEOUT}.
+ verify = Verify,
+ timer = Timer}}.
%%----------------------------------------------------------------------
%% Func: StateName/2
@@ -123,8 +125,7 @@ open_socket(init, StateData) ->
{next_state, wait_for_stream,
StateData#state{socket = Socket,
xmlpid = XMLStreamPid,
- streamid = new_id()},
- ?S2STIMEOUT};
+ streamid = new_id()}};
{error, Reason} ->
?DEBUG("s2s_out: inet6 connect return ~p~n", [Reason]),
Error = ?ERR_REMOTE_SERVER_NOT_FOUND,
@@ -174,8 +175,7 @@ wait_for_stream({xmlstreamstart, Name, Attrs}, StateData) ->
{"id", SID}],
[{xmlcdata, Key2}]})
end,
- {next_state, wait_for_validation,
- StateData#state{new = New}, ?S2STIMEOUT};
+ {next_state, wait_for_validation, StateData#state{new = New}};
_ ->
send_text(StateData#state.socket, ?INVALID_NAMESPACE_ERR),
{stop, normal, StateData}
@@ -201,7 +201,7 @@ wait_for_validation({xmlstreamelement, El}, StateData) ->
case Type of
"valid" ->
send_queue(StateData#state.socket, StateData#state.queue),
- {next_state, stream_established, StateData, ?S2STIMEOUT};
+ {next_state, stream_established, StateData};
_ ->
% TODO: bounce packets
{stop, normal, StateData}
@@ -210,7 +210,7 @@ wait_for_validation({xmlstreamelement, El}, StateData) ->
?INFO_MSG("recv verify: ~p", [{From, To, Id, Type}]),
case StateData#state.verify of
false ->
- {next_state, wait_for_validation, StateData, ?S2STIMEOUT};
+ {next_state, wait_for_validation, StateData};
{Pid, _Key, _SID} ->
case Type of
"valid" ->
@@ -227,7 +227,7 @@ wait_for_validation({xmlstreamelement, El}, StateData) ->
{stop, normal, StateData}
end;
_ ->
- {next_state, wait_for_validation, StateData, ?S2STIMEOUT}
+ {next_state, wait_for_validation, StateData}
end;
wait_for_validation({xmlstreamend, Name}, StateData) ->
@@ -270,7 +270,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
_ ->
ok
end,
- {next_state, stream_established, StateData, ?S2STIMEOUT};
+ {next_state, stream_established, StateData};
stream_established({xmlstreamend, Name}, StateData) ->
{stop, normal, StateData};
@@ -334,24 +334,40 @@ code_change(OldVsn, StateName, StateData, Extra) ->
%%----------------------------------------------------------------------
handle_info({send_text, Text}, StateName, StateData) ->
send_text(StateData#state.socket, Text),
- {next_state, StateName, StateData};
+ cancel_timer(StateData#state.timer),
+ Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
+ {next_state, StateName, StateData#state{timer = Timer}};
+
handle_info({send_element, El}, StateName, StateData) ->
+ cancel_timer(StateData#state.timer),
+ Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
case StateName of
stream_established ->
send_element(StateData#state.socket, El),
- {next_state, StateName, StateData};
+ {next_state, StateName, StateData#state{timer = Timer}};
_ ->
Q = queue:in(El, StateData#state.queue),
- {next_state, StateName, StateData#state{queue = Q}}
+ {next_state, StateName, StateData#state{queue = Q,
+ timer = Timer}}
end;
+
handle_info({tcp, Socket, Data}, StateName, StateData) ->
xml_stream:send_text(StateData#state.xmlpid, Data),
{next_state, StateName, StateData};
+
handle_info({tcp_closed, Socket}, StateName, StateData) ->
gen_fsm:send_event(self(), closed),
{next_state, StateName, StateData};
+
handle_info({tcp_error, Socket, Reason}, StateName, StateData) ->
gen_fsm:send_event(self(), closed),
+ {next_state, StateName, StateData};
+
+handle_info({timeout, Timer, _}, StateName,
+ #state{timer = Timer} = StateData) ->
+ {stop, normal, StateData};
+
+handle_info(_, StateName, StateData) ->
{next_state, StateName, StateData}.
%%----------------------------------------------------------------------
@@ -361,6 +377,8 @@ handle_info({tcp_error, Socket, Reason}, StateName, StateData) ->
%%----------------------------------------------------------------------
terminate(Reason, StateName, StateData) ->
?INFO_MSG("terminated: ~p", [Reason]),
+ Error = ?ERR_REMOTE_SERVER_NOT_FOUND,
+ bounce_queue(StateData#state.queue, Error),
case StateData#state.new of
false ->
ok;
@@ -396,13 +414,34 @@ send_queue(Socket, Q) ->
ok
end.
+bounce_queue(Q, Error) ->
+ case queue:out(Q) of
+ {{value, El}, Q1} ->
+ Err = jlib:make_error_reply(El, Error),
+ From = jlib:string_to_jid(xml:get_tag_attr_s("from", El)),
+ To = jlib:string_to_jid(xml:get_tag_attr_s("to", El)),
+ ejabberd_router:route(To, From, Err),
+ bounce_queue(Q1, Error);
+ {empty, Q1} ->
+ ok
+ end.
+
new_id() ->
randoms:get_string().
+cancel_timer(Timer) ->
+ erlang:cancel_timer(Timer),
+ receive
+ {timeout, Timer, _} ->
+ ok
+ after 0 ->
+ ok
+ end.
+
bounce_messages(Error) ->
receive
{send_element, El} ->
- {xmlelement, Name, Attrs, SubTags} = El,
+ {xmlelement, _Name, Attrs, _SubTags} = El,
case xml:get_attr_s("type", Attrs) of
"error" ->
ok;
@@ -410,7 +449,7 @@ bounce_messages(Error) ->
Err = jlib:make_error_reply(El, Error),
From = jlib:string_to_jid(xml:get_attr_s("from", Attrs)),
To = jlib:string_to_jid(xml:get_attr_s("to", Attrs)),
- ejabberd_router ! {route, To, From, Err}
+ ejabberd_router:route(To, From, Err)
end,
bounce_messages(Error)
after 0 ->
diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl
index ce1328ca..7f1c5360 100644
--- a/src/mod_muc/mod_muc.erl
+++ b/src/mod_muc/mod_muc.erl
@@ -298,28 +298,30 @@ iq_disco_items(Host, From) ->
iq_get_register_info(From, Lang) ->
{LUser, LServer, _} = jlib:jid_tolower(From),
LUS = {LUser, LServer},
- Nick = case catch mnesia:dirty_read(muc_registered, LUS) of
+ {Nick, Registered} = case catch mnesia:dirty_read(muc_registered, LUS) of
{'EXIT', Reason} ->
- "";
+ {"", []};
[] ->
- "";
+ {"", []};
[#muc_registered{nick = N}] ->
- N
+ {N, [{xmlelement, "registered", [], []}]}
end,
- [{xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(
- Lang, "You need a x:data capable client to register.")}]},
- {xmlelement, "x",
- [{"xmlns", ?NS_XDATA}],
- [{xmlelement, "title", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Nick Registration")}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- translate:translate(
- Lang, "Enter nick you want to register.")}]},
- ?XFIELD("text-single", "Nick", "nick", Nick)]}].
+ Registered ++
+ [{xmlelement, "instructions", [],
+ [{xmlcdata,
+ translate:translate(
+ Lang, "You need a x:data capable client to register.")}]},
+ {xmlelement, "x",
+ [{"xmlns", ?NS_XDATA}],
+ [{xmlelement, "title", [],
+ [{xmlcdata,
+ translate:translate(
+ Lang, "Nickname Registration")}]},
+ {xmlelement, "instructions", [],
+ [{xmlcdata,
+ translate:translate(
+ Lang, "Enter nickname you want to register.")}]},
+ ?XFIELD("text-single", "Nickname", "nick", Nick)]}].
iq_set_register_info(From, XData) ->
{LUser, LServer, _} = jlib:jid_tolower(From),
@@ -358,7 +360,7 @@ iq_set_register_info(From, XData) ->
{atomic, ok} ->
{result, []};
{atomic, false} ->
- {error, ?ERR_NOT_ALLOWED};
+ {error, ?ERR_CONFLICT};
_ ->
{error, ?ERR_INTERNAL_SERVER_ERROR}
end
@@ -394,8 +396,8 @@ iq_get_vcard(Lang) ->
[{xmlcdata,
"http://ejabberd.jabberstudio.org/"}]},
{xmlelement, "DESC", [],
- [{xmlcdata, "ejabberd MUC module\n"
- "Copyright (c) 2003 Alexey Shchepin"}]}].
+ [{xmlcdata, translate:translate(Lang, "ejabberd MUC module\n"
+ "Copyright (c) 2003 Alexey Shchepin")}]}].
broadcast_service_message(Msg) ->
diff --git a/src/mod_register.erl b/src/mod_register.erl
index 52ebcb00..f900a9ef 100644
--- a/src/mod_register.erl
+++ b/src/mod_register.erl
@@ -99,13 +99,15 @@ process_iq(From, _To, {iq, ID, Type, XMLNS, SubEl}) ->
[SubEl, ?ERR_BAD_REQUEST]}
end;
get ->
+ Lang = xml:get_tag_attr_s("xml:lang", SubEl),
{iq, ID, result, XMLNS, [{xmlelement,
"query",
[{"xmlns", "jabber:iq:register"}],
[{xmlelement, "instructions", [],
[{xmlcdata,
- "Choose a username and password "
- "to register with this server."}]},
+ translate:translate(Lang,
+ "Choose a username and password "
+ "to register with this server.")}]},
{xmlelement, "username", [], []},
{xmlelement, "password", [], []}]}]}
end.
diff --git a/src/msgs/ru.msg b/src/msgs/ru.msg
index c9bb60c4..782b6acd 100644
--- a/src/msgs/ru.msg
+++ b/src/msgs/ru.msg
@@ -38,8 +38,9 @@
{"Start Modules", "Запуск модулей"}.
{"Stop Modules", "Остановка модулей"}.
-
-
+% mod_register.erl
+{"Choose a username and password to register with this server.",
+ "Выберите идентификатор пользователя и пароль для регистрации на этом сервере."}.
% mod_vcard.erl
{"You need a x:data capable client to search",
@@ -62,9 +63,13 @@
{"Organization Name", "Название организации"}.
{"Organization Unit", "Отдел организации"}.
+% mod_muc/mod_muc.erl
+{"Nickname Registration", "Регистрация псевдонима"}.
+{"Enter nickname you want to register.", "Введите псевдоним, который вы хотели бы зарегистрировать"}.
+{"ejabberd MUC module\nCopyright (c) 2003 Alexey Shchepin",
+ "ejabberd MUC модуль\nCopyright (c) 2003 Алексей Щепин"}.
% mod_muc/mod_muc_room.erl
-
{"Room title", "Название комнаты"}.
{"Allow users to change subject?", "Разрешить пользователям изменять тему?"}.
{"Allow users to query other users?",