From 58bfea2ad11a75615cfc47d217e3e650bc42a190 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Thu, 19 Jun 2008 10:23:52 +0000
Subject: [PATCH 002/582] Replace the use of xml_stream by exmpp_xmlstream.
exmpp_xml is configured to produce old #xmlelement records. exmpp_xmlstream
is configured to send old xmlstreamstart tuple.
Users are able to connect to ejabberd.
Next step: ejabberd_c2s.
SVN Revision: 1365
---
ChangeLog | 12 ++++++++++++
src/ejabberd_receiver.erl | 37 +++++++++++++++++++------------------
2 files changed, 31 insertions(+), 18 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e0bb52ad1..727c47ec3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-06-19 Jean-Sébastien Pédron
+
+ * src/ejabberd_receiver.erl: Replace the use of xml_stream by
+ exmpp_xmlstream. exmpp_xml is configured to produce old #xmlelement
+ records. exmpp_xmlstream is configured to send old xmlstreamstart
+ tuple. Users are able to connect to ejabberd. Next step:
+ ejabberd_c2s.
+
+2008-06-19 Jean-Sébastien Pédron
+
+ Start the transition to exmpp.
+
2008-06-18 Badlop
* src/ejabberd.app: The ejabberd version number is defined in the
diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl
index 72b3608d6..208ec6a39 100644
--- a/src/ejabberd_receiver.erl
+++ b/src/ejabberd_receiver.erl
@@ -131,11 +131,8 @@ init([Socket, SockMod, Shaper, MaxStanzaSize]) ->
%% Description: Handling call messages
%%--------------------------------------------------------------------
handle_call({starttls, TLSSocket}, _From,
- #state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid,
- max_stanza_size = MaxStanzaSize} = State) ->
- close_stream(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
+ #state{xml_stream_state = XMLStreamState} = State) ->
+ NewXMLStreamState = exmpp_xmlstream:reset(XMLStreamState),
NewState = State#state{socket = TLSSocket,
sock_mod = tls,
xml_stream_state = NewXMLStreamState},
@@ -146,11 +143,8 @@ handle_call({starttls, TLSSocket}, _From,
{stop, normal, ok, NewState}
end;
handle_call({compress, ZlibSocket}, _From,
- #state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid,
- max_stanza_size = MaxStanzaSize} = State) ->
- close_stream(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
+ #state{xml_stream_state = XMLStreamState} = State) ->
+ NewXMLStreamState = exmpp_xmlstream:reset(XMLStreamState),
NewState = State#state{socket = ZlibSocket,
sock_mod = ejabberd_zlib,
xml_stream_state = NewXMLStreamState},
@@ -161,15 +155,21 @@ handle_call({compress, ZlibSocket}, _From,
{stop, normal, ok, NewState}
end;
handle_call(reset_stream, _From,
- #state{xml_stream_state = XMLStreamState,
- c2s_pid = C2SPid,
- max_stanza_size = MaxStanzaSize} = State) ->
- close_stream(XMLStreamState),
- NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize),
+ #state{xml_stream_state = XMLStreamState} = State) ->
+ NewXMLStreamState = exmpp_xmlstream:reset(XMLStreamState),
Reply = ok,
{reply, Reply, State#state{xml_stream_state = NewXMLStreamState}};
handle_call({become_controller, C2SPid}, _From, State) ->
- XMLStreamState = xml_stream:new(C2SPid, State#state.max_stanza_size),
+ % XXX OLD FORMAT
+ Parser = exmpp_xml:start_parser([
+ {namespace, false},
+ {name_as_atom, false},
+ {maxsize, State#state.max_stanza_size}
+ ]),
+ XMLStreamState = exmpp_xmlstream:start(
+ {gen_fsm, C2SPid}, Parser,
+ [{xmlstreamstart, old}]
+ ),
NewState = State#state{c2s_pid = C2SPid,
xml_stream_state = XMLStreamState},
activate_socket(NewState),
@@ -291,7 +291,7 @@ process_data(Data,
shaper_state = ShaperState,
c2s_pid = C2SPid} = State) ->
?DEBUG("Received XML on stream = ~p", [binary_to_list(Data)]),
- XMLStreamState1 = xml_stream:parse(XMLStreamState, Data),
+ {ok, XMLStreamState1} = exmpp_xmlstream:parse(XMLStreamState, Data),
{NewShaperState, Pause} = shaper:update(ShaperState, size(Data)),
if
C2SPid == undefined ->
@@ -307,4 +307,5 @@ process_data(Data,
close_stream(undefined) ->
ok;
close_stream(XMLStreamState) ->
- xml_stream:close(XMLStreamState).
+ exmpp_xml:stop_parser(exmpp_xmlstream:get_parser(XMLStreamState)),
+ exmpp_xmlstream:stop(XMLStreamState).
From e4646a6788951d3e5d5598668089c65ff6c5f466 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 20 Jun 2008 12:49:39 +0000
Subject: [PATCH 003/582] Add exmpp detection.
SVN Revision: 1366
---
ChangeLog | 4 ++++
src/Makefile.in | 2 +-
src/aclocal.m4 | 11 ++++++++++-
src/configure | 15 +++++++++++++--
4 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 727c47ec3..6386fdbf0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-06-20 Jean-Sébastien Pédron
+
+ * src/configure, src/aclocal.m4, src/Makefile.in: Add exmpp detection.
+
2008-06-19 Jean-Sébastien Pédron
* src/ejabberd_receiver.erl: Replace the use of xml_stream by
diff --git a/src/Makefile.in b/src/Makefile.in
index 57bb56333..7391a8d9a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -12,7 +12,7 @@ ERLANG_CFLAGS= @ERLANG_CFLAGS@
EXPAT_LIBS = @EXPAT_LIBS@
ERLANG_LIBS = @ERLANG_LIBS@
-ERLC_FLAGS += @ERLANG_SSL39@
+ERLC_FLAGS += @ERLANG_SSL39@ -I@ERLANG_EXMPP@/include
ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj
# make debug=true to compile Erlang module with debug informations.
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 46020d339..65509eefc 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -123,8 +123,14 @@ AC_DEFUN(AM_WITH_ERLANG,
start() ->
EIDirS = code:lib_dir("erl_interface") ++ "\n",
EILibS = libpath("erl_interface") ++ "\n",
+ EXMPPDir = code:lib_dir("exmpp"),
+ case EXMPPDir of
+ {error, bad_name} -> exit("exmpp not found");
+ _ -> ok
+ end,
+ EXMPPDirS = EXMPPDir ++ "\n",
RootDirS = code:root_dir() ++ "\n",
- file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ RootDirS)),
+ file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ EXMPPDirS ++ RootDirS)),
halt().
-[ifdef]('id-pkix').
@@ -182,6 +188,8 @@ _EOF
ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
# Third line
ERLANG_SSL39=`cat conftest.out | head -n 3 | tail -n 1`
+ # Fourth line
+ ERLANG_EXMPP=`cat conftest.out | head -n 4 | tail -n 1`
# End line
ERLANG_DIR=`cat conftest.out | tail -n 1`
@@ -191,6 +199,7 @@ _EOF
AC_SUBST(ERLANG_CFLAGS)
AC_SUBST(ERLANG_LIBS)
AC_SUBST(ERLANG_SSL39)
+ AC_SUBST(ERLANG_EXMPP)
AC_SUBST(ERLC)
AC_SUBST(ERL)
])
diff --git a/src/configure b/src/configure
index b874f6cab..573a17ee7 100755
--- a/src/configure
+++ b/src/configure
@@ -664,6 +664,7 @@ ERL
ERLANG_CFLAGS
ERLANG_LIBS
ERLANG_SSL39
+ERLANG_EXMPP
LIBICONV
CPP
GREP
@@ -2930,8 +2931,14 @@ echo "$as_me: error: erlang not found" >&2;}
start() ->
EIDirS = code:lib_dir("erl_interface") ++ "\n",
EILibS = libpath("erl_interface") ++ "\n",
+ EXMPPDir = code:lib_dir("exmpp"),
+ case EXMPPDir of
+ {error, bad_name} -> exit("exmpp not found");
+ _ -> ok
+ end,
+ EXMPPDirS = EXMPPDir ++ "\n",
RootDirS = code:root_dir() ++ "\n",
- file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ RootDirS)),
+ file:write_file("conftest.out", list_to_binary(EIDirS ++ EILibS ++ ssldef() ++ EXMPPDirS ++ RootDirS)),
halt().
-ifdef('id-pkix').
@@ -2995,6 +3002,8 @@ echo "$as_me: error: erlang program was not properly executed, (conftest.out was
ERLANG_EI_LIB=`cat conftest.out | head -n 2 | tail -n 1`
# Third line
ERLANG_SSL39=`cat conftest.out | head -n 3 | tail -n 1`
+ # Fourth line
+ ERLANG_EXMPP=`cat conftest.out | head -n 4 | tail -n 1`
# End line
ERLANG_DIR=`cat conftest.out | tail -n 1`
@@ -3007,6 +3016,7 @@ echo "$as_me: error: erlang program was not properly executed, (conftest.out was
+
#locating iconv
@@ -6542,6 +6552,7 @@ ERL!$ERL$ac_delim
ERLANG_CFLAGS!$ERLANG_CFLAGS$ac_delim
ERLANG_LIBS!$ERLANG_LIBS$ac_delim
ERLANG_SSL39!$ERLANG_SSL39$ac_delim
+ERLANG_EXMPP!$ERLANG_EXMPP$ac_delim
LIBICONV!$LIBICONV$ac_delim
CPP!$CPP$ac_delim
GREP!$GREP$ac_delim
@@ -6583,7 +6594,7 @@ SSL_CFLAGS!$SSL_CFLAGS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 89; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
From a19f280fcc8d7662b01af6cd2a973155e2f1ee45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 20 Jun 2008 12:50:20 +0000
Subject: [PATCH 004/582] Enable the new #xmlel record.
SVN Revision: 1367
---
ChangeLog | 2 ++
src/ejabberd_receiver.erl | 7 +++----
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 6386fdbf0..7af378f4c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,8 @@
* src/configure, src/aclocal.m4, src/Makefile.in: Add exmpp detection.
+ * src/ejabberd_receiver.erl: Enable the new #xmlel record.
+
2008-06-19 Jean-Sébastien Pédron
* src/ejabberd_receiver.erl: Replace the use of xml_stream by
diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl
index 208ec6a39..5fdad76af 100644
--- a/src/ejabberd_receiver.erl
+++ b/src/ejabberd_receiver.erl
@@ -160,15 +160,14 @@ handle_call(reset_stream, _From,
Reply = ok,
{reply, Reply, State#state{xml_stream_state = NewXMLStreamState}};
handle_call({become_controller, C2SPid}, _From, State) ->
- % XXX OLD FORMAT
Parser = exmpp_xml:start_parser([
- {namespace, false},
- {name_as_atom, false},
+ {namespace, true},
+ {name_as_atom, true},
{maxsize, State#state.max_stanza_size}
]),
XMLStreamState = exmpp_xmlstream:start(
{gen_fsm, C2SPid}, Parser,
- [{xmlstreamstart, old}]
+ [{xmlstreamstart, new}]
),
NewState = State#state{c2s_pid = C2SPid,
xml_stream_state = XMLStreamState},
From 389b5e64480eedbb7d6771a3c3045d1847fb0f33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 20 Jun 2008 12:52:29 +0000
Subject: [PATCH 005/582] First bunch of modifications to use exmpp. All FSM
state function are updated. But other functions are not for now.
Users are able to connect to ejabberd but some features may not work.
SVN Revision: 1368
---
ChangeLog | 4 +
src/ejabberd_c2s.erl | 865 ++++++++++++++++++++++---------------------
2 files changed, 440 insertions(+), 429 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 7af378f4c..3447a057b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,10 @@
* src/ejabberd_receiver.erl: Enable the new #xmlel record.
+ * src/ejabberd_c2s.erl: First bunch of modifications to use exmpp. All
+ FSM state function are updated. But other functions are not for now.
+ Users are able to connect to ejabberd but some features may not work.
+
2008-06-19 Jean-Sébastien Pédron
* src/ejabberd_receiver.erl: Replace the use of xml_stream by
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 358b1fe32..400b725fe 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -54,8 +54,9 @@
handle_info/3,
terminate/3]).
+-include("exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("mod_privacy.hrl").
-define(SETS, gb_sets).
@@ -93,11 +94,11 @@
%-define(DBGFSM, true).
--ifdef(DBGFSM).
+%-ifdef(DBGFSM).
-define(FSMOPTS, [{debug, [trace]}]).
--else.
--define(FSMOPTS, []).
--endif.
+%-else.
+%-define(FSMOPTS, []).
+%-endif.
%% Module start with or without supervisor:
-ifdef(NO_TRANSIENT_SUPERVISORS).
@@ -113,6 +114,11 @@
-define(C2S_OPEN_TIMEOUT, 60000).
-define(C2S_HIBERNATE_TIMEOUT, 90000).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, ['jabber:client']).
+-define(PREFIXED_NS, [{?NS_XMPP, "stream"}]).
+
-define(STREAM_HEADER,
""
"
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
-wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
+wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
DefaultLang = case ?MYLANG of
undefined ->
" xml:lang='en'";
DL ->
" xml:lang='" ++ DL ++ "'"
end,
- case xml:get_attr_s("xmlns:stream", Attrs) of
- ?NS_STREAM ->
- Server = jlib:nameprep(xml:get_attr_s("to", Attrs)),
+ Header = exmpp_stream:opening_reply(Opening,
+ StateData#state.streamid),
+ Header1 = exmpp_stream:set_lang(Header, DefaultLang),
+ case NS of
+ ?NS_XMPP ->
+ Server = exmpp_stringprep:nameprep(
+ exmpp_stream:get_receiving_entity(Opening)),
case lists:member(Server, ?MYHOSTS) of
true ->
- Lang = xml:get_attr_s("xml:lang", Attrs),
- change_shaper(StateData, jlib:make_jid("", Server, "")),
- case xml:get_attr_s("version", Attrs) of
- "1.0" ->
- Header = io_lib:format(?STREAM_HEADER,
- [StateData#state.streamid,
- Server,
- " version='1.0'",
- DefaultLang]),
- send_text(StateData, Header),
+ Lang = exmpp_stream:get_lang(Opening),
+ change_shaper(StateData,
+ exmpp_jid:make_jid("", Server, "")),
+ case exmpp_stream:get_version(Opening) of
+ {1, 0} ->
+ send_element(StateData, Header1),
case StateData#state.authenticated of
false ->
SASLState =
@@ -255,11 +305,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
ejabberd_auth:check_password_with_authmodule(
U, Server, P)
end),
- Mechs = lists:map(
- fun(S) ->
- {xmlelement, "mechanism", [],
- [{xmlcdata, S}]}
- end, cyrsasl:listmech(Server)),
+ SASL_Mechs = [exmpp_server_sasl:feature(
+ cyrsasl:listmech(Server))],
SockMod =
(StateData#state.sockmod):get_sockmod(
StateData#state.socket),
@@ -268,10 +315,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
case Zlib andalso
(SockMod == gen_tcp) of
true ->
- [{xmlelement, "compression",
- [{"xmlns", ?NS_FEATURE_COMPRESS}],
- [{xmlelement, "method",
- [], [{xmlcdata, "zlib"}]}]}];
+ [exmpp_server_compression:feature(["zlib"])];
_ ->
[]
end,
@@ -283,29 +327,19 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
(TLSEnabled == false) andalso
(SockMod == gen_tcp) of
true ->
- case TLSRequired of
- true ->
- [{xmlelement, "starttls",
- [{"xmlns", ?NS_TLS}],
- [{xmlelement, "required",
- [], []}]}];
- _ ->
- [{xmlelement, "starttls",
- [{"xmlns", ?NS_TLS}], []}]
- end;
+ [exmpp_server_tls:feature(TLSRequired)];
false ->
[]
end,
send_element(StateData,
- {xmlelement, "stream:features", [],
- TLSFeature ++ CompressFeature ++
- [{xmlelement, "mechanisms",
- [{"xmlns", ?NS_SASL}],
- Mechs}] ++
- ejabberd_hooks:run_fold(
- c2s_stream_features,
- Server,
- [], [])}),
+ exmpp_stream:features(
+ TLSFeature ++
+ CompressFeature ++
+ SASL_Mechs ++
+ ejabberd_hooks:run_fold(
+ c2s_stream_features,
+ Server,
+ [], []))),
fsm_next_state(wait_for_feature_request,
StateData#state{
server = Server,
@@ -316,11 +350,10 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
"" ->
send_element(
StateData,
- {xmlelement, "stream:features", [],
- [{xmlelement, "bind",
- [{"xmlns", ?NS_BIND}], []},
- {xmlelement, "session",
- [{"xmlns", ?NS_SESSION}], []}]}),
+ exmpp_stream:features([
+ exmpp_server_binding:feature(),
+ exmpp_server_session:feature()
+ ])),
fsm_next_state(wait_for_bind,
StateData#state{
server = Server,
@@ -328,7 +361,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
_ ->
send_element(
StateData,
- {xmlelement, "stream:features", [], []}),
+ exmpp_stream:features([])),
fsm_next_state(wait_for_session,
StateData#state{
server = Server,
@@ -336,22 +369,16 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
end
end;
_ ->
- Header = io_lib:format(
- ?STREAM_HEADER,
- [StateData#state.streamid, Server, "",
- DefaultLang]),
if
(not StateData#state.tls_enabled) and
StateData#state.tls_required ->
- send_text(StateData,
- Header ++
- ?POLICY_VIOLATION_ERR(
- Lang,
- "Use of STARTTLS required") ++
- ?STREAM_TRAILER),
+ send_element(StateData,
+ exmpp_xml:append_child(Header1,
+ exmpp_stream:error('policy-violation',
+ Lang, "Use of STARTTLS required"))),
{stop, normal, StateData};
true ->
- send_text(StateData, Header),
+ send_element(StateData, Header1),
fsm_next_state(wait_for_auth,
StateData#state{
server = Server,
@@ -359,20 +386,16 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
end
end;
_ ->
- Header = io_lib:format(
- ?STREAM_HEADER,
- [StateData#state.streamid, ?MYNAME, "",
- DefaultLang]),
- send_text(StateData,
- Header ++ ?HOST_UNKNOWN_ERR ++ ?STREAM_TRAILER),
+ Header2 = exmpp_stream:set_initiating_entity(Header1,
+ ?MYNAME),
+ send_element(StateData, exmpp_xml:append_child(Header2,
+ exmpp_stream:error('host-unknown'))),
{stop, normal, StateData}
end;
_ ->
- Header = io_lib:format(
- ?STREAM_HEADER,
- [StateData#state.streamid, ?MYNAME, "", DefaultLang]),
- send_text(StateData,
- Header ++ ?INVALID_NS_ERR ++ ?STREAM_TRAILER),
+ Header2 = exmpp_stream:set_initiating_entity(Header1, ?MYNAME),
+ send_element(StateData, exmpp_xml:append_child(Header2,
+ exmpp_stream:error('invalid-namespace'))),
{stop, normal, StateData}
end;
@@ -380,18 +403,21 @@ wait_for_stream(timeout, StateData) ->
{stop, normal, StateData};
wait_for_stream({xmlstreamelement, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_stream({xmlstreamend, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_stream({xmlstreamerror, _}, StateData) ->
- Header = io_lib:format(?STREAM_HEADER,
- ["none", ?MYNAME, " version='1.0'", ""]),
- send_text(StateData,
- Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ Header = exmpp_stream:opening_reply(?MYNAME, 'jabber:client', "1.0",
+ "none"),
+ Header1 = exmpp_xml:append_child(Header,
+ exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, Header1),
{stop, normal, StateData};
wait_for_stream(closed, StateData) ->
@@ -400,118 +426,96 @@ wait_for_stream(closed, StateData) ->
wait_for_auth({xmlstreamelement, El}, StateData) ->
case is_auth_packet(El) of
- {auth, _ID, get, {U, _, _, _}} ->
- {xmlelement, Name, Attrs, _Els} = jlib:make_result_iq_reply(El),
- case U of
- "" ->
- UCdata = [];
- _ ->
- UCdata = [{xmlcdata, U}]
+ {auth, _ID, get, {_U, _, _, _}} ->
+ Fields = case ejabberd_auth:plain_password_required(
+ StateData#state.server) of
+ false -> both;
+ true -> plain
end,
- Res = case ejabberd_auth:plain_password_required(
- StateData#state.server) of
- false ->
- {xmlelement, Name, Attrs,
- [{xmlelement, "query", [{"xmlns", ?NS_AUTH}],
- [{xmlelement, "username", [], UCdata},
- {xmlelement, "password", [], []},
- {xmlelement, "digest", [], []},
- {xmlelement, "resource", [], []}
- ]}]};
- true ->
- {xmlelement, Name, Attrs,
- [{xmlelement, "query", [{"xmlns", ?NS_AUTH}],
- [{xmlelement, "username", [], UCdata},
- {xmlelement, "password", [], []},
- {xmlelement, "resource", [], []}
- ]}]}
- end,
- send_element(StateData, Res),
+ send_element(StateData,
+ exmpp_server_legacy_auth:fields(El, Fields)),
fsm_next_state(wait_for_auth, StateData);
{auth, _ID, set, {_U, _P, _D, ""}} ->
- Err = jlib:make_error_reply(
- El,
- ?ERR_AUTH_NO_RESOURCE_PROVIDED(StateData#state.lang)),
- send_element(StateData, Err),
+ Err = exmpp_stanza:error('not-acceptable',
+ {StateData#state.lang, "No resource provided"}),
+ send_element(StateData, exmpp_iq:error(El, Err)),
fsm_next_state(wait_for_auth, StateData);
{auth, _ID, set, {U, P, D, R}} ->
- JID = jlib:make_jid(U, StateData#state.server, R),
- case (JID /= error) andalso
- (acl:match_rule(StateData#state.server,
- StateData#state.access, JID) == allow) of
- true ->
- case ejabberd_auth:check_password_with_authmodule(
- U, StateData#state.server, P,
- StateData#state.streamid, D) of
- {true, AuthModule} ->
- ?INFO_MSG(
- "(~w) Accepted legacy authentication for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- SID = {now(), self()},
- Conn = get_conn_type(StateData),
- Info = [{ip, StateData#state.ip}, {conn, Conn},
- {auth_module, AuthModule}],
- ejabberd_sm:open_session(
- SID, U, StateData#state.server, R, Info),
- Res1 = jlib:make_result_iq_reply(El),
- Res = setelement(4, Res1, []),
- send_element(StateData, Res),
- change_shaper(StateData, JID),
- {Fs, Ts} = ejabberd_hooks:run_fold(
- roster_get_subscription_lists,
- StateData#state.server,
- {[], []},
- [U, StateData#state.server]),
- LJID = jlib:jid_tolower(
- jlib:jid_remove_resource(JID)),
- Fs1 = [LJID | Fs],
- Ts1 = [LJID | Ts],
- PrivList =
- ejabberd_hooks:run_fold(
+ try
+ JID = exmpp_jid:make_jid(U, StateData#state.server, R),
+ case acl:match_rule(StateData#state.server,
+ StateData#state.access, JID) of
+ allow ->
+ case ejabberd_auth:check_password_with_authmodule(
+ U, StateData#state.server, P,
+ StateData#state.streamid, D) of
+ {true, AuthModule} ->
+ ?INFO_MSG(
+ "(~w) Accepted legacy authentication for ~s",
+ [StateData#state.socket,
+ exmpp_jid:jid_to_string(JID)]),
+ SID = {now(), self()},
+ Conn = get_conn_type(StateData),
+ Info = [{ip, StateData#state.ip}, {conn, Conn},
+ {auth_module, AuthModule}],
+ ejabberd_sm:open_session(
+ SID, U, StateData#state.server, R, Info),
+ Res = exmpp_server_legacy_auth:success(El),
+ send_element(StateData, Res),
+ change_shaper(StateData, JID),
+ {Fs, Ts} = ejabberd_hooks:run_fold(
+ roster_get_subscription_lists,
+ StateData#state.server,
+ {[], []},
+ [U, StateData#state.server]),
+ LJID = {JID#jid.lnode, JID#jid.ldomain, ""},
+ Fs1 = [LJID | Fs],
+ Ts1 = [LJID | Ts],
+ PrivList = ejabberd_hooks:run_fold(
privacy_get_user_list, StateData#state.server,
#userlist{},
[U, StateData#state.server]),
- fsm_next_state(session_established,
- StateData#state{
- user = U,
- resource = R,
- jid = JID,
- sid = SID,
- conn = Conn,
- auth_module = AuthModule,
- pres_f = ?SETS:from_list(Fs1),
- pres_t = ?SETS:from_list(Ts1),
- privacy_list = PrivList});
- _ ->
- ?INFO_MSG(
- "(~w) Failed legacy authentication for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- Err = jlib:make_error_reply(
- El, ?ERR_NOT_AUTHORIZED),
- send_element(StateData, Err),
- fsm_next_state(wait_for_auth, StateData)
- end;
- _ ->
- if
- JID == error ->
- ?INFO_MSG(
- "(~w) Forbidden legacy authentication for "
- "username '~s' with resource '~s'",
- [StateData#state.socket, U, R]),
- Err = jlib:make_error_reply(El, ?ERR_JID_MALFORMED),
- send_element(StateData, Err),
- fsm_next_state(wait_for_auth, StateData);
- true ->
- ?INFO_MSG(
- "(~w) Forbidden legacy authentication for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
- send_element(StateData, Err),
- fsm_next_state(wait_for_auth, StateData)
- end
+ fsm_next_state(session_established,
+ StateData#state{
+ user = U,
+ resource = R,
+ jid = JID,
+ sid = SID,
+ conn = Conn,
+ auth_module = AuthModule,
+ pres_f = ?SETS:from_list(Fs1),
+ pres_t = ?SETS:from_list(Ts1),
+ privacy_list = PrivList});
+ _ ->
+ ?INFO_MSG(
+ "(~w) Failed legacy authentication for ~s",
+ [StateData#state.socket,
+ exmpp_jid:jid_to_string(JID)]),
+ Err = exmpp_stanza:error('not-authorized'),
+ Res = exmpp_iq:error_without_original(El, Err),
+ send_element(StateData, Res),
+ fsm_next_state(wait_for_auth, StateData)
+ end;
+ _ ->
+ ?INFO_MSG(
+ "(~w) Forbidden legacy authentication for ~s",
+ [StateData#state.socket,
+ exmpp_jid:jid_to_string(JID)]),
+ Err = exmpp_stanza:error('not-allowed'),
+ Res = exmpp_iq:error_without_original(El, Err),
+ send_element(StateData, Res),
+ fsm_next_state(wait_for_auth, StateData)
+ end
+ catch
+ throw:_Exception ->
+ ?INFO_MSG(
+ "(~w) Forbidden legacy authentication for "
+ "username '~s' with resource '~s'",
+ [StateData#state.socket, U, R]),
+ Err1 = exmpp_stanza:error('jid-malformed'),
+ Res1 = exmpp_iq:error_without_original(El, Err1),
+ send_element(StateData, Res1),
+ fsm_next_state(wait_for_auth, StateData)
end;
_ ->
process_unauthenticated_stanza(StateData, El),
@@ -522,38 +526,36 @@ wait_for_auth(timeout, StateData) ->
{stop, normal, StateData};
wait_for_auth({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_auth({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_auth(closed, StateData) ->
{stop, normal, StateData}.
-wait_for_feature_request({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, Attrs, Els} = El,
+wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
+ StateData) ->
Zlib = StateData#state.zlib,
TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled,
TLSRequired = StateData#state.tls_required,
SockMod = (StateData#state.sockmod):get_sockmod(StateData#state.socket),
- case {xml:get_attr_s("xmlns", Attrs), Name} of
- {?NS_SASL, "auth"} when not ((SockMod == gen_tcp) and TLSRequired) ->
- Mech = xml:get_attr_s("mechanism", Attrs),
- ClientIn = jlib:decode_base64(xml:get_cdata(Els)),
+ case {NS, Name} of
+ {?NS_SASL, 'auth'} when not ((SockMod == gen_tcp) and TLSRequired) ->
+ {auth, Mech, ClientIn} = exmpp_server_sasl:next_step(El),
case cyrsasl:server_start(StateData#state.sasl_state,
Mech,
ClientIn) of
{ok, Props} ->
(StateData#state.sockmod):reset_stream(
StateData#state.socket),
- send_element(StateData,
- {xmlelement, "success",
- [{"xmlns", ?NS_SASL}], []}),
- U = xml:get_attr_s(username, Props),
+ send_element(StateData, exmpp_server_sasl:success()),
+ U = proplists:get_value(username, Props),
?INFO_MSG("(~w) Accepted authentication for ~s",
[StateData#state.socket, U]),
fsm_next_state(wait_for_stream,
@@ -563,10 +565,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
user = U });
{continue, ServerOut, NewSASLState} ->
send_element(StateData,
- {xmlelement, "challenge",
- [{"xmlns", ?NS_SASL}],
- [{xmlcdata,
- jlib:encode_base64(ServerOut)}]}),
+ exmpp_server_sasl:challenge(ServerOut)),
fsm_next_state(wait_for_sasl_response,
StateData#state{
sasl_state = NewSASLState});
@@ -575,20 +574,18 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
"(~w) Failed authentication for ~s@~s",
[StateData#state.socket,
Username, StateData#state.server]),
+ % XXX OLD FORMAT: list_to_atom(Error).
send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, Error, [], []}]}),
+ exmpp_server_sasl:failure(list_to_atom(Error))),
{next_state, wait_for_feature_request, StateData,
?C2S_OPEN_TIMEOUT};
{error, Error} ->
+ % XXX OLD FORMAT: list_to_atom(Error).
send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, Error, [], []}]}),
+ exmpp_server_sasl:failure(list_to_atom(Error))),
fsm_next_state(wait_for_feature_request, StateData)
end;
- {?NS_TLS, "starttls"} when TLS == true,
+ {?NS_TLS, 'starttls'} when TLS == true,
TLSEnabled == false,
SockMod == gen_tcp ->
TLSOpts = case ejabberd_config:get_local_option(
@@ -601,55 +598,45 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
certfile, 1, StateData#state.tls_options)]
end,
Socket = StateData#state.socket,
+ Proceed = exmpp_xml:document_fragment_to_list(
+ exmpp_server_tls:proceed(), ?DEFAULT_NS, ?PREFIXED_NS),
TLSSocket = (StateData#state.sockmod):starttls(
Socket, TLSOpts,
- xml:element_to_string(
- {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []})),
+ Proceed),
fsm_next_state(wait_for_stream,
StateData#state{socket = TLSSocket,
streamid = new_id(),
tls_enabled = true
});
- {?NS_COMPRESS, "compress"} when Zlib == true,
+ {?NS_COMPRESS, 'compress'} when Zlib == true,
SockMod == gen_tcp ->
- case xml:get_subtag(El, "method") of
- false ->
+ case exmpp_server_compression:selected_method(El) of
+ undefined ->
send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_COMPRESS}],
- [{xmlelement, "setup-failed", [], []}]}),
+ exmpp_server_compression:failure('steup-failed')),
fsm_next_state(wait_for_feature_request, StateData);
- Method ->
- case xml:get_tag_cdata(Method) of
- "zlib" ->
- Socket = StateData#state.socket,
- ZlibSocket = (StateData#state.sockmod):compress(
- Socket,
- xml:element_to_string(
- {xmlelement, "compressed",
- [{"xmlns", ?NS_COMPRESS}], []})),
- fsm_next_state(wait_for_stream,
- StateData#state{socket = ZlibSocket,
- streamid = new_id()
- });
- _ ->
- send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_COMPRESS}],
- [{xmlelement, "unsupported-method",
- [], []}]}),
- fsm_next_state(wait_for_feature_request,
- StateData)
- end
+ "zlib" ->
+ Socket = StateData#state.socket,
+ ZlibSocket = (StateData#state.sockmod):compress(
+ Socket,
+ exmpp_server_compression:compressed()),
+ fsm_next_state(wait_for_stream,
+ StateData#state{socket = ZlibSocket,
+ streamid = new_id()
+ });
+ _ ->
+ send_element(StateData,
+ exmpp_server_compression:failure('unsupported-method')),
+ fsm_next_state(wait_for_feature_request,
+ StateData)
end;
_ ->
if
(SockMod == gen_tcp) and TLSRequired ->
Lang = StateData#state.lang,
- send_text(StateData, ?POLICY_VIOLATION_ERR(
- Lang,
- "Use of STARTTLS required") ++
- ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error(
+ 'policy-violation', Lang, "Use of STARTTLS required")),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
true ->
process_unauthenticated_stanza(StateData, El),
@@ -661,32 +648,31 @@ wait_for_feature_request(timeout, StateData) ->
{stop, normal, StateData};
wait_for_feature_request({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_feature_request({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_feature_request(closed, StateData) ->
{stop, normal, StateData}.
-wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, Attrs, Els} = El,
- case {xml:get_attr_s("xmlns", Attrs), Name} of
- {?NS_SASL, "response"} ->
- ClientIn = jlib:decode_base64(xml:get_cdata(Els)),
+wait_for_sasl_response({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
+ StateData) ->
+ case {NS, Name} of
+ {?NS_SASL, 'response'} ->
+ {response, ClientIn} = exmpp_server_sasl:next_step(El),
case cyrsasl:server_step(StateData#state.sasl_state,
ClientIn) of
{ok, Props} ->
(StateData#state.sockmod):reset_stream(
StateData#state.socket),
- send_element(StateData,
- {xmlelement, "success",
- [{"xmlns", ?NS_SASL}], []}),
- U = xml:get_attr_s(username, Props),
- AuthModule = xml:get_attr_s(auth_module, Props),
+ send_element(StateData, exmpp_server_sasl:success()),
+ U = proplists:get_value(username, Props),
+ AuthModule = proplists:get_value(auth_module, Props),
?INFO_MSG("(~w) Accepted authentication for ~s",
[StateData#state.socket, U]),
fsm_next_state(wait_for_stream,
@@ -697,10 +683,7 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
user = U});
{continue, ServerOut, NewSASLState} ->
send_element(StateData,
- {xmlelement, "challenge",
- [{"xmlns", ?NS_SASL}],
- [{xmlcdata,
- jlib:encode_base64(ServerOut)}]}),
+ exmpp_server_sasl:challenge(ServerOut)),
fsm_next_state(wait_for_sasl_response,
StateData#state{sasl_state = NewSASLState});
{error, Error, Username} ->
@@ -708,16 +691,14 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
"(~w) Failed authentication for ~s@~s",
[StateData#state.socket,
Username, StateData#state.server]),
+ % XXX OLD FORMAT: list_to_atom(Error).
send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, Error, [], []}]}),
+ exmpp_server_sasl:failure(list_to_atom(Error))),
fsm_next_state(wait_for_feature_request, StateData);
{error, Error} ->
+ % XXX OLD FORMAT: list_to_atom(Error).
send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, Error, [], []}]}),
+ exmpp_server_sasl:failure(list_to_atom(Error))),
fsm_next_state(wait_for_feature_request, StateData)
end;
_ ->
@@ -729,11 +710,12 @@ wait_for_sasl_response(timeout, StateData) ->
{stop, normal, StateData};
wait_for_sasl_response({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_sasl_response({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_sasl_response(closed, StateData) ->
@@ -742,35 +724,25 @@ wait_for_sasl_response(closed, StateData) ->
wait_for_bind({xmlstreamelement, El}, StateData) ->
- case jlib:iq_query_info(El) of
- #iq{type = set, xmlns = ?NS_BIND, sub_el = SubEl} = IQ ->
- U = StateData#state.user,
- R1 = xml:get_path_s(SubEl, [{elem, "resource"}, cdata]),
- R = case jlib:resourceprep(R1) of
- error -> error;
- "" ->
- lists:concat(
- [randoms:get_string() | tuple_to_list(now())]);
- Resource -> Resource
- end,
- case R of
- error ->
- Err = jlib:make_error_reply(El, ?ERR_BAD_REQUEST),
- send_element(StateData, Err),
- fsm_next_state(wait_for_bind, StateData);
- _ ->
- JID = jlib:make_jid(U, StateData#state.server, R),
- Res = IQ#iq{type = result,
- sub_el = [{xmlelement, "bind",
- [{"xmlns", ?NS_BIND}],
- [{xmlelement, "jid", [],
- [{xmlcdata,
- jlib:jid_to_string(JID)}]}]}]},
- send_element(StateData, jlib:iq_to_xml(Res)),
- fsm_next_state(wait_for_session,
- StateData#state{resource = R, jid = JID})
- end;
- _ ->
+ try
+ U = StateData#state.user,
+ R = case exmpp_server_binding:wished_resource(El) of
+ undefined ->
+ lists:concat([randoms:get_string() | tuple_to_list(now())]);
+ Resource ->
+ Resource
+ end,
+ JID = exmpp_jid:make_jid(U, StateData#state.server, R),
+ Res = exmpp_server_binding:bind(El, JID),
+ send_element(StateData, Res),
+ fsm_next_state(wait_for_session,
+ StateData#state{resource = R, jid = JID})
+ catch
+ throw:{stringprep, resourceprep, _, _} ->
+ Err = exmpp_server_binding:error(El, 'bad-request'),
+ send_element(StateData, Err),
+ fsm_next_state(wait_for_bind, StateData);
+ throw:Exception ->
fsm_next_state(wait_for_bind, StateData)
end;
@@ -778,11 +750,12 @@ wait_for_bind(timeout, StateData) ->
{stop, normal, StateData};
wait_for_bind({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_bind({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_bind(closed, StateData) ->
@@ -791,57 +764,58 @@ wait_for_bind(closed, StateData) ->
wait_for_session({xmlstreamelement, El}, StateData) ->
- case jlib:iq_query_info(El) of
- #iq{type = set, xmlns = ?NS_SESSION} ->
- U = StateData#state.user,
- R = StateData#state.resource,
- JID = StateData#state.jid,
- case acl:match_rule(StateData#state.server,
- StateData#state.access, JID) of
- allow ->
- ?INFO_MSG("(~w) Opened session for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- SID = {now(), self()},
- Conn = get_conn_type(StateData),
- Info = [{ip, StateData#state.ip}, {conn, Conn},
- {auth_module, StateData#state.auth_module}],
- ejabberd_sm:open_session(
- SID, U, StateData#state.server, R, Info),
- Res = jlib:make_result_iq_reply(El),
- send_element(StateData, Res),
- change_shaper(StateData, JID),
- {Fs, Ts} = ejabberd_hooks:run_fold(
- roster_get_subscription_lists,
- StateData#state.server,
- {[], []},
- [U, StateData#state.server]),
- LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
- Fs1 = [LJID | Fs],
- Ts1 = [LJID | Ts],
- PrivList =
- ejabberd_hooks:run_fold(
- privacy_get_user_list, StateData#state.server,
- #userlist{},
- [U, StateData#state.server]),
- fsm_next_state(session_established,
- StateData#state{
- sid = SID,
- conn = Conn,
- pres_f = ?SETS:from_list(Fs1),
- pres_t = ?SETS:from_list(Ts1),
- privacy_list = PrivList});
- _ ->
- ejabberd_hooks:run(forbidden_session_hook,
- StateData#state.server, [JID]),
- ?INFO_MSG("(~w) Forbidden session for ~s",
- [StateData#state.socket,
- jlib:jid_to_string(JID)]),
- Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED),
- send_element(StateData, Err),
- fsm_next_state(wait_for_session, StateData)
- end;
- _ ->
+ try
+ U = StateData#state.user,
+ R = StateData#state.resource,
+ JID = StateData#state.jid,
+ exmpp_server_session:want_establishment(El),
+ case acl:match_rule(StateData#state.server,
+ StateData#state.access, JID) of
+ allow ->
+ ?INFO_MSG("(~w) Opened session for ~s",
+ [StateData#state.socket,
+ exmpp_jid:jid_to_string(JID)]),
+ SID = {now(), self()},
+ Conn = get_conn_type(StateData),
+ Info = [{ip, StateData#state.ip}, {conn, Conn},
+ {auth_module, StateData#state.auth_module}],
+ ejabberd_sm:open_session(
+ SID, U, StateData#state.server, R, Info),
+ Res = exmpp_server_session:establish(El),
+ send_element(StateData, Res),
+ change_shaper(StateData, JID),
+ {Fs, Ts} = ejabberd_hooks:run_fold(
+ roster_get_subscription_lists,
+ StateData#state.server,
+ {[], []},
+ [U, StateData#state.server]),
+ LJID = {JID#jid.lnode, JID#jid.ldomain, ""},
+ Fs1 = [LJID | Fs],
+ Ts1 = [LJID | Ts],
+ PrivList =
+ ejabberd_hooks:run_fold(
+ privacy_get_user_list, StateData#state.server,
+ #userlist{},
+ [U, StateData#state.server]),
+ fsm_next_state(session_established,
+ StateData#state{
+ sid = SID,
+ conn = Conn,
+ pres_f = ?SETS:from_list(Fs1),
+ pres_t = ?SETS:from_list(Ts1),
+ privacy_list = PrivList});
+ _ ->
+ ejabberd_hooks:run(forbidden_session_hook,
+ StateData#state.server, [JID]),
+ ?INFO_MSG("(~w) Forbidden session for ~s",
+ [StateData#state.socket,
+ exmpp_jid:jid_to_string(JID)]),
+ Err = exmpp_server_session:error(El, 'not-allowed'),
+ send_element(StateData, Err),
+ fsm_next_state(wait_for_session, StateData)
+ end
+ catch
+ throw:_Exception ->
fsm_next_state(wait_for_session, StateData)
end;
@@ -849,11 +823,12 @@ wait_for_session(timeout, StateData) ->
{stop, normal, StateData};
wait_for_session({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_session({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_session(closed, StateData) ->
@@ -861,90 +836,121 @@ wait_for_session(closed, StateData) ->
session_established({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, Attrs, _Els} = El,
- User = StateData#state.user,
- Server = StateData#state.server,
- % TODO: check 'from' attribute in stanza
- FromJID = StateData#state.jid,
- To = xml:get_attr_s("to", Attrs),
- ToJID = case To of
- "" ->
- jlib:make_jid(User, Server, "");
- _ ->
- jlib:string_to_jid(To)
- end,
- NewEl1 = jlib:remove_attr("xmlns", El),
- NewEl = case xml:get_attr_s("xml:lang", Attrs) of
- "" ->
- case StateData#state.lang of
- "" -> NewEl1;
- Lang ->
- xml:replace_tag_attr("xml:lang", Lang, NewEl1)
- end;
- _ ->
- NewEl1
- end,
- NewState =
- case ToJID of
- error ->
- case xml:get_attr_s("type", Attrs) of
- "error" -> StateData;
- "result" -> StateData;
+ try
+ User = StateData#state.user,
+ Server = StateData#state.server,
+ % TODO: check 'from' attribute in stanza
+ FromJID = StateData#state.jid,
+ To = exmpp_stanza:get_recipient(El),
+ ToJID = case To of
+ "" ->
+ exmpp_jid:make_jid(User, Server, "");
_ ->
- Err = jlib:make_error_reply(NewEl, ?ERR_JID_MALFORMED),
- send_element(StateData, Err),
- StateData
+ exmpp_jid:string_to_jid(To)
+ end,
+ NewEl = case exmpp_stanza:get_lang(El) of
+ "" ->
+ case StateData#state.lang of
+ "" -> El;
+ Lang ->
+ exmpp_stanza:set_lang(El, Lang)
+ end;
+ _ ->
+ El
+ end,
+ NewState = case El of
+ #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence'} ->
+ % XXX OLD FORMAT: NewEl.
+ PresenceElOld = ejabberd_hooks:run_fold(
+ c2s_update_presence,
+ Server,
+ exmpp_xml:xmlel_to_xmlelement(NewEl,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ [User, Server]),
+ PresenceEl = exmpp_xml:xmlelement_to_xmlel(PresenceElOld,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ % XXX OLD FORMAT: PresenceElOld.
+ ejabberd_hooks:run(
+ user_send_packet,
+ Server,
+ [FromJID, ToJID, PresenceElOld]),
+ case ToJID of
+ #jid{node = User,
+ domain = Server,
+ resource = ""} ->
+ ?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
+ [FromJID, PresenceEl, StateData]),
+ % XXX OLD FORMAT: PresenceElOld.
+ presence_update(FromJID, PresenceElOld,
+ StateData);
+ _ ->
+ % XXX OLD FORMAT: PresenceElOld.
+ presence_track(FromJID, ToJID, PresenceElOld,
+ StateData)
end;
- _ ->
- case Name of
- "presence" ->
- PresenceEl = ejabberd_hooks:run_fold(
- c2s_update_presence,
- Server,
- NewEl,
- [User, Server]),
+ #xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
+ IQ_Content = case exmpp_iq:get_type(El) of
+ 'get' -> exmpp_iq:get_request(El);
+ 'set' -> exmpp_iq:get_request(El);
+ 'result' -> exmpp_iq:get_result(El);
+ 'error' -> exmpp_stanza:get_error(El)
+ end,
+ case IQ_Content of
+ #xmlel{ns = ?NS_PRIVACY} = IQ ->
+ % XXX OLD FORMAT: IQ was #iq.
+ process_privacy_iq(
+ FromJID, ToJID, IQ, StateData);
+ _ ->
+ % XXX OLD FORMAT: NewElOld.
+ NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
+ ?DEFAULT_NS, ?PREFIXED_NS),
ejabberd_hooks:run(
user_send_packet,
Server,
- [FromJID, ToJID, PresenceEl]),
- case ToJID of
- #jid{user = User,
- server = Server,
- resource = ""} ->
- ?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
- [FromJID, PresenceEl, StateData]),
- presence_update(FromJID, PresenceEl,
- StateData);
- _ ->
- presence_track(FromJID, ToJID, PresenceEl,
- StateData)
- end;
- "iq" ->
- case jlib:iq_query_info(NewEl) of
- #iq{xmlns = ?NS_PRIVACY} = IQ ->
- process_privacy_iq(
- FromJID, ToJID, IQ, StateData);
- _ ->
- ejabberd_hooks:run(
- user_send_packet,
- Server,
- [FromJID, ToJID, NewEl]),
- ejabberd_router:route(
- FromJID, ToJID, NewEl),
- StateData
- end;
- "message" ->
- ejabberd_hooks:run(user_send_packet,
- Server,
- [FromJID, ToJID, NewEl]),
- ejabberd_router:route(FromJID, ToJID, NewEl),
- StateData;
- _ ->
+ [FromJID, ToJID, NewElOld]),
+ % XXX OLD FORMAT: NewElOld.
+ ejabberd_router:route(
+ FromJID, ToJID, NewElOld),
StateData
- end
+ end;
+ #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message'} ->
+ % XXX OLD FORMAT: NewElOld.
+ NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ ejabberd_hooks:run(user_send_packet,
+ Server,
+ [FromJID, ToJID, NewElOld]),
+ % XXX OLD FORMAT: NewElOld.
+ ejabberd_router:route(FromJID, ToJID, NewElOld),
+ StateData;
+ _ ->
+ StateData
end,
- ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, El}]),
- fsm_next_state(session_established, NewState);
+ % XXX OLD FORMAT: El.
+ ElOld = exmpp_xml:xmlel_to_xmlelement(El,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, ElOld}]),
+ fsm_next_state(session_established, NewState)
+ catch
+ throw:{stringprep, _, _, _} ->
+ case exmpp_stanza:get_type(El) of
+ "error" ->
+ ok;
+ "result" ->
+ ok;
+ _ ->
+ Err = exmpp_stanza:reply_with_error(El, 'jid-malformed'),
+ send_element(StateData, Err)
+ end,
+ % XXX OLD FORMAT: ElOld1.
+ ElOld1 = exmpp_xml:xmlel_to_xmlelement(El,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, ElOld1}]),
+ fsm_next_state(session_established, StateData);
+ throw:Exception ->
+ io:format("SESSION ESTABLISHED: Exception=~p~n", [Exception]),
+ fsm_next_state(session_established, StateData)
+ end;
%% We hibernate the process to reduce memory consumption after a
%% configurable activity timeout
@@ -956,11 +962,12 @@ session_established(timeout, StateData) ->
fsm_next_state(session_established, StateData);
session_established({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
session_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
session_established(closed, StateData) ->
From 2a439984446b63fc725e187cadc89579427066cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 20 Jun 2008 14:54:59 +0000
Subject: [PATCH 007/582] o Change the usage of #state.lang somewhat. o Fix
value of DefaultLang: it doesn't contain the whole serialized attribute. o
Use exmpp_jid:make_bare_jid/2 more.
I started to work on the second half of the module and discovered
several annoying things:
o JID are represented in two forms: the #jid record and the
{N, D, R} tuple.
o Sometimes, #xmlelement may contain non-#xml* tuples in their
children. This is the case for some stanzas. Their
children are used to pass random data.
I'm less and less convicted that ejabberd_c2s can be fully converted
without starting to work on other modules.
SVN Revision: 1370
---
ChangeLog | 4 ++++
src/ejabberd_c2s.erl | 54 ++++++++++++++++++++------------------------
2 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 3447a057b..ea528f668 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,10 @@
FSM state function are updated. But other functions are not for now.
Users are able to connect to ejabberd but some features may not work.
+ * src/ejabberd_c2s.erl: Change the usage of #state.lang somewhat.
+ Fix value of DefaultLang: it doesn't contain the whole serialized
+ attribute. Use exmpp_jid:make_bare_jid/2 more.
+
2008-06-19 Jean-Sébastien Pédron
* src/ejabberd_receiver.erl: Replace the use of xml_stream by
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 400b725fe..e50f9bdb5 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -142,7 +142,6 @@
-define(NS_AUTH, "jabber:iq:auth").
-define(NS_FEATURE_COMPRESS, "http://jabber.org/features/compress").
-define(NS_PRIVACY, "jabber:iq:privacy").
--define(NS_VCARD, "vcard-temp").
-define(STREAM_ERROR(Condition),
exmpp_xml:xmlel_to_xmlelement(exmpp_stream:error(Condition),
@@ -273,9 +272,9 @@ get_subscribed_and_online(FsmRef) ->
wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
DefaultLang = case ?MYLANG of
undefined ->
- " xml:lang='en'";
+ "en";
DL ->
- " xml:lang='" ++ DL ++ "'"
+ DL
end,
Header = exmpp_stream:opening_reply(Opening,
StateData#state.streamid),
@@ -287,8 +286,9 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
case lists:member(Server, ?MYHOSTS) of
true ->
Lang = exmpp_stream:get_lang(Opening),
+ % OLD FORMAT: JID with empty strings.
change_shaper(StateData,
- exmpp_jid:make_jid("", Server, "")),
+ exmpp_jid:make_bare_jid(undefined, Server)),
case exmpp_stream:get_version(Opening) of
{1, 0} ->
send_element(StateData, Header1),
@@ -375,7 +375,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
send_element(StateData,
exmpp_xml:append_child(Header1,
exmpp_stream:error('policy-violation',
- Lang, "Use of STARTTLS required"))),
+ "en", "Use of STARTTLS required"))),
{stop, normal, StateData};
true ->
send_element(StateData, Header1),
@@ -437,7 +437,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
fsm_next_state(wait_for_auth, StateData);
{auth, _ID, set, {_U, _P, _D, ""}} ->
Err = exmpp_stanza:error('not-acceptable',
- {StateData#state.lang, "No resource provided"}),
+ {"en", "No resource provided"}),
send_element(StateData, exmpp_iq:error(El, Err)),
fsm_next_state(wait_for_auth, StateData);
{auth, _ID, set, {U, P, D, R}} ->
@@ -468,7 +468,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = {JID#jid.lnode, JID#jid.ldomain, ""},
+ LJID = {JID#jid.lnode, JID#jid.ldomain,
+ undefined},
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList = ejabberd_hooks:run_fold(
@@ -633,9 +634,8 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
_ ->
if
(SockMod == gen_tcp) and TLSRequired ->
- Lang = StateData#state.lang,
send_element(StateData, exmpp_stream:error(
- 'policy-violation', Lang, "Use of STARTTLS required")),
+ 'policy-violation', "en", "Use of STARTTLS required")),
send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
true ->
@@ -742,7 +742,7 @@ wait_for_bind({xmlstreamelement, El}, StateData) ->
Err = exmpp_server_binding:error(El, 'bad-request'),
send_element(StateData, Err),
fsm_next_state(wait_for_bind, StateData);
- throw:Exception ->
+ throw:_Exception ->
fsm_next_state(wait_for_bind, StateData)
end;
@@ -789,7 +789,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = {JID#jid.lnode, JID#jid.ldomain, ""},
+ LJID = {JID#jid.lnode, JID#jid.ldomain, undefined},
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList =
@@ -805,6 +805,8 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
pres_t = ?SETS:from_list(Ts1),
privacy_list = PrivList});
_ ->
+ % OLD FORMAT: Jid may use 'undefined' instead of empty
+ % strings.
ejabberd_hooks:run(forbidden_session_hook,
StateData#state.server, [JID]),
?INFO_MSG("(~w) Forbidden session for ~s",
@@ -843,15 +845,15 @@ session_established({xmlstreamelement, El}, StateData) ->
FromJID = StateData#state.jid,
To = exmpp_stanza:get_recipient(El),
ToJID = case To of
- "" ->
- exmpp_jid:make_jid(User, Server, "");
+ undefined ->
+ exmpp_jid:make_bare_jid(User, Server);
_ ->
exmpp_jid:string_to_jid(To)
end,
NewEl = case exmpp_stanza:get_lang(El) of
- "" ->
+ undefined ->
case StateData#state.lang of
- "" -> El;
+ undefined -> El;
Lang ->
exmpp_stanza:set_lang(El, Lang)
end;
@@ -889,17 +891,12 @@ session_established({xmlstreamelement, El}, StateData) ->
StateData)
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
- IQ_Content = case exmpp_iq:get_type(El) of
- 'get' -> exmpp_iq:get_request(El);
- 'set' -> exmpp_iq:get_request(El);
- 'result' -> exmpp_iq:get_result(El);
- 'error' -> exmpp_stanza:get_error(El)
- end,
- case IQ_Content of
- #xmlel{ns = ?NS_PRIVACY} = IQ ->
+ case exmpp_iq:get_payload(El) of
+ #xmlel{ns = ?NS_PRIVACY} ->
% XXX OLD FORMAT: IQ was #iq.
+ IQ_Record = exmpp_iq:make_iq_record(El),
process_privacy_iq(
- FromJID, ToJID, IQ, StateData);
+ FromJID, ToJID, IQ_Record, StateData);
_ ->
% XXX OLD FORMAT: NewElOld.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
@@ -1018,6 +1015,7 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
fsm_reply(Reply, StateName, StateData);
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
+ % XXX OLD FORMAT: This function needs update. User has the form {N, D, R}.
Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available,
Pred = fun(User, _Caps) ->
@@ -1042,15 +1040,13 @@ code_change(_OldVsn, StateName, StateData, _Extra) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
handle_info({send_text, Text}, StateName, StateData) ->
+ % XXX OLD FORMAT: This clause should be removed.
send_text(StateData, Text),
ejabberd_hooks:run(c2s_loop_debug, [Text]),
fsm_next_state(StateName, StateData);
handle_info(replaced, _StateName, StateData) ->
- Lang = StateData#state.lang,
- send_text(StateData,
- xml:element_to_string(
- ?SERRT_CONFLICT(Lang, "Replaced by new connection"))
- ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('conflict')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData#state{authenticated = replaced}};
handle_info({route, From, To, Packet}, StateName, StateData) ->
{xmlelement, Name, Attrs, Els} = Packet,
From e95df7999f57600b4819f069d4313d041ee6373d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 23 Jun 2008 11:47:10 +0000
Subject: [PATCH 008/582] Convert JID to the expected form outside of the C2S
(empty fields must be set to the empty string). This fixes the broken
routing.
SVN Revision: 1375
---
ChangeLog | 6 ++++++
src/ejabberd_c2s.erl | 31 +++++++++++++++++++------------
2 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index ea528f668..9be49fd1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-06-23 Jean-Sébastien Pédron
+
+ * src/ejabberd_c2s.erl (session_established): Convert JID to the
+ expected form outside of the C2S (empty fields must be set to the
+ empty string). This fixes the broken routing.
+
2008-06-20 Jean-Sébastien Pédron
* src/configure, src/aclocal.m4, src/Makefile.in: Add exmpp detection.
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index e50f9bdb5..1e3e38df6 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -871,32 +871,37 @@ session_established({xmlstreamelement, El}, StateData) ->
[User, Server]),
PresenceEl = exmpp_xml:xmlelement_to_xmlel(PresenceElOld,
?DEFAULT_NS, ?PREFIXED_NS),
- % XXX OLD FORMAT: PresenceElOld.
+ % XXX OLD FORMAT: PresenceElOld, *JID.
+ FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
+ ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
ejabberd_hooks:run(
user_send_packet,
Server,
- [FromJID, ToJID, PresenceElOld]),
+ [FromJIDOld, ToJIDOld, PresenceElOld]),
case ToJID of
#jid{node = User,
domain = Server,
- resource = ""} ->
+ resource = undefined} ->
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
[FromJID, PresenceEl, StateData]),
% XXX OLD FORMAT: PresenceElOld.
- presence_update(FromJID, PresenceElOld,
+ presence_update(FromJIDOld, PresenceElOld,
StateData);
_ ->
% XXX OLD FORMAT: PresenceElOld.
- presence_track(FromJID, ToJID, PresenceElOld,
+ presence_track(FromJIDOld, ToJIDOld, PresenceElOld,
StateData)
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
+ % XXX OLD FORMAT: JIDs.
+ FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
+ ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
case exmpp_iq:get_payload(El) of
#xmlel{ns = ?NS_PRIVACY} ->
% XXX OLD FORMAT: IQ was #iq.
- IQ_Record = exmpp_iq:make_iq_record(El),
+ IQ_Record = exmpp_iq:to_ejabberd_iq(El),
process_privacy_iq(
- FromJID, ToJID, IQ_Record, StateData);
+ FromJIDOld, ToJIDOld, IQ_Record, StateData);
_ ->
% XXX OLD FORMAT: NewElOld.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
@@ -904,21 +909,23 @@ session_established({xmlstreamelement, El}, StateData) ->
ejabberd_hooks:run(
user_send_packet,
Server,
- [FromJID, ToJID, NewElOld]),
+ [FromJIDOld, ToJIDOld, NewElOld]),
% XXX OLD FORMAT: NewElOld.
ejabberd_router:route(
- FromJID, ToJID, NewElOld),
+ FromJIDOld, ToJIDOld, NewElOld),
StateData
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'message'} ->
- % XXX OLD FORMAT: NewElOld.
+ % XXX OLD FORMAT: NewElOld, JIDs.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
?DEFAULT_NS, ?PREFIXED_NS),
+ FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
+ ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
ejabberd_hooks:run(user_send_packet,
Server,
- [FromJID, ToJID, NewElOld]),
+ [FromJIDOld, ToJIDOld, NewElOld]),
% XXX OLD FORMAT: NewElOld.
- ejabberd_router:route(FromJID, ToJID, NewElOld),
+ ejabberd_router:route(FromJIDOld, ToJIDOld, NewElOld),
StateData;
_ ->
StateData
From 4e2e68a3fb2122af3dd6839764daa57ae7171c8e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 24 Jun 2008 08:55:24 +0000
Subject: [PATCH 009/582] The handle_info clause that treats routing order is
now converted. In-memory sets and dict still use the short JID form with
empty strings for unspecified fields. Users are able to connect to ejabberd
but some features don't seem to work proprerly.
SVN Revision: 1376
---
ChangeLog | 7 ++
src/ejabberd_c2s.erl | 223 +++++++++++++++++++++++++------------------
2 files changed, 138 insertions(+), 92 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 9be49fd1e..269717f7a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-06-24 Jean-Sébastien Pédron
+
+ * src/ejabberd_c2s.erl: The handle_info clause that treats routing
+ order is now converted. In-memory sets and dict still use the short
+ JID form with empty strings for unspecified fields. Users are able to
+ connect to ejabberd but some features don't seem to work proprerly.
+
2008-06-23 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl (session_established): Convert JID to the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 1e3e38df6..7567a591e 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -872,8 +872,8 @@ session_established({xmlstreamelement, El}, StateData) ->
PresenceEl = exmpp_xml:xmlelement_to_xmlel(PresenceElOld,
?DEFAULT_NS, ?PREFIXED_NS),
% XXX OLD FORMAT: PresenceElOld, *JID.
- FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
- ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
+ FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
+ ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
ejabberd_hooks:run(
user_send_packet,
Server,
@@ -893,15 +893,17 @@ session_established({xmlstreamelement, El}, StateData) ->
StateData)
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
- % XXX OLD FORMAT: JIDs.
- FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
- ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
+ % XXX OLD FORMAT: JIDs.
+ FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
+ ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
case exmpp_iq:get_payload(El) of
#xmlel{ns = ?NS_PRIVACY} ->
% XXX OLD FORMAT: IQ was #iq.
- IQ_Record = exmpp_iq:to_ejabberd_iq(El),
+ ElOld2 = exmpp_xml:xmlel_to_xmlelement(El,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ IQ = jlib:iq_query_info(ElOld2),
process_privacy_iq(
- FromJIDOld, ToJIDOld, IQ_Record, StateData);
+ FromJIDOld, ToJIDOld, IQ, StateData);
_ ->
% XXX OLD FORMAT: NewElOld.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
@@ -919,8 +921,8 @@ session_established({xmlstreamelement, El}, StateData) ->
% XXX OLD FORMAT: NewElOld, JIDs.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
?DEFAULT_NS, ?PREFIXED_NS),
- FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
- ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
+ FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
+ ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
ejabberd_hooks:run(user_send_packet,
Server,
[FromJIDOld, ToJIDOld, NewElOld]),
@@ -1055,15 +1057,20 @@ handle_info(replaced, _StateName, StateData) ->
send_element(StateData, exmpp_stream:error('conflict')),
send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData#state{authenticated = replaced}};
-handle_info({route, From, To, Packet}, StateName, StateData) ->
- {xmlelement, Name, Attrs, Els} = Packet,
+handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
+ %% XXX OLD FORMAT: From, To and Packet are in the old format.
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ From = exmpp_jid:from_ejabberd_jid(FromOld),
+ To = exmpp_jid:from_ejabberd_jid(ToOld),
{Pass, NewAttrs, NewState} =
- case Name of
- "presence" ->
- case xml:get_attr_s("type", Attrs) of
- "probe" ->
- LFrom = jlib:jid_tolower(From),
- LBFrom = jlib:jid_remove_resource(LFrom),
+ case Packet of
+ #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = Attrs} ->
+ case exmpp_presence:get_type(Packet) of
+ 'probe' ->
+ % XXX OLD FORMAT: LFrom and LBFrom.
+ LFrom = short_jid(From),
+ LBFrom = short_jid(exmpp_jid:jid_to_bare_jid(From)),
NewStateData =
case ?SETS:is_element(
LFrom, StateData#state.pres_a) orelse
@@ -1075,6 +1082,8 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
case ?SETS:is_element(
LFrom, StateData#state.pres_f) of
true ->
+ % XXX OLD FORMAT: Stores old short
+ % JIDs.
A = ?SETS:add_element(
LFrom,
StateData#state.pres_a),
@@ -1083,6 +1092,8 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
case ?SETS:is_element(
LBFrom, StateData#state.pres_f) of
true ->
+ % XXX OLD FORMAT: Stores
+ % old short JIDs.
A = ?SETS:add_element(
LBFrom,
StateData#state.pres_a),
@@ -1092,40 +1103,51 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
end
end
end,
- process_presence_probe(From, To, NewStateData),
+ % XXX OLD FORMAT: FromOld and ToOld
+ process_presence_probe(FromOld, ToOld, NewStateData),
{false, Attrs, NewStateData};
- "error" ->
- NewA = remove_element(jlib:jid_tolower(From),
+ 'error' ->
+ % XXX OLD FORMAT: LFrom.
+ LFrom = short_jid(From),
+ NewA = remove_element(LFrom,
StateData#state.pres_a),
{true, Attrs, StateData#state{pres_a = NewA}};
- "invisible" ->
- Attrs1 = lists:keydelete("type", 1, Attrs),
- {true, [{"type", "unavailable"} | Attrs1], StateData};
- "subscribe" ->
+ 'invisible' ->
+ % XXX OLD FORMAT: Create a function to change 'type'.
+ Attrs1 = exmpp_stanza:set_type_in_attrs(Attrs,
+ "unavailable"),
+ {true, Attrs1, StateData};
+ 'subscribe' ->
{true, Attrs, StateData};
- "subscribed" ->
+ 'subscribed' ->
{true, Attrs, StateData};
- "unsubscribe" ->
+ 'unsubscribe' ->
{true, Attrs, StateData};
- "unsubscribed" ->
+ 'unsubscribed' ->
{true, Attrs, StateData};
_ ->
+ % XXX OLD FORMAT: From, To, Packet.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {From, To, Packet},
+ {FromOld, ToOld, PacketOld},
in]) of
allow ->
- LFrom = jlib:jid_tolower(From),
- LBFrom = jlib:jid_remove_resource(LFrom),
+ % XXX OLD FORMAT: LFrom and LBFrom.
+ LFrom = short_jid(From),
+ LBFrom = short_jid(
+ exmpp_jid:jid_to_bare_jid(From)),
%% Note contact availability
+ % XXX OLD FORMAT: Els are #xmlelement.
+ Els = PacketOld#xmlelement.children,
Caps = mod_caps:read_caps(Els),
- mod_caps:note_caps(StateData#state.server, From, Caps),
- NewAvailable = case xml:get_attr_s("type", Attrs) of
- "unavailable" ->
+ % XXX OLD FORMAT: From.
+ mod_caps:note_caps(StateData#state.server, FromOld, Caps),
+ NewAvailable = case exmpp_presence:get_type(Packet) of
+ 'unavailable' ->
?DICT:erase(LFrom, StateData#state.pres_available);
_ ->
?DICT:store(LFrom, Caps, StateData#state.pres_available)
@@ -1164,10 +1186,14 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
{false, Attrs, StateData}
end
end;
- "broadcast" ->
+ % XXX OLD FORMAT: broadcast?
+ #xmlel{ns = _NS, name = 'broadcast', attrs = Attrs} ->
+ % XXX OLD FORMAT: Els are #xmlelement.
+ Els = PacketOld#xmlelement.children,
?DEBUG("broadcast~n~p~n", [Els]),
case Els of
[{item, IJID, ISubscription}] ->
+ % XXX OLD FORMAT: IJID is an old #jid.
{false, Attrs,
roster_change(IJID, ISubscription,
StateData)};
@@ -1182,76 +1208,82 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
false ->
{false, Attrs, StateData};
NewPL ->
- PrivPushIQ =
- #iq{type = set, xmlns = ?NS_PRIVACY,
- id = "push",
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_PRIVACY}],
- [{xmlelement, "list",
- [{"name", PrivListName}],
- []}]}]},
- PrivPushEl =
- jlib:replace_from_to(
- jlib:jid_remove_resource(
- StateData#state.jid),
- StateData#state.jid,
- jlib:iq_to_xml(PrivPushIQ)),
+ PrivPushEl = exmpp_server_privacy:list_push(
+ StateData#state.jid, PrivListName),
send_element(StateData, PrivPushEl),
{false, Attrs, StateData#state{privacy_list = NewPL}}
end;
_ ->
{false, Attrs, StateData}
end;
- "iq" ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{xmlns = ?NS_VCARD} ->
- Host = StateData#state.server,
- case ets:lookup(sm_iqtable, {?NS_VCARD, Host}) of
- [{_, Module, Function, Opts}] ->
- gen_iq_handler:handle(Host, Module, Function, Opts,
- From, To, IQ);
- [] ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err)
- end,
- {false, Attrs, StateData};
- #iq{} ->
- case ejabberd_hooks:run_fold(
- privacy_check_packet, StateData#state.server,
- allow,
- [StateData#state.user,
- StateData#state.server,
- StateData#state.privacy_list,
- {From, To, Packet},
- in]) of
- allow ->
- {true, Attrs, StateData};
- deny ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
- ejabberd_router:route(To, From, Err),
- {false, Attrs, StateData}
+ #xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq', attrs = Attrs} ->
+ case exmpp_iq:is_request(Packet) of
+ true ->
+ case exmpp_iq:get_request(Packet) of
+ #xmlel{ns = ?NS_VCARD} ->
+ Host = StateData#state.server,
+ % XXX OLD FORMAT: sm_iqtable contains strings
+ % for namespaces.
+ case ets:lookup(sm_iqtable, {atom_to_list(?NS_VCARD), Host}) of
+ [{_, Module, Function, Opts}] ->
+ % XXX OLD FORMAT: IQ is an old #iq,
+ % From, To.
+ IQ = jlib:iq_query_info(PacketOld),
+ io:format("IQ = ~p~n", [IQ]),
+ gen_iq_handler:handle(Host, Module, Function, Opts,
+ FromOld, ToOld, IQ);
+ [] ->
+ Err = exmpp_stanza:error('feature-not-implemented'),
+ Res = exmpp_iq:error(Packet, Err),
+ % XXX OLD FORMAT: To, From, Res.
+ ResOld = exmpp_xml:xmlel_to_xmlelement(
+ Res, ?DEFAULT_NS, ?PREFIXED_NS),
+ ejabberd_router:route(ToOld, FromOld, ResOld)
+ end,
+ {false, Attrs, StateData};
+ _ ->
+ % XXX OLD FORMAT: From, To and Packet.
+ case ejabberd_hooks:run_fold(
+ privacy_check_packet, StateData#state.server,
+ allow,
+ [StateData#state.user,
+ StateData#state.server,
+ StateData#state.privacy_list,
+ {FromOld, ToOld, PacketOld},
+ in]) of
+ allow ->
+ {true, Attrs, StateData};
+ deny ->
+ Err = exmpp_stanza:error(
+ 'feature-not-implemented'),
+ Res = exmpp_iq:error(Packet, Err),
+ % XXX OLD FORMAT: To, From, Res.
+ ResOld = exmpp_xml:xmlel_to_xmlelement(
+ Res,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ ejabberd_router:route(ToOld, FromOld, ResOld),
+ {false, Attrs, StateData}
+ end
end;
- _ ->
+ false ->
{true, Attrs, StateData}
end;
- "message" ->
+ #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', attrs = Attrs} ->
+ % XXX OLD FORMAT: From, To and Packet.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {From, To, Packet},
+ {FromOld, ToOld, PacketOld},
in]) of
allow ->
{true, Attrs, StateData};
deny ->
{false, Attrs, StateData}
end;
- _ ->
+ #xmlel{attrs = Attrs} ->
{true, Attrs, StateData}
end,
if
@@ -1259,19 +1291,22 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
catch send_text(StateData, ?STREAM_TRAILER),
{stop, normal, StateData};
Pass ->
- Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- NewAttrs),
- FixedPacket = {xmlelement, Name, Attrs2, Els},
- Text = xml:element_to_string(FixedPacket),
- send_text(StateData, Text),
+ Attrs2 = exmpp_stanza:set_sender_in_attrs(NewAttrs, From),
+ Attrs3 = exmpp_stanza:set_recipient_in_attrs(Attrs2, To),
+ FixedPacket = Packet#xmlel{attrs = Attrs3},
+ send_element(StateData, FixedPacket),
+ % XXX OLD FORMAT: From, To, FixedPacket.
+ FixedPacketOld = exmpp_xml:xmlel_to_xmlelement(FixedPacket,
+ ?DEFAULT_NS, ?PREFIXED_NS),
ejabberd_hooks:run(user_receive_packet,
StateData#state.server,
- [StateData#state.jid, From, To, FixedPacket]),
- ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
+ [StateData#state.jid, FromOld, ToOld, FixedPacketOld]),
+ % XXX OLD FORMAT: From, To, FixedPacket.
+ ejabberd_hooks:run(c2s_loop_debug, [{route, FromOld, ToOld, PacketOld}]),
fsm_next_state(StateName, NewState);
true ->
- ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
+ % XXX OLD FORMAT: From, To, FixedPacket.
+ ejabberd_hooks:run(c2s_loop_debug, [{route, FromOld, ToOld, PacketOld}]),
fsm_next_state(StateName, NewState)
end;
handle_info({'DOWN', Monitor, _Type, _Object, _Info}, _StateName, StateData)
@@ -1981,3 +2016,7 @@ fsm_reply(Reply, StateName, StateData) ->
%% Used by c2s blacklist plugins
is_ip_blacklisted({IP,_Port}) ->
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]).
+
+short_jid(JID) ->
+ JID1 = exmpp_jid:to_ejabberd_jid(JID),
+ {JID1#jid.lnode, JID1#jid.ldomain, JID1#jid.lresource}.
From e93e846e160a3fa8c5bf11fe5424dfd262fa86bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 24 Jun 2008 09:44:56 +0000
Subject: [PATCH 010/582] o Use the new exmpp_stream:opening_reply/3 function
in wait_for_stream/2. o The function terminate/3 is converted to exmpp.
SVN Revision: 1377
---
ChangeLog | 4 ++++
src/ejabberd_c2s.erl | 46 ++++++++++++++++++++++++--------------------
2 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 269717f7a..5fa9f4736 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,10 @@
JID form with empty strings for unspecified fields. Users are able to
connect to ejabberd but some features don't seem to work proprerly.
+ * src/ejabberd_c2s.erl: Use the new exmpp_stream:opening_reply/3
+ function in wait_for_stream/2. The function terminate/3 is converted
+ to exmpp.
+
2008-06-23 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl (session_established): Convert JID to the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 7567a591e..04e45780d 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -277,8 +277,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
DL
end,
Header = exmpp_stream:opening_reply(Opening,
- StateData#state.streamid),
- Header1 = exmpp_stream:set_lang(Header, DefaultLang),
+ StateData#state.streamid, DefaultLang),
case NS of
?NS_XMPP ->
Server = exmpp_stringprep:nameprep(
@@ -291,7 +290,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
exmpp_jid:make_bare_jid(undefined, Server)),
case exmpp_stream:get_version(Opening) of
{1, 0} ->
- send_element(StateData, Header1),
+ send_element(StateData, Header),
case StateData#state.authenticated of
false ->
SASLState =
@@ -373,12 +372,12 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
(not StateData#state.tls_enabled) and
StateData#state.tls_required ->
send_element(StateData,
- exmpp_xml:append_child(Header1,
+ exmpp_xml:append_child(Header,
exmpp_stream:error('policy-violation',
"en", "Use of STARTTLS required"))),
{stop, normal, StateData};
true ->
- send_element(StateData, Header1),
+ send_element(StateData, Header),
fsm_next_state(wait_for_auth,
StateData#state{
server = Server,
@@ -386,14 +385,14 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
end
end;
_ ->
- Header2 = exmpp_stream:set_initiating_entity(Header1,
+ Header2 = exmpp_stream:set_initiating_entity(Header,
?MYNAME),
send_element(StateData, exmpp_xml:append_child(Header2,
exmpp_stream:error('host-unknown'))),
{stop, normal, StateData}
end;
_ ->
- Header2 = exmpp_stream:set_initiating_entity(Header1, ?MYNAME),
+ Header2 = exmpp_stream:set_initiating_entity(Header, ?MYNAME),
send_element(StateData, exmpp_xml:append_child(Header2,
exmpp_stream:error('invalid-namespace'))),
{stop, normal, StateData}
@@ -1328,26 +1327,29 @@ terminate(_Reason, StateName, StateData) ->
replaced ->
?INFO_MSG("(~w) Replaced session for ~s",
[StateData#state.socket,
- jlib:jid_to_string(StateData#state.jid)]),
+ exmpp_jid:jid_to_string(StateData#state.jid)]),
From = StateData#state.jid,
- Packet = {xmlelement, "presence",
- [{"type", "unavailable"}],
- [{xmlelement, "status", [],
- [{xmlcdata, "Replaced by new connection"}]}]},
+ Packet = exmpp_presence:unavailable(),
+ Packet1 = exmpp_presence:set_status(Packet,
+ "Replaced by new connection"),
ejabberd_sm:close_session_unset_presence(
StateData#state.sid,
StateData#state.user,
StateData#state.server,
StateData#state.resource,
"Replaced by new connection"),
+ % XXX OLD FORMAT: From, Packet1
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ Packet1Old = exmpp_xml:xmlel_to_xmlelement(Packet1,
+ ?DEFAULT_NS, ?PREFIXED_NS),
presence_broadcast(
- StateData, From, StateData#state.pres_a, Packet),
+ StateData, FromOld, StateData#state.pres_a, Packet1Old),
presence_broadcast(
- StateData, From, StateData#state.pres_i, Packet);
+ StateData, FromOld, StateData#state.pres_i, Packet1Old);
_ ->
?INFO_MSG("(~w) Close session for ~s",
[StateData#state.socket,
- jlib:jid_to_string(StateData#state.jid)]),
+ exmpp_jid:jid_to_string(StateData#state.jid)]),
EmptySet = ?SETS:new(),
case StateData of
@@ -1361,8 +1363,11 @@ terminate(_Reason, StateName, StateData) ->
StateData#state.resource);
_ ->
From = StateData#state.jid,
- Packet = {xmlelement, "presence",
- [{"type", "unavailable"}], []},
+ Packet = exmpp_presence:unavailable(),
+ % XXX OLD FORMAT: From, Packet.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ ?DEFAULT_NS, ?PREFIXED_NS),
ejabberd_sm:close_session_unset_presence(
StateData#state.sid,
StateData#state.user,
@@ -1370,9 +1375,9 @@ terminate(_Reason, StateName, StateData) ->
StateData#state.resource,
""),
presence_broadcast(
- StateData, From, StateData#state.pres_a, Packet),
+ StateData, FromOld, StateData#state.pres_a, PacketOld),
presence_broadcast(
- StateData, From, StateData#state.pres_i, Packet)
+ StateData, FromOld, StateData#state.pres_i, PacketOld)
end
end;
_ ->
@@ -2018,5 +2023,4 @@ is_ip_blacklisted({IP,_Port}) ->
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]).
short_jid(JID) ->
- JID1 = exmpp_jid:to_ejabberd_jid(JID),
- {JID1#jid.lnode, JID1#jid.ldomain, JID1#jid.lresource}.
+ {JID#jid.lnode, JID#jid.ldomain, JID#jid.lresource}.
From 6f931ce4fd13d74f1d630e099ddc532364403656 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 24 Jun 2008 16:12:56 +0000
Subject: [PATCH 011/582] Convert all presence-related functions.
SVN Revision: 1378
---
ChangeLog | 2 +
src/ejabberd_c2s.erl | 412 ++++++++++++++++++++++---------------------
2 files changed, 214 insertions(+), 200 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5fa9f4736..e314e31e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,8 @@
function in wait_for_stream/2. The function terminate/3 is converted
to exmpp.
+ * src/ejabberd_c2s.erl: Convert all presence-related functions.
+
2008-06-23 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl (session_established): Convert JID to the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 04e45780d..060fdadd1 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -119,61 +119,15 @@
-define(DEFAULT_NS, ['jabber:client']).
-define(PREFIXED_NS, [{?NS_XMPP, "stream"}]).
--define(STREAM_HEADER,
- ""
- ""
- ).
-
--define(STREAM_TRAILER, "").
-
--define(INVALID_NS_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
--define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
--define(HOST_UNKNOWN_ERR,
- xml:element_to_string(?SERR_HOST_UNKNOWN)).
--define(POLICY_VIOLATION_ERR(Lang, Text),
- xml:element_to_string(?SERRT_POLICY_VIOLATION(Lang, Text))).
-
% XXX OLD FORMAT
--define(NS_STREAM, "http://etherx.jabber.org/streams").
-define(NS_AUTH, "jabber:iq:auth").
--define(NS_FEATURE_COMPRESS, "http://jabber.org/features/compress").
--define(NS_PRIVACY, "jabber:iq:privacy").
-
--define(STREAM_ERROR(Condition),
- exmpp_xml:xmlel_to_xmlelement(exmpp_stream:error(Condition),
- [?NS_JABBER_CLIENT], [{?NS_XMPP, "stream"}])).
--define(SERR_XML_NOT_WELL_FORMED, ?STREAM_ERROR('xml-not-well-formed')).
--define(SERR_HOST_UNKNOWN, ?STREAM_ERROR('host-unknown')).
--define(SERR_INVALID_NAMESPACE, ?STREAM_ERROR('invalid-namespace')).
-
--define(STREAM_ERRORT(Condition, Lang, Text),
- exmpp_xml:xmlel_to_xmlelement(exmpp_stream:error(Condition, {Lang, Text}),
- [?NS_JABBER_CLIENT], [{?NS_XMPP, "stream"}])).
--define(SERRT_POLICY_VIOLATION(Lang, Text),
- ?STREAM_ERRORT('policy-violation', Lang, Text)).
--define(SERRT_CONFLICT(Lang, Text),
- ?STREAM_ERRORT('conflict', Lang, Text)).
-define(STANZA_ERROR(Condition),
exmpp_xml:xmlel_to_xmlelement(exmpp_stanza:error(Condition),
[?NS_JABBER_CLIENT], [{?NS_XMPP, "stream"}])).
--define(ERR_BAD_REQUEST, ?STANZA_ERROR('bad-request')).
--define(ERR_NOT_ALLOWED, ?STANZA_ERROR('not-allowed')).
--define(ERR_JID_MALFORMED, ?STANZA_ERROR('jid-malformed')).
--define(ERR_NOT_AUTHORIZED, ?STANZA_ERROR('not-authorized')).
-define(ERR_FEATURE_NOT_IMPLEMENTED, ?STANZA_ERROR('feature-not-implemented')).
-define(ERR_SERVICE_UNAVAILABLE, ?STANZA_ERROR('service-unavialable')).
--define(STANZA_ERRORT(Condition, Lang, Text),
- exmpp_xml:xmlel_to_xmlelement(exmpp_stanza:error(Condition, {Lang, Text}),
- [?NS_JABBER_CLIENT], [{?NS_XMPP, "stream"}])).
--define(ERR_AUTH_NO_RESOURCE_PROVIDED(Lang),
- ?STANZA_ERRORT('not-acceptable', Lang, "No resource provided")).
-
-record(iq, {id = "",
type,
xmlns = "",
@@ -285,7 +239,6 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
case lists:member(Server, ?MYHOSTS) of
true ->
Lang = exmpp_stream:get_lang(Opening),
- % OLD FORMAT: JID with empty strings.
change_shaper(StateData,
exmpp_jid:make_bare_jid(undefined, Server)),
case exmpp_stream:get_version(Opening) of
@@ -442,8 +395,10 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{auth, _ID, set, {U, P, D, R}} ->
try
JID = exmpp_jid:make_jid(U, StateData#state.server, R),
+ % XXX OLD FORMAT: JID.
+ JIDOld = exmpp_jid:to_ejabberd_jid(JID),
case acl:match_rule(StateData#state.server,
- StateData#state.access, JID) of
+ StateData#state.access, JIDOld) of
allow ->
case ejabberd_auth:check_password_with_authmodule(
U, StateData#state.server, P,
@@ -467,8 +422,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = {JID#jid.lnode, JID#jid.ldomain,
- undefined},
+ LJID = short_jid(
+ exmpp_jid:jid_to_bare_jid(JID)),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList = ejabberd_hooks:run_fold(
@@ -767,9 +722,11 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
U = StateData#state.user,
R = StateData#state.resource,
JID = StateData#state.jid,
- exmpp_server_session:want_establishment(El),
+ % XXX OLD FORMAT: JID.
+ JIDOld = exmpp_jid:to_ejabberd_jid(JID),
+ true = exmpp_server_session:want_establishment(El),
case acl:match_rule(StateData#state.server,
- StateData#state.access, JID) of
+ StateData#state.access, JIDOld) of
allow ->
?INFO_MSG("(~w) Opened session for ~s",
[StateData#state.socket,
@@ -788,7 +745,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = {JID#jid.lnode, JID#jid.ldomain, undefined},
+ LJID = short_jid(exmpp_jid:jid_to_bare_jid(JID)),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList =
@@ -804,10 +761,9 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
pres_t = ?SETS:from_list(Ts1),
privacy_list = PrivList});
_ ->
- % OLD FORMAT: Jid may use 'undefined' instead of empty
- % strings.
+ % XXX OLD FORMAT: Jid.
ejabberd_hooks:run(forbidden_session_hook,
- StateData#state.server, [JID]),
+ StateData#state.server, [JIDOld]),
?INFO_MSG("(~w) Forbidden session for ~s",
[StateData#state.socket,
exmpp_jid:jid_to_string(JID)]),
@@ -816,7 +772,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
fsm_next_state(wait_for_session, StateData)
end
catch
- throw:_Exception ->
+ _Exception ->
fsm_next_state(wait_for_session, StateData)
end;
@@ -883,12 +839,10 @@ session_established({xmlstreamelement, El}, StateData) ->
resource = undefined} ->
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
[FromJID, PresenceEl, StateData]),
- % XXX OLD FORMAT: PresenceElOld.
- presence_update(FromJIDOld, PresenceElOld,
+ presence_update(FromJID, PresenceEl,
StateData);
_ ->
- % XXX OLD FORMAT: PresenceElOld.
- presence_track(FromJIDOld, ToJIDOld, PresenceElOld,
+ presence_track(FromJID, ToJID, PresenceEl,
StateData)
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
@@ -896,7 +850,7 @@ session_established({xmlstreamelement, El}, StateData) ->
FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
case exmpp_iq:get_payload(El) of
- #xmlel{ns = ?NS_PRIVACY} ->
+ #xmlel{ns = ?NS_JABBER_PRIVACY} ->
% XXX OLD FORMAT: IQ was #iq.
ElOld2 = exmpp_xml:xmlel_to_xmlelement(El,
?DEFAULT_NS, ?PREFIXED_NS),
@@ -1015,23 +969,33 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
User = StateData#state.user,
PresLast = StateData#state.pres_last,
- Show = get_showtag(PresLast),
- Status = get_statustag(PresLast),
+ Show = case PresLast of
+ undefined -> "unavailable";
+ _ -> exmpp_presence:get_show(PresLast)
+ end,
+ Status = case PresLast of
+ undefined -> "";
+ _ -> exmpp_presence:get_status(PresLast)
+ end,
Resource = StateData#state.resource,
- Reply = {User, Resource, Show, Status},
+ Reply = {User, Resource, atom_to_list(Show), Status},
fsm_reply(Reply, StateName, StateData);
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
- % XXX OLD FORMAT: This function needs update. User has the form {N, D, R}.
Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available,
- Pred = fun(User, _Caps) ->
- ?SETS:is_element(jlib:jid_remove_resource(User),
+ Pred = fun({U, S, _R} = User, _Caps) ->
+ ?SETS:is_element({U, S, undefined},
Subscribed) orelse
?SETS:is_element(User, Subscribed)
end,
- SubscribedAndOnline = ?DICT:filter(Pred, Online),
+ % XXX OLD FORMAT: Resource is "".
+ Old = fun({U, S, undefined}, _Caps) -> {U, S, ""};
+ (User, _Caps) -> User
+ end,
+ SubscribedAndOnline = ?DICT:map(Old, ?DICT:filter(Pred, Online)),
+ io:format("===== SubscribedAndOnline = ~p~n", [SubscribedAndOnline]),
{reply, ?DICT:to_list(SubscribedAndOnline), StateName, StateData};
handle_sync_event(_Event, _From, StateName, StateData) ->
@@ -1081,7 +1045,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
case ?SETS:is_element(
LFrom, StateData#state.pres_f) of
true ->
- % XXX OLD FORMAT: Stores old short
+ % XXX OLD FORMAT: Stores short
% JIDs.
A = ?SETS:add_element(
LFrom,
@@ -1092,7 +1056,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
LBFrom, StateData#state.pres_f) of
true ->
% XXX OLD FORMAT: Stores
- % old short JIDs.
+ % short JIDs.
A = ?SETS:add_element(
LBFrom,
StateData#state.pres_a),
@@ -1102,8 +1066,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
end
end
end,
- % XXX OLD FORMAT: FromOld and ToOld
- process_presence_probe(FromOld, ToOld, NewStateData),
+ process_presence_probe(From, To, NewStateData),
{false, Attrs, NewStateData};
'error' ->
% XXX OLD FORMAT: LFrom.
@@ -1191,8 +1154,9 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
Els = PacketOld#xmlelement.children,
?DEBUG("broadcast~n~p~n", [Els]),
case Els of
- [{item, IJID, ISubscription}] ->
- % XXX OLD FORMAT: IJID is an old #jid.
+ [{item, {U, S, R} = _IJIDShort, ISubscription}] ->
+ % XXX OLD FORMAT: IJID is of the form {U, S, R}.
+ IJID = exmpp_jid:make_jid(U, S, R),
{false, Attrs,
roster_change(IJID, ISubscription,
StateData)};
@@ -1287,7 +1251,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
end,
if
Pass == exit ->
- catch send_text(StateData, ?STREAM_TRAILER),
+ catch send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
Pass ->
Attrs2 = exmpp_stanza:set_sender_in_attrs(NewAttrs, From),
@@ -1338,14 +1302,10 @@ terminate(_Reason, StateName, StateData) ->
StateData#state.server,
StateData#state.resource,
"Replaced by new connection"),
- % XXX OLD FORMAT: From, Packet1
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- Packet1Old = exmpp_xml:xmlel_to_xmlelement(Packet1,
- ?DEFAULT_NS, ?PREFIXED_NS),
presence_broadcast(
- StateData, FromOld, StateData#state.pres_a, Packet1Old),
+ StateData, From, StateData#state.pres_a, Packet1),
presence_broadcast(
- StateData, FromOld, StateData#state.pres_i, Packet1Old);
+ StateData, From, StateData#state.pres_i, Packet1);
_ ->
?INFO_MSG("(~w) Close session for ~s",
[StateData#state.socket,
@@ -1364,10 +1324,6 @@ terminate(_Reason, StateName, StateData) ->
_ ->
From = StateData#state.jid,
Packet = exmpp_presence:unavailable(),
- % XXX OLD FORMAT: From, Packet.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- ?DEFAULT_NS, ?PREFIXED_NS),
ejabberd_sm:close_session_unset_presence(
StateData#state.sid,
StateData#state.user,
@@ -1375,9 +1331,9 @@ terminate(_Reason, StateName, StateData) ->
StateData#state.resource,
""),
presence_broadcast(
- StateData, FromOld, StateData#state.pres_a, PacketOld),
+ StateData, From, StateData#state.pres_a, Packet),
presence_broadcast(
- StateData, FromOld, StateData#state.pres_i, PacketOld)
+ StateData, From, StateData#state.pres_i, Packet)
end
end;
_ ->
@@ -1391,8 +1347,10 @@ terminate(_Reason, StateName, StateData) ->
%%%----------------------------------------------------------------------
change_shaper(StateData, JID) ->
+ % XXX OLD FORMAT: JIDOld is an old #jid.
+ JIDOld = exmpp_jid:to_ejabberd_jid(JID),
Shaper = acl:match_rule(StateData#state.server,
- StateData#state.shaper, JID),
+ StateData#state.shaper, JIDOld),
(StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
send_text(StateData, Text) ->
@@ -1408,7 +1366,10 @@ new_id() ->
is_auth_packet(El) ->
- case jlib:iq_query_info(El) of
+ % XXX OLD FORMAT: El.
+ ElOld = exmpp_xml:xmlel_to_xmlelement(El,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ case jlib:iq_query_info(ElOld) of
#iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} ->
{xmlelement, _, _, Els} = SubEl,
{auth, ID, Type,
@@ -1448,8 +1409,8 @@ get_conn_type(StateData) ->
end.
process_presence_probe(From, To, StateData) ->
- LFrom = jlib:jid_tolower(From),
- LBFrom = setelement(3, LFrom, ""),
+ LFrom = short_jid(From),
+ LBFrom = short_jid(exmpp_jid:jid_to_bare_jid(From)),
case StateData#state.pres_last of
undefined ->
ok;
@@ -1470,47 +1431,54 @@ process_presence_probe(From, To, StateData) ->
if
Cond1 ->
Packet = StateData#state.pres_last,
+ % XXX OLD FORMAT: From, To, Packet.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ ?DEFAULT_NS, ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {To, From, Packet},
+ {ToOld, FromOld, PacketOld},
out]) of
deny ->
ok;
allow ->
Pid=element(2, StateData#state.sid),
- ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [From, To, Pid]),
+ % XXX OLD FORMAT: From, To.
+ ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [FromOld, ToOld, Pid]),
%% Don't route a presence probe to oneself
case From == To of
false ->
- ejabberd_router:route(To, From, Packet);
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(ToOld, FromOld, PacketOld);
true ->
ok
end
end;
Cond2 ->
- ejabberd_router:route(To, From,
- {xmlelement, "presence",
- [],
- []});
+ Packet = exmpp_presence:available(),
+ % XXX OLD FORMAT: From, To, Packet.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ ejabberd_router:route(ToOld, FromOld, PacketOld);
true ->
ok
end
end.
presence_update(From, Packet, StateData) ->
- {xmlelement, _Name, Attrs, _Els} = Packet,
- case xml:get_attr_s("type", Attrs) of
- "unavailable" ->
- Status = case xml:get_subtag(Packet, "status") of
- false ->
- "";
- StatusTag ->
- xml:get_tag_cdata(StatusTag)
- end,
+ case exmpp_presence:get_type(Packet) of
+ 'unavailable' ->
+ Status = case exmpp_presence:get_status(Packet) of
+ undefined -> "";
+ S -> S
+ end,
Info = [{ip, StateData#state.ip},{conn, StateData#state.conn}],
ejabberd_sm:unset_presence(StateData#state.sid,
StateData#state.user,
@@ -1524,8 +1492,12 @@ presence_update(From, Packet, StateData) ->
pres_a = ?SETS:new(),
pres_i = ?SETS:new(),
pres_invis = false};
- "invisible" ->
- NewPriority = get_priority_from_presence(Packet),
+ 'invisible' ->
+ NewPriority = try
+ exmpp_presence:get_priority(Packet)
+ catch
+ _Exception -> 0
+ end,
update_priority(NewPriority, Packet, StateData),
NewState =
if
@@ -1545,26 +1517,34 @@ presence_update(From, Packet, StateData) ->
StateData
end,
NewState;
- "error" ->
+ 'error' ->
StateData;
- "probe" ->
+ 'probe' ->
StateData;
- "subscribe" ->
+ 'subscribe' ->
StateData;
- "subscribed" ->
+ 'subscribed' ->
StateData;
- "unsubscribe" ->
+ 'unsubscribe' ->
StateData;
- "unsubscribed" ->
+ 'unsubscribed' ->
StateData;
_ ->
OldPriority = case StateData#state.pres_last of
undefined ->
0;
OldPresence ->
- get_priority_from_presence(OldPresence)
+ try
+ exmpp_presence:get_priority(OldPresence)
+ catch
+ _Exception -> 0
+ end
end,
- NewPriority = get_priority_from_presence(Packet),
+ NewPriority = try
+ exmpp_presence:get_priority(Packet)
+ catch
+ _Exception1 -> 0
+ end,
update_priority(NewPriority, Packet, StateData),
FromUnavail = (StateData#state.pres_last == undefined) or
StateData#state.pres_invis,
@@ -1572,9 +1552,11 @@ presence_update(From, Packet, StateData) ->
NewState =
if
FromUnavail ->
+ % XXX OLD FORMAT: JID.
+ JIDOld = exmpp_jid:to_ejabberd_jid(StateData#state.jid),
ejabberd_hooks:run(user_available_hook,
StateData#state.server,
- [StateData#state.jid]),
+ [JIDOld]),
if NewPriority >= 0 ->
resend_offline_messages(StateData),
resend_subscription_requests(StateData);
@@ -1604,66 +1586,85 @@ presence_update(From, Packet, StateData) ->
end.
presence_track(From, To, Packet, StateData) ->
- {xmlelement, _Name, Attrs, _Els} = Packet,
- LTo = jlib:jid_tolower(To),
+ LTo = short_jid(To),
User = StateData#state.user,
Server = StateData#state.server,
- case xml:get_attr_s("type", Attrs) of
- "unavailable" ->
- ejabberd_router:route(From, To, Packet),
+ % XXX OLD FORMAT: From, To, Packet.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ BFromOld = exmpp_jid:to_ejabberd_jid(exmpp_jid:jid_to_bare_jid(From)),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ case exmpp_presence:get_type(Packet) of
+ 'unavailable' ->
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(FromOld, ToOld, PacketOld),
I = remove_element(LTo, StateData#state.pres_i),
A = remove_element(LTo, StateData#state.pres_a),
StateData#state{pres_i = I,
pres_a = A};
- "invisible" ->
- ejabberd_router:route(From, To, Packet),
+ 'invisible' ->
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(FromOld, ToOld, PacketOld),
I = ?SETS:add_element(LTo, StateData#state.pres_i),
A = remove_element(LTo, StateData#state.pres_a),
StateData#state{pres_i = I,
pres_a = A};
- "subscribe" ->
+ 'subscribe' ->
+ % XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
- [User, Server, To, subscribe]),
- ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
+ [User, Server, ToOld, subscribe]),
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(BFromOld, ToOld, PacketOld),
StateData;
- "subscribed" ->
+ 'subscribed' ->
+ % XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
- [User, Server, To, subscribed]),
- ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
+ [User, Server, ToOld, subscribed]),
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(BFromOld, ToOld, PacketOld),
StateData;
- "unsubscribe" ->
+ 'unsubscribe' ->
+ % XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
- [User, Server, To, unsubscribe]),
- ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
+ [User, Server, ToOld, unsubscribe]),
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(BFromOld, ToOld, PacketOld),
StateData;
- "unsubscribed" ->
+ 'unsubscribed' ->
+ % XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
- [User, Server, To, unsubscribed]),
- ejabberd_router:route(jlib:jid_remove_resource(From), To, Packet),
+ [User, Server, ToOld, unsubscribed]),
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(BFromOld, ToOld, PacketOld),
StateData;
- "error" ->
- ejabberd_router:route(From, To, Packet),
+ 'error' ->
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(FromOld, ToOld, PacketOld),
StateData;
- "probe" ->
- ejabberd_router:route(From, To, Packet),
+ 'probe' ->
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(FromOld, ToOld, PacketOld),
StateData;
_ ->
+ % XXX OLD FORMAT: From, To, Packet.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {From, To, Packet},
+ {FromOld, ToOld, PacketOld},
out]) of
deny ->
ok;
allow ->
- ejabberd_router:route(From, To, Packet)
+ % XXX OLD FORMAT: From, To, Packet.
+ ejabberd_router:route(FromOld, ToOld, PacketOld)
end,
I = remove_element(LTo, StateData#state.pres_i),
A = ?SETS:add_element(LTo, StateData#state.pres_a),
@@ -1672,41 +1673,54 @@ presence_track(From, To, Packet, StateData) ->
end.
presence_broadcast(StateData, From, JIDSet, Packet) ->
- lists:foreach(fun(JID) ->
- FJID = jlib:make_jid(JID),
+ lists:foreach(fun({U, S, R}) ->
+ FJID = exmpp_jid:make_jid(U, S, R),
+ % XXX OLD FORMAT: From, FJID, Packet.
+ FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ ?DEFAULT_NS, ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {From, FJID, Packet},
+ {FromOld, FJIDOld, PacketOld},
out]) of
deny ->
ok;
allow ->
- ejabberd_router:route(From, FJID, Packet)
+ % XXX OLD FORMAT: From, FJID, Packet.
+ ejabberd_router:route(FromOld, FJIDOld, PacketOld)
end
end, ?SETS:to_list(JIDSet)).
presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
+ % XXX OLD FORMAT: From, Packet.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ ?DEFAULT_NS, ?PREFIXED_NS),
lists:foreach(
- fun(JID) ->
+ fun({U, S, R} = JID) ->
case ?SETS:is_element(JID, T) of
true ->
- FJID = jlib:make_jid(JID),
+ FJID = exmpp_jid:make_jid(U, S, R),
+ % XXX OLD FORMAT: FJID.
+ FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {From, FJID, Packet},
+ {FromOld, FJIDOld, PacketOld},
out]) of
deny ->
ok;
allow ->
- ejabberd_router:route(From, FJID, Packet)
+ % XXX OLD FORMAT: From, FJID, Packet.
+ ejabberd_router:route(FromOld, FJIDOld, PacketOld)
end;
_ ->
ok
@@ -1715,13 +1729,21 @@ presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
presence_broadcast_first(From, StateData, Packet) ->
- ?SETS:fold(fun(JID, X) ->
+ Probe = exmpp_presence:probe(),
+ % XXX OLD FORMAT: From, Packet, Probe.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ ProbeOld = exmpp_xml:xmlel_to_xmlelement(Probe,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ ?SETS:fold(fun({U, S, R}, X) ->
+ FJID = exmpp_jid:make_jid(U, S, R),
+ % XXX OLD FORMAT: FJID.
+ FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
ejabberd_router:route(
- From,
- jlib:make_jid(JID),
- {xmlelement, "presence",
- [{"type", "probe"}],
- []}),
+ FromOld,
+ FJIDOld,
+ ProbeOld),
X
end,
[],
@@ -1731,20 +1753,22 @@ presence_broadcast_first(From, StateData, Packet) ->
StateData;
true ->
As = ?SETS:fold(
- fun(JID, A) ->
- FJID = jlib:make_jid(JID),
+ fun({U, S, R} = JID, A) ->
+ FJID = exmpp_jid:make_jid(U, S, R),
+ % XXX OLD FORMAT: FJID.
+ FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {From, FJID, Packet},
+ {FromOld, FJIDOld, PacketOld},
out]) of
deny ->
ok;
allow ->
- ejabberd_router:route(From, FJID, Packet)
+ ejabberd_router:route(FromOld, FJIDOld, PacketOld)
end,
?SETS:add_element(JID, A)
end,
@@ -1764,7 +1788,7 @@ remove_element(E, Set) ->
roster_change(IJID, ISubscription, StateData) ->
- LIJID = jlib:jid_tolower(IJID),
+ LIJID = short_jid(IJID),
IsFrom = (ISubscription == both) or (ISubscription == from),
IsTo = (ISubscription == both) or (ISubscription == to),
OldIsFrom = ?SETS:is_element(LIJID, StateData#state.pres_f),
@@ -1786,7 +1810,10 @@ roster_change(IJID, ISubscription, StateData) ->
P ->
?DEBUG("roster changed for ~p~n", [StateData#state.user]),
From = StateData#state.jid,
- To = jlib:make_jid(IJID),
+ To = IJID,
+ % XXX OLD FORMAT: From, To.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
Cond1 = (not StateData#state.pres_invis) and IsFrom
and (not OldIsFrom),
Cond2 = (not IsFrom) and OldIsFrom
@@ -1795,18 +1822,23 @@ roster_change(IJID, ISubscription, StateData) ->
if
Cond1 ->
?DEBUG("C1: ~p~n", [LIJID]),
+ % XXX OLD FORMAT: P.
+ POld = exmpp_xml:xmlelement_to_xmlel(P,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ % XXX OLD FORMAT: From, To, P.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {From, To, P},
+ {FromOld, ToOld, POld},
out]) of
deny ->
ok;
allow ->
- ejabberd_router:route(From, To, P)
+ % XXX OLD FORMAT: From, To, P.
+ ejabberd_router:route(FromOld, ToOld, POld)
end,
A = ?SETS:add_element(LIJID,
StateData#state.pres_a),
@@ -1815,20 +1847,24 @@ roster_change(IJID, ISubscription, StateData) ->
pres_t = TSet};
Cond2 ->
?DEBUG("C2: ~p~n", [LIJID]),
- PU = {xmlelement, "presence",
- [{"type", "unavailable"}], []},
+ PU = exmpp_presence:unavailable(),
+ % XXX OLD FORMAT: PU.
+ PUOld = exmpp_xml:xmlelement_to_xmlel(PU,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ % XXX OLD FORMAT: From, To, PU.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {From, To, PU},
+ {FromOld, ToOld, PUOld},
out]) of
deny ->
ok;
allow ->
- ejabberd_router:route(From, To, PU)
+ % XXX OLD FORMAT: From, To, PU.
+ ejabberd_router:route(FromOld, ToOld, PUOld)
end,
I = remove_element(LIJID,
StateData#state.pres_i),
@@ -1846,27 +1882,17 @@ roster_change(IJID, ISubscription, StateData) ->
update_priority(Priority, Packet, StateData) ->
Info = [{ip, StateData#state.ip},{conn, StateData#state.conn}],
+ % XXX OLD FORMAT: Packet.
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ ?DEFAULT_NS, ?PREFIXED_NS),
ejabberd_sm:set_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
StateData#state.resource,
Priority,
- Packet,
+ PacketOld,
Info).
-get_priority_from_presence(PresencePacket) ->
- case xml:get_subtag(PresencePacket, "priority") of
- false ->
- 0;
- SubEl ->
- case catch list_to_integer(xml:get_tag_cdata(SubEl)) of
- P when is_integer(P) ->
- P;
- _ ->
- 0
- end
- end.
-
process_privacy_iq(From, To,
#iq{type = Type, sub_el = SubEl} = IQ,
StateData) ->
@@ -1952,21 +1978,6 @@ resend_subscription_requests(#state{user = User,
end,
PendingSubscriptions).
-get_showtag(undefined) ->
- "unavailable";
-get_showtag(Presence) ->
- case xml:get_path_s(Presence, [{elem, "show"}, cdata]) of
- "" -> "available";
- ShowTag -> ShowTag
- end.
-
-get_statustag(undefined) ->
- "";
-get_statustag(Presence) ->
- case xml:get_path_s(Presence, [{elem, "status"}, cdata]) of
- ShowTag -> ShowTag
- end.
-
process_unauthenticated_stanza(StateData, El) ->
case jlib:iq_query_info(El) of
#iq{} = IQ ->
@@ -2022,5 +2033,6 @@ fsm_reply(Reply, StateName, StateData) ->
is_ip_blacklisted({IP,_Port}) ->
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]).
-short_jid(JID) ->
+short_jid(JID0) ->
+ JID = exmpp_jid:to_ejabberd_jid(JID0),
{JID#jid.lnode, JID#jid.ldomain, JID#jid.lresource}.
From 07651d712ffc95f6a40ec3fcaa2f9f15f85c68a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 25 Jun 2008 12:37:45 +0000
Subject: [PATCH 012/582] Finish ejabberd_c2s conversion with the functions
related to offline stanzas.
SVN Revision: 1380
---
ChangeLog | 5 +++
src/ejabberd_c2s.erl | 88 ++++++++++++++++++++++++++++----------------
2 files changed, 61 insertions(+), 32 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e314e31e5..9790c3f08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-25 Jean-Sébastien Pédron
+
+ * src/ejabberd_c2s.erl: Finish ejabberd_c2s conversion with the
+ functions related to offline stanzas.
+
2008-06-24 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl: The handle_info clause that treats routing
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 060fdadd1..1f87d2a25 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -851,12 +851,8 @@ session_established({xmlstreamelement, El}, StateData) ->
ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
case exmpp_iq:get_payload(El) of
#xmlel{ns = ?NS_JABBER_PRIVACY} ->
- % XXX OLD FORMAT: IQ was #iq.
- ElOld2 = exmpp_xml:xmlel_to_xmlelement(El,
- ?DEFAULT_NS, ?PREFIXED_NS),
- IQ = jlib:iq_query_info(ElOld2),
process_privacy_iq(
- FromJIDOld, ToJIDOld, IQ, StateData);
+ FromJID, ToJID, El, StateData);
_ ->
% XXX OLD FORMAT: NewElOld.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
@@ -1894,21 +1890,28 @@ update_priority(Priority, Packet, StateData) ->
Info).
process_privacy_iq(From, To,
- #iq{type = Type, sub_el = SubEl} = IQ,
+ El,
StateData) ->
+ % XXX OLD FORMAT: IQ is #iq.
+ ElOld = exmpp_xml:xmlel_to_xmlelement(El,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ IQOld = jlib:iq_query_info(ElOld),
+ % XXX OLD FORMAT: JIDs.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
{Res, NewStateData} =
- case Type of
+ case exmpp_iq:get_type(El) of
get ->
R = ejabberd_hooks:run_fold(
privacy_iq_get, StateData#state.server,
{error, ?ERR_FEATURE_NOT_IMPLEMENTED},
- [From, To, IQ, StateData#state.privacy_list]),
+ [FromOld, ToOld, IQOld, StateData#state.privacy_list]),
{R, StateData};
set ->
case ejabberd_hooks:run_fold(
privacy_iq_set, StateData#state.server,
{error, ?ERR_FEATURE_NOT_IMPLEMENTED},
- [From, To, IQ]) of
+ [FromOld, ToOld, IQOld]) of
{result, R, NewPrivList} ->
{{result, R},
StateData#state{privacy_list = NewPrivList}};
@@ -1917,13 +1920,20 @@ process_privacy_iq(From, To,
end,
IQRes =
case Res of
- {result, Result} ->
- IQ#iq{type = result, sub_el = Result};
- {error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
+ {result, ResultOld} ->
+ Result = exmpp_xml:xmlelement_to_xmlel(ResultOld,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ exmpp_iq:result(El, Result);
+ {error, ErrorOld} ->
+ Error = exmpp_xml:xmlelement_to_xmlel(ErrorOld,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ exmpp_iq:error(El, Error)
end,
+ % XXX OLD FORMAT: To, From, IQRes.
+ IQResOld = exmpp_xml:xmlel_to_xmlelement(IQRes,
+ ?DEFAULT_NS, ?PREFIXED_NS),
ejabberd_router:route(
- To, From, jlib:iq_to_xml(IQRes)),
+ ToOld, FromOld, IQResOld),
NewStateData.
@@ -1935,16 +1945,18 @@ resend_offline_messages(#state{user = User,
[],
[User, Server]) of
Rs when list(Rs) ->
+ % XXX OLD FORMAT: From, To, Packet.
+ % XXX OLD FORMAT ON DISK!
lists:foreach(
fun({route,
- From, To, {xmlelement, Name, Attrs, Els} = Packet}) ->
+ FromOld, ToOld, PacketOld}) ->
Pass = case ejabberd_hooks:run_fold(
privacy_check_packet, Server,
allow,
[User,
Server,
PrivList,
- {From, To, Packet},
+ {FromOld, ToOld, PacketOld},
in]) of
allow ->
true;
@@ -1953,12 +1965,17 @@ resend_offline_messages(#state{user = User,
end,
if
Pass ->
- Attrs2 = jlib:replace_from_to_attrs(
- jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
+ % XXX OLD FORMAT: From, To, Packet.
+ From = exmpp_jid:from_ejabberd_jid(FromOld),
+ To = exmpp_jid:from_ejabberd_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ ?DEFAULT_NS, ?PREFIXED_NS),
+ Attrs1 = exmpp_stanza:set_sender_in_attrs(
+ Packet#xmlel.attrs, From),
+ Attrs2 = exmpp_stanza:set_recipient_in_attrs(
+ Attrs1, To),
send_element(StateData,
- {xmlelement, Name, Attrs2, Els});
+ Packet#xmlel{attrs = Attrs2});
true ->
ok
end
@@ -1972,32 +1989,39 @@ resend_subscription_requests(#state{user = User,
Server,
[],
[User, Server]),
- lists:foreach(fun(XMLPacket) ->
+ % XXX OLD FORMAT: XMLPacket.
+ % XXX OLD FORMAT ON DISK!
+ lists:foreach(fun(XMLPacketOld) ->
+ XMLPacket = exmpp_xml:xmlelement_to_xmlel(
+ XMLPacketOld, ?DEFAULT_NS, ?PREFIXED_NS),
send_element(StateData,
XMLPacket)
end,
PendingSubscriptions).
process_unauthenticated_stanza(StateData, El) ->
- case jlib:iq_query_info(El) of
+ ElOld = exmpp_xml:xmlel_to_xmlelement(El, ?DEFAULT_NS, ?PREFIXED_NS),
+ case jlib:iq_query_info(ElOld) of
#iq{} = IQ ->
- Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
+ ResOld = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
StateData#state.server,
empty,
[StateData#state.server, IQ,
StateData#state.ip]),
- case Res of
+ case ResOld of
empty ->
% The only reasonable IQ's here are auth and register IQ's
% They contain secrets, so don't include subelements to response
- ResIQ = IQ#iq{type = error,
- sub_el = [?ERR_SERVICE_UNAVAILABLE]},
- Res1 = jlib:replace_from_to(
- jlib:make_jid("", StateData#state.server, ""),
- jlib:make_jid("", "", ""),
- jlib:iq_to_xml(ResIQ)),
- send_element(StateData, jlib:remove_attr("to", Res1));
+ ResIQ = exmpp_iq:error_without_original(El,
+ exmpp_stanza:error(El#xmlel.ns, 'service-unavailable')),
+ Res1 = exmpp_stanza:set_sender(ResIQ,
+ exmpp_jid:make_bare_jid(undefined,
+ StateData#state.server)),
+ Res2 = exmpp_stanza:remove_recipient(Res1),
+ send_element(StateData, Res2);
_ ->
+ Res = exmpp_xml:xmlelement_to_xmlel(ResOld,
+ ?DEFAULT_NS, ?PREFIXED_NS),
send_element(StateData, Res)
end;
_ ->
From 999f3233bbcaa5a82c3bfeec2f54f6a3b630c366 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 25 Jun 2008 13:27:03 +0000
Subject: [PATCH 013/582] Fix short JID comparison in
get_subscribed_and_online; it was using 'undefined' instead of empty strings.
SVN Revision: 1381
---
ChangeLog | 3 +++
src/ejabberd_c2s.erl | 9 +++------
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 9790c3f08..e49553877 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,9 @@
* src/ejabberd_c2s.erl: Finish ejabberd_c2s conversion with the
functions related to offline stanzas.
+ * src/ejabberd_c2s.erl (get_subscribed_and_online): Fix short JID
+ comparison; it was using 'undefined' instead of empty strings.
+
2008-06-24 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl: The handle_info clause that treats routing
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 1f87d2a25..c847506be 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -981,16 +981,13 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available,
+ % XXX OLF FORMAT: short JID with empty string(s).
Pred = fun({U, S, _R} = User, _Caps) ->
- ?SETS:is_element({U, S, undefined},
+ ?SETS:is_element({U, S, ""},
Subscribed) orelse
?SETS:is_element(User, Subscribed)
end,
- % XXX OLD FORMAT: Resource is "".
- Old = fun({U, S, undefined}, _Caps) -> {U, S, ""};
- (User, _Caps) -> User
- end,
- SubscribedAndOnline = ?DICT:map(Old, ?DICT:filter(Pred, Online)),
+ SubscribedAndOnline = ?DICT:filter(Pred, Online),
io:format("===== SubscribedAndOnline = ~p~n", [SubscribedAndOnline]),
{reply, ?DICT:to_list(SubscribedAndOnline), StateName, StateData};
From 1a311a30b5ebd1153367d59f379f73bda8387db7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Thu, 26 Jun 2008 15:47:21 +0000
Subject: [PATCH 014/582] o Use a macro in ?DEFAULT_NS instead of the
namespace atom directly. o Comment DBGFSM our again. o Remove macro
ERR_SERVICE_UNAVAILABLE. o In wait_for_auth and is_auth_packet, an empty
resource is returned as 'undefined', not the empty string in the {auth, ...}
tuple. o In handle_sync_event, remove a debugging printf. o In
handle_info({route, ...}), use macro IS_PRESENCE & friends instead of direct
matching with NS_JABBER_CLIENT and name. This way, the S2S doesn't have to
change the namespace of all its incoming stanzas to NS_JABBER_CLIENT. o In
send_element, for stanzas under the NS_JABBER_SERVER namespace, lie to
exmpp_xml by telling it that this namespace is the default one.
SVN Revision: 1382
---
ChangeLog | 15 +++++++++++++++
src/ejabberd_c2s.erl | 30 +++++++++++++++++-------------
2 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e49553877..f42d06a56 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2008-06-26 Jean-Sébastien Pédron
+
+ * src/ejabberd_c2s.erl: Use a macro in ?DEFAULT_NS instead of the
+ namespace atom directly. Comment DBGFSM our again. Remove macro
+ ERR_SERVICE_UNAVAILABLE.
+ (wait_for_auth, is_auth_packet): An empty resource is returned as
+ 'undefined', not the empty string in the {auth, ...} tuple.
+ (handle_sync_event): Remove a debugging printf.
+ (handle_info/{route, ...}): Use macro IS_PRESENCE & friends instead of
+ direct matching with NS_JABBER_CLIENT and name. This way, the S2S
+ doesn't have to change the namespace of all its incoming stanzas to
+ NS_JABBER_CLIENT.
+ (send_element): For stanzas under the NS_JABBER_SERVER namespace, lie
+ to exmpp_xml by telling it that this namespace is the default one.
+
2008-06-25 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl: Finish ejabberd_c2s conversion with the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index c847506be..38aae6e8b 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -94,11 +94,11 @@
%-define(DBGFSM, true).
-%-ifdef(DBGFSM).
+-ifdef(DBGFSM).
-define(FSMOPTS, [{debug, [trace]}]).
-%-else.
-%-define(FSMOPTS, []).
-%-endif.
+-else.
+-define(FSMOPTS, []).
+-endif.
%% Module start with or without supervisor:
-ifdef(NO_TRANSIENT_SUPERVISORS).
@@ -116,7 +116,7 @@
% These are the namespace already declared by the stream opening. This is
% used at serialization time.
--define(DEFAULT_NS, ['jabber:client']).
+-define(DEFAULT_NS, [?NS_JABBER_CLIENT]).
-define(PREFIXED_NS, [{?NS_XMPP, "stream"}]).
% XXX OLD FORMAT
@@ -126,7 +126,6 @@
exmpp_xml:xmlel_to_xmlelement(exmpp_stanza:error(Condition),
[?NS_JABBER_CLIENT], [{?NS_XMPP, "stream"}])).
-define(ERR_FEATURE_NOT_IMPLEMENTED, ?STANZA_ERROR('feature-not-implemented')).
--define(ERR_SERVICE_UNAVAILABLE, ?STANZA_ERROR('service-unavialable')).
-record(iq, {id = "",
type,
@@ -387,7 +386,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
send_element(StateData,
exmpp_server_legacy_auth:fields(El, Fields)),
fsm_next_state(wait_for_auth, StateData);
- {auth, _ID, set, {_U, _P, _D, ""}} ->
+ {auth, _ID, set, {_U, _P, _D, undefined}} ->
Err = exmpp_stanza:error('not-acceptable',
{"en", "No resource provided"}),
send_element(StateData, exmpp_iq:error(El, Err)),
@@ -988,7 +987,6 @@ handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
?SETS:is_element(User, Subscribed)
end,
SubscribedAndOnline = ?DICT:filter(Pred, Online),
- io:format("===== SubscribedAndOnline = ~p~n", [SubscribedAndOnline]),
{reply, ?DICT:to_list(SubscribedAndOnline), StateName, StateData};
handle_sync_event(_Event, _From, StateName, StateData) ->
@@ -1021,7 +1019,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
To = exmpp_jid:from_ejabberd_jid(ToOld),
{Pass, NewAttrs, NewState} =
case Packet of
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence', attrs = Attrs} ->
+ #xmlel{attrs = Attrs} when ?IS_PRESENCE(Packet) ->
case exmpp_presence:get_type(Packet) of
'probe' ->
% XXX OLD FORMAT: LFrom and LBFrom.
@@ -1172,7 +1170,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
_ ->
{false, Attrs, StateData}
end;
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq', attrs = Attrs} ->
+ #xmlel{attrs = Attrs} when ?IS_IQ(Packet) ->
case exmpp_iq:is_request(Packet) of
true ->
case exmpp_iq:get_request(Packet) of
@@ -1224,7 +1222,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
false ->
{true, Attrs, StateData}
end;
- #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', attrs = Attrs} ->
+ #xmlel{attrs = Attrs} when ?IS_MESSAGE(Packet) ->
% XXX OLD FORMAT: From, To and Packet.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
@@ -1350,8 +1348,14 @@ send_text(StateData, Text) ->
?DEBUG("Send XML on stream = ~p", [lists:flatten(Text)]),
(StateData#state.sockmod):send(StateData#state.socket, Text).
+send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
+ send_text(StateData, exmpp_xml:document_to_list(El));
+send_element(StateData, #xmlel{ns = ?NS_JABBER_SERVER} = El) ->
+ send_text(StateData, exmpp_xml:document_fragment_to_list(El,
+ [?NS_JABBER_SERVER], ?PREFIXED_NS));
send_element(StateData, El) ->
- send_text(StateData, xml:element_to_string(El)).
+ send_text(StateData, exmpp_xml:document_fragment_to_list(El,
+ ?DEFAULT_NS, ?PREFIXED_NS)).
new_id() ->
@@ -1366,7 +1370,7 @@ is_auth_packet(El) ->
#iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} ->
{xmlelement, _, _, Els} = SubEl,
{auth, ID, Type,
- get_auth_tags(Els, "", "", "", "")};
+ get_auth_tags(Els, "", "", "", undefined)};
_ ->
false
end.
From 22e79490fffbc7d62d42774d5ba4c8a2e2ca2918 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Thu, 26 Jun 2008 15:48:19 +0000
Subject: [PATCH 015/582] Convert to exmpp.
SVN Revision: 1383
---
ChangeLog | 2 +
src/ejabberd_s2s_in.erl | 298 +++++++++++++++----------------
src/ejabberd_s2s_out.erl | 370 ++++++++++++++++++---------------------
3 files changed, 319 insertions(+), 351 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index f42d06a56..0851fcd71 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,8 @@
(send_element): For stanzas under the NS_JABBER_SERVER namespace, lie
to exmpp_xml by telling it that this namespace is the default one.
+ * src/ejabberd_s2s_in.erl, src/ejabberd_s2s_out.erl: Convert to exmpp.
+
2008-06-25 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl: Finish ejabberd_c2s conversion with the
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 9827775d2..31ae9454e 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -46,8 +46,9 @@
handle_info/3,
terminate/3]).
+ -include("exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-ifdef(SSL39).
-include_lib("ssl/include/ssl_pkix.hrl").
-define(PKIXEXPLICIT, 'OTP-PKIX').
@@ -92,28 +93,10 @@
[SockData, Opts])).
-endif.
--define(STREAM_HEADER(Version),
- (""
- "")
- ).
-
--define(STREAM_TRAILER, "").
-
--define(INVALID_NAMESPACE_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
-
--define(HOST_UNKNOWN_ERR,
- xml:element_to_string(?SERR_HOST_UNKNOWN)).
-
--define(INVALID_FROM_ERR,
- xml:element_to_string(?SERR_INVALID_FROM)).
-
--define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, [?NS_JABBER_SERVER]).
+-define(PREFIXED_NS, [{?NS_XMPP, "stream"}, {?NS_JABBER_DIALBACK, "db"}]).
%%%----------------------------------------------------------------------
%%% API
@@ -174,13 +157,16 @@ init([{SockMod, Socket}, Opts]) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
-wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
- case {xml:get_attr_s("xmlns", Attrs),
- xml:get_attr_s("xmlns:db", Attrs),
- xml:get_attr_s("version", Attrs) == "1.0"} of
- {"jabber:server", _, true} when
+wait_for_stream({xmlstreamstart, Opening}, StateData) ->
+ case {exmpp_stream:get_default_ns(Opening),
+ exmpp_xml:is_ns_declared_here(Opening, ?NS_JABBER_DIALBACK),
+ exmpp_stream:get_version(Opening) == {1, 0}} of
+ {?NS_JABBER_SERVER, _, true} when
StateData#state.tls and (not StateData#state.authenticated) ->
- send_text(StateData, ?STREAM_HEADER(" version='1.0'")),
+ Opening_Reply = exmpp_stream:opening_reply(Opening,
+ StateData#state.streamid),
+ send_element(StateData,
+ exmpp_stream:set_dialback_support(Opening_Reply)),
SASL =
if
StateData#state.tls_enabled ->
@@ -190,10 +176,8 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
case (StateData#state.sockmod):get_verify_result(
StateData#state.socket) of
0 ->
- [{xmlelement, "mechanisms",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, "mechanism", [],
- [{xmlcdata, "EXTERNAL"}]}]}];
+ [exmpp_server_sasl:feature(
+ ["EXTERNAL"])];
_ ->
[]
end;
@@ -207,30 +191,35 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
StateData#state.tls_enabled ->
[];
true ->
- [{xmlelement, "starttls",
- [{"xmlns", ?NS_TLS}], []}]
+ [exmpp_server_tls:feature()]
end,
- send_element(StateData,
- {xmlelement, "stream:features", [],
- SASL ++ StartTLS}),
+ send_element(StateData, exmpp_stream:features(SASL ++ StartTLS)),
{next_state, wait_for_feature_request, StateData};
- {"jabber:server", _, true} when
+ {?NS_JABBER_SERVER, _, true} when
StateData#state.authenticated ->
- send_text(StateData, ?STREAM_HEADER(" version='1.0'")),
+ Opening_Reply = exmpp_stream:opening_reply(Opening,
+ StateData#state.streamid),
send_element(StateData,
- {xmlelement, "stream:features", [], []}),
+ exmpp_stream:set_dialback_support(Opening_Reply)),
+ send_element(StateData, exmpp_stream:features([])),
{next_state, stream_established, StateData};
- {"jabber:server", "jabber:server:dialback", _} ->
- send_text(StateData, ?STREAM_HEADER("")),
+ {?NS_JABBER_SERVER, true, _} ->
+ Opening_Reply = exmpp_stream:opening_reply(Opening,
+ StateData#state.streamid),
+ send_element(StateData,
+ exmpp_stream:set_dialback_support(Opening_Reply)),
{next_state, stream_established, StateData};
_ ->
- send_text(StateData, ?INVALID_NAMESPACE_ERR),
+ send_element(StateData, exmpp_stream:error('invalid-namespace')),
{stop, normal, StateData}
end;
wait_for_stream({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?STREAM_HEADER("") ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ Opening_Reply = exmpp_stream:opening_reply(undefined, ?NS_JABBER_SERVER,
+ "", StateData#state.streamid),
+ send_element(StateData, Opening_Reply),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_stream(timeout, StateData) ->
@@ -241,31 +230,29 @@ wait_for_stream(closed, StateData) ->
wait_for_feature_request({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, Attrs, Els} = El,
TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled,
SockMod = (StateData#state.sockmod):get_sockmod(StateData#state.socket),
- case {xml:get_attr_s("xmlns", Attrs), Name} of
- {?NS_TLS, "starttls"} when TLS == true,
+ case El of
+ #xmlel{ns = ?NS_TLS, name = 'starttls'} when TLS == true,
TLSEnabled == false,
SockMod == gen_tcp ->
?DEBUG("starttls", []),
Socket = StateData#state.socket,
+ Proceed = exmpp_xml:document_fragment_to_list(
+ exmpp_server_tls:proceed(), ?DEFAULT_NS, ?PREFIXED_NS),
TLSOpts = StateData#state.tls_options,
TLSSocket = (StateData#state.sockmod):starttls(
Socket, TLSOpts,
- xml:element_to_string(
- {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []})),
+ Proceed),
{next_state, wait_for_stream,
StateData#state{socket = TLSSocket,
streamid = new_id(),
tls_enabled = true
}};
- {?NS_SASL, "auth"} when TLSEnabled ->
- Mech = xml:get_attr_s("mechanism", Attrs),
- case Mech of
- "EXTERNAL" ->
- Auth = jlib:decode_base64(xml:get_cdata(Els)),
+ #xmlel{ns = ?NS_SASL, name = 'auth'} when TLSEnabled ->
+ case exmpp_server_sasl:next_step(El) of
+ {auth, "EXTERNAL", Auth} ->
AuthDomain = jlib:nameprep(Auth),
AuthRes =
case (StateData#state.sockmod):get_peer_certificate(
@@ -300,8 +287,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
(StateData#state.sockmod):reset_stream(
StateData#state.socket),
send_element(StateData,
- {xmlelement, "success",
- [{"xmlns", ?NS_SASL}], []}),
+ exmpp_server_sasl:success()),
?DEBUG("(~w) Accepted s2s authentication for ~s",
[StateData#state.socket, AuthDomain]),
{next_state, wait_for_stream,
@@ -311,16 +297,14 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
}};
true ->
send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}], []}),
- send_text(StateData, ?STREAM_TRAILER),
+ exmpp_server_sasl:failure()),
+ send_element(StateData,
+ exmpp_stream:closing()),
{stop, normal, StateData}
end;
_ ->
send_element(StateData,
- {xmlelement, "failure",
- [{"xmlns", ?NS_SASL}],
- [{xmlelement, "invalid-mechanism", [], []}]}),
+ exmpp_server_sasl:failure('invalid-mechanism')),
{stop, normal, StateData}
end;
_ ->
@@ -328,11 +312,12 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
end;
wait_for_feature_request({xmlstreamend, _Name}, StateData) ->
- send_text(StateData, ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_feature_request({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_feature_request(closed, StateData) ->
@@ -345,8 +330,8 @@ stream_established({xmlstreamelement, El}, StateData) ->
case is_key_packet(El) of
{key, To, From, Id, Key} ->
?DEBUG("GET KEY: ~p", [{To, From, Id, Key}]),
- LTo = jlib:nameprep(To),
- LFrom = jlib:nameprep(From),
+ LTo = exmpp_stringprep:nameprep(To),
+ LFrom = exmpp_stringprep:nameprep(From),
%% Checks if the from domain is allowed and if the to
%% domain is handled by this server:
case {ejabberd_s2s:allow_host(To, From),
@@ -358,49 +343,56 @@ stream_established({xmlstreamelement, El}, StateData) ->
Key, StateData#state.streamid}),
Conns = ?DICT:store({LFrom, LTo}, wait_for_verification,
StateData#state.connections),
- change_shaper(StateData, LTo, jlib:make_jid("", LFrom, "")),
+ change_shaper(StateData, LTo,
+ exmpp_jid:make_bare_jid(undefined, LFrom)),
{next_state,
stream_established,
StateData#state{connections = Conns,
timer = Timer}};
{_, false} ->
- send_text(StateData, ?HOST_UNKNOWN_ERR),
+ send_element(StateData, exmpp_stream:error('host-unknown')),
{stop, normal, StateData};
{false, _} ->
- send_text(StateData, ?INVALID_FROM_ERR),
+ send_element(StateData, exmpp_stream:error('invalid-from')),
{stop, normal, StateData}
end;
{verify, To, From, Id, Key} ->
?DEBUG("VERIFY KEY: ~p", [{To, From, Id, Key}]),
- LTo = jlib:nameprep(To),
- LFrom = jlib:nameprep(From),
- Type = case ejabberd_s2s:has_key({LTo, LFrom}, Key) of
- true -> "valid";
- _ -> "invalid"
- end,
- %Type = if Key == Key1 -> "valid";
- % true -> "invalid"
- % end,
- send_element(StateData,
- {xmlelement,
- "db:verify",
- [{"from", To},
- {"to", From},
- {"id", Id},
- {"type", Type}],
- []}),
+ LTo = exmpp_stringprep:nameprep(To),
+ LFrom = exmpp_stringprep:nameprep(From),
+ send_element(StateData, exmpp_dialback:verify_response(
+ El, ejabberd_s2s:has_key({LTo, LFrom}, Key))),
{next_state, stream_established, StateData#state{timer = Timer}};
_ ->
- NewEl = jlib:remove_attr("xmlns", El),
- {xmlelement, Name, Attrs, _Els} = NewEl,
- From_s = xml:get_attr_s("from", Attrs),
- From = jlib:string_to_jid(From_s),
- To_s = xml:get_attr_s("to", Attrs),
- To = jlib:string_to_jid(To_s),
+ From = case exmpp_stanza:get_sender(El) of
+ undefined ->
+ error;
+ F ->
+ try
+ exmpp_jid:string_to_jid(F)
+ catch
+ _Exception1 -> error
+ end
+ end,
+ To = case exmpp_stanza:get_recipient(El) of
+ undefined ->
+ error;
+ T ->
+ try
+ exmpp_jid:string_to_jid(T)
+ catch
+ _Exception2 -> error
+ end
+ end,
+ % XXX OLD FORMAT: El.
+ % XXX No namespace conversion (:server <-> :client) is done.
+ % This is handled by C2S and S2S send_element functions.
+ ElOld = exmpp_xml:xmlel_to_xmlelement(El,
+ ?DEFAULT_NS, ?PREFIXED_NS),
if
(To /= error) and (From /= error) ->
- LFrom = From#jid.lserver,
- LTo = To#jid.lserver,
+ LFrom = From#jid.ldomain,
+ LTo = To#jid.ldomain,
if
StateData#state.authenticated ->
case (LFrom == StateData#state.auth_domain)
@@ -409,15 +401,19 @@ stream_established({xmlstreamelement, El}, StateData) ->
LTo,
ejabberd_router:dirty_get_all_domains()) of
true ->
- if ((Name == "iq") or
- (Name == "message") or
- (Name == "presence")) ->
+ Name = El#xmlel.name,
+ if ((Name == 'iq') or
+ (Name == 'message') or
+ (Name == 'presence')) ->
+ % XXX OLD FORMAT: From, To.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
ejabberd_hooks:run(
s2s_receive_packet,
LFrom,
- [From, To, NewEl]),
+ [FromOld, ToOld, ElOld]),
ejabberd_router:route(
- From, To, NewEl);
+ FromOld, ToOld, ElOld);
true ->
error
end;
@@ -428,15 +424,19 @@ stream_established({xmlstreamelement, El}, StateData) ->
case ?DICT:find({LFrom, LTo},
StateData#state.connections) of
{ok, established} ->
- if ((Name == "iq") or
- (Name == "message") or
- (Name == "presence")) ->
+ Name = El#xmlel.name,
+ if ((Name == 'iq') or
+ (Name == 'message') or
+ (Name == 'presence')) ->
+ % XXX OLD FORMAT: From, To.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
ejabberd_hooks:run(
s2s_receive_packet,
LFrom,
- [From, To, NewEl]),
+ [FromOld, ToOld, ElOld]),
ejabberd_router:route(
- From, To, NewEl);
+ FromOld, ToOld, ElOld);
true ->
error
end;
@@ -447,35 +447,24 @@ stream_established({xmlstreamelement, El}, StateData) ->
true ->
error
end,
- ejabberd_hooks:run(s2s_loop_debug, [{xmlstreamelement, El}]),
+ ejabberd_hooks:run(s2s_loop_debug, [{xmlstreamelement, ElOld}]),
{next_state, stream_established, StateData#state{timer = Timer}}
end;
stream_established({valid, From, To}, StateData) ->
- send_element(StateData,
- {xmlelement,
- "db:result",
- [{"from", To},
- {"to", From},
- {"type", "valid"}],
- []}),
- LFrom = jlib:nameprep(From),
- LTo = jlib:nameprep(To),
+ send_element(StateData, exmpp_dialback:validate(From, To)),
+ LFrom = exmpp_stringprep:nameprep(From),
+ LTo = exmpp_stringprep:nameprep(To),
NSD = StateData#state{
connections = ?DICT:store({LFrom, LTo}, established,
StateData#state.connections)},
{next_state, stream_established, NSD};
stream_established({invalid, From, To}, StateData) ->
- send_element(StateData,
- {xmlelement,
- "db:result",
- [{"from", To},
- {"to", From},
- {"type", "invalid"}],
- []}),
- LFrom = jlib:nameprep(From),
- LTo = jlib:nameprep(To),
+ Valid = exmpp_dialback:validate(From, To),
+ send_element(StateData, exmpp_stanza:set_type(Valid, "invalid")),
+ LFrom = exmpp_stringprep:nameprep(From),
+ LTo = exmpp_stringprep:nameprep(To),
NSD = StateData#state{
connections = ?DICT:erase({LFrom, LTo},
StateData#state.connections)},
@@ -485,8 +474,8 @@ stream_established({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
stream_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
stream_established(timeout, StateData) ->
@@ -570,12 +559,21 @@ terminate(Reason, _StateName, StateData) ->
send_text(StateData, Text) ->
(StateData#state.sockmod):send(StateData#state.socket, Text).
+
+send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
+ send_text(StateData, exmpp_xml:document_to_list(El));
+send_element(StateData, #xmlel{ns = ?NS_JABBER_CLIENT} = El) ->
+ send_text(StateData, exmpp_xml:document_fragment_to_list(El,
+ [?NS_JABBER_CLIENT], ?PREFIXED_NS));
send_element(StateData, El) ->
- send_text(StateData, xml:element_to_string(El)).
+ send_text(StateData, exmpp_xml:document_fragment_to_list(El,
+ ?DEFAULT_NS, ?PREFIXED_NS)).
change_shaper(StateData, Host, JID) ->
- Shaper = acl:match_rule(Host, StateData#state.shaper, JID),
+ % XXX OLD FORMAT: JIDOld is an old #jid.
+ JIDOld = exmpp_jid:to_ejabberd_jid(JID),
+ Shaper = acl:match_rule(Host, StateData#state.shaper, JIDOld),
(StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
@@ -592,18 +590,20 @@ cancel_timer(Timer) ->
end.
-is_key_packet({xmlelement, Name, Attrs, Els}) when Name == "db:result" ->
+is_key_packet(#xmlel{ns = ?NS_JABBER_DIALBACK, name = 'result',
+ attrs = Attrs} = El) ->
{key,
- xml:get_attr_s("to", Attrs),
- xml:get_attr_s("from", Attrs),
- xml:get_attr_s("id", Attrs),
- xml:get_cdata(Els)};
-is_key_packet({xmlelement, Name, Attrs, Els}) when Name == "db:verify" ->
+ exmpp_stanza:get_recipient_from_attrs(Attrs),
+ exmpp_stanza:get_sender_from_attrs(Attrs),
+ exmpp_stanza:get_id_from_attrs(Attrs),
+ exmpp_xml:get_cdata_as_list(El)};
+is_key_packet(#xmlel{ns = ?NS_JABBER_DIALBACK, name = 'verify',
+ attrs = Attrs} = El) ->
{verify,
- xml:get_attr_s("to", Attrs),
- xml:get_attr_s("from", Attrs),
- xml:get_attr_s("id", Attrs),
- xml:get_cdata(Els)};
+ exmpp_stanza:get_recipient_from_attrs(Attrs),
+ exmpp_stanza:get_sender_from_attrs(Attrs),
+ exmpp_stanza:get_id_from_attrs(Attrs),
+ exmpp_xml:get_cdata_as_list(El)};
is_key_packet(_) ->
false.
@@ -625,10 +625,10 @@ get_cert_domains(Cert) ->
end,
if
D /= error ->
- case jlib:string_to_jid(D) of
- #jid{luser = "",
- lserver = LD,
- lresource = ""} ->
+ case exmpp_jid:string_to_jid(D) of
+ #jid{lnode = undefined,
+ ldomain = LD,
+ lresource = undefined} ->
[LD];
_ ->
[]
@@ -662,8 +662,8 @@ get_cert_domains(Cert) ->
{ok, D} when is_binary(D) ->
case jlib:string_to_jid(
binary_to_list(D)) of
- #jid{luser = "",
- lserver = LD,
+ #jid{lnode = "",
+ ldomain = LD,
lresource = ""} ->
case idna:domain_utf8_to_ascii(LD) of
false ->
@@ -678,10 +678,10 @@ get_cert_domains(Cert) ->
[]
end;
({dNSName, D}) when is_list(D) ->
- case jlib:string_to_jid(D) of
- #jid{luser = "",
- lserver = LD,
- lresource = ""} ->
+ case exmpp_jid:string_to_jid(D) of
+ #jid{lnode = undefined,
+ ldomain = LD,
+ lresource = undefined} ->
[LD];
_ ->
[]
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index e465cfb39..d33439a6e 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -54,8 +54,9 @@
code_change/4,
test_get_addr_port/1]).
+-include("exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-record(state, {socket,
streamid,
@@ -72,7 +73,7 @@
new = false, verify = false,
timer}).
-%%-define(DBGFSM, true).
+%-define(DBGFSM, true).
-ifdef(DBGFSM).
-define(FSMOPTS, [{debug, [trace]}]).
@@ -98,25 +99,10 @@
%% Specified in miliseconds. Default value is 5 minutes.
-define(MAX_RETRY_DELAY, 300000).
--define(STREAM_HEADER,
- ""
- ""
- ).
-
--define(STREAM_TRAILER, "").
-
--define(INVALID_NAMESPACE_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
-
--define(HOST_UNKNOWN_ERR,
- xml:element_to_string(?SERR_HOST_UNKNOWN)).
-
--define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, [?NS_JABBER_SERVER]).
+-define(PREFIXED_NS, [{?NS_XMPP, "stream"}, {?NS_JABBER_DIALBACK, "db"}]).
%%%----------------------------------------------------------------------
%%% API
@@ -209,16 +195,19 @@ open_socket(init, StateData) ->
{ok, Socket} ->
Version = if
StateData#state.use_v10 ->
- " version='1.0'";
+ "1.0";
true ->
""
end,
NewStateData = StateData#state{socket = Socket,
tls_enabled = false,
streamid = new_id()},
- send_text(NewStateData, io_lib:format(?STREAM_HEADER,
- [StateData#state.server,
- Version])),
+ Opening = exmpp_stream:opening(
+ StateData#state.server,
+ ?NS_JABBER_SERVER,
+ Version),
+ send_element(NewStateData,
+ exmpp_stream:set_dialback_support(Opening)),
{next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT};
{error, _Reason} ->
?INFO_MSG("s2s connection: ~s -> ~s (remote server not found)",
@@ -272,27 +261,27 @@ open_socket1(Addr, Port) ->
%%----------------------------------------------------------------------
-wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
- case {xml:get_attr_s("xmlns", Attrs),
- xml:get_attr_s("xmlns:db", Attrs),
- xml:get_attr_s("version", Attrs) == "1.0"} of
- {"jabber:server", "jabber:server:dialback", false} ->
+wait_for_stream({xmlstreamstart, Opening}, StateData) ->
+ case {exmpp_stream:get_default_ns(Opening),
+ exmpp_xml:is_ns_declared_here(Opening, ?NS_JABBER_DIALBACK),
+ exmpp_stream:get_version(Opening) == {1, 0}} of
+ {?NS_JABBER_SERVER, true, false} ->
send_db_request(StateData);
- {"jabber:server", "jabber:server:dialback", true} when
+ {?NS_JABBER_SERVER, true, true} when
StateData#state.use_v10 ->
{next_state, wait_for_features, StateData, ?FSMTIMEOUT};
- {"jabber:server", "", true} when StateData#state.use_v10 ->
+ {?NS_JABBER_SERVER, false, true} when StateData#state.use_v10 ->
{next_state, wait_for_features, StateData#state{db_enabled = false}, ?FSMTIMEOUT};
_ ->
- send_text(StateData, ?INVALID_NAMESPACE_ERR),
+ send_element(StateData, exmpp_stream:error('invalid-namespace')),
?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid namespace)",
[StateData#state.myname, StateData#state.server]),
{stop, normal, StateData}
end;
wait_for_stream({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
?INFO_MSG("Closing s2s connection: ~s -> ~s (invalid xml)",
[StateData#state.myname, StateData#state.server]),
{stop, normal, StateData};
@@ -376,8 +365,8 @@ wait_for_validation({xmlstreamend, _Name}, StateData) ->
wait_for_validation({xmlstreamerror, _}, StateData) ->
?INFO_MSG("wait for validation: ~s -> ~s (xmlstreamerror)",
[StateData#state.myname, StateData#state.server]),
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_validation(timeout, #state{verify = {VPid, VKey, SID}} = StateData)
@@ -401,41 +390,37 @@ wait_for_validation(closed, StateData) ->
wait_for_features({xmlstreamelement, El}, StateData) ->
case El of
- {xmlelement, "stream:features", _Attrs, Els} ->
+ #xmlel{ns = ?NS_XMPP, name = 'features'} = Features ->
{SASLEXT, StartTLS, StartTLSRequired} =
lists:foldl(
- fun({xmlelement, "mechanisms", Attrs1, Els1} = _El1,
+ fun(#xmlel{ns = ?NS_SASL, name = 'mechanisms'},
{_SEXT, STLS, STLSReq} = Acc) ->
- case xml:get_attr_s("xmlns", Attrs1) of
- ?NS_SASL ->
- NewSEXT =
- lists:any(
- fun({xmlelement, "mechanism", _, Els2}) ->
- case xml:get_cdata(Els2) of
- "EXTERNAL" -> true;
- _ -> false
- end;
- (_) -> false
- end, Els1),
- {NewSEXT, STLS, STLSReq};
- _ ->
+ try
+ Mechs = exmpp_client_sasl:announced_mechanisms(
+ El),
+ NewSEXT = lists:member("EXTERNAL", Mechs),
+ {NewSEXT, STLS, STLSReq}
+ catch
+ _Exception ->
Acc
end;
- ({xmlelement, "starttls", Attrs1, _Els1} = El1,
+ (#xmlel{ns = ?NS_TLS, name ='starttls'},
{SEXT, _STLS, _STLSReq} = Acc) ->
- case xml:get_attr_s("xmlns", Attrs1) of
- ?NS_TLS ->
- Req = case xml:get_subtag(El1, "required") of
- {xmlelement, _, _, _} -> true;
- false -> false
- end,
- {SEXT, true, Req};
- _ ->
+ try
+ Support = exmpp_client_tls:announced_support(
+ El),
+ case Support of
+ none -> Acc;
+ optional -> {SEXT, true, false};
+ required -> {SEXT, true, true}
+ end
+ catch
+ _Exception ->
Acc
end;
(_, Acc) ->
Acc
- end, {false, false, false}, Els),
+ end, {false, false, false}, Features#xmlel.children),
if
(not SASLEXT) and (not StartTLS) and
StateData#state.authenticated ->
@@ -450,19 +435,14 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
SASLEXT and StateData#state.try_auth and
(StateData#state.new /= false) ->
send_element(StateData,
- {xmlelement, "auth",
- [{"xmlns", ?NS_SASL},
- {"mechanism", "EXTERNAL"}],
- [{xmlcdata,
- jlib:encode_base64(
- StateData#state.myname)}]}),
+ exmpp_client_sasl:selected_mechanism("EXTERNAL",
+ StateData#state.myname)),
{next_state, wait_for_auth_result,
StateData#state{try_auth = false}, ?FSMTIMEOUT};
StartTLS and StateData#state.tls and
(not StateData#state.tls_enabled) ->
send_element(StateData,
- {xmlelement, "starttls",
- [{"xmlns", ?NS_TLS}], []}),
+ exmpp_client_tls:starttls()),
{next_state, wait_for_starttls_proceed, StateData,
?FSMTIMEOUT};
StartTLSRequired and (not StateData#state.tls) ->
@@ -483,9 +463,8 @@ wait_for_features({xmlstreamelement, El}, StateData) ->
use_v10 = false}, ?FSMTIMEOUT}
end;
_ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('bad-format')),
+ send_element(StateData, exmpp_stream:closing()),
?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)",
[StateData#state.myname, StateData#state.server]),
{stop, normal, StateData}
@@ -496,8 +475,8 @@ wait_for_features({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
wait_for_features({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
?INFO_MSG("wait for features: xmlstreamerror", []),
{stop, normal, StateData};
@@ -512,48 +491,29 @@ wait_for_features(closed, StateData) ->
wait_for_auth_result({xmlstreamelement, El}, StateData) ->
case El of
- {xmlelement, "success", Attrs, _Els} ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_SASL ->
- ?DEBUG("auth: ~p", [{StateData#state.myname,
- StateData#state.server}]),
- ejabberd_socket:reset_stream(StateData#state.socket),
- send_text(StateData,
- io_lib:format(?STREAM_HEADER,
- [StateData#state.server,
- " version='1.0'"])),
- {next_state, wait_for_stream,
- StateData#state{streamid = new_id(),
- authenticated = true
- }, ?FSMTIMEOUT};
- _ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
- ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)",
- [StateData#state.myname, StateData#state.server]),
- {stop, normal, StateData}
- end;
- {xmlelement, "failure", Attrs, _Els} ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_SASL ->
- ?DEBUG("restarted: ~p", [{StateData#state.myname,
- StateData#state.server}]),
- ejabberd_socket:close(StateData#state.socket),
- {next_state, reopen_socket,
- StateData#state{socket = undefined}, ?FSMTIMEOUT};
- _ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
- ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)",
- [StateData#state.myname, StateData#state.server]),
- {stop, normal, StateData}
- end;
+ #xmlel{ns = ?NS_SASL, name = 'success'} ->
+ ?DEBUG("auth: ~p", [{StateData#state.myname,
+ StateData#state.server}]),
+ ejabberd_socket:reset_stream(StateData#state.socket),
+ Opening = exmpp_stream:opening(
+ StateData#state.server,
+ ?NS_JABBER_SERVER,
+ "1.0"),
+ send_element(StateData,
+ exmpp_stream:set_dialback_support(Opening)),
+ {next_state, wait_for_stream,
+ StateData#state{streamid = new_id(),
+ authenticated = true
+ }, ?FSMTIMEOUT};
+ #xmlel{ns = ?NS_SASL, name = 'failure'} ->
+ ?DEBUG("restarted: ~p", [{StateData#state.myname,
+ StateData#state.server}]),
+ ejabberd_socket:close(StateData#state.socket),
+ {next_state, reopen_socket,
+ StateData#state{socket = undefined}, ?FSMTIMEOUT};
_ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('bad-format')),
+ send_element(StateData, exmpp_stream:closing()),
?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)",
[StateData#state.myname, StateData#state.server]),
{stop, normal, StateData}
@@ -564,8 +524,8 @@ wait_for_auth_result({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
wait_for_auth_result({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
?INFO_MSG("wait for auth result: xmlstreamerror", []),
{stop, normal, StateData};
@@ -580,42 +540,36 @@ wait_for_auth_result(closed, StateData) ->
wait_for_starttls_proceed({xmlstreamelement, El}, StateData) ->
case El of
- {xmlelement, "proceed", Attrs, _Els} ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_TLS ->
- ?DEBUG("starttls: ~p", [{StateData#state.myname,
- StateData#state.server}]),
- Socket = StateData#state.socket,
- TLSOpts = case ejabberd_config:get_local_option(
- {domain_certfile,
- StateData#state.server}) of
- undefined ->
- StateData#state.tls_options;
- CertFile ->
- [{certfile, CertFile} |
- lists:keydelete(
- certfile, 1,
- StateData#state.tls_options)]
- end,
- TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
- NewStateData = StateData#state{socket = TLSSocket,
- streamid = new_id(),
- tls_enabled = true
- },
- send_text(NewStateData,
- io_lib:format(?STREAM_HEADER,
- [StateData#state.server,
- " version='1.0'"])),
- {next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT};
- _ ->
- send_text(StateData,
- xml:element_to_string(?SERR_BAD_FORMAT) ++
- ?STREAM_TRAILER),
- ?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)",
- [StateData#state.myname, StateData#state.server]),
- {stop, normal, StateData}
- end;
+ #xmlel{ns = ?NS_TLS, name = 'proceed'} ->
+ ?DEBUG("starttls: ~p", [{StateData#state.myname,
+ StateData#state.server}]),
+ Socket = StateData#state.socket,
+ TLSOpts = case ejabberd_config:get_local_option(
+ {domain_certfile,
+ StateData#state.server}) of
+ undefined ->
+ StateData#state.tls_options;
+ CertFile ->
+ [{certfile, CertFile} |
+ lists:keydelete(
+ certfile, 1,
+ StateData#state.tls_options)]
+ end,
+ TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
+ NewStateData = StateData#state{socket = TLSSocket,
+ streamid = new_id(),
+ tls_enabled = true
+ },
+ Opening = exmpp_stream:opening(
+ StateData#state.server,
+ ?NS_JABBER_SERVER,
+ "1.0"),
+ send_element(NewStateData,
+ exmpp_stream:set_dialback_support(Opening)),
+ {next_state, wait_for_stream, NewStateData, ?FSMTIMEOUT};
_ ->
+ send_element(StateData, exmpp_stream:error('bad-format')),
+ send_element(StateData, exmpp_stream:closing()),
?INFO_MSG("Closing s2s connection: ~s -> ~s (bad format)",
[StateData#state.myname, StateData#state.server]),
{stop, normal, StateData}
@@ -626,8 +580,8 @@ wait_for_starttls_proceed({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
wait_for_starttls_proceed({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
?INFO_MSG("wait for starttls proceed: xmlstreamerror", []),
{stop, normal, StateData};
@@ -690,8 +644,8 @@ stream_established({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
stream_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData,
- ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
?INFO_MSG("stream established: ~s -> ~s (xmlstreamerror)",
[StateData#state.myname, StateData#state.server]),
{stop, normal, StateData};
@@ -759,7 +713,10 @@ handle_info({send_text, Text}, StateName, StateData) ->
{next_state, StateName, StateData#state{timer = Timer},
get_timeout_interval(StateName)};
-handle_info({send_element, El}, StateName, StateData) ->
+handle_info({send_element, ElOld}, StateName, StateData) ->
+ % XXX OLD FORMAT: El.
+ El = exmpp_xml:xmlelement_to_xmlel(ElOld,
+ [?NS_JABBER_CLIENT], ?PREFIXED_NS),
case StateName of
stream_established ->
cancel_timer(StateData#state.timer),
@@ -769,7 +726,7 @@ handle_info({send_element, El}, StateName, StateData) ->
%% In this state we bounce all message: We are waiting before
%% trying to reconnect
wait_before_retry ->
- bounce_element(El, ?ERR_REMOTE_SERVER_NOT_FOUND),
+ bounce_element(El, 'remote-server-not-found'),
{next_state, StateName, StateData};
_ ->
Q = queue:in(El, StateData#state.queue),
@@ -811,8 +768,8 @@ terminate(Reason, StateName, StateData) ->
{StateData#state.myname, StateData#state.server}, self(), Key)
end,
%% bounce queue manage by process and Erlang message queue
- bounce_queue(StateData#state.queue, ?ERR_REMOTE_SERVER_NOT_FOUND),
- bounce_messages(?ERR_REMOTE_SERVER_NOT_FOUND),
+ bounce_queue(StateData#state.queue, 'remote-server-not-found'),
+ bounce_messages('remote-server-not-found'),
case StateData#state.socket of
undefined ->
ok;
@@ -828,8 +785,14 @@ terminate(Reason, StateName, StateData) ->
send_text(StateData, Text) ->
ejabberd_socket:send(StateData#state.socket, Text).
+send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
+ send_text(StateData, exmpp_xml:document_to_list(El));
+send_element(StateData, #xmlel{ns = ?NS_JABBER_CLIENT} = El) ->
+ send_text(StateData, exmpp_xml:document_fragment_to_list(El,
+ [?NS_JABBER_CLIENT], ?PREFIXED_NS));
send_element(StateData, El) ->
- send_text(StateData, xml:element_to_string(El)).
+ send_text(StateData, exmpp_xml:document_fragment_to_list(El,
+ ?DEFAULT_NS, ?PREFIXED_NS)).
send_queue(StateData, Q) ->
case queue:out(Q) of
@@ -840,24 +803,31 @@ send_queue(StateData, Q) ->
ok
end.
-%% Bounce a single message (xmlelement)
-bounce_element(El, Error) ->
- {xmlelement, _Name, Attrs, _SubTags} = El,
- case xml:get_attr_s("type", Attrs) of
+%% Bounce a single message (xmlel)
+bounce_element(El, Condition) ->
+ case exmpp_stanza:get_type(El) of
"error" -> ok;
"result" -> ok;
_ ->
- 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)
+ Error = exmpp_stanza:error(El#xmlel.ns, Condition),
+ Err = exmpp_stanza:reply_with_error(El, Error),
+ From = exmpp_jid:string_to_jid(exmpp_stanza:get_sender(El)),
+ To = exmpp_jid:string_to_jid(exmpp_stanza:get_recipient(El)),
+ % XXX OLD FORMAT: From, To, Err.
+ % XXX No namespace conversion (:server <-> :client) is done.
+ % This is handled by C2S and S2S send_element functions.
+ ErrOld = exmpp_xml:xmlel_to_xmlelement(Err,
+ [?NS_JABBER_CLIENT], ?PREFIXED_NS),
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
+ ejabberd_router:route(ToOld, FromOld, ErrOld)
end.
-bounce_queue(Q, Error) ->
+bounce_queue(Q, Condition) ->
case queue:out(Q) of
{{value, El}, Q1} ->
- bounce_element(El, Error),
- bounce_queue(Q1, Error);
+ bounce_element(El, Condition),
+ bounce_queue(Q1, Condition);
{empty, _} ->
ok
end.
@@ -874,11 +844,14 @@ cancel_timer(Timer) ->
ok
end.
-bounce_messages(Error) ->
+bounce_messages(Condition) ->
receive
- {send_element, El} ->
- bounce_element(El, Error),
- bounce_messages(Error)
+ {send_element, ElOld} ->
+ % XXX OLD FORMAT: El.
+ El = exmpp_xml:xmlelement_to_xmlel(ElOld,
+ [?NS_JABBER_CLIENT], ?PREFIXED_NS),
+ bounce_element(El, Condition),
+ bounce_messages(Condition)
after 0 ->
ok
end.
@@ -902,40 +875,33 @@ send_db_request(StateData) ->
false ->
ok;
Key1 ->
- send_element(StateData,
- {xmlelement,
- "db:result",
- [{"from", StateData#state.myname},
- {"to", Server}],
- [{xmlcdata, Key1}]})
+ send_element(StateData, exmpp_dialback:key(
+ StateData#state.myname, Server, Key1))
end,
case StateData#state.verify of
false ->
ok;
{_Pid, Key2, SID} ->
- send_element(StateData,
- {xmlelement,
- "db:verify",
- [{"from", StateData#state.myname},
- {"to", StateData#state.server},
- {"id", SID}],
- [{xmlcdata, Key2}]})
+ send_element(StateData, exmpp_dialback:verify_request(
+ StateData#state.myname, StateData#state.server, SID, Key2))
end,
{next_state, wait_for_validation, StateData#state{new = New}, ?FSMTIMEOUT*6}.
-is_verify_res({xmlelement, Name, Attrs, _Els}) when Name == "db:result" ->
+is_verify_res(#xmlel{ns = ?NS_JABBER_DIALBACK, name = 'result',
+ attrs = Attrs}) ->
{result,
- xml:get_attr_s("to", Attrs),
- xml:get_attr_s("from", Attrs),
- xml:get_attr_s("id", Attrs),
- xml:get_attr_s("type", Attrs)};
-is_verify_res({xmlelement, Name, Attrs, _Els}) when Name == "db:verify" ->
+ exmpp_stanza:get_recipient_from_attrs(Attrs),
+ exmpp_stanza:get_sender_from_attrs(Attrs),
+ exmpp_stanza:get_id_from_attrs(Attrs),
+ exmpp_stanza:get_type_from_attrs(Attrs)};
+is_verify_res(#xmlel{ns = ?NS_JABBER_DIALBACK, name = 'verify',
+ attrs = Attrs}) ->
{verify,
- xml:get_attr_s("to", Attrs),
- xml:get_attr_s("from", Attrs),
- xml:get_attr_s("id", Attrs),
- xml:get_attr_s("type", Attrs)};
+ exmpp_stanza:get_recipient_from_attrs(Attrs),
+ exmpp_stanza:get_sender_from_attrs(Attrs),
+ exmpp_stanza:get_id_from_attrs(Attrs),
+ exmpp_stanza:get_type_from_attrs(Attrs)};
is_verify_res(_) ->
false.
@@ -1032,8 +998,8 @@ get_timeout_interval(StateName) ->
%% function that want to wait for a reconnect delay before stopping.
wait_before_reconnect(StateData) ->
%% bounce queue manage by process and Erlang message queue
- bounce_queue(StateData#state.queue, ?ERR_REMOTE_SERVER_NOT_FOUND),
- bounce_messages(?ERR_REMOTE_SERVER_NOT_FOUND),
+ bounce_queue(StateData#state.queue, 'remote-server-not-found'),
+ bounce_messages('remote-server-not-found'),
cancel_timer(StateData#state.timer),
Delay = case StateData#state.delay_to_retry of
undefined_delay ->
From b32aba27c1b593d560b04973d404f570535791b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 27 Jun 2008 13:46:08 +0000
Subject: [PATCH 016/582] o Use the new exmpp namespace macro names. o Update
send_element/2 to use exmpp new to_list functions.
SVN Revision: 1384
---
ChangeLog | 6 +++
src/ejabberd_c2s.erl | 80 +++++++++++++++++++---------------------
src/ejabberd_s2s_in.erl | 26 +++++++------
src/ejabberd_s2s_out.erl | 23 +++++++-----
4 files changed, 71 insertions(+), 64 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0851fcd71..947a8e4ad 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-06-27 Jean-Sébastien Pédron
+
+ * src/ejabberd_c2s.erl, src/ejabberd_s2s_out.erl,
+ src/ejabberd_s2s_in.erl: Use the new exmpp namespace macro names.
+ Update send_element/2 to use exmpp new to_list functions.
+
2008-06-26 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl: Use a macro in ?DEFAULT_NS instead of the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 38aae6e8b..953e9beb2 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -116,11 +116,8 @@
% These are the namespace already declared by the stream opening. This is
% used at serialization time.
--define(DEFAULT_NS, [?NS_JABBER_CLIENT]).
--define(PREFIXED_NS, [{?NS_XMPP, "stream"}]).
-
-% XXX OLD FORMAT
--define(NS_AUTH, "jabber:iq:auth").
+-define(DEFAULT_NS, ?NS_JABBER_CLIENT).
+-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
-define(STANZA_ERROR(Condition),
exmpp_xml:xmlel_to_xmlelement(exmpp_stanza:error(Condition),
@@ -553,7 +550,7 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
end,
Socket = StateData#state.socket,
Proceed = exmpp_xml:document_fragment_to_list(
- exmpp_server_tls:proceed(), ?DEFAULT_NS, ?PREFIXED_NS),
+ exmpp_server_tls:proceed(), [?DEFAULT_NS], ?PREFIXED_NS),
TLSSocket = (StateData#state.sockmod):starttls(
Socket, TLSOpts,
Proceed),
@@ -821,10 +818,10 @@ session_established({xmlstreamelement, El}, StateData) ->
c2s_update_presence,
Server,
exmpp_xml:xmlel_to_xmlelement(NewEl,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
[User, Server]),
PresenceEl = exmpp_xml:xmlelement_to_xmlel(PresenceElOld,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
% XXX OLD FORMAT: PresenceElOld, *JID.
FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
@@ -849,13 +846,13 @@ session_established({xmlstreamelement, El}, StateData) ->
FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
case exmpp_iq:get_payload(El) of
- #xmlel{ns = ?NS_JABBER_PRIVACY} ->
+ #xmlel{ns = ?NS_PRIVACY} ->
process_privacy_iq(
FromJID, ToJID, El, StateData);
_ ->
% XXX OLD FORMAT: NewElOld.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(
user_send_packet,
Server,
@@ -868,7 +865,7 @@ session_established({xmlstreamelement, El}, StateData) ->
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'message'} ->
% XXX OLD FORMAT: NewElOld, JIDs.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
ejabberd_hooks:run(user_send_packet,
@@ -882,7 +879,7 @@ session_established({xmlstreamelement, El}, StateData) ->
end,
% XXX OLD FORMAT: El.
ElOld = exmpp_xml:xmlel_to_xmlelement(El,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, ElOld}]),
fsm_next_state(session_established, NewState)
catch
@@ -898,7 +895,7 @@ session_established({xmlstreamelement, El}, StateData) ->
end,
% XXX OLD FORMAT: ElOld1.
ElOld1 = exmpp_xml:xmlel_to_xmlelement(El,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, ElOld1}]),
fsm_next_state(session_established, StateData);
throw:Exception ->
@@ -1014,7 +1011,7 @@ handle_info(replaced, _StateName, StateData) ->
handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
%% XXX OLD FORMAT: From, To and Packet are in the old format.
Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
From = exmpp_jid:from_ejabberd_jid(FromOld),
To = exmpp_jid:from_ejabberd_jid(ToOld),
{Pass, NewAttrs, NewState} =
@@ -1191,7 +1188,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
Res = exmpp_iq:error(Packet, Err),
% XXX OLD FORMAT: To, From, Res.
ResOld = exmpp_xml:xmlel_to_xmlelement(
- Res, ?DEFAULT_NS, ?PREFIXED_NS),
+ Res, [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_router:route(ToOld, FromOld, ResOld)
end,
{false, Attrs, StateData};
@@ -1214,7 +1211,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
% XXX OLD FORMAT: To, From, Res.
ResOld = exmpp_xml:xmlel_to_xmlelement(
Res,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_router:route(ToOld, FromOld, ResOld),
{false, Attrs, StateData}
end
@@ -1251,7 +1248,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
send_element(StateData, FixedPacket),
% XXX OLD FORMAT: From, To, FixedPacket.
FixedPacketOld = exmpp_xml:xmlel_to_xmlelement(FixedPacket,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(user_receive_packet,
StateData#state.server,
[StateData#state.jid, FromOld, ToOld, FixedPacketOld]),
@@ -1349,13 +1346,11 @@ send_text(StateData, Text) ->
(StateData#state.sockmod):send(StateData#state.socket, Text).
send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
- send_text(StateData, exmpp_xml:document_to_list(El));
+ send_text(StateData, exmpp_stream:to_list(El));
send_element(StateData, #xmlel{ns = ?NS_JABBER_SERVER} = El) ->
- send_text(StateData, exmpp_xml:document_fragment_to_list(El,
- [?NS_JABBER_SERVER], ?PREFIXED_NS));
+ send_text(StateData, exmpp_stanza:to_list(El, ?NS_JABBER_SERVER));
send_element(StateData, El) ->
- send_text(StateData, exmpp_xml:document_fragment_to_list(El,
- ?DEFAULT_NS, ?PREFIXED_NS)).
+ send_text(StateData, exmpp_stanza:to_list(El, ?DEFAULT_NS)).
new_id() ->
@@ -1365,9 +1360,10 @@ new_id() ->
is_auth_packet(El) ->
% XXX OLD FORMAT: El.
ElOld = exmpp_xml:xmlel_to_xmlelement(El,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ NS_Auth = atom_to_list(?NS_LEGACY_AUTH),
case jlib:iq_query_info(ElOld) of
- #iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} ->
+ #iq{id = ID, type = Type, xmlns = NS_Auth, sub_el = SubEl} ->
{xmlelement, _, _, Els} = SubEl,
{auth, ID, Type,
get_auth_tags(Els, "", "", "", undefined)};
@@ -1432,7 +1428,7 @@ process_presence_probe(From, To, StateData) ->
FromOld = exmpp_jid:to_ejabberd_jid(From),
ToOld = exmpp_jid:to_ejabberd_jid(To),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
@@ -1462,7 +1458,7 @@ process_presence_probe(From, To, StateData) ->
FromOld = exmpp_jid:to_ejabberd_jid(From),
ToOld = exmpp_jid:to_ejabberd_jid(To),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_router:route(ToOld, FromOld, PacketOld);
true ->
ok
@@ -1591,7 +1587,7 @@ presence_track(From, To, Packet, StateData) ->
BFromOld = exmpp_jid:to_ejabberd_jid(exmpp_jid:jid_to_bare_jid(From)),
ToOld = exmpp_jid:to_ejabberd_jid(To),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
case exmpp_presence:get_type(Packet) of
'unavailable' ->
% XXX OLD FORMAT: From, To, Packet.
@@ -1676,7 +1672,7 @@ presence_broadcast(StateData, From, JIDSet, Packet) ->
FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
FromOld = exmpp_jid:to_ejabberd_jid(From),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
@@ -1697,7 +1693,7 @@ presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
% XXX OLD FORMAT: From, Packet.
FromOld = exmpp_jid:to_ejabberd_jid(From),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
lists:foreach(
fun({U, S, R} = JID) ->
case ?SETS:is_element(JID, T) of
@@ -1730,9 +1726,9 @@ presence_broadcast_first(From, StateData, Packet) ->
% XXX OLD FORMAT: From, Packet, Probe.
FromOld = exmpp_jid:to_ejabberd_jid(From),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ProbeOld = exmpp_xml:xmlel_to_xmlelement(Probe,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
?SETS:fold(fun({U, S, R}, X) ->
FJID = exmpp_jid:make_jid(U, S, R),
% XXX OLD FORMAT: FJID.
@@ -1821,7 +1817,7 @@ roster_change(IJID, ISubscription, StateData) ->
?DEBUG("C1: ~p~n", [LIJID]),
% XXX OLD FORMAT: P.
POld = exmpp_xml:xmlelement_to_xmlel(P,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
% XXX OLD FORMAT: From, To, P.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
@@ -1847,7 +1843,7 @@ roster_change(IJID, ISubscription, StateData) ->
PU = exmpp_presence:unavailable(),
% XXX OLD FORMAT: PU.
PUOld = exmpp_xml:xmlelement_to_xmlel(PU,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
% XXX OLD FORMAT: From, To, PU.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
@@ -1881,7 +1877,7 @@ update_priority(Priority, Packet, StateData) ->
Info = [{ip, StateData#state.ip},{conn, StateData#state.conn}],
% XXX OLD FORMAT: Packet.
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_sm:set_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
@@ -1895,7 +1891,7 @@ process_privacy_iq(From, To,
StateData) ->
% XXX OLD FORMAT: IQ is #iq.
ElOld = exmpp_xml:xmlel_to_xmlelement(El,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
IQOld = jlib:iq_query_info(ElOld),
% XXX OLD FORMAT: JIDs.
FromOld = exmpp_jid:to_ejabberd_jid(From),
@@ -1923,16 +1919,16 @@ process_privacy_iq(From, To,
case Res of
{result, ResultOld} ->
Result = exmpp_xml:xmlelement_to_xmlel(ResultOld,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
exmpp_iq:result(El, Result);
{error, ErrorOld} ->
Error = exmpp_xml:xmlelement_to_xmlel(ErrorOld,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
exmpp_iq:error(El, Error)
end,
% XXX OLD FORMAT: To, From, IQRes.
IQResOld = exmpp_xml:xmlel_to_xmlelement(IQRes,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_router:route(
ToOld, FromOld, IQResOld),
NewStateData.
@@ -1970,7 +1966,7 @@ resend_offline_messages(#state{user = User,
From = exmpp_jid:from_ejabberd_jid(FromOld),
To = exmpp_jid:from_ejabberd_jid(ToOld),
Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
Attrs1 = exmpp_stanza:set_sender_in_attrs(
Packet#xmlel.attrs, From),
Attrs2 = exmpp_stanza:set_recipient_in_attrs(
@@ -1994,14 +1990,14 @@ resend_subscription_requests(#state{user = User,
% XXX OLD FORMAT ON DISK!
lists:foreach(fun(XMLPacketOld) ->
XMLPacket = exmpp_xml:xmlelement_to_xmlel(
- XMLPacketOld, ?DEFAULT_NS, ?PREFIXED_NS),
+ XMLPacketOld, [?DEFAULT_NS], ?PREFIXED_NS),
send_element(StateData,
XMLPacket)
end,
PendingSubscriptions).
process_unauthenticated_stanza(StateData, El) ->
- ElOld = exmpp_xml:xmlel_to_xmlelement(El, ?DEFAULT_NS, ?PREFIXED_NS),
+ ElOld = exmpp_xml:xmlel_to_xmlelement(El, [?DEFAULT_NS], ?PREFIXED_NS),
case jlib:iq_query_info(ElOld) of
#iq{} = IQ ->
ResOld = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
@@ -2022,7 +2018,7 @@ process_unauthenticated_stanza(StateData, El) ->
send_element(StateData, Res2);
_ ->
Res = exmpp_xml:xmlelement_to_xmlel(ResOld,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
send_element(StateData, Res)
end;
_ ->
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 31ae9454e..ed8b922e0 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -95,8 +95,10 @@
% These are the namespace already declared by the stream opening. This is
% used at serialization time.
--define(DEFAULT_NS, [?NS_JABBER_SERVER]).
--define(PREFIXED_NS, [{?NS_XMPP, "stream"}, {?NS_JABBER_DIALBACK, "db"}]).
+-define(DEFAULT_NS, ?NS_JABBER_SERVER).
+-define(PREFIXED_NS, [
+ {?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}
+]).
%%%----------------------------------------------------------------------
%%% API
@@ -159,7 +161,7 @@ init([{SockMod, Socket}, Opts]) ->
wait_for_stream({xmlstreamstart, Opening}, StateData) ->
case {exmpp_stream:get_default_ns(Opening),
- exmpp_xml:is_ns_declared_here(Opening, ?NS_JABBER_DIALBACK),
+ exmpp_xml:is_ns_declared_here(Opening, ?NS_DIALBACK),
exmpp_stream:get_version(Opening) == {1, 0}} of
{?NS_JABBER_SERVER, _, true} when
StateData#state.tls and (not StateData#state.authenticated) ->
@@ -240,7 +242,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
?DEBUG("starttls", []),
Socket = StateData#state.socket,
Proceed = exmpp_xml:document_fragment_to_list(
- exmpp_server_tls:proceed(), ?DEFAULT_NS, ?PREFIXED_NS),
+ exmpp_server_tls:proceed(), [?DEFAULT_NS], ?PREFIXED_NS),
TLSOpts = StateData#state.tls_options,
TLSSocket = (StateData#state.sockmod):starttls(
Socket, TLSOpts,
@@ -388,7 +390,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
% XXX No namespace conversion (:server <-> :client) is done.
% This is handled by C2S and S2S send_element functions.
ElOld = exmpp_xml:xmlel_to_xmlelement(El,
- ?DEFAULT_NS, ?PREFIXED_NS),
+ [?DEFAULT_NS], ?PREFIXED_NS),
if
(To /= error) and (From /= error) ->
LFrom = From#jid.ldomain,
@@ -561,13 +563,13 @@ send_text(StateData, Text) ->
send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
- send_text(StateData, exmpp_xml:document_to_list(El));
+ send_text(StateData, exmpp_stream:to_list(El));
send_element(StateData, #xmlel{ns = ?NS_JABBER_CLIENT} = El) ->
- send_text(StateData, exmpp_xml:document_fragment_to_list(El,
- [?NS_JABBER_CLIENT], ?PREFIXED_NS));
+ send_text(StateData, exmpp_stanza:to_list(El,
+ ?NS_JABBER_CLIENT, ?PREFIXED_NS));
send_element(StateData, El) ->
- send_text(StateData, exmpp_xml:document_fragment_to_list(El,
- ?DEFAULT_NS, ?PREFIXED_NS)).
+ send_text(StateData, exmpp_stanza:to_list(El,
+ ?DEFAULT_NS, ?PREFIXED_NS)).
change_shaper(StateData, Host, JID) ->
@@ -590,14 +592,14 @@ cancel_timer(Timer) ->
end.
-is_key_packet(#xmlel{ns = ?NS_JABBER_DIALBACK, name = 'result',
+is_key_packet(#xmlel{ns = ?NS_DIALBACK, name = 'result',
attrs = Attrs} = El) ->
{key,
exmpp_stanza:get_recipient_from_attrs(Attrs),
exmpp_stanza:get_sender_from_attrs(Attrs),
exmpp_stanza:get_id_from_attrs(Attrs),
exmpp_xml:get_cdata_as_list(El)};
-is_key_packet(#xmlel{ns = ?NS_JABBER_DIALBACK, name = 'verify',
+is_key_packet(#xmlel{ns = ?NS_DIALBACK, name = 'verify',
attrs = Attrs} = El) ->
{verify,
exmpp_stanza:get_recipient_from_attrs(Attrs),
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index d33439a6e..ef099609b 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -101,8 +101,11 @@
% These are the namespace already declared by the stream opening. This is
% used at serialization time.
--define(DEFAULT_NS, [?NS_JABBER_SERVER]).
--define(PREFIXED_NS, [{?NS_XMPP, "stream"}, {?NS_JABBER_DIALBACK, "db"}]).
+-define(DEFAULT_NS, ?NS_JABBER_SERVER).
+-define(PREFIXED_NS, [
+ {?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}
+]).
+
%%%----------------------------------------------------------------------
%%% API
@@ -263,7 +266,7 @@ open_socket1(Addr, Port) ->
wait_for_stream({xmlstreamstart, Opening}, StateData) ->
case {exmpp_stream:get_default_ns(Opening),
- exmpp_xml:is_ns_declared_here(Opening, ?NS_JABBER_DIALBACK),
+ exmpp_xml:is_ns_declared_here(Opening, ?NS_DIALBACK),
exmpp_stream:get_version(Opening) == {1, 0}} of
{?NS_JABBER_SERVER, true, false} ->
send_db_request(StateData);
@@ -786,13 +789,13 @@ send_text(StateData, Text) ->
ejabberd_socket:send(StateData#state.socket, Text).
send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
- send_text(StateData, exmpp_xml:document_to_list(El));
+ send_text(StateData, exmpp_stream:to_list(El));
send_element(StateData, #xmlel{ns = ?NS_JABBER_CLIENT} = El) ->
- send_text(StateData, exmpp_xml:document_fragment_to_list(El,
- [?NS_JABBER_CLIENT], ?PREFIXED_NS));
+ send_text(StateData, exmpp_stanza:to_list(El,
+ ?NS_JABBER_CLIENT, ?PREFIXED_NS));
send_element(StateData, El) ->
- send_text(StateData, exmpp_xml:document_fragment_to_list(El,
- ?DEFAULT_NS, ?PREFIXED_NS)).
+ send_text(StateData, exmpp_stanza:to_list(El,
+ ?DEFAULT_NS, ?PREFIXED_NS)).
send_queue(StateData, Q) ->
case queue:out(Q) of
@@ -888,14 +891,14 @@ send_db_request(StateData) ->
{next_state, wait_for_validation, StateData#state{new = New}, ?FSMTIMEOUT*6}.
-is_verify_res(#xmlel{ns = ?NS_JABBER_DIALBACK, name = 'result',
+is_verify_res(#xmlel{ns = ?NS_DIALBACK, name = 'result',
attrs = Attrs}) ->
{result,
exmpp_stanza:get_recipient_from_attrs(Attrs),
exmpp_stanza:get_sender_from_attrs(Attrs),
exmpp_stanza:get_id_from_attrs(Attrs),
exmpp_stanza:get_type_from_attrs(Attrs)};
-is_verify_res(#xmlel{ns = ?NS_JABBER_DIALBACK, name = 'verify',
+is_verify_res(#xmlel{ns = ?NS_DIALBACK, name = 'verify',
attrs = Attrs}) ->
{verify,
exmpp_stanza:get_recipient_from_attrs(Attrs),
From d05c2ee8a1d9d89b92c6d3464328159f766ae315 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 30 Jun 2008 12:13:15 +0000
Subject: [PATCH 017/582] Use -include_lib instead of -include to include
exmpp.hrl. This is a better solution than specifying the path (with -I) on
erlc(1) command line.
SVN Revision: 1388
---
ChangeLog | 9 +++++++++
src/Makefile.in | 2 +-
src/ejabberd_c2s.erl | 2 +-
src/ejabberd_s2s_in.erl | 2 +-
src/ejabberd_s2s_out.erl | 2 +-
5 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 947a8e4ad..9e9fc965a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-06-30 Jean-Sébastien Pédron
+
+ * src/Makefile.in: Remove the -I flag for exmpp includes; the
+ -include_lib pragma is a better solution.
+
+ * src/ejabberd_c2s.erl, src/ejabberd_s2s_in.erl,
+ src/ejabberd_s2s_out.erl: Use -include_lib instead of -include to
+ include exmpp.hrl.
+
2008-06-27 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl, src/ejabberd_s2s_out.erl,
diff --git a/src/Makefile.in b/src/Makefile.in
index 7391a8d9a..57bb56333 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -12,7 +12,7 @@ ERLANG_CFLAGS= @ERLANG_CFLAGS@
EXPAT_LIBS = @EXPAT_LIBS@
ERLANG_LIBS = @ERLANG_LIBS@
-ERLC_FLAGS += @ERLANG_SSL39@ -I@ERLANG_EXMPP@/include
+ERLC_FLAGS += @ERLANG_SSL39@
ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj
# make debug=true to compile Erlang module with debug informations.
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 953e9beb2..828df898c 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -54,7 +54,7 @@
handle_info/3,
terminate/3]).
--include("exmpp.hrl").
+-include_lib("exmpp/include/exmpp.hrl").
-include("ejabberd.hrl").
-include("mod_privacy.hrl").
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index ed8b922e0..70f5cecce 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -46,7 +46,7 @@
handle_info/3,
terminate/3]).
- -include("exmpp.hrl").
+-include_lib("exmpp/include/exmpp.hrl").
-include("ejabberd.hrl").
-ifdef(SSL39).
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index ef099609b..19f68d25e 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -54,7 +54,7 @@
code_change/4,
test_get_addr_port/1]).
--include("exmpp.hrl").
+-include_lib("exmpp/include/exmpp.hrl").
-include("ejabberd.hrl").
From 264e72830b213c81b9c7120b6e9704f9701444df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 30 Jun 2008 14:04:31 +0000
Subject: [PATCH 018/582] Convert to exmpp.
SVN Revision: 1389
---
ChangeLog | 2 ++
src/ejabberd_s2s.erl | 67 ++++++++++++++++++++++++++++++--------------
2 files changed, 48 insertions(+), 21 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 9e9fc965a..0491d68f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,8 @@
src/ejabberd_s2s_out.erl: Use -include_lib instead of -include to
include exmpp.hrl.
+ * src/ejabberd_s2s.erl: Convert to exmpp.
+
2008-06-27 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl, src/ejabberd_s2s_out.erl,
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index cd878c1b2..424b9fc99 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -46,13 +46,21 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("ejabberd_ctl.hrl").
-define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER, 1).
-define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER_PER_NODE, 1).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, ?NS_JABBER_CLIENT).
+-define(PREFIXED_NS, [
+ {?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}
+]).
+
-record(s2s, {fromto, pid, key}).
-record(state, {}).
@@ -66,7 +74,12 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-route(From, To, Packet) ->
+route(FromOld, ToOld, PacketOld) ->
+ % XXX OLD FORMAT: From, To, Packet.
+ From = exmpp_jid:from_ejabberd_jid(FromOld),
+ To = exmpp_jid:from_ejabberd_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ [?DEFAULT_NS], ?PREFIXED_NS),
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -201,7 +214,12 @@ handle_cast(_Msg, State) ->
handle_info({mnesia_system_event, {mnesia_down, Node}}, State) ->
clean_table_from_bad_node(Node),
{noreply, State};
-handle_info({route, From, To, Packet}, State) ->
+handle_info({route, FromOld, ToOld, PacketOld}, State) ->
+ % XXX OLD FORMAT: From, To, Packet
+ From = exmpp_jid:from_ejabberd_jid(FromOld),
+ To = exmpp_jid:from_ejabberd_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ [?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -249,35 +267,42 @@ clean_table_from_bad_node(Node) ->
do_route(From, To, Packet) ->
?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
+ % XXX OLD FORMAT: From, To.
+ FromOld = exmpp_jid:to_ejabberd_jid(From),
+ ToOld = exmpp_jid:to_ejabberd_jid(To),
case find_connection(From, To) of
{atomic, Pid} when pid(Pid) ->
?DEBUG("sending to process ~p~n", [Pid]),
- {xmlelement, Name, Attrs, Els} = Packet,
- NewAttrs = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- #jid{lserver = MyServer} = From,
+ NewPacket1 = exmpp_stanza:set_sender(Packet, From),
+ NewPacket = exmpp_stanza:set_recipient(NewPacket1, To),
+ #jid{ldomain = MyServer} = From,
+ % XXX OLD FORMAT: NewPacket.
+ NewPacketOld = exmpp_xml:xmlel_to_xmlelement(NewPacket,
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(
s2s_send_packet,
MyServer,
- [From, To, Packet]),
- send_element(Pid, {xmlelement, Name, NewAttrs, Els}),
+ [FromOld, ToOld, NewPacketOld]),
+ send_element(Pid, NewPacket),
ok;
{aborted, _Reason} ->
- case xml:get_tag_attr_s("type", Packet) of
+ case exmpp_stanza:get_type(Packet) of
"error" -> ok;
"result" -> ok;
_ ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
+ Err = exmpp_stanza:reply_with_error(Packet,
+ exmpp_stanza:error('service-unavailable')),
+ % XXX OLD FORMAT: Err.
+ ErrOld = exmpp_xml:xmlel_to_xmlelement(Err,
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ ejabberd_router:route(ToOld, FromOld, ErrOld)
end,
false
end.
find_connection(From, To) ->
- #jid{lserver = MyServer} = From,
- #jid{lserver = Server} = To,
+ #jid{ldomain = MyServer} = From,
+ #jid{ldomain = Server} = To,
FromTo = {MyServer, Server},
MaxS2SConnectionsNumber = max_s2s_connections_number(FromTo),
MaxS2SConnectionsNumberPerNode =
@@ -330,7 +355,7 @@ choose_pid(From, Pids) ->
% Use sticky connections based on the JID of the sender (whithout
% the resource to ensure that a muc room always uses the same
% connection)
- Pid = lists:nth(erlang:phash(jlib:jid_remove_resource(From), length(Pids1)),
+ Pid = lists:nth(erlang:phash(exmpp_jid:jid_to_bare_jid(From), length(Pids1)),
Pids1),
?DEBUG("Using ejabberd_s2s_out ~p~n", [Pid]),
Pid.
@@ -381,14 +406,14 @@ new_connection(MyServer, Server, From, FromTo,
max_s2s_connections_number({From, To}) ->
case acl:match_rule(
- From, max_s2s_connections, jlib:make_jid("", To, "")) of
+ From, max_s2s_connections, exmpp_jid:make_bare_jid(To)) of
Max when is_integer(Max) -> Max;
_ -> ?DEFAULT_MAX_S2S_CONNECTIONS_NUMBER
end.
max_s2s_connections_number_per_node({From, To}) ->
case acl:match_rule(
- From, max_s2s_connections_per_node, jlib:make_jid("", To, "")) of
+ From, max_s2s_connections_per_node, exmpp_jid:make_bare_jid(To)) of
Max when is_integer(Max) -> Max;
_ -> ?DEFAULT_MAX_S2S_CONNECTIONS_NUMBER_PER_NODE
end.
@@ -405,12 +430,12 @@ needed_connections_number(Ls, MaxS2SConnectionsNumber,
%% service.
%% --------------------------------------------------------------------
is_service(From, To) ->
- LFromDomain = From#jid.lserver,
+ LFromDomain = From#jid.ldomain,
case ejabberd_config:get_local_option({route_subdomains, LFromDomain}) of
s2s -> % bypass RFC 3920 10.3
false;
_ ->
- LDstDomain = To#jid.lserver,
+ LDstDomain = To#jid.ldomain,
P = fun(Domain) -> is_subdomain(LDstDomain, Domain) end,
lists:any(P, ?MYHOSTS)
end.
From 290040ad9dd88a4d5608374efcafa73510e58e0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 30 Jun 2008 15:49:58 +0000
Subject: [PATCH 019/582] o Add function to convert to and from old ejabberd
#jid record. o Move function short_jid/1 from ejabberd_c2s.
SVN Revision: 1390
---
ChangeLog | 3 +++
src/jlib.erl | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 0491d68f4..689eea395 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,9 @@
* src/ejabberd_s2s.erl: Convert to exmpp.
+ * src/jlib.erl: Add function to convert to and from old ejabberd #jid
+ record. Move function short_jid/1 from ejabberd_c2s.
+
2008-06-27 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl, src/ejabberd_s2s_out.erl,
diff --git a/src/jlib.erl b/src/jlib.erl
index 4fd897599..d6938c799 100644
--- a/src/jlib.erl
+++ b/src/jlib.erl
@@ -60,7 +60,10 @@
datetime_string_to_timestamp/1,
decode_base64/1,
encode_base64/1,
- ip_to_list/1]).
+ ip_to_list/1,
+ from_old_jid/1,
+ to_old_jid/1,
+ short_jid/1]).
-include("jlib.hrl").
@@ -683,3 +686,51 @@ ip_to_list({IP, _Port}) ->
ip_to_list(IP);
ip_to_list({A,B,C,D}) ->
lists:flatten(io_lib:format("~w.~w.~w.~w",[A,B,C,D])).
+
+% --------------------------------------------------------------------
+% Compat layer.
+% --------------------------------------------------------------------
+
+%% @spec (JID) -> New_JID
+%% JID = jid()
+%% New_JID = jid()
+%% @doc Convert a JID from its ejabberd form to its exmpp form.
+%%
+%% Empty fields are set to `undefined', not the empty string.
+
+from_old_jid(#jid{user = Node, resource = Resource,
+ luser = LNode, lresource = LResource} = JID) ->
+ {Node1, LNode1} = case Node of
+ "" -> {undefined, undefined};
+ _ -> {Node, LNode}
+ end,
+ {Resource1, LResource1} = case Resource of
+ "" -> {undefined, undefined};
+ _ -> {Resource, LResource}
+ end,
+ JID#jid{user = Node1, resource = Resource1,
+ luser = LNode1, lresource = LResource1}.
+
+%% @spec (JID) -> New_JID
+%% JID = jid()
+%% New_JID = jid()
+%% @doc Convert a JID from its exmpp form to its ejabberd form.
+%%
+%% Empty fields are set to the empty string, not `undefined'.
+
+to_old_jid(#jid{user = Node, resource = Resource,
+ luser = LNode, lresource = LResource} = JID) ->
+ {Node1, LNode1} = case Node of
+ undefined -> {"", ""};
+ _ -> {Node, LNode}
+ end,
+ {Resource1, LResource1} = case Resource of
+ undefined -> {"", ""};
+ _ -> {Resource, LResource}
+ end,
+ JID#jid{user = Node1, resource = Resource1,
+ luser = LNode1, lresource = LResource1}.
+
+short_jid(JID0) ->
+ JID = to_old_jid(JID0),
+ {JID#jid.luser, JID#jid.lserver, JID#jid.lresource}.
From cc033b3b980ab6ae15ccb5a6cbdbc4d3a53b6bf0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 30 Jun 2008 15:51:23 +0000
Subject: [PATCH 020/582] o Use the new functions from jlib. o Use the new
exmpp_xml:node_to_list/3.
SVN Revision: 1391
---
ChangeLog | 4 ++
src/ejabberd_c2s.erl | 90 +++++++++++++++++++---------------------
src/ejabberd_s2s.erl | 12 +++---
src/ejabberd_s2s_in.erl | 12 +++---
src/ejabberd_s2s_out.erl | 4 +-
5 files changed, 61 insertions(+), 61 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 689eea395..dacc736dd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,10 @@
* src/jlib.erl: Add function to convert to and from old ejabberd #jid
record. Move function short_jid/1 from ejabberd_c2s.
+ * src/ejabberd_c2s.erl, src/ejabberd_s2s.erl, src/ejabberd_s2s_in.erl,
+ src/ejabberd_s2s_out.erl: Use the new functions from jlib. Use the new
+ exmpp_xml:node_to_list/3.
+
2008-06-27 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl, src/ejabberd_s2s_out.erl,
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 828df898c..26c696f72 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -392,7 +392,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
try
JID = exmpp_jid:make_jid(U, StateData#state.server, R),
% XXX OLD FORMAT: JID.
- JIDOld = exmpp_jid:to_ejabberd_jid(JID),
+ JIDOld = jlib:to_old_jid(JID),
case acl:match_rule(StateData#state.server,
StateData#state.access, JIDOld) of
allow ->
@@ -418,7 +418,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = short_jid(
+ LJID = jlib:short_jid(
exmpp_jid:jid_to_bare_jid(JID)),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
@@ -719,7 +719,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
R = StateData#state.resource,
JID = StateData#state.jid,
% XXX OLD FORMAT: JID.
- JIDOld = exmpp_jid:to_ejabberd_jid(JID),
+ JIDOld = jlib:to_old_jid(JID),
true = exmpp_server_session:want_establishment(El),
case acl:match_rule(StateData#state.server,
StateData#state.access, JIDOld) of
@@ -741,7 +741,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = short_jid(exmpp_jid:jid_to_bare_jid(JID)),
+ LJID = jlib:short_jid(exmpp_jid:jid_to_bare_jid(JID)),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList =
@@ -823,8 +823,8 @@ session_established({xmlstreamelement, El}, StateData) ->
PresenceEl = exmpp_xml:xmlelement_to_xmlel(PresenceElOld,
[?DEFAULT_NS], ?PREFIXED_NS),
% XXX OLD FORMAT: PresenceElOld, *JID.
- FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
- ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
+ FromJIDOld = jlib:to_old_jid(FromJID),
+ ToJIDOld = jlib:to_old_jid(ToJID),
ejabberd_hooks:run(
user_send_packet,
Server,
@@ -843,8 +843,8 @@ session_established({xmlstreamelement, El}, StateData) ->
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
% XXX OLD FORMAT: JIDs.
- FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
- ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
+ FromJIDOld = jlib:to_old_jid(FromJID),
+ ToJIDOld = jlib:to_old_jid(ToJID),
case exmpp_iq:get_payload(El) of
#xmlel{ns = ?NS_PRIVACY} ->
process_privacy_iq(
@@ -866,8 +866,8 @@ session_established({xmlstreamelement, El}, StateData) ->
% XXX OLD FORMAT: NewElOld, JIDs.
NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
[?DEFAULT_NS], ?PREFIXED_NS),
- FromJIDOld = exmpp_jid:to_ejabberd_jid(FromJID),
- ToJIDOld = exmpp_jid:to_ejabberd_jid(ToJID),
+ FromJIDOld = jlib:to_old_jid(FromJID),
+ ToJIDOld = jlib:to_old_jid(ToJID),
ejabberd_hooks:run(user_send_packet,
Server,
[FromJIDOld, ToJIDOld, NewElOld]),
@@ -1012,16 +1012,16 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
%% XXX OLD FORMAT: From, To and Packet are in the old format.
Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
[?DEFAULT_NS], ?PREFIXED_NS),
- From = exmpp_jid:from_ejabberd_jid(FromOld),
- To = exmpp_jid:from_ejabberd_jid(ToOld),
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
{Pass, NewAttrs, NewState} =
case Packet of
#xmlel{attrs = Attrs} when ?IS_PRESENCE(Packet) ->
case exmpp_presence:get_type(Packet) of
'probe' ->
% XXX OLD FORMAT: LFrom and LBFrom.
- LFrom = short_jid(From),
- LBFrom = short_jid(exmpp_jid:jid_to_bare_jid(From)),
+ LFrom = jlib:short_jid(From),
+ LBFrom = jlib:short_jid(exmpp_jid:jid_to_bare_jid(From)),
NewStateData =
case ?SETS:is_element(
LFrom, StateData#state.pres_a) orelse
@@ -1058,7 +1058,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
{false, Attrs, NewStateData};
'error' ->
% XXX OLD FORMAT: LFrom.
- LFrom = short_jid(From),
+ LFrom = jlib:short_jid(From),
NewA = remove_element(LFrom,
StateData#state.pres_a),
{true, Attrs, StateData#state{pres_a = NewA}};
@@ -1087,8 +1087,8 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
in]) of
allow ->
% XXX OLD FORMAT: LFrom and LBFrom.
- LFrom = short_jid(From),
- LBFrom = short_jid(
+ LFrom = jlib:short_jid(From),
+ LBFrom = jlib:short_jid(
exmpp_jid:jid_to_bare_jid(From)),
%% Note contact availability
% XXX OLD FORMAT: Els are #xmlelement.
@@ -1336,7 +1336,7 @@ terminate(_Reason, StateName, StateData) ->
change_shaper(StateData, JID) ->
% XXX OLD FORMAT: JIDOld is an old #jid.
- JIDOld = exmpp_jid:to_ejabberd_jid(JID),
+ JIDOld = jlib:to_old_jid(JID),
Shaper = acl:match_rule(StateData#state.server,
StateData#state.shaper, JIDOld),
(StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
@@ -1402,8 +1402,8 @@ get_conn_type(StateData) ->
end.
process_presence_probe(From, To, StateData) ->
- LFrom = short_jid(From),
- LBFrom = short_jid(exmpp_jid:jid_to_bare_jid(From)),
+ LFrom = jlib:short_jid(From),
+ LBFrom = jlib:short_jid(exmpp_jid:jid_to_bare_jid(From)),
case StateData#state.pres_last of
undefined ->
ok;
@@ -1425,8 +1425,8 @@ process_presence_probe(From, To, StateData) ->
Cond1 ->
Packet = StateData#state.pres_last,
% XXX OLD FORMAT: From, To, Packet.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
@@ -1455,8 +1455,8 @@ process_presence_probe(From, To, StateData) ->
Cond2 ->
Packet = exmpp_presence:available(),
% XXX OLD FORMAT: From, To, Packet.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_router:route(ToOld, FromOld, PacketOld);
@@ -1546,7 +1546,7 @@ presence_update(From, Packet, StateData) ->
if
FromUnavail ->
% XXX OLD FORMAT: JID.
- JIDOld = exmpp_jid:to_ejabberd_jid(StateData#state.jid),
+ JIDOld = jlib:to_old_jid(StateData#state.jid),
ejabberd_hooks:run(user_available_hook,
StateData#state.server,
[JIDOld]),
@@ -1579,13 +1579,13 @@ presence_update(From, Packet, StateData) ->
end.
presence_track(From, To, Packet, StateData) ->
- LTo = short_jid(To),
+ LTo = jlib:short_jid(To),
User = StateData#state.user,
Server = StateData#state.server,
% XXX OLD FORMAT: From, To, Packet.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- BFromOld = exmpp_jid:to_ejabberd_jid(exmpp_jid:jid_to_bare_jid(From)),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ BFromOld = jlib:to_old_jid(exmpp_jid:jid_to_bare_jid(From)),
+ ToOld = jlib:to_old_jid(To),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
case exmpp_presence:get_type(Packet) of
@@ -1669,8 +1669,8 @@ presence_broadcast(StateData, From, JIDSet, Packet) ->
lists:foreach(fun({U, S, R}) ->
FJID = exmpp_jid:make_jid(U, S, R),
% XXX OLD FORMAT: From, FJID, Packet.
- FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
- FromOld = exmpp_jid:to_ejabberd_jid(From),
+ FJIDOld = jlib:to_old_jid(FJID),
+ FromOld = jlib:to_old_jid(From),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
@@ -1691,7 +1691,7 @@ presence_broadcast(StateData, From, JIDSet, Packet) ->
presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
% XXX OLD FORMAT: From, Packet.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
+ FromOld = jlib:to_old_jid(From),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
lists:foreach(
@@ -1700,7 +1700,7 @@ presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
true ->
FJID = exmpp_jid:make_jid(U, S, R),
% XXX OLD FORMAT: FJID.
- FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
+ FJIDOld = jlib:to_old_jid(FJID),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
@@ -1724,7 +1724,7 @@ presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
presence_broadcast_first(From, StateData, Packet) ->
Probe = exmpp_presence:probe(),
% XXX OLD FORMAT: From, Packet, Probe.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
+ FromOld = jlib:to_old_jid(From),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
ProbeOld = exmpp_xml:xmlel_to_xmlelement(Probe,
@@ -1732,7 +1732,7 @@ presence_broadcast_first(From, StateData, Packet) ->
?SETS:fold(fun({U, S, R}, X) ->
FJID = exmpp_jid:make_jid(U, S, R),
% XXX OLD FORMAT: FJID.
- FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
+ FJIDOld = jlib:to_old_jid(FJID),
ejabberd_router:route(
FromOld,
FJIDOld,
@@ -1749,7 +1749,7 @@ presence_broadcast_first(From, StateData, Packet) ->
fun({U, S, R} = JID, A) ->
FJID = exmpp_jid:make_jid(U, S, R),
% XXX OLD FORMAT: FJID.
- FJIDOld = exmpp_jid:to_ejabberd_jid(FJID),
+ FJIDOld = jlib:to_old_jid(FJID),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
@@ -1781,7 +1781,7 @@ remove_element(E, Set) ->
roster_change(IJID, ISubscription, StateData) ->
- LIJID = short_jid(IJID),
+ LIJID = jlib:short_jid(IJID),
IsFrom = (ISubscription == both) or (ISubscription == from),
IsTo = (ISubscription == both) or (ISubscription == to),
OldIsFrom = ?SETS:is_element(LIJID, StateData#state.pres_f),
@@ -1805,8 +1805,8 @@ roster_change(IJID, ISubscription, StateData) ->
From = StateData#state.jid,
To = IJID,
% XXX OLD FORMAT: From, To.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
Cond1 = (not StateData#state.pres_invis) and IsFrom
and (not OldIsFrom),
Cond2 = (not IsFrom) and OldIsFrom
@@ -1894,8 +1894,8 @@ process_privacy_iq(From, To,
[?DEFAULT_NS], ?PREFIXED_NS),
IQOld = jlib:iq_query_info(ElOld),
% XXX OLD FORMAT: JIDs.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
{Res, NewStateData} =
case exmpp_iq:get_type(El) of
get ->
@@ -1963,8 +1963,8 @@ resend_offline_messages(#state{user = User,
if
Pass ->
% XXX OLD FORMAT: From, To, Packet.
- From = exmpp_jid:from_ejabberd_jid(FromOld),
- To = exmpp_jid:from_ejabberd_jid(ToOld),
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
[?DEFAULT_NS], ?PREFIXED_NS),
Attrs1 = exmpp_stanza:set_sender_in_attrs(
@@ -2053,7 +2053,3 @@ fsm_reply(Reply, StateName, StateData) ->
%% Used by c2s blacklist plugins
is_ip_blacklisted({IP,_Port}) ->
ejabberd_hooks:run_fold(check_bl_c2s, false, [IP]).
-
-short_jid(JID0) ->
- JID = exmpp_jid:to_ejabberd_jid(JID0),
- {JID#jid.lnode, JID#jid.ldomain, JID#jid.lresource}.
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index 424b9fc99..8ea563768 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -76,8 +76,8 @@ start_link() ->
route(FromOld, ToOld, PacketOld) ->
% XXX OLD FORMAT: From, To, Packet.
- From = exmpp_jid:from_ejabberd_jid(FromOld),
- To = exmpp_jid:from_ejabberd_jid(ToOld),
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
[?DEFAULT_NS], ?PREFIXED_NS),
case catch do_route(From, To, Packet) of
@@ -216,8 +216,8 @@ handle_info({mnesia_system_event, {mnesia_down, Node}}, State) ->
{noreply, State};
handle_info({route, FromOld, ToOld, PacketOld}, State) ->
% XXX OLD FORMAT: From, To, Packet
- From = exmpp_jid:from_ejabberd_jid(FromOld),
- To = exmpp_jid:from_ejabberd_jid(ToOld),
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
[?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
case catch do_route(From, To, Packet) of
@@ -268,8 +268,8 @@ do_route(From, To, Packet) ->
?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
% XXX OLD FORMAT: From, To.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
case find_connection(From, To) of
{atomic, Pid} when pid(Pid) ->
?DEBUG("sending to process ~p~n", [Pid]),
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 70f5cecce..5c6e2d503 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -241,7 +241,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
SockMod == gen_tcp ->
?DEBUG("starttls", []),
Socket = StateData#state.socket,
- Proceed = exmpp_xml:document_fragment_to_list(
+ Proceed = exmpp_xml:node_to_list(
exmpp_server_tls:proceed(), [?DEFAULT_NS], ?PREFIXED_NS),
TLSOpts = StateData#state.tls_options,
TLSSocket = (StateData#state.sockmod):starttls(
@@ -408,8 +408,8 @@ stream_established({xmlstreamelement, El}, StateData) ->
(Name == 'message') or
(Name == 'presence')) ->
% XXX OLD FORMAT: From, To.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
ejabberd_hooks:run(
s2s_receive_packet,
LFrom,
@@ -431,8 +431,8 @@ stream_established({xmlstreamelement, El}, StateData) ->
(Name == 'message') or
(Name == 'presence')) ->
% XXX OLD FORMAT: From, To.
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
ejabberd_hooks:run(
s2s_receive_packet,
LFrom,
@@ -574,7 +574,7 @@ send_element(StateData, El) ->
change_shaper(StateData, Host, JID) ->
% XXX OLD FORMAT: JIDOld is an old #jid.
- JIDOld = exmpp_jid:to_ejabberd_jid(JID),
+ JIDOld = jlib:to_old_jid(JID),
Shaper = acl:match_rule(Host, StateData#state.shaper, JIDOld),
(StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index 19f68d25e..45a92b8f6 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -821,8 +821,8 @@ bounce_element(El, Condition) ->
% This is handled by C2S and S2S send_element functions.
ErrOld = exmpp_xml:xmlel_to_xmlelement(Err,
[?NS_JABBER_CLIENT], ?PREFIXED_NS),
- FromOld = exmpp_jid:to_ejabberd_jid(From),
- ToOld = exmpp_jid:to_ejabberd_jid(To),
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
ejabberd_router:route(ToOld, FromOld, ErrOld)
end.
From 06965000a5e7afa72d87b82b7a6baae1d2db6195 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 30 Jun 2008 16:55:03 +0000
Subject: [PATCH 021/582] Before doing any routing, the router print a warning
if old structures are used. Then it converts the structures to the old format
and route them. The router doesn't care about the structures format but the
conversion is necesary for code called from this module.
In C2S and S2S, no conversion is done before calling
ejabberd_router:route/3.
SVN Revision: 1392
---
ChangeLog | 10 +++++
src/ejabberd_c2s.erl | 85 ++++++++++++----------------------------
src/ejabberd_router.erl | 61 +++++++++++++++++++++++-----
src/ejabberd_s2s.erl | 5 +--
src/ejabberd_s2s_in.erl | 4 +-
src/ejabberd_s2s_out.erl | 9 +----
6 files changed, 91 insertions(+), 83 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index dacc736dd..c773f335a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -16,6 +16,16 @@
src/ejabberd_s2s_out.erl: Use the new functions from jlib. Use the new
exmpp_xml:node_to_list/3.
+ * src/ejabberd_router.erl: Before doing any routing, the router print
+ a warning if old structures are used. Then it converts the structures
+ to the old format and route them. The router doesn't care about the
+ structures format but the conversion is necesary for code called from
+ this module.
+
+ * src/ejabberd_c2s.erl, src/ejabberd_s2s.erl, src/ejabberd_s2s_in.erl,
+ src/ejabberd_s2s_out.erl: No conversion is done before calling
+ ejabberd_router:route/3.
+
2008-06-27 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl, src/ejabberd_s2s_out.erl,
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 26c696f72..91a866d47 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -857,9 +857,8 @@ session_established({xmlstreamelement, El}, StateData) ->
user_send_packet,
Server,
[FromJIDOld, ToJIDOld, NewElOld]),
- % XXX OLD FORMAT: NewElOld.
ejabberd_router:route(
- FromJIDOld, ToJIDOld, NewElOld),
+ FromJID, ToJID, NewEl),
StateData
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'message'} ->
@@ -871,8 +870,7 @@ session_established({xmlstreamelement, El}, StateData) ->
ejabberd_hooks:run(user_send_packet,
Server,
[FromJIDOld, ToJIDOld, NewElOld]),
- % XXX OLD FORMAT: NewElOld.
- ejabberd_router:route(FromJIDOld, ToJIDOld, NewElOld),
+ ejabberd_router:route(FromJID, ToJID, NewEl),
StateData;
_ ->
StateData
@@ -1186,10 +1184,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
[] ->
Err = exmpp_stanza:error('feature-not-implemented'),
Res = exmpp_iq:error(Packet, Err),
- % XXX OLD FORMAT: To, From, Res.
- ResOld = exmpp_xml:xmlel_to_xmlelement(
- Res, [?DEFAULT_NS], ?PREFIXED_NS),
- ejabberd_router:route(ToOld, FromOld, ResOld)
+ ejabberd_router:route(To, From, Res)
end,
{false, Attrs, StateData};
_ ->
@@ -1208,11 +1203,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
Err = exmpp_stanza:error(
'feature-not-implemented'),
Res = exmpp_iq:error(Packet, Err),
- % XXX OLD FORMAT: To, From, Res.
- ResOld = exmpp_xml:xmlel_to_xmlelement(
- Res,
- [?DEFAULT_NS], ?PREFIXED_NS),
- ejabberd_router:route(ToOld, FromOld, ResOld),
+ ejabberd_router:route(To, From, Res),
{false, Attrs, StateData}
end
end;
@@ -1446,20 +1437,14 @@ process_presence_probe(From, To, StateData) ->
%% Don't route a presence probe to oneself
case From == To of
false ->
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(ToOld, FromOld, PacketOld);
+ ejabberd_router:route(To, From, Packet);
true ->
ok
end
end;
Cond2 ->
Packet = exmpp_presence:available(),
- % XXX OLD FORMAT: From, To, Packet.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
- ejabberd_router:route(ToOld, FromOld, PacketOld);
+ ejabberd_router:route(To, From, Packet);
true ->
ok
end
@@ -1584,21 +1569,19 @@ presence_track(From, To, Packet, StateData) ->
Server = StateData#state.server,
% XXX OLD FORMAT: From, To, Packet.
FromOld = jlib:to_old_jid(From),
- BFromOld = jlib:to_old_jid(exmpp_jid:jid_to_bare_jid(From)),
+ BFrom = exmpp_jid:jid_to_bare_jid(From),
ToOld = jlib:to_old_jid(To),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
case exmpp_presence:get_type(Packet) of
'unavailable' ->
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(FromOld, ToOld, PacketOld),
+ ejabberd_router:route(From, To, Packet),
I = remove_element(LTo, StateData#state.pres_i),
A = remove_element(LTo, StateData#state.pres_a),
StateData#state{pres_i = I,
pres_a = A};
'invisible' ->
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(FromOld, ToOld, PacketOld),
+ ejabberd_router:route(From, To, Packet),
I = ?SETS:add_element(LTo, StateData#state.pres_i),
A = remove_element(LTo, StateData#state.pres_a),
StateData#state{pres_i = I,
@@ -1608,40 +1591,34 @@ presence_track(From, To, Packet, StateData) ->
ejabberd_hooks:run(roster_out_subscription,
Server,
[User, Server, ToOld, subscribe]),
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(BFromOld, ToOld, PacketOld),
+ ejabberd_router:route(BFrom, To, Packet),
StateData;
'subscribed' ->
% XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
[User, Server, ToOld, subscribed]),
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(BFromOld, ToOld, PacketOld),
+ ejabberd_router:route(BFrom, To, Packet),
StateData;
'unsubscribe' ->
% XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
[User, Server, ToOld, unsubscribe]),
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(BFromOld, ToOld, PacketOld),
+ ejabberd_router:route(BFrom, To, Packet),
StateData;
'unsubscribed' ->
% XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
[User, Server, ToOld, unsubscribed]),
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(BFromOld, ToOld, PacketOld),
+ ejabberd_router:route(BFrom, To, Packet),
StateData;
'error' ->
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(FromOld, ToOld, PacketOld),
+ ejabberd_router:route(From, To, Packet),
StateData;
'probe' ->
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(FromOld, ToOld, PacketOld),
+ ejabberd_router:route(From, To, Packet),
StateData;
_ ->
% XXX OLD FORMAT: From, To, Packet.
@@ -1656,8 +1633,7 @@ presence_track(From, To, Packet, StateData) ->
deny ->
ok;
allow ->
- % XXX OLD FORMAT: From, To, Packet.
- ejabberd_router:route(FromOld, ToOld, PacketOld)
+ ejabberd_router:route(From, To, Packet)
end,
I = remove_element(LTo, StateData#state.pres_i),
A = ?SETS:add_element(LTo, StateData#state.pres_a),
@@ -1684,8 +1660,7 @@ presence_broadcast(StateData, From, JIDSet, Packet) ->
deny ->
ok;
allow ->
- % XXX OLD FORMAT: From, FJID, Packet.
- ejabberd_router:route(FromOld, FJIDOld, PacketOld)
+ ejabberd_router:route(From, FJID, Packet)
end
end, ?SETS:to_list(JIDSet)).
@@ -1712,8 +1687,7 @@ presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
deny ->
ok;
allow ->
- % XXX OLD FORMAT: From, FJID, Packet.
- ejabberd_router:route(FromOld, FJIDOld, PacketOld)
+ ejabberd_router:route(From, FJID, Packet)
end;
_ ->
ok
@@ -1727,16 +1701,12 @@ presence_broadcast_first(From, StateData, Packet) ->
FromOld = jlib:to_old_jid(From),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
- ProbeOld = exmpp_xml:xmlel_to_xmlelement(Probe,
- [?DEFAULT_NS], ?PREFIXED_NS),
?SETS:fold(fun({U, S, R}, X) ->
FJID = exmpp_jid:make_jid(U, S, R),
- % XXX OLD FORMAT: FJID.
- FJIDOld = jlib:to_old_jid(FJID),
ejabberd_router:route(
- FromOld,
- FJIDOld,
- ProbeOld),
+ From,
+ FJID,
+ Probe),
X
end,
[],
@@ -1761,7 +1731,7 @@ presence_broadcast_first(From, StateData, Packet) ->
deny ->
ok;
allow ->
- ejabberd_router:route(FromOld, FJIDOld, PacketOld)
+ ejabberd_router:route(From, FJID, Packet)
end,
?SETS:add_element(JID, A)
end,
@@ -1830,8 +1800,7 @@ roster_change(IJID, ISubscription, StateData) ->
deny ->
ok;
allow ->
- % XXX OLD FORMAT: From, To, P.
- ejabberd_router:route(FromOld, ToOld, POld)
+ ejabberd_router:route(From, To, P)
end,
A = ?SETS:add_element(LIJID,
StateData#state.pres_a),
@@ -1856,8 +1825,7 @@ roster_change(IJID, ISubscription, StateData) ->
deny ->
ok;
allow ->
- % XXX OLD FORMAT: From, To, PU.
- ejabberd_router:route(FromOld, ToOld, PUOld)
+ ejabberd_router:route(From, To, PU)
end,
I = remove_element(LIJID,
StateData#state.pres_i),
@@ -1926,11 +1894,8 @@ process_privacy_iq(From, To,
[?DEFAULT_NS], ?PREFIXED_NS),
exmpp_iq:error(El, Error)
end,
- % XXX OLD FORMAT: To, From, IQRes.
- IQResOld = exmpp_xml:xmlel_to_xmlelement(IQRes,
- [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_router:route(
- ToOld, FromOld, IQResOld),
+ To, From, IQRes),
NewStateData.
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index 0085e8adf..d31c90132 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -46,8 +46,9 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-record(route, {domain, pid, local_hint}).
-record(state, {}).
@@ -64,7 +65,27 @@ start_link() ->
route(From, To, Packet) ->
- case catch do_route(From, To, Packet) of
+ % XXX OLD FORMAT: This code helps to detect old format routing.
+ {FromOld, ToOld, PacketOld} = case Packet of
+ #xmlelement{} ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nROUTE: old #xmlelement:~n~p~n~p~n~n",
+ [Packet, erlang:get_stacktrace()]),
+ {From, To, Packet};
+ _ ->
+ F = jlib:to_old_jid(From),
+ T = jlib:to_old_jid(To),
+ Default_NS = case lists:member({Packet#xmlel.ns, none},
+ Packet#xmlel.declared_ns) of
+ true -> [];
+ false -> [Packet#xmlel.ns]
+ end,
+ P = exmpp_xml:xmlel_to_xmlelement(Packet,
+ Default_NS,
+ [{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
+ {F, T, P}
+ end,
+ case catch do_route(FromOld, ToOld, PacketOld) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, To, Packet}]);
@@ -237,7 +258,27 @@ handle_cast(_Msg, State) ->
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({route, From, To, Packet}, State) ->
- case catch do_route(From, To, Packet) of
+ % XXX OLD FORMAT: This code helps to detect old format routing.
+ {FromOld, ToOld, PacketOld} = case Packet of
+ #xmlelement{} ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nROUTE: old #xmlelement:~n~p~n~p~n~n",
+ [Packet, erlang:get_stacktrace()]),
+ {From, To, Packet};
+ _ ->
+ F = jlib:to_old_jid(From),
+ T = jlib:to_old_jid(To),
+ Default_NS = case lists:member({Packet#xmlel.ns, none},
+ Packet#xmlel.declared_ns) of
+ true -> [];
+ false -> [Packet#xmlel.ns]
+ end,
+ P = exmpp_xml:xmlel_to_xmlelement(Packet,
+ Default_NS,
+ [{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
+ {F, T, P}
+ end,
+ case catch do_route(FromOld, ToOld, PacketOld) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, To, Packet}]);
@@ -303,7 +344,7 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
case ejabberd_hooks:run_fold(filter_packet,
{OrigFrom, OrigTo, OrigPacket}, []) of
{From, To, Packet} ->
- LDstDomain = To#jid.lserver,
+ LDstDomain = To#jid.ldomain,
case mnesia:dirty_read(route, LDstDomain) of
[] ->
ejabberd_s2s:route(From, To, Packet);
@@ -327,14 +368,14 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
{domain_balancing, LDstDomain}) of
undefined -> now();
random -> now();
- source -> jlib:jid_tolower(From);
- destination -> jlib:jid_tolower(To);
+ source -> jlib:short_jid(From);
+ destination -> jlib:short_jid(To);
bare_source ->
- jlib:jid_remove_resource(
- jlib:jid_tolower(From));
+ jlib:short_jid(
+ exmpp_jid:jid_to_bare_jid(From));
bare_destination ->
- jlib:jid_remove_resource(
- jlib:jid_tolower(To))
+ jlib:short_jid(
+ exmpp_jid:jid_tl_bare_jid(To))
end,
case get_component_number(LDstDomain) of
undefined ->
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index 8ea563768..a5f67fa9f 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -292,10 +292,7 @@ do_route(From, To, Packet) ->
_ ->
Err = exmpp_stanza:reply_with_error(Packet,
exmpp_stanza:error('service-unavailable')),
- % XXX OLD FORMAT: Err.
- ErrOld = exmpp_xml:xmlel_to_xmlelement(Err,
- [?DEFAULT_NS], ?PREFIXED_NS),
- ejabberd_router:route(ToOld, FromOld, ErrOld)
+ ejabberd_router:route(To, From, Err)
end,
false
end.
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 5c6e2d503..6504ec9f8 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -415,7 +415,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
LFrom,
[FromOld, ToOld, ElOld]),
ejabberd_router:route(
- FromOld, ToOld, ElOld);
+ From, To, El);
true ->
error
end;
@@ -438,7 +438,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
LFrom,
[FromOld, ToOld, ElOld]),
ejabberd_router:route(
- FromOld, ToOld, ElOld);
+ From, To, El);
true ->
error
end;
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index 45a92b8f6..bcf5b811b 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -816,14 +816,9 @@ bounce_element(El, Condition) ->
Err = exmpp_stanza:reply_with_error(El, Error),
From = exmpp_jid:string_to_jid(exmpp_stanza:get_sender(El)),
To = exmpp_jid:string_to_jid(exmpp_stanza:get_recipient(El)),
- % XXX OLD FORMAT: From, To, Err.
- % XXX No namespace conversion (:server <-> :client) is done.
+ % No namespace conversion (:server <-> :client) is done.
% This is handled by C2S and S2S send_element functions.
- ErrOld = exmpp_xml:xmlel_to_xmlelement(Err,
- [?NS_JABBER_CLIENT], ?PREFIXED_NS),
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- ejabberd_router:route(ToOld, FromOld, ErrOld)
+ ejabberd_router:route(To, From, Err)
end.
bounce_queue(Q, Condition) ->
From 87218e1447a2d47166f35fb220ed94d34a90c4b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 07:49:57 +0000
Subject: [PATCH 022/582] Convert to exmpp.
SVN Revision: 1393
---
ChangeLog | 4 +
src/ejabberd_sm.erl | 228 +++++++++++++++++++++++++++-----------------
2 files changed, 144 insertions(+), 88 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c773f335a..6cb3c2887 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-01 Jean-Sébastien Pédron
+
+ * src/ejabberd_sm.erl: Convert to exmpp.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 2d4b7c5b9..acb18341f 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -56,8 +56,9 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("ejabberd_ctl.hrl").
-record(session, {sid, usr, us, priority, info}).
@@ -66,6 +67,20 @@
%% default value for the maximum number of user connections
-define(MAX_USER_SESSIONS, infinity).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, ?NS_JABBER_CLIENT).
+-define(PREFIXED_NS, [
+ {?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}
+]).
+
+% XXX OLD FORMAT: Re-include jlib.hrl (after clean-up).
+-record(iq, {id = "",
+ type,
+ xmlns = "",
+ lang = "",
+ sub_el}).
+
%%====================================================================
%% API
%%====================================================================
@@ -76,7 +91,12 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-route(From, To, Packet) ->
+route(FromOld, ToOld, PacketOld) ->
+ % XXX OLD FORMAT: From, To, Packet.
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ [?DEFAULT_NS], ?PREFIXED_NS),
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -88,9 +108,11 @@ route(From, To, Packet) ->
open_session(SID, User, Server, Resource, Info) ->
set_session(SID, User, Server, Resource, undefined, Info),
check_for_sessions_to_replace(User, Server, Resource),
- JID = jlib:make_jid(User, Server, Resource),
- ejabberd_hooks:run(sm_register_connection_hook, JID#jid.lserver,
- [SID, JID, Info]).
+ JID = exmpp_jid:make_jid(User, Server, Resource),
+ % XXX OLD FORMAT: JID.
+ JIDOld = jlib:to_old_jid(JID),
+ ejabberd_hooks:run(sm_register_connection_hook, JID#jid.ldomain,
+ [SID, JIDOld, Info]).
close_session(SID, User, Server, Resource) ->
Info = case mnesia:dirty_read({session, SID}) of
@@ -101,9 +123,11 @@ close_session(SID, User, Server, Resource) ->
mnesia:delete({session, SID})
end,
mnesia:sync_dirty(F),
- JID = jlib:make_jid(User, Server, Resource),
- ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.lserver,
- [SID, JID, Info]).
+ JID = exmpp_jid:make_jid(User, Server, Resource),
+ % XXX OLD FORMAT: JID.
+ JIDOld = jlib:to_old_jid(JID),
+ ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.ldomain,
+ [SID, JIDOld, Info]).
check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
case ejabberd_auth:is_user_exists(User, Server) of
@@ -114,19 +138,19 @@ check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
end.
bounce_offline_message(From, To, Packet) ->
- Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
+ Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'),
ejabberd_router:route(To, From, Err),
stop.
disconnect_removed_user(User, Server) ->
- ejabberd_sm:route(jlib:make_jid("", "", ""),
- jlib:make_jid(User, Server, ""),
- {xmlelement, "broadcast", [],
- [{exit, "User removed"}]}).
+ ejabberd_sm:route(#jid{},
+ exmpp_jid:make_bare_jid(User, Server),
+ #xmlel{name = 'broadcast',
+ children = [{exit, "User removed"}]}).
get_user_resources(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
case catch mnesia:dirty_index_read(session, US, #session.us) of
{'EXIT', _Reason} ->
@@ -136,9 +160,9 @@ get_user_resources(User, Server) ->
end.
get_user_ip(User, Server, Resource) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LResource = jlib:resourceprep(Resource),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ LResource = exmpp_stringprep:resourceprep(Resource),
USR = {LUser, LServer, LResource},
case mnesia:dirty_index_read(session, USR, #session.usr) of
[] ->
@@ -149,9 +173,9 @@ get_user_ip(User, Server, Resource) ->
end.
get_user_info(User, Server, Resource) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LResource = jlib:resourceprep(Resource),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ LResource = exmpp_stringprep:resourceprep(Resource),
USR = {LUser, LServer, LResource},
case mnesia:dirty_index_read(session, USR, #session.usr) of
[] ->
@@ -166,23 +190,23 @@ get_user_info(User, Server, Resource) ->
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
set_session(SID, User, Server, Resource, Priority, Info),
- ejabberd_hooks:run(set_presence_hook, jlib:nameprep(Server),
+ ejabberd_hooks:run(set_presence_hook, exmpp_stringprep:nameprep(Server),
[User, Server, Resource, Presence]).
unset_presence(SID, User, Server, Resource, Status, Info) ->
set_session(SID, User, Server, Resource, undefined, Info),
- ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
+ ejabberd_hooks:run(unset_presence_hook, exmpp_stringprep:nameprep(Server),
[User, Server, Resource, Status]).
close_session_unset_presence(SID, User, Server, Resource, Status) ->
close_session(SID, User, Server, Resource),
- ejabberd_hooks:run(unset_presence_hook, jlib:nameprep(Server),
+ ejabberd_hooks:run(unset_presence_hook, exmpp_stringprep:nameprep(Server),
[User, Server, Resource, Status]).
get_session_pid(User, Server, Resource) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LResource = jlib:resourceprep(Resource),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ LResource = exmpp_stringprep:resourceprep(Resource),
USR = {LUser, LServer, LResource},
case catch mnesia:dirty_index_read(session, USR, #session.usr) of
[#session{sid = {_, Pid}}] -> Pid;
@@ -204,7 +228,7 @@ dirty_get_my_sessions_list() ->
['$_']}]).
get_vh_session_list(Server) ->
- LServer = jlib:nameprep(Server),
+ LServer = exmpp_stringprep:nameprep(Server),
mnesia:dirty_select(
session,
[{#session{usr = '$1', _ = '_'},
@@ -287,7 +311,12 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
-handle_info({route, From, To, Packet}, State) ->
+handle_info({route, FromOld, ToOld, PacketOld}, State) ->
+ % XXX OLD FORMAT: From, To, Packet.
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ [?DEFAULT_NS], ?PREFIXED_NS),
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -339,9 +368,9 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
set_session(SID, User, Server, Resource, Priority, Info) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LResource = jlib:resourceprep(Resource),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ LResource = exmpp_stringprep:resourceprep(Resource),
US = {LUser, LServer},
USR = {LUser, LServer, LResource},
F = fun() ->
@@ -371,45 +400,49 @@ clean_table_from_bad_node(Node) ->
do_route(From, To, Packet) ->
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
- #jid{user = User, server = Server,
- luser = LUser, lserver = LServer, lresource = LResource} = To,
- {xmlelement, Name, Attrs, _Els} = Packet,
+ #jid{node = User, domain = Server,
+ lnode = LUser, ldomain = LServer, lresource = LResource} = To,
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
case LResource of
- "" ->
- case Name of
- "presence" ->
+ undefined ->
+ case Packet of
+ _ when ?IS_PRESENCE(Packet) ->
{Pass, _Subsc} =
- case xml:get_attr_s("type", Attrs) of
- "subscribe" ->
- Reason = xml:get_path_s(
- Packet,
- [{elem, "status"}, cdata]),
+ case exmpp_presence:get_type(Packet) of
+ 'subscribe' ->
+ Reason = exmpp_presence:get_status(Packet),
+ % XXX OLD FORMAT: From.
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
- [User, Server, From, subscribe, Reason]),
+ [User, Server, FromOld, subscribe, Reason]),
true};
- "subscribed" ->
+ 'subscribed' ->
+ % XXX OLD FORMAT: From.
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
- [User, Server, From, subscribed, ""]),
+ [User, Server, FromOld, subscribed, ""]),
true};
- "unsubscribe" ->
+ 'unsubscribe' ->
+ % XXX OLD FORMAT: From.
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
- [User, Server, From, unsubscribe, ""]),
+ [User, Server, FromOld, unsubscribe, ""]),
true};
- "unsubscribed" ->
+ 'unsubscribed' ->
+ % XXX OLD FORMAT: From.
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
- [User, Server, From, unsubscribed, ""]),
+ [User, Server, FromOld, unsubscribed, ""]),
true};
_ ->
{true, false}
@@ -421,21 +454,21 @@ do_route(From, To, Packet) ->
fun({_, R}) ->
do_route(
From,
- jlib:jid_replace_resource(To, R),
+ exmpp_jid:bare_jid_to_jid(To, R),
Packet)
end, PResources);
true ->
ok
end;
- "message" ->
+ _ when ?IS_MESSAGE(Packet) ->
route_message(From, To, Packet);
- "iq" ->
+ _ when ?IS_IQ(Packet) ->
process_iq(From, To, Packet);
- "broadcast" ->
+ #xmlel{name = 'broadcast'} ->
lists:foreach(
fun(R) ->
do_route(From,
- jlib:jid_replace_resource(To, R),
+ exmpp_jid:bare_jid_to_jid(To, R),
Packet)
end, get_user_resources(User, Server));
_ ->
@@ -445,17 +478,17 @@ do_route(From, To, Packet) ->
USR = {LUser, LServer, LResource},
case mnesia:dirty_index_read(session, USR, #session.usr) of
[] ->
- case Name of
- "message" ->
+ case Packet of
+ _ when ?IS_MESSAGE(Packet) ->
route_message(From, To, Packet);
- "iq" ->
- case xml:get_attr_s("type", Attrs) of
- "error" -> ok;
- "result" -> ok;
+ _ when ?IS_IQ(Packet) ->
+ case exmpp_iq:get_type(Packet) of
+ 'error' -> ok;
+ 'result' -> ok;
_ ->
Err =
- jlib:make_error_reply(
- Packet, ?ERR_RECIPIENT_UNAVAILABLE),
+ exmpp_iq:error(Packet,
+ 'service-unavailable'),
ejabberd_router:route(To, From, Err)
end;
_ ->
@@ -465,21 +498,29 @@ do_route(From, To, Packet) ->
Session = lists:max(Ss),
Pid = element(2, Session#session.sid),
?DEBUG("sending to process ~p~n", [Pid]),
- Pid ! {route, From, To, Packet}
+ % XXX OLD FORMAT: From, To, Packet.
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ Pid ! {route, FromOld, ToOld, PacketOld}
end
end.
route_message(From, To, Packet) ->
- LUser = To#jid.luser,
- LServer = To#jid.lserver,
+ LUser = To#jid.lnode,
+ LServer = To#jid.ldomain,
PrioRes = get_user_present_resources(LUser, LServer),
+ % XXX OLD FORMAT: From, To, Packet.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
case catch lists:max(PrioRes) of
{Priority, _R} when is_integer(Priority), Priority >= 0 ->
lists:foreach(
%% Route messages to all priority that equals the max, if
%% positive
fun({P, R}) when P == Priority ->
- LResource = jlib:resourceprep(R),
+ LResource = exmpp_stringprep:resourceprep(R),
USR = {LUser, LServer, LResource},
case mnesia:dirty_index_read(session, USR, #session.usr) of
[] ->
@@ -488,7 +529,8 @@ route_message(From, To, Packet) ->
Session = lists:max(Ss),
Pid = element(2, Session#session.sid),
?DEBUG("sending to process ~p~n", [Pid]),
- Pid ! {route, From, To, Packet}
+ % XXX OLD FORMAT: From, To, Packet.
+ Pid ! {route, FromOld, ToOld, PacketOld}
end;
%% Ignore other priority:
({_Prio, _Res}) ->
@@ -496,22 +538,23 @@ route_message(From, To, Packet) ->
end,
PrioRes);
_ ->
- case xml:get_tag_attr_s("type", Packet) of
- "error" ->
+ case exmpp_message:get_type(Packet) of
+ 'error' ->
ok;
- "groupchat" ->
+ 'groupchat' ->
bounce_offline_message(From, To, Packet);
- "headline" ->
+ 'headline' ->
bounce_offline_message(From, To, Packet);
_ ->
case ejabberd_auth:is_user_exists(LUser, LServer) of
true ->
+ % XXX OLD FORMAT: From, To, Packet.
ejabberd_hooks:run(offline_message_hook,
LServer,
- [From, To, Packet]);
+ [FromOld, ToOld, PacketOld]);
_ ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_SERVICE_UNAVAILABLE),
+ Err = exmpp_stanza:reply_with_error(
+ Packet, 'service-unaivailable'),
ejabberd_router:route(To, From, Err)
end
end
@@ -557,9 +600,9 @@ get_user_present_resources(LUser, LServer) ->
%% On new session, check if some existing connections need to be replace
check_for_sessions_to_replace(User, Server, Resource) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
- LResource = jlib:resourceprep(Resource),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ LResource = exmpp_stringprep:resourceprep(Resource),
%% TODO: Depending on how this is executed, there could be an unneeded
%% replacement for max_sessions. We need to check this at some point.
@@ -606,7 +649,7 @@ check_max_sessions(LUser, LServer) ->
%% Defaults to infinity
get_max_user_sessions(LUser, Host) ->
case acl:match_rule(
- Host, max_user_sessions, jlib:make_jid(LUser, Host, "")) of
+ Host, max_user_sessions, exmpp_jid:make_bare_jid(LUser, Host)) of
Max when is_integer(Max) -> Max;
infinity -> infinity;
_ -> ?MAX_USER_SESSIONS
@@ -616,32 +659,41 @@ get_max_user_sessions(LUser, Host) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
process_iq(From, To, Packet) ->
- IQ = jlib:iq_query_info(Packet),
+ % XXX OLD FORMAT: From, To, Packet.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ IQ = jlib:iq_query_info(PacketOld),
case IQ of
#iq{xmlns = XMLNS} ->
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
case ets:lookup(sm_iqtable, {XMLNS, Host}) of
[{_, Module, Function}] ->
- ResIQ = Module:Function(From, To, IQ),
+ % XXX OLD FORMAT: From, To, IQ.
+ ResIQ = Module:Function(FromOld, ToOld, IQ),
if
ResIQ /= ignore ->
- ejabberd_router:route(To, From,
- jlib:iq_to_xml(ResIQ));
+ % XXX OLD FORMAT: ResIQ.
+ ReplyOld = jlib:iq_to_xml(ResIQ),
+ Reply = exmpp_xml:xmlelement_to_xmlel(ReplyOld,
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ ejabberd_router:route(To, From, Reply);
true ->
ok
end;
[{_, Module, Function, Opts}] ->
+ % XXX OLD FORMAT: From, To, IQ.
gen_iq_handler:handle(Host, Module, Function, Opts,
- From, To, IQ);
+ FromOld, ToOld, IQ);
[] ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_SERVICE_UNAVAILABLE),
+ Err = exmpp_iq:error(Packet, 'service-unavailable'),
ejabberd_router:route(To, From, Err)
end;
reply ->
ok;
_ ->
- Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
+ Err = exmpp_iq:error(Packet, 'bad-request'),
ejabberd_router:route(To, From, Err),
ok
end.
From 8c33e12616109fd94d764e8b78158a16f2b29e34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 08:01:06 +0000
Subject: [PATCH 023/582] Use the new clause of
exmpp_stanza:reply_with_error/2, exmpp_iq:error/2,
exmpp_iq:error_without_original/2 and the new exmpp_jid:make_bare_jid/1.
SVN Revision: 1394
---
ChangeLog | 6 ++++++
src/ejabberd_c2s.erl | 29 ++++++++++++-----------------
src/ejabberd_s2s.erl | 2 +-
src/ejabberd_s2s_in.erl | 2 +-
src/ejabberd_s2s_out.erl | 3 +--
5 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 6cb3c2887..e6197bc00 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,12 @@
* src/ejabberd_sm.erl: Convert to exmpp.
+ * src/ejabberd_c2s.erl, src/ejabberd_s2s.erl, src/ejabberd_s2s_in.erl,
+ src/ejabberd_s2s_out.erl: Use the new clause of
+ exmpp_stanza:reply_with_error/2, exmpp_iq:error/2,
+ exmpp_iq:error_without_original/2 and the new
+ exmpp_jid:make_bare_jid/1.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 91a866d47..86892b195 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -124,6 +124,7 @@
[?NS_JABBER_CLIENT], [{?NS_XMPP, "stream"}])).
-define(ERR_FEATURE_NOT_IMPLEMENTED, ?STANZA_ERROR('feature-not-implemented')).
+% XXX OLD FORMAT: Re-include jlib.hrl (after clean-up).
-record(iq, {id = "",
type,
xmlns = "",
@@ -236,7 +237,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
true ->
Lang = exmpp_stream:get_lang(Opening),
change_shaper(StateData,
- exmpp_jid:make_bare_jid(undefined, Server)),
+ exmpp_jid:make_bare_jid(Server)),
case exmpp_stream:get_version(Opening) of
{1, 0} ->
send_element(StateData, Header),
@@ -442,8 +443,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
"(~w) Failed legacy authentication for ~s",
[StateData#state.socket,
exmpp_jid:jid_to_string(JID)]),
- Err = exmpp_stanza:error('not-authorized'),
- Res = exmpp_iq:error_without_original(El, Err),
+ Res = exmpp_iq:error_without_original(El,
+ 'not-authorized'),
send_element(StateData, Res),
fsm_next_state(wait_for_auth, StateData)
end;
@@ -452,8 +453,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
"(~w) Forbidden legacy authentication for ~s",
[StateData#state.socket,
exmpp_jid:jid_to_string(JID)]),
- Err = exmpp_stanza:error('not-allowed'),
- Res = exmpp_iq:error_without_original(El, Err),
+ Res = exmpp_iq:error_without_original(El,
+ 'not-allowed'),
send_element(StateData, Res),
fsm_next_state(wait_for_auth, StateData)
end
@@ -463,8 +464,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
"(~w) Forbidden legacy authentication for "
"username '~s' with resource '~s'",
[StateData#state.socket, U, R]),
- Err1 = exmpp_stanza:error('jid-malformed'),
- Res1 = exmpp_iq:error_without_original(El, Err1),
+ Res1 = exmpp_iq:error_without_original(El, 'jid-malformed'),
send_element(StateData, Res1),
fsm_next_state(wait_for_auth, StateData)
end;
@@ -1134,8 +1134,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
{false, Attrs, StateData}
end
end;
- % XXX OLD FORMAT: broadcast?
- #xmlel{ns = _NS, name = 'broadcast', attrs = Attrs} ->
+ #xmlel{name = 'broadcast', attrs = Attrs} ->
% XXX OLD FORMAT: Els are #xmlelement.
Els = PacketOld#xmlelement.children,
?DEBUG("broadcast~n~p~n", [Els]),
@@ -1182,8 +1181,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
gen_iq_handler:handle(Host, Module, Function, Opts,
FromOld, ToOld, IQ);
[] ->
- Err = exmpp_stanza:error('feature-not-implemented'),
- Res = exmpp_iq:error(Packet, Err),
+ Res = exmpp_iq:error(Packet, 'feature-not-implemented'),
ejabberd_router:route(To, From, Res)
end,
{false, Attrs, StateData};
@@ -1200,9 +1198,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
allow ->
{true, Attrs, StateData};
deny ->
- Err = exmpp_stanza:error(
- 'feature-not-implemented'),
- Res = exmpp_iq:error(Packet, Err),
+ Res = exmpp_iq:error(Packet, 'feature-not-implemented'),
ejabberd_router:route(To, From, Res),
{false, Attrs, StateData}
end
@@ -1975,10 +1971,9 @@ process_unauthenticated_stanza(StateData, El) ->
% The only reasonable IQ's here are auth and register IQ's
% They contain secrets, so don't include subelements to response
ResIQ = exmpp_iq:error_without_original(El,
- exmpp_stanza:error(El#xmlel.ns, 'service-unavailable')),
+ 'service-unavailable'),
Res1 = exmpp_stanza:set_sender(ResIQ,
- exmpp_jid:make_bare_jid(undefined,
- StateData#state.server)),
+ exmpp_jid:make_bare_jid(StateData#state.server)),
Res2 = exmpp_stanza:remove_recipient(Res1),
send_element(StateData, Res2);
_ ->
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index a5f67fa9f..e023cd4a2 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -291,7 +291,7 @@ do_route(From, To, Packet) ->
"result" -> ok;
_ ->
Err = exmpp_stanza:reply_with_error(Packet,
- exmpp_stanza:error('service-unavailable')),
+ 'service-unavailable'),
ejabberd_router:route(To, From, Err)
end,
false
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 6504ec9f8..b3229a69e 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -346,7 +346,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
Conns = ?DICT:store({LFrom, LTo}, wait_for_verification,
StateData#state.connections),
change_shaper(StateData, LTo,
- exmpp_jid:make_bare_jid(undefined, LFrom)),
+ exmpp_jid:make_bare_jid(LFrom)),
{next_state,
stream_established,
StateData#state{connections = Conns,
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index bcf5b811b..93171ced3 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -812,8 +812,7 @@ bounce_element(El, Condition) ->
"error" -> ok;
"result" -> ok;
_ ->
- Error = exmpp_stanza:error(El#xmlel.ns, Condition),
- Err = exmpp_stanza:reply_with_error(El, Error),
+ Err = exmpp_stanza:reply_with_error(El, Condition),
From = exmpp_jid:string_to_jid(exmpp_stanza:get_sender(El)),
To = exmpp_jid:string_to_jid(exmpp_stanza:get_recipient(El)),
% No namespace conversion (:server <-> :client) is done.
From 83a33726ce33e700257f406a8bb0b28bb553b790 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 09:12:59 +0000
Subject: [PATCH 024/582] Add function short_bare_jid/1.
SVN Revision: 1395
---
ChangeLog | 2 ++
src/jlib.erl | 33 +++++++++++++++++++--------------
2 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e6197bc00..54deda3d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,8 @@
exmpp_iq:error_without_original/2 and the new
exmpp_jid:make_bare_jid/1.
+ * src/jlib.erl: Add function short_bare_jid/1.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/jlib.erl b/src/jlib.erl
index d6938c799..4a0fbcbfa 100644
--- a/src/jlib.erl
+++ b/src/jlib.erl
@@ -63,7 +63,8 @@
ip_to_list/1,
from_old_jid/1,
to_old_jid/1,
- short_jid/1]).
+ short_jid/1,
+ short_bare_jid/1]).
-include("jlib.hrl").
@@ -699,14 +700,14 @@ ip_to_list({A,B,C,D}) ->
%% Empty fields are set to `undefined', not the empty string.
from_old_jid(#jid{user = Node, resource = Resource,
- luser = LNode, lresource = LResource} = JID) ->
+ luser = LNode, lresource = LResource} = JID) ->
{Node1, LNode1} = case Node of
- "" -> {undefined, undefined};
- _ -> {Node, LNode}
+ "" -> {undefined, undefined};
+ _ -> {Node, LNode}
end,
{Resource1, LResource1} = case Resource of
- "" -> {undefined, undefined};
- _ -> {Resource, LResource}
+ "" -> {undefined, undefined};
+ _ -> {Resource, LResource}
end,
JID#jid{user = Node1, resource = Resource1,
luser = LNode1, lresource = LResource1}.
@@ -719,18 +720,22 @@ from_old_jid(#jid{user = Node, resource = Resource,
%% Empty fields are set to the empty string, not `undefined'.
to_old_jid(#jid{user = Node, resource = Resource,
- luser = LNode, lresource = LResource} = JID) ->
+ luser = LNode, lresource = LResource} = JID) ->
{Node1, LNode1} = case Node of
- undefined -> {"", ""};
- _ -> {Node, LNode}
+ undefined -> {"", ""};
+ _ -> {Node, LNode}
end,
{Resource1, LResource1} = case Resource of
- undefined -> {"", ""};
- _ -> {Resource, LResource}
+ undefined -> {"", ""};
+ _ -> {Resource, LResource}
end,
JID#jid{user = Node1, resource = Resource1,
luser = LNode1, lresource = LResource1}.
-short_jid(JID0) ->
- JID = to_old_jid(JID0),
- {JID#jid.luser, JID#jid.lserver, JID#jid.lresource}.
+short_jid(JID) ->
+ JID1 = to_old_jid(JID),
+ {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}.
+
+short_bare_jid(JID) ->
+ JID1 = to_old_jid(exmpp_jid:jid_to_bare_jid(JID)),
+ {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}.
From b9074097da43cb4637aaa1fe82f7df21f8331d71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 09:13:49 +0000
Subject: [PATCH 025/582] Forgot to convert a from the new to the
old record.
SVN Revision: 1396
---
ChangeLog | 3 +++
src/ejabberd_sm.erl | 5 ++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 54deda3d2..74200742b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,9 @@
* src/jlib.erl: Add function short_bare_jid/1.
+ * src/ejabberd_sm.erl: Forgot to convert a from the new to
+ the old record.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index acb18341f..8ca59bfbc 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -190,8 +190,11 @@ get_user_info(User, Server, Resource) ->
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
set_session(SID, User, Server, Resource, Priority, Info),
+ % XXX OLD FORMAT: Presence.
+ PresenceOld = exmpp_xml:xmlel_to_xmlelement(Presence,
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(set_presence_hook, exmpp_stringprep:nameprep(Server),
- [User, Server, Resource, Presence]).
+ [User, Server, Resource, PresenceOld]).
unset_presence(SID, User, Server, Resource, Status, Info) ->
set_session(SID, User, Server, Resource, undefined, Info),
From f55274c7fb8c4efe5fb96f9abe365795aaac9c02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 09:17:48 +0000
Subject: [PATCH 026/582] o Use jlib:short_bare_jid/1. o Rewrite
is_auth_packet/1 to use new formats. o Don't convert before
calling ejabberd_sm:set_presence/7. o Don't convert broadcast children,
because it's an internal special element.
SVN Revision: 1397
---
ChangeLog | 5 ++++
src/ejabberd_c2s.erl | 71 ++++++++++++++++----------------------------
2 files changed, 31 insertions(+), 45 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 74200742b..3b009fe1d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,11 @@
* src/ejabberd_sm.erl: Forgot to convert a from the new to
the old record.
+ * src/ejabberd_c2s.erl: Use jlib:short_bare_jid/1. Rewrite
+ is_auth_packet/1 to use new formats. Don't convert before
+ calling ejabberd_sm:set_presence/7. Don't convert broadcast children,
+ because it's an internal special element.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 86892b195..f47433896 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -419,8 +419,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = jlib:short_jid(
- exmpp_jid:jid_to_bare_jid(JID)),
+ LJID = jlib:short_bare_jid(JID),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList = ejabberd_hooks:run_fold(
@@ -741,7 +740,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = jlib:short_jid(exmpp_jid:jid_to_bare_jid(JID)),
+ LJID = jlib:short_bare_jid(JID),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList =
@@ -1017,9 +1016,8 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
#xmlel{attrs = Attrs} when ?IS_PRESENCE(Packet) ->
case exmpp_presence:get_type(Packet) of
'probe' ->
- % XXX OLD FORMAT: LFrom and LBFrom.
LFrom = jlib:short_jid(From),
- LBFrom = jlib:short_jid(exmpp_jid:jid_to_bare_jid(From)),
+ LBFrom = jlib:short_bare_jid(From),
NewStateData =
case ?SETS:is_element(
LFrom, StateData#state.pres_a) orelse
@@ -1031,8 +1029,6 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
case ?SETS:is_element(
LFrom, StateData#state.pres_f) of
true ->
- % XXX OLD FORMAT: Stores short
- % JIDs.
A = ?SETS:add_element(
LFrom,
StateData#state.pres_a),
@@ -1041,8 +1037,6 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
case ?SETS:is_element(
LBFrom, StateData#state.pres_f) of
true ->
- % XXX OLD FORMAT: Stores
- % short JIDs.
A = ?SETS:add_element(
LBFrom,
StateData#state.pres_a),
@@ -1055,15 +1049,13 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
process_presence_probe(From, To, NewStateData),
{false, Attrs, NewStateData};
'error' ->
- % XXX OLD FORMAT: LFrom.
LFrom = jlib:short_jid(From),
NewA = remove_element(LFrom,
StateData#state.pres_a),
{true, Attrs, StateData#state{pres_a = NewA}};
'invisible' ->
- % XXX OLD FORMAT: Create a function to change 'type'.
Attrs1 = exmpp_stanza:set_type_in_attrs(Attrs,
- "unavailable"),
+ 'unavailable'),
{true, Attrs1, StateData};
'subscribe' ->
{true, Attrs, StateData};
@@ -1084,10 +1076,8 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
{FromOld, ToOld, PacketOld},
in]) of
allow ->
- % XXX OLD FORMAT: LFrom and LBFrom.
LFrom = jlib:short_jid(From),
- LBFrom = jlib:short_jid(
- exmpp_jid:jid_to_bare_jid(From)),
+ LBFrom = jlib:short_bare_jid(From),
%% Note contact availability
% XXX OLD FORMAT: Els are #xmlelement.
Els = PacketOld#xmlelement.children,
@@ -1135,12 +1125,9 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
end
end;
#xmlel{name = 'broadcast', attrs = Attrs} ->
- % XXX OLD FORMAT: Els are #xmlelement.
- Els = PacketOld#xmlelement.children,
- ?DEBUG("broadcast~n~p~n", [Els]),
- case Els of
+ ?DEBUG("broadcast~n~p~n", [Packet#xmlel.children]),
+ case Packet#xmlel.children of
[{item, {U, S, R} = _IJIDShort, ISubscription}] ->
- % XXX OLD FORMAT: IJID is of the form {U, S, R}.
IJID = exmpp_jid:make_jid(U, S, R),
{false, Attrs,
roster_change(IJID, ISubscription,
@@ -1177,7 +1164,6 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
% XXX OLD FORMAT: IQ is an old #iq,
% From, To.
IQ = jlib:iq_query_info(PacketOld),
- io:format("IQ = ~p~n", [IQ]),
gen_iq_handler:handle(Host, Module, Function, Opts,
FromOld, ToOld, IQ);
[] ->
@@ -1233,12 +1219,13 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
Attrs3 = exmpp_stanza:set_recipient_in_attrs(Attrs2, To),
FixedPacket = Packet#xmlel{attrs = Attrs3},
send_element(StateData, FixedPacket),
- % XXX OLD FORMAT: From, To, FixedPacket.
+ % XXX OLD FORMAT: JID, From, To, FixedPacket.
+ JIDOld = jlib:to_old_jid(StateData#state.jid),
FixedPacketOld = exmpp_xml:xmlel_to_xmlelement(FixedPacket,
[?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(user_receive_packet,
StateData#state.server,
- [StateData#state.jid, FromOld, ToOld, FixedPacketOld]),
+ [JIDOld, FromOld, ToOld, FixedPacketOld]),
% XXX OLD FORMAT: From, To, FixedPacket.
ejabberd_hooks:run(c2s_loop_debug, [{route, FromOld, ToOld, PacketOld}]),
fsm_next_state(StateName, NewState);
@@ -1345,30 +1332,27 @@ new_id() ->
is_auth_packet(El) ->
- % XXX OLD FORMAT: El.
- ElOld = exmpp_xml:xmlel_to_xmlelement(El,
- [?DEFAULT_NS], ?PREFIXED_NS),
- NS_Auth = atom_to_list(?NS_LEGACY_AUTH),
- case jlib:iq_query_info(ElOld) of
- #iq{id = ID, type = Type, xmlns = NS_Auth, sub_el = SubEl} ->
- {xmlelement, _, _, Els} = SubEl,
- {auth, ID, Type,
- get_auth_tags(Els, "", "", "", undefined)};
- _ ->
+ case exmpp_iq:is_request(El) of
+ true ->
+ {auth, exmpp_stanza:get_id(El), exmpp_iq:get_type(El),
+ get_auth_tags(El#xmlel.children,
+ undefined, undefined, undefined, undefined)};
+ false ->
false
end.
-get_auth_tags([{xmlelement, Name, _Attrs, Els}| L], U, P, D, R) ->
- CData = xml:get_cdata(Els),
+get_auth_tags([#xmlel{ns = ?NS_LEGACY_AUTH, name = Name, children = Els} | L],
+ U, P, D, R) ->
+ CData = exmpp_xml:get_cdata_from_list_as_list(Els),
case Name of
- "username" ->
+ 'username' ->
get_auth_tags(L, CData, P, D, R);
- "password" ->
+ 'password' ->
get_auth_tags(L, U, CData, D, R);
- "digest" ->
+ 'digest' ->
get_auth_tags(L, U, P, CData, R);
- "resource" ->
+ 'resource' ->
get_auth_tags(L, U, P, D, CData);
_ ->
get_auth_tags(L, U, P, D, R)
@@ -1390,7 +1374,7 @@ get_conn_type(StateData) ->
process_presence_probe(From, To, StateData) ->
LFrom = jlib:short_jid(From),
- LBFrom = jlib:short_jid(exmpp_jid:jid_to_bare_jid(From)),
+ LBFrom = jlib:short_bare_jid(From),
case StateData#state.pres_last of
undefined ->
ok;
@@ -1563,9 +1547,9 @@ presence_track(From, To, Packet, StateData) ->
LTo = jlib:short_jid(To),
User = StateData#state.user,
Server = StateData#state.server,
+ BFrom = exmpp_jid:jid_to_bare_jid(From),
% XXX OLD FORMAT: From, To, Packet.
FromOld = jlib:to_old_jid(From),
- BFrom = exmpp_jid:jid_to_bare_jid(From),
ToOld = jlib:to_old_jid(To),
PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
@@ -1839,15 +1823,12 @@ roster_change(IJID, ISubscription, StateData) ->
update_priority(Priority, Packet, StateData) ->
Info = [{ip, StateData#state.ip},{conn, StateData#state.conn}],
- % XXX OLD FORMAT: Packet.
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_sm:set_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
StateData#state.resource,
Priority,
- PacketOld,
+ Packet,
Info).
process_privacy_iq(From, To,
From ffbf8d5faa71552f52880d346e501ec5f889cedd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 09:41:32 +0000
Subject: [PATCH 027/582] Convert acl to exmpp.
SVN Revision: 1398
---
ChangeLog | 5 +++++
src/acl.erl | 4 ++--
src/ejabberd_c2s.erl | 9 +++------
src/ejabberd_s2s_in.erl | 4 +---
4 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 3b009fe1d..9c98b3e51 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,11 @@
calling ejabberd_sm:set_presence/7. Don't convert broadcast children,
because it's an internal special element.
+ * src/acl.erl: Convert to exmpp.
+
+ * src/ejabberd_c2s.erl, src/ejabberd_s2s_in.erl: acl doesn't require
+ conversion anymore.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/acl.erl b/src/acl.erl
index eed295cb8..e65c34c4a 100644
--- a/src/acl.erl
+++ b/src/acl.erl
@@ -87,7 +87,7 @@ add_list(Host, ACLs, Clear) ->
end.
normalize(A) ->
- jlib:nodeprep(A).
+ exmpp_stringprep:nodeprep(A).
normalize_spec({A, B}) ->
{A, normalize(B)};
normalize_spec({A, B, C}) ->
@@ -158,7 +158,7 @@ match_acl(ACL, JID, Host) ->
all -> true;
none -> false;
_ ->
- {User, Server, Resource} = jlib:jid_tolower(JID),
+ {User, Server, Resource} = jlib:short_jid(JID),
lists:any(fun(#acl{aclspec = Spec}) ->
case Spec of
all ->
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index f47433896..271ffabd7 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -392,10 +392,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{auth, _ID, set, {U, P, D, R}} ->
try
JID = exmpp_jid:make_jid(U, StateData#state.server, R),
- % XXX OLD FORMAT: JID.
- JIDOld = jlib:to_old_jid(JID),
case acl:match_rule(StateData#state.server,
- StateData#state.access, JIDOld) of
+ StateData#state.access, JID) of
allow ->
case ejabberd_auth:check_password_with_authmodule(
U, StateData#state.server, P,
@@ -717,11 +715,9 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
U = StateData#state.user,
R = StateData#state.resource,
JID = StateData#state.jid,
- % XXX OLD FORMAT: JID.
- JIDOld = jlib:to_old_jid(JID),
true = exmpp_server_session:want_establishment(El),
case acl:match_rule(StateData#state.server,
- StateData#state.access, JIDOld) of
+ StateData#state.access, JID) of
allow ->
?INFO_MSG("(~w) Opened session for ~s",
[StateData#state.socket,
@@ -757,6 +753,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
privacy_list = PrivList});
_ ->
% XXX OLD FORMAT: Jid.
+ JIDOld = jlib:to_old_jid(JID),
ejabberd_hooks:run(forbidden_session_hook,
StateData#state.server, [JIDOld]),
?INFO_MSG("(~w) Forbidden session for ~s",
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index b3229a69e..562033076 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -573,9 +573,7 @@ send_element(StateData, El) ->
change_shaper(StateData, Host, JID) ->
- % XXX OLD FORMAT: JIDOld is an old #jid.
- JIDOld = jlib:to_old_jid(JID),
- Shaper = acl:match_rule(Host, StateData#state.shaper, JIDOld),
+ Shaper = acl:match_rule(Host, StateData#state.shaper, JID),
(StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
From b08ae0734747053a50260b0d3fc4726b021b9681 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 09:46:57 +0000
Subject: [PATCH 028/582] acl doesn't require conversion anymore.
SVN Revision: 1399
---
src/ejabberd_c2s.erl | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 271ffabd7..8cc98e0f2 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1306,10 +1306,8 @@ terminate(_Reason, StateName, StateData) ->
%%%----------------------------------------------------------------------
change_shaper(StateData, JID) ->
- % XXX OLD FORMAT: JIDOld is an old #jid.
- JIDOld = jlib:to_old_jid(JID),
Shaper = acl:match_rule(StateData#state.server,
- StateData#state.shaper, JIDOld),
+ StateData#state.shaper, JID),
(StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
send_text(StateData, Text) ->
@@ -1674,10 +1672,6 @@ presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
presence_broadcast_first(From, StateData, Packet) ->
Probe = exmpp_presence:probe(),
- % XXX OLD FORMAT: From, Packet, Probe.
- FromOld = jlib:to_old_jid(From),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
?SETS:fold(fun({U, S, R}, X) ->
FJID = exmpp_jid:make_jid(U, S, R),
ejabberd_router:route(
@@ -1695,8 +1689,11 @@ presence_broadcast_first(From, StateData, Packet) ->
As = ?SETS:fold(
fun({U, S, R} = JID, A) ->
FJID = exmpp_jid:make_jid(U, S, R),
- % XXX OLD FORMAT: FJID.
+ % XXX OLD FORMAT: From, FJID, Packet.
+ FromOld = jlib:to_old_jid(From),
FJIDOld = jlib:to_old_jid(FJID),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
From 6f7cf2e58b770af7eb109856e4eeedd4f5e8389c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 10:20:01 +0000
Subject: [PATCH 029/582] Use a function to convert to old structures instead
of duplicating code inside the module.
SVN Revision: 1400
---
ChangeLog | 3 ++
src/ejabberd_router.erl | 62 +++++++++++++++--------------------------
2 files changed, 26 insertions(+), 39 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 9c98b3e51..a73436b6c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,6 +23,9 @@
* src/ejabberd_c2s.erl, src/ejabberd_s2s_in.erl: acl doesn't require
conversion anymore.
+ * src/ejabberd_router.erl: Use a function to convert to old
+ structures instead of duplicating code inside the module.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index d31c90132..26c494ba0 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -66,25 +66,7 @@ start_link() ->
route(From, To, Packet) ->
% XXX OLD FORMAT: This code helps to detect old format routing.
- {FromOld, ToOld, PacketOld} = case Packet of
- #xmlelement{} ->
- catch throw(for_stacktrace), % To have a stacktrace.
- io:format("~nROUTE: old #xmlelement:~n~p~n~p~n~n",
- [Packet, erlang:get_stacktrace()]),
- {From, To, Packet};
- _ ->
- F = jlib:to_old_jid(From),
- T = jlib:to_old_jid(To),
- Default_NS = case lists:member({Packet#xmlel.ns, none},
- Packet#xmlel.declared_ns) of
- true -> [];
- false -> [Packet#xmlel.ns]
- end,
- P = exmpp_xml:xmlel_to_xmlelement(Packet,
- Default_NS,
- [{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
- {F, T, P}
- end,
+ {FromOld, ToOld, PacketOld} = convert_to_old_structs(From, To, Packet),
case catch do_route(FromOld, ToOld, PacketOld) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -258,26 +240,7 @@ handle_cast(_Msg, State) ->
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({route, From, To, Packet}, State) ->
- % XXX OLD FORMAT: This code helps to detect old format routing.
- {FromOld, ToOld, PacketOld} = case Packet of
- #xmlelement{} ->
- catch throw(for_stacktrace), % To have a stacktrace.
- io:format("~nROUTE: old #xmlelement:~n~p~n~p~n~n",
- [Packet, erlang:get_stacktrace()]),
- {From, To, Packet};
- _ ->
- F = jlib:to_old_jid(From),
- T = jlib:to_old_jid(To),
- Default_NS = case lists:member({Packet#xmlel.ns, none},
- Packet#xmlel.declared_ns) of
- true -> [];
- false -> [Packet#xmlel.ns]
- end,
- P = exmpp_xml:xmlel_to_xmlelement(Packet,
- Default_NS,
- [{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
- {F, T, P}
- end,
+ {FromOld, ToOld, PacketOld} = convert_to_old_structs(From, To, Packet),
case catch do_route(FromOld, ToOld, PacketOld) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -443,3 +406,24 @@ update_tables() ->
ok
end.
+convert_to_old_structs(From, To, Packet) ->
+ % XXX OLD FORMAT: This code helps to detect old format routing.
+ if
+ is_record(Packet, xmlelement) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nROUTE: old #xmlelement:~n~p~n~p~n~n",
+ [Packet, erlang:get_stacktrace()]),
+ {From, To, Packet};
+ true ->
+ F = jlib:to_old_jid(From),
+ T = jlib:to_old_jid(To),
+ Default_NS = case lists:member({Packet#xmlel.ns, none},
+ Packet#xmlel.declared_ns) of
+ true -> [];
+ false -> [Packet#xmlel.ns]
+ end,
+ P = exmpp_xml:xmlel_to_xmlelement(Packet,
+ Default_NS,
+ [{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
+ {F, T, P}
+ end.
From 094fa47f9f0e10d65d45a9e2101c7f7ae614de01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 10:21:35 +0000
Subject: [PATCH 030/582] Convert gen_iq_handler to exmpp.
SVN Revision: 1401
---
ChangeLog | 5 +++++
src/ejabberd_c2s.erl | 7 ++-----
src/ejabberd_sm.erl | 2 +-
src/gen_iq_handler.erl | 47 ++++++++++++++++++++++++++++++++++++++----
4 files changed, 51 insertions(+), 10 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a73436b6c..13c5f29f5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -26,6 +26,11 @@
* src/ejabberd_router.erl: Use a function to convert to old
structures instead of duplicating code inside the module.
+ * src/gen_iq_handler.erl: Convert to exmpp.
+
+ * src/ejabberd_sm.erl, src/ejabberd_c2s.erl: Don't convert
+ before calling gen_iq_handler:handle/7.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 8cc98e0f2..140e23378 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1158,11 +1158,8 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
% for namespaces.
case ets:lookup(sm_iqtable, {atom_to_list(?NS_VCARD), Host}) of
[{_, Module, Function, Opts}] ->
- % XXX OLD FORMAT: IQ is an old #iq,
- % From, To.
- IQ = jlib:iq_query_info(PacketOld),
gen_iq_handler:handle(Host, Module, Function, Opts,
- FromOld, ToOld, IQ);
+ From, To, Packet);
[] ->
Res = exmpp_iq:error(Packet, 'feature-not-implemented'),
ejabberd_router:route(To, From, Res)
@@ -1935,7 +1932,7 @@ resend_subscription_requests(#state{user = User,
process_unauthenticated_stanza(StateData, El) ->
ElOld = exmpp_xml:xmlel_to_xmlelement(El, [?DEFAULT_NS], ?PREFIXED_NS),
case jlib:iq_query_info(ElOld) of
- #iq{} = IQ ->
+ IQ when is_record(IQ, iq) ->
ResOld = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
StateData#state.server,
empty,
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 8ca59bfbc..bae6ce473 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -688,7 +688,7 @@ process_iq(From, To, Packet) ->
[{_, Module, Function, Opts}] ->
% XXX OLD FORMAT: From, To, IQ.
gen_iq_handler:handle(Host, Module, Function, Opts,
- FromOld, ToOld, IQ);
+ From, To, Packet);
[] ->
Err = exmpp_iq:error(Packet, 'service-unavailable'),
ejabberd_router:route(To, From, Err)
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index 912f22c17..aeae283f7 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -41,12 +41,21 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
-record(state, {host,
module,
function}).
+% XXX OLD FORMAT: Re-include jlib.hrl (after clean-up).
+-record(iq, {id = "",
+ type,
+ xmlns = "",
+ lang = "",
+ sub_el}).
+
%%====================================================================
%% API
%%====================================================================
@@ -101,10 +110,12 @@ handle(Host, Module, Function, Opts, From, To, IQ) ->
no_queue ->
process_iq(Host, Module, Function, From, To, IQ);
{one_queue, Pid} ->
- Pid ! {process_iq, From, To, IQ};
+ {FromOld, ToOld, IQ_Rec} = convert_to_old_structs(From, To, IQ),
+ Pid ! {process_iq, FromOld, ToOld, IQ_Rec};
{queues, Pids} ->
Pid = lists:nth(erlang:phash(now(), length(Pids)), Pids),
- Pid ! {process_iq, From, To, IQ};
+ {FromOld, ToOld, IQ_Rec} = convert_to_old_structs(From, To, IQ),
+ Pid ! {process_iq, FromOld, ToOld, IQ_Rec};
parallel ->
spawn(?MODULE, process_iq, [Host, Module, Function, From, To, IQ]);
_ ->
@@ -113,14 +124,20 @@ handle(Host, Module, Function, Opts, From, To, IQ) ->
process_iq(_Host, Module, Function, From, To, IQ) ->
- case catch Module:Function(From, To, IQ) of
+ {FromOld, ToOld, IQ_Rec} = convert_to_old_structs(From, To, IQ),
+ case catch Module:Function(FromOld, ToOld, IQ_Rec) of
{'EXIT', Reason} ->
?ERROR_MSG("~p", [Reason]);
ResIQ ->
if
ResIQ /= ignore ->
+ ReplyOld = jlib:iq_to_xml(ResIQ),
+ Reply = exmpp_xml:xmlelement_to_xmlel(ReplyOld,
+ [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx},
+ {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
ejabberd_router:route(To, From,
- jlib:iq_to_xml(ResIQ));
+ Reply);
true ->
ok
end
@@ -199,3 +216,25 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+
+convert_to_old_structs(From, To, IQ) ->
+ if
+ is_record(IQ, iq) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nIQ HANDLER: old #iq:~n~p~n~p~n~n",
+ [IQ, erlang:get_stacktrace()]),
+ {From, To, IQ};
+ true ->
+ F = jlib:to_old_jid(From),
+ T = jlib:to_old_jid(To),
+ Default_NS = case lists:member({IQ#xmlel.ns, none},
+ IQ#xmlel.declared_ns) of
+ true -> [];
+ false -> [IQ#xmlel.ns]
+ end,
+ IQOld = exmpp_xml:xmlel_to_xmlelement(IQ,
+ Default_NS,
+ [{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
+ I = jlib:iq_query_info(IQOld),
+ {F, T, I}
+ end.
From d6e6432a46c8a3c10aca643acf915c894b7e2930 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 13:34:51 +0000
Subject: [PATCH 031/582] Convert to exmpp.
SVN Revision: 1402
---
ChangeLog | 2 +
src/ejabberd_local.erl | 97 +++++++++++++++++++++++++++++-------------
2 files changed, 70 insertions(+), 29 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 13c5f29f5..b4f760626 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -31,6 +31,8 @@
* src/ejabberd_sm.erl, src/ejabberd_c2s.erl: Don't convert
before calling gen_iq_handler:handle/7.
+ * src/ejabberd_local.erl: Convert to exmpp.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index b54173581..e86c030bc 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -45,8 +45,9 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-record(state, {}).
@@ -54,6 +55,13 @@
-define(IQTABLE, local_iqtable).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, ?NS_JABBER_CLIENT).
+-define(PREFIXED_NS, [
+ {?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}
+]).
+
%%====================================================================
%% API
%%====================================================================
@@ -65,39 +73,51 @@ start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
process_iq(From, To, Packet) ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{xmlns = XMLNS} ->
- Host = To#jid.lserver,
+ case exmpp_iq:get_kind(Packet) of
+ request ->
+ Host = To#jid.ldomain,
+ Request = exmpp_iq:get_request(Packet),
+ XMLNS = case Request#xmlel.ns of
+ NS when is_atom(NS) -> atom_to_list(NS);
+ NS -> NS
+ end,
case ets:lookup(?IQTABLE, {XMLNS, Host}) of
[{_, Module, Function}] ->
- ResIQ = Module:Function(From, To, IQ),
+ % XXX OLD FORMAT: From, To, Packet.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ IQ_Rec = jlib:iq_query_info(PacketOld),
+ ResIQ = Module:Function(FromOld, ToOld, IQ_Rec),
if
ResIQ /= ignore ->
+ % XXX OLD FORMAT: ResIQ.
+ ReplyOld = jlib:iq_to_xml(ResIQ),
+ Reply = exmpp_xml:xmlelement_to_xmlel(ReplyOld,
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_router:route(
- To, From, jlib:iq_to_xml(ResIQ));
+ To, From, Reply);
true ->
ok
end;
[{_, Module, Function, Opts}] ->
gen_iq_handler:handle(Host, Module, Function, Opts,
- From, To, IQ);
+ From, To, Packet);
[] ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_FEATURE_NOT_IMPLEMENTED),
+ Err = exmpp_iq:error(Packet, 'feature-not-implemented'),
ejabberd_router:route(To, From, Err)
end;
- reply ->
+ response ->
process_iq_reply(From, To, Packet);
_ ->
- Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST),
+ Err = exmpp_iq:error(Packet, 'bad-request'),
ejabberd_router:route(To, From, Err),
ok
end.
process_iq_reply(From, To, Packet) ->
- IQ = jlib:iq_query_or_response_info(Packet),
- #iq{id = ID} = IQ,
+ ID = exmpp_stanza:get_id(Packet),
case catch mnesia:dirty_read(iq_response, ID) of
[] ->
ok;
@@ -114,13 +134,24 @@ process_iq_reply(From, To, Packet) ->
end,
case mnesia:transaction(F) of
{atomic, {Module, Function}} ->
- Module:Function(From, To, IQ);
+ % XXX OLD FORMAT: From, To, Packet.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ IQ_Rec = jlib:iq_query_or_response_info(PacketOld),
+ Module:Function(FromOld, ToOld, IQ_Rec);
_ ->
ok
end
end.
-route(From, To, Packet) ->
+route(FromOld, ToOld, PacketOld) ->
+ % XXX OLD FORMAT: From, To, Packet.
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ [?DEFAULT_NS], ?PREFIXED_NS),
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -145,7 +176,7 @@ refresh_iq_handlers() ->
ejabberd_local ! refresh_iq_handlers.
bounce_resource_packet(From, To, Packet) ->
- Err = jlib:make_error_reply(Packet, ?ERR_ITEM_NOT_FOUND),
+ Err = exmpp_stanza:error(Packet, 'item-not-found'),
ejabberd_router:route(To, From, Err),
stop.
@@ -202,7 +233,12 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
-handle_info({route, From, To, Packet}, State) ->
+handle_info({route, FromOld, ToOld, PacketOld}, State) ->
+ % XXX OLD FORMAT: From, To, Packet.
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ [?DEFAULT_NS], ?PREFIXED_NS),
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -272,29 +308,32 @@ do_route(From, To, Packet) ->
?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
if
- To#jid.luser /= "" ->
+ To#jid.lnode /= undefined ->
ejabberd_sm:route(From, To, Packet);
- To#jid.lresource == "" ->
- {xmlelement, Name, _Attrs, _Els} = Packet,
- case Name of
- "iq" ->
+ To#jid.lresource == undefined ->
+ case Packet of
+ _ when ?IS_IQ(Packet) ->
process_iq(From, To, Packet);
- "message" ->
+ _ when ?IS_MESSAGE(Packet) ->
ok;
- "presence" ->
+ _ when ?IS_PRESENCE(Packet) ->
ok;
_ ->
ok
end;
true ->
- {xmlelement, _Name, Attrs, _Els} = Packet,
- case xml:get_attr_s("type", Attrs) of
+ case exmpp_stanza:get_type(Packet) of
"error" -> ok;
"result" -> ok;
_ ->
+ % XXX OLD FORMAT: From, To, Packet.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(local_send_to_resource_hook,
- To#jid.lserver,
- [From, To, Packet])
+ To#jid.ldomain,
+ [FromOld, ToOld, PacketOld])
end
end.
From a25609f66bb8a0f2f5f4746b0ea7bb9a2e3d63bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 14:19:36 +0000
Subject: [PATCH 032/582] Accept new #xmlel in functions that create #iq. A
warning is printed when these functions are called with an old #xmlelement.
SVN Revision: 1403
---
ChangeLog | 4 ++++
src/jlib.erl | 14 ++++++++++++--
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b4f760626..92f2b00cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,6 +33,10 @@
* src/ejabberd_local.erl: Convert to exmpp.
+ * src/jlib.erl: Accept new #xmlel in functions that create #iq. A
+ warning is printed when these functions are called with an old
+ #xmlelement.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/jlib.erl b/src/jlib.erl
index 4a0fbcbfa..b926c15fb 100644
--- a/src/jlib.erl
+++ b/src/jlib.erl
@@ -360,7 +360,17 @@ iq_query_info(El) ->
iq_query_or_response_info(El) ->
iq_info_internal(El, any).
-iq_info_internal({xmlelement, Name, Attrs, Els}, Filter) when Name == "iq" ->
+iq_info_internal({xmlel, NS, _, _, _, _} = El, Filter) ->
+ ElOld = exmpp_xml:xmlel_to_xmlelement(El, [NS],
+ [{'http://etherx.jabber.org/streams', "stream"}]),
+ iq_info_internal2(ElOld, Filter);
+iq_info_internal(El, Filter) ->
+ catch throw(for_stacktrace),
+ io:format("~nJLIB: old #xmlelement:~n~p~n~p~n~n",
+ [El, erlang:get_stacktrace()]),
+ iq_info_internal2(El, Filter).
+
+iq_info_internal2({xmlelement, Name, Attrs, Els}, Filter) when Name == "iq" ->
%% Filter is either request or any. If it is request, any replies
%% are converted to the atom reply.
ID = xml:get_attr_s("id", Attrs),
@@ -413,7 +423,7 @@ iq_info_internal({xmlelement, Name, Attrs, Els}, Filter) when Name == "iq" ->
Class == reply, Filter /= any ->
reply
end;
-iq_info_internal(_, _) ->
+iq_info_internal2(_, _) ->
not_iq.
is_iq_request_type(set) -> true;
From 5317dd64d78766a061c5377ff23ddbd7ab6fe6a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 14:20:20 +0000
Subject: [PATCH 033/582] Change warning message.
SVN Revision: 1404
---
ChangeLog | 2 ++
src/ejabberd_router.erl | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 92f2b00cb..12d2b100b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -37,6 +37,8 @@
warning is printed when these functions are called with an old
#xmlelement.
+ * src/ejabberd_router.erl: Change warning message.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index 26c494ba0..1774268b0 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -411,7 +411,7 @@ convert_to_old_structs(From, To, Packet) ->
if
is_record(Packet, xmlelement) ->
catch throw(for_stacktrace), % To have a stacktrace.
- io:format("~nROUTE: old #xmlelement:~n~p~n~p~n~n",
+ io:format("~nROUTER: old #xmlelement:~n~p~n~p~n~n",
[Packet, erlang:get_stacktrace()]),
{From, To, Packet};
true ->
From 48cf5cb84aea6c0b33f34c0abf4a84a244f1e7f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 14:25:02 +0000
Subject: [PATCH 034/582] Do not use the #iq record anymore internally. However
it's still created and passed to other modules.
SVN Revision: 1405
---
ChangeLog | 4 ++++
src/ejabberd_c2s.erl | 28 ++++++++++------------------
src/ejabberd_local.erl | 12 ++++--------
src/ejabberd_sm.erl | 30 +++++++++++-------------------
src/gen_iq_handler.erl | 12 ++----------
5 files changed, 31 insertions(+), 55 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 12d2b100b..4e03125f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -39,6 +39,10 @@
* src/ejabberd_router.erl: Change warning message.
+ * src/ejabberd_sm.erl, src/ejabberd_c2s.erl, src/ejabberd_local.erl,
+ src/gen_iq_handler.erl: Do not use the #iq record anymore internally.
+ However it's still created and passed to other modules.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 140e23378..76e92de8d 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -124,13 +124,6 @@
[?NS_JABBER_CLIENT], [{?NS_XMPP, "stream"}])).
-define(ERR_FEATURE_NOT_IMPLEMENTED, ?STANZA_ERROR('feature-not-implemented')).
-% XXX OLD FORMAT: Re-include jlib.hrl (after clean-up).
--record(iq, {id = "",
- type,
- xmlns = "",
- lang = "",
- sub_el}).
-
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
@@ -546,7 +539,7 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
certfile, 1, StateData#state.tls_options)]
end,
Socket = StateData#state.socket,
- Proceed = exmpp_xml:document_fragment_to_list(
+ Proceed = exmpp_xml:node_to_list(
exmpp_server_tls:proceed(), [?DEFAULT_NS], ?PREFIXED_NS),
TLSSocket = (StateData#state.sockmod):starttls(
Socket, TLSOpts,
@@ -1825,10 +1818,8 @@ update_priority(Priority, Packet, StateData) ->
process_privacy_iq(From, To,
El,
StateData) ->
- % XXX OLD FORMAT: IQ is #iq.
- ElOld = exmpp_xml:xmlel_to_xmlelement(El,
- [?DEFAULT_NS], ?PREFIXED_NS),
- IQOld = jlib:iq_query_info(ElOld),
+ % XXX OLD FORMAT: IQ_Rec is an #iq.
+ IQ_Rec = jlib:iq_query_info(El),
% XXX OLD FORMAT: JIDs.
FromOld = jlib:to_old_jid(From),
ToOld = jlib:to_old_jid(To),
@@ -1838,13 +1829,13 @@ process_privacy_iq(From, To,
R = ejabberd_hooks:run_fold(
privacy_iq_get, StateData#state.server,
{error, ?ERR_FEATURE_NOT_IMPLEMENTED},
- [FromOld, ToOld, IQOld, StateData#state.privacy_list]),
+ [FromOld, ToOld, IQ_Rec, StateData#state.privacy_list]),
{R, StateData};
set ->
case ejabberd_hooks:run_fold(
privacy_iq_set, StateData#state.server,
{error, ?ERR_FEATURE_NOT_IMPLEMENTED},
- [FromOld, ToOld, IQOld]) of
+ [FromOld, ToOld, IQ_Rec]) of
{result, R, NewPrivList} ->
{{result, R},
StateData#state{privacy_list = NewPrivList}};
@@ -1930,13 +1921,14 @@ resend_subscription_requests(#state{user = User,
PendingSubscriptions).
process_unauthenticated_stanza(StateData, El) ->
- ElOld = exmpp_xml:xmlel_to_xmlelement(El, [?DEFAULT_NS], ?PREFIXED_NS),
- case jlib:iq_query_info(ElOld) of
- IQ when is_record(IQ, iq) ->
+ case exmpp_iq:get_kind(El) of
+ request ->
+ % XXX OLD FORMAT: IQ_Rec is an #iq.
+ IQ_Rec = jlib:iq_query_info(El),
ResOld = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
StateData#state.server,
empty,
- [StateData#state.server, IQ,
+ [StateData#state.server, IQ_Rec,
StateData#state.ip]),
case ResOld of
empty ->
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index e86c030bc..b0c355163 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -77,18 +77,14 @@ process_iq(From, To, Packet) ->
request ->
Host = To#jid.ldomain,
Request = exmpp_iq:get_request(Packet),
- XMLNS = case Request#xmlel.ns of
- NS when is_atom(NS) -> atom_to_list(NS);
- NS -> NS
- end,
+ XMLNS = exmpp_xml:get_ns_as_list(Request),
case ets:lookup(?IQTABLE, {XMLNS, Host}) of
[{_, Module, Function}] ->
- % XXX OLD FORMAT: From, To, Packet.
+ % XXX OLD FORMAT: From, To.
FromOld = jlib:to_old_jid(From),
ToOld = jlib:to_old_jid(To),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
- IQ_Rec = jlib:iq_query_info(PacketOld),
+ % XXX OLD FORMAT: IQ_Rec is an #iq.
+ IQ_Rec = jlib:iq_query_info(Packet),
ResIQ = Module:Function(FromOld, ToOld, IQ_Rec),
if
ResIQ /= ignore ->
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index bae6ce473..31d40eaf0 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -74,13 +74,6 @@
{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}
]).
-% XXX OLD FORMAT: Re-include jlib.hrl (after clean-up).
--record(iq, {id = "",
- type,
- xmlns = "",
- lang = "",
- sub_el}).
-
%%====================================================================
%% API
%%====================================================================
@@ -662,19 +655,19 @@ get_max_user_sessions(LUser, Host) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
process_iq(From, To, Packet) ->
- % XXX OLD FORMAT: From, To, Packet.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
- IQ = jlib:iq_query_info(PacketOld),
- case IQ of
- #iq{xmlns = XMLNS} ->
+ case exmpp_iq:get_kind(Packet) of
+ request ->
Host = To#jid.ldomain,
+ Request = exmpp_iq:get_request(Packet),
+ XMLNS = exmpp_xml:get_ns_as_list(Request),
case ets:lookup(sm_iqtable, {XMLNS, Host}) of
[{_, Module, Function}] ->
- % XXX OLD FORMAT: From, To, IQ.
- ResIQ = Module:Function(FromOld, ToOld, IQ),
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ % XXX OLD FORMAT: IQ_Rec is an #iq.
+ IQ_Rec = jlib:iq_query_info(Packet),
+ ResIQ = Module:Function(FromOld, ToOld, IQ_Rec),
if
ResIQ /= ignore ->
% XXX OLD FORMAT: ResIQ.
@@ -686,14 +679,13 @@ process_iq(From, To, Packet) ->
ok
end;
[{_, Module, Function, Opts}] ->
- % XXX OLD FORMAT: From, To, IQ.
gen_iq_handler:handle(Host, Module, Function, Opts,
From, To, Packet);
[] ->
Err = exmpp_iq:error(Packet, 'service-unavailable'),
ejabberd_router:route(To, From, Err)
end;
- reply ->
+ response ->
ok;
_ ->
Err = exmpp_iq:error(Packet, 'bad-request'),
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index aeae283f7..e3da47f0c 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -227,14 +227,6 @@ convert_to_old_structs(From, To, IQ) ->
true ->
F = jlib:to_old_jid(From),
T = jlib:to_old_jid(To),
- Default_NS = case lists:member({IQ#xmlel.ns, none},
- IQ#xmlel.declared_ns) of
- true -> [];
- false -> [IQ#xmlel.ns]
- end,
- IQOld = exmpp_xml:xmlel_to_xmlelement(IQ,
- Default_NS,
- [{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
- I = jlib:iq_query_info(IQOld),
- {F, T, I}
+ I_Rec = jlib:iq_query_info(IQ),
+ {F, T, I_Rec}
end.
From 13b78b1ad2aac7a4fa518422f1834fe55d97d3ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 1 Jul 2008 15:51:34 +0000
Subject: [PATCH 035/582] Routing is now done with #xmlel. A warning is printed
if those modules have to route an old #xmlelement.
SVN Revision: 1406
---
ChangeLog | 5 +++
src/ejabberd_local.erl | 26 ++++++++++------
src/ejabberd_router.erl | 69 +++++++++++++++++++++--------------------
src/ejabberd_s2s.erl | 31 +++++++++++-------
src/ejabberd_sm.erl | 22 +++++++++----
5 files changed, 94 insertions(+), 59 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 4e03125f2..0b324577c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -43,6 +43,11 @@
src/gen_iq_handler.erl: Do not use the #iq record anymore internally.
However it's still created and passed to other modules.
+ * src/ejabberd_router.erl, src/ejabberd_sm.erl,
+ src/ejabberd_local.erl, src/ejabberd_s2s.erl: Routing is now done with
+ #xmlel. A warning is printed if those modules have to route an old
+ #xmlelement.
+
2008-06-30 Jean-Sébastien Pédron
* src/Makefile.in: Remove the -I flag for exmpp includes; the
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index b0c355163..76719bbb8 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -133,21 +133,24 @@ process_iq_reply(From, To, Packet) ->
% XXX OLD FORMAT: From, To, Packet.
FromOld = jlib:to_old_jid(From),
ToOld = jlib:to_old_jid(To),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
- IQ_Rec = jlib:iq_query_or_response_info(PacketOld),
+ IQ_Rec = jlib:iq_query_or_response_info(Packet),
Module:Function(FromOld, ToOld, IQ_Rec);
_ ->
ok
end
end.
-route(FromOld, ToOld, PacketOld) ->
+route(FromOld, ToOld, #xmlelement{} = PacketOld) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nLOCAL: old #xmlelement:~n~p~n~p~n~n",
+ [PacketOld, erlang:get_stacktrace()]),
% XXX OLD FORMAT: From, To, Packet.
From = jlib:from_old_jid(FromOld),
To = jlib:from_old_jid(ToOld),
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld, [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ route(From, To, Packet);
+route(From, To, Packet) ->
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -229,12 +232,17 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
-handle_info({route, FromOld, ToOld, PacketOld}, State) ->
+handle_info({route, FromOld, ToOld, #xmlelement{} = PacketOld}, State) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nLOCAL: old #xmlelement:~n~p~n~p~n~n",
+ [PacketOld, erlang:get_stacktrace()]),
% XXX OLD FORMAT: From, To, Packet.
From = jlib:from_old_jid(FromOld),
To = jlib:from_old_jid(ToOld),
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld, [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ handle_info({route, From, To, Packet}, State);
+handle_info({route, From, To, Packet}, State) ->
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index 1774268b0..cd7f02002 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -64,10 +64,18 @@ start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+route(FromOld, ToOld, #xmlelement{} = PacketOld) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nROUTER: old #xmlelement:~n~p~n~p~n~n",
+ [PacketOld, erlang:get_stacktrace()]),
+ % XXX OLD FORMAT: From, To, Packet.
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld, [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ route(From, To, Packet);
route(From, To, Packet) ->
- % XXX OLD FORMAT: This code helps to detect old format routing.
- {FromOld, ToOld, PacketOld} = convert_to_old_structs(From, To, Packet),
- case catch do_route(FromOld, ToOld, PacketOld) of
+ case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, To, Packet}]);
@@ -239,9 +247,18 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
+handle_info({route, FromOld, ToOld, #xmlelement{} = PacketOld}, State) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nROUTER: old #xmlelement:~n~p~n~p~n~n",
+ [PacketOld, erlang:get_stacktrace()]),
+ % XXX OLD FORMAT: From, To, Packet.
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld, [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ handle_info({route, From, To, Packet}, State);
handle_info({route, From, To, Packet}, State) ->
- {FromOld, ToOld, PacketOld} = convert_to_old_structs(From, To, Packet),
- case catch do_route(FromOld, ToOld, PacketOld) of
+ case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
[Reason, {From, To, Packet}]);
@@ -304,9 +321,19 @@ code_change(_OldVsn, State, _Extra) ->
do_route(OrigFrom, OrigTo, OrigPacket) ->
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n",
[OrigFrom, OrigTo, OrigPacket]),
+ % XXX OLD FORMAT: OrigFrom, OrigTo, OrigPacket.
+ OrigFromOld = jlib:to_old_jid(OrigFrom),
+ OrigToOld = jlib:to_old_jid(OrigTo),
+ OrigPacketOld = exmpp_xml:xmlel_to_xmlelement(OrigPacket,
+ [?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
case ejabberd_hooks:run_fold(filter_packet,
- {OrigFrom, OrigTo, OrigPacket}, []) of
- {From, To, Packet} ->
+ {OrigFromOld, OrigToOld, OrigPacketOld}, []) of
+ {FromOld, ToOld, PacketOld} ->
+ % XXX OLD FORMAT: From, To, Packet.
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ [?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
LDstDomain = To#jid.ldomain,
case mnesia:dirty_read(route, LDstDomain) of
[] ->
@@ -334,11 +361,9 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
source -> jlib:short_jid(From);
destination -> jlib:short_jid(To);
bare_source ->
- jlib:short_jid(
- exmpp_jid:jid_to_bare_jid(From));
+ jlib:short_bare_jid(From);
bare_destination ->
- jlib:short_jid(
- exmpp_jid:jid_tl_bare_jid(To))
+ jlib:short_bare_jid(To)
end,
case get_component_number(LDstDomain) of
undefined ->
@@ -405,25 +430,3 @@ update_tables() ->
false ->
ok
end.
-
-convert_to_old_structs(From, To, Packet) ->
- % XXX OLD FORMAT: This code helps to detect old format routing.
- if
- is_record(Packet, xmlelement) ->
- catch throw(for_stacktrace), % To have a stacktrace.
- io:format("~nROUTER: old #xmlelement:~n~p~n~p~n~n",
- [Packet, erlang:get_stacktrace()]),
- {From, To, Packet};
- true ->
- F = jlib:to_old_jid(From),
- T = jlib:to_old_jid(To),
- Default_NS = case lists:member({Packet#xmlel.ns, none},
- Packet#xmlel.declared_ns) of
- true -> [];
- false -> [Packet#xmlel.ns]
- end,
- P = exmpp_xml:xmlel_to_xmlelement(Packet,
- Default_NS,
- [{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
- {F, T, P}
- end.
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index e023cd4a2..b8af4251f 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -74,12 +74,17 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-route(FromOld, ToOld, PacketOld) ->
+route(FromOld, ToOld, #xmlelement{} = PacketOld) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nS2S: old #xmlelement:~n~p~n~p~n~n",
+ [PacketOld, erlang:get_stacktrace()]),
% XXX OLD FORMAT: From, To, Packet.
From = jlib:from_old_jid(FromOld),
To = jlib:from_old_jid(ToOld),
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld, [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ route(From, To, Packet);
+route(From, To, Packet) ->
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -214,12 +219,17 @@ handle_cast(_Msg, State) ->
handle_info({mnesia_system_event, {mnesia_down, Node}}, State) ->
clean_table_from_bad_node(Node),
{noreply, State};
-handle_info({route, FromOld, ToOld, PacketOld}, State) ->
- % XXX OLD FORMAT: From, To, Packet
+handle_info({route, FromOld, ToOld, #xmlelement{} = PacketOld}, State) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nS2S: old #xmlelement:~n~p~n~p~n~n",
+ [PacketOld, erlang:get_stacktrace()]),
+ % XXX OLD FORMAT: From, To, Packet.
From = jlib:from_old_jid(FromOld),
To = jlib:from_old_jid(ToOld),
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld, [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ handle_info({route, From, To, Packet}, State);
+handle_info({route, From, To, Packet}, State) ->
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -267,16 +277,15 @@ clean_table_from_bad_node(Node) ->
do_route(From, To, Packet) ->
?DEBUG("s2s manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
case find_connection(From, To) of
{atomic, Pid} when pid(Pid) ->
?DEBUG("sending to process ~p~n", [Pid]),
NewPacket1 = exmpp_stanza:set_sender(Packet, From),
NewPacket = exmpp_stanza:set_recipient(NewPacket1, To),
#jid{ldomain = MyServer} = From,
- % XXX OLD FORMAT: NewPacket.
+ % XXX OLD FORMAT: From, To, NewPacket.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
NewPacketOld = exmpp_xml:xmlel_to_xmlelement(NewPacket,
[?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 31d40eaf0..9300958d5 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -84,12 +84,17 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-route(FromOld, ToOld, PacketOld) ->
+route(FromOld, ToOld, #xmlelement{} = PacketOld) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nSM: old #xmlelement:~n~p~n~p~n~n",
+ [PacketOld, erlang:get_stacktrace()]),
% XXX OLD FORMAT: From, To, Packet.
From = jlib:from_old_jid(FromOld),
To = jlib:from_old_jid(ToOld),
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld, [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ route(From, To, Packet);
+route(From, To, Packet) ->
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
@@ -307,12 +312,17 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
-handle_info({route, FromOld, ToOld, PacketOld}, State) ->
+handle_info({route, FromOld, ToOld, #xmlelement{} = PacketOld}, State) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nSM: old #xmlelement:~n~p~n~p~n~n",
+ [PacketOld, erlang:get_stacktrace()]),
% XXX OLD FORMAT: From, To, Packet.
From = jlib:from_old_jid(FromOld),
To = jlib:from_old_jid(ToOld),
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld, [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ handle_info({route, From, To, Packet}, State);
+handle_info({route, From, To, Packet}, State) ->
case catch do_route(From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~nwhen processing: ~p",
From 1a687a4f1a1410f9a42e42327567ec8da80715c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 8 Jul 2008 15:43:52 +0000
Subject: [PATCH 036/582] SASL errors are now atoms, not strings anymore.
SVN Revision: 1420
---
ChangeLog | 6 ++++++
src/cyrsasl.erl | 20 ++++++++++----------
src/cyrsasl_anonymous.erl | 2 +-
src/cyrsasl_digest.erl | 8 ++++----
src/cyrsasl_plain.erl | 4 ++--
src/ejabberd_c2s.erl | 12 ++++--------
6 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0b324577c..5c7a7d30e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-07-08 Jean-Sébastien Pédron
+
+ * src/cyrsasl.erl, src/cyrsasl_anonymous.erl, src/cyrsasl_digest.erl,
+ src/cyrsasl_plain.erl, src/ejabberd_c2s.erl: Errors are now atoms, not
+ strings anymore.
+
2008-07-01 Jean-Sébastien Pédron
* src/ejabberd_sm.erl: Convert to exmpp.
diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl
index 17354e21f..e942aa3e8 100644
--- a/src/cyrsasl.erl
+++ b/src/cyrsasl.erl
@@ -86,14 +86,14 @@ register_mechanism(Mechanism, Module, RequirePlainPassword) ->
%% end.
check_credentials(_State, Props) ->
- User = xml:get_attr_s(username, Props),
- case jlib:nodeprep(User) of
- error ->
- {error, "not-authorized"};
- "" ->
- {error, "not-authorized"};
- _LUser ->
- ok
+ case proplists:get_value(username, Props) of
+ undefined ->
+ {error, 'not-authorized'};
+ User ->
+ case exmpp_stringprep:is_node(User) of
+ false -> {error, 'not-authorized'};
+ true -> ok
+ end
end.
listmech(Host) ->
@@ -133,10 +133,10 @@ server_start(State, Mech, ClientIn) ->
mech_state = MechState},
ClientIn);
_ ->
- {error, "no-mechanism"}
+ {error, 'no-mechanism'}
end;
false ->
- {error, "no-mechanism"}
+ {error, 'no-mechanism'}
end.
server_step(State, ClientIn) ->
diff --git a/src/cyrsasl_anonymous.erl b/src/cyrsasl_anonymous.erl
index b9cf7449c..4f1219882 100644
--- a/src/cyrsasl_anonymous.erl
+++ b/src/cyrsasl_anonymous.erl
@@ -50,7 +50,7 @@ mech_step(State, _ClientIn) ->
%% Checks that the username is available
case ejabberd_auth:is_user_exists(User, Server) of
- true -> {error, "not-authorized"};
+ true -> {error, 'not-authorized'};
false -> {ok, [{username, User},
{auth_module, ejabberd_auth_anonymous}]}
end.
diff --git a/src/cyrsasl_digest.erl b/src/cyrsasl_digest.erl
index 5395205d7..c269a74bf 100644
--- a/src/cyrsasl_digest.erl
+++ b/src/cyrsasl_digest.erl
@@ -39,13 +39,13 @@ mech_step(#state{step = 1, nonce = Nonce} = State, _) ->
mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
case parse(ClientIn) of
bad ->
- {error, "bad-protocol"};
+ {error, 'bad-protocol'};
KeyVals ->
UserName = xml:get_attr_s("username", KeyVals),
AuthzId = xml:get_attr_s("authzid", KeyVals),
case (State#state.get_password)(UserName) of
{false, _} ->
- {error, "not-authorized", UserName};
+ {error, 'not-authorized', UserName};
{Passwd, AuthModule} ->
Response = response(KeyVals, UserName, Passwd,
Nonce, AuthzId, "AUTHENTICATE"),
@@ -61,7 +61,7 @@ mech_step(#state{step = 3, nonce = Nonce} = State, ClientIn) ->
username = UserName,
authzid = AuthzId}};
_ ->
- {error, "not-authorized", UserName}
+ {error, 'not-authorized', UserName}
end
end
end;
@@ -73,7 +73,7 @@ mech_step(#state{step = 5,
{auth_module, AuthModule}]};
mech_step(A, B) ->
?DEBUG("SASL DIGEST: A ~p B ~p", [A,B]),
- {error, "bad-protocol"}.
+ {error, 'bad-protocol'}.
parse(S) ->
diff --git a/src/cyrsasl_plain.erl b/src/cyrsasl_plain.erl
index 1b9cddb49..c0ca708d8 100644
--- a/src/cyrsasl_plain.erl
+++ b/src/cyrsasl_plain.erl
@@ -51,10 +51,10 @@ mech_step(State, ClientIn) ->
{ok, [{username, User}, {authzid, AuthzId},
{auth_module, AuthModule}]};
_ ->
- {error, "not-authorized", User}
+ {error, 'not-authorized', User}
end;
_ ->
- {error, "bad-protocol"}
+ {error, 'bad-protocol'}
end.
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 76e92de8d..0b3360947 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -515,15 +515,13 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
"(~w) Failed authentication for ~s@~s",
[StateData#state.socket,
Username, StateData#state.server]),
- % XXX OLD FORMAT: list_to_atom(Error).
send_element(StateData,
- exmpp_server_sasl:failure(list_to_atom(Error))),
+ exmpp_server_sasl:failure(Error)),
{next_state, wait_for_feature_request, StateData,
?C2S_OPEN_TIMEOUT};
{error, Error} ->
- % XXX OLD FORMAT: list_to_atom(Error).
send_element(StateData,
- exmpp_server_sasl:failure(list_to_atom(Error))),
+ exmpp_server_sasl:failure(Error)),
fsm_next_state(wait_for_feature_request, StateData)
end;
{?NS_TLS, 'starttls'} when TLS == true,
@@ -631,14 +629,12 @@ wait_for_sasl_response({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
"(~w) Failed authentication for ~s@~s",
[StateData#state.socket,
Username, StateData#state.server]),
- % XXX OLD FORMAT: list_to_atom(Error).
send_element(StateData,
- exmpp_server_sasl:failure(list_to_atom(Error))),
+ exmpp_server_sasl:failure(Error)),
fsm_next_state(wait_for_feature_request, StateData);
{error, Error} ->
- % XXX OLD FORMAT: list_to_atom(Error).
send_element(StateData,
- exmpp_server_sasl:failure(list_to_atom(Error))),
+ exmpp_server_sasl:failure(Error)),
fsm_next_state(wait_for_feature_request, StateData)
end;
_ ->
From d5aa4be7e5dddce190d667f694b8872c11caab33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 9 Jul 2008 09:14:19 +0000
Subject: [PATCH 037/582] Convert #xmlelement returned by the
'c2s_stream_features' hook to #xmlel.
SVN Revision: 1421
---
ChangeLog | 5 +++++
src/ejabberd_c2s.erl | 11 +++++++----
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5c7a7d30e..726641487 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-07-09 Jean-Sébastien Pédron
+
+ * src/ejabberd_c2s.erl: Convert #xmlelement returned by the
+ 'c2s_stream_features' hook to #xmlel.
+
2008-07-08 Jean-Sébastien Pédron
* src/cyrsasl.erl, src/cyrsasl_anonymous.erl, src/cyrsasl_digest.erl,
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 0b3360947..9ecd3ebf5 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -273,15 +273,18 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
false ->
[]
end,
+ % XXX OLD FORMAT: Other_Feats.
+ Other_FeatsOld = ejabberd_hooks:run_fold(
+ c2s_stream_features,
+ Server,
+ [], []),
+ Other_Feats = [exmpp_xml:xmlelement_to_xmlel(F, [?DEFAULT_NS], ?PREFIXED_NS) || F <- Other_FeatsOld],
send_element(StateData,
exmpp_stream:features(
TLSFeature ++
CompressFeature ++
SASL_Mechs ++
- ejabberd_hooks:run_fold(
- c2s_stream_features,
- Server,
- [], []))),
+ Other_Feats)),
fsm_next_state(wait_for_feature_request,
StateData#state{
server = Server,
From 7ca5bebab3e13832ee579150887ff94e96d1b53d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 9 Jul 2008 09:16:03 +0000
Subject: [PATCH 038/582] Convert to exmpp.
SVN Revision: 1422
---
ChangeLog | 4 +
src/ejabberd_auth.erl | 4 +-
src/ejabberd_auth_anonymous.erl | 15 +-
src/ejabberd_auth_internal.erl | 18 +--
src/ejabberd_auth_ldap.erl | 8 +-
src/ejabberd_auth_odbc.erl | 263 +++++++++++++++++---------------
6 files changed, 164 insertions(+), 148 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 726641487..15b69708f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@
* src/ejabberd_c2s.erl: Convert #xmlelement returned by the
'c2s_stream_features' hook to #xmlel.
+ * src/ejabberd_auth.erl, src/ejabberd_auth_internal.erl,
+ src/ejabberd_auth_odbc.erl, src/ejabberd_auth_ldap.erl,
+ src/ejabberd_auth_anonymous.erl: Convert to exmpp.
+
2008-07-08 Jean-Sébastien Pédron
* src/cyrsasl.erl, src/cyrsasl_anonymous.erl, src/cyrsasl_digest.erl,
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl
index d6a7e5228..358d44ae0 100644
--- a/src/ejabberd_auth.erl
+++ b/src/ejabberd_auth.erl
@@ -146,7 +146,7 @@ try_register(User, Server, Password) ->
true ->
{atomic, exists};
false ->
- case lists:member(jlib:nameprep(Server), ?MYHOSTS) of
+ case lists:member(exmpp_stringprep:nameprep(Server), ?MYHOSTS) of
true ->
lists:foldl(
fun(_M, {atomic, ok} = Res) ->
@@ -286,7 +286,7 @@ auth_modules() ->
%% Return the list of authenticated modules for a given host
auth_modules(Server) ->
- LServer = jlib:nameprep(Server),
+ LServer = exmpp_stringprep:nameprep(Server),
Method = ejabberd_config:get_local_option({auth_method, LServer}),
Methods = if
Method == undefined -> [];
diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl
index 3c5c58fed..8ba4d7336 100644
--- a/src/ejabberd_auth_anonymous.erl
+++ b/src/ejabberd_auth_anonymous.erl
@@ -122,8 +122,8 @@ allow_multiple_connections(Host) ->
%% Check if user exist in the anonymus database
anonymous_user_exist(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
case catch mnesia:dirty_read({anonymous, US}) of
[] ->
@@ -142,15 +142,16 @@ remove_connection(SID, LUser, LServer) ->
%% Register connection
register_connection(SID, #jid{luser = LUser, lserver = LServer}, Info) ->
- AuthModule = xml:get_attr_s(auth_module, Info),
- case AuthModule == ?MODULE of
- true ->
+ case proplists:get_value(auth_module, Info) of
+ undefined ->
+ ok;
+ ?MODULE ->
US = {LUser, LServer},
mnesia:sync_dirty(
fun() -> mnesia:write(#anonymous{us = US, sid=SID})
end);
- false ->
- ok
+ _ ->
+ ok
end.
%% Remove an anonymous user from the anonymous users table
diff --git a/src/ejabberd_auth_internal.erl b/src/ejabberd_auth_internal.erl
index 315cc4620..71d9086d7 100644
--- a/src/ejabberd_auth_internal.erl
+++ b/src/ejabberd_auth_internal.erl
@@ -67,8 +67,8 @@ plain_password_required() ->
false.
check_password(User, Server, Password) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
case catch mnesia:dirty_read({passwd, US}) of
[#passwd{password = Password}] ->
@@ -78,8 +78,8 @@ check_password(User, Server, Password) ->
end.
check_password(User, Server, Password, StreamID, Digest) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
case catch mnesia:dirty_read({passwd, US}) of
[#passwd{password = Passwd}] ->
@@ -99,8 +99,8 @@ check_password(User, Server, Password, StreamID, Digest) ->
end.
set_password(User, Server, Password) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
if
(LUser == error) or (LServer == error) ->
@@ -114,8 +114,8 @@ set_password(User, Server, Password) ->
end.
try_register(User, Server, Password) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
if
(LUser == error) or (LServer == error) ->
@@ -139,7 +139,7 @@ dirty_get_registered_users() ->
mnesia:dirty_all_keys(passwd).
get_vh_registered_users(Server) ->
- LServer = jlib:nameprep(Server),
+ LServer = exmpp_stringprep:nameprep(Server),
mnesia:dirty_select(
passwd,
[{#passwd{us = '$1', _ = '_'},
diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl
index e22be1bc9..d576a82fd 100644
--- a/src/ejabberd_auth_ldap.erl
+++ b/src/ejabberd_auth_ldap.erl
@@ -238,9 +238,11 @@ get_vh_registered_users_ldap(Server) ->
{User, UIDFormat} ->
case eldap_utils:get_user_part(User, UIDFormat) of
{ok, U} ->
- case jlib:nodeprep(U) of
- error -> [];
- LU -> [{LU, jlib:nameprep(Server)}]
+ try
+ [{exmpp_stringprep:nodeprep(U), exmpp_stringprep:nameprep(Server)}]
+ catch
+ _ ->
+ []
end;
_ -> []
end
diff --git a/src/ejabberd_auth_odbc.erl b/src/ejabberd_auth_odbc.erl
index 14bd61b94..06ae695ea 100644
--- a/src/ejabberd_auth_odbc.erl
+++ b/src/ejabberd_auth_odbc.erl
@@ -62,71 +62,75 @@ plain_password_required() ->
false.
check_password(User, Server, Password) ->
- case jlib:nodeprep(User) of
- error ->
- false;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{Password}]} ->
- Password /= "";
- _ ->
- false
- end
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ LServer = exmpp_stringprep:nameprep(Server),
+ case catch odbc_queries:get_password(LServer, Username) of
+ {selected, ["password"], [{Password}]} ->
+ Password /= "";
+ _ ->
+ false
+ end
+ catch
+ _ ->
+ false
end.
check_password(User, Server, Password, StreamID, Digest) ->
- case jlib:nodeprep(User) of
- error ->
- false;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{Passwd}]} ->
- DigRes = if
- Digest /= "" ->
- Digest == sha:sha(StreamID ++ Passwd);
- true ->
- false
- end,
- if DigRes ->
- true;
- true ->
- (Passwd == Password) and (Password /= "")
- end;
- _ ->
- false
- end
+ try
+ LUser = exmpp_stringpre:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ LServer = exmpp_stringprep:nameprep(Server),
+ case catch odbc_queries:get_password(LServer, Username) of
+ {selected, ["password"], [{Passwd}]} ->
+ DigRes = if
+ Digest /= "" ->
+ Digest == sha:sha(StreamID ++ Passwd);
+ true ->
+ false
+ end,
+ if DigRes ->
+ true;
+ true ->
+ (Passwd == Password) and (Password /= "")
+ end;
+ _ ->
+ false
+ end
+ catch
+ _ ->
+ false
end.
set_password(User, Server, Password) ->
- case jlib:nodeprep(User) of
- error ->
- {error, invalid_jid};
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- Pass = ejabberd_odbc:escape(Password),
- LServer = jlib:nameprep(Server),
- catch odbc_queries:set_password_t(LServer, Username, Pass)
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ Pass = ejabberd_odbc:escape(Password),
+ LServer = exmpp_stringprep:nameprep(Server),
+ catch odbc_queries:set_password_t(LServer, Username, Pass)
+ catch
+ _ ->
+ {error, invalid_jid}
end.
try_register(User, Server, Password) ->
- case jlib:nodeprep(User) of
- error ->
- {error, invalid_jid};
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- Pass = ejabberd_odbc:escape(Password),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:add_user(LServer, Username, Pass) of
- {updated, 1} ->
- {atomic, ok};
- _ ->
- {atomic, exists}
- end
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ Pass = ejabberd_odbc:escape(Password),
+ LServer = exmpp_stringprep:nameprep(Server),
+ case catch odbc_queries:add_user(LServer, Username, Pass) of
+ {updated, 1} ->
+ {atomic, ok};
+ _ ->
+ {atomic, exists}
+ end
+ catch
+ _ ->
+ {error, invalid_jid}
end.
dirty_get_registered_users() ->
@@ -137,7 +141,7 @@ dirty_get_registered_users() ->
end, Servers).
get_vh_registered_users(Server) ->
- LServer = jlib:nameprep(Server),
+ LServer = exmpp_stringprep:nameprep(Server),
case catch odbc_queries:list_users(LServer) of
{selected, ["username"], Res} ->
[{U, LServer} || {U} <- Res];
@@ -146,7 +150,7 @@ get_vh_registered_users(Server) ->
end.
get_vh_registered_users(Server, Opts) ->
- LServer = jlib:nameprep(Server),
+ LServer = exmpp_stringprep:nameprep(Server),
case catch odbc_queries:list_users(LServer, Opts) of
{selected, ["username"], Res} ->
[{U, LServer} || {U} <- Res];
@@ -155,7 +159,7 @@ get_vh_registered_users(Server, Opts) ->
end.
get_vh_registered_users_number(Server) ->
- LServer = jlib:nameprep(Server),
+ LServer = exmpp_stringprep:nameprep(Server),
case catch odbc_queries:users_number(LServer) of
{selected, [_], [{Res}]} ->
list_to_integer(Res);
@@ -164,7 +168,7 @@ get_vh_registered_users_number(Server) ->
end.
get_vh_registered_users_number(Server, Opts) ->
- LServer = jlib:nameprep(Server),
+ LServer = exmpp_stringprep:nameprep(Server),
case catch odbc_queries:users_number(LServer, Opts) of
{selected, [_], [{Res}]} ->
list_to_integer(Res);
@@ -173,84 +177,89 @@ get_vh_registered_users_number(Server, Opts) ->
end.
get_password(User, Server) ->
- case jlib:nodeprep(User) of
- error ->
- false;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{Password}]} ->
- Password;
- _ ->
- false
- end
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ LServer = exmpp_stringprep:nameprep(Server),
+ case catch odbc_queries:get_password(LServer, Username) of
+ {selected, ["password"], [{Password}]} ->
+ Password;
+ _ ->
+ false
+ end
+ catch
+ _ ->
+ false
end.
get_password_s(User, Server) ->
- case jlib:nodeprep(User) of
- error ->
- "";
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{Password}]} ->
- Password;
- _ ->
- ""
- end
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ LServer = exmpp_stringprep:nameprep(Server),
+ case catch odbc_queries:get_password(LServer, Username) of
+ {selected, ["password"], [{Password}]} ->
+ Password;
+ _ ->
+ ""
+ end
+ catch
+ _ ->
+ ""
end.
is_user_exists(User, Server) ->
- case jlib:nodeprep(User) of
- error ->
- false;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- case catch odbc_queries:get_password(LServer, Username) of
- {selected, ["password"], [{_Password}]} ->
- true;
- _ ->
- false
- end
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ LServer = exmpp_stringprep:nameprep(Server),
+ case catch odbc_queries:get_password(LServer, Username) of
+ {selected, ["password"], [{_Password}]} ->
+ true;
+ _ ->
+ false
+ end
+ catch
+ _ ->
+ false
end.
remove_user(User, Server) ->
- case jlib:nodeprep(User) of
- error ->
- error;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- LServer = jlib:nameprep(Server),
- catch odbc_queries:del_user(LServer, Username),
- ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
- [User, Server])
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ LServer = exmpp_stringprep:nameprep(Server),
+ catch odbc_queries:del_user(LServer, Username),
+ ejabberd_hooks:run(remove_user, exmpp_stringprep:nameprep(Server),
+ [User, Server])
+ catch
+ _ ->
+ error
end.
remove_user(User, Server, Password) ->
- case jlib:nodeprep(User) of
- error ->
- error;
- LUser ->
- Username = ejabberd_odbc:escape(LUser),
- Pass = ejabberd_odbc:escape(Password),
- LServer = jlib:nameprep(Server),
- F = fun() ->
- Result = odbc_queries:del_user_return_password(
- LServer, Username, Pass),
- case Result of
- {selected, ["password"], [{Password}]} ->
- ejabberd_hooks:run(remove_user, jlib:nameprep(Server),
- [User, Server]),
- ok;
- {selected, ["password"], []} ->
- not_exists;
- _ ->
- not_allowed
- end
- end,
- {atomic, Result} = odbc_queries:sql_transaction(LServer, F),
- Result
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ Username = ejabberd_odbc:escape(LUser),
+ Pass = ejabberd_odbc:escape(Password),
+ LServer = exmpp_stringprep:nameprep(Server),
+ F = fun() ->
+ Result = odbc_queries:del_user_return_password(
+ LServer, Username, Pass),
+ case Result of
+ {selected, ["password"], [{Password}]} ->
+ ejabberd_hooks:run(remove_user, exmpp_stringprep:nameprep(Server),
+ [User, Server]),
+ ok;
+ {selected, ["password"], []} ->
+ not_exists;
+ _ ->
+ not_allowed
+ end
+ end,
+ {atomic, Result} = odbc_queries:sql_transaction(LServer, F),
+ Result
+ catch
+ _ ->
+ error
end.
From 8bfccb42a95ebfa1e46158855c787342096f13d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 11 Jul 2008 12:40:49 +0000
Subject: [PATCH 039/582] Exmpp now takes care of stanza serialization and
compatible namespaces.
SVN Revision: 1433
---
ChangeLog | 6 ++++++
src/ejabberd_c2s.erl | 4 +---
src/ejabberd_s2s_in.erl | 6 +-----
src/ejabberd_s2s_out.erl | 6 +-----
4 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 15b69708f..8ed38c6f3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-07-11 Jean-Sébastien Pédron
+
+ * src/ejabberd_s2s_in.erl, src/ejabberd_s2s_out.erl,
+ src/ejabberd_c2s.erl: Exmpp now takes care of stanza serialization and
+ compatible namespaces.
+
2008-07-09 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl: Convert #xmlelement returned by the
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 9ecd3ebf5..dae88f07a 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1305,10 +1305,8 @@ send_text(StateData, Text) ->
send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
send_text(StateData, exmpp_stream:to_list(El));
-send_element(StateData, #xmlel{ns = ?NS_JABBER_SERVER} = El) ->
- send_text(StateData, exmpp_stanza:to_list(El, ?NS_JABBER_SERVER));
send_element(StateData, El) ->
- send_text(StateData, exmpp_stanza:to_list(El, ?DEFAULT_NS)).
+ send_text(StateData, exmpp_stanza:to_list(El)).
new_id() ->
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 562033076..c0c863c1e 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -564,12 +564,8 @@ send_text(StateData, Text) ->
send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
send_text(StateData, exmpp_stream:to_list(El));
-send_element(StateData, #xmlel{ns = ?NS_JABBER_CLIENT} = El) ->
- send_text(StateData, exmpp_stanza:to_list(El,
- ?NS_JABBER_CLIENT, ?PREFIXED_NS));
send_element(StateData, El) ->
- send_text(StateData, exmpp_stanza:to_list(El,
- ?DEFAULT_NS, ?PREFIXED_NS)).
+ send_text(StateData, exmpp_stanza:to_list(El)).
change_shaper(StateData, Host, JID) ->
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index 93171ced3..baa5d23f5 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -790,12 +790,8 @@ send_text(StateData, Text) ->
send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
send_text(StateData, exmpp_stream:to_list(El));
-send_element(StateData, #xmlel{ns = ?NS_JABBER_CLIENT} = El) ->
- send_text(StateData, exmpp_stanza:to_list(El,
- ?NS_JABBER_CLIENT, ?PREFIXED_NS));
send_element(StateData, El) ->
- send_text(StateData, exmpp_stanza:to_list(El,
- ?DEFAULT_NS, ?PREFIXED_NS)).
+ send_text(StateData, exmpp_stanza:to_list(El)).
send_queue(StateData, Q) ->
case queue:out(Q) of
From 5610d00b4dcc0aa5b77e40c915dd3829f5074c32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 11 Jul 2008 12:41:48 +0000
Subject: [PATCH 040/582] Convert to exmpp. Note that this module hasn't been
tested yet!
SVN Revision: 1434
---
ChangeLog | 3 +
src/ejabberd_service.erl | 130 +++++++++++++++++++--------------------
2 files changed, 66 insertions(+), 67 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8ed38c6f3..cd04540e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,9 @@
src/ejabberd_c2s.erl: Exmpp now takes care of stanza serialization and
compatible namespaces.
+ * src/ejabberd_service.erl: Convert to exmpp. Note that this module
+ hasn't been tested yet!
+
2008-07-09 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl: Convert #xmlelement returned by the
diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl
index 351743ae0..b6a977ce6 100644
--- a/src/ejabberd_service.erl
+++ b/src/ejabberd_service.erl
@@ -47,8 +47,9 @@
handle_info/3,
terminate/3]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-record(state, {socket, sockmod, streamid,
hosts, password, access,
@@ -62,31 +63,10 @@
-define(FSMOPTS, []).
-endif.
--define(STREAM_HEADER,
- ""
- ""
- ).
-
--define(STREAM_TRAILER, "").
-
--define(INVALID_HEADER_ERR,
- ""
- "Invalid Stream Header"
- ""
- ).
-
--define(INVALID_HANDSHAKE_ERR,
- "Invalid Handshake"
- ""
- ).
-
--define(INVALID_XML_ERR,
- xml:element_to_string(?SERR_XML_NOT_WELL_FORMED)).
--define(INVALID_NS_ERR,
- xml:element_to_string(?SERR_INVALID_NAMESPACE)).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, ?NS_COMPONENT_ACCEPT).
+-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
%%%----------------------------------------------------------------------
%%% API
@@ -167,24 +147,32 @@ init([{SockMod, Socket}, Opts]) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
-wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
+wait_for_stream({xmlstreamstart, #xmlel{ns = NS}}, StateData) ->
% TODO
- case xml:get_attr_s("xmlns", Attrs) of
- "jabber:component:accept" ->
- Header = io_lib:format(?STREAM_HEADER,
- [StateData#state.streamid, ?MYNAME]),
- send_text(StateData, Header),
+ case NS of
+ ?NS_COMPONENT_ACCEPT ->
+ Opening_Reply = exmpp_stream:opening_reply(?MYNAME,
+ ?NS_COMPONENT_ACCEPT,
+ {0, 0}, StateData#state.streamid),
+ send_element(StateData, Opening_Reply),
{next_state, wait_for_handshake, StateData};
_ ->
- send_text(StateData, ?INVALID_HEADER_ERR),
+ Error = #xmlel{ns = ?NS_XMPP, name = 'stream', children = [
+ #xmlel{ns = ?NS_XMPP, name = 'error', children = [
+ #xmlcdata{cdata = <<"Invalid Stream Header">>}
+ ]}
+ ]},
+ send_element(StateData, Error),
{stop, normal, StateData}
end;
wait_for_stream({xmlstreamerror, _}, StateData) ->
- Header = io_lib:format(?STREAM_HEADER,
- ["none", ?MYNAME]),
- send_text(StateData,
- Header ++ ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ Opening_Reply = exmpp_stream:opening_reply(?MYNAME,
+ ?NS_COMPONENT_ACCEPT,
+ {0, 0}, "none"),
+ send_element(StateData, Opening_Reply),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_stream(closed, StateData) ->
@@ -192,13 +180,13 @@ wait_for_stream(closed, StateData) ->
wait_for_handshake({xmlstreamelement, El}, StateData) ->
- {xmlelement, Name, _Attrs, Els} = El,
- case {Name, xml:get_cdata(Els)} of
- {"handshake", Digest} ->
+ case {El#xmlel.name, exmpp_xml:get_cdata(El)} of
+ {'handshake', Digest} ->
case sha:sha(StateData#state.streamid ++
StateData#state.password) of
Digest ->
- send_text(StateData, ""),
+ send_element(StateData,
+ #xmlel{ns = ?NS_COMPONENT_ACCEPT, name = 'handshake'}),
lists:foreach(
fun(H) ->
ejabberd_router:register_route(H),
@@ -206,7 +194,10 @@ wait_for_handshake({xmlstreamelement, El}, StateData) ->
end, StateData#state.hosts),
{next_state, stream_established, StateData};
_ ->
- send_text(StateData, ?INVALID_HANDSHAKE_ERR),
+ send_element(StateData,
+ #xmlel{ns = ?NS_XMPP, name = 'error', children = [
+ #xmlcdata{cdata = <<"Invalid Handshake">>}]}),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData}
end;
_ ->
@@ -217,7 +208,8 @@ wait_for_handshake({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
wait_for_handshake({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
wait_for_handshake(closed, StateData) ->
@@ -225,20 +217,18 @@ wait_for_handshake(closed, StateData) ->
stream_established({xmlstreamelement, El}, StateData) ->
- NewEl = jlib:remove_attr("xmlns", El),
- {xmlelement, Name, Attrs, _Els} = NewEl,
- From = xml:get_attr_s("from", Attrs),
+ From = exmpp_stanza:get_sender(El),
FromJID = case StateData#state.check_from of
%% If the admin does not want to check the from field
%% when accept packets from any address.
%% In this case, the component can send packet of
%% behalf of the server users.
- false -> jlib:string_to_jid(From);
+ false -> exmpp_jid:string_to_jid(From);
%% The default is the standard behaviour in XEP-0114
_ ->
- FromJID1 = jlib:string_to_jid(From),
+ FromJID1 = exmpp_jib:string_to_jid(From),
case FromJID1 of
- #jid{lserver = Server} ->
+ #jid{ldomain = Server} ->
case lists:member(Server, StateData#state.hosts) of
true -> FromJID1;
false -> error
@@ -246,18 +236,18 @@ stream_established({xmlstreamelement, El}, StateData) ->
_ -> error
end
end,
- To = xml:get_attr_s("to", Attrs),
+ To = exmpp_stanza:get_recipient(El),
ToJID = case To of
- "" -> error;
- _ -> jlib:string_to_jid(To)
+ undefined -> error;
+ _ -> exmpp_jib:string_to_jid(To)
end,
- if ((Name == "iq") or
- (Name == "message") or
- (Name == "presence")) and
+ if ((El#xmlel.name == 'iq') or
+ (El#xmlel.name == 'message') or
+ (El#xmlel.name == 'presence')) and
(ToJID /= error) and (FromJID /= error) ->
- ejabberd_router:route(FromJID, ToJID, NewEl);
+ ejabberd_router:route(FromJID, ToJID, El);
true ->
- Err = jlib:make_error_reply(NewEl, ?ERR_BAD_REQUEST),
+ Err = exmpp_stanza:reply_with_error(El, 'bad-request'),
send_element(StateData, Err),
error
end,
@@ -268,7 +258,8 @@ stream_established({xmlstreamend, _Name}, StateData) ->
{stop, normal, StateData};
stream_established({xmlstreamerror, _}, StateData) ->
- send_text(StateData, ?INVALID_XML_ERR ++ ?STREAM_TRAILER),
+ send_element(StateData, exmpp_stream:error('xml-not-well-formed')),
+ send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
stream_established(closed, StateData) ->
@@ -322,22 +313,25 @@ code_change(_OldVsn, StateName, StateData, _Extra) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
handle_info({send_text, Text}, StateName, StateData) ->
+ % XXX OLD FORMAT: This clause should be removed.
send_text(StateData, Text),
{next_state, StateName, StateData};
handle_info({send_element, El}, StateName, StateData) ->
send_element(StateData, El),
{next_state, StateName, StateData};
-handle_info({route, From, To, Packet}, StateName, StateData) ->
+handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
+ %% XXX OLD FORMAT: From, To and Packet are in the old format.
+ Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
+ [?NS_JABBER_CLIENT], ?PREFIXED_NS),
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
case acl:match_rule(global, StateData#state.access, From) of
allow ->
- {xmlelement, Name, Attrs, Els} = Packet,
- Attrs2 = jlib:replace_from_to_attrs(jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- Text = xml:element_to_string({xmlelement, Name, Attrs2, Els}),
- send_text(StateData, Text);
+ El1 = exmpp_stanza:set_sender(Packet, From),
+ El2 = exmpp_stanza:set_recipient(El1, To),
+ send_element(StateData, El2);
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_NOT_ALLOWED),
+ Err = exmpp_stanza:reply_with_error(Packet, 'not-allowed'),
ejabberd_router:route(To, From, Err)
end,
{next_state, StateName, StateData}.
@@ -369,8 +363,10 @@ terminate(Reason, StateName, StateData) ->
send_text(StateData, Text) ->
(StateData#state.sockmod):send(StateData#state.socket, Text).
+send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
+ send_text(StateData, exmpp_stream:to_list(El));
send_element(StateData, El) ->
- send_text(StateData, xml:element_to_string(El)).
+ send_text(StateData, exmpp_stanza:to_list(El)).
new_id() ->
randoms:get_string().
From 332fb55e3abcce272d7ba2b0c32e363b57a0979b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 11 Jul 2008 12:48:27 +0000
Subject: [PATCH 041/582] MFC: Merge revisions from 1362 to revision 1434 from
trunk.
SVN Revision: 1435
---
ChangeLog | 138 ++++++++++-
doc/guide.html | 360 ++++++++++++++++-------------
doc/guide.tex | 74 +++++-
src/Makefile.in | 6 +-
src/configure | 3 +
src/configure.ac | 3 +
src/ejabberd.cfg.example | 2 +-
src/ejabberd_c2s.erl | 3 +
src/ejabberd_config.erl | 6 +-
src/ejabberd_ctl.erl | 1 +
src/ejabberd_local.erl | 7 +
src/ejabberd_receiver.erl | 6 +-
src/ejabberd_sm.erl | 15 +-
src/mod_caps.erl | 12 +
src/mod_configure.erl | 2 +-
src/mod_muc/mod_muc_log.erl | 19 +-
src/mod_muc/mod_muc_room.erl | 13 +-
src/mod_privacy_odbc.erl | 25 +-
src/mod_pubsub/gen_pubsub_node.erl | 2 +
src/mod_pubsub/mod_pubsub.erl | 109 ++++++---
src/mod_pubsub/node.template | 9 +-
src/mod_pubsub/node_buddy.erl | 8 +
src/mod_pubsub/node_club.erl | 9 +-
src/mod_pubsub/node_default.erl | 116 ++++++++--
src/mod_pubsub/node_dispatch.erl | 9 +-
src/mod_pubsub/node_pep.erl | 35 ++-
src/mod_pubsub/node_private.erl | 9 +-
src/mod_pubsub/node_public.erl | 9 +-
src/mod_pubsub/node_zoo.erl | 181 +++++++++++++++
src/mod_register.erl | 3 +-
src/mod_roster.erl | 1 +
src/mod_shared_roster.erl | 88 ++++++-
src/web/ejabberd_http.erl | 27 ++-
src/web/ejabberd_http_poll.erl | 38 ++-
src/web/ejabberd_web_admin.erl | 2 +-
tools/ejabberdctl | 3 +-
36 files changed, 1055 insertions(+), 298 deletions(-)
create mode 100644 src/mod_pubsub/node_zoo.erl
diff --git a/ChangeLog b/ChangeLog
index cd04540e4..72fe05cb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-11 Jean-Sébastien Pédron
+
+ Merge revisions from 1362 to revision 1434 from trunk.
+
2008-07-11 Jean-Sébastien Pédron
* src/ejabberd_s2s_in.erl, src/ejabberd_s2s_out.erl,
@@ -7,6 +11,11 @@
* src/ejabberd_service.erl: Convert to exmpp. Note that this module
hasn't been tested yet!
+2008-07-10 Badlop
+
+ * src/configure.ac: Don't check for erlang header file (EJAB-232)
+ * src/configure: Likewise
+
2008-07-09 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl: Convert #xmlelement returned by the
@@ -16,12 +25,99 @@
src/ejabberd_auth_odbc.erl, src/ejabberd_auth_ldap.erl,
src/ejabberd_auth_anonymous.erl: Convert to exmpp.
+2008-07-09 Badlop
+
+ * src/configure.ac: Check for erlang header files (EJAB-232)
+ * src/configure: Likewise
+
+ * src/mod_pubsub/mod_pubsub.erl: Fix compilation warnings
+ * src/mod_pubsub/node_zoo.erl: Likewise
+
+ * src/mod_shared_roster.erl: Allow to get subscribed to a contact
+ that is already in the roster by means of a shared roster group:
+ add it to another roster group and it gets subscribed
+ automatically (EJAB-407)
+
+ * src/mod_roster.erl: Likewise
+
+ * src/mod_muc/mod_muc_log.erl: Fix XHTML compliance: ensure some
+ language is set, include ID attribute in each message, add
+ microseconds to ensure unique value (EJAB-497)
+
+ * src/mod_register.erl: Support for io_lib newline character in
+ the body of welcome_message (EJAB-501)
+ * doc/guide.tex: Document the newline character
+ * src/ejabberd.cfg.example: Example usage of newline character
+
+ * src/ejabberd_config.erl (load_file): error message on sasl.log
+ is not flattened (EJAB-616)
+
+ * doc/guide.tex: mod_muc_log XMPP URI supports the updated version
+ RFC 5122 (EJAB-631)
+ * doc/guide.html: Likewise
+
2008-07-08 Jean-Sébastien Pédron
* src/cyrsasl.erl, src/cyrsasl_anonymous.erl, src/cyrsasl_digest.erl,
src/cyrsasl_plain.erl, src/ejabberd_c2s.erl: Errors are now atoms, not
strings anymore.
+2008-07-08 Badlop
+
+ * tools/ejabberdctl: Work also when 'which' is unavailable
+
+2008-07-08 Christophe Romain
+
+ * src/web/ejabberd_http_poll.erl: improve ip fetching patch
+
+2008-07-07 Badlop
+
+ * src/Makefile.in: Spool, config and log dirs: writtable by owner,
+ readable by group, nothing by others (EJAB-686)
+ * doc/guide.tex: New section Securing sensible files
+ * doc/guide.html: Likewise
+
+ * doc/guide.tex: Solaris Makefile install: use ginstall (thanks to
+ Jonathan Auer)(EJAB-649)
+ * doc/guide.html: Likewise
+
+2008-07-03 Jerome Sautret
+
+ * src/mod_privacy_odbc.erl: Support for privacy lists in MySQL
+ (thanks to Igor Goryachev)(EJAB-538)
+
+2008-07-03 Christophe Romain
+
+ * src/mod_pubsub/mod_pubsub.erl: Fix permission control on item
+ retrieve (EJAB-453)
+ * src/mod_pubsub/node_dispatch.erl: Likewise
+ * src/mod_pubsub/node_buddy.erl: Likewise
+ * src/mod_pubsub/node_private.erl: Likewise
+ * src/mod_pubsub/node_public.erl: Likewise
+ * src/mod_pubsub/node_default.erl: Likewise
+ * src/mod_pubsub/node_pep.erl: Likewise
+ * src/mod_pubsub/node_club.erl: Likewise
+ * src/mod_pubsub/gen_pubsub_node.erl: Likewise
+ * src/mod_pubsub/node.template: Likewise
+
+ * src/mod_pubsub/mod_pubsub.erl: Allow subscriber to request specific
+ items by ItemID; Allow to retrieve pubsub#title configuration (thanks
+ to Kevin Crosbie); Fix forbidden result on setting
+ affiliation/subscription
+
+ * src/mod_pubsub/node_zoo.erl: Add node type without
+ home// constraint
+
+ * src/ejabberd_local.erl: prevent iq_response table overload
+ (EJAB-608)
+ * src/mod_caps.erl: Likewise
+
+ * src/web/ejabberd_http.erl: Retrieve correct IP from http connection
+ * src/web/ejabberd_http_poll.erl: Likewise
+ * src/ejabberd_receiver.erl: Likewise
+ * src/ejabberd_sm.erl: Likewise
+ * src/ejabberd_c2s.erl: Likewise
+
2008-07-01 Jean-Sébastien Pédron
* src/ejabberd_sm.erl: Convert to exmpp.
@@ -100,6 +196,19 @@
src/ejabberd_s2s_out.erl: No conversion is done before calling
ejabberd_router:route/3.
+2008-06-29 Badlop
+
+ * src/ejabberd_ctl.erl: Web Admin and Ad-hoc admin: dump only
+ persistent tables (EJAB-678)
+
+ * src/mod_pubsub/node_pep.erl: Complain if mod_caps disabled and
+ mod_pubsub has PEP plugin enabled (EJAB-677)
+
+2008-06-28 Badlop
+
+ * src/mod_muc/mod_muc_room.erl: Allow to store room
+ description (thanks to Christopher Dupont)(EJAB-670)
+
2008-06-27 Jean-Sébastien Pédron
* src/ejabberd_c2s.erl, src/ejabberd_s2s_out.erl,
@@ -150,6 +259,15 @@
expected form outside of the C2S (empty fields must be set to the
empty string). This fixes the broken routing.
+2008-06-21 Badlop
+
+ * src/web/ejabberd_http.erl: Support PUT and DELETE methods in
+ ejabberd_http (thanks to Eric Cestari)(EJAB-662)
+
+ * doc/guide.tex: Explain that S2S outgoing first tries IPv4 and if
+ that fails then tries IPv6
+ * doc/guide.html: Likewise
+
2008-06-20 Jean-Sébastien Pédron
* src/configure, src/aclocal.m4, src/Makefile.in: Add exmpp detection.
@@ -271,7 +389,7 @@
2008-05-19 Mickael Remond
* src/ejabberd_s2s_out.erl: Avoid an harmless error (function clause in
- logs)
+ logs)
2008-05-17 Badlop
@@ -344,11 +462,11 @@
being immediately shown in an 'all' special shared roster
group (thanks to Alexey Shchepin) (EJAB-71)
* src/mod_register.erl: New vhost event user_registered
-
+
* doc/guide.tex: Document option registration_timeout (EJAB-614)
2008-04-25 Badlop
-
+
* src/ejabberd_c2s.erl: Added forbidden_session_hook
* src/acl.erl: New access types: resource, resource_regexp and
@@ -506,7 +624,7 @@
* doc/webadmmainru.png: Likewise
* doc/disco.png: Removed because not used
-
+
* doc/guide.tex: Fix Latex reference to webadmin section. Update
explanation of screenshots. Update xmpp addresses of Mickael
Remond and Sander Devrieze.
@@ -619,7 +737,7 @@
* src/eldap.erl: Faster LDAP reconnection (Thanks to Christophe
Romain) (EJAB-581)
-
+
2008-03-17 Mickael Remond
* src/ejabberd_s2s.erl: Only trigger s2s_connect_hook on
@@ -630,7 +748,7 @@
* src/ejabberd_ctl.erl: API improvement: Added
reopen_log_hook (EJAB-565)
-
+
* src/ejabberd_s2s.erl: API improvement: Added s2s_connect_hook
(EJAB-566).
@@ -722,7 +840,7 @@
configuration sanity checks (EJAB-533)
* src/src/ejabberd_app.erl: Likewise
* src/ejabberd_app.erl: Likewise
-
+
2008-02-26 Badlop
* src/msgs/it.msg: Updated (thanks to Smart2128)
@@ -858,7 +976,7 @@
* src/mod_pubsub/node_pep.erl: Likewise
* src/mod_pubsub/node_private.erl: Likewise
* src/mod_pubsub/node.template: Likewise
-
+
* src/mod_pubsub/gen_pubsub_node.erl: API improvement: Added a way
to generate custom item name
* src/mod_pubsub/node_dispatch.erl: Likewise
@@ -895,7 +1013,7 @@
* src/mod_pubsub/gen_pubsub_nodetree.erl: Likewise
* src/mod_pubsub/nodetree_default.erl: Likewise
* src/mod_pubsub/nodetree_virtual.erl: Likewise
-
+
2008-01-30 Badlop
* doc/guide.tex: Removed the option served_hosts in mod_pubsub
@@ -960,7 +1078,7 @@
* src/ejabberd.hrl: Likewise
* doc/introduction.tex: Updated to 22 languages
-
+
* doc/Makefile: Ensure that Bash is used
* doc/guide.tex: Updated copyright dates to 2008.
diff --git a/doc/guide.html b/doc/guide.html
index b94c65959..b7f10839b 100644
--- a/doc/guide.html
+++ b/doc/guide.html
@@ -106,105 +106,107 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}
2.4.4 Install
2.4.5 Start
2.4.6 Specific Notes for BSD
-2.4.7 Specific Notes for Microsoft Windows
+2.4.7 Specific Notes for Sun Solaris
+2.4.8 Specific Notes for Microsoft Windows
-2.5 Create a Jabber Account for Administration
-2.6 Upgrading ejabberd
+2.5 Create a Jabber Account for Administration
+2.6 Upgrading ejabberd
-Chapter 3 Configuring ejabberd
+Chapter 3 Configuring ejabberd
-Chapter 4 Managing an ejabberd server
+Chapter 4 Managing an ejabberd server
-Chapter 5 Securing ejabberd
+Chapter 5 Securing ejabberd
-Chapter 6 Clustering
+Chapter 6 Clustering
-Chapter 7 Debugging
+Chapter 7 Debugging
-Appendix A Internationalization and Localization
-Appendix B Release Notes
-Appendix C Acknowledgements
-Appendix D Copyright Information
+Appendix A Internationalization and Localization
+Appendix B Release Notes
+Appendix C Acknowledgements
+Appendix D Copyright Information
ejabberd is a free and open source instant messaging server written in Erlang.
ejabberd is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.
ejabberd is designed to be a rock-solid and feature rich XMPP server.
ejabberd is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.
@@ -360,7 +362,7 @@ To get the full list run the command:
/sbin/ejabberdctl Administration script
/var/lib/ejabberd/
-
- .erlang.cookie
- Erlang cookie file
+ .erlang.cookie
- Erlang cookie file (see section 5.3)
- db
- Mnesia database spool files
- ebin
- Binary Erlang files (*.beam)
- priv
-
@@ -389,8 +391,23 @@ and configurable options to fine tune the Erlang runtime system.
2.4.6 Specific Notes for BSD
The command to compile ejabberd in BSD systems is:
gmake
+
+
+
You need to have GNU install,
+but it isn’t included in Solaris.
+It can be easily installed if your Solaris system
+is set up for blastwave.org
+package repository.
+Make sure /opt/csw/bin is in your PATH and run:
+
pkg-get -i fileutils
+
If that program is called ginstall,
+modify the ejabberd Makefile script to suit your system,
+for example:
+
cat Makefile | sed s/install/ginstall/ > Makefile.gi
+
And finally install ejabberd with:
+
gmake -f Makefile.gi ginstall
-
+
To compile ejabberd on a Microsoft Windows system, you need:
-
@@ -428,7 +445,7 @@ nmake -f Makefile.win32
- Edit the file
ejabberd\src\ejabberd.cfg
and run
werl -s ejabberd -name ejabberd
-
You need a Jabber account and grant him administrative privileges
+
You need a Jabber account and grant him administrative privileges
to enter the ejabberd Web Admin:
-
Register a Jabber account on your ejabberd server, for example admin1@example.org.
@@ -449,16 +466,16 @@ favourite browser. Make sure to enter the full JID as username (in this
example: admin1@example.org. The reason that you also need to enter the
suffix, is because ejabberd’s virtual hosting support.
-
To upgrade an ejabberd installation to a new version,
+
To upgrade an ejabberd installation to a new version,
simply uninstall the old version, and then install the new one.
Of course, it is important that the configuration file
and Mnesia database spool directory are not removed.
ejabberd automatically updates the Mnesia table definitions at startup when needed.
If you also use an external database for storage of some modules,
check if the release notes of the new ejabberd version
indicates you need to also update those tables.
-
+
-
The configuration file will be loaded the first time you start ejabberd. The
+
The configuration file will be loaded the first time you start ejabberd. The
content from this file will be parsed and stored in the internal ejabberd database. Subsequently the
configuration will be loaded from the database and any commands in the
configuration file are appended to the entries in the database.
Note that ejabberd never edits the configuration file.
@@ -477,7 +494,7 @@ override_acls.
With these lines the old global options (shared between all ejabberd nodes in a
cluster), local options (which are specific for this particular ejabberd node)
and ACLs will be removed before new ones are added.
-
+
The option hosts defines a list containing one or more domains that
ejabberd will serve.
Examples:
-
+
Options can be defined separately for every virtual host using the
host_config option. It has the following
syntax:
@@ -561,7 +578,7 @@ other different modules for some specific virtual hosts:
}
]}.
-
+
The option listen defines for which addresses and ports ejabberd
will listen and what services will be run on them. Each element of the list is a
tuple with the following elements:
@@ -623,7 +640,10 @@ do not allow outgoing sockets on port 5222.
If HTTP Polling is enabled, it wil
is also needed in the Jabber client. Remark also that HTTP Polling can be
interesting to host a web-based Jabber client such as
JWChat.
-
- inet6
- Set up the socket for IPv6.
+
- inet6
- Set up the socket for IPv6 instead of IPv4.
+Note: this option is not required for S2S outgoing connections,
+because when ejabberd attempts to establish a S2S outgoing connection
+it first tries IPv4, and if that fails it attempts with IPv6.
- {ip, IPAddress}
- This option specifies which network
interface to listen for. For example
{ip, {192, 168, 1, 1}}
.
- {max_stanza_size, Size}
-
@@ -832,7 +852,7 @@ services you have to make the transports log and do XDB by themselves:
</xdb_file>
</xdb>
-
+
The option auth_method defines the authentication method that is used
for user authentication:
{auth_method, [<method>]}.
@@ -941,7 +961,7 @@ attacks.
- You may want to allow login access only for certain users. pam_listfile.so
module provides such functionality.
-
+
Access control in ejabberd is performed via Access Control Lists (ACLs). The
@@ -1048,7 +1068,7 @@ There’s also available the access max_s2s_connections_per_node.<
Allow up to 3 connections with each remote server:
{access, max_s2s_connections, [{3, all}]}.
-
+
Shapers enable you to limit connection traffic. The syntax of
shapers is like this:
{shaper, <shapername>, <kind>}.
@@ -1067,7 +1087,7 @@ To define a shaper named ‘normal’ with traffic speed limi
50,000 bytes/second:
{shaper, fast, {maxrate, 50000}}.
-
+
The option language defines the default language of server strings that
can be seen by Jabber clients. If a Jabber client do not support
xml:lang, the specified language is used. The default value is
@@ -1079,7 +1099,7 @@ To set Russian as default language:
To set Spanish as default language:
{language, "es"}.
-
+
The option include_config_file in a configuration file instructs ejabberd to include other configuration files immediately.
The basic usage is:
{include_config_file, <filename>}.
It is also possible to specify suboptions:
@@ -1110,7 +1130,7 @@ and later includes another file with additional rules:
{acl, admin, {user, "bob", "localhost"}}.
{acl, admin, {user, "jan", "localhost"}}.
-
+
In the ejabberd configuration file,
it is possible to define a macro for a value
and later use this macro when defining an option.
A macro is defined with this syntax:
@@ -1159,7 +1179,7 @@ This usage behaves as if it were defined and used this way:
]
}.
-
+
ejabberd uses its internal Mnesia database by default. However, it is
possible to use a relational database or an LDAP server to store persistent,
@@ -1181,7 +1201,7 @@ different storage systems for modules, and so forth.
The following databas
Normally any LDAP compatible server should work; inform us about your
success with a not-listed server so that we can list it here.
-
+
Although this section will describe ejabberd’s configuration when you want to
use the native MySQL driver, it does not describe MySQL’s installation and
database creation. Check the MySQL documentation and the tutorial Using ejabberd with MySQL native driver for information regarding these topics.
@@ -1237,7 +1257,7 @@ relational databases like MySQL. To enable storage to your database, just make
sure that your database is running well (see previous sections), and replace the
suffix-less or ldap module variant with the odbc module variant. Keep in mind
that you cannot have several variants of the same module loaded!
-
+
Although this section will describe ejabberd’s configuration when you want to
use Microsoft SQL Server, it does not describe Microsoft SQL Server’s
installation and database creation. Check the MySQL documentation and the
@@ -1273,7 +1293,7 @@ database, just make sure that your database is running well (see previous
sections), and replace the suffix-less or ldap module variant with the odbc
module variant. Keep in mind that you cannot have several variants of the same
module loaded!
-
+
Although this section will describe ejabberd’s configuration when you want to
use the native PostgreSQL driver, it does not describe PostgreSQL’s installation
and database creation. Check the PostgreSQL documentation and the tutorial Using ejabberd with MySQL native driver for information regarding these topics.
@@ -1332,7 +1352,7 @@ relational databases like PostgreSQL. To enable storage to your database, just
make sure that your database is running well (see previous sections), and
replace the suffix-less or ldap module variant with the odbc module variant.
Keep in mind that you cannot have several variants of the same module loaded!
-
+
Although this section will describe ejabberd’s configuration when you want to
use the ODBC driver, it does not describe the installation and database creation
of your database. Check the documentation of your database. The tutorial Using ejabberd with MySQL native driver also can help you. Note that the tutorial
@@ -1375,7 +1395,7 @@ database, just make sure that your database is running well (see previous
sections), and replace the suffix-less or ldap module variant with the odbc
module variant. Keep in mind that you cannot have several variants of the same
module loaded!
-
+
ejabberd has built-in LDAP support. You can authenticate users against LDAP
server and use LDAP directory as vCard storage. Shared rosters are not supported
yet.
@@ -1552,7 +1572,7 @@ configuration is shown below:{auth_method, ldap}.
...
]}.
-
+
The option modules defines the list of modules that will be loaded after
ejabberd’s startup. Each entry in the list is a tuple in which the first
element is the name of a module and the second is a list of options for that
@@ -1574,7 +1594,7 @@ all entries end with a comma:
{mod_version, []}
]}.
-
+
The following table lists all modules included in ejabberd.
Module | Feature | Dependencies |
mod_adhoc | Ad-Hoc Commands (XEP-0050) | |
@@ -1636,7 +1656,7 @@ Last connection date and time: Use mod_last_odbc instead of
ejabberd website. Please remember that these contributions might not work or
that they can contain severe bugs and security leaks. Therefore, use them at
your own risk!
-
The following options are used by many modules. Therefore, they are described in
+
The following options are used by many modules. Therefore, they are described in
this separate section.
Many modules define handlers for processing IQ queries of different namespaces
@@ -1688,7 +1708,7 @@ the "@HOST@" keyword must be used:
...
]}.
-
+
This module enables configured users to broadcast announcements and to set
the message of the day (MOTD).
Configured users can perform these actions with a
@@ -1752,7 +1772,7 @@ Only administrators can send announcements:
Note that mod_announce can be resource intensive on large
deployments as it can broadcast lot of messages. This module should be
disabled for instances of ejabberd with hundreds of thousands users.
-
+
@@ -1795,7 +1815,7 @@ To serve a link to the Jabber User Directory on jabber.org:
...
]}.
-
+
This module simply echoes any Jabber
packet back to the sender. This mirror can be of interest for
ejabberd and Jabber client debugging.
Options:
@@ -1815,7 +1835,7 @@ of them all?
...
]}.
-
+
This module is an IRC transport that can be used to join channels on IRC
servers.
End user information:
@@ -1874,7 +1894,7 @@ our domains and on other servers.
...
]}.
-
+
This module adds support for Last Activity (XEP-0012). It can be used to
discover when a disconnected user last accessed the server, to know when a
connected user was last active on the server, or to query the uptime of the
@@ -1883,7 +1903,7 @@ connected user was last active on the server, or to query the uptime of the
iqdisc
This specifies
the processing discipline for Last activity (jabber:iq:last) IQ queries (see section 3.3.2).
-
+
With this module enabled, your server will support Multi-User Chat
(XEP-0045). End users will be able to join text conferences.
Some of the features of Multi-User Chat:
-
@@ -2083,7 +2103,7 @@ newly created chatrooms have by default those options.
...
]}.
-
+
This module enables optional logging of Multi-User Chat (MUC) conversations to
HTML. Once you enable this module, users can join a chatroom using a MUC capable
Jabber client, and if they have enough privileges, they can request the
@@ -2092,8 +2112,8 @@ configuration form in which they can set the option to enable chatroom logging.<
Chatroom details are added on top of each page: room title, JID,
author, subject and configuration.
-Room title and JID are links to join the chatroom (using
-XMPP URIs).
+The room JID in the generated HTML is a link to join the chatroom (using
+XMPP URI).
Subject and chatroom configuration changes are tracked and displayed.
Joins, leaves, nick changes, kicks, bans and ‘/me’ are tracked and
displayed, including the reason if available.
@@ -2190,7 +2210,7 @@ top link will be the default <a href="/">Home</a>
.
...
]}.
-
+
This module implements offline message storage. This means that all messages
sent to an offline user will be stored on the server until that user comes
online again. Thus it is very similar to how email works. Note that
@@ -2201,7 +2221,7 @@ is use to set a max number of offline messages per user (quota). Its
value can be either infinity or a strictly positive
integer. The default value is infinity.
-
+
This module implements Blocking Communication (also known as Privacy Rules)
as defined in section 10 from XMPP IM. If end users have support for it in
their Jabber client, they will be able to:
@@ -2229,7 +2249,7 @@ subscription type (or globally).
iqdisc
This specifies
the processing discipline for Blocking Communication (jabber:iq:privacy) IQ queries (see section 3.3.2).
-
+
This module adds support for Private XML Storage (XEP-0049):
Using this method, Jabber entities can store private data on the server and
@@ -2241,7 +2261,7 @@ of client-specific preferences; another is Bookmark Storage ( This specifies
the processing discipline for Private XML Storage (jabber:iq:private) IQ queries (see section 3.3.2).
-
+
This module implements SOCKS5 Bytestreams (XEP-0065).
It allows ejabberd to act as a file transfer proxy between two
XMPP clients.
Options:
@@ -2296,7 +2316,7 @@ The simpliest configuration of the module:
...
]}.
-
+
This module offers a Publish-Subscribe Service (XEP-0060).
The functionality in mod_pubsub can be extended using plugins.
The plugin that implements PEP (Personal Eventing via Pubsub) (XEP-0163)
@@ -2327,7 +2347,7 @@ and is shared by all node plugins.
...
]}.
-
+
This module adds support for In-Band Registration (XEP-0077). This protocol
enables end users to use a Jabber client to:
-
@@ -2343,6 +2363,7 @@ restrictions by default).
- welcome_message
- Set a welcome message that
is sent to each newly registered account. The first string is the subject, and
the second string is the message body.
+In the body you can set a newline with the characters: ~n.
- registration_watchers
- This option defines a
list of JIDs which will be notified each time a new account is registered.
- iqdisc
- This specifies
@@ -2393,19 +2414,19 @@ Also define a registration timeout of one hour:
...
{mod_register,
[
- {welcome_message, {"Welcome!", "Welcome to this Jabber server. Check http://www.jabber.org"}},
+ {welcome_message, {"Welcome!", "Hi.~nWelcome to this Jabber server.~n Check http://www.jabber.org~n~nBye"}},
{registration_watchers, ["admin1@example.org", "boss@example.net"]}
]},
...
]}.
-
+
This module implements roster management as defined in RFC 3921: XMPP IM.
Options:
-
iqdisc
- This specifies
the processing discipline for Roster Management (jabber:iq:roster) IQ queries (see section 3.3.2).
-
+
This module adds support for logging end user packets via a Jabber message
auditing service such as
Bandersnatch. All user
@@ -2435,7 +2456,7 @@ To log all end user packets to the Bandersnatch service running on
...
]}.
-
+
This module enables you to create shared roster groups. This means that you can
create groups of people that can see members from (other) groups in their
rosters. The big advantages of this feature are that end users do not need to
@@ -2510,7 +2531,7 @@ roster groups as shown in the following table:
-
+
This module adds support for Statistics Gathering (XEP-0039). This protocol
allows you to retrieve next statistics from your ejabberd deployment:
-
@@ -2542,14 +2563,14 @@ by sending:
</query>
</iq>
-
+
This module features support for Entity Time (XEP-0090). By using this XEP,
you are able to discover the time at another entity’s location.
Options:
-
iqdisc
- This specifies
the processing discipline for Entity Time (jabber:iq:time) IQ queries (see section 3.3.2).
-
+
This module allows end users to store and retrieve their vCard, and to retrieve
other users vCards, as defined in vcard-temp (XEP-0054). The module also
implements an uncomplicated Jabber User Directory based on the vCards of
@@ -2604,7 +2625,7 @@ and that all virtual hosts will be searched instead of only the current one:
...
]}.
-
+
ejabberd can map LDAP attributes to vCard fields. This behaviour is
implemented in the mod_vcard_ldap module. This module does not depend on the
authentication method (see 3.2.5).
The mod_vcard_ldap module has
@@ -2778,7 +2799,7 @@ searching his info in LDAP.
ldap_vcard_map
-
+
This module implements Software Version (XEP-0092). Consequently, it
answers ejabberd’s version when queried.
Options:
-
@@ -2787,9 +2808,9 @@ The default value is true.
- iqdisc
- This specifies
the processing discipline for Software Version (jabber:iq:version) IQ queries (see section 3.3.2).
-
-
-
The ejabberdctl command line administration script allows to start, stop and perform
+
+
+
The ejabberdctl command line administration script allows to start, stop and perform
many other administrative tasks in a local or remote ejabberd server.
When ejabberdctl is executed without any parameter,
it displays the available options. If there isn’t an ejabberd server running,
the available parameters are:
@@ -2822,7 +2843,7 @@ and other codes may be used for specifical results.
This can be used by other scripts to determine automatically
if a command succedded or failed,
for example using: echo $?
-
ejabberd is an Erlang/OTP application that runs inside an Erlang runtime system.
+
ejabberd is an Erlang/OTP application that runs inside an Erlang runtime system.
This system is configured using environment variables and command line parameters.
The ejabberdctl administration script uses many of those possibilities.
You can configure some of them with the file ejabberdctl.cfg,
@@ -2889,7 +2910,7 @@ Starts the Erlang system detached from the system console.
Note that some characters need to be escaped when used in shell scripts, for instance "
and {}
.
You can find other options in the Erlang manual page (erl -man erl).
-
+
The ejabberd Web Admin allows to administer most of ejabberd using a web browser.
This feature is enabled by default:
a ejabberd_http listener with the option web_admin (see
section 3.1.3) is included in the listening ports. Then you can open
@@ -2949,15 +2970,15 @@ web browser to https://192.168.1.1:5280/admin/
:
...
]}.
-
If you enable mod_configure and mod_adhoc,
+
If you enable mod_configure and mod_adhoc,
you can perform several administrative tasks in ejabberd
with a Jabber client.
The client must support Ad-Hoc Commands (XEP-0050),
and you must login in the Jabber server with
an account with proper privileges.
-
ejabberd uses the distributed Mnesia database.
+
ejabberd uses the distributed Mnesia database.
Being distributed, Mnesia enforces consistency of its file,
-so it stores the name of the Erlang node in it.
+so it stores the name of the Erlang node in it (see section 5.4).
The name of an Erlang node includes the hostname of the computer.
So, the name of the Erlang node changes
if you change the name of the machine in which ejabberd runs,
@@ -2971,8 +2992,8 @@ you must follow these instructions:
For example:
ejabberdctl restore /tmp/ejabberd-oldhost.backup
-
-
+
+
You need to take the following TCP ports in mind when configuring your firewall:
Port | Description |
@@ -2983,7 +3004,7 @@ you must follow these instructions:
port range | Used for connections between Erlang nodes. This range is configurable (see section 5.2). |
-
epmd (Erlang Port Mapper Daemon)
+
epmd (Erlang Port Mapper Daemon)
is a small name server included in Erlang/OTP
and used by Erlang programs when establishing distributed Erlang communications.
ejabberd needs epmd to use ejabberdctl and also when clustering ejabberd nodes.
@@ -3008,9 +3029,10 @@ but can be configured in the file ejabberdctl.cfg.
The Erlang command-line parameter used internally is, for example:
erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375
-
The Erlang cookie is a string with numbers and letters.
-An Erlang node reads the cookie at startup from the command-line parameter -setcookie
-or from a cookie file.
+
The Erlang cookie is a string with numbers and letters.
+An Erlang node reads the cookie at startup from the command-line parameter -setcookie.
+If not indicated, the cookie is read from the cookie file $HOME/.erlang.cookie.
+If this file does not exist, it is created immediately with a random cookie.
Two Erlang nodes communicate only if they have the same cookie.
Setting a cookie on the Erlang node allows you to structure your Erlang network
and define which nodes are allowed to connect to which.
Thanks to Erlang cookies, you can prevent access to the Erlang node by mistake,
@@ -3021,7 +3043,7 @@ to prevent unauthorized access or intrusion to an Erlang node.
The communication between Erlang nodes are not encrypted,
so the cookie could be read sniffing the traffic on the network.
The recommended way to secure the Erlang node is to block the port 4369.
-
An Erlang node may have a node name.
+
An Erlang node may have a node name.
The name can be short (if indicated with the command-line parameter -sname)
or long (if indicated with the parameter -name).
Starting an Erlang node with -sname limits the communication between Erlang nodes to the LAN.
Using the option -sname instead of -name is a simple method
@@ -3029,10 +3051,30 @@ to difficult unauthorized access to your Erlang node.
However, it is not ultimately effective to prevent access to the Erlang node,
because it may be possible to fake the fact that you are on another network
using a modified version of Erlang epmd.
-The recommended way to secure the Erlang node is to block the port 4369.
-
+The recommended way to secure the Erlang node is to block the port 4369.
+
ejabberd stores sensible data in the file system either in plain text or binary files.
+The file system permissions should be set to only allow the proper user to read,
+write and execute those files and directories.
-
+ejabberd configuration file: /etc/ejabberd/ejabberd.cfg
-
+Contains the JID of administrators
+and passwords of external components.
+The backup files probably contain also this information,
+so it is preferable to secure the whole /etc/ejabberd/ directory.
+
- ejabberd service log: /var/log/ejabberd/ejabberd.log
-
+Contains IP addresses of clients.
+If the loglevel is set to 5, it contains whole conversations and passwords.
+If a logrotate system is used, there may be several log files with similar information,
+so it is preferable to secure the whole /var/log/ejabberd/ directory.
+
- Mnesia database spool files: /var/lib/ejabberd/db/*
-
+The files store binary data, but some parts are still readable.
+The files are generated by Mnesia and their permissions cannot be set directly,
+so it is preferable to secure the whole /var/lib/ejabberd/db/ directory.
+
- Erlang cookie file: /var/lib/ejabberd/.erlang.cookie
-
+See section 5.3.
+
+
-
+
A Jabber domain is served by one or more ejabberd nodes. These nodes can
be run on different machines that are connected via a network. They all
must have the ability to connect to port 4369 of all another nodes, and must
@@ -3046,29 +3088,29 @@ router,
session manager,
s2s manager.
-
+
This module is the main router of Jabber packets on each node. It
routes them based on their destination’s domains. It uses a global
routing table. The domain of the packet’s destination is searched in the
routing table, and if it is found, the packet is routed to the
appropriate process. If not, it is sent to the s2s manager.
-
+
This module routes packets which have a destination domain equal to
one of this server’s host names. If the destination JID has a non-empty user
part, it is routed to the session manager, otherwise it is processed depending
on its content.
-
+
This module routes packets to local users. It looks up to which user
resource a packet must be sent via a presence table. Then the packet is
either routed to the appropriate c2s process, or stored in offline
storage, or bounced back.
-
+
This module routes packets to other Jabber servers. First, it
checks if an opened s2s connection from the domain of the packet’s
source to the domain of the packet’s destination exists. If that is the case,
the s2s manager routes the packet to the process
serving this connection, otherwise a new connection is opened.
-
+
Suppose you already configured ejabberd on one machine named (first),
and you need to setup another one to make an ejabberd cluster. Then do
following steps:
-
@@ -3102,10 +3144,10 @@ and ‘
access
’ options — they will be taken from
enabled only on one machine in the cluster).
You can repeat these steps for other machines supposed to serve this
domain.
-
+
-
-
+
+
ejabberd includes an algorithm to load balance the components that are plugged on an ejabberd cluster. It means that you can plug one or several instances of the same component on each ejabberd cluster and that the traffic will be automatically distributed.
The default distribution algorithm try to deliver to a local instance of a component. If several local instances are available, one instance is chosen randomly. If no instance is available locally, one instance is chosen randomly among the remote component instances.
If you need a different behaviour, you can change the load balancing behaviour with the option domain_balancing. The syntax of the option is the following:
{domain_balancing, "component.example.com", <balancing_criterium>}.
Several balancing criteria are available:
-
@@ -3114,13 +3156,13 @@ domain.
-
+
When there is a risk of failure for a given component, domain balancing can cause service trouble. If one component is failing the service will not work correctly unless the sessions are rebalanced.
In this case, it is best to limit the problem to the sessions handled by the failing component. This is what the domain_balancing_component_number option does, making the load balancing algorithm not dynamic, but sticky on a fix number of component instances.
The syntax is the following:
{domain_balancing_component_number, "component.example.com", N}
-
+
-
+
ejabberd includes a watchdog mechanism.
If a process in the ejabberd server consumes too much memory,
a message is sent to the Jabber accounts defined with the option
@@ -3132,7 +3174,7 @@ Example configuration:
To remove all watchdog admins, set the option with an empty list:
{watchdog_admins, []}.
-
An ejabberd node writes two log files:
+
An ejabberd node writes two log files:
-
ejabberd.log
- is the ejabberd service log, with the messages reported by ejabberd code
- sasl.log
- is the Erlang/OTP system log, with the messages reported by Erlang/OTP using SASL (System Architecture Support Libraries)
@@ -3149,12 +3191,12 @@ The possible levels are:
For example, the default configuration is:
{loglevel, 4}.
-
The Debug Console is an Erlang shell attached to an already running ejabberd server.
+
The Debug Console is an Erlang shell attached to an already running ejabberd server.
With this Erlang shell, an experienced administrator can perform complex tasks.
This shell gives complete control over the ejabberd server,
so it is important to use it with extremely care.
There are some simple and safe examples in the article
Interconnecting Erlang Nodes
To exit the shell, close the window or press the keys: control+c control+c.
-
+
All built-in modules support the xml:lang attribute inside IQ queries.
Figure A.1, for example, shows the reply to the following query:
<iq id='5'
@@ -3181,9 +3223,9 @@ HTTP header ‘Accept-Language: ru’
-
+
Release notes are available from ejabberd Home Page
-
Thanks to all people who contributed to this guide:
+
Thanks to all people who contributed to this guide:
-
Ejabberd Installation and Operation Guide.
+
Ejabberd Installation and Operation Guide.
Copyright © 2003 — 2008 Process-one
This document is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
diff --git a/doc/guide.tex b/doc/guide.tex
index 73d889fc5..5a23a359a 100644
--- a/doc/guide.tex
+++ b/doc/guide.tex
@@ -361,7 +361,7 @@ The files and directories created are, by default:
\titem{/sbin/ejabberdctl} Administration script
\titem{/var/lib/ejabberd/}
\begin{description}
- \titem{.erlang.cookie} Erlang cookie file
+ \titem{.erlang.cookie} Erlang cookie file (see section \ref{cookie})
\titem{db} Mnesia database spool files
\titem{ebin} Binary Erlang files (*.beam)
\titem{priv}
@@ -405,6 +405,31 @@ gmake
\end{verbatim}
+\makesubsection{solaris}{Specific Notes for Sun Solaris}
+\ind{install!solaris}
+
+You need to have \term{GNU install},
+but it isn't included in Solaris.
+It can be easily installed if your Solaris system
+is set up for \footahref{http://www.blastwave.org/}{blastwave.org}
+package repository.
+Make sure \term{/opt/csw/bin} is in your \term{PATH} and run:
+\begin{verbatim}
+pkg-get -i fileutils
+\end{verbatim}
+
+If that program is called \term{ginstall},
+modify the \ejabberd{} \term{Makefile} script to suit your system,
+for example:
+\begin{verbatim}
+cat Makefile | sed s/install/ginstall/ > Makefile.gi
+\end{verbatim}
+And finally install \ejabberd{} with:
+\begin{verbatim}
+gmake -f Makefile.gi ginstall
+\end{verbatim}
+
+
\makesubsection{windows}{Specific Notes for Microsoft Windows}
\ind{install!windows}
@@ -729,7 +754,10 @@ This is a detailed description of each option allowed by the listening modules:
is also needed in the \Jabber{} client. Remark also that HTTP Polling can be
interesting to host a web-based \Jabber{} client such as
\footahref{http://jwchat.sourceforge.net/}{JWChat}.
- \titem{inet6} \ind{options!inet6}\ind{IPv6}Set up the socket for IPv6.
+ \titem{inet6} \ind{options!inet6}\ind{IPv6}Set up the socket for IPv6 instead of IPv4.
+ Note: this option is not required for S2S outgoing connections,
+ because when ejabberd attempts to establish a S2S outgoing connection
+ it first tries IPv4, and if that fails it attempts with IPv6.
\titem{\{ip, IPAddress\}} \ind{options!ip}This option specifies which network
interface to listen for. For example \verb|{ip, {192, 168, 1, 1}}|.
\titem{\{max\_stanza\_size, Size\}}
@@ -2710,9 +2738,9 @@ Features:
\begin{itemize}
\item Chatroom details are added on top of each page: room title, JID,
author, subject and configuration.
-\item \ind{protocols!RFC 4622: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)}
- Room title and JID are links to join the chatroom (using
- \footahref{http://www.ietf.org/rfc/rfc4622.txt}{XMPP URIs}).
+\item \ind{protocols!RFC 5122: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)}
+ The room JID in the generated HTML is a link to join the chatroom (using
+ \footahref{http://www.xmpp.org/rfcs/rfc5122.html}{XMPP URI}).
\item Subject and chatroom configuration changes are tracked and displayed.
\item Joins, leaves, nick changes, kicks, bans and `/me' are tracked and
displayed, including the reason if available.
@@ -3008,6 +3036,7 @@ Options:
\titem{welcome\_message} \ind{options!welcomem}Set a welcome message that
is sent to each newly registered account. The first string is the subject, and
the second string is the message body.
+ In the body you can set a newline with the characters: \term{\~\ n}.
\titem{registration\_watchers} \ind{options!rwatchers}This option defines a
list of JIDs which will be notified each time a new account is registered.
\iqdiscitem{In-Band Registration (\ns{jabber:iq:register})}
@@ -3066,7 +3095,7 @@ Also define a registration timeout of one hour:
...
{mod_register,
[
- {welcome_message, {"Welcome!", "Welcome to this Jabber server. Check http://www.jabber.org"}},
+ {welcome_message, {"Welcome!", "Hi.~nWelcome to this Jabber server.~n Check http://www.jabber.org~n~nBye"}},
{registration_watchers, ["admin1@example.org", "boss@example.net"]}
]},
...
@@ -3781,7 +3810,7 @@ an account with proper privileges.
\ejabberd{} uses the distributed Mnesia database.
Being distributed, Mnesia enforces consistency of its file,
-so it stores the name of the Erlang node in it.
+so it stores the name of the Erlang node in it (see section \ref{nodename}).
The name of an Erlang node includes the hostname of the computer.
So, the name of the Erlang node changes
if you change the name of the machine in which \ejabberd{} runs,
@@ -3861,8 +3890,9 @@ erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375
\makesection{cookie}{Erlang Cookie}
The Erlang cookie is a string with numbers and letters.
-An Erlang node reads the cookie at startup from the command-line parameter \term{-setcookie}
-or from a cookie file.
+An Erlang node reads the cookie at startup from the command-line parameter \term{-setcookie}.
+If not indicated, the cookie is read from the cookie file \term{\$HOME/.erlang.cookie}.
+If this file does not exist, it is created immediately with a random cookie.
Two Erlang nodes communicate only if they have the same cookie.
Setting a cookie on the Erlang node allows you to structure your Erlang network
and define which nodes are allowed to connect to which.
@@ -3894,6 +3924,32 @@ using a modified version of Erlang \term{epmd}.
The recommended way to secure the Erlang node is to block the port 4369.
+\makesection{secure-files}{Securing sensible files}
+
+\ejabberd{} stores sensible data in the file system either in plain text or binary files.
+The file system permissions should be set to only allow the proper user to read,
+write and execute those files and directories.
+
+\begin{description}
+ \titem{ejabberd configuration file: /etc/ejabberd/ejabberd.cfg}
+ Contains the JID of administrators
+ and passwords of external components.
+ The backup files probably contain also this information,
+ so it is preferable to secure the whole \term{/etc/ejabberd/} directory.
+ \titem{ejabberd service log: /var/log/ejabberd/ejabberd.log}
+ Contains IP addresses of clients.
+ If the loglevel is set to 5, it contains whole conversations and passwords.
+ If a logrotate system is used, there may be several log files with similar information,
+ so it is preferable to secure the whole \term{/var/log/ejabberd/} directory.
+ \titem{Mnesia database spool files: /var/lib/ejabberd/db/*}
+ The files store binary data, but some parts are still readable.
+ The files are generated by Mnesia and their permissions cannot be set directly,
+ so it is preferable to secure the whole \term{/var/lib/ejabberd/db/} directory.
+ \titem{Erlang cookie file: /var/lib/ejabberd/.erlang.cookie}
+ See section \ref{cookie}.
+\end{description}
+
+
\makechapter{clustering}{Clustering}
\ind{clustering}
diff --git a/src/Makefile.in b/src/Makefile.in
index 57bb56333..607af353e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -60,6 +60,7 @@ DESTDIR =
EJABBERDDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
BEAMDIR = $(EJABBERDDIR)/ebin
+SPOOLDIR = $(EJABBERDDIR)/db
PRIVDIR = $(EJABBERDDIR)/priv
SODIR = $(PRIVDIR)/lib
PBINDIR = $(PRIVDIR)/bin
@@ -116,20 +117,21 @@ install: all
install -m 644 *.beam $(BEAMDIR)
rm -f $(BEAMDIR)/configure.beam
install -m 644 *.app $(BEAMDIR)
+ install -d -m 750 $(SPOOLDIR)
install -d $(SODIR)
install -d $(PBINDIR)
install -m 644 *.so $(SODIR)
$(INSTALL_EPAM)
install -d $(MSGSDIR)
install -m 644 msgs/*.msg $(MSGSDIR)
- install -d $(ETCDIR)
+ install -d -m 750 $(ETCDIR)
[ -f $(ETCDIR)/ejabberd.cfg ] && install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new || install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
sed -e "s*@rootdir@*@prefix@*" ejabberdctl.template > ejabberdctl.example
[ -f $(ETCDIR)/ejabberdctl.cfg ] && install -b -m 644 ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new || install -b -m 644 ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
install -b -m 644 inetrc $(ETCDIR)/inetrc
install -d $(SBINDIR)
install -m 755 ejabberdctl.example $(SBINDIR)/ejabberdctl
- install -d $(LOGDIR)
+ install -d -m 750 $(LOGDIR)
uninstall: uninstall-binary
diff --git a/src/configure b/src/configure
index 573a17ee7..034868416 100755
--- a/src/configure
+++ b/src/configure
@@ -4765,6 +4765,9 @@ _ACEOF
fi
+# Check Erlang headers are installed
+#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
+
# Change default prefix
diff --git a/src/configure.ac b/src/configure.ac
index a3e8894e9..254b16b06 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -26,6 +26,9 @@ AM_WITH_PAM
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
+# Check Erlang headers are installed
+#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
+
# Change default prefix
AC_PREFIX_DEFAULT(/)
diff --git a/src/ejabberd.cfg.example b/src/ejabberd.cfg.example
index e1d63ed9e..eb43bb3ca 100644
--- a/src/ejabberd.cfg.example
+++ b/src/ejabberd.cfg.example
@@ -459,7 +459,7 @@
%% a message with this subject and body.
%%
{welcome_message, {"Welcome!",
- "Welcome to this Jabber server."}},
+ "Hi.~nWelcome to this Jabber server."}},
%%
%% When a user registers, send a notification to
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index dae88f07a..82fd029ce 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1223,6 +1223,9 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
handle_info({'DOWN', Monitor, _Type, _Object, _Info}, _StateName, StateData)
when Monitor == StateData#state.socket_monitor ->
{stop, normal, StateData};
+handle_info({peername, IP}, StateName, StateData) ->
+ ejabberd_sm:set_session_ip(StateData#state.sid, IP),
+ fsm_next_state(StateName, StateData#state{ip = IP});
handle_info(Info, StateName, StateData) ->
?ERROR_MSG("Unexpected info: ~p", [Info]),
fsm_next_state(StateName, StateData).
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index 7a9cade1f..c18cfe6de 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -96,8 +96,10 @@ get_plain_terms_file(File1) ->
{ok, Terms} ->
include_config_files(Terms);
{error, Reason} ->
- ?ERROR_MSG("Can't load config file ~p: ~p", [File, Reason]),
- exit(File ++ ": " ++ file:format_error(Reason))
+ ExitText = lists:flatten(File ++ ": around line "
+ ++ file:format_error(Reason)),
+ ?ERROR_MSG("Problem loading ejabberd config file:~n~s", [ExitText]),
+ exit(ExitText)
end.
%% @doc Convert configuration filename to absolute path.
diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl
index 7cb36141d..9a84b592e 100644
--- a/src/ejabberd_ctl.erl
+++ b/src/ejabberd_ctl.erl
@@ -30,6 +30,7 @@
-export([start/0,
init/0,
process/1,
+ dump_to_textfile/1,
register_commands/3,
register_commands/4,
unregister_commands/3,
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index 76719bbb8..c3786ca53 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -37,6 +37,7 @@
register_iq_handler/5,
register_iq_response_handler/4,
unregister_iq_handler/2,
+ unregister_iq_response_handler/2,
refresh_iq_handlers/0,
bounce_resource_packet/3
]).
@@ -168,6 +169,9 @@ register_iq_handler(Host, XMLNS, Module, Fun) ->
register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
+unregister_iq_response_handler(Host, ID) ->
+ ejabberd_local ! {unregister_iq_response_handler, Host, ID}.
+
unregister_iq_handler(Host, XMLNS) ->
ejabberd_local ! {unregister_iq_handler, Host, XMLNS}.
@@ -254,6 +258,9 @@ handle_info({route, From, To, Packet}, State) ->
handle_info({register_iq_response_handler, _Host, ID, Module, Function}, State) ->
mnesia:dirty_write(#iq_response{id = ID, module = Module, function = Function}),
{noreply, State};
+handle_info({unregister_iq_response_handler, _Host, ID}, State) ->
+ mnesia:dirty_delete({iq_response, ID}),
+ {noreply, State};
handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) ->
ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function}),
catch mod_disco:register_feature(Host, XMLNS),
diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl
index 5fdad76af..3b6c80439 100644
--- a/src/ejabberd_receiver.erl
+++ b/src/ejabberd_receiver.erl
@@ -268,7 +268,8 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
activate_socket(#state{socket = Socket,
- sock_mod = SockMod}) ->
+ sock_mod = SockMod,
+ c2s_pid = C2SPid}) ->
PeerName =
case SockMod of
gen_tcp ->
@@ -281,7 +282,8 @@ activate_socket(#state{socket = Socket,
case PeerName of
{error, _Reason} ->
self() ! {tcp_closed, Socket};
- {ok, _} ->
+ {ok, IP} ->
+ C2SPid ! {peername, IP},
ok
end.
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 9300958d5..ccf679386 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -49,7 +49,8 @@
ctl_process/2,
get_session_pid/3,
get_user_info/3,
- get_user_ip/3
+ get_user_ip/3,
+ set_session_ip/2
]).
%% gen_server callbacks
@@ -186,6 +187,18 @@ get_user_info(User, Server, Resource) ->
[{node, Node}, {conn, Conn}, {ip, IP}]
end.
+set_session_ip(SID, IP) ->
+ case mnesia:dirty_read(session, SID) of
+ [#session{info = Info} = Session] ->
+ NewInfo = case lists:keymember(ip, 1, Info) of
+ true -> lists:keyreplace(ip, 1, Info, {ip, IP});
+ false -> [{ip, IP}|Info]
+ end,
+ mnesia:dirty_write(Session#session{info = NewInfo});
+ _ ->
+ ok
+ end.
+
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
set_session(SID, User, Server, Resource, Priority, Info),
% XXX OLD FORMAT: Presence.
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 2be0fac66..3240aa6e2 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -53,6 +53,7 @@
-define(PROCNAME, ejabberd_mod_caps).
-define(DICT, dict).
+-define(CAPS_QUERY_TIMEOUT, 60000). % 1mn without answer, consider client never answer
-record(caps, {node, version, exts}).
-record(caps_features, {node_pair, features}).
@@ -220,6 +221,7 @@ handle_cast({note_caps, From,
ejabberd_local:register_iq_response_handler
(Host, ID, ?MODULE, handle_disco_response),
ejabberd_router:route(jlib:make_jid("", Host, ""), From, Stanza),
+ timer:send_after(?CAPS_QUERY_TIMEOUT, self(), {disco_timeout, ID}),
?DICT:store(ID, {Node, SubNode}, Dict)
end, Requests, Missing),
{noreply, State#state{disco_requests = NewRequests}};
@@ -274,6 +276,16 @@ handle_cast({disco_response, From, _To,
end,
NewRequests = ?DICT:erase(ID, Requests),
{noreply, State#state{disco_requests = NewRequests}};
+handle_cast({disco_timeout, ID}, #state{host = Host, disco_requests = Requests} = State) ->
+ %% do not wait a response anymore for this IQ, client certainly will never answer
+ NewRequests = case ?DICT:is_key(ID, Requests) of
+ true ->
+ ejabberd_local:unregister_iq_response_handler(Host, ID),
+ ?DICT:erase(ID, Requests);
+ false ->
+ Requests
+ end,
+ {noreply, State#state{disco_requests = NewRequests}};
handle_cast(visit_feature_queries, #state{feature_queries = FeatureQueries} = State) ->
Timestamp = timestamp(),
NewFeatureQueries =
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index 625e380cd..e012794dd 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -1416,7 +1416,7 @@ set_form(_From, _Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XD
false ->
{error, ?ERR_BAD_REQUEST};
{value, {_, [String]}} ->
- case rpc:call(Node, mnesia, dump_to_textfile, [String]) of
+ case rpc:call(Node, ejabberd_ctl, dump_to_textfile, [String]) of
{badrpc, _Reason} ->
{error, ?ERR_INTERNAL_SERVER_ERROR};
{error, _Reason} ->
diff --git a/src/mod_muc/mod_muc_log.erl b/src/mod_muc/mod_muc_log.erl
index fce9c15b2..9ab8d4ce2 100644
--- a/src/mod_muc/mod_muc_log.erl
+++ b/src/mod_muc/mod_muc_log.erl
@@ -120,9 +120,11 @@ init([Host, Opts]) ->
NoFollow = gen_mod:get_opt(spam_prevention, Opts, true),
Lang = case ejabberd_config:get_local_option({language, Host}) of
undefined ->
- "";
- L ->
- L
+ case ejabberd_config:get_global_option(language) of
+ undefined -> "en";
+ L -> L
+ end;
+ L -> L
end,
{ok, #state{host = Host,
out_dir = OutDir,
@@ -286,9 +288,10 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
top_link = TopLink} = State,
Room = get_room_info(RoomJID, Opts),
+ Now = now(),
TimeStamp = case Timezone of
- local -> calendar:now_to_local_time(now());
- universal -> calendar:now_to_universal_time(now())
+ local -> calendar:now_to_local_time(Now);
+ universal -> calendar:now_to_universal_time(Now)
end,
{Fd, Fn, _Dir} = build_filename_string(TimeStamp, OutDir, Room#room.jid, DirType),
{Date, Time} = TimeStamp,
@@ -382,10 +385,12 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
{Hour, Minute, Second} = Time,
STime = lists:flatten(
io_lib:format("~2..0w:~2..0w:~2..0w", [Hour, Minute, Second])),
+ {_, _, Microsecs} = Now,
+ STimeUnique = io_lib:format("~s.~w", [STime, Microsecs]),
% Write message
- file:write(F, io_lib:format("[~s] ~s~n",
- [STime, STime, STime, Text])),
+ file:write(F, io_lib:format("[~s] ~s~n",
+ [STimeUnique, STimeUnique, STimeUnique, STime, Text])),
% Close file
file:close(F),
diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl
index e858d680f..64957a70a 100644
--- a/src/mod_muc/mod_muc_room.erl
+++ b/src/mod_muc/mod_muc_room.erl
@@ -59,6 +59,7 @@
-record(lqueue, {queue, len, max}).
-record(config, {title = "",
+ description = "",
allow_change_subj = true,
allow_query_users = true,
allow_private_messages = true,
@@ -2614,7 +2615,10 @@ get_config(Lang, StateData, From) ->
[{xmlcdata, "http://jabber.org/protocol/muc#roomconfig"}]}]},
?STRINGXFIELD("Room title",
"muc#roomconfig_roomname",
- Config#config.title)
+ Config#config.title),
+ ?STRINGXFIELD("Room description",
+ "muc#roomconfig_roomdesc",
+ Config#config.description)
] ++
case acl:match_rule(StateData#state.server_host, AccessPersistent, From) of
allow ->
@@ -2761,6 +2765,8 @@ set_xoption([], Config) ->
Config;
set_xoption([{"muc#roomconfig_roomname", [Val]} | Opts], Config) ->
?SET_STRING_XOPT(title, Val);
+set_xoption([{"muc#roomconfig_roomdesc", [Val]} | Opts], Config) ->
+ ?SET_STRING_XOPT(description, Val);
set_xoption([{"muc#roomconfig_changesubject", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(allow_change_subj, Val);
set_xoption([{"allow_query_users", [Val]} | Opts], Config) ->
@@ -2856,6 +2862,7 @@ set_opts([], StateData) ->
set_opts([{Opt, Val} | Opts], StateData) ->
NSD = case Opt of
title -> StateData#state{config = (StateData#state.config)#config{title = Val}};
+ description -> StateData#state{config = (StateData#state.config)#config{description = Val}};
allow_change_subj -> StateData#state{config = (StateData#state.config)#config{allow_change_subj = Val}};
allow_query_users -> StateData#state{config = (StateData#state.config)#config{allow_query_users = Val}};
allow_private_messages -> StateData#state{config = (StateData#state.config)#config{allow_private_messages = Val}};
@@ -2895,6 +2902,7 @@ make_opts(StateData) ->
Config = StateData#state.config,
[
?MAKE_CONFIG_OPT(title),
+ ?MAKE_CONFIG_OPT(description),
?MAKE_CONFIG_OPT(allow_change_subj),
?MAKE_CONFIG_OPT(allow_query_users),
?MAKE_CONFIG_OPT(allow_private_messages),
@@ -2991,9 +2999,12 @@ process_iq_disco_info(_From, get, Lang, StateData) ->
iq_disco_info_extras(Lang, StateData) ->
Len = length(?DICT:to_list(StateData#state.users)),
+ RoomDescription = (StateData#state.config)#config.description,
[{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}],
[?RFIELDT("hidden", "FORM_TYPE",
"http://jabber.org/protocol/muc#roominfo"),
+ ?RFIELD("Room description", "muc#roominfo_description",
+ RoomDescription),
?RFIELD("Number of occupants", "muc#roominfo_occupants",
integer_to_list(Len))
]}].
diff --git a/src/mod_privacy_odbc.erl b/src/mod_privacy_odbc.erl
index 8db812d0b..b4e267d28 100644
--- a/src/mod_privacy_odbc.erl
+++ b/src/mod_privacy_odbc.erl
@@ -16,7 +16,7 @@
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
-%%%
+%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
@@ -698,11 +698,11 @@ raw_to_item({SType, SValue, SAction, SOrder, SMatchAll, SMatchIQ,
"d" -> deny
end,
Order = list_to_integer(SOrder),
- MatchAll = SMatchAll == "t",
- MatchIQ = SMatchIQ == "t",
- MatchMessage = SMatchMessage == "t",
- MatchPresenceIn = SMatchPresenceIn == "t",
- MatchPresenceOut = SMatchPresenceOut == "t",
+ MatchAll = SMatchAll == "1" orelse SMatchAll == "t",
+ MatchIQ = SMatchIQ == "1" orelse SMatchIQ == "t" ,
+ MatchMessage = SMatchMessage == "1" orelse SMatchMessage == "t",
+ MatchPresenceIn = SMatchPresenceIn == "1" orelse SMatchPresenceIn == "t",
+ MatchPresenceOut = SMatchPresenceOut == "1" orelse SMatchPresenceOut == "t",
#listitem{type = Type,
value = Value,
action = Action,
@@ -750,11 +750,11 @@ item_to_raw(#listitem{type = Type,
deny -> "d"
end,
SOrder = integer_to_list(Order),
- SMatchAll = if MatchAll -> "t"; true -> "f" end,
- SMatchIQ = if MatchIQ -> "t"; true -> "f" end,
- SMatchMessage = if MatchMessage -> "t"; true -> "f" end,
- SMatchPresenceIn = if MatchPresenceIn -> "t"; true -> "f" end,
- SMatchPresenceOut = if MatchPresenceOut -> "t"; true -> "f" end,
+ SMatchAll = if MatchAll -> "1"; true -> "0" end,
+ SMatchIQ = if MatchIQ -> "1"; true -> "0" end,
+ SMatchMessage = if MatchMessage -> "1"; true -> "0" end,
+ SMatchPresenceIn = if MatchPresenceIn -> "1"; true -> "0" end,
+ SMatchPresenceOut = if MatchPresenceOut -> "1"; true -> "0" end,
["'", SType, "', "
"'", SValue, "', "
"'", SAction, "', "
@@ -871,6 +871,3 @@ sql_set_privacy_list(ID, RItems) ->
") "
"values ('", ID, "', ", Items, ");"])
end, RItems).
-
-
-
diff --git a/src/mod_pubsub/gen_pubsub_node.erl b/src/mod_pubsub/gen_pubsub_node.erl
index 195ed3934..bbbb5c409 100644
--- a/src/mod_pubsub/gen_pubsub_node.erl
+++ b/src/mod_pubsub/gen_pubsub_node.erl
@@ -62,7 +62,9 @@ behaviour_info(callbacks) ->
{get_states, 2},
{get_state, 3},
{set_state, 1},
+ {get_items, 7},
{get_items, 2},
+ {get_item, 8},
{get_item, 3},
{set_item, 1},
{get_item_name, 3}
diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl
index cb8ce997d..e83e0170f 100644
--- a/src/mod_pubsub/mod_pubsub.erl
+++ b/src/mod_pubsub/mod_pubsub.erl
@@ -30,16 +30,17 @@
%%%
%%% @reference See XEP-0060: Pubsub for
%%% the latest version of the PubSub specification.
-%%% This module uses version 1.10 of the specification as a base.
+%%% This module uses version 1.11 of the specification as a base.
%%% Most of the specification is implemented.
-%%% Code is derivated from the original pubsub v1.7, functions concerning config may be rewritten.
-%%% Code also inspired from the original PEP patch by Magnus Henoch (mangeATfreemail.hu)
+%%% Functions concerning configuration should be rewritten.
+%%% Code is derivated from the original pubsub v1.7, by Alexey Shchepin
%%% TODO
%%% plugin: generate Reply (do not use broadcast atom anymore)
-module(mod_pubsub).
--version('1.10-01').
+-author('christophe.romain@process-one.net').
+-version('1.11-01').
-behaviour(gen_server).
-behaviour(gen_mod).
@@ -912,7 +913,17 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, _Lang, Access, Plugins) ->
unsubscribe_node(Host, Node, From, JID, SubId);
{get, "items"} ->
MaxItems = xml:get_attr_s("max_items", Attrs),
- get_items(Host, Node, From, MaxItems);
+ SubId = xml:get_attr_s("subid", Attrs),
+ ItemIDs = lists:foldl(fun
+ ({xmlelement, "item", ItemAttrs, _}, Acc) ->
+ case xml:get_attr_s("id", ItemAttrs) of
+ "" -> Acc;
+ ItemID -> ItemID
+ end;
+ (_, Acc) ->
+ Acc
+ end, [], xml:remove_cdata(Els)),
+ get_items(Host, Node, From, SubId, MaxItems, ItemIDs);
{get, "subscriptions"} ->
get_subscriptions(Host, From, Plugins);
{get, "affiliations"} ->
@@ -1436,7 +1447,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
Action = fun(#pubsub_node{options = Options, type = Type}) ->
Features = features(Type),
PublishFeature = lists:member("publish", Features),
- Model = get_option(Options, publish_model),
+ PublishModel = get_option(Options, publish_model),
MaxItems = max_items(Options),
PayloadSize = size(term_to_binary(Payload)),
PayloadMaxSize = get_option(Options, max_payload_size),
@@ -1459,7 +1470,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
%% % Publisher attempts to publish to transient notification node with item
%% {error, extended_error(?ERR_BAD_REQUEST, "item-forbidden")};
true ->
- node_call(Type, publish_item, [Host, Node, Publisher, Model, MaxItems, ItemId, Payload])
+ node_call(Type, publish_item, [Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload])
end
end,
%%ejabberd_hooks:run(pubsub_publish_item, Host, [Host, Node, JID, service_jid(Host), ItemId, Payload]),
@@ -1622,7 +1633,7 @@ purge_node(Host, Node, Owner) ->
%% The permission are not checked in this function.
%% @todo We probably need to check that the user doing the query has the right
%% to read the items.
-get_items(Host, Node, _JID, SMaxItems) ->
+get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) ->
MaxItems =
if
SMaxItems == "" -> ?MAXITEMS;
@@ -1636,24 +1647,60 @@ get_items(Host, Node, _JID, SMaxItems) ->
{error, Error} ->
{error, Error};
_ ->
- case get_items(Host, Node) of
- [] ->
- {error, ?ERR_ITEM_NOT_FOUND};
- Items ->
+ Action = fun(#pubsub_node{options = Options, type = Type}) ->
+ Features = features(Type),
+ RetreiveFeature = lists:member("retrieve-items", Features),
+ PersistentFeature = lists:member("persistent-items", Features),
+ AccessModel = get_option(Options, access_model),
+ AllowedGroups = get_option(Options, roster_groups_allowed),
+ {PresenceSubscription, RosterGroup} =
+ case Host of
+ {OUser, OServer, _} ->
+ get_roster_info(OUser, OServer,
+ jlib:jid_tolower(From), AllowedGroups);
+ _ ->
+ {true, true}
+ end,
+ if
+ not RetreiveFeature ->
+ %% Item Retrieval Not Supported
+ {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-items")};
+ not PersistentFeature ->
+ %% Persistent Items Not Supported
+ {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")};
+ true ->
+ node_call(Type, get_items,
+ [Host, Node, From,
+ AccessModel, PresenceSubscription, RosterGroup,
+ SubId])
+ end
+ end,
+ case transaction(Host, Node, Action, sync_dirty) of
+ {error, Reason} ->
+ {error, Reason};
+ {result, Items} ->
+ SendItems = case ItemIDs of
+ [] ->
+ Items;
+ _ ->
+ lists:filter(fun(Item) ->
+ lists:member(Item, ItemIDs)
+ end, Items)
+ end,
%% Generate the XML response (Item list), limiting the
%% number of items sent to MaxItems:
ItemsEls = lists:map(
- fun(#pubsub_item{itemid = {ItemId, _},
- payload = Payload}) ->
- ItemAttrs = case ItemId of
- "" -> [];
- _ -> [{"id", ItemId}]
- end,
- {xmlelement, "item", ItemAttrs, Payload}
- end, lists:sublist(Items, MaxItems)),
+ fun(#pubsub_item{itemid = {ItemId, _},
+ payload = Payload}) ->
+ ItemAttrs = case ItemId of
+ "" -> [];
+ _ -> [{"id", ItemId}]
+ end,
+ {xmlelement, "item", ItemAttrs, Payload}
+ end, lists:sublist(SendItems, MaxItems)),
{result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
- [{xmlelement, "items", [{"node", node_to_string(Node)}],
- ItemsEls}]}]}
+ [{xmlelement, "items", [{"node", node_to_string(Node)}],
+ ItemsEls}]}]}
end
end.
@@ -1809,7 +1856,7 @@ set_affiliations(Host, Node, From, EntitiesEls) ->
end, Entities),
{result, []};
_ ->
- {error, ?ERR_NOT_ALLOWED}
+ {error, ?ERR_FORBIDDEN}
end
end,
transaction(Host, Node, Action, sync_dirty)
@@ -1870,7 +1917,7 @@ get_subscriptions(Host, Node, JID) ->
%% Service does not support manage subscriptions
{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "manage-affiliations")};
Affiliation /= {result, owner} ->
- % Entity is not an owner
+ %% Entity is not an owner
{error, ?ERR_FORBIDDEN};
true ->
node_call(Type, get_node_subscriptions, [Host, Node])
@@ -1938,7 +1985,7 @@ set_subscriptions(Host, Node, From, EntitiesEls) ->
end, Entities),
{result, []};
_ ->
- {error, ?ERR_NOT_ALLOWED}
+ {error, ?ERR_FORBIDDEN}
end
end,
transaction(Host, Node, Action, sync_dirty)
@@ -2352,7 +2399,10 @@ get_configure(Host, Node, From, Lang) ->
transaction(Host, Node, Action, sync_dirty).
get_default(Host, _Node, _From, Lang) ->
- Type = hd(plugins(Host)), % first configured plugin is default
+ Type = case Host of
+ {_, _, _} -> ?PEPNODE;
+ _ -> hd(plugins(Host))
+ end,
Options = node_options(Type),
{result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}],
[{xmlelement, "default", [],
@@ -2435,6 +2485,7 @@ get_configure_xfields(_Type, Options, Lang, _Owners) ->
?BOOL_CONFIG_FIELD("Notify subscribers when the node is deleted", notify_delete),
?BOOL_CONFIG_FIELD("Notify subscribers when items are removed from the node", notify_retract),
?BOOL_CONFIG_FIELD("Persist items to storage", persist_items),
+ ?STRING_CONFIG_FIELD("A friendly name for the node", title),
?INTEGER_CONFIG_FIELD("Max # of items to persist", max_items),
?BOOL_CONFIG_FIELD("Whether to allow subscriptions", subscribe),
?ALIST_CONFIG_FIELD("Specify the access model", access_model,
@@ -2551,7 +2602,7 @@ set_xoption([], NewOpts) ->
NewOpts;
set_xoption([{"FORM_TYPE", _} | Opts], NewOpts) ->
set_xoption(Opts, NewOpts);
-set_xoption([{"pubsub#roster_groups_allowed", Value} | Opts], NewOpts) ->
+set_xoption([{"pubsub#roster_groups_allowed", _Value} | Opts], NewOpts) ->
?SET_LIST_XOPT(roster_groups_allowed, []); % XXX: waiting for EJAB-659 to be solved
set_xoption([{"pubsub#deliver_payloads", [Val]} | Opts], NewOpts) ->
?SET_BOOL_XOPT(deliver_payloads, Val);
@@ -2602,7 +2653,7 @@ features() ->
[
%"access-authorize", % OPTIONAL
"access-open", % OPTIONAL this relates to access_model option in node_default
- %"access-presence", % OPTIONAL
+ "access-presence", % OPTIONAL this relates to access_model option in node_pep
%"access-roster", % OPTIONAL
%"access-whitelist", % OPTIONAL
% see plugin "auto-create", % OPTIONAL
@@ -2616,7 +2667,7 @@ features() ->
% see plugin "filtered-notifications", % RECOMMENDED
%TODO "get-pending", % OPTIONAL
% see plugin "instant-nodes", % RECOMMENDED
- %TODO "item-ids", % RECOMMENDED
+ "item-ids", % RECOMMENDED
"last-published", % RECOMMENDED
%TODO "cache-last-item",
%TODO "leased-subscription", % OPTIONAL
diff --git a/src/mod_pubsub/node.template b/src/mod_pubsub/node.template
index 850a38ec9..973aa38a4 100644
--- a/src/mod_pubsub/node.template
+++ b/src/mod_pubsub/node.template
@@ -61,7 +61,9 @@
get_states/2,
get_state/3,
set_state/1,
+ get_items/7,
get_items/2,
+ get_item/8,
get_item/3,
set_item/1
]).
@@ -94,7 +96,6 @@ features() ->
["create-nodes",
"delete-nodes",
"instant-nodes",
- "item-ids",
"outcast-affiliation",
"persistent-items",
"publish",
@@ -170,8 +171,14 @@ set_state(State) ->
get_items(Host, Node) ->
node_default:get_items(Host, Node).
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId)
+ node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
get_item(Host, Node, ItemId) ->
node_default:get_item(Host, Node, ItemId).
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
set_item(Item) ->
node_default:set_item(Item).
diff --git a/src/mod_pubsub/node_buddy.erl b/src/mod_pubsub/node_buddy.erl
index cdf3a696f..cd051b66f 100644
--- a/src/mod_pubsub/node_buddy.erl
+++ b/src/mod_pubsub/node_buddy.erl
@@ -62,7 +62,9 @@
get_states/2,
get_state/3,
set_state/1,
+ get_items/7,
get_items/2,
+ get_item/8,
get_item/3,
set_item/1,
get_item_name/3
@@ -172,9 +174,15 @@ set_state(State) ->
get_items(Host, Node) ->
node_default:get_items(Host, Node).
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
get_item(Host, Node, ItemId) ->
node_default:get_item(Host, Node, ItemId).
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
set_item(Item) ->
node_default:set_item(Item).
diff --git a/src/mod_pubsub/node_club.erl b/src/mod_pubsub/node_club.erl
index d927053fb..155edc10a 100644
--- a/src/mod_pubsub/node_club.erl
+++ b/src/mod_pubsub/node_club.erl
@@ -62,7 +62,9 @@
get_states/2,
get_state/3,
set_state/1,
+ get_items/7,
get_items/2,
+ get_item/8,
get_item/3,
set_item/1,
get_item_name/3
@@ -96,7 +98,6 @@ features() ->
["create-nodes",
"delete-nodes",
"instant-nodes",
- "item-ids",
"outcast-affiliation",
"persistent-items",
"publish",
@@ -172,9 +173,15 @@ set_state(State) ->
get_items(Host, Node) ->
node_default:get_items(Host, Node).
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
get_item(Host, Node, ItemId) ->
node_default:get_item(Host, Node, ItemId).
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
set_item(Item) ->
node_default:set_item(Item).
diff --git a/src/mod_pubsub/node_default.erl b/src/mod_pubsub/node_default.erl
index fc4194c32..491676269 100644
--- a/src/mod_pubsub/node_default.erl
+++ b/src/mod_pubsub/node_default.erl
@@ -69,7 +69,9 @@
get_states/2,
get_state/3,
set_state/1,
+ get_items/7,
get_items/2,
+ get_item/8,
get_item/3,
set_item/1,
get_item_name/3
@@ -158,7 +160,6 @@ features() ->
"auto-create",
"delete-nodes",
"instant-nodes",
- "item-ids",
"manage-subscriptions",
"modify-affiliations",
"outcast-affiliation",
@@ -192,18 +193,14 @@ features() ->
%% module by implementing this function like this:
%% ```check_create_user_permission(Host, Node, Owner, Access) ->
%% node_default:check_create_user_permission(Host, Node, Owner, Access).'''
-create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
+create_node_permission(_Host, ServerHost, Node, _ParentNode, Owner, Access) ->
LOwner = jlib:jid_tolower(Owner),
{User, Server, _Resource} = LOwner,
Allowed = case acl:match_rule(ServerHost, Access, LOwner) of
allow ->
- if Server == Host -> %% Server == ServerHost ??
- true;
- true ->
- case Node of
- ["home", Server, User | _] -> true;
- _ -> false
- end
+ case Node of
+ ["home", Server, User | _] -> true;
+ _ -> false
end;
_ ->
case Owner of
@@ -211,8 +208,7 @@ create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
_ -> false
end
end,
- ChildOK = true, %% TODO test with ParentNode
- {result, Allowed and ChildOK}.
+ {result, Allowed}.
%% @spec (Host, Node, Owner) ->
%% {result, Result} | exit
@@ -297,12 +293,12 @@ subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
not Authorized ->
%% JIDs do not match
{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "invalid-jid")};
- Subscription == pending ->
- %% Requesting entity has pending subscription
- {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "pending-subscription")};
Affiliation == outcast ->
%% Requesting entity is blocked
{error, ?ERR_FORBIDDEN};
+ Subscription == pending ->
+ %% Requesting entity has pending subscription
+ {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "pending-subscription")};
(AccessModel == presence) and (not PresenceSubscription) ->
%% Entity is not authorized to create a subscription (presence subscription required)
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
@@ -446,6 +442,7 @@ publish_item(Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
{error, ?ERR_FORBIDDEN};
true ->
PubId = {PublisherKey, now()},
+ %% TODO: check creation, presence, roster (EJAB-663)
Item = case get_item(Host, Node, ItemId) of
{error, ?ERR_ITEM_NOT_FOUND} ->
#pubsub_item{itemid = {ItemId, {Host, Node}},
@@ -501,7 +498,7 @@ remove_extra_items(Host, Node, MaxItems, ItemIds) ->
%% ItemId = string()
%% @doc Triggers item deletion.
%% Default plugin: The user performing the deletion must be the node owner
-%% or a node publisher e item publisher.
+%% or a publisher.
delete_item(Host, Node, Publisher, ItemId) ->
PublisherKey = jlib:jid_tolower(jlib:jid_remove_resource(Publisher)),
State = case get_state(Host, Node, PublisherKey) of
@@ -542,17 +539,16 @@ delete_item(Host, Node, Publisher, ItemId) ->
purge_node(Host, Node, Owner) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
case get_state(Host, Node, OwnerKey) of
- {error, ?ERR_ITEM_NOT_FOUND} ->
- %% This should not append (case node does not exists)
- {error, ?ERR_ITEM_NOT_FOUND};
{result, #pubsub_state{items = Items, affiliation = owner}} ->
lists:foreach(fun(ItemId) ->
mnesia:delete({pubsub_item, {ItemId, {Host, Node}}})
end, Items),
{result, {default, broadcast}};
+ {result, _} ->
+ %% Entity is not owner
+ {error, ?ERR_FORBIDDEN};
_ ->
- %% Entity is not an owner
- {error, ?ERR_FORBIDDEN}
+ {error, ?ERR_ITEM_NOT_FOUND}
end.
%% @spec (Host, JID) -> [{Node,Affiliation}]
@@ -588,7 +584,7 @@ get_affiliation(Host, Node, Owner) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
Affiliation = case get_state(Host, Node, OwnerKey) of
{result, #pubsub_state{affiliation = A}} -> A;
- _ -> unknown
+ _ -> none
end,
{result, Affiliation}.
@@ -638,7 +634,7 @@ get_subscription(Host, Node, Owner) ->
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
Subscription = case get_state(Host, Node, OwnerKey) of
{result, #pubsub_state{subscription = S}} -> S;
- _ -> unknown
+ _ -> none
end,
{result, Subscription}.
@@ -713,6 +709,44 @@ get_items(Host, Node) ->
Items = mnesia:match_object(
#pubsub_item{itemid = {'_', {Host, Node}}, _ = '_'}),
{result, Items}.
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
+ {Affiliation, Subscription} =
+ case get_state(Host, Node, jlib:jid_tolower(jlib:jid_remove_resource(JID))) of
+ {result, #pubsub_state{affiliation = A, subscription = S}} -> {A, S};
+ _ -> {none, none}
+ end,
+ Subscribed = not ((Subscription == none) or (Subscription == pending)),
+ if
+ %%SubID == "", ?? ->
+ %% Entity has multiple subscriptions to the node but does not specify a subscription ID
+ %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")};
+ %%InvalidSubID ->
+ %% Entity is subscribed but specifies an invalid subscription ID
+ %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
+ Affiliation == outcast ->
+ %% Requesting entity is blocked
+ {error, ?ERR_FORBIDDEN};
+ (AccessModel == open) and (not Subscribed) ->
+ %% Entity is not subscribed
+ {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-subscribed")};
+ (AccessModel == presence) and (not PresenceSubscription) ->
+ %% Entity is not authorized to create a subscription (presence subscription required)
+ {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
+ (AccessModel == roster) and (not RosterGroup) ->
+ %% Entity is not authorized to create a subscription (not in roster group)
+ {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")};
+ (AccessModel == whitelist) -> % TODO: to be done
+ %% Node has whitelist access model
+ {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")};
+ (AccessModel == authorize) -> % TODO: to be done
+ %% Node has authorize access model
+ {error, ?ERR_FORBIDDEN};
+ %%MustPay ->
+ %% % Payment is required for a subscription
+ %% {error, ?ERR_PAYMENT_REQUIRED};
+ true ->
+ get_items(Host, Node)
+ end.
%% @spec (Host, Node, ItemId) -> [Item] | []
%% Host = mod_pubsub:host()
@@ -727,6 +761,44 @@ get_item(Host, Node, ItemId) ->
_ ->
{error, ?ERR_ITEM_NOT_FOUND}
end.
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
+ {Affiliation, Subscription} =
+ case get_state(Host, Node, jlib:jid_tolower(jlib:jid_remove_resource(JID))) of
+ {result, #pubsub_state{affiliation = A, subscription = S}} -> {A, S};
+ _ -> {none, none}
+ end,
+ Subscribed = not ((Subscription == none) or (Subscription == pending)),
+ if
+ %%SubID == "", ?? ->
+ %% Entity has multiple subscriptions to the node but does not specify a subscription ID
+ %{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")};
+ %%InvalidSubID ->
+ %% Entity is subscribed but specifies an invalid subscription ID
+ %{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
+ Affiliation == outcast ->
+ %% Requesting entity is blocked
+ {error, ?ERR_FORBIDDEN};
+ (AccessModel == open) and (not Subscribed) ->
+ %% Entity is not subscribed
+ {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-subscribed")};
+ (AccessModel == presence) and (not PresenceSubscription) ->
+ %% Entity is not authorized to create a subscription (presence subscription required)
+ {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
+ (AccessModel == roster) and (not RosterGroup) ->
+ %% Entity is not authorized to create a subscription (not in roster group)
+ {error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")};
+ (AccessModel == whitelist) -> % TODO: to be done
+ %% Node has whitelist access model
+ {error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")};
+ (AccessModel == authorize) -> % TODO: to be done
+ %% Node has authorize access model
+ {error, ?ERR_FORBIDDEN};
+ %%MustPay ->
+ %% % Payment is required for a subscription
+ %% {error, ?ERR_PAYMENT_REQUIRED};
+ true ->
+ get_item(Host, Node, ItemId)
+ end.
%% @spec (Item) -> ok | {error, Reason::stanzaError()}
%% Item = mod_pubsub:pubsubItems()
diff --git a/src/mod_pubsub/node_dispatch.erl b/src/mod_pubsub/node_dispatch.erl
index 3b4418c3e..0532826d2 100644
--- a/src/mod_pubsub/node_dispatch.erl
+++ b/src/mod_pubsub/node_dispatch.erl
@@ -60,7 +60,9 @@
get_states/2,
get_state/3,
set_state/1,
+ get_items/7,
get_items/2,
+ get_item/8,
get_item/3,
set_item/1,
get_item_name/3
@@ -94,7 +96,6 @@ features() ->
["create-nodes",
"delete-nodes",
"instant-nodes",
- "item-ids",
"outcast-affiliation",
"persistent-items",
"publish",
@@ -175,9 +176,15 @@ set_state(State) ->
get_items(Host, Node) ->
node_default:get_items(Host, Node).
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
get_item(Host, Node, ItemId) ->
node_default:get_item(Host, Node, ItemId).
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
set_item(Item) ->
node_default:set_item(Item).
diff --git a/src/mod_pubsub/node_pep.erl b/src/mod_pubsub/node_pep.erl
index 97bf1b2fa..2c648148d 100644
--- a/src/mod_pubsub/node_pep.erl
+++ b/src/mod_pubsub/node_pep.erl
@@ -29,6 +29,7 @@
-module(node_pep).
-author('christophe.romain@process-one.net').
+-include("ejabberd.hrl").
-include("pubsub.hrl").
-include("jlib.hrl").
@@ -57,7 +58,9 @@
get_states/2,
get_state/3,
set_state/1,
+ get_items/7,
get_items/2,
+ get_item/8,
get_item/3,
set_item/1,
get_item_name/3
@@ -65,6 +68,7 @@
init(Host, ServerHost, Opts) ->
node_default:init(Host, ServerHost, Opts),
+ complain_if_modcaps_disabled(ServerHost),
ok.
terminate(Host, ServerHost) ->
@@ -94,7 +98,6 @@ features() ->
"auto-subscribe", %*
"delete-nodes", %*
"filtered-notifications", %*
- "item-ids",
"modify-affiliations",
"outcast-affiliation",
"persistent-items",
@@ -183,7 +186,7 @@ get_node_subscriptions(_Host, _Node) ->
{result, []}.
get_subscription(_Host, _Node, _Owner) ->
- {result, unknown}.
+ {result, none}.
set_subscription(_Host, _Node, _Owner, _Subscription) ->
ok.
@@ -200,11 +203,39 @@ set_state(State) ->
get_items(Host, Node) ->
node_default:get_items(Host, Node).
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
get_item(Host, Node, ItemId) ->
node_default:get_item(Host, Node, ItemId).
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
set_item(Item) ->
node_default:set_item(Item).
get_item_name(Host, Node, Id) ->
node_default:get_item_name(Host, Node, Id).
+
+
+%%%
+%%% Internal
+%%%
+
+%% @doc Check mod_caps is enabled, otherwise show warning.
+%% The PEP plugin for mod_pubsub requires mod_caps to be enabled in the host.
+%% Check that the mod_caps module is enabled in that Jabber Host
+%% If not, show a warning message in the ejabberd log file.
+complain_if_modcaps_disabled(ServerHost) ->
+ Modules = ejabberd_config:get_local_option({modules, ServerHost}),
+ ModCaps = [mod_caps_enabled || {mod_caps, _Opts} <- Modules],
+ case ModCaps of
+ [] ->
+ ?WARNING_MSG("The PEP plugin is enabled in mod_pubsub of host ~p. "
+ "This plugin requires mod_caps to be enabled, "
+ "but it isn't.", [ServerHost]);
+ _ ->
+ ok
+ end.
+
diff --git a/src/mod_pubsub/node_private.erl b/src/mod_pubsub/node_private.erl
index 35f63c925..00e952392 100644
--- a/src/mod_pubsub/node_private.erl
+++ b/src/mod_pubsub/node_private.erl
@@ -62,7 +62,9 @@
get_states/2,
get_state/3,
set_state/1,
+ get_items/7,
get_items/2,
+ get_item/8,
get_item/3,
set_item/1,
get_item_name/3
@@ -96,7 +98,6 @@ features() ->
["create-nodes",
"delete-nodes",
"instant-nodes",
- "item-ids",
"outcast-affiliation",
"persistent-items",
"publish",
@@ -175,9 +176,15 @@ set_state(State) ->
get_items(Host, Node) ->
node_default:get_items(Host, Node).
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
get_item(Host, Node, ItemId) ->
node_default:get_item(Host, Node, ItemId).
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
set_item(Item) ->
node_default:set_item(Item).
diff --git a/src/mod_pubsub/node_public.erl b/src/mod_pubsub/node_public.erl
index 1586abe86..ab4107a76 100644
--- a/src/mod_pubsub/node_public.erl
+++ b/src/mod_pubsub/node_public.erl
@@ -62,7 +62,9 @@
get_states/2,
get_state/3,
set_state/1,
+ get_items/7,
get_items/2,
+ get_item/8,
get_item/3,
set_item/1,
get_item_name/3
@@ -96,7 +98,6 @@ features() ->
["create-nodes",
"delete-nodes",
"instant-nodes",
- "item-ids",
"outcast-affiliation",
"persistent-items",
"publish",
@@ -172,9 +173,15 @@ set_state(State) ->
get_items(Host, Node) ->
node_default:get_items(Host, Node).
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
get_item(Host, Node, ItemId) ->
node_default:get_item(Host, Node, ItemId).
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
set_item(Item) ->
node_default:set_item(Item).
diff --git a/src/mod_pubsub/node_zoo.erl b/src/mod_pubsub/node_zoo.erl
new file mode 100644
index 000000000..45e601ed7
--- /dev/null
+++ b/src/mod_pubsub/node_zoo.erl
@@ -0,0 +1,181 @@
+%%% ====================================================================
+%%% ``The contents of this file are subject to the Erlang Public License,
+%%% Version 1.1, (the "License"); you may not use this file except in
+%%% compliance with the License. You should have received a copy of the
+%%% Erlang Public License along with this software. If not, it can be
+%%% retrieved via the world wide web at http://www.erlang.org/.
+%%%
+%%% Software distributed under the License is distributed on an "AS IS"
+%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%%% the License for the specific language governing rights and limitations
+%%% under the License.
+%%%
+%%% The Initial Developer of the Original Code is Process-one.
+%%% Portions created by Process-one are Copyright 2006-2008, Process-one
+%%% All Rights Reserved.''
+%%% This software is copyright 2006-2008, Process-one.
+%%%
+%%% @copyright 2006-2008 Process-one
+%%% @author Christophe romain
+%%% [http://www.process-one.net/]
+%%% @version {@vsn}, {@date} {@time}
+%%% @end
+%%% ====================================================================
+
+-module(node_zoo).
+-author('christophe.romain@process-one.net').
+
+-include("pubsub.hrl").
+-include("jlib.hrl").
+
+-behaviour(gen_pubsub_node).
+
+%% API definition
+-export([init/3, terminate/2,
+ options/0, features/0,
+ create_node_permission/6,
+ create_node/3,
+ delete_node/2,
+ purge_node/3,
+ subscribe_node/8,
+ unsubscribe_node/5,
+ publish_item/7,
+ delete_item/4,
+ remove_extra_items/4,
+ get_entity_affiliations/2,
+ get_node_affiliations/2,
+ get_affiliation/3,
+ set_affiliation/4,
+ get_entity_subscriptions/2,
+ get_node_subscriptions/2,
+ get_subscription/3,
+ set_subscription/4,
+ get_states/2,
+ get_state/3,
+ set_state/1,
+ get_items/7,
+ get_items/2,
+ get_item/8,
+ get_item/3,
+ set_item/1,
+ get_item_name/3
+ ]).
+
+
+init(Host, ServerHost, Opts) ->
+ node_default:init(Host, ServerHost, Opts).
+
+terminate(Host, ServerHost) ->
+ node_default:terminate(Host, ServerHost).
+
+options() ->
+ [{node_type, zoo},
+ {deliver_payloads, true},
+ {notify_config, false},
+ {notify_delete, false},
+ {notify_retract, true},
+ {persist_items, true},
+ {max_items, ?MAXITEMS div 2},
+ {subscribe, true},
+ {access_model, open},
+ {roster_groups_allowed, []},
+ {publish_model, publishers},
+ {max_payload_size, ?MAX_PAYLOAD_SIZE},
+ {send_last_published_item, never},
+ {deliver_notifications, true},
+ {presence_based_delivery, false}].
+
+features() ->
+ node_default:features().
+
+%% use same code as node_default, but do not limite node to
+%% the home/localhost/user/... hierarchy
+%% any node is allowed
+create_node_permission(_Host, ServerHost, _Node, _ParentNode, Owner, Access) ->
+ LOwner = jlib:jid_tolower(Owner),
+ %%{_User, _Server, _Resource} = LOwner,
+ Allowed = case acl:match_rule(ServerHost, Access, LOwner) of
+ allow ->
+ true;
+ _ ->
+ case Owner of
+ {jid, "", _, "", "", _, ""} -> true;
+ _ -> false
+ end
+ end,
+ {result, Allowed}.
+
+create_node(Host, Node, Owner) ->
+ node_default:create_node(Host, Node, Owner).
+
+delete_node(Host, Removed) ->
+ node_default:delete_node(Host, Removed).
+
+subscribe_node(Host, Node, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup) ->
+ node_default:subscribe_node(Host, Node, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup).
+
+unsubscribe_node(Host, Node, Sender, Subscriber, SubID) ->
+ node_default:unsubscribe_node(Host, Node, Sender, Subscriber, SubID).
+
+publish_item(Host, Node, Publisher, Model, MaxItems, ItemId, Payload) ->
+ node_default:publish_item(Host, Node, Publisher, Model, MaxItems, ItemId, Payload).
+
+remove_extra_items(Host, Node, MaxItems, ItemIds) ->
+ node_default:remove_extra_items(Host, Node, MaxItems, ItemIds).
+
+delete_item(Host, Node, JID, ItemId) ->
+ node_default:delete_item(Host, Node, JID, ItemId).
+
+purge_node(Host, Node, Owner) ->
+ node_default:purge_node(Host, Node, Owner).
+
+get_entity_affiliations(Host, Owner) ->
+ node_default:get_entity_affiliations(Host, Owner).
+
+get_node_affiliations(Host, Node) ->
+ node_default:get_node_affiliations(Host, Node).
+
+get_affiliation(Host, Node, Owner) ->
+ node_default:get_affiliation(Host, Node, Owner).
+
+set_affiliation(Host, Node, Owner, Affiliation) ->
+ node_default:set_affiliation(Host, Node, Owner, Affiliation).
+
+get_entity_subscriptions(Host, Owner) ->
+ node_default:get_entity_subscriptions(Host, Owner).
+
+get_node_subscriptions(Host, Node) ->
+ node_default:get_node_subscriptions(Host, Node).
+
+get_subscription(Host, Node, Owner) ->
+ node_default:get_subscription(Host, Node, Owner).
+
+set_subscription(Host, Node, Owner, Subscription) ->
+ node_default:set_subscription(Host, Node, Owner, Subscription).
+
+get_states(Host, Node) ->
+ node_default:get_states(Host, Node).
+
+get_state(Host, Node, JID) ->
+ node_default:get_state(Host, Node, JID).
+
+set_state(State) ->
+ node_default:set_state(State).
+
+get_items(Host, Node) ->
+ node_default:get_items(Host, Node).
+
+get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
+get_item(Host, Node, ItemId) ->
+ node_default:get_item(Host, Node, ItemId).
+
+get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
+ node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
+
+set_item(Item) ->
+ node_default:set_item(Item).
+
+get_item_name(Host, Node, Id) ->
+ node_default:get_item_name(Host, Node, Id).
diff --git a/src/mod_register.erl b/src/mod_register.erl
index a936ea5e1..21080c8a2 100644
--- a/src/mod_register.erl
+++ b/src/mod_register.erl
@@ -241,12 +241,13 @@ send_welcome_message(JID) ->
{"", ""} ->
ok;
{Subj, Body} ->
+ BodyFormatted = io_lib:format(Body, []),
ejabberd_router:route(
jlib:make_jid("", Host, ""),
JID,
{xmlelement, "message", [{"type", "normal"}],
[{xmlelement, "subject", [], [{xmlcdata, Subj}]},
- {xmlelement, "body", [], [{xmlcdata, Body}]}]});
+ {xmlelement, "body", [], [{xmlcdata, BodyFormatted}]}]});
_ ->
ok
end.
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index f1f59665a..038de586a 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -40,6 +40,7 @@
set_items/3,
remove_user/2,
get_jid_info/4,
+ item_to_xml/1,
webadmin_page/3,
webadmin_user/4]).
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index 7b8558cf5..ff378010d 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -155,12 +155,12 @@ get_user_roster(Items, US) ->
{{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)],
SRItems ++ NewItems1.
-%% This function in use to rewrite the roster entries when moving or renaming
+%% This function rewrites the roster entries when moving or renaming
%% them in the user contact list.
process_item(RosterItem, Host) ->
- USFrom = RosterItem#roster.us,
- {User,Server,_Resource} = RosterItem#roster.jid,
- USTo = {User,Server},
+ USFrom = {UserFrom, ServerFrom} = RosterItem#roster.us,
+ {UserTo, ServerTo, ResourceTo} = RosterItem#roster.jid,
+ USTo = {UserTo, ServerTo},
DisplayedGroups = get_user_displayed_groups(USFrom),
CommonGroups = lists:filter(fun(Group) ->
is_user_in_group(USTo, Group, Host)
@@ -174,9 +174,83 @@ process_item(RosterItem, Host) ->
end, CommonGroups),
RosterItem#roster{subscription = both, ask = none,
groups=[GroupNames]};
- _ -> RosterItem#roster{subscription = both, ask = none}
+ %% Both users have at least a common shared group,
+ %% So each user can see the other
+ _ ->
+ %% Check if the list of groups of the new roster item
+ %% include at least a new one
+ case lists:subtract(RosterItem#roster.groups, CommonGroups) of
+ [] ->
+ RosterItem#roster{subscription = both, ask = none};
+ %% If so, it means the user wants to add that contact
+ %% to his personal roster
+ PersonalGroups ->
+ %% Store roster items in From and To rosters
+ set_new_rosteritems(UserFrom, ServerFrom,
+ UserTo, ServerTo, ResourceTo,
+ PersonalGroups)
+ end
end.
+build_roster_record(User1, Server1, User2, Server2, Groups) ->
+ USR2 = {User2, Server2, ""},
+ #roster{usj = {User1, Server1, USR2},
+ us = {User1, Server1},
+ jid = USR2,
+ name = User2,
+ subscription = both,
+ ask = none,
+ groups = Groups
+ }.
+
+set_new_rosteritems(UserFrom, ServerFrom,
+ UserTo, ServerTo, ResourceTo, GroupsFrom) ->
+ Mod = case lists:member(mod_roster_odbc,
+ gen_mod:loaded_modules(ServerFrom)) of
+ true -> mod_roster_odbc;
+ false -> mod_roster
+ end,
+
+ RIFrom = build_roster_record(UserFrom, ServerFrom,
+ UserTo, ServerTo, GroupsFrom),
+ set_item(UserFrom, ServerFrom, ResourceTo, RIFrom),
+ JIDTo = jlib:make_jid(UserTo, ServerTo, ""),
+
+ JIDFrom = jlib:make_jid(UserFrom, ServerFrom, ""),
+ RITo = build_roster_record(UserTo, ServerTo,
+ UserFrom, ServerFrom, []),
+ set_item(UserTo, ServerTo, "", RITo),
+
+ %% From requests
+ Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribe),
+ Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribe, ""),
+
+ %% To accepts
+ Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribed),
+ Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribed, ""),
+
+ %% To requests
+ Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribe),
+ Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribe, ""),
+
+ %% From accepts
+ Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribed),
+ Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribed, ""),
+
+ RIFrom.
+
+set_item(User, Server, Resource, Item) ->
+ ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
+ id = "push",
+ sub_el = [{xmlelement, "query",
+ [{"xmlns", ?NS_ROSTER}],
+ [mod_roster:item_to_xml(Item)]}]},
+ ejabberd_router:route(
+ jlib:make_jid(User, Server, Resource),
+ jlib:make_jid("", Server, ""),
+ jlib:iq_to_xml(ResIQ)).
+
+
get_subscription_lists({F, T}, User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
@@ -414,10 +488,10 @@ get_user_displayed_groups(US) ->
end, get_user_groups(US))),
[Group || Group <- DisplayedGroups1, is_group_enabled(Host, Group)].
-is_user_in_group(US, Group, Host) ->
+is_user_in_group({_U, S} = US, Group, Host) ->
case catch mnesia:dirty_match_object(
#sr_user{us=US, group_host={Group, Host}}) of
- [] -> false;
+ [] -> lists:member(US, get_group_users(S, Group));
_ -> true
end.
diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl
index a53910803..34eeef739 100644
--- a/src/web/ejabberd_http.erl
+++ b/src/web/ejabberd_http.erl
@@ -271,13 +271,14 @@ process(Handlers, Request) ->
process(HandlersLeft, Request)
end.
-process_request(#state{request_method = 'GET',
+process_request(#state{request_method = Method,
request_path = {abs_path, Path},
request_auth = Auth,
request_lang = Lang,
request_handlers = RequestHandlers,
sockmod = SockMod,
- socket = Socket} = State) ->
+ socket = Socket} = State)
+ when Method=:='GET' orelse Method=:='HEAD' orelse Method=:='DELETE' ->
case (catch url_decode_q_split(Path)) of
{'EXIT', _} ->
process_request(false);
@@ -289,19 +290,19 @@ process_request(#state{request_method = 'GET',
LQ
end,
LPath = string:tokens(NPath, "/"),
- {ok, {IP, _Port}} =
+ {ok, IP} =
case SockMod of
gen_tcp ->
inet:peername(Socket);
_ ->
SockMod:peername(Socket)
end,
- Request = #request{method = 'GET',
+ Request = #request{method = Method,
path = LPath,
q = LQuery,
auth = Auth,
lang = Lang,
- ip=IP},
+ ip = IP},
%% XXX bard: This previously passed control to
%% ejabberd_web:process_get, now passes it to a local
%% procedure (process) that handles dispatching based on
@@ -319,7 +320,7 @@ process_request(#state{request_method = 'GET',
end
end;
-process_request(#state{request_method = 'POST',
+process_request(#state{request_method = Method,
request_path = {abs_path, Path},
request_auth = Auth,
request_content_length = Len,
@@ -327,7 +328,7 @@ process_request(#state{request_method = 'POST',
sockmod = SockMod,
socket = Socket,
request_handlers = RequestHandlers} = State)
- when is_integer(Len) ->
+ when (Method=:='POST' orelse Method=:='PUT') andalso is_integer(Len) ->
case SockMod of
gen_tcp ->
inet:setopts(Socket, [{packet, 0}]);
@@ -347,12 +348,20 @@ process_request(#state{request_method = 'POST',
LQ ->
LQ
end,
- Request = #request{method = 'POST',
+ {ok, IP} =
+ case SockMod of
+ gen_tcp ->
+ inet:peername(Socket);
+ _ ->
+ SockMod:peername(Socket)
+ end,
+ Request = #request{method = Method,
path = LPath,
q = LQuery,
auth = Auth,
data = Data,
- lang = Lang},
+ lang = Lang,
+ ip = IP},
case process(RequestHandlers, Request) of
El when element(1, El) == xmlelement ->
make_xhtml_output(State, 200, [], El);
diff --git a/src/web/ejabberd_http_poll.erl b/src/web/ejabberd_http_poll.erl
index f5b419275..ad6c46b77 100644
--- a/src/web/ejabberd_http_poll.erl
+++ b/src/web/ejabberd_http_poll.erl
@@ -50,13 +50,16 @@
-record(http_poll, {id, pid}).
+-define(NULL_PEER, {{0, 0, 0, 0}, 0}).
+
-record(state, {id,
key,
output = "",
input = "",
waiting_input = false, %% {ReceiverPid, Tag}
last_receiver,
- timer}).
+ timer,
+ ip = ?NULL_PEER }).
%-define(DBGFSM, true).
@@ -94,11 +97,16 @@ setopts({http_poll, FsmRef}, Opts) ->
ok
end.
-sockname(_Socket) ->
- {ok, {{0, 0, 0, 0}, 0}}.
+sockname(_) ->
+ {ok, ?NULL_PEER}.
-peername(_Socket) ->
- {ok, {{0, 0, 0, 0}, 0}}.
+peername({http_poll, FsmRef}) ->
+ case catch gen_fsm:sync_send_all_state_event(FsmRef, peername, 1000) of
+ {ok, IP} -> {ok, IP};
+ _ -> {ok, ?NULL_PEER}
+ end;
+peername(_) ->
+ {ok, ?NULL_PEER}.
controlling_process(_Socket, _Pid) ->
ok.
@@ -107,7 +115,7 @@ close({http_poll, FsmRef}) ->
catch gen_fsm:sync_send_all_state_event(FsmRef, close).
-process([], #request{data = Data} = _Request) ->
+process([], #request{data = Data, ip = IP} = _Request) ->
case catch parse_request(Data) of
{ok, ID1, Key, NewKey, Packet} ->
ID = if
@@ -123,7 +131,7 @@ process([], #request{data = Data} = _Request) ->
true ->
ID1
end,
- case http_put(ID, Key, NewKey, Packet) of
+ case http_put(ID, Key, NewKey, Packet, IP) of
{error, not_exists} ->
{200, ?BAD_REQUEST, ""};
{error, bad_key} ->
@@ -249,7 +257,7 @@ handle_sync_event(stop, _From, _StateName, StateData) ->
Reply = ok,
{stop, normal, Reply, StateData};
-handle_sync_event({http_put, Key, NewKey, Packet},
+handle_sync_event({http_put, Key, NewKey, Packet, IP},
_From, StateName, StateData) ->
Allow = case StateData#state.key of
"" ->
@@ -271,7 +279,8 @@ handle_sync_event({http_put, Key, NewKey, Packet},
Input = [StateData#state.input|Packet],
Reply = ok,
{reply, Reply, StateName, StateData#state{input = Input,
- key = NewKey}};
+ key = NewKey,
+ ip = IP}};
{Receiver, _Tag} ->
Receiver ! {tcp, {http_poll, self()},
list_to_binary(Packet)},
@@ -282,7 +291,8 @@ handle_sync_event({http_put, Key, NewKey, Packet},
StateData#state{waiting_input = false,
last_receiver = Receiver,
key = NewKey,
- timer = Timer}}
+ timer = Timer,
+ ip = IP}}
end;
true ->
Reply = {error, bad_key},
@@ -293,6 +303,10 @@ handle_sync_event(http_get, _From, StateName, StateData) ->
Reply = {ok, StateData#state.output},
{reply, Reply, StateName, StateData#state{output = ""}};
+handle_sync_event(peername, _From, StateName, StateData) ->
+ Reply = {ok, StateData#state.ip},
+ {reply, Reply, StateName, StateData};
+
handle_sync_event(_Event, _From, StateName, StateData) ->
Reply = ok,
{reply, Reply, StateName, StateData}.
@@ -343,13 +357,13 @@ terminate(_Reason, _StateName, StateData) ->
%%% Internal functions
%%%----------------------------------------------------------------------
-http_put(ID, Key, NewKey, Packet) ->
+http_put(ID, Key, NewKey, Packet, IP) ->
case mnesia:dirty_read({http_poll, ID}) of
[] ->
{error, not_exists};
[#http_poll{pid = FsmRef}] ->
gen_fsm:sync_send_all_state_event(
- FsmRef, {http_put, Key, NewKey, Packet})
+ FsmRef, {http_put, Key, NewKey, Packet, IP})
end.
http_get(ID) ->
diff --git a/src/web/ejabberd_web_admin.erl b/src/web/ejabberd_web_admin.erl
index abc1ac871..d133fa14d 100644
--- a/src/web/ejabberd_web_admin.erl
+++ b/src/web/ejabberd_web_admin.erl
@@ -2022,7 +2022,7 @@ node_backup_parse_query(Node, Query) ->
rpc:call(Node, mnesia,
install_fallback, [Path]);
"dump" ->
- rpc:call(Node, mnesia,
+ rpc:call(Node, ejabberd_ctl,
dump_to_textfile, [Path]);
"load" ->
rpc:call(Node, mnesia,
diff --git a/tools/ejabberdctl b/tools/ejabberdctl
index 9d3f7bd5a..c821e8081 100755
--- a/tools/ejabberdctl
+++ b/tools/ejabberdctl
@@ -4,7 +4,8 @@ NODE=ejabberd
HOST=localhost
# Define ejabberd environment
-base="`dirname $(which "$0")`/.."
+here=`which "$0" 2>/dev/null || echo .`
+base="`dirname $here`/.."
ROOTDIR=`(cd "$base"; echo $PWD)`
SASL_LOG_PATH=$ROOTDIR/sasl.log
EJABBERD_DB=$ROOTDIR/database/$NODE
From 574dbbfd08378de06e47763956e8b3dff5dce47f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 15 Jul 2008 08:45:05 +0000
Subject: [PATCH 042/582] Merge revisions from 1434 to revision 1444 from
trunk.
SVN Revision: 1445
---
ChangeLog | 63 +++++++
doc/Makefile | 2 +-
doc/guide.html | 63 ++++---
doc/guide.tex | 64 ++++---
{src => include}/adhoc.hrl | 0
{src => include}/ejabberd.hrl | 0
{src => include}/ejabberd_config.hrl | 0
{src => include}/ejabberd_ctl.hrl | 0
{src/web => include}/ejabberd_http.hrl | 0
{src/web => include}/ejabberd_web_admin.hrl | 0
{src/eldap => include}/eldap.hrl | 0
{src => include}/jlib.hrl | 0
{src => include}/mod_privacy.hrl | 0
{src/mod_proxy65 => include}/mod_proxy65.hrl | 0
{src => include}/mod_roster.hrl | 0
{src/mod_pubsub => include}/pubsub.hrl | 0
src/Makefile.in | 171 +++++++++++++++----
src/aclocal.m4 | 15 +-
src/configure | 150 +++++++++++-----
src/configure.ac | 26 ++-
src/ejabberd.cfg.example | 2 +-
src/ejabberd_auth_ldap.erl | 2 +-
src/ejabberd_zlib/Makefile.in | 3 +-
src/ejabberdctl.template | 98 ++++++-----
src/eldap/Makefile.in | 3 +-
src/mod_irc/Makefile.in | 4 +-
src/mod_muc/Makefile.in | 4 +-
src/mod_offline.erl | 4 +-
src/mod_offline_odbc.erl | 4 +-
src/mod_proxy65/Makefile.in | 4 +-
src/mod_proxy65/mod_proxy65_service.erl | 4 +-
src/mod_proxy65/mod_proxy65_stream.erl | 2 +-
src/mod_pubsub/Makefile.in | 4 +-
src/mod_register.erl | 3 +-
src/mod_roster.erl | 4 +-
src/mod_roster_odbc.erl | 4 +-
src/mod_shared_roster.erl | 4 +-
src/mod_vcard_ldap.erl | 2 +-
src/odbc/Makefile.in | 4 +-
src/pam/Makefile.in | 4 +-
src/tls/Makefile.in | 4 +-
src/web/Makefile.in | 6 +-
42 files changed, 525 insertions(+), 202 deletions(-)
rename {src => include}/adhoc.hrl (100%)
rename {src => include}/ejabberd.hrl (100%)
rename {src => include}/ejabberd_config.hrl (100%)
rename {src => include}/ejabberd_ctl.hrl (100%)
rename {src/web => include}/ejabberd_http.hrl (100%)
rename {src/web => include}/ejabberd_web_admin.hrl (100%)
rename {src/eldap => include}/eldap.hrl (100%)
rename {src => include}/jlib.hrl (100%)
rename {src => include}/mod_privacy.hrl (100%)
rename {src/mod_proxy65 => include}/mod_proxy65.hrl (100%)
rename {src => include}/mod_roster.hrl (100%)
rename {src/mod_pubsub => include}/pubsub.hrl (100%)
diff --git a/ChangeLog b/ChangeLog
index 72fe05cb9..ae52d1fa1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,66 @@
+2008-07-15 Jean-Sébastien Pédron
+
+ Merge revisions from 1434 to revision 1444 from trunk.
+
+ * configure: Recreated with autoconf(1) after merge.
+
+2008-07-14 Badlop
+
+ * doc/guide.tex: Update what permissions does enable-user grant
+ * doc/guide.html: Likewise
+
+ * src/configure.ac: Don't explicitely put root privileges when a
+ user is not explicitely enabled
+ * src/configure: Likewise
+ * src/Makefile.in: Likewise
+
+ * src/Makefile.in: Fix docdir so it recognizes prefix. If sbin dir
+ does not exist, create it. Fix cookiefile permission
+ check. (EJAB-696)
+
+2008-07-13 Badlop
+
+ * src/configure.ac: Update installation permissions (EJAB-402)
+ * src/configure: Likewise
+
+ * src/Makefile.in: The mnesia, ebin and priv dirs are now
+ installed in different locations. Install header files and
+ documentation (EJAB-696)
+ * doc/guide.tex: Likewise
+ * doc/guide.html: Likewise
+
+ * include/*.hrl: Place for all ejabberd header files (EJAB-696)
+ * src/*/*.erl: Update references to header files
+ * src/*/Makefile.in: Include the include/ dir
+
+ * src/configure.ac: Allow to execute ejabberd with a normal
+ system user (thanks to Viq)(EJAB-402)
+ * src/configure: Likewise
+ * src/ejabberdctl.template: Likewise
+ * src/Makefile.in: Likewise
+ * doc/guide.tex: Likewise
+ * doc/guide.html: Likewise
+
+2008-07-12 Badlop
+
+ * src/configure.ac: Improve legibility
+ * src/aclocal.m4: Likewise
+ * src/configure: Likewise
+
+ * src/ejabberdctl.template: Remove garbage variable. Document node
+ option
+
+ * doc/guide.tex: Add references to sections.
+ * doc/guide.html: Likewise
+
+2008-07-11 Badlop
+
+ * src/mod_register.erl: Revert support for io_lib newline, since
+ there is a standard character that representes newline (EJAB-501)
+ * doc/guide.tex: Update documentation to explain newline character
+ * doc/guide.html: Likewise
+ * src/ejabberd.cfg.example: Likewise
+
2008-07-11 Jean-Sébastien Pédron
Merge revisions from 1362 to revision 1434 from trunk.
diff --git a/doc/Makefile b/doc/Makefile
index c1f35fdff..2fda395a0 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -16,7 +16,7 @@ all: release pdf html
release:
@echo "Notes for the releaser:"
@echo "* Do not forget to add a link to the release notes in guide.tex"
- @echo "* Do not forget to update the version number in src/ejabberd.hrl!"
+ @echo "* Do not forget to update the version number in src/ejabberd.app!"
@echo "* Do not forget to update the features in introduction.tex (including \new{} and \improved{} tags)."
@echo "Press any key to continue"
@read foo
diff --git a/doc/guide.html b/doc/guide.html
index b7f10839b..735fc1f8c 100644
--- a/doc/guide.html
+++ b/doc/guide.html
@@ -333,14 +333,24 @@ Alternatively, the latest development version can be retrieved from the Subversi
To compile ejabberd execute the commands:
./configure
make
-
The build configuration script provides several parameters.
+
The build configuration script allows several options.
To get the full list run the command:
./configure --help
Some options that you may be interested in modifying:
-
--prefix=/
-
- Specify the path prefix where the files will be copied when running the make install command.
- --enable-pam
-
- Enable the PAM authentication method.
- --enable-odbc or --enable-mssql
-
+ Specify the path prefix where the files will be copied when running
+ the make install command.
- --enable-user[=USER]
-
+ Allow this normal system user to execute the ejabberdctl script
+ (see section 4.1),
+ read the configuration files,
+ read and write in the spool directory,
+ read and write in the log directory.
+ The account user and group must exist in the machine
+ before running make install.
+ This account doesn’t need an explicit HOME directory, because
+ /var/lib/ejabberd/ will be used by default.
- --enable-pam
-
+ Enable the PAM authentication method (see section 3.1.4).
- --enable-odbc or --enable-mssql
-
Required if you want to use an external database.
See section 3.2 for more information.
- --enable-full-xml
-
Enable the use of XML based optimisations.
@@ -351,34 +361,43 @@ To get the full list run the command:
To install ejabberd in the destination directories, run the command:
make install
-
Note that you may need to have administrative privileges in the system.
The files and directories created are, by default:
+
Note that you probably need administrative privileges in the system
+to install ejabberd.
The files and directories created are, by default:
-
- /etc/ejabberd/
- Configuration files:
+ /etc/ejabberd/
- Configuration directory:
-
ejabberd.cfg
- ejabberd configuration file
- ejabberdctl.cfg
- Configuration file of the administration script
-
- inetrc
- Network DNS configuration
+
- inetrc
- Network DNS configuration file
- - /sbin/ejabberdctl
- Administration script
-
- /var/lib/ejabberd/
-
+
- /lib/ejabberd/
-
-
- .erlang.cookie
- Erlang cookie file (see section 5.3)
-
- db
- Mnesia database spool files
-
- ebin
- Binary Erlang files (*.beam)
-
- priv
-
+ ebin/
- Erlang binary files (*.beam)
+
- include/
- Erlang header files (*.hrl)
+
- priv/
- Additional files required at runtime
-
- lib
- Binary system libraries (*.so)
-
- msgs
- Translated strings (*.msgs)
+ bin/
- Binary C programs
+
- lib/
- Binary system libraries (*.so)
+
- msgs/
- Translation files (*.msgs)
- - /var/log/ejabberd/
- Log files (see section 7.2):
+
- /sbin/ejabberdctl
- Administration script (see section 4.1)
+
- /share/doc/ejabberd/
- Documentation of ejabberd
+
- /var/lib/ejabberd/
- Spool directory:
+
-
+ .erlang.cookie
- Erlang cookie file (see section 5.3)
+
- acl.DCD, ...
- Mnesia database spool files (*.DCD, *.DCL, *.DAT)
+
+ - /var/log/ejabberd/
- Log directory (see section 7.2):
-
ejabberd.log
- ejabberd service log
- sasl.log
- Erlang/OTP system log
-
You can use the ejabberdctl command line administration script to start and stop ejabberd.
Usage example:
+
You can use the ejabberdctl command line administration script to start and stop ejabberd.
+If you provided the configure option --enable-user=USER (see 2.4.3),
+you can execute ejabberdctl with either that system account or root.
Usage example:
ejabberdctl start
ejabberdctl status
@@ -939,7 +958,7 @@ for more information.
Though it is quite easy to set up PAM support in ejabberd, PAM itself introduces some
security issues:
-
To perform PAM authentication ejabberd uses external C-program called
-epam. By default, it is located in
/var/lib/ejabberd/priv/lib/
+epam. By default, it is located in /var/lib/ejabberd/priv/bin/
directory. You have to set it root on execution in the case when your PAM module
requires root privileges (pam_unix.so for example). Also you have to grant access
for ejabberd to this file and remove all other permissions from it.
@@ -2363,7 +2382,7 @@ restrictions by default).
- welcome_message
- Set a welcome message that
is sent to each newly registered account. The first string is the subject, and
the second string is the message body.
-In the body you can set a newline with the characters: ~n.
+In the body you can set a newline with the characters:
\n
- registration_watchers
- This option defines a
list of JIDs which will be notified each time a new account is registered.
- iqdisc
- This specifies
@@ -2414,7 +2433,7 @@ Also define a registration timeout of one hour:
...
{mod_register,
[
- {welcome_message, {"Welcome!", "Hi.~nWelcome to this Jabber server.~n Check http://www.jabber.org~n~nBye"}},
+ {welcome_message, {"Welcome!", "Hi.\nWelcome to this Jabber server.\n Check http://www.jabber.org\n\nBye"}},
{registration_watchers, ["admin1@example.org", "boss@example.net"]}
]},
...
@@ -2895,7 +2914,7 @@ Starts the Erlang system detached from the system console.
Specify the directory where Erlang binary files (*.beam) are located.
- -s ejabberd
-
Tell Erlang runtime system to start the ejabberd application.
-
- -mnesia dir "/var/lib/ejabberd/db/nodename"
-
+
- -mnesia dir "/var/lib/ejabberd/"
-
Specify the Mnesia database directory.
- -sasl sasl_error_logger {file, "/var/log/ejabberd/sasl.log"}
-
Path to the Erlang/OTP system log file.
@@ -3065,10 +3084,10 @@ Contains IP addresses of clients.
If the loglevel is set to 5, it contains whole conversations and passwords.
If a logrotate system is used, there may be several log files with similar information,
so it is preferable to secure the whole /var/log/ejabberd/ directory.
-
- Mnesia database spool files: /var/lib/ejabberd/db/*
-
+
- Mnesia database spool files in /var/lib/ejabberd/
-
The files store binary data, but some parts are still readable.
The files are generated by Mnesia and their permissions cannot be set directly,
-so it is preferable to secure the whole /var/lib/ejabberd/db/ directory.
+so it is preferable to secure the whole /var/lib/ejabberd/ directory.
- Erlang cookie file: /var/lib/ejabberd/.erlang.cookie
-
See section 5.3.
diff --git a/doc/guide.tex b/doc/guide.tex
index 5a23a359a..3831ac024 100644
--- a/doc/guide.tex
+++ b/doc/guide.tex
@@ -313,7 +313,7 @@ To compile \ejabberd{} execute the commands:
make
\end{verbatim}
-The build configuration script provides several parameters.
+The build configuration script allows several options.
To get the full list run the command:
\begin{verbatim}
./configure --help
@@ -322,10 +322,22 @@ To get the full list run the command:
Some options that you may be interested in modifying:
\begin{description}
\titem{--prefix=/}
- Specify the path prefix where the files will be copied when running the make install command.
+ Specify the path prefix where the files will be copied when running
+ the \term{make install} command.
+
+ \titem{--enable-user[=USER]}
+ Allow this normal system user to execute the ejabberdctl script
+ (see section~\ref{ejabberdctl}),
+ read the configuration files,
+ read and write in the spool directory,
+ read and write in the log directory.
+ The account user and group must exist in the machine
+ before running \term{make install}.
+ This account doesn't need an explicit HOME directory, because
+ \term{/var/lib/ejabberd/} will be used by default.
\titem{--enable-pam}
- Enable the PAM authentication method.
+ Enable the PAM authentication method (see section \ref{pam}).
\titem{--enable-odbc or --enable-mssql}
Required if you want to use an external database.
@@ -348,29 +360,36 @@ To install \ejabberd{} in the destination directories, run the command:
\begin{verbatim}
make install
\end{verbatim}
-Note that you may need to have administrative privileges in the system.
+Note that you probably need administrative privileges in the system
+to install \term{ejabberd}.
The files and directories created are, by default:
\begin{description}
- \titem{/etc/ejabberd/} Configuration files:
+ \titem{/etc/ejabberd/} Configuration directory:
\begin{description}
\titem{ejabberd.cfg} ejabberd configuration file
\titem{ejabberdctl.cfg} Configuration file of the administration script
- \titem{inetrc} Network DNS configuration
+ \titem{inetrc} Network DNS configuration file
\end{description}
- \titem{/sbin/ejabberdctl} Administration script
- \titem{/var/lib/ejabberd/}
+ \titem{/lib/ejabberd/}
\begin{description}
- \titem{.erlang.cookie} Erlang cookie file (see section \ref{cookie})
- \titem{db} Mnesia database spool files
- \titem{ebin} Binary Erlang files (*.beam)
- \titem{priv}
+ \titem{ebin/} Erlang binary files (*.beam)
+ \titem{include/} Erlang header files (*.hrl)
+ \titem{priv/} Additional files required at runtime
\begin{description}
- \titem{lib} Binary system libraries (*.so)
- \titem{msgs} Translated strings (*.msgs)
+ \titem{bin/} Binary C programs
+ \titem{lib/} Binary system libraries (*.so)
+ \titem{msgs/} Translation files (*.msgs)
\end{description}
\end{description}
- \titem{/var/log/ejabberd/} Log files (see section~\ref{logfiles}):
+ \titem{/sbin/ejabberdctl} Administration script (see section~\ref{ejabberdctl})
+ \titem{/share/doc/ejabberd/} Documentation of ejabberd
+ \titem{/var/lib/ejabberd/} Spool directory:
+ \begin{description}
+ \titem{.erlang.cookie} Erlang cookie file (see section \ref{cookie})
+ \titem{acl.DCD, ...} Mnesia database spool files (*.DCD, *.DCL, *.DAT)
+ \end{description}
+ \titem{/var/log/ejabberd/} Log directory (see section~\ref{logfiles}):
\begin{description}
\titem{ejabberd.log} ejabberd service log
\titem{sasl.log} Erlang/OTP system log
@@ -382,6 +401,8 @@ The files and directories created are, by default:
\ind{install!start}
You can use the \term{ejabberdctl} command line administration script to start and stop \ejabberd{}.
+If you provided the configure option \term{--enable-user=USER} (see \ref{compile}),
+you can execute \term{ejabberdctl} with either that system account or root.
Usage example:
\begin{verbatim}
@@ -393,6 +414,7 @@ ejabberd is running
ejabberdctl stop
\end{verbatim}
+
Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl},
and configurable options to fine tune the Erlang runtime system.
@@ -1117,7 +1139,7 @@ security issues:
\begin{itemize}
\item To perform PAM authentication \ejabberd{} uses external C-program called
-\term{epam}. By default, it is located in \verb|/var/lib/ejabberd/priv/lib/|
+\term{epam}. By default, it is located in \verb|/var/lib/ejabberd/priv/bin/|
directory. You have to set it root on execution in the case when your PAM module
requires root privileges (\term{pam\_unix.so} for example). Also you have to grant access
for \ejabberd{} to this file and remove all other permissions from it.
@@ -3036,7 +3058,7 @@ Options:
\titem{welcome\_message} \ind{options!welcomem}Set a welcome message that
is sent to each newly registered account. The first string is the subject, and
the second string is the message body.
- In the body you can set a newline with the characters: \term{\~\ n}.
+ In the body you can set a newline with the characters: \verb|\n|
\titem{registration\_watchers} \ind{options!rwatchers}This option defines a
list of JIDs which will be notified each time a new account is registered.
\iqdiscitem{In-Band Registration (\ns{jabber:iq:register})}
@@ -3095,7 +3117,7 @@ Also define a registration timeout of one hour:
...
{mod_register,
[
- {welcome_message, {"Welcome!", "Hi.~nWelcome to this Jabber server.~n Check http://www.jabber.org~n~nBye"}},
+ {welcome_message, {"Welcome!", "Hi.\nWelcome to this Jabber server.\n Check http://www.jabber.org\n\nBye"}},
{registration_watchers, ["admin1@example.org", "boss@example.net"]}
]},
...
@@ -3708,7 +3730,7 @@ The command line parameters:
Specify the directory where Erlang binary files (*.beam) are located.
\titem{-s ejabberd}
Tell Erlang runtime system to start the \ejabberd{} application.
- \titem{-mnesia dir "/var/lib/ejabberd/db/nodename"}
+ \titem{-mnesia dir "/var/lib/ejabberd/"}
Specify the Mnesia database directory.
\titem{-sasl sasl\_error\_logger \{file, "/var/log/ejabberd/sasl.log"\}}
Path to the Erlang/OTP system log file.
@@ -3941,10 +3963,10 @@ write and execute those files and directories.
If the loglevel is set to 5, it contains whole conversations and passwords.
If a logrotate system is used, there may be several log files with similar information,
so it is preferable to secure the whole \term{/var/log/ejabberd/} directory.
- \titem{Mnesia database spool files: /var/lib/ejabberd/db/*}
+ \titem{Mnesia database spool files in /var/lib/ejabberd/}
The files store binary data, but some parts are still readable.
The files are generated by Mnesia and their permissions cannot be set directly,
- so it is preferable to secure the whole \term{/var/lib/ejabberd/db/} directory.
+ so it is preferable to secure the whole \term{/var/lib/ejabberd/} directory.
\titem{Erlang cookie file: /var/lib/ejabberd/.erlang.cookie}
See section \ref{cookie}.
\end{description}
diff --git a/src/adhoc.hrl b/include/adhoc.hrl
similarity index 100%
rename from src/adhoc.hrl
rename to include/adhoc.hrl
diff --git a/src/ejabberd.hrl b/include/ejabberd.hrl
similarity index 100%
rename from src/ejabberd.hrl
rename to include/ejabberd.hrl
diff --git a/src/ejabberd_config.hrl b/include/ejabberd_config.hrl
similarity index 100%
rename from src/ejabberd_config.hrl
rename to include/ejabberd_config.hrl
diff --git a/src/ejabberd_ctl.hrl b/include/ejabberd_ctl.hrl
similarity index 100%
rename from src/ejabberd_ctl.hrl
rename to include/ejabberd_ctl.hrl
diff --git a/src/web/ejabberd_http.hrl b/include/ejabberd_http.hrl
similarity index 100%
rename from src/web/ejabberd_http.hrl
rename to include/ejabberd_http.hrl
diff --git a/src/web/ejabberd_web_admin.hrl b/include/ejabberd_web_admin.hrl
similarity index 100%
rename from src/web/ejabberd_web_admin.hrl
rename to include/ejabberd_web_admin.hrl
diff --git a/src/eldap/eldap.hrl b/include/eldap.hrl
similarity index 100%
rename from src/eldap/eldap.hrl
rename to include/eldap.hrl
diff --git a/src/jlib.hrl b/include/jlib.hrl
similarity index 100%
rename from src/jlib.hrl
rename to include/jlib.hrl
diff --git a/src/mod_privacy.hrl b/include/mod_privacy.hrl
similarity index 100%
rename from src/mod_privacy.hrl
rename to include/mod_privacy.hrl
diff --git a/src/mod_proxy65/mod_proxy65.hrl b/include/mod_proxy65.hrl
similarity index 100%
rename from src/mod_proxy65/mod_proxy65.hrl
rename to include/mod_proxy65.hrl
diff --git a/src/mod_roster.hrl b/include/mod_roster.hrl
similarity index 100%
rename from src/mod_roster.hrl
rename to include/mod_roster.hrl
diff --git a/src/mod_pubsub/pubsub.hrl b/include/pubsub.hrl
similarity index 100%
rename from src/mod_pubsub/pubsub.hrl
rename to include/pubsub.hrl
diff --git a/src/Makefile.in b/src/Makefile.in
index 607af353e..3d398f569 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -12,37 +12,53 @@ ERLANG_CFLAGS= @ERLANG_CFLAGS@
EXPAT_LIBS = @EXPAT_LIBS@
ERLANG_LIBS = @ERLANG_LIBS@
-ERLC_FLAGS += @ERLANG_SSL39@
-
ASN_FLAGS = -bber_bin +der +compact_bit_string +optimize +noobj
+
+INSTALLUSER=@INSTALLUSER@
+# if no user was enabled, don't set privileges or ownership
+ifeq ($(INSTALLUSER),)
+ O_USER=
+ G_USER=
+ CHOWN_COMMAND=echo
+ CHOWN_OUTPUT=/dev/null
+else
+ O_USER=-o $(INSTALLUSER)
+ G_USER=-g $(INSTALLUSER)
+ CHOWN_COMMAND=chown
+ CHOWN_OUTPUT=&1
+endif
+
+EFLAGS += @ERLANG_SSL39@
+EFLAGS += -I ../include
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
- ERLC_FLAGS+=+debug_info
+ EFLAGS+=+debug_info
endif
ifdef ejabberd_debug
- ERLC_FLAGS+=-Dejabberd_debug
+ EFLAGS+=-Dejabberd_debug
endif
ifeq (@hipe@, true)
- ERLC_FLAGS+=+native
+ EFLAGS+=+native
endif
ifeq (@roster_gateway_workaround@, true)
- ERLC_FLAGS+=-DROSTER_GATEWAY_WORKAROUND
+ EFLAGS+=-DROSTER_GATEWAY_WORKAROUND
endif
ifeq (@full_xml@, true)
- ERLC_FLAGS+=-DFULL_XML_SUPPORT
+ EFLAGS+=-DFULL_XML_SUPPORT
endif
ifeq (@transient_supervisors@, false)
- ERLC_FLAGS+=-DNO_TRANSIENT_SUPERVISORS
+ EFLAGS+=-DNO_TRANSIENT_SUPERVISORS
endif
INSTALL_EPAM=
ifeq (@pam@, pam)
- INSTALL_EPAM=install -m 750 epam $(PBINDIR)
+ INSTALL_EPAM=install -m 750 $(O_USER) epam $(PBINDIR)
endif
prefix = @prefix@
@@ -58,17 +74,47 @@ BEAMS = $(SOURCES:.erl=.beam)
DESTDIR =
-EJABBERDDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
-BEAMDIR = $(EJABBERDDIR)/ebin
-SPOOLDIR = $(EJABBERDDIR)/db
-PRIVDIR = $(EJABBERDDIR)/priv
-SODIR = $(PRIVDIR)/lib
-PBINDIR = $(PRIVDIR)/bin
-MSGSDIR = $(PRIVDIR)/msgs
-LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
+# /etc/ejabberd/
ETCDIR = $(DESTDIR)@sysconfdir@/ejabberd
+
+# /sbin/
SBINDIR = $(DESTDIR)@sbindir@
+# /lib/ejabberd/
+EJABBERDDIR = $(DESTDIR)@libdir@/ejabberd
+
+# /share/doc/ejabberd
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+datarootdir = @datarootdir@
+DOCDIR = @docdir@
+
+# /usr/lib/ejabberd/ebin/
+BEAMDIR = $(EJABBERDDIR)/ebin
+
+# /usr/lib/ejabberd/include/
+INCLUDEDIR = $(EJABBERDDIR)/include
+
+# /usr/lib/ejabberd/priv/
+PRIVDIR = $(EJABBERDDIR)/priv
+
+# /usr/lib/ejabberd/priv/bin
+PBINDIR = $(PRIVDIR)/bin
+
+# /usr/lib/ejabberd/priv/lib
+SODIR = $(PRIVDIR)/lib
+
+# /usr/lib/ejabberd/priv/msgs
+MSGSDIR = $(PRIVDIR)/msgs
+
+# /var/lib/ejabberd/
+SPOOLDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
+
+# /var/lib/ejabberd/.erlang.cookie
+COOKIEFILE = $(SPOOLDIR)/.erlang.cookie
+
+# /var/log/ejabberd/
+LOGDIR = $(DESTDIR)@localstatedir@/log/ejabberd
+
ifeq ($(shell uname),Darwin)
DYNAMIC_LIB_CFLAGS = -fPIC -bundle -flat_namespace -undefined suppress
else
@@ -85,7 +131,7 @@ $(BEAMS): $(ERLBEHAVBEAMS)
all-recursive: $(ERLBEHAVBEAMS)
%.beam: %.erl
- @ERLC@ -W $(ERLC_FLAGS) $<
+ @ERLC@ -W $(EFLAGS) $<
all-recursive install-recursive uninstall-recursive \
@@ -100,7 +146,7 @@ mostlyclean-recursive maintainer-clean-recursive:
%.hrl: %.asn1
@ERLC@ $(ASN_FLAGS) $<
- @ERLC@ -W $(ERLC_FLAGS) $*.erl
+ @ERLC@ -W $(EFLAGS) $*.erl
$(ERLSHLIBS): %.so: %.c
$(CC) $(CFLAGS) $(LDFLAGS) $(LIBS) \
@@ -113,39 +159,90 @@ $(ERLSHLIBS): %.so: %.c
$(DYNAMIC_LIB_CFLAGS)
install: all
+ #
+ # Configuration files
+ install -d -m 750 $(G_USER) $(ETCDIR)
+ [ -f $(ETCDIR)/ejabberd.cfg ] \
+ && install -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new \
+ || install -b -m 640 $(G_USER) ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
+ sed -e "s*@rootdir@*@prefix@*" \
+ -e "s*@installuser@*@INSTALLUSER@*" \
+ -e "s*@LIBDIR@*@libdir@*" \
+ -e "s*@SYSCONFDIR@*@sysconfdir@*" \
+ -e "s*@LOCALSTATEDIR@*@localstatedir@*" \
+ -e "s*@erl@*@ERL@*" ejabberdctl.template \
+ > ejabberdctl.example
+ [ -f $(ETCDIR)/ejabberdctl.cfg ] \
+ && install -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new \
+ || install -b -m 640 $(G_USER) ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
+ install -b -m 644 $(G_USER) inetrc $(ETCDIR)/inetrc
+ #
+ # Administration script
+ [ -d $(SBINDIR) ] || install -d 750 $(SBINDIR)
+ install -m 550 $(G_USER) ejabberdctl.example $(SBINDIR)/ejabberdctl
+ #
+ # Binary Erlang files
install -d $(BEAMDIR)
+ install -m 644 *.app $(BEAMDIR)
install -m 644 *.beam $(BEAMDIR)
rm -f $(BEAMDIR)/configure.beam
- install -m 644 *.app $(BEAMDIR)
- install -d -m 750 $(SPOOLDIR)
- install -d $(SODIR)
+ #
+ # ejabberd header files
+ install -d $(INCLUDEDIR)
+ install -m 644 ../include/*.hrl $(INCLUDEDIR)
+ #
+ # Binary C programs
install -d $(PBINDIR)
- install -m 644 *.so $(SODIR)
$(INSTALL_EPAM)
+ #
+ # Binary system libraries
+ install -d $(SODIR)
+ install -m 644 *.so $(SODIR)
+ #
+ # Translated strings
install -d $(MSGSDIR)
install -m 644 msgs/*.msg $(MSGSDIR)
- install -d -m 750 $(ETCDIR)
- [ -f $(ETCDIR)/ejabberd.cfg ] && install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new || install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
- sed -e "s*@rootdir@*@prefix@*" ejabberdctl.template > ejabberdctl.example
- [ -f $(ETCDIR)/ejabberdctl.cfg ] && install -b -m 644 ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new || install -b -m 644 ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
- install -b -m 644 inetrc $(ETCDIR)/inetrc
- install -d $(SBINDIR)
- install -m 755 ejabberdctl.example $(SBINDIR)/ejabberdctl
- install -d -m 750 $(LOGDIR)
+ #
+ # Spool directory
+ install -d -m 750 $(O_USER) $(SPOOLDIR)
+ $(CHOWN_COMMAND) -R @INSTALLUSER@ $(SPOOLDIR) >$(CHOWN_OUTPUT)
+ chmod -R 750 $(SPOOLDIR)
+ [ ! -f $(COOKIEFILE) ] || { $(CHOWN_COMMAND) @INSTALLUSER@ $(COOKIEFILE) >$(CHOWN_OUTPUT) ; chmod 400 $(COOKIEFILE) ; }
+ #
+ # Log directory
+ install -d -m 750 $(O_USER) $(LOGDIR)
+ $(CHOWN_COMMAND) -R @INSTALLUSER@ $(LOGDIR) >$(CHOWN_OUTPUT)
+ chmod -R 750 $(LOGDIR)
+ #
+ # Documentation
+ install -d $(DOCDIR)
+ install ../doc/guide.html $(DOCDIR)
+ install ../doc/*.png $(DOCDIR)
+ install ../doc/*.txt $(DOCDIR)
uninstall: uninstall-binary
uninstall-binary:
- rm -rf $(BEAMDIR)
- rm -rf $(SODIR)
- rm -rf $(MSGSDIR)
- rm -rf $(PRIVDIR)
- rm -rf $(SBINDIR)/ejabberdctl
+ rm -f $(SBINDIR)/ejabberdctl
+ rm -fr $(DOCDIR)
+ rm -f $(BEAMDIR)/*.beam
+ rm -f $(BEAMDIR)/*.app
+ rm -fr $(BEAMDIR)
+ rm -f $(INCLUDEDIR)/*.hrl
+ rm -fr $(INCLUDEDIR)
+ rm -fr $(PBINDIR)
+ rm -f $(SODIR)/*.so
+ rm -fr $(SODIR)
+ rm -f $(MSGSDIR)/*.msgs
+ rm -fr $(MSGSDIR)
+ rm -fr $(PRIVDIR)
+ rm -fr $(EJABBERDDIR)
uninstall-all: uninstall-binary
rm -rf $(ETCDIR)
- rm -rf $(LOGDIR)
rm -rf $(EJABBERDDIR)
+ rm -rf $(SPOOLDIR)
+ rm -rf $(LOGDIR)
clean: clean-recursive clean-local
diff --git a/src/aclocal.m4 b/src/aclocal.m4
index 65509eefc..10a9e4bd1 100644
--- a/src/aclocal.m4
+++ b/src/aclocal.m4
@@ -1,6 +1,6 @@
AC_DEFUN(AM_WITH_EXPAT,
[ AC_ARG_WITH(expat,
- [ --with-expat=PREFIX prefix where EXPAT is installed])
+ [AC_HELP_STRING([--with-expat=PREFIX], [prefix where EXPAT is installed])])
EXPAT_CFLAGS=
EXPAT_LIBS=
@@ -34,7 +34,7 @@ AC_DEFUN(AM_WITH_EXPAT,
AC_DEFUN(AM_WITH_ZLIB,
[ AC_ARG_WITH(zlib,
- [ --with-zlib=PREFIX prefix where zlib is installed])
+ [AC_HELP_STRING([--with-zlib=PREFIX], [prefix where zlib is installed])])
ZLIB_CFLAGS=
ZLIB_LIBS=
@@ -68,7 +68,7 @@ AC_DEFUN(AM_WITH_ZLIB,
AC_DEFUN(AM_WITH_PAM,
[ AC_ARG_WITH(pam,
- [ --with-pam=PREFIX prefix where PAM is installed])
+ [AC_HELP_STRING([--with-pam=PREFIX], [prefix where PAM is installed])])
PAM_CFLAGS=
PAM_LIBS=
@@ -102,7 +102,7 @@ AC_DEFUN(AM_WITH_PAM,
AC_DEFUN(AM_WITH_ERLANG,
[ AC_ARG_WITH(erlang,
- [ --with-erlang=PREFIX path to erlc and erl ])
+ [AC_HELP_STRING([--with-erlang=PREFIX], [path to erlc and erl])])
AC_PATH_TOOL(ERLC, erlc, , $with_erlang:$with_erlang/bin:$PATH)
AC_PATH_TOOL(ERL, erl, , $with_erlang:$with_erlang/bin:$PATH)
@@ -204,14 +204,13 @@ _EOF
AC_SUBST(ERL)
])
-
AC_DEFUN(AC_MOD_ENABLE,
[
$1=
make_$1=
AC_MSG_CHECKING([whether build $1])
AC_ARG_ENABLE($1,
- [ --enable-$1 enable $1 (default: $2)],
+ [AC_HELP_STRING([--enable-$1], [enable $1 (default: $2)])],
[mr_enable_$1="$enableval"],
[mr_enable_$1=$2])
if test "$mr_enable_$1" = "yes"; then
@@ -232,7 +231,7 @@ AC_DEFUN([AM_ICONV],
dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
dnl those with the standalone portable GNU libiconv installed).
AC_ARG_WITH([libiconv-prefix],
-[ --with-libiconv-prefix=PREFIX prefix where libiconv is installed], [
+ [AC_HELP_STRING([--with-libiconv-prefix=PREFIX], [prefix where libiconv is installed])], [
for dir in `echo "$withval" | tr : ' '`; do
if test -d $dir/include; then CPPFLAGS="$CPPFLAGS -I$dir/include"; fi
if test -d $dir/include; then CFLAGS="$CFLAGS -I$dir/include"; fi
@@ -317,7 +316,7 @@ size_t iconv();
dnl
AC_DEFUN(AM_WITH_OPENSSL,
[ AC_ARG_WITH(openssl,
- [ --with-openssl=PREFIX prefix where OPENSSL is installed ])
+ [AC_HELP_STRING([--with-openssl=PREFIX], [prefix where OPENSSL is installed])])
unset SSL_LIBS;
unset SSL_CFLAGS;
have_openssl=no
diff --git a/src/configure b/src/configure
index 034868416..a6cc19b6c 100755
--- a/src/configure
+++ b/src/configure
@@ -1,6 +1,8 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61.
+# Generated by GNU Autoconf 2.61 for ejabberd.erl version.
+#
+# Report bugs to .
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -570,13 +572,12 @@ MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
+PACKAGE_NAME='ejabberd.erl'
+PACKAGE_TARNAME='ejabberd'
+PACKAGE_VERSION='version'
+PACKAGE_STRING='ejabberd.erl version'
+PACKAGE_BUGREPORT='ejabberd@process-one.net'
-ac_unique_file="ejabberd.erl"
# Factoring default headers for most tests.
ac_includes_default="\
#include
@@ -703,6 +704,7 @@ transient_supervisors
full_xml
SSL_LIBS
SSL_CFLAGS
+INSTALLUSER
LTLIBOBJS'
ac_subst_files=''
ac_precious_vars='build_alias
@@ -752,7 +754,7 @@ sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
includedir='${prefix}/include'
oldincludedir='/usr/include'
-docdir='${datarootdir}/doc/${PACKAGE}'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
@@ -1216,7 +1218,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
+\`configure' configures ejabberd.erl version to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1264,7 +1266,7 @@ Fine tuning of the installation directories:
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
- --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/ejabberd]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
@@ -1276,37 +1278,49 @@ _ACEOF
fi
if test -n "$ac_init_help"; then
-
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of ejabberd.erl version:";;
+ esac
cat <<\_ACEOF
Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --enable-mod_pubsub enable mod_pubsub (default: yes)
+ --enable-mod_pubsub enable mod_pubsub (default: yes)
--enable-mod_irc enable mod_irc (default: yes)
--enable-mod_muc enable mod_muc (default: yes)
- --enable-mod_proxy65 enable mod_proxy65 (default: yes)
- --enable-eldap enable eldap (default: yes)
- --enable-pam enable pam (default: no)
- --enable-web enable web (default: yes)
- --enable-tls enable tls (default: yes)
- --enable-odbc enable odbc (default: no)
- --enable-ejabberd_zlib enable ejabberd_zlib (default: yes)
- --enable-hipe Compile natively with HiPE, not recommended (default: no)
- --enable-roster-gateway-workaround Turn on workaround for processing gateway subscriptions (default: no)
- --enable-mssql Use Microsoft SQL Server database (default: no, requires --enable-odbc)
- --enable-transient_supervisors Use Erlang supervision for transient process (default: yes)
- --enable-full-xml Use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)
+ --enable-mod_proxy65 enable mod_proxy65 (default: yes)
+ --enable-eldap enable eldap (default: yes)
+ --enable-pam enable pam (default: no)
+ --enable-web enable web (default: yes)
+ --enable-tls enable tls (default: yes)
+ --enable-odbc enable odbc (default: no)
+ --enable-ejabberd_zlib enable ejabberd_zlib (default: yes)
+ --enable-hipe compile natively with HiPE, not recommended
+ (default: no)
+ --enable-roster-gateway-workaround
+ turn on workaround for processing gateway
+ subscriptions (default: no)
+ --enable-mssql use Microsoft SQL Server database (default: no,
+ requires --enable-odbc)
+ --enable-transient_supervisors
+ use Erlang supervision for transient process
+ (default: yes)
+ --enable-full-xml use XML features in XMPP stream (ex: CDATA)
+ (default: no, requires XML compliant clients)
+ --enable-user[=USER] allow this system user to start ejabberd (default:
+ no)
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-erlang=PREFIX path to erlc and erl
- --with-libiconv-prefix=PREFIX prefix where libiconv is installed
- --with-expat=PREFIX prefix where EXPAT is installed
- --with-zlib=PREFIX prefix where zlib is installed
- --with-pam=PREFIX prefix where PAM is installed
- --with-openssl=PREFIX prefix where OPENSSL is installed
+ --with-libiconv-prefix=PREFIX
+ prefix where libiconv is installed
+ --with-expat=PREFIX prefix where EXPAT is installed
+ --with-zlib=PREFIX prefix where zlib is installed
+ --with-pam=PREFIX prefix where PAM is installed
+ --with-openssl=PREFIX prefix where OPENSSL is installed
Some influential environment variables:
CC C compiler command
@@ -1321,6 +1335,7 @@ Some influential environment variables:
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
+Report bugs to .
_ACEOF
ac_status=$?
fi
@@ -1381,7 +1396,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-configure
+ejabberd.erl configure version
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1395,7 +1410,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by $as_me, which was
+It was created by ejabberd.erl $as_me version, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -1728,6 +1743,14 @@ fi
+
+
+
+
+
+
+
+
@@ -4131,7 +4154,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to ejabberd@process-one.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -4376,7 +4404,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to ejabberd@process-one.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -4620,7 +4653,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to ejabberd@process-one.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -4888,7 +4926,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to ejabberd@process-one.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -5676,7 +5719,12 @@ echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to ejabberd@process-one.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -5849,7 +5897,12 @@ echo "$as_me: WARNING: krb5.h: section \"Present But Cannot Be Compiled\"" >
echo "$as_me: WARNING: krb5.h: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: krb5.h: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: krb5.h: in the future, the compiler will take precedence" >&2;}
-
+ ( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to ejabberd@process-one.net ##
+## --------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ echo "$as_me:$LINENO: checking for krb5.h" >&5
@@ -5866,6 +5919,22 @@ fi
+ENABLEUSER=""
+# Check whether --enable-user was given.
+if test "${enable_user+set}" = set; then
+ enableval=$enable_user; case "${enableval}" in
+ yes) ENABLEUSER=`whoami` ;;
+ no) ENABLEUSER="" ;;
+ *) ENABLEUSER=$enableval
+ esac
+fi
+
+if test "$ENABLEUSER" != ""; then
+ echo "allow this system user to start ejabberd: $ENABLEUSER"
+ INSTALLUSER=$ENABLEUSER
+
+fi
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -6292,7 +6361,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by $as_me, which was
+This file was extended by ejabberd.erl $as_me version, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -6335,7 +6404,7 @@ Report bugs to ."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-config.status
+ejabberd.erl config.status version
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -6594,10 +6663,11 @@ transient_supervisors!$transient_supervisors$ac_delim
full_xml!$full_xml$ac_delim
SSL_LIBS!$SSL_LIBS$ac_delim
SSL_CFLAGS!$SSL_CFLAGS$ac_delim
+INSTALLUSER!$INSTALLUSER$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/src/configure.ac b/src/configure.ac
index 254b16b06..ba6384633 100644
--- a/src/configure.ac
+++ b/src/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.53)
-AC_INIT(ejabberd.erl,, ejabberd@process-one.net)
+AC_INIT(ejabberd.erl, version, [ejabberd@process-one.net], [ejabberd])
# Checks for programs.
AC_PROG_CC
@@ -48,7 +48,7 @@ AC_MOD_ENABLE(odbc, no)
AC_MOD_ENABLE(ejabberd_zlib, yes)
AC_ARG_ENABLE(hipe,
-[ --enable-hipe Compile natively with HiPE, not recommended (default: no)],
+[AC_HELP_STRING([--enable-hipe], [compile natively with HiPE, not recommended (default: no)])],
[case "${enableval}" in
yes) hipe=true ;;
no) hipe=false ;;
@@ -57,7 +57,7 @@ esac],[hipe=false])
AC_SUBST(hipe)
AC_ARG_ENABLE(roster_gateway_workaround,
-[ --enable-roster-gateway-workaround Turn on workaround for processing gateway subscriptions (default: no)],
+[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
[case "${enableval}" in
yes) roster_gateway_workaround=true ;;
no) roster_gateway_workaround=false ;;
@@ -66,7 +66,7 @@ esac],[roster_gateway_workaround=false])
AC_SUBST(roster_gateway_workaround)
AC_ARG_ENABLE(mssql,
-[ --enable-mssql Use Microsoft SQL Server database (default: no, requires --enable-odbc)],
+[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
[case "${enableval}" in
yes) db_type=mssql ;;
no) db_type=generic ;;
@@ -75,7 +75,7 @@ esac],[db_type=generic])
AC_SUBST(db_type)
AC_ARG_ENABLE(transient_supervisors,
-[ --enable-transient_supervisors Use Erlang supervision for transient process (default: yes)],
+[AC_HELP_STRING([--enable-transient_supervisors], [use Erlang supervision for transient process (default: yes)])],
[case "${enableval}" in
yes) transient_supervisors=true ;;
no) transient_supervisors=false ;;
@@ -84,7 +84,7 @@ esac],[transient_supervisors=true])
AC_SUBST(transient_supervisors)
AC_ARG_ENABLE(full_xml,
-[ --enable-full-xml Use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)],
+[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
[case "${enableval}" in
yes) full_xml=true ;;
no) full_xml=false ;;
@@ -122,4 +122,18 @@ else
fi
AC_CHECK_HEADER(krb5.h,,)
+ENABLEUSER=""
+AC_ARG_ENABLE(user,
+ [AS_HELP_STRING([--enable-user[[[[=USER]]]]], [allow this system user to start ejabberd (default: no)])],
+ [case "${enableval}" in
+ yes) ENABLEUSER=`whoami` ;;
+ no) ENABLEUSER="" ;;
+ *) ENABLEUSER=$enableval
+ esac],
+ [])
+if test "$ENABLEUSER" != ""; then
+ echo "allow this system user to start ejabberd: $ENABLEUSER"
+ AC_SUBST([INSTALLUSER], [$ENABLEUSER])
+fi
+
AC_OUTPUT
diff --git a/src/ejabberd.cfg.example b/src/ejabberd.cfg.example
index eb43bb3ca..022a9ebc2 100644
--- a/src/ejabberd.cfg.example
+++ b/src/ejabberd.cfg.example
@@ -459,7 +459,7 @@
%% a message with this subject and body.
%%
{welcome_message, {"Welcome!",
- "Hi.~nWelcome to this Jabber server."}},
+ "Hi.\nWelcome to this Jabber server."}},
%%
%% When a user registers, send a notification to
diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl
index d576a82fd..b9bf3b477 100644
--- a/src/ejabberd_auth_ldap.erl
+++ b/src/ejabberd_auth_ldap.erl
@@ -58,7 +58,7 @@
]).
-include("ejabberd.hrl").
--include("eldap/eldap.hrl").
+-include("eldap.hrl").
-record(state, {host,
eldap_id,
diff --git a/src/ejabberd_zlib/Makefile.in b/src/ejabberd_zlib/Makefile.in
index f24addbc3..3a70186bd 100644
--- a/src/ejabberd_zlib/Makefile.in
+++ b/src/ejabberd_zlib/Makefile.in
@@ -19,7 +19,8 @@ else
DYNAMIC_LIB_CFLAGS = -fpic -shared
endif
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/ejabberdctl.template b/src/ejabberdctl.template
index e086d1ef4..fcf0a80cc 100644
--- a/src/ejabberdctl.template
+++ b/src/ejabberdctl.template
@@ -11,13 +11,15 @@ ERL_MAX_ETS_TABLES=1400
NODE=ejabberd
HOST=localhost
ERLANG_NODE=$NODE@$HOST
-ROOTDIR=@rootdir@
-EJABBERD_CONFIG_PATH=$ROOTDIR/etc/ejabberd/ejabberd.cfg
-LOGS_DIR=$ROOTDIR/var/log/ejabberd/
-EJABBERD_DB=$ROOTDIR/var/lib/ejabberd/db/$NODE
+ERL=@erl@
+INSTALLUSER=@installuser@
+ETCDIR=@SYSCONFDIR@/ejabberd
+EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.cfg
+LOGDIR=@LOCALSTATEDIR@/log/ejabberd
+SPOOLDIR=@LOCALSTATEDIR@/lib/ejabberd
# read custom configuration
-CONFIG=$ROOTDIR/etc/ejabberd/ejabberdctl.cfg
+CONFIG=$ETCDIR/ejabberdctl.cfg
[ -f "$CONFIG" ] && . "$CONFIG"
# parse command line parameters
@@ -30,12 +32,27 @@ while [ $# -ne 0 ] ; do
--node) ERLANG_NODE=$1; shift ;;
--config) EJABBERD_CONFIG_PATH=$1 ; shift ;;
--ctl-config) CONFIG=$1 ; shift ;;
- --logs) LOGS_DIR=$1 ; shift ;;
- --spool) EJABBERD_DB=$1 ; shift ;;
+ --logs) LOGDIR=$1 ; shift ;;
+ --spool) SPOOLDIR=$1 ; shift ;;
*) ARGS="$ARGS $PARAM" ;;
esac
done
+# check the proper system user is used
+ID=`id -g`
+EJID=`id -g $INSTALLUSER`
+EXEC_CMD="false"
+if [ $ID -eq 0 ] ; then
+ EXEC_CMD="su ${INSTALLUSER} -c"
+fi
+if [ "$ID" -eq "$EJID" ] ; then
+ EXEC_CMD="sh -c"
+fi
+if [ "$EXEC_CMD" = "false" ] ; then
+ echo "This command can only be run by root or the user $INSTALLUSER" >&2
+ exit 1
+fi
+
NAME=-name
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && NAME=-sname
@@ -48,31 +65,36 @@ fi
ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $KERNEL_OPTS"
# define additional environment variables
-EJABBERD_EBIN=$ROOTDIR/var/lib/ejabberd/ebin
-EJABBERD_MSGS_PATH=$ROOTDIR/var/lib/ejabberd/priv/msgs
-EJABBERD_SO_PATH=$ROOTDIR/var/lib/ejabberd/priv/lib
-EJABBERD_BIN_PATH=$ROOTDIR/var/lib/ejabberd/priv/bin
-EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
-SASL_LOG_PATH=$LOGS_DIR/sasl.log
+EJABBERDDIR=@LIBDIR@/ejabberd
+BEAMDIR=$EJABBERDDIR/ebin
+PRIVDIR=$EJABBERDDIR/priv
+PBINDIR=$PRIVDIR/bin
+SODIR=$PRIVDIR/lib
+MSGSDIR=$PRIVDIR/msgs
+
+EJABBERD_LOG_PATH=$LOGDIR/ejabberd.log
+SASL_LOG_PATH=$LOGDIR/sasl.log
DATETIME=`date "+%Y%m%d-%H%M%S"`
-ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
-ERL_INETRC=$ROOTDIR/etc/ejabberd/inetrc
-HOME=$ROOTDIR/var/lib/ejabberd
+ERL_CRASH_DUMP=$LOGDIR/erl_crash_$DATETIME.dump
+ERL_INETRC=$ETCDIR/inetrc
+HOME=$SPOOLDIR
+
+# create the home dir with the proper user if doesn't exist, because it stores cookie file
+[ -d $HOME ] || $EXEC_CMD "mkdir -p $HOME"
# export global variables
export EJABBERD_CONFIG_PATH
-export EJABBERD_MSGS_PATH
+export MSGSDIR
export EJABBERD_LOG_PATH
-export EJABBERD_SO_PATH
-export EJABBERD_BIN_PATH
+export SODIR
+export PBINDIR
export ERL_CRASH_DUMP
export ERL_INETRC
export ERL_MAX_PORTS
export ERL_MAX_ETS_TABLES
export HOME
+export EXEC_CMD
-[ -d $EJABBERD_DB ] || mkdir -p $EJABBERD_DB
-[ -d $LOGS_DIR ] || mkdir -p $LOGS_DIR
# Compatibility in ZSH
#setopt shwordsplit 2>/dev/null
@@ -80,14 +102,14 @@ export HOME
# start server
start ()
{
- erl \
+ $EXEC_CMD "$ERL \
$NAME $ERLANG_NODE \
-noinput -detached \
- -pa $EJABBERD_EBIN \
- -mnesia dir "\"$EJABBERD_DB\"" \
+ -pa $BEAMDIR \
+ -mnesia dir \"\\\"$SPOOLDIR\\\"\" \
-s ejabberd \
- -sasl sasl_error_logger \{file,\"$SASL_LOG_PATH\"\} \
- $ERLANG_OPTS $ARGS "$@"
+ -sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \
+ $ERLANG_OPTS $ARGS \"$@\""
}
# attach to server
@@ -109,10 +131,10 @@ debug ()
echo "Press any key to continue"
read foo
echo ""
- erl \
+ $EXEC_CMD "$ERL \
$NAME ${NODE}debug \
-remsh $ERLANG_NODE \
- $ERLANG_OPTS $ARGS "$@"
+ $ERLANG_OPTS $ARGS \"$@\""
}
# start interactive server
@@ -133,23 +155,22 @@ live ()
echo "Press any key to continue"
read foo
echo ""
- erl \
+ $EXEC_CMD "$ERL \
$NAME $ERLANG_NODE \
- $ERLANG_OPTS \
- -pa $EJABBERD_EBIN \
- -mnesia dir "\"$EJABBERD_DB\"" \
+ -pa $BEAMDIR \
+ -mnesia dir \"\\\"$SPOOLDIR\\\"\" \
-s ejabberd \
- $ERLANG_OPTS $ARGS "$@"
+ $ERLANG_OPTS $ARGS \"$@\""
}
# common control function
ctl ()
{
- erl \
+ $EXEC_CMD "$ERL \
$NAME ejabberdctl \
-noinput \
- -pa $EJABBERD_EBIN \
- -s ejabberd_ctl -extra $ERLANG_NODE $@
+ -pa $BEAMDIR \
+ -s ejabberd_ctl -extra $ERLANG_NODE $@"
result=$?
case $result in
0) :;;
@@ -163,8 +184,9 @@ ctl ()
echo "Optional parameters when starting an ejabberd node:"
echo " --config file Config file of ejabberd: $EJABBERD_CONFIG_PATH"
echo " --ctl-config file Config file of ejabberdctl: $CONFIG"
- echo " --logs dir Directory for logs: $LOGS_DIR"
- echo " --spool dir Database spool dir: $EJABBERD_DB"
+ echo " --logs dir Directory for logs: $LOGDIR"
+ echo " --spool dir Database spool dir: $SPOOLDIR"
+ echo " --node nodename ejabberd node name: $ERLANG_NODE"
echo "";;
esac
return $result
diff --git a/src/eldap/Makefile.in b/src/eldap/Makefile.in
index 1c9b7ca22..4c9c33c22 100644
--- a/src/eldap/Makefile.in
+++ b/src/eldap/Makefile.in
@@ -9,7 +9,8 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/mod_irc/Makefile.in b/src/mod_irc/Makefile.in
index 5000721a6..86212e45c 100644
--- a/src/mod_irc/Makefile.in
+++ b/src/mod_irc/Makefile.in
@@ -16,7 +16,9 @@ else
DYNAMIC_LIB_CFLAGS = -fpic -shared
endif
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/mod_muc/Makefile.in b/src/mod_muc/Makefile.in
index 8aa3bf5e1..80725d33d 100644
--- a/src/mod_muc/Makefile.in
+++ b/src/mod_muc/Makefile.in
@@ -9,7 +9,9 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index 3a751c328..3db29844b 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -43,8 +43,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
--include("web/ejabberd_http.hrl").
--include("web/ejabberd_web_admin.hrl").
+-include("ejabberd_http.hrl").
+-include("ejabberd_web_admin.hrl").
-record(offline_msg, {us, timestamp, expire, from, to, packet}).
diff --git a/src/mod_offline_odbc.erl b/src/mod_offline_odbc.erl
index c3d0513d0..79d7c51ae 100644
--- a/src/mod_offline_odbc.erl
+++ b/src/mod_offline_odbc.erl
@@ -42,8 +42,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
--include("web/ejabberd_http.hrl").
--include("web/ejabberd_web_admin.hrl").
+-include("ejabberd_http.hrl").
+-include("ejabberd_web_admin.hrl").
-record(offline_msg, {user, timestamp, expire, from, to, packet}).
diff --git a/src/mod_proxy65/Makefile.in b/src/mod_proxy65/Makefile.in
index b9eba4267..62ae77c9f 100644
--- a/src/mod_proxy65/Makefile.in
+++ b/src/mod_proxy65/Makefile.in
@@ -9,7 +9,9 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/mod_proxy65/mod_proxy65_service.erl b/src/mod_proxy65/mod_proxy65_service.erl
index 41c3af7d5..4ee3ec61a 100644
--- a/src/mod_proxy65/mod_proxy65_service.erl
+++ b/src/mod_proxy65/mod_proxy65_service.erl
@@ -41,8 +41,8 @@
%% API.
-export([start_link/2]).
--include("../ejabberd.hrl").
--include("../jlib.hrl").
+-include("ejabberd.hrl").
+-include("jlib.hrl").
-define(PROCNAME, ejabberd_mod_proxy65_service).
diff --git a/src/mod_proxy65/mod_proxy65_stream.erl b/src/mod_proxy65/mod_proxy65_stream.erl
index ccc060afe..046ac8e71 100644
--- a/src/mod_proxy65/mod_proxy65_stream.erl
+++ b/src/mod_proxy65/mod_proxy65_stream.erl
@@ -58,7 +58,7 @@
]).
-include("mod_proxy65.hrl").
--include("../ejabberd.hrl").
+-include("ejabberd.hrl").
-define(WAIT_TIMEOUT, 60000). %% 1 minute (is it enough?)
diff --git a/src/mod_pubsub/Makefile.in b/src/mod_pubsub/Makefile.in
index 39f6a16e8..25dbf57a5 100644
--- a/src/mod_pubsub/Makefile.in
+++ b/src/mod_pubsub/Makefile.in
@@ -9,7 +9,9 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/mod_register.erl b/src/mod_register.erl
index 21080c8a2..a936ea5e1 100644
--- a/src/mod_register.erl
+++ b/src/mod_register.erl
@@ -241,13 +241,12 @@ send_welcome_message(JID) ->
{"", ""} ->
ok;
{Subj, Body} ->
- BodyFormatted = io_lib:format(Body, []),
ejabberd_router:route(
jlib:make_jid("", Host, ""),
JID,
{xmlelement, "message", [{"type", "normal"}],
[{xmlelement, "subject", [], [{xmlcdata, Subj}]},
- {xmlelement, "body", [], [{xmlcdata, BodyFormatted}]}]});
+ {xmlelement, "body", [], [{xmlcdata, Body}]}]});
_ ->
ok
end.
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 038de586a..c1569bb61 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -47,8 +47,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("mod_roster.hrl").
--include("web/ejabberd_http.hrl").
--include("web/ejabberd_web_admin.hrl").
+-include("ejabberd_http.hrl").
+-include("ejabberd_web_admin.hrl").
start(Host, Opts) ->
diff --git a/src/mod_roster_odbc.erl b/src/mod_roster_odbc.erl
index d38121560..dfb76dcbe 100644
--- a/src/mod_roster_odbc.erl
+++ b/src/mod_roster_odbc.erl
@@ -46,8 +46,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("mod_roster.hrl").
--include("web/ejabberd_http.hrl").
--include("web/ejabberd_web_admin.hrl").
+-include("ejabberd_http.hrl").
+-include("ejabberd_web_admin.hrl").
start(Host, Opts) ->
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index ff378010d..f363bd22e 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -52,8 +52,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("mod_roster.hrl").
--include("web/ejabberd_http.hrl").
--include("web/ejabberd_web_admin.hrl").
+-include("ejabberd_http.hrl").
+-include("ejabberd_web_admin.hrl").
-record(sr_group, {group_host, opts}).
-record(sr_user, {us, group_host}).
diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl
index 2b5e7faac..2225f7c86 100644
--- a/src/mod_vcard_ldap.erl
+++ b/src/mod_vcard_ldap.erl
@@ -50,7 +50,7 @@
]).
-include("ejabberd.hrl").
--include("eldap/eldap.hrl").
+-include("eldap.hrl").
-include("jlib.hrl").
-define(PROCNAME, ejabberd_mod_vcard_ldap).
diff --git a/src/odbc/Makefile.in b/src/odbc/Makefile.in
index 974517c5b..5bd130b6e 100644
--- a/src/odbc/Makefile.in
+++ b/src/odbc/Makefile.in
@@ -9,7 +9,9 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/pam/Makefile.in b/src/pam/Makefile.in
index d86b119b9..57c1ab78a 100644
--- a/src/pam/Makefile.in
+++ b/src/pam/Makefile.in
@@ -9,7 +9,9 @@ LIBS = @LIBS@ @PAM_LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/tls/Makefile.in b/src/tls/Makefile.in
index dfb8c87d0..db4a874e1 100644
--- a/src/tls/Makefile.in
+++ b/src/tls/Makefile.in
@@ -19,7 +19,9 @@ else
DYNAMIC_LIB_CFLAGS = -fpic -shared
endif
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/web/Makefile.in b/src/web/Makefile.in
index 7c4732da8..3a75f7e17 100644
--- a/src/web/Makefile.in
+++ b/src/web/Makefile.in
@@ -9,7 +9,9 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ../../include
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
@@ -21,7 +23,7 @@ BEAMS = $(addprefix $(OUTDIR)/,$(SOURCES:.erl=.beam))
all: $(BEAMS)
-$(OUTDIR)/%.beam: %.erl ejabberd_http.hrl
+$(OUTDIR)/%.beam: %.erl
@ERLC@ -W $(EFLAGS) -o $(OUTDIR) $<
clean:
From 532e8ee228bab2ecf750cc7a15ea7a97cf766ec4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Thu, 17 Jul 2008 15:26:48 +0000
Subject: [PATCH 043/582] Start conversion to exmpp. For now, only direct calls
from ejabberd_c2s are done. Calls through gen_iq_handler aren't.
SVN Revision: 1457
---
ChangeLog | 6 ++++++
src/ejabberd_c2s.erl | 6 ++----
src/mod_caps.erl | 51 ++++++++++++++++++++------------------------
3 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index ae52d1fa1..8fe09d32c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-07-17 Jean-Sébastien Pédron
+
+ * src/mod_caps.erl, src/ejabberd_c2s.erl: Start conversion to exmpp.
+ For now, only direct calls from ejabberd_c2s are done. Calls through
+ gen_iq_handler aren't.
+
2008-07-15 Jean-Sébastien Pédron
Merge revisions from 1434 to revision 1444 from trunk.
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 82fd029ce..8c35273a7 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1068,11 +1068,9 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
LFrom = jlib:short_jid(From),
LBFrom = jlib:short_bare_jid(From),
%% Note contact availability
- % XXX OLD FORMAT: Els are #xmlelement.
- Els = PacketOld#xmlelement.children,
+ Els = Packet#xmlel.children,
Caps = mod_caps:read_caps(Els),
- % XXX OLD FORMAT: From.
- mod_caps:note_caps(StateData#state.server, FromOld, Caps),
+ mod_caps:note_caps(StateData#state.server, From, Caps),
NewAvailable = case exmpp_presence:get_type(Packet) of
'unavailable' ->
?DICT:erase(LFrom, StateData#state.pres_available);
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 3240aa6e2..9d7846a48 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -48,8 +48,9 @@
code_change/3
]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-define(PROCNAME, ejabberd_mod_caps).
-define(DICT, dict).
@@ -61,29 +62,26 @@
disco_requests = ?DICT:new(),
feature_queries = []}).
+% XXX OLD FORMAT: Re-include jlib.hrl (after clean-up).
+-record(iq, {id = "",
+ type,
+ xmlns = "",
+ lang = "",
+ sub_el}).
+
%% read_caps takes a list of XML elements (the child elements of a
%% stanza) and returns an opaque value representing the
%% Entity Capabilities contained therein, or the atom nothing if no
%% capabilities are advertised.
read_caps(Els) ->
read_caps(Els, nothing).
-read_caps([{xmlelement, "c", Attrs, _Els} | Tail], Result) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_CAPS ->
- Node = xml:get_attr_s("node", Attrs),
- Version = xml:get_attr_s("ver", Attrs),
- Exts = string:tokens(xml:get_attr_s("ext", Attrs), " "),
- read_caps(Tail, #caps{node = Node, version = Version, exts = Exts});
- _ ->
- read_caps(Tail, Result)
- end;
-read_caps([{xmlelement, "x", Attrs, _Els} | Tail], Result) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_MUC_USER ->
- nothing;
- _ ->
- read_caps(Tail, Result)
- end;
+read_caps([#xmlel{ns = ?NS_CAPS, name = 'c'} = El | Tail], _Result) ->
+ Node = exmpp_xml:get_attribute(El, 'node'),
+ Version = exmpp_xml:get_attribute(El, 'ver'),
+ Exts = string:tokens(exmpp_xml:get_attribute(El, 'ext'), " "),
+ read_caps(Tail, #caps{node = Node, version = Version, exts = Exts});
+read_caps([#xmlel{ns = ?NS_MUC_USER, name = 'x'} | _Tail], _Result) ->
+ nothing;
read_caps([_ | Tail], Result) ->
read_caps(Tail, Result);
read_caps([], Result) ->
@@ -210,17 +208,14 @@ handle_cast({note_caps, From,
lists:foldl(
fun(SubNode, Dict) ->
ID = randoms:get_string(),
- Stanza =
- {xmlelement, "iq",
- [{"type", "get"},
- {"id", ID}],
- [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_INFO},
- {"node", lists:concat([Node, "#", SubNode])}],
- []}]},
+ Query = exmpp_xml:set_attribute(
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'query'},
+ 'node', lists:concat([Node, "#", SubNode])),
+ Stanza = exmpp_iq:get(?NS_JABBER_CLIENT, Query, ID),
ejabberd_local:register_iq_response_handler
(Host, ID, ?MODULE, handle_disco_response),
- ejabberd_router:route(jlib:make_jid("", Host, ""), From, Stanza),
+ ejabberd_router:route(exmpp_jid:make_bare_jid(Host),
+ From, Stanza),
timer:send_after(?CAPS_QUERY_TIMEOUT, self(), {disco_timeout, ID}),
?DICT:store(ID, {Node, SubNode}, Dict)
end, Requests, Missing),
@@ -301,7 +296,7 @@ handle_cast(visit_feature_queries, #state{feature_queries = FeatureQueries} = St
{noreply, State#state{feature_queries = NewFeatureQueries}}.
handle_disco_response(From, To, IQ) ->
- #jid{lserver = Host} = To,
+ #jid{ldomain = Host} = To,
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:cast(Proc, {disco_response, From, To, IQ}).
From 07b1210b50771e10fec1500a5cc1830d26de052f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Thu, 17 Jul 2008 15:33:50 +0000
Subject: [PATCH 044/582] Merge revisions from 1444 to revision 1457 from
trunk.
SVN Revision: 1458
---
ChangeLog | 39 ++++++++++
doc/guide.html | 23 +++---
doc/guide.tex | 23 +++---
src/Makefile.in | 11 ++-
{include => src}/adhoc.hrl | 0
{include => src}/ejabberd.hrl | 0
src/ejabberd_auth_ldap.erl | 2 +-
src/ejabberd_c2s.erl | 9 ++-
{include => src}/ejabberd_config.hrl | 0
{include => src}/ejabberd_ctl.hrl | 0
src/ejabberd_receiver.erl | 6 +-
src/ejabberd_sm.erl | 15 +---
src/ejabberd_zlib/Makefile.in | 3 +-
src/ejabberdctl.template | 45 ++++++------
src/eldap/Makefile.in | 3 +-
{include => src/eldap}/eldap.hrl | 0
{include => src}/jlib.hrl | 0
src/mod_irc/Makefile.in | 2 +-
src/mod_muc/Makefile.in | 2 +-
src/mod_offline.erl | 4 +-
src/mod_offline_odbc.erl | 4 +-
{include => src}/mod_privacy.hrl | 0
src/mod_proxy65/Makefile.in | 2 +-
{include => src/mod_proxy65}/mod_proxy65.hrl | 0
src/mod_pubsub/Makefile.in | 2 +-
{include => src/mod_pubsub}/pubsub.hrl | 0
src/mod_roster.erl | 4 +-
{include => src}/mod_roster.hrl | 0
src/mod_roster_odbc.erl | 4 +-
src/mod_shared_roster.erl | 4 +-
src/mod_vcard_ldap.erl | 2 +-
src/odbc/Makefile.in | 2 +-
src/pam/Makefile.in | 2 +-
src/stringprep/Makefile.in | 4 +-
src/tls/Makefile.in | 2 +-
src/web/Makefile.in | 3 +-
{include => src/web}/ejabberd_http.hrl | 0
src/web/ejabberd_http_poll.erl | 76 +++++++++-----------
{include => src/web}/ejabberd_web_admin.hrl | 0
39 files changed, 166 insertions(+), 132 deletions(-)
rename {include => src}/adhoc.hrl (100%)
rename {include => src}/ejabberd.hrl (100%)
rename {include => src}/ejabberd_config.hrl (100%)
rename {include => src}/ejabberd_ctl.hrl (100%)
rename {include => src/eldap}/eldap.hrl (100%)
rename {include => src}/jlib.hrl (100%)
rename {include => src}/mod_privacy.hrl (100%)
rename {include => src/mod_proxy65}/mod_proxy65.hrl (100%)
rename {include => src/mod_pubsub}/pubsub.hrl (100%)
rename {include => src}/mod_roster.hrl (100%)
rename {include => src/web}/ejabberd_http.hrl (100%)
rename {include => src/web}/ejabberd_web_admin.hrl (100%)
diff --git a/ChangeLog b/ChangeLog
index 8fe09d32c..07524ef9b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,48 @@
+2008-07-17 Jean-Sébastien Pédron
+
+ Merge revisions from 1444 to revision 1457 from trunk.
+
2008-07-17 Jean-Sébastien Pédron
* src/mod_caps.erl, src/ejabberd_c2s.erl: Start conversion to exmpp.
For now, only direct calls from ejabberd_c2s are done. Calls through
gen_iq_handler aren't.
+2008-07-17 Christophe Romain
+
+ * src/web/Makefile.in: use -DSSL39 if compiling with R12
+
+2008-07-16 Badlop
+
+ * src/ejabberd_c2s.erl: Put auth_module in Info always (EJAB-549)
+
+ * src/*.hrl: Get back all ejabberd header files to their original
+ placement in src/ subdirectories (EJAB-696)
+ * src/*/*.erl: Likewise
+ * src/*/Makefile.in: Likewise
+ * src/Makefile.in: Install header files in system include/ dir,
+ reproducing the subdirectory structure of src/
+
+ * src/ejabberdctl.template: Update environment variable names
+
+2008-07-15 Badlop
+
+ * src/ejabberdctl.template: Small fix so arguments of the command
+ are also passed to erl
+
+ * doc/guide.tex: Improve explanation of option 'hosts' in
+ ejabberd_service
+ * doc/guide.html: Likewise
+
+2008-07-15 Alexey Shchepin
+
+ * src/web/ejabberd_http_poll.erl: Report connection's IP address
+
+ * src/ejabberd_c2s.erl: Rolled back the previous IP getting patch
+ * src/ejabberd_sm.erl: Likewise
+ * src/ejabberd_receiver.erl: Likewise
+ * src/web/ejabberd_http_poll.erl: Likewise
+
2008-07-15 Jean-Sébastien Pédron
Merge revisions from 1434 to revision 1444 from trunk.
diff --git a/doc/guide.html b/doc/guide.html
index 735fc1f8c..02ea12132 100644
--- a/doc/guide.html
+++ b/doc/guide.html
@@ -637,9 +637,14 @@ This option can be used with ejabberd_service only. It is
used to disable control on the from field on packets send by an
external components. The option can be either true or
false. The default value is true which conforms to XEP-0114.
- - {hosts, [Hostnames], [HostOptions]}
- This option
-defines one or more hostnames of connected services and enables you to
-specify additional options including {password, Secret}.
+
- {hosts, [Hostnames], [HostOptions]}
-
+This option of ejabberd_service allows to define one or more hostnames
+of external Jabber components that provide a service.
+In HostOptions it is possible to define the password required to those components
+when attempt to connect to ejabberd: {password, Secret}.
+Note that you cannot define in a single ejabberd_service components of
+different services: add an ejabberd_service for each service,
+as seen in an example below.
- http_bind
-
This option enables HTTP Binding (XEP-0124 and XEP-0206) support. HTTP Bind
enables access via HTTP requests to ejabberd from behind firewalls which
@@ -818,19 +823,19 @@ connected to port 5237 with password ‘ggsecret’.
ssl, {certfile, "/path/to/ssl.pem"}]},
{5269, ejabberd_s2s_in, []},
{5280, ejabberd_http, [http_poll, web_admin]},
- {5233, ejabberd_service, [{host, "aim.example.org",
+ {5233, ejabberd_service, [{hosts, ["aim.example.org"],
[{password, "aimsecret"}]}]},
{5234, ejabberd_service, [{hosts, ["icq.example.org", "sms.example.org"],
[{password, "jitsecret"}]}]},
- {5235, ejabberd_service, [{host, "msn.example.org",
+ {5235, ejabberd_service, [{hosts, ["msn.example.org"],
[{password, "msnsecret"}]}]},
- {5236, ejabberd_service, [{host, "yahoo.example.org",
+ {5236, ejabberd_service, [{hosts, ["yahoo.example.org"],
[{password, "yahoosecret"}]}]},
- {5237, ejabberd_service, [{host, "gg.example.org",
+ {5237, ejabberd_service, [{hosts, ["gg.example.org"],
[{password, "ggsecret"}]}]},
- {5238, ejabberd_service, [{host, "jmc.example.org",
+ {5238, ejabberd_service, [{hosts, ["jmc.example.org"],
[{password, "jmcsecret"}]}]},
- {5239, ejabberd_service, [{host, "custom.example.org",
+ {5239, ejabberd_service, [{hosts, ["custom.example.org"],
[{password, "customsecret"}]},
{service_check_from, false}]}
]
diff --git a/doc/guide.tex b/doc/guide.tex
index 3831ac024..17cfbeb80 100644
--- a/doc/guide.tex
+++ b/doc/guide.tex
@@ -748,9 +748,14 @@ This is a detailed description of each option allowed by the listening modules:
used to disable control on the from field on packets send by an
external components. The option can be either \term{true} or
\term{false}. The default value is \term{true} which conforms to \xepref{0114}.
- \titem{\{hosts, [Hostnames], [HostOptions]\}} \ind{options!hosts}This option
- defines one or more hostnames of connected services and enables you to
- specify additional options including \poption{\{password, Secret\}}.
+ \titem{\{hosts, [Hostnames], [HostOptions]\}} \ind{options!hosts}
+ This option of \term{ejabberd\_service} allows to define one or more hostnames
+ of external Jabber components that provide a service.
+ In \term{HostOptions} it is possible to define the password required to those components
+ when attempt to connect to ejabberd: \poption{\{password, Secret\}}.
+ Note that you cannot define in a single \term{ejabberd\_service} components of
+ different services: add an \term{ejabberd\_service} for each service,
+ as seen in an example below.
\titem{http\_bind} \ind{options!http\_bind}\ind{protocols!XEP-0206: HTTP Binding}\ind{JWChat}\ind{web-based Jabber client}
This option enables HTTP Binding (\xepref{0124} and \xepref{0206}) support. HTTP Bind
enables access via HTTP requests to \ejabberd{} from behind firewalls which
@@ -945,19 +950,19 @@ In this example, the following configuration defines that:
ssl, {certfile, "/path/to/ssl.pem"}]},
{5269, ejabberd_s2s_in, []},
{5280, ejabberd_http, [http_poll, web_admin]},
- {5233, ejabberd_service, [{host, "aim.example.org",
+ {5233, ejabberd_service, [{hosts, ["aim.example.org"],
[{password, "aimsecret"}]}]},
{5234, ejabberd_service, [{hosts, ["icq.example.org", "sms.example.org"],
[{password, "jitsecret"}]}]},
- {5235, ejabberd_service, [{host, "msn.example.org",
+ {5235, ejabberd_service, [{hosts, ["msn.example.org"],
[{password, "msnsecret"}]}]},
- {5236, ejabberd_service, [{host, "yahoo.example.org",
+ {5236, ejabberd_service, [{hosts, ["yahoo.example.org"],
[{password, "yahoosecret"}]}]},
- {5237, ejabberd_service, [{host, "gg.example.org",
+ {5237, ejabberd_service, [{hosts, ["gg.example.org"],
[{password, "ggsecret"}]}]},
- {5238, ejabberd_service, [{host, "jmc.example.org",
+ {5238, ejabberd_service, [{hosts, ["jmc.example.org"],
[{password, "jmcsecret"}]}]},
- {5239, ejabberd_service, [{host, "custom.example.org",
+ {5239, ejabberd_service, [{hosts, ["custom.example.org"],
[{password, "customsecret"}]},
{service_check_from, false}]}
]
diff --git a/src/Makefile.in b/src/Makefile.in
index 3d398f569..5dabf5431 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -29,7 +29,6 @@ else
endif
EFLAGS += @ERLANG_SSL39@
-EFLAGS += -I ../include
# make debug=true to compile Erlang module with debug informations.
ifdef debug
@@ -189,7 +188,15 @@ install: all
#
# ejabberd header files
install -d $(INCLUDEDIR)
- install -m 644 ../include/*.hrl $(INCLUDEDIR)
+ install -m 644 *.hrl $(INCLUDEDIR)
+ install -d $(INCLUDEDIR)/eldap/
+ install -m 644 eldap/*.hrl $(INCLUDEDIR)/eldap/
+ install -d $(INCLUDEDIR)/mod_proxy65/
+ install -m 644 mod_proxy65/*.hrl $(INCLUDEDIR)/mod_proxy65/
+ install -d $(INCLUDEDIR)/mod_pubsub/
+ install -m 644 mod_pubsub/*.hrl $(INCLUDEDIR)/mod_pubsub/
+ install -d $(INCLUDEDIR)/web/
+ install -m 644 web/*.hrl $(INCLUDEDIR)/web/
#
# Binary C programs
install -d $(PBINDIR)
diff --git a/include/adhoc.hrl b/src/adhoc.hrl
similarity index 100%
rename from include/adhoc.hrl
rename to src/adhoc.hrl
diff --git a/include/ejabberd.hrl b/src/ejabberd.hrl
similarity index 100%
rename from include/ejabberd.hrl
rename to src/ejabberd.hrl
diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl
index b9bf3b477..d576a82fd 100644
--- a/src/ejabberd_auth_ldap.erl
+++ b/src/ejabberd_auth_ldap.erl
@@ -58,7 +58,7 @@
]).
-include("ejabberd.hrl").
--include("eldap.hrl").
+-include("eldap/eldap.hrl").
-record(state, {host,
eldap_id,
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 8c35273a7..da1239064 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1221,9 +1221,6 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
handle_info({'DOWN', Monitor, _Type, _Object, _Info}, _StateName, StateData)
when Monitor == StateData#state.socket_monitor ->
{stop, normal, StateData};
-handle_info({peername, IP}, StateName, StateData) ->
- ejabberd_sm:set_session_ip(StateData#state.sid, IP),
- fsm_next_state(StateName, StateData#state{ip = IP});
handle_info(Info, StateName, StateData) ->
?ERROR_MSG("Unexpected info: ~p", [Info]),
fsm_next_state(StateName, StateData).
@@ -1420,7 +1417,8 @@ presence_update(From, Packet, StateData) ->
undefined -> "";
S -> S
end,
- Info = [{ip, StateData#state.ip},{conn, StateData#state.conn}],
+ Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
+ {auth_module, StateData#state.auth_module}],
ejabberd_sm:unset_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
@@ -1804,7 +1802,8 @@ roster_change(IJID, ISubscription, StateData) ->
update_priority(Priority, Packet, StateData) ->
- Info = [{ip, StateData#state.ip},{conn, StateData#state.conn}],
+ Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
+ {auth_module, StateData#state.auth_module}],
ejabberd_sm:set_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
diff --git a/include/ejabberd_config.hrl b/src/ejabberd_config.hrl
similarity index 100%
rename from include/ejabberd_config.hrl
rename to src/ejabberd_config.hrl
diff --git a/include/ejabberd_ctl.hrl b/src/ejabberd_ctl.hrl
similarity index 100%
rename from include/ejabberd_ctl.hrl
rename to src/ejabberd_ctl.hrl
diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl
index 3b6c80439..5fdad76af 100644
--- a/src/ejabberd_receiver.erl
+++ b/src/ejabberd_receiver.erl
@@ -268,8 +268,7 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
activate_socket(#state{socket = Socket,
- sock_mod = SockMod,
- c2s_pid = C2SPid}) ->
+ sock_mod = SockMod}) ->
PeerName =
case SockMod of
gen_tcp ->
@@ -282,8 +281,7 @@ activate_socket(#state{socket = Socket,
case PeerName of
{error, _Reason} ->
self() ! {tcp_closed, Socket};
- {ok, IP} ->
- C2SPid ! {peername, IP},
+ {ok, _} ->
ok
end.
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index ccf679386..9300958d5 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -49,8 +49,7 @@
ctl_process/2,
get_session_pid/3,
get_user_info/3,
- get_user_ip/3,
- set_session_ip/2
+ get_user_ip/3
]).
%% gen_server callbacks
@@ -187,18 +186,6 @@ get_user_info(User, Server, Resource) ->
[{node, Node}, {conn, Conn}, {ip, IP}]
end.
-set_session_ip(SID, IP) ->
- case mnesia:dirty_read(session, SID) of
- [#session{info = Info} = Session] ->
- NewInfo = case lists:keymember(ip, 1, Info) of
- true -> lists:keyreplace(ip, 1, Info, {ip, IP});
- false -> [{ip, IP}|Info]
- end,
- mnesia:dirty_write(Session#session{info = NewInfo});
- _ ->
- ok
- end.
-
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
set_session(SID, User, Server, Resource, Priority, Info),
% XXX OLD FORMAT: Presence.
diff --git a/src/ejabberd_zlib/Makefile.in b/src/ejabberd_zlib/Makefile.in
index 3a70186bd..dd781d0ae 100644
--- a/src/ejabberd_zlib/Makefile.in
+++ b/src/ejabberd_zlib/Makefile.in
@@ -19,8 +19,9 @@ else
DYNAMIC_LIB_CFLAGS = -fpic -shared
endif
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/ejabberdctl.template b/src/ejabberdctl.template
index fcf0a80cc..02ebd56b5 100644
--- a/src/ejabberdctl.template
+++ b/src/ejabberdctl.template
@@ -15,12 +15,12 @@ ERL=@erl@
INSTALLUSER=@installuser@
ETCDIR=@SYSCONFDIR@/ejabberd
EJABBERD_CONFIG_PATH=$ETCDIR/ejabberd.cfg
-LOGDIR=@LOCALSTATEDIR@/log/ejabberd
+LOGS_DIR=@LOCALSTATEDIR@/log/ejabberd
SPOOLDIR=@LOCALSTATEDIR@/lib/ejabberd
# read custom configuration
-CONFIG=$ETCDIR/ejabberdctl.cfg
-[ -f "$CONFIG" ] && . "$CONFIG"
+EJABBERDCTL_CONFIG_PATH=$ETCDIR/ejabberdctl.cfg
+[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
# parse command line parameters
ARGS=
@@ -31,8 +31,8 @@ while [ $# -ne 0 ] ; do
--) break ;;
--node) ERLANG_NODE=$1; shift ;;
--config) EJABBERD_CONFIG_PATH=$1 ; shift ;;
- --ctl-config) CONFIG=$1 ; shift ;;
- --logs) LOGDIR=$1 ; shift ;;
+ --ctl-config) EJABBERDCTL_CONFIG_PATH=$1 ; shift ;;
+ --logs) LOGS_DIR=$1 ; shift ;;
--spool) SPOOLDIR=$1 ; shift ;;
*) ARGS="$ARGS $PARAM" ;;
esac
@@ -66,16 +66,16 @@ ERLANG_OPTS="+K $POLL -smp $SMP +P $ERL_PROCESSES $KERNEL_OPTS"
# define additional environment variables
EJABBERDDIR=@LIBDIR@/ejabberd
-BEAMDIR=$EJABBERDDIR/ebin
-PRIVDIR=$EJABBERDDIR/priv
-PBINDIR=$PRIVDIR/bin
-SODIR=$PRIVDIR/lib
-MSGSDIR=$PRIVDIR/msgs
+EJABBERD_EBIN_PATH=$EJABBERDDIR/ebin
+EJABBERD_PRIV_PATH=$EJABBERDDIR/priv
+EJABBERD_BIN_PATH=$EJABBERD_PRIV_PATH/bin
+EJABBERD_SO_PATH=$EJABBERD_PRIV_PATH/lib
+EJABBERD_MSGS_PATH=$EJABBERD_PRIV_PATH/msgs
-EJABBERD_LOG_PATH=$LOGDIR/ejabberd.log
-SASL_LOG_PATH=$LOGDIR/sasl.log
+EJABBERD_LOG_PATH=$LOGS_DIR/ejabberd.log
+SASL_LOG_PATH=$LOGS_DIR/sasl.log
DATETIME=`date "+%Y%m%d-%H%M%S"`
-ERL_CRASH_DUMP=$LOGDIR/erl_crash_$DATETIME.dump
+ERL_CRASH_DUMP=$LOGS_DIR/erl_crash_$DATETIME.dump
ERL_INETRC=$ETCDIR/inetrc
HOME=$SPOOLDIR
@@ -84,10 +84,10 @@ HOME=$SPOOLDIR
# export global variables
export EJABBERD_CONFIG_PATH
-export MSGSDIR
+export EJABBERD_MSGS_PATH
export EJABBERD_LOG_PATH
-export SODIR
-export PBINDIR
+export EJABBERD_SO_PATH
+export EJABBERD_BIN_PATH
export ERL_CRASH_DUMP
export ERL_INETRC
export ERL_MAX_PORTS
@@ -105,7 +105,7 @@ start ()
$EXEC_CMD "$ERL \
$NAME $ERLANG_NODE \
-noinput -detached \
- -pa $BEAMDIR \
+ -pa $EJABBERD_EBIN_PATH \
-mnesia dir \"\\\"$SPOOLDIR\\\"\" \
-s ejabberd \
-sasl sasl_error_logger \\{file,\\\"$SASL_LOG_PATH\\\"\\} \
@@ -157,7 +157,7 @@ live ()
echo ""
$EXEC_CMD "$ERL \
$NAME $ERLANG_NODE \
- -pa $BEAMDIR \
+ -pa $EJABBERD_EBIN_PATH \
-mnesia dir \"\\\"$SPOOLDIR\\\"\" \
-s ejabberd \
$ERLANG_OPTS $ARGS \"$@\""
@@ -166,11 +166,12 @@ live ()
# common control function
ctl ()
{
+ COMMAND=$@
$EXEC_CMD "$ERL \
$NAME ejabberdctl \
-noinput \
- -pa $BEAMDIR \
- -s ejabberd_ctl -extra $ERLANG_NODE $@"
+ -pa $EJABBERD_EBIN_PATH \
+ -s ejabberd_ctl -extra $ERLANG_NODE $COMMAND"
result=$?
case $result in
0) :;;
@@ -183,8 +184,8 @@ ctl ()
echo ""
echo "Optional parameters when starting an ejabberd node:"
echo " --config file Config file of ejabberd: $EJABBERD_CONFIG_PATH"
- echo " --ctl-config file Config file of ejabberdctl: $CONFIG"
- echo " --logs dir Directory for logs: $LOGDIR"
+ echo " --ctl-config file Config file of ejabberdctl: $EJABBERDCTL_CONFIG_PATH"
+ echo " --logs dir Directory for logs: $LOGS_DIR"
echo " --spool dir Database spool dir: $SPOOLDIR"
echo " --node nodename ejabberd node name: $ERLANG_NODE"
echo "";;
diff --git a/src/eldap/Makefile.in b/src/eldap/Makefile.in
index 4c9c33c22..22cdad48b 100644
--- a/src/eldap/Makefile.in
+++ b/src/eldap/Makefile.in
@@ -9,8 +9,9 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/include/eldap.hrl b/src/eldap/eldap.hrl
similarity index 100%
rename from include/eldap.hrl
rename to src/eldap/eldap.hrl
diff --git a/include/jlib.hrl b/src/jlib.hrl
similarity index 100%
rename from include/jlib.hrl
rename to src/jlib.hrl
diff --git a/src/mod_irc/Makefile.in b/src/mod_irc/Makefile.in
index 86212e45c..76a2d57f6 100644
--- a/src/mod_irc/Makefile.in
+++ b/src/mod_irc/Makefile.in
@@ -16,7 +16,7 @@ else
DYNAMIC_LIB_CFLAGS = -fpic -shared
endif
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
diff --git a/src/mod_muc/Makefile.in b/src/mod_muc/Makefile.in
index 80725d33d..5ede5e521 100644
--- a/src/mod_muc/Makefile.in
+++ b/src/mod_muc/Makefile.in
@@ -9,7 +9,7 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index 3db29844b..3a751c328 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -43,8 +43,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
--include("ejabberd_http.hrl").
--include("ejabberd_web_admin.hrl").
+-include("web/ejabberd_http.hrl").
+-include("web/ejabberd_web_admin.hrl").
-record(offline_msg, {us, timestamp, expire, from, to, packet}).
diff --git a/src/mod_offline_odbc.erl b/src/mod_offline_odbc.erl
index 79d7c51ae..c3d0513d0 100644
--- a/src/mod_offline_odbc.erl
+++ b/src/mod_offline_odbc.erl
@@ -42,8 +42,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
--include("ejabberd_http.hrl").
--include("ejabberd_web_admin.hrl").
+-include("web/ejabberd_http.hrl").
+-include("web/ejabberd_web_admin.hrl").
-record(offline_msg, {user, timestamp, expire, from, to, packet}).
diff --git a/include/mod_privacy.hrl b/src/mod_privacy.hrl
similarity index 100%
rename from include/mod_privacy.hrl
rename to src/mod_privacy.hrl
diff --git a/src/mod_proxy65/Makefile.in b/src/mod_proxy65/Makefile.in
index 62ae77c9f..3fc94c662 100644
--- a/src/mod_proxy65/Makefile.in
+++ b/src/mod_proxy65/Makefile.in
@@ -9,7 +9,7 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
diff --git a/include/mod_proxy65.hrl b/src/mod_proxy65/mod_proxy65.hrl
similarity index 100%
rename from include/mod_proxy65.hrl
rename to src/mod_proxy65/mod_proxy65.hrl
diff --git a/src/mod_pubsub/Makefile.in b/src/mod_pubsub/Makefile.in
index 25dbf57a5..4088303cb 100644
--- a/src/mod_pubsub/Makefile.in
+++ b/src/mod_pubsub/Makefile.in
@@ -9,7 +9,7 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
diff --git a/include/pubsub.hrl b/src/mod_pubsub/pubsub.hrl
similarity index 100%
rename from include/pubsub.hrl
rename to src/mod_pubsub/pubsub.hrl
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index c1569bb61..038de586a 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -47,8 +47,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("mod_roster.hrl").
--include("ejabberd_http.hrl").
--include("ejabberd_web_admin.hrl").
+-include("web/ejabberd_http.hrl").
+-include("web/ejabberd_web_admin.hrl").
start(Host, Opts) ->
diff --git a/include/mod_roster.hrl b/src/mod_roster.hrl
similarity index 100%
rename from include/mod_roster.hrl
rename to src/mod_roster.hrl
diff --git a/src/mod_roster_odbc.erl b/src/mod_roster_odbc.erl
index dfb76dcbe..d38121560 100644
--- a/src/mod_roster_odbc.erl
+++ b/src/mod_roster_odbc.erl
@@ -46,8 +46,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("mod_roster.hrl").
--include("ejabberd_http.hrl").
--include("ejabberd_web_admin.hrl").
+-include("web/ejabberd_http.hrl").
+-include("web/ejabberd_web_admin.hrl").
start(Host, Opts) ->
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index f363bd22e..ff378010d 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -52,8 +52,8 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("mod_roster.hrl").
--include("ejabberd_http.hrl").
--include("ejabberd_web_admin.hrl").
+-include("web/ejabberd_http.hrl").
+-include("web/ejabberd_web_admin.hrl").
-record(sr_group, {group_host, opts}).
-record(sr_user, {us, group_host}).
diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl
index 2225f7c86..2b5e7faac 100644
--- a/src/mod_vcard_ldap.erl
+++ b/src/mod_vcard_ldap.erl
@@ -50,7 +50,7 @@
]).
-include("ejabberd.hrl").
--include("eldap.hrl").
+-include("eldap/eldap.hrl").
-include("jlib.hrl").
-define(PROCNAME, ejabberd_mod_vcard_ldap).
diff --git a/src/odbc/Makefile.in b/src/odbc/Makefile.in
index 5bd130b6e..3f4898d3a 100644
--- a/src/odbc/Makefile.in
+++ b/src/odbc/Makefile.in
@@ -9,7 +9,7 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
diff --git a/src/pam/Makefile.in b/src/pam/Makefile.in
index 57c1ab78a..bde289402 100644
--- a/src/pam/Makefile.in
+++ b/src/pam/Makefile.in
@@ -9,7 +9,7 @@ LIBS = @LIBS@ @PAM_LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
diff --git a/src/stringprep/Makefile.in b/src/stringprep/Makefile.in
index 248aee693..3ac6c24db 100644
--- a/src/stringprep/Makefile.in
+++ b/src/stringprep/Makefile.in
@@ -16,7 +16,9 @@ else
DYNAMIC_LIB_CFLAGS = -fpic -shared
endif
-EFLAGS = -I .. -pz ..
+EFLAGS += -I ..
+EFLAGS += -pz ..
+
# make debug=true to compile Erlang module with debug informations.
ifdef debug
EFLAGS+=+debug_info
diff --git a/src/tls/Makefile.in b/src/tls/Makefile.in
index db4a874e1..b6f10efc2 100644
--- a/src/tls/Makefile.in
+++ b/src/tls/Makefile.in
@@ -19,7 +19,7 @@ else
DYNAMIC_LIB_CFLAGS = -fpic -shared
endif
-EFLAGS += -I ../../include
+EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
diff --git a/src/web/Makefile.in b/src/web/Makefile.in
index 3a75f7e17..21f7c9348 100644
--- a/src/web/Makefile.in
+++ b/src/web/Makefile.in
@@ -9,7 +9,8 @@ LIBS = @LIBS@
ERLANG_CFLAGS = @ERLANG_CFLAGS@
ERLANG_LIBS = @ERLANG_LIBS@
-EFLAGS += -I ../../include
+EFLAGS += @ERLANG_SSL39@
+EFLAGS += -I ..
EFLAGS += -pz ..
# make debug=true to compile Erlang module with debug informations.
diff --git a/include/ejabberd_http.hrl b/src/web/ejabberd_http.hrl
similarity index 100%
rename from include/ejabberd_http.hrl
rename to src/web/ejabberd_http.hrl
diff --git a/src/web/ejabberd_http_poll.erl b/src/web/ejabberd_http_poll.erl
index ad6c46b77..2b36136cd 100644
--- a/src/web/ejabberd_http_poll.erl
+++ b/src/web/ejabberd_http_poll.erl
@@ -30,7 +30,7 @@
-behaviour(gen_fsm).
%% External exports
--export([start_link/2,
+-export([start_link/3,
init/1,
handle_event/3,
handle_sync_event/4,
@@ -50,16 +50,14 @@
-record(http_poll, {id, pid}).
--define(NULL_PEER, {{0, 0, 0, 0}, 0}).
-
-record(state, {id,
key,
+ socket,
output = "",
input = "",
waiting_input = false, %% {ReceiverPid, Tag}
last_receiver,
- timer,
- ip = ?NULL_PEER }).
+ timer}).
%-define(DBGFSM, true).
@@ -77,19 +75,19 @@
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
-start(ID, Key) ->
+start(ID, Key, IP) ->
mnesia:create_table(http_poll,
[{ram_copies, [node()]},
{attributes, record_info(fields, http_poll)}]),
- supervisor:start_child(ejabberd_http_poll_sup, [ID, Key]).
+ supervisor:start_child(ejabberd_http_poll_sup, [ID, Key, IP]).
-start_link(ID, Key) ->
- gen_fsm:start_link(?MODULE, [ID, Key], ?FSMOPTS).
+start_link(ID, Key, IP) ->
+ gen_fsm:start_link(?MODULE, [ID, Key, IP], ?FSMOPTS).
-send({http_poll, FsmRef}, Packet) ->
+send({http_poll, FsmRef, _IP}, Packet) ->
gen_fsm:sync_send_all_state_event(FsmRef, {send, Packet}).
-setopts({http_poll, FsmRef}, Opts) ->
+setopts({http_poll, FsmRef, _IP}, Opts) ->
case lists:member({active, once}, Opts) of
true ->
gen_fsm:send_all_state_event(FsmRef, {activate, self()});
@@ -97,31 +95,27 @@ setopts({http_poll, FsmRef}, Opts) ->
ok
end.
-sockname(_) ->
- {ok, ?NULL_PEER}.
+sockname(_Socket) ->
+ {ok, {{0, 0, 0, 0}, 0}}.
-peername({http_poll, FsmRef}) ->
- case catch gen_fsm:sync_send_all_state_event(FsmRef, peername, 1000) of
- {ok, IP} -> {ok, IP};
- _ -> {ok, ?NULL_PEER}
- end;
-peername(_) ->
- {ok, ?NULL_PEER}.
+peername({http_poll, _FsmRef, IP}) ->
+ {ok, IP}.
controlling_process(_Socket, _Pid) ->
ok.
-close({http_poll, FsmRef}) ->
+close({http_poll, FsmRef, _IP}) ->
catch gen_fsm:sync_send_all_state_event(FsmRef, close).
-process([], #request{data = Data, ip = IP} = _Request) ->
+process([], #request{data = Data,
+ ip = IP} = _Request) ->
case catch parse_request(Data) of
{ok, ID1, Key, NewKey, Packet} ->
ID = if
(ID1 == "0") or (ID1 == "mobile") ->
NewID = sha:sha(term_to_binary({now(), make_ref()})),
- {ok, Pid} = start(NewID, ""),
+ {ok, Pid} = start(NewID, "", IP),
mnesia:transaction(
fun() ->
mnesia:write(#http_poll{id = NewID,
@@ -131,7 +125,7 @@ process([], #request{data = Data, ip = IP} = _Request) ->
true ->
ID1
end,
- case http_put(ID, Key, NewKey, Packet, IP) of
+ case http_put(ID, Key, NewKey, Packet) of
{error, not_exists} ->
{200, ?BAD_REQUEST, ""};
{error, bad_key} ->
@@ -176,8 +170,8 @@ process(_, _Request) ->
%% ignore |
%% {stop, StopReason}
%%----------------------------------------------------------------------
-init([ID, Key]) ->
- ?INFO_MSG("started: ~p", [{ID, Key}]),
+init([ID, Key, IP]) ->
+ ?INFO_MSG("started: ~p", [{ID, Key, IP}]),
%% Read c2s options from the first ejabberd_c2s configuration in
%% the config file listen section
@@ -187,12 +181,12 @@ init([ID, Key]) ->
%% connector.
Opts = ejabberd_c2s_config:get_c2s_limits(),
- ejabberd_socket:start(ejabberd_c2s, ?MODULE, {http_poll, self()}, Opts),
- %{ok, C2SPid} = ejabberd_c2s:start({?MODULE, {http_poll, self()}}, Opts),
- %ejabberd_c2s:become_controller(C2SPid),
+ Socket = {http_poll, self(), IP},
+ ejabberd_socket:start(ejabberd_c2s, ?MODULE, Socket, Opts),
Timer = erlang:start_timer(?HTTP_POLL_TIMEOUT, self(), []),
{ok, loop, #state{id = ID,
key = Key,
+ socket = Socket,
timer = Timer}}.
%%----------------------------------------------------------------------
@@ -229,7 +223,7 @@ handle_event({activate, From}, StateName, StateData) ->
StateData#state{waiting_input = {From, ok}}};
Input ->
Receiver = From,
- Receiver ! {tcp, {http_poll, self()}, list_to_binary(Input)},
+ Receiver ! {tcp, StateData#state.socket, list_to_binary(Input)},
{next_state, StateName, StateData#state{input = "",
waiting_input = false,
last_receiver = Receiver
@@ -257,7 +251,7 @@ handle_sync_event(stop, _From, _StateName, StateData) ->
Reply = ok,
{stop, normal, Reply, StateData};
-handle_sync_event({http_put, Key, NewKey, Packet, IP},
+handle_sync_event({http_put, Key, NewKey, Packet},
_From, StateName, StateData) ->
Allow = case StateData#state.key of
"" ->
@@ -279,10 +273,9 @@ handle_sync_event({http_put, Key, NewKey, Packet, IP},
Input = [StateData#state.input|Packet],
Reply = ok,
{reply, Reply, StateName, StateData#state{input = Input,
- key = NewKey,
- ip = IP}};
+ key = NewKey}};
{Receiver, _Tag} ->
- Receiver ! {tcp, {http_poll, self()},
+ Receiver ! {tcp, StateData#state.socket,
list_to_binary(Packet)},
cancel_timer(StateData#state.timer),
Timer = erlang:start_timer(?HTTP_POLL_TIMEOUT, self(), []),
@@ -291,8 +284,7 @@ handle_sync_event({http_put, Key, NewKey, Packet, IP},
StateData#state{waiting_input = false,
last_receiver = Receiver,
key = NewKey,
- timer = Timer,
- ip = IP}}
+ timer = Timer}}
end;
true ->
Reply = {error, bad_key},
@@ -303,10 +295,6 @@ handle_sync_event(http_get, _From, StateName, StateData) ->
Reply = {ok, StateData#state.output},
{reply, Reply, StateName, StateData#state{output = ""}};
-handle_sync_event(peername, _From, StateName, StateData) ->
- Reply = {ok, StateData#state.ip},
- {reply, Reply, StateName, StateData};
-
handle_sync_event(_Event, _From, StateName, StateData) ->
Reply = ok,
{reply, Reply, StateName, StateData}.
@@ -345,10 +333,10 @@ terminate(_Reason, _StateName, StateData) ->
case StateData#state.last_receiver of
undefined -> ok;
Receiver ->
- Receiver ! {tcp_closed, {http_poll, self()}}
+ Receiver ! {tcp_closed, StateData#state.socket}
end;
{Receiver, _Tag} ->
- Receiver ! {tcp_closed, {http_poll, self()}}
+ Receiver ! {tcp_closed, StateData#state.socket}
end,
catch resend_messages(StateData#state.output),
ok.
@@ -357,13 +345,13 @@ terminate(_Reason, _StateName, StateData) ->
%%% Internal functions
%%%----------------------------------------------------------------------
-http_put(ID, Key, NewKey, Packet, IP) ->
+http_put(ID, Key, NewKey, Packet) ->
case mnesia:dirty_read({http_poll, ID}) of
[] ->
{error, not_exists};
[#http_poll{pid = FsmRef}] ->
gen_fsm:sync_send_all_state_event(
- FsmRef, {http_put, Key, NewKey, Packet, IP})
+ FsmRef, {http_put, Key, NewKey, Packet})
end.
http_get(ID) ->
diff --git a/include/ejabberd_web_admin.hrl b/src/web/ejabberd_web_admin.hrl
similarity index 100%
rename from include/ejabberd_web_admin.hrl
rename to src/web/ejabberd_web_admin.hrl
From 75a8be230ba09219f4bd87b2e3bc1bf0ede0a919 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 21 Jul 2008 15:28:44 +0000
Subject: [PATCH 045/582] Prepare gen_iq_handler to pass arguments in the new
format to a built-in list of modules known to support them. Other modules
will still receive arguments in the old format.
SVN Revision: 1462
---
ChangeLog | 6 +++
src/gen_iq_handler.erl | 85 +++++++++++++++++++++++++++---------------
2 files changed, 60 insertions(+), 31 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 07524ef9b..20b91bbfc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-07-21 Jean-Sébastien Pédron
+
+ * src/gen_iq_handler.erl: Prepare gen_iq_handler to pass arguments in
+ the new format to a built-in list of modules known to support them.
+ Other modules will still receive arguments in the old format.
+
2008-07-17 Jean-Sébastien Pédron
Merge revisions from 1444 to revision 1457 from trunk.
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index e3da47f0c..11fba0929 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -56,6 +56,11 @@
lang = "",
sub_el}).
+% XXX OLD FORMAT: modules not in the following list will receive
+% old format strudctures.
+-define(CONVERTED_MODULES, [
+]).
+
%%====================================================================
%% API
%%====================================================================
@@ -110,37 +115,55 @@ handle(Host, Module, Function, Opts, From, To, IQ) ->
no_queue ->
process_iq(Host, Module, Function, From, To, IQ);
{one_queue, Pid} ->
- {FromOld, ToOld, IQ_Rec} = convert_to_old_structs(From, To, IQ),
- Pid ! {process_iq, FromOld, ToOld, IQ_Rec};
+ Pid ! {process_iq, From, To, IQ};
{queues, Pids} ->
Pid = lists:nth(erlang:phash(now(), length(Pids)), Pids),
- {FromOld, ToOld, IQ_Rec} = convert_to_old_structs(From, To, IQ),
- Pid ! {process_iq, FromOld, ToOld, IQ_Rec};
+ Pid ! {process_iq, From, To, IQ};
parallel ->
- spawn(?MODULE, process_iq, [Host, Module, Function, From, To, IQ]);
+ spawn(?MODULE, process_iq,
+ [Host, Module, Function, From, To, IQ]);
_ ->
todo
end.
+process_iq(Host, Module, Function, FromOld, ToOld, IQ_Rec)
+ when is_record(IQ_Rec, iq) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nIQ HANDLER: old #iq for ~s:~s:~n~p~n~p~n~n",
+ [Module, Function, IQ_Rec, erlang:get_stacktrace()]),
+ From = jlib:from_old_jid(FromOld),
+ To = jlib:from_old_jid(ToOld),
+ IQOld = jlib:iq_to_xml(IQ_Rec),
+ IQOld1 = IQOld#xmlelement{children = [IQOld#xmlelement.children]},
+ IQ = exmpp_xml:xmlelement_to_xmlel(IQOld1,
+ [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx},
+ {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
+ process_iq(Host, Module, Function, From, To, IQ);
process_iq(_Host, Module, Function, From, To, IQ) ->
- {FromOld, ToOld, IQ_Rec} = convert_to_old_structs(From, To, IQ),
- case catch Module:Function(FromOld, ToOld, IQ_Rec) of
+ Ret = case lists:member(Module, ?CONVERTED_MODULES) of
+ true ->
+ catch Module:Function(From, To, IQ);
+ false ->
+ {FromOld, ToOld, IQ_Rec} = convert_to_old_structs(
+ Module, Function, From, To, IQ),
+ catch Module:Function(FromOld, ToOld, IQ_Rec)
+ end,
+ case Ret of
{'EXIT', Reason} ->
?ERROR_MSG("~p", [Reason]);
- ResIQ ->
- if
- ResIQ /= ignore ->
- ReplyOld = jlib:iq_to_xml(ResIQ),
- Reply = exmpp_xml:xmlelement_to_xmlel(ReplyOld,
- [?NS_JABBER_CLIENT],
- [{?NS_XMPP, ?NS_XMPP_pfx},
- {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
- ejabberd_router:route(To, From,
- Reply);
- true ->
- ok
- end
+ ignore ->
+ ok;
+ ResIQ when is_record(ResIQ, iq) ->
+ ReplyOld = jlib:iq_to_xml(ResIQ),
+ Reply = exmpp_xml:xmlelement_to_xmlel(ReplyOld,
+ [?NS_JABBER_CLIENT],
+ [{?NS_XMPP, ?NS_XMPP_pfx},
+ {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
+ ejabberd_router:route(To, From, Reply);
+ Reply ->
+ ejabberd_router:route(To, From, Reply)
end.
%%====================================================================
@@ -217,16 +240,16 @@ code_change(_OldVsn, State, _Extra) ->
%%% Internal functions
%%--------------------------------------------------------------------
-convert_to_old_structs(From, To, IQ) ->
+convert_to_old_structs(Mod, Fun, From, To, IQ) ->
+ catch throw(for_stacktrace), % To have a stacktrace.
+ io:format("~nIQ HANDLER: ~s:~s expects old #iq:~n~p~n~p~n~n",
+ [Mod, Fun, IQ, erlang:get_stacktrace()]),
if
- is_record(IQ, iq) ->
- catch throw(for_stacktrace), % To have a stacktrace.
- io:format("~nIQ HANDLER: old #iq:~n~p~n~p~n~n",
- [IQ, erlang:get_stacktrace()]),
- {From, To, IQ};
- true ->
- F = jlib:to_old_jid(From),
- T = jlib:to_old_jid(To),
- I_Rec = jlib:iq_query_info(IQ),
- {F, T, I_Rec}
+ is_record(IQ, iq) ->
+ {From, To, IQ};
+ true ->
+ F = jlib:to_old_jid(From),
+ T = jlib:to_old_jid(To),
+ I_Rec = jlib:iq_query_info(IQ),
+ {F, T, I_Rec}
end.
From 6e91399922a988218f13384e9146e5124e34c86d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 21 Jul 2008 15:29:52 +0000
Subject: [PATCH 046/582] Convert to exmpp.
SVN Revision: 1463
---
ChangeLog | 2 +
src/gen_iq_handler.erl | 1 +
src/mod_roster.erl | 451 +++++++++++++++++++++--------------------
3 files changed, 230 insertions(+), 224 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 20b91bbfc..73c49c0ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,8 @@
the new format to a built-in list of modules known to support them.
Other modules will still receive arguments in the old format.
+ * src/mod_roster.erl, src/gen_iq_handler.erl: Convert to exmpp.
+
2008-07-17 Jean-Sébastien Pédron
Merge revisions from 1444 to revision 1457 from trunk.
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index 11fba0929..09318e058 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -59,6 +59,7 @@
% XXX OLD FORMAT: modules not in the following list will receive
% old format strudctures.
-define(CONVERTED_MODULES, [
+ mod_roster
]).
%%====================================================================
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 038de586a..4e7e5ecab 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -44,8 +44,9 @@
webadmin_page/3,
webadmin_user/4]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("mod_roster.hrl").
-include("web/ejabberd_http.hrl").
-include("web/ejabberd_web_admin.hrl").
@@ -77,7 +78,8 @@ start(Host, Opts) ->
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(webadmin_user, Host,
?MODULE, webadmin_user, 50),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
+ % XXX OLD FORMAT: NS as string.
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_ROSTER),
?MODULE, process_iq, IQDisc).
stop(Host) ->
@@ -101,21 +103,22 @@ stop(Host) ->
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(webadmin_user, Host,
?MODULE, webadmin_user, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
+ % XXX OLD FORMAT: NS as string.
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
+ atom_to_list(?NS_ROSTER)).
process_iq(From, To, IQ) ->
- #iq{sub_el = SubEl} = IQ,
- #jid{lserver = LServer} = From,
+ #jid{ldomain = LServer} = From,
case lists:member(LServer, ?MYHOSTS) of
true ->
process_local_iq(From, To, IQ);
_ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}
+ exmpp_iq:error(IQ, 'item-not-found')
end.
-process_local_iq(From, To, #iq{type = Type} = IQ) ->
- case Type of
+process_local_iq(From, To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
process_iq_set(From, To, IQ);
get ->
@@ -124,19 +127,17 @@ process_local_iq(From, To, #iq{type = Type} = IQ) ->
-process_iq_get(From, To, #iq{sub_el = SubEl} = IQ) ->
- LUser = From#jid.luser,
- LServer = From#jid.lserver,
+process_iq_get(From, To, IQ) ->
+ LUser = From#jid.lnode,
+ LServer = From#jid.ldomain,
US = {LUser, LServer},
- case catch ejabberd_hooks:run_fold(roster_get, To#jid.lserver, [], [US]) of
+ case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
Items when is_list(Items) ->
XItems = lists:map(fun item_to_xml/1, Items),
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- XItems}]};
+ exmpp_iq:result(IQ, #xmlel{ns = ?NS_ROSTER, name = 'query',
+ children = XItems});
_ ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
+ exmpp_iq:error(IQ, 'internal-server-error')
end.
get_user_roster(Acc, US) ->
@@ -153,139 +154,138 @@ get_user_roster(Acc, US) ->
item_to_xml(Item) ->
- Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}],
+ {U, S, R} = Item#roster.jid,
+ Attrs1 = exmpp_xml:set_attribute_in_list([],
+ 'jid', exmpp_jid:jid_to_string(U, S, R)),
Attrs2 = case Item#roster.name of
"" ->
Attrs1;
Name ->
- [{"name", Name} | Attrs1]
- end,
- Attrs3 = case Item#roster.subscription of
- none ->
- [{"subscription", "none"} | Attrs2];
- from ->
- [{"subscription", "from"} | Attrs2];
- to ->
- [{"subscription", "to"} | Attrs2];
- both ->
- [{"subscription", "both"} | Attrs2];
- remove ->
- [{"subscription", "remove"} | Attrs2]
+ exmpp_xml:set_attribute_in_list(Attrs1, 'name', Name)
end,
+ Attrs3 = exmpp_xml:set_attribute_in_list(Attrs2,
+ 'subscription', Item#roster.subscription),
Attrs4 = case ask_to_pending(Item#roster.ask) of
out ->
- [{"ask", "subscribe"} | Attrs3];
+ exmpp_xml:set_attribute_in_list(Attrs3,
+ 'ask', "subscribe");
both ->
- [{"ask", "subscribe"} | Attrs3];
+ exmpp_xml:set_attribute_in_list(Attrs3,
+ 'ask', "subscribe");
_ ->
Attrs3
end,
SubEls1 = lists:map(fun(G) ->
- {xmlelement, "group", [], [{xmlcdata, G}]}
+ exmpp_xml:set_cdata(
+ #xmlel{ns = ?NS_ROSTER, name = 'group'}, G)
end, Item#roster.groups),
SubEls = SubEls1 ++ Item#roster.xs,
- {xmlelement, "item", Attrs4, SubEls}.
+ #xmlel{ns = ?NS_ROSTER, name = 'item', attrs = Attrs4, children = SubEls}.
-process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els),
- IQ#iq{type = result, sub_el = []}.
-
-process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
- JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
- #jid{user = User, luser = LUser, lserver = LServer} = From,
- case JID1 of
- error ->
- ok;
+process_iq_set(From, To, IQ) ->
+ case exmpp_iq:get_request(IQ) of
+ #xmlel{children = Els} ->
+ lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els);
_ ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- LJID = jlib:jid_tolower(JID1),
- F = fun() ->
- Res = mnesia:read({roster, {LUser, LServer, LJID}}),
- Item = case Res of
- [] ->
- #roster{usj = {LUser, LServer, LJID},
- us = {LUser, LServer},
- jid = JID};
- [I] ->
- I#roster{jid = JID,
- name = "",
- groups = [],
- xs = []}
- end,
- Item1 = process_item_attrs(Item, Attrs),
- Item2 = process_item_els(Item1, Els),
- case Item2#roster.subscription of
- remove ->
- mnesia:delete({roster, {LUser, LServer, LJID}});
- _ ->
- mnesia:write(Item2)
- end,
- %% If the item exist in shared roster, take the
- %% subscription information from there:
- Item3 = ejabberd_hooks:run_fold(roster_process_item,
- LServer, Item2, [LServer]),
- {Item, Item3}
- end,
- case mnesia:transaction(F) of
- {atomic, {OldItem, Item}} ->
- push_item(User, LServer, To, Item),
- case Item#roster.subscription of
+ ok
+ end,
+ exmpp_iq:result(IQ).
+
+process_item_set(From, To, #xmlel{} = Item) ->
+ try
+ JID1 = exmpp_jid:string_to_jid(exmpp_xml:get_attribute(Item, 'jid')),
+ % XXX OLD FORMAT: old JID (with empty strings).
+ #jid{node = User, lnode = LUser, ldomain = LServer} =
+ jlib:to_old_jid(From),
+ JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
+ LJID = jlib:short_jid(JID1),
+ F = fun() ->
+ Res = mnesia:read({roster, {LUser, LServer, LJID}}),
+ Item = case Res of
+ [] ->
+ #roster{usj = {LUser, LServer, LJID},
+ us = {LUser, LServer},
+ jid = JID};
+ [I] ->
+ I#roster{jid = JID,
+ name = "",
+ groups = [],
+ xs = []}
+ end,
+ Item1 = process_item_attrs(Item, Item#xmlel.attrs),
+ Item2 = process_item_els(Item1, Item#xmlel.children),
+ case Item2#roster.subscription of
remove ->
- IsTo = case OldItem#roster.subscription of
- both -> true;
- to -> true;
- _ -> false
- end,
- IsFrom = case OldItem#roster.subscription of
- both -> true;
- from -> true;
- _ -> false
- end,
- if IsTo ->
- ejabberd_router:route(
- jlib:jid_remove_resource(From),
- jlib:make_jid(OldItem#roster.jid),
- {xmlelement, "presence",
- [{"type", "unsubscribe"}],
- []});
- true -> ok
- end,
- if IsFrom ->
- ejabberd_router:route(
- jlib:jid_remove_resource(From),
- jlib:make_jid(OldItem#roster.jid),
- {xmlelement, "presence",
- [{"type", "unsubscribed"}],
- []});
- true -> ok
- end,
- ok;
+ mnesia:delete({roster, {LUser, LServer, LJID}});
_ ->
- ok
- end;
- E ->
- ?DEBUG("ROSTER: roster item set error: ~p~n", [E]),
- ok
- end
+ mnesia:write(Item2)
+ end,
+ %% If the item exist in shared roster, take the
+ %% subscription information from there:
+ Item3 = ejabberd_hooks:run_fold(roster_process_item,
+ LServer, Item2, [LServer]),
+ {Item, Item3}
+ end,
+ case mnesia:transaction(F) of
+ {atomic, {OldItem, Item}} ->
+ push_item(User, LServer, To, Item),
+ case Item#roster.subscription of
+ remove ->
+ IsTo = case OldItem#roster.subscription of
+ both -> true;
+ to -> true;
+ _ -> false
+ end,
+ IsFrom = case OldItem#roster.subscription of
+ both -> true;
+ from -> true;
+ _ -> false
+ end,
+ {U, S, R} = OldItem#roster.jid,
+ if IsTo ->
+ ejabberd_router:route(
+ exmpp_jid:jid_to_bare_jid(From),
+ exmpp_jid:make_jid(U, S, R),
+ exmpp_presence:unsubscribe());
+ true -> ok
+ end,
+ if IsFrom ->
+ ejabberd_router:route(
+ exmpp_jid:jid_to_bare_jid(From),
+ exmpp_jid:make_jid(U, S, R),
+ exmpp_presence:unsubscribed());
+ true -> ok
+ end,
+ ok;
+ _ ->
+ ok
+ end;
+ E ->
+ ?DEBUG("ROSTER: roster item set error: ~p~n", [E]),
+ ok
+ end
+ catch
+ _ ->
+ ok
end;
process_item_set(_From, _To, _) ->
ok.
-process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
+process_item_attrs(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of
- "jid" ->
- case jlib:string_to_jid(Val) of
- error ->
- process_item_attrs(Item, Attrs);
- JID1 ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- process_item_attrs(Item#roster{jid = JID}, Attrs)
+ 'jid' ->
+ try
+ JID1 = exmpp_jid:string_to_jid(Val),
+ JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
+ process_item_attrs(Item#roster{jid = JID}, Attrs)
+ catch
+ _ ->
+ process_item_attrs(Item, Attrs)
end;
- "name" ->
+ 'name' ->
process_item_attrs(Item#roster{name = Val}, Attrs);
- "subscription" ->
+ 'subscription' ->
case Val of
"remove" ->
process_item_attrs(Item#roster{subscription = remove},
@@ -293,7 +293,7 @@ process_item_attrs(Item, [{Attr, Val} | Attrs]) ->
_ ->
process_item_attrs(Item, Attrs)
end;
- "ask" ->
+ 'ask' ->
process_item_attrs(Item, Attrs);
_ ->
process_item_attrs(Item, Attrs)
@@ -302,30 +302,30 @@ process_item_attrs(Item, []) ->
Item.
-process_item_els(Item, [{xmlelement, Name, Attrs, SEls} | Els]) ->
+process_item_els(Item, [#xmlel{ns = NS, name = Name} = El | Els]) ->
case Name of
- "group" ->
- Groups = [xml:get_cdata(SEls) | Item#roster.groups],
+ 'group' ->
+ Groups = [exmpp_xml:get_cdata(El) | Item#roster.groups],
process_item_els(Item#roster{groups = Groups}, Els);
_ ->
- case xml:get_attr_s("xmlns", Attrs) of
- "" ->
+ if
+ NS == ?NS_JABBER_CLIENT; NS == ?NS_JABBER_SERVER ->
process_item_els(Item, Els);
- _ ->
- XEls = [{xmlelement, Name, Attrs, SEls} | Item#roster.xs],
+ true ->
+ XEls = [El | Item#roster.xs],
process_item_els(Item#roster{xs = XEls}, Els)
end
end;
-process_item_els(Item, [{xmlcdata, _} | Els]) ->
+process_item_els(Item, [_ | Els]) ->
process_item_els(Item, Els);
process_item_els(Item, []) ->
Item.
push_item(User, Server, From, Item) ->
- ejabberd_sm:route(jlib:make_jid("", "", ""),
- jlib:make_jid(User, Server, ""),
- {xmlelement, "broadcast", [],
+ ejabberd_sm:route(exmpp_jid:make_bare_jid(""),
+ exmpp_jid:make_bare_jid(User, Server),
+ #xmlel{name = 'broadcast', children =
[{item,
Item#roster.jid,
Item#roster.subscription}]}),
@@ -335,19 +335,17 @@ push_item(User, Server, From, Item) ->
% TODO: don't push to those who didn't load roster
push_item(User, Server, Resource, From, Item) ->
- ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
- id = "push",
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- [item_to_xml(Item)]}]},
+ Request = #xmlel{ns = ?NS_ROSTER, name = 'query',
+ children = item_to_xml(Item)},
+ ResIQ = exmpp_iq:set(?NS_JABBER_CLIENT, Request, "push"),
ejabberd_router:route(
From,
- jlib:make_jid(User, Server, Resource),
- jlib:iq_to_xml(ResIQ)).
+ exmpp_jid:make_jid(User, Server, Resource),
+ ResIQ).
get_subscription_lists(_, User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
case mnesia:dirty_index_read(roster, US, #roster.us) of
Items when is_list(Items) ->
@@ -384,15 +382,15 @@ out_subscription(User, Server, JID, Type) ->
process_subscription(out, User, Server, JID, Type, []).
process_subscription(Direction, User, Server, JID1, Type, Reason) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
- LJID = jlib:jid_tolower(JID1),
+ LJID = jlib:short_jid(JID1),
F = fun() ->
Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of
[] ->
- JID = {JID1#jid.user,
- JID1#jid.server,
+ JID = {JID1#jid.node,
+ JID1#jid.domain,
JID1#jid.resource},
#roster{usj = {LUser, LServer, LJID},
us = US,
@@ -444,13 +442,9 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
none ->
ok;
_ ->
- T = case AutoReply of
- subscribed -> "subscribed";
- unsubscribed -> "unsubscribed"
- end,
ejabberd_router:route(
- jlib:make_jid(User, Server, ""), JID1,
- {xmlelement, "presence", [{"type", T}], []})
+ exmpp_jid:make_bare_jid(User, Server), JID1,
+ exmpp_presence:AutoReply())
end,
case Push of
{push, Item} ->
@@ -460,7 +454,7 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
ok;
true ->
push_item(User, Server,
- jlib:make_jid(User, Server, ""), Item)
+ exmpp_jid:make_bare_jid(User, Server), Item)
end,
true;
none ->
@@ -567,8 +561,8 @@ in_auto_reply(_, _, _) -> none.
remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringpre:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
F = fun() ->
lists:foreach(fun(R) ->
@@ -582,8 +576,8 @@ remove_user(User, Server) ->
set_items(User, Server, SubEl) ->
{xmlelement, _Name, _Attrs, Els} = SubEl,
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
F = fun() ->
lists:foreach(fun(El) ->
process_item_set_t(LUser, LServer, El)
@@ -591,42 +585,43 @@ set_items(User, Server, SubEl) ->
end,
mnesia:transaction(F).
-process_item_set_t(LUser, LServer, {xmlelement, _Name, Attrs, Els}) ->
- JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
- case JID1 of
- error ->
- ok;
+process_item_set_t(LUser, LServer, #xmlel{} = El) ->
+ try
+ JID1 = exmpp_jid:string_to_jid(exmpp_xml:get_attribute(El, 'jid')),
+ JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
+ LJID = {JID1#jid.lnode, JID1#jid.ldomain, JID1#jid.lresource},
+ Item = #roster{usj = {LUser, LServer, LJID},
+ us = {LUser, LServer},
+ jid = JID},
+ Item1 = process_item_attrs_ws(Item, El#xmlel.attrs),
+ Item2 = process_item_els(Item1, El#xmlel.children),
+ case Item2#roster.subscription of
+ remove ->
+ mnesia:delete({roster, {LUser, LServer, LJID}});
+ _ ->
+ mnesia:write(Item2)
+ end
+ catch
_ ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- LJID = {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource},
- Item = #roster{usj = {LUser, LServer, LJID},
- us = {LUser, LServer},
- jid = JID},
- Item1 = process_item_attrs_ws(Item, Attrs),
- Item2 = process_item_els(Item1, Els),
- case Item2#roster.subscription of
- remove ->
- mnesia:delete({roster, {LUser, LServer, LJID}});
- _ ->
- mnesia:write(Item2)
- end
+ ok
end;
process_item_set_t(_LUser, _LServer, _) ->
ok.
-process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
+process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of
- "jid" ->
- case jlib:string_to_jid(Val) of
- error ->
- process_item_attrs_ws(Item, Attrs);
- JID1 ->
- JID = {JID1#jid.user, JID1#jid.server, JID1#jid.resource},
- process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
+ 'jid' ->
+ try
+ JID1 = exmpp_jid:string_to_jid(Val),
+ JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
+ process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
+ catch
+ _ ->
+ process_item_attrs_ws(Item, Attrs)
end;
- "name" ->
+ 'name' ->
process_item_attrs_ws(Item#roster{name = Val}, Attrs);
- "subscription" ->
+ 'subscription' ->
case Val of
"remove" ->
process_item_attrs_ws(Item#roster{subscription = remove},
@@ -646,7 +641,7 @@ process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
_ ->
process_item_attrs_ws(Item, Attrs)
end;
- "ask" ->
+ 'ask' ->
process_item_attrs_ws(Item, Attrs);
_ ->
process_item_attrs_ws(Item, Attrs)
@@ -655,8 +650,8 @@ process_item_attrs_ws(Item, []) ->
Item.
get_in_pending_subscriptions(Ls, User, Server) ->
- JID = jlib:make_jid(User, Server, ""),
- US = {JID#jid.luser, JID#jid.lserver},
+ JID = exmpp_jid:make_bare_jid(User, Server),
+ US = {JID#jid.lnode, JID#jid.ldomain},
case mnesia:dirty_index_read(roster, US, #roster.us) of
Result when list(Result) ->
Ls ++ lists:map(
@@ -667,12 +662,14 @@ get_in_pending_subscriptions(Ls, User, Server) ->
true ->
""
end,
- {xmlelement, "presence",
- [{"from", jlib:jid_to_string(R#roster.jid)},
- {"to", jlib:jid_to_string(JID)},
- {"type", "subscribe"}],
- [{xmlelement, "status", [],
- [{xmlcdata, Status}]}]}
+ {U, S, R} = R#roster.jid,
+ Attrs1 = exmpp_stanza:set_sender_in_list([],
+ exmpp_jid:jid_to_string(U, S, R)),
+ Attrs2 = exmpp_stanza:set_recipient_in_list(Attrs1,
+ exmpp_jid:jid_to_string(JID)),
+ Pres1 = exmpp_presence:subscribe(),
+ Pres2 = Pres1#xmlel{attrs = Attrs2},
+ exmpp_presence:set_status(Pres2, Status)
end,
lists:filter(
fun(R) ->
@@ -691,14 +688,14 @@ get_in_pending_subscriptions(Ls, User, Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_jid_info(_, User, Server, JID) ->
- LUser = jlib:nodeprep(User),
- LJID = jlib:jid_tolower(JID),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LJID = jlib:short_jid(JID),
+ LServer = exmpp_stringprep:nameprep(Server),
case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of
[#roster{subscription = Subscription, groups = Groups}] ->
{Subscription, Groups};
_ ->
- LRJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)),
+ LRJID = jlib:short_jid(exmpp_jid:jid_to_bare_jid(JID)),
if
LRJID == LJID ->
{none, []};
@@ -787,7 +784,7 @@ webadmin_page(_, Host,
webadmin_page(Acc, _, _) -> Acc.
user_roster(User, Server, Query, Lang) ->
- US = {jlib:nodeprep(User), jlib:nameprep(Server)},
+ US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
Res = user_roster_parse_query(User, Server, Items1, Query),
Items = mnesia:dirty_index_read(roster, US, #roster.us),
@@ -815,9 +812,10 @@ user_roster(User, Server, Query, Lang) ->
[?C(Group), ?BR]
end, R#roster.groups),
Pending = ask_to_pending(R#roster.ask),
+ {U, S, R} = R#roster.jid,
?XE("tr",
[?XAC("td", [{"class", "valign"}],
- jlib:jid_to_string(R#roster.jid)),
+ catch exmpp_jid:jid_to_string(U, S, R)),
?XAC("td", [{"class", "valign"}],
R#roster.name),
?XAC("td", [{"class", "valign"}],
@@ -862,11 +860,12 @@ user_roster_parse_query(User, Server, Items, Query) ->
{value, {_, undefined}} ->
error;
{value, {_, SJID}} ->
- case jlib:string_to_jid(SJID) of
- JID when is_record(JID, jid) ->
- user_roster_subscribe_jid(User, Server, JID),
- ok;
- error ->
+ try
+ JID = exmpp_jid:string_to_jid(SJID),
+ user_roster_subscribe_jid(User, Server, JID),
+ ok
+ catch
+ _ ->
error
end;
false ->
@@ -887,9 +886,9 @@ user_roster_parse_query(User, Server, Items, Query) ->
user_roster_subscribe_jid(User, Server, JID) ->
out_subscription(User, Server, JID, subscribe),
- UJID = jlib:make_jid(User, Server, ""),
+ UJID = exmpp_jid:make_bare_jid(User, Server),
ejabberd_router:route(
- UJID, JID, {xmlelement, "presence", [{"type", "subscribe"}], []}).
+ UJID, JID, exmpp_presence:subscribe()).
user_roster_item_parse_query(User, Server, Items, Query) ->
lists:foreach(
@@ -898,28 +897,32 @@ user_roster_item_parse_query(User, Server, Items, Query) ->
case lists:keysearch(
"validate" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of
{value, _} ->
- JID1 = jlib:make_jid(JID),
+ {U, S, R} = JID,
+ JID1 = exmpp_jid:make_jid(U, S, R),
out_subscription(
User, Server, JID1, subscribed),
- UJID = jlib:make_jid(User, Server, ""),
+ UJID = exmpp_jid:make_bare_jid(User, Server),
ejabberd_router:route(
- UJID, JID1, {xmlelement, "presence",
- [{"type", "subscribed"}], []}),
+ UJID, JID1, exmpp_presence:subscribed()),
throw(submitted);
false ->
case lists:keysearch(
"remove" ++ ejabberd_web_admin:term_to_id(JID), 1, Query) of
{value, _} ->
- UJID = jlib:make_jid(User, Server, ""),
+ UJID = exmpp_jid:make_bare_jid(User, Server),
+ Attrs1 = exmpp_xml:set_attribute_in_list([],
+ 'jid', exmpp_jid:jid_to_string(JID)),
+ Attrs2 = exmpp_xml:set_attribute_in_list(Attrs1,
+ 'subscription', "remove"),
+ Item = #xmlel{ns = ?NS_ROSTER, name = 'item',
+ attrs = Attrs2},
+ Request = #xmlel{
+ ns = ?NS_ROSTER,
+ name = 'query',
+ children = [Item]},
process_iq(
UJID, UJID,
- #iq{type = set,
- sub_el = {xmlelement, "query",
- [{"xmlns", ?NS_ROSTER}],
- [{xmlelement, "item",
- [{"jid", jlib:jid_to_string(JID)},
- {"subscription", "remove"}],
- []}]}}),
+ exmpp_iq:set(?NS_JABBER_CLIENT, Request)),
throw(submitted);
false ->
ok
@@ -930,7 +933,7 @@ user_roster_item_parse_query(User, Server, Items, Query) ->
nothing.
us_to_list({User, Server}) ->
- jlib:jid_to_string({User, Server, ""}).
+ exmpp_jid:bare_jid_to_string(User, Server).
webadmin_user(Acc, _User, _Server, Lang) ->
Acc ++ [?XE("h3", [?ACT("roster/", "Roster")])].
From b33ac4722844c335072e0b27bd7c90c48ad3964a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 21 Jul 2008 15:30:32 +0000
Subject: [PATCH 047/582] Convert to exmpp.
SVN Revision: 1464
---
ChangeLog | 3 +-
src/gen_iq_handler.erl | 3 +-
src/mod_vcard.erl | 610 +++++++++++++++++++++--------------------
3 files changed, 311 insertions(+), 305 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 73c49c0ab..ad48991b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,7 +4,8 @@
the new format to a built-in list of modules known to support them.
Other modules will still receive arguments in the old format.
- * src/mod_roster.erl, src/gen_iq_handler.erl: Convert to exmpp.
+ * src/mod_roster.erl, src/mod_vcard.erl, src/gen_iq_handler.erl:
+ Convert to exmpp.
2008-07-17 Jean-Sébastien Pédron
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index 09318e058..0a949566f 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -59,7 +59,8 @@
% XXX OLD FORMAT: modules not in the following list will receive
% old format strudctures.
-define(CONVERTED_MODULES, [
- mod_roster
+ mod_roster,
+ mod_vcard
]).
%%====================================================================
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 2a6474eba..fd78c3fb8 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -36,8 +36,9 @@
reindex_vcards/0,
remove_user/2]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-define(JUD_MATCHES, 30).
@@ -83,9 +84,11 @@ start(Host, Opts) ->
ejabberd_hooks:add(remove_user, Host,
?MODULE, remove_user, 50),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
+ % XXX OLD FORMAT: NS as string.
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, atom_to_list(?NS_VCARD),
?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
+ % XXX OLD FORMAT: NS as string.
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_VCARD),
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"),
@@ -123,8 +126,12 @@ loop(Host, ServerHost) ->
stop(Host) ->
ejabberd_hooks:delete(remove_user, Host,
?MODULE, remove_user, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
+ % XXX OLD FORMAT: NS as string.
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
+ atom_to_list(?NS_VCARD)),
+ % XXX OLD FORMAT: NS as string.
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
+ atom_to_list(?NS_VCARD)),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
Proc ! stop,
@@ -138,51 +145,53 @@ get_sm_features(Acc, _From, _To, Node, _Lang) ->
[] ->
case Acc of
{result, Features} ->
- {result, [?NS_VCARD | Features]};
+ % XXX OLD FORMAT: NS as string.
+ {result, [atom_to_list(?NS_VCARD) | Features]};
empty ->
- {result, [?NS_VCARD]}
+ % XXX OLD FORMAT: NS as string.
+ {result, [atom_to_list(?NS_VCARD)]}
end;
_ ->
Acc
end.
-process_local_iq(_From, _To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
+process_local_iq(_From, _To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
get ->
- IQ#iq{type = result,
- sub_el = [{xmlelement, "vCard",
- [{"xmlns", ?NS_VCARD}],
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd"}]},
- {xmlelement, "URL", [],
- [{xmlcdata, ?EJABBERD_URI}]},
- {xmlelement, "DESC", [],
- [{xmlcdata,
- translate:translate(
- Lang,
- "Erlang Jabber Server") ++
- "\nCopyright (c) 2002-2008 ProcessOne"}]},
- {xmlelement, "BDAY", [],
- [{xmlcdata, "2002-11-16"}]}
- ]}]}
+ Lang = case exmpp_stanza:get_lang(IQ) of
+ undefined -> "";
+ L -> L
+ end,
+ Result = #xmlel{ns = ?NS_VCARD, name = 'vCard', children = [
+ exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'FN'},
+ "ejabberd"),
+ exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'URL'},
+ ?EJABBERD_URI),
+ exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'DESC'},
+ translate:translate(Lang, "Erlang Jabber Server") ++
+ "\nCopyright (c) 2002-2008 ProcessOne"),
+ exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'BDAY'},
+ "2002-11-16")
+ ]},
+ exmpp_iq:result(IQ, Result)
end.
-process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
+process_sm_iq(From, To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- #jid{user = User, lserver = LServer} = From,
+ #jid{node = User, ldomain = LServer} = From,
case lists:member(LServer, ?MYHOSTS) of
true ->
- set_vcard(User, LServer, SubEl),
- IQ#iq{type = result, sub_el = []};
+ set_vcard(User, LServer, exmpp_iq:get_request(IQ)),
+ exmpp_iq:result(IQ);
false ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
+ exmpp_iq:error(IQ, 'not-allowed')
end;
get ->
- #jid{luser = LUser, lserver = LServer} = To,
+ #jid{lnode = LUser, ldomain = LServer} = To,
US = {LUser, LServer},
F = fun() ->
mnesia:read({vcard, US})
@@ -190,27 +199,46 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
Els = case mnesia:transaction(F) of
{atomic, Rs} ->
lists:map(fun(R) ->
- R#vcard.vcard
+ case R#vcard.vcard of
+ #xmlel{} = E ->
+ E;
+ #xmlelement{} = E ->
+ % XXX OLD FORMAT: Base contains old elements.
+ io:format("VCARD: Old element in base: ~p~n", [E]),
+ exmpp_xml:xmlelement_to_xmlel(E, [?NS_VCARD], [])
+ end
end, Rs);
{aborted, _Reason} ->
[]
end,
- IQ#iq{type = result, sub_el = Els}
+ exmpp_iq:result(IQ, Els)
end.
set_vcard(User, LServer, VCARD) ->
- FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
- Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
- Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
- Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
- Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
- BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
- CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
- Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]),
- EMail1 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, {elem, "USERID"},cdata]),
- EMail2 = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
- OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
- OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
+ FN = exmpp_xml:get_path(VCARD,
+ [{element, 'FN'}, cdata_as_list]),
+ Family = exmpp_xml:get_path(VCARD,
+ [{element, 'N'}, {element, 'FAMILY'}, cdata_as_list]),
+ Given = exmpp_xml:get_path(VCARD,
+ [{element, 'N'}, {element, 'GIVEN'}, cdata_as_list]),
+ Middle = exmpp_xml:get_path(VCARD,
+ [{element, 'N'}, {element, 'MIDDLE'}, cdata_as_list]),
+ Nickname = exmpp_xml:get_path(VCARD,
+ [{element, 'NICKNAME'}, cdata_as_list]),
+ BDay = exmpp_xml:get_path(VCARD,
+ [{element, 'BDAY'}, cdata_as_list]),
+ CTRY = exmpp_xml:get_path(VCARD,
+ [{element, 'ADR'}, {element, 'CTRY'}, cdata_as_list]),
+ Locality = exmpp_xml:get_path(VCARD,
+ [{element, 'ADR'}, {element, 'LOCALITY'}, cdata_as_list]),
+ EMail1 = exmpp_xml:get_path(VCARD,
+ [{element, 'EMAIL'}, {element, 'USERID'}, cdata_as_list]),
+ EMail2 = exmpp_xml:get_path(VCARD,
+ [{element, 'EMAIL'}, cdata_as_list]),
+ OrgName = exmpp_xml:get_path(VCARD,
+ [{element, 'ORG'}, {element, 'ORGNAME'}, cdata_as_list]),
+ OrgUnit = exmpp_xml:get_path(VCARD,
+ [{element, 'ORG'}, {element, 'ORGUNIT'}, cdata_as_list]),
EMail = case EMail1 of
"" ->
EMail2;
@@ -218,76 +246,70 @@ set_vcard(User, LServer, VCARD) ->
EMail1
end,
- LUser = jlib:nodeprep(User),
- LFN = stringprep:tolower(FN),
- LFamily = stringprep:tolower(Family),
- LGiven = stringprep:tolower(Given),
- LMiddle = stringprep:tolower(Middle),
- LNickname = stringprep:tolower(Nickname),
- LBDay = stringprep:tolower(BDay),
- LCTRY = stringprep:tolower(CTRY),
- LLocality = stringprep:tolower(Locality),
- LEMail = stringprep:tolower(EMail),
- LOrgName = stringprep:tolower(OrgName),
- LOrgUnit = stringprep:tolower(OrgUnit),
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ LFN = exmpp_stringprep:to_lower(FN),
+ LFamily = exmpp_stringprep:to_lower(Family),
+ LGiven = exmpp_stringprep:to_lower(Given),
+ LMiddle = exmpp_stringprep:to_lower(Middle),
+ LNickname = exmpp_stringprep:to_lower(Nickname),
+ LBDay = exmpp_stringprep:to_lower(BDay),
+ LCTRY = exmpp_stringprep:to_lower(CTRY),
+ LLocality = exmpp_stringprep:to_lower(Locality),
+ LEMail = exmpp_stringprep:to_lower(EMail),
+ LOrgName = exmpp_stringprep:to_lower(OrgName),
+ LOrgUnit = exmpp_stringprep:to_lower(OrgUnit),
- US = {LUser, LServer},
+ US = {LUser, LServer},
- if
- (LUser == error) or
- (LFN == error) or
- (LFamily == error) or
- (LGiven == error) or
- (LMiddle == error) or
- (LNickname == error) or
- (LBDay == error) or
- (LCTRY == error) or
- (LLocality == error) or
- (LEMail == error) or
- (LOrgName == error) or
- (LOrgUnit == error) ->
- {error, badarg};
- true ->
- F = fun() ->
- mnesia:write(#vcard{us = US, vcard = VCARD}),
- mnesia:write(
- #vcard_search{us = US,
- user = {User, LServer},
- luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
- end,
- mnesia:transaction(F)
+ F = fun() ->
+ % XXX OLD FORMAT: We keep persistent data in the old format
+ % for now.
+ VCARDOld = exmpp_xml:xmlel_to_xmlelement(VCARD, [?NS_VCARD], []),
+ mnesia:write(#vcard{us = US, vcard = VCARDOld}),
+ mnesia:write(
+ #vcard_search{us = US,
+ user = {User, LServer},
+ luser = LUser,
+ fn = FN, lfn = LFN,
+ family = Family, lfamily = LFamily,
+ given = Given, lgiven = LGiven,
+ middle = Middle, lmiddle = LMiddle,
+ nickname = Nickname, lnickname = LNickname,
+ bday = BDay, lbday = LBDay,
+ ctry = CTRY, lctry = LCTRY,
+ locality = Locality, llocality = LLocality,
+ email = EMail, lemail = LEMail,
+ orgname = OrgName, lorgname = LOrgName,
+ orgunit = OrgUnit, lorgunit = LOrgUnit
+ })
+ end,
+ mnesia:transaction(F)
+ catch
+ _ ->
+ {error, badarg}
end.
-define(TLFIELD(Type, Label, Var),
- {xmlelement, "field", [{"type", Type},
- {"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
+ #xmlel{ns = ?NS_VCARD, name = 'field', attrs = [
+ #xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'label', value = translate:translate(Lang, Label)},
+ #xmlattr{name = 'var', value = Var}]}).
-define(FORM(JID),
- [{xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "You need an x:data capable client to search")}]},
- {xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "form"}],
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search users in ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "instructions", [],
- [{xmlcdata, translate:translate(Lang, "Fill in the form to search "
- "for any matching Jabber User "
- "(Add * to the end of field to "
- "match substring)")}]},
+ [#xmlel{ns = ?NS_SEARCH, name = 'instructions', children =
+ [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "You need an x:data capable client to search"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs =
+ [#xmlattr{name = 'type', value = "form"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "Search users in ") ++ jlib:jid_to_string(JID))}]},
+ #xmlel{ns = ?NS_SEARCH, name = 'instructions', children =
+ [#xmlcdata{cdata = list_to_binary(translate:translate(Lang,
+ "Fill in the form to search "
+ "for any matching Jabber User "
+ "(Add * to the end of field to "
+ "match substring)"))}]},
?TLFIELD("text-single", "User", "user"),
?TLFIELD("text-single", "Full Name", "fn"),
?TLFIELD("text-single", "Name", "first"),
@@ -306,157 +328,139 @@ set_vcard(User, LServer, VCARD) ->
do_route(ServerHost, From, To, Packet) ->
- #jid{user = User, resource = Resource} = To,
+ #jid{node = User, resource = Resource} = To,
if
- (User /= "") or (Resource /= "") ->
- Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE),
+ (User /= undefined) or (Resource /= undefined) ->
+ Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'),
ejabberd_router ! {route, To, From, Err};
true ->
- IQ = jlib:iq_query_info(Packet),
- case IQ of
- #iq{type = Type, xmlns = ?NS_SEARCH, lang = Lang, sub_el = SubEl} ->
- case Type of
- set ->
- XDataEl = find_xdata_el(SubEl),
- case XDataEl of
- false ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From, Err);
- _ ->
- XData = jlib:parse_xdata_submit(XDataEl),
- case XData of
- invalid ->
- Err = jlib:make_error_reply(
- Packet,
- ?ERR_BAD_REQUEST),
- ejabberd_router:route(To, From,
- Err);
- _ ->
- ResIQ =
- IQ#iq{
- type = result,
- sub_el =
- [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "result"}],
- search_result(Lang, To, ServerHost, XData)
- }]}]},
- ejabberd_router:route(
- To, From, jlib:iq_to_xml(ResIQ))
- end
- end;
- get ->
- ResIQ = IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_SEARCH}],
- ?FORM(To)
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_INFO, lang = Lang} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_INFO}],
- [{xmlelement, "identity",
- [{"category", "directory"},
- {"type", "user"},
- {"name",
- translate:translate(Lang, "vCard User Search")}],
- []},
- {xmlelement, "feature",
- [{"var", ?NS_SEARCH}], []},
- {xmlelement, "feature",
- [{"var", ?NS_VCARD}], []}
- ]
- }]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = Type, xmlns = ?NS_DISCO_ITEMS} ->
- case Type of
- set ->
- Err = jlib:make_error_reply(
- Packet, ?ERR_NOT_ALLOWED),
- ejabberd_router:route(To, From, Err);
- get ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "query",
- [{"xmlns", ?NS_DISCO_ITEMS}],
- []}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ))
- end;
- #iq{type = get, xmlns = ?NS_VCARD, lang = Lang} ->
- ResIQ =
- IQ#iq{type = result,
- sub_el = [{xmlelement,
- "vCard",
- [{"xmlns", ?NS_VCARD}],
- iq_get_vcard(Lang)}]},
- ejabberd_router:route(To,
- From,
- jlib:iq_to_xml(ResIQ));
+ try
+ Request = exmpp_iq:get_request(Packet),
+ Type = exmpp_iq:get_type(Packet),
+ Lang = exmpp_stanza:get_lang(Packet),
+ case {Type, Request#xmlel.ns} of
+ {set, ?NS_SEARCH} ->
+ XDataEl = find_xdata_el(Request),
+ case XDataEl of
+ false ->
+ Err = exmpp_iq:error(Packet, 'bad-request'),
+ ejabberd_router:route(To, From, Err);
+ _ ->
+ XData = jlib:parse_xdata_submit(XDataEl),
+ case XData of
+ invalid ->
+ Err = exmpp_iq:error(Packet,
+ 'bad-request'),
+ ejabberd_router:route(To, From,
+ Err);
+ _ ->
+ Result = #xmlel{
+ ns = ?NS_SEARCH,
+ name = 'query',
+ children = [
+ #xmlel{
+ ns = ?NS_DATA_FORMS,
+ name = 'x',
+ attrs = [#xmlattr{name = 'type',
+ value = "result"}],
+ children = search_result(Lang,
+ To, ServerHost, XData)}]},
+ ResIQ = exmpp_iq:result(Packet,
+ Result),
+ ejabberd_router:route(
+ To, From, ResIQ)
+ end
+ end;
+ {get, ?NS_SEARCH} ->
+ Result = #xmlel{ns = ?NS_SEARCH, name = 'query',
+ children = ?FORM(To)},
+ ResIQ = exmpp_iq:result(Packet, Result),
+ ejabberd_router:route(To,
+ From,
+ ResIQ);
+ {set, ?NS_DISCO_INFO} ->
+ Err = exmpp_iq:error(Packet, 'not-allowed'),
+ ejabberd_router:route(To, From, Err);
+ {get, ?NS_DISCO_INFO} ->
+ Result = #xmlel{ns = ?NS_DISCO_INFO, name = 'query',
+ children = [
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'identity',
+ attrs = [
+ #xmlattr{name = 'category',
+ value = "directory"},
+ #xmlattr{name = 'type',
+ value = "user"},
+ #xmlattr{name = 'name',
+ value = translate:translate(Lang,
+ "vCard User Search")}]},
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature',
+ attrs = [
+ #xmlattr{name = 'var',
+ value = atom_to_list(?NS_SEARCH)}]},
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature',
+ attrs = [
+ #xmlattr{name = 'var',
+ value = atom_to_list(?NS_VCARD)}]}
+ ]},
+ ResIQ = exmpp_iq:result(Packet, Result),
+ ejabberd_router:route(To,
+ From,
+ ResIQ);
+ {set, ?NS_DISCO_ITEMS} ->
+ Err = exmpp_iq:error(Packet, 'not-allowed'),
+ ejabberd_router:route(To, From, Err);
+ {get, ?NS_DISCO_ITEMS} ->
+ Result = #xmlel{ns = ?NS_DISCO_ITEMS, name = 'query'},
+ ResIQ = exmpp_iq:result(Packet, Result),
+ ejabberd_router:route(To,
+ From,
+ ResIQ);
+ {get, ?NS_VCARD} ->
+ Result = #xmlel{ns = ?NS_VCARD, name = 'vCard',
+ children = iq_get_vcard(Lang)},
+ ResIQ = exmpp_iq:result(Packet, Result),
+ ejabberd_router:route(To,
+ From,
+ ResIQ);
+ _ ->
+ Err = exmpp_iq:error(Packet, 'service-unavailable'),
+ ejabberd_router:route(To, From, Err)
+ end
+ catch
_ ->
- Err = jlib:make_error_reply(Packet,
- ?ERR_SERVICE_UNAVAILABLE),
- ejabberd_router:route(To, From, Err)
+ Err1 = exmpp_iq:error(Packet, 'service-unavailable'),
+ ejabberd_router:route(To, From, Err1)
end
end.
iq_get_vcard(Lang) ->
- [{xmlelement, "FN", [],
- [{xmlcdata, "ejabberd/mod_vcard"}]},
- {xmlelement, "URL", [],
- [{xmlcdata, ?EJABBERD_URI}]},
- {xmlelement, "DESC", [],
- [{xmlcdata, translate:translate(
- Lang,
- "ejabberd vCard module") ++
- "\nCopyright (c) 2003-2008 ProcessOne"}]}].
+ [
+ #xmlel{ns = ?NS_SEARCH, name = 'FN', children = [
+ #xmlcdata{cdata = <<"ejabberd/mod_vcard">>}]},
+ #xmlel{ns = ?NS_SEARCH, name = 'URL', children = [
+ #xmlcdata{cdata = list_to_binary(?EJABBERD_URI)}]},
+ #xmlel{ns = ?NS_SEARCH, name ='DESC', children = [
+ #xmlcdata{cdata = list_to_binary(
+ translate:translate(Lang, "ejabberd vCard module") ++
+ "\nCopyright (c) 2003-2008 ProcessOne")}]}
+ ].
-find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
+find_xdata_el(#xmlel{children = SubEls}) ->
find_xdata_el1(SubEls).
find_xdata_el1([]) ->
false;
-find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_XDATA ->
- {xmlelement, Name, Attrs, SubEls};
- _ ->
- find_xdata_el1(Els)
- end;
+find_xdata_el1([#xmlel{ns = ?NS_DATA_FORMS} = El | _Els]) ->
+ El;
find_xdata_el1([_ | Els]) ->
find_xdata_el1(Els).
--define(LFIELD(Label, Var),
- {xmlelement, "field", [{"label", translate:translate(Lang, Label)},
- {"var", Var}], []}).
-
search_result(Lang, JID, ServerHost, Data) ->
- [{xmlelement, "title", [],
- [{xmlcdata, translate:translate(Lang, "Search Results for ") ++
- jlib:jid_to_string(JID)}]},
- {xmlelement, "reported", [],
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(
+ translate:translate(Lang, "Search Results for ") ++
+ exmpp_jid:jid_to_string(JID))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'reported', children =
[?TLFIELD("text-single", "Jabber ID", "jid"),
?TLFIELD("text-single", "Full Name", "fn"),
?TLFIELD("text-single", "Name", "first"),
@@ -472,13 +476,14 @@ search_result(Lang, JID, ServerHost, Data) ->
]}] ++ lists:map(fun record_to_item/1, search(ServerHost, Data)).
-define(FIELD(Var, Val),
- {xmlelement, "field", [{"var", Var}],
- [{xmlelement, "value", [],
- [{xmlcdata, Val}]}]}).
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = Var}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children =
+ [#xmlcdata{cdata = list_to_binary(Val)}]}]}).
record_to_item(R) ->
{User, Server} = R#vcard_search.user,
- {xmlelement, "item", [],
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'item', children =
[
?FIELD("jid", User ++ "@" ++ Server),
?FIELD("fn", R#vcard_search.fn),
@@ -599,61 +604,60 @@ set_vcard_t(R, _) ->
User = US,
VCARD = R#vcard.vcard,
- FN = xml:get_path_s(VCARD, [{elem, "FN"}, cdata]),
- Family = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "FAMILY"}, cdata]),
- Given = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "GIVEN"}, cdata]),
- Middle = xml:get_path_s(VCARD, [{elem, "N"}, {elem, "MIDDLE"}, cdata]),
- Nickname = xml:get_path_s(VCARD, [{elem, "NICKNAME"}, cdata]),
- BDay = xml:get_path_s(VCARD, [{elem, "BDAY"}, cdata]),
- CTRY = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "CTRY"}, cdata]),
- Locality = xml:get_path_s(VCARD, [{elem, "ADR"}, {elem, "LOCALITY"},cdata]),
- EMail = xml:get_path_s(VCARD, [{elem, "EMAIL"}, cdata]),
- OrgName = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGNAME"}, cdata]),
- OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]),
+ FN = exmpp_xml:get_path(VCARD,
+ [{element, 'FN'}, cdata_as_list]),
+ Family = exmpp_xml:get_path(VCARD,
+ [{element, 'N'}, {element, 'FAMILY'}, cdata_as_list]),
+ Given = exmpp_xml:get_path(VCARD,
+ [{element, 'N'}, {element, 'GIVEN'}, cdata_as_list]),
+ Middle = exmpp_xml:get_path(VCARD,
+ [{element, 'N'}, {element, 'MIDDLE'}, cdata_as_list]),
+ Nickname = exmpp_xml:get_path(VCARD,
+ [{element, 'NICKNAME'}, cdata_as_list]),
+ BDay = exmpp_xml:get_path(VCARD,
+ [{element, 'BDAY'}, cdata_as_list]),
+ CTRY = exmpp_xml:get_path(VCARD,
+ [{element, 'ADR'}, {element, 'CTRY'}, cdata_as_list]),
+ Locality = exmpp_xml:get_path(VCARD,
+ [{element, 'ADR'}, {element, 'LOCALITY'},cdata_as_list]),
+ EMail = exmpp_xml:get_path(VCARD,
+ [{element, 'EMAIL'}, cdata_as_list]),
+ OrgName = exmpp_xml:get_path(VCARD,
+ [{element, 'ORG'}, {element, 'ORGNAME'}, cdata_as_list]),
+ OrgUnit = exmpp_xml:get_path(VCARD,
+ [{element, 'ORG'}, {element, 'ORGUNIT'}, cdata_as_list]),
- {LUser, _LServer} = US,
- LFN = stringprep:tolower(FN),
- LFamily = stringprep:tolower(Family),
- LGiven = stringprep:tolower(Given),
- LMiddle = stringprep:tolower(Middle),
- LNickname = stringprep:tolower(Nickname),
- LBDay = stringprep:tolower(BDay),
- LCTRY = stringprep:tolower(CTRY),
- LLocality = stringprep:tolower(Locality),
- LEMail = stringprep:tolower(EMail),
- LOrgName = stringprep:tolower(OrgName),
- LOrgUnit = stringprep:tolower(OrgUnit),
-
- if
- (LUser == error) or
- (LFN == error) or
- (LFamily == error) or
- (LGiven == error) or
- (LMiddle == error) or
- (LNickname == error) or
- (LBDay == error) or
- (LCTRY == error) or
- (LLocality == error) or
- (LEMail == error) or
- (LOrgName == error) or
- (LOrgUnit == error) ->
- {error, badarg};
- true ->
- mnesia:write(
- #vcard_search{us = US,
- user = User, luser = LUser,
- fn = FN, lfn = LFN,
- family = Family, lfamily = LFamily,
- given = Given, lgiven = LGiven,
- middle = Middle, lmiddle = LMiddle,
- nickname = Nickname, lnickname = LNickname,
- bday = BDay, lbday = LBDay,
- ctry = CTRY, lctry = LCTRY,
- locality = Locality, llocality = LLocality,
- email = EMail, lemail = LEMail,
- orgname = OrgName, lorgname = LOrgName,
- orgunit = OrgUnit, lorgunit = LOrgUnit
- })
+ try
+ {LUser, _LServer} = US,
+ LFN = exmpp_stringprep:to_lower(FN),
+ LFamily = exmpp_stringprep:to_lower(Family),
+ LGiven = exmpp_stringprep:to_lower(Given),
+ LMiddle = exmpp_stringprep:to_lower(Middle),
+ LNickname = exmpp_stringprep:to_lower(Nickname),
+ LBDay = exmpp_stringprep:to_lower(BDay),
+ LCTRY = exmpp_stringprep:to_lower(CTRY),
+ LLocality = exmpp_stringprep:to_lower(Locality),
+ LEMail = exmpp_stringprep:to_lower(EMail),
+ LOrgName = exmpp_stringprep:to_lower(OrgName),
+ LOrgUnit = exmpp_stringprep:to_lower(OrgUnit),
+ mnesia:write(
+ #vcard_search{us = US,
+ user = User, luser = LUser,
+ fn = FN, lfn = LFN,
+ family = Family, lfamily = LFamily,
+ given = Given, lgiven = LGiven,
+ middle = Middle, lmiddle = LMiddle,
+ nickname = Nickname, lnickname = LNickname,
+ bday = BDay, lbday = LBDay,
+ ctry = CTRY, lctry = LCTRY,
+ locality = Locality, llocality = LLocality,
+ email = EMail, lemail = LEMail,
+ orgname = OrgName, lorgname = LOrgName,
+ orgunit = OrgUnit, lorgunit = LOrgUnit
+ })
+ catch
+ _ ->
+ {error, badarg}
end.
@@ -665,8 +669,8 @@ reindex_vcards() ->
remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_jid:nodeprep(User),
+ LServer = exmpp_jid:nameprep(Server),
US = {LUser, LServer},
F = fun() ->
mnesia:delete({vcard, US}),
From 4a1e45070ec1f5e8c13f09e7feba7bf3d21cc89b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 21 Jul 2008 15:53:58 +0000
Subject: [PATCH 048/582] One call to jlib:jid_to_string/1 was remaining.
SVN Revision: 1465
---
ChangeLog | 2 ++
src/mod_vcard.erl | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index ad48991b0..cc53893a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,8 @@
* src/mod_roster.erl, src/mod_vcard.erl, src/gen_iq_handler.erl:
Convert to exmpp.
+ * src/mod_vcard.erl: One call to jlib:jid_to_string/1 was remaining.
+
2008-07-17 Jean-Sébastien Pédron
Merge revisions from 1444 to revision 1457 from trunk.
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index fd78c3fb8..9f980dd70 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -303,7 +303,7 @@ set_vcard(User, LServer, VCARD) ->
#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs =
[#xmlattr{name = 'type', value = "form"}], children =
[#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
- [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "Search users in ") ++ jlib:jid_to_string(JID))}]},
+ [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "Search users in ") ++ exmpp_jid:jid_to_string(JID))}]},
#xmlel{ns = ?NS_SEARCH, name = 'instructions', children =
[#xmlcdata{cdata = list_to_binary(translate:translate(Lang,
"Fill in the form to search "
From a8ab6c1568abe882dd529fa60ce6afb146a12e19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Mon, 21 Jul 2008 15:54:47 +0000
Subject: [PATCH 049/582] Add support for #xmlel to parse_xdata_submit/1 and
friends. This fixes the user search in mod_vcard.
SVN Revision: 1466
---
ChangeLog | 3 +++
src/jlib.erl | 19 +++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/ChangeLog b/ChangeLog
index cc53893a8..e18a404d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,9 @@
* src/mod_vcard.erl: One call to jlib:jid_to_string/1 was remaining.
+ * src/jlib.erl: Add support for #xmlel to parse_xdata_submit/1 and
+ friends. This fixes the user search in mod_vcard.
+
2008-07-17 Jean-Sébastien Pédron
Merge revisions from 1444 to revision 1457 from trunk.
diff --git a/src/jlib.erl b/src/jlib.erl
index b926c15fb..698e704e4 100644
--- a/src/jlib.erl
+++ b/src/jlib.erl
@@ -448,6 +448,13 @@ iq_to_xml(#iq{id = ID, type = Type, sub_el = SubEl}) ->
end.
+parse_xdata_submit({xmlel, _, _, _, Attrs, Els}) ->
+ case exmpp_xml:get_attribute_from_list(Attrs, 'type') of
+ "submit" ->
+ lists:reverse(parse_xdata_fields(Els, []));
+ _ ->
+ invalid
+ end;
parse_xdata_submit(El) ->
{xmlelement, _Name, Attrs, Els} = El,
case xml:get_attr_s("type", Attrs) of
@@ -459,6 +466,15 @@ parse_xdata_submit(El) ->
parse_xdata_fields([], Res) ->
Res;
+parse_xdata_fields([{xmlel, _, _, 'field', Attrs, SubEls} | Els],
+ Res) ->
+ case exmpp_xml:get_attribute_from_list(Attrs, 'var') of
+ "" ->
+ parse_xdata_fields(Els, Res);
+ Var ->
+ Field = {Var, lists:reverse(parse_xdata_values(SubEls, []))},
+ parse_xdata_fields(Els, [Field | Res])
+ end;
parse_xdata_fields([{xmlelement, Name, Attrs, SubEls} | Els], Res) ->
case Name of
"field" ->
@@ -478,6 +494,9 @@ parse_xdata_fields([_ | Els], Res) ->
parse_xdata_values([], Res) ->
Res;
+parse_xdata_values([{xmlel, _, _, 'value', _, SubEls} | Els], Res) ->
+ Val = exmpp_xml:get_cdata_from_list_as_list(SubEls),
+ parse_xdata_values(Els, [Val | Res]);
parse_xdata_values([{xmlelement, Name, _Attrs, SubEls} | Els], Res) ->
case Name of
"value" ->
From 37b99639d43b17b18e090eeace19d5ef6c107f96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 22 Jul 2008 14:03:11 +0000
Subject: [PATCH 050/582] Convert to exmpp.
SVN Revision: 1468
---
ChangeLog | 4 +
src/gen_iq_handler.erl | 1 +
src/mod_disco.erl | 255 +++++++++++++++++++++++------------------
3 files changed, 147 insertions(+), 113 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e18a404d8..e19d2da6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-22 Jean-Sébastien Pédron
+
+ * src/mod_disco.erl, src/gen_iq_handler.erl: Convert to exmpp.
+
2008-07-21 Jean-Sébastien Pédron
* src/gen_iq_handler.erl: Prepare gen_iq_handler to pass arguments in
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index 0a949566f..19a0da6c4 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -59,6 +59,7 @@
% XXX OLD FORMAT: modules not in the following list will receive
% old format strudctures.
-define(CONVERTED_MODULES, [
+ mod_disco,
mod_roster,
mod_vcard
]).
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index cf8751e07..9700a6546 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -47,8 +47,9 @@
register_extra_domain/2,
unregister_extra_domain/2]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-record(disco_publish, {owner_node, jid, name, node}).
@@ -62,13 +63,13 @@ start(Host, Opts) ->
ejabberd_local:refresh_iq_handlers(),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, atom_to_list(?NS_DISCO_ITEMS),
?MODULE, process_local_iq_items, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, atom_to_list(?NS_DISCO_INFO),
?MODULE, process_local_iq_info, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_DISCO_ITEMS),
?MODULE, process_sm_iq_items, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_DISCO_INFO),
?MODULE, process_sm_iq_info, IQDisc),
catch ets:new(disco_features, [named_table, ordered_set, public]),
@@ -100,10 +101,10 @@ stop(Host) ->
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 100),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_services, 100),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO),
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, atom_to_list(?NS_DISCO_ITEMS)),
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, atom_to_list(?NS_DISCO_INFO)),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_DISCO_ITEMS)),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_DISCO_INFO)),
catch ets:match_delete(disco_features, {{'_', Host}}),
catch ets:match_delete(disco_extra_domains, {{'_', Host}}),
ok.
@@ -125,71 +126,82 @@ unregister_extra_domain(Host, Domain) ->
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
ets:delete(disco_extra_domains, {Domain, Host}).
-process_local_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
+process_local_iq_items(From, To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
get ->
- Node = xml:get_tag_attr_s("node", SubEl),
- Host = To#jid.lserver,
+ SubEl = exmpp_iq:get_request(IQ),
+ Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Host = To#jid.ldomain,
+ Lang = exmpp_stanza:get_lang(IQ),
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
case ejabberd_hooks:run_fold(disco_local_items,
Host,
empty,
- [From, To, Node, Lang]) of
+ [FromOld, ToOld, Node, Lang]) of
{result, Items} ->
+ % XXX OLD FORMAT: Items might be an #xmlelement.
ANode = case Node of
"" -> [];
- _ -> [{"node", Node}]
+ _ -> [#xmlattr{name = 'node', value = Node}]
end,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_ITEMS} | ANode],
- Items
- }]};
+ Result = #xmlel{ns = ?NS_DISCO_ITEMS, name = 'query',
+ attrs = ANode, children = Items},
+ exmpp_iq:result(IQ, Result);
{error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
+ % XXX OLD FORMAT: Error.
+ exmpp_iq:error(IQ, Error)
end
end.
-process_local_iq_info(From, To, #iq{type = Type, lang = Lang,
- sub_el = SubEl} = IQ) ->
- case Type of
+process_local_iq_info(From, To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
get ->
- Host = To#jid.lserver,
- Node = xml:get_tag_attr_s("node", SubEl),
+ Host = To#jid.ldomain,
+ SubEl = exmpp_iq:get_request(IQ),
+ Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Lang = exmpp_stanza:get_lang(IQ),
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ % XXX OLD FORMAT: Identity might be an #xmlelement.
Identity = ejabberd_hooks:run_fold(disco_local_identity,
Host,
[],
- [From, To, Node, Lang]),
+ [FromOld, ToOld, Node, Lang]),
+ % XXX OLD FORMAT: From, To.
case ejabberd_hooks:run_fold(disco_local_features,
Host,
empty,
- [From, To, Node, Lang]) of
+ [FromOld, ToOld, Node, Lang]) of
{result, Features} ->
ANode = case Node of
"" -> [];
- _ -> [{"node", Node}]
+ _ -> [#xmlattr{name = 'node', value = Node}]
end,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_INFO} | ANode],
- Identity ++
- lists:map(fun feature_to_xml/1, Features)
- }]};
+ Result = #xmlel{ns = ?NS_DISCO_INFO, name = 'query',
+ attrs = ANode,
+ children = Identity ++ lists:map(fun feature_to_xml/1,
+ Features)},
+ exmpp_iq:result(IQ, Result);
{error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
+ exmpp_iq:error(IQ, Error)
end
end.
get_local_identity(Acc, _From, _To, [], _Lang) ->
- Acc ++ [{xmlelement, "identity",
- [{"category", "server"},
- {"type", "im"},
- {"name", "ejabberd"}], []}];
+ Acc ++ [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs = [
+ #xmlattr{name = 'category', value = "server"},
+ #xmlattr{name = 'type', value = "im"},
+ #xmlattr{name = 'name', value = "ejabberd"}
+ ]}];
get_local_identity(Acc, _From, _To, _Node, _Lang) ->
Acc.
@@ -202,7 +214,7 @@ get_local_features(Acc, _From, To, [], _Lang) ->
{result, Features} -> Features;
empty -> []
end,
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
{result,
ets:select(disco_features, [{{{'_', Host}}, [], ['$_']}]) ++ Feats};
@@ -211,29 +223,36 @@ get_local_features(Acc, _From, _To, _Node, _Lang) ->
{result, _Features} ->
Acc;
empty ->
- {error, ?ERR_ITEM_NOT_FOUND}
+ {error, 'item-not-found'}
end.
feature_to_xml({{Feature, _Host}}) ->
feature_to_xml(Feature);
feature_to_xml(Feature) when is_list(Feature) ->
- {xmlelement, "feature", [{"var", Feature}], []}.
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [
+ #xmlattr{name = 'var', value = Feature}
+ ]}.
domain_to_xml({Domain}) ->
- {xmlelement, "item", [{"jid", Domain}], []};
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [
+ #xmlattr{name = 'jid', value = Domain}
+ ]};
domain_to_xml(Domain) ->
- {xmlelement, "item", [{"jid", Domain}], []}.
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [
+ #xmlattr{name = 'jid', value = Domain}
+ ]}.
get_local_services({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
Acc;
get_local_services(Acc, _From, To, [], _Lang) ->
+ % XXX OLD FORMAT: Items might be an #xmlelement.
Items = case Acc of
{result, Its} -> Its;
empty -> []
end,
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
{result,
lists:usort(
lists:map(fun domain_to_xml/1,
@@ -246,7 +265,7 @@ get_local_services({result, _} = Acc, _From, _To, _Node, _Lang) ->
Acc;
get_local_services(empty, _From, _To, _Node, _Lang) ->
- {error, ?ERR_ITEM_NOT_FOUND}.
+ {error, 'item-not-found'}.
get_vh_services(Host) ->
Hosts = lists:sort(fun(H1, H2) -> length(H1) >= length(H2) end, ?MYHOSTS),
@@ -264,46 +283,49 @@ get_vh_services(Host) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-process_sm_iq_items(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
+process_sm_iq_items(From, To, IQ) ->
+ SubEl = exmpp_iq:get_request(IQ),
+ case exmpp_iq:get_type(IQ) of
set ->
- #jid{luser = LTo, lserver = ToServer} = To,
- #jid{luser = LFrom, lserver = LServer} = From,
+ #jid{lnode = LTo, ldomain = ToServer} = To,
+ #jid{lnode = LFrom, ldomain = LServer} = From,
Self = (LTo == LFrom) andalso (ToServer == LServer),
- Node = xml:get_tag_attr_s("node", SubEl),
+ Node = exmpp_xml:get_attribute(SubEl, 'node'),
if
Self, Node /= [] ->
%% Here, we treat disco publish attempts to your own JID.
- {xmlelement, _, _, Items} = SubEl,
+ Items = SubEl#xmlel.children,
case process_disco_publish({LFrom, LServer}, Node, Items) of
ok ->
- IQ#iq{type = result, sub_el = []};
+ exmpp_iq:result(IQ);
{error, Err} ->
- IQ#iq{type = error, sub_el = [SubEl, Err]}
+ exmpp_iq:error(IQ, Err)
end;
true ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
+ exmpp_iq:error(IQ, 'not-allowed')
end;
get ->
- Host = To#jid.lserver,
- Node = xml:get_tag_attr_s("node", SubEl),
+ Host = To#jid.ldomain,
+ Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Lang = exmpp_stanza:get_lang(IQ),
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
case ejabberd_hooks:run_fold(disco_sm_items,
Host,
empty,
- [From, To, Node, Lang]) of
+ [FromOld, ToOld, Node, Lang]) of
{result, Items} ->
ANode = case Node of
"" -> [];
- _ -> [{"node", Node}]
+ _ -> [#xmlattr{name = 'node', value = Node}]
end,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_ITEMS} | ANode],
- Items
- }]};
+ Result = #xmlel{ns = ?NS_DISCO_ITEMS, name = 'query',
+ attrs = ANode, children = Items},
+ exmpp_iq:result(IQ, Result);
{error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
+ exmpp_iq:error(IQ, Error)
end
end.
@@ -311,8 +333,8 @@ get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
Acc;
get_sm_items(Acc,
- #jid{luser = LFrom, lserver = LSFrom},
- #jid{user = User, server = Server, luser = LTo, lserver = LSTo} = _To,
+ #jid{lnode = LFrom, ldomain = LSFrom},
+ #jid{node = User, domain = Server, lnode = LTo, ldomain = LSTo} = _To,
[], _Lang) ->
Items = case Acc of
{result, Its} -> Its;
@@ -328,43 +350,48 @@ get_sm_items({result, _} = Acc, _From, _To, _Node, _Lang) ->
Acc;
get_sm_items(empty, From, To, _Node, _Lang) ->
- #jid{luser = LFrom, lserver = LSFrom} = From,
- #jid{luser = LTo, lserver = LSTo} = To,
+ #jid{lnode = LFrom, ldomain = LSFrom} = From,
+ #jid{lnode = LTo, ldomain = LSTo} = To,
case {LFrom, LSFrom} of
{LTo, LSTo} ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
_ ->
- {error, ?ERR_NOT_ALLOWED}
+ {error, 'not-allowed'}
end.
-process_sm_iq_info(From, To, #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
- case Type of
+process_sm_iq_info(From, To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
get ->
- Host = To#jid.lserver,
- Node = xml:get_tag_attr_s("node", SubEl),
+ Host = To#jid.ldomain,
+ SubEl = exmpp_iq:get_request(IQ),
+ Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Lang = exmpp_stanza:get_lang(IQ),
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ % XXX OLD FORMAT: Identity might be an #xmlelement.
Identity = ejabberd_hooks:run_fold(disco_sm_identity,
Host,
[],
- [From, To, Node, Lang]),
+ [FromOld, ToOld, Node, Lang]),
case ejabberd_hooks:run_fold(disco_sm_features,
Host,
empty,
- [From, To, Node, Lang]) of
+ [FromOld, ToOld, Node, Lang]) of
{result, Features} ->
ANode = case Node of
"" -> [];
- _ -> [{"node", Node}]
+ _ -> [#xmlattr{name = 'node', value = Node}]
end,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_DISCO_INFO} | ANode],
- Identity ++
- lists:map(fun feature_to_xml/1, Features)
- }]};
+ Result = #xmlel{ns = ?NS_DISCO_INFO, name = 'query',
+ attrs = ANode,
+ children = Identity ++ lists:map(fun feature_to_xml/1,
+ Features)},
+ exmpp_iq:result(IQ, Result);
{error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
+ exmpp_iq:error(IQ, Error)
end
end.
@@ -372,13 +399,13 @@ get_sm_identity(Acc, _From, _To, _Node, _Lang) ->
Acc.
get_sm_features(empty, From, To, _Node, _Lang) ->
- #jid{luser = LFrom, lserver = LSFrom} = From,
- #jid{luser = LTo, lserver = LSTo} = To,
+ #jid{lnode = LFrom, ldomain = LSFrom} = From,
+ #jid{lnode = LTo, ldomain = LSTo} = To,
case {LFrom, LSFrom} of
{LTo, LSTo} ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
_ ->
- {error, ?ERR_NOT_ALLOWED}
+ {error, 'not-allowed'}
end;
get_sm_features(Acc, _From, _To, _Node, _Lang) ->
@@ -389,15 +416,17 @@ get_sm_features(Acc, _From, _To, _Node, _Lang) ->
get_user_resources(User, Server) ->
Rs = ejabberd_sm:get_user_resources(User, Server),
lists:map(fun(R) ->
- {xmlelement, "item",
- [{"jid", User ++ "@" ++ Server ++ "/" ++ R},
- {"name", User}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [
+ #xmlattr{name = 'jid', value =
+ exmpp_jid:jid_to_string(User, Server, R)},
+ #xmlattr{name = 'name', value = User}
+ ]}
end, lists:sort(Rs)).
get_publish_items(empty,
- #jid{luser = LFrom, lserver = LSFrom},
- #jid{luser = LTo, lserver = LSTo} = _To,
+ #jid{lnode = LFrom, ldomain = LSFrom},
+ #jid{lnode = LTo, ldomain = LSTo} = _To,
Node, _Lang) ->
if
(LFrom == LTo) and (LSFrom == LSTo) ->
@@ -411,11 +440,11 @@ get_publish_items(Acc, _From, _To, _Node, _Lang) ->
process_disco_publish(User, Node, Items) ->
F = fun() ->
lists:foreach(
- fun({xmlelement, _Name, _Attrs, _SubEls} = Item) ->
- Action = xml:get_tag_attr_s("action", Item),
- Jid = xml:get_tag_attr_s("jid", Item),
- PNode = xml:get_tag_attr_s("node", Item),
- Name = xml:get_tag_attr_s("name", Item),
+ fun(#xmlel{} = Item) ->
+ Action = exmpp_xml:get_attribute(Item, 'action'),
+ Jid = exmpp_xml:get_attribute(Item, 'jid'),
+ PNode = exmpp_xml:get_attribute(Item, 'node'),
+ Name = exmpp_xml:get_attribute(Item, 'name'),
?INFO_MSG("Disco publish: ~p ~p ~p ~p ~p ~p~n",
[User, Action, Node, Jid, PNode, Name]),
@@ -442,7 +471,7 @@ process_disco_publish(User, Node, Items) ->
"remove" ->
case SupersededItems of
[] ->
- mnesia:abort({error, ?ERR_ITEM_NOT_FOUND});
+ mnesia:abort({error, 'item-not-found'});
_ ->
lists:map(
fun(O) ->
@@ -451,9 +480,9 @@ process_disco_publish(User, Node, Items) ->
end;
_ ->
%% invalid "action" attribute - return an error
- mnesia:abort({error, ?ERR_BAD_REQUEST})
+ mnesia:abort({error, 'bad-request'})
end;
- ({xmlcdata, _CDATA}) ->
+ (#xmlcdata{}) ->
ok
end, Items)
end,
@@ -463,13 +492,13 @@ process_disco_publish(User, Node, Items) ->
{atomic, _} ->
ok;
_ ->
- {error, ?ERR_INTERNAL_SERVER_ERROR}
+ {error, 'internal-server-error'}
end.
retrieve_disco_publish(User, Node) ->
case catch mnesia:dirty_read({disco_publish, {User, Node}}) of
{'EXIT', _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
[] ->
empty;
Items ->
@@ -478,20 +507,20 @@ retrieve_disco_publish(User, Node) ->
fun(#disco_publish{jid = Jid,
name = Name,
node = PNode}) ->
- {xmlelement, "item",
- lists:append([[{"jid", Jid}],
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ lists:append([[#xmlattr{name = 'jid', value = Jid}],
case Name of
"" ->
[];
_ ->
- [{"name", Name}]
+ [#xmlattr{name = 'name', value = Name}]
end,
case PNode of
"" ->
[];
_ ->
- [{"node", PNode}]
- end]), []}
+ [#xmlattr{name = 'node', value = PNode}]
+ end])}
end, Items)}
end.
From adaf3921560a8a60bb7bdd6206f3488e3fff367d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 22 Jul 2008 14:51:19 +0000
Subject: [PATCH 051/582] o Finish conversion to exmpp for mod_caps. o In
ejabberd_loca, IQ response handler are now always called with arguments in
the new format.
SVN Revision: 1469
---
ChangeLog | 6 ++++++
src/ejabberd_local.erl | 6 +-----
src/gen_iq_handler.erl | 1 +
src/mod_caps.erl | 24 ++++++++----------------
4 files changed, 16 insertions(+), 21 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e19d2da6b..514c75211 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,12 @@
* src/mod_disco.erl, src/gen_iq_handler.erl: Convert to exmpp.
+ * src/mod_caps.erl, src/gen_iq_handler.erl: Finish conversion to
+ exmpp.
+
+ * src/ejabberd_local.erl (process_iq_reply): IQ handler are now always
+ called with arguments in the new format.
+
2008-07-21 Jean-Sébastien Pédron
* src/gen_iq_handler.erl: Prepare gen_iq_handler to pass arguments in
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index c3786ca53..f047569f9 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -131,11 +131,7 @@ process_iq_reply(From, To, Packet) ->
end,
case mnesia:transaction(F) of
{atomic, {Module, Function}} ->
- % XXX OLD FORMAT: From, To, Packet.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- IQ_Rec = jlib:iq_query_or_response_info(Packet),
- Module:Function(FromOld, ToOld, IQ_Rec);
+ Module:Function(From, To, Packet);
_ ->
ok
end
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index 19a0da6c4..8cc1c4c65 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -59,6 +59,7 @@
% XXX OLD FORMAT: modules not in the following list will receive
% old format strudctures.
-define(CONVERTED_MODULES, [
+ mod_caps,
mod_disco,
mod_roster,
mod_vcard
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 9d7846a48..9b3bef70b 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -62,13 +62,6 @@
disco_requests = ?DICT:new(),
feature_queries = []}).
-% XXX OLD FORMAT: Re-include jlib.hrl (after clean-up).
--record(iq, {id = "",
- type,
- xmlns = "",
- lang = "",
- sub_el}).
-
%% read_caps takes a list of XML elements (the child elements of a
%% stanza) and returns an opaque value representing the
%% Entity Capabilities contained therein, or the atom nothing if no
@@ -224,17 +217,16 @@ handle_cast({note_caps, From,
?ERROR_MSG("Transaction failed: ~p", [Error]),
{noreply, State}
end;
-handle_cast({disco_response, From, _To,
- #iq{type = Type, id = ID,
- sub_el = SubEls}},
+handle_cast({disco_response, From, _To, IQ},
#state{disco_requests = Requests} = State) ->
- case {Type, SubEls} of
- {result, [{xmlelement, "query", _Attrs, Els}]} ->
+ ID = exmpp_stanza:get_id(IQ),
+ case {exmpp_iq:get_type(IQ), exmpp_iq:get_payload(IQ)} of
+ {result, #xmlel{name = 'query', children = Els}} ->
case ?DICT:find(ID, Requests) of
{ok, {Node, SubNode}} ->
Features =
- lists:flatmap(fun({xmlelement, "feature", FAttrs, _}) ->
- [xml:get_attr_s("var", FAttrs)];
+ lists:flatmap(fun(#xmlel{name = 'feature'} = F) ->
+ [exmpp_xml:get_attribute(F, 'var')];
(_) ->
[]
end, Els),
@@ -262,9 +254,9 @@ handle_cast({disco_response, From, _To,
?ERROR_MSG("ID '~s' matches no query", [ID])
end;
%gen_server:cast(self(), visit_feature_queries),
- %?DEBUG("Error IQ reponse from ~s:~n~p", [jlib:jid_to_string(From), SubEls]);
+ %?DEBUG("Error IQ reponse from ~s:~n~p", [exmpp_jid:jid_to_string(From), SubEls]);
{result, _} ->
- ?DEBUG("Invalid IQ contents from ~s:~n~p", [jlib:jid_to_string(From), SubEls]);
+ ?DEBUG("Invalid IQ contents from ~s:~n~p", [exmpp_jid:jid_to_string(From), IQ#xmlel.children]);
_ ->
%% Can't do anything about errors
ok
From 70956ece120fbe155b56f8c6d7f432965025d883 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Fri, 25 Jul 2008 14:26:59 +0000
Subject: [PATCH 052/582] Convert to exmpp.
SVN Revision: 1492
---
ChangeLog | 5 +
src/adhoc.erl | 87 ++--
src/gen_iq_handler.erl | 3 +
src/mod_adhoc.erl | 121 +++---
src/mod_announce.erl | 313 +++++++-------
src/mod_configure.erl | 938 ++++++++++++++++++++---------------------
6 files changed, 739 insertions(+), 728 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 514c75211..8e9dce87a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-07-25 Jean-Sébastien Pédron
+
+ * src/adhoc.erl, src/mod_configure.erl, src/mod_announce.erl,
+ src/mod_adhoc.erl, src/gen_iq_handler.erl: Convert to exmpp.
+
2008-07-22 Jean-Sébastien Pédron
* src/mod_disco.erl, src/gen_iq_handler.erl: Convert to exmpp.
diff --git a/src/adhoc.erl b/src/adhoc.erl
index b4641253f..a35dc763f 100644
--- a/src/adhoc.erl
+++ b/src/adhoc.erl
@@ -31,47 +31,53 @@
produce_response/2,
produce_response/1]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("adhoc.hrl").
%% Parse an ad-hoc request. Return either an adhoc_request record or
%% an {error, ErrorType} tuple.
-parse_request(#iq{type = set, lang = Lang, sub_el = SubEl, xmlns = ?NS_COMMANDS}) ->
- ?DEBUG("entering parse_request...", []),
- Node = xml:get_tag_attr_s("node", SubEl),
- SessionID = xml:get_tag_attr_s("sessionid", SubEl),
- Action = xml:get_tag_attr_s("action", SubEl),
- XData = find_xdata_el(SubEl),
- {xmlelement, _, _, AllEls} = SubEl,
- if XData ->
- Others = lists:delete(XData, AllEls);
- true ->
- Others = AllEls
- end,
+parse_request(IQ) ->
+ try
+ SubEl = exmpp_iq:get_request(IQ),
+ case {exmpp_iq:get_type(IQ), SubEl#xmlel.ns} of
+ {set, ?NS_ADHOC} ->
+ ?DEBUG("entering parse_request...", []),
+ Lang = exmpp_stanza:get_lang(IQ),
+ Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ SessionID = exmpp_xml:get_attribute(SubEl, 'sessionid'),
+ Action = exmpp_xml:get_attribute(SubEl, 'action'),
+ XData = find_xdata_el(SubEl),
+ AllEls = SubEl#xmlel.ns,
+ if XData ->
+ Others = lists:delete(XData, AllEls);
+ true ->
+ Others = AllEls
+ end,
- #adhoc_request{lang = Lang,
- node = Node,
- sessionid = SessionID,
- action = Action,
- xdata = XData,
- others = Others};
-parse_request(_) ->
- {error, ?ERR_BAD_REQUEST}.
+ #adhoc_request{lang = Lang,
+ node = Node,
+ sessionid = SessionID,
+ action = Action,
+ xdata = XData,
+ others = Others};
+ _ ->
+ {error, 'bad-request'}
+ end
+ catch
+ _ ->
+ {error, 'bad-request'}
+ end.
%% Borrowed from mod_vcard.erl
-find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
+find_xdata_el(#xmlel{children = SubEls}) ->
find_xdata_el1(SubEls).
find_xdata_el1([]) ->
false;
-find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
- case xml:get_attr_s("xmlns", Attrs) of
- ?NS_XDATA ->
- {xmlelement, Name, Attrs, SubEls};
- _ ->
- find_xdata_el1(Els)
- end;
+find_xdata_el1([#xmlel{ns = ?NS_DATA_FORMS} = El | _Els]) ->
+ El;
find_xdata_el1([_ | Els]) ->
find_xdata_el1(Els).
@@ -109,20 +115,19 @@ produce_response(#adhoc_response{lang = _Lang,
"" ->
ActionsElAttrs = [];
_ ->
- ActionsElAttrs = [{"execute", DefaultAction}]
+ ActionsElAttrs = [#xmlattr{name = 'execute', value = DefaultAction}]
end,
- ActionsEls = [{xmlelement, "actions",
- ActionsElAttrs,
- [{xmlelement, Action, [], []} || Action <- Actions]}]
+ ActionsEls = [#xmlel{ns = ?NS_ADHOC, name = 'actions', attrs =
+ ActionsElAttrs, children =
+ [#xmlel{ns = ?NS_ADHOC, name = Action} || Action <- Actions]}]
end,
NotesEls = lists:map(fun({Type, Text}) ->
- {xmlelement, "note",
- [{"type", Type}],
- [{xmlcdata, Text}]}
+ #xmlel{ns = ?NS_ADHOC, name = 'note', attrs =
+ [#xmlattr{name = 'type', value = Type}],
+ children = [#xmlcdata{cdata = list_to_binary(Text)}]}
end, Notes),
- {xmlelement, "command",
- [{"xmlns", ?NS_COMMANDS},
- {"sessionid", SessionID},
- {"node", Node},
- {"status", atom_to_list(Status)}],
+ #xmlel{ns = ?NS_ADHOC, name = 'command', attrs =
+ [#xmlattr{name = 'sessionid', value = SessionID},
+ #xmlattr{name = 'node', value = Node},
+ #xmlattr{name = 'status', value = atom_to_list(Status)}], children =
ActionsEls ++ NotesEls ++ Elements}.
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index 8cc1c4c65..33d445942 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -59,7 +59,10 @@
% XXX OLD FORMAT: modules not in the following list will receive
% old format strudctures.
-define(CONVERTED_MODULES, [
+ mod_adhoc,
+ mod_annouce,
mod_caps,
+ mod_configure,
mod_disco,
mod_roster,
mod_vcard
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl
index be1bc1cb8..87f66899b 100644
--- a/src/mod_adhoc.erl
+++ b/src/mod_adhoc.erl
@@ -42,16 +42,17 @@
ping_item/4,
ping_command/4]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("adhoc.hrl").
start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ADHOC_s,
?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ADHOC_s,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
@@ -73,12 +74,12 @@ stop(Host) ->
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 99),
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS).
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC_s),
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC_s).
%-------------------------------------------------------------------------
-get_local_commands(Acc, _From, #jid{server = Server, lserver = LServer} = _To, "", Lang) ->
+get_local_commands(Acc, _From, #jid{domain = Server, ldomain = LServer} = _To, "", Lang) ->
Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false),
case Display of
false ->
@@ -88,17 +89,20 @@ get_local_commands(Acc, _From, #jid{server = Server, lserver = LServer} = _To, "
{result, I} -> I;
_ -> []
end,
- Nodes = [{xmlelement,
- "item",
- [{"jid", Server},
- {"node", ?NS_COMMANDS},
- {"name", translate:translate(Lang, "Commands")}],
- []}],
+ Nodes = [#xmlel{ns = ?NS_DISCO_ITEMS,
+ name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = Server},
+ #xmlattr{name = 'node', value = ?NS_ADHOC_s},
+ #xmlattr{name = 'name', value = translate:translate(Lang, "Commands")}]
+ }],
{result, Items ++ Nodes}
end;
-get_local_commands(_Acc, From, #jid{lserver = LServer} = To, ?NS_COMMANDS, Lang) ->
- ejabberd_hooks:run_fold(adhoc_local_items, LServer, {result, []}, [From, To, Lang]);
+get_local_commands(_Acc, From, #jid{ldomain = LServer} = To, ?NS_ADHOC_s, Lang) ->
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ ejabberd_hooks:run_fold(adhoc_local_items, LServer, {result, []}, [FromOld, ToOld, Lang]);
get_local_commands(_Acc, _From, _To, "ping", _Lang) ->
{result, []};
@@ -108,7 +112,7 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) ->
%-------------------------------------------------------------------------
-get_sm_commands(Acc, _From, #jid{lserver = LServer} = To, "", Lang) ->
+get_sm_commands(Acc, _From, #jid{ldomain = LServer} = To, "", Lang) ->
Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false),
case Display of
false ->
@@ -118,17 +122,20 @@ get_sm_commands(Acc, _From, #jid{lserver = LServer} = To, "", Lang) ->
{result, I} -> I;
_ -> []
end,
- Nodes = [{xmlelement,
- "item",
- [{"jid", jlib:jid_to_string(To)},
- {"node", ?NS_COMMANDS},
- {"name", translate:translate(Lang, "Commands")}],
- []}],
+ Nodes = [#xmlel{ns = ?NS_DISCO_ITEMS,
+ name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(To)},
+ #xmlattr{name = 'node', value = ?NS_ADHOC_s},
+ #xmlattr{name = 'name', value = translate:translate(Lang, "Commands")}]
+ }],
{result, Items ++ Nodes}
end;
-get_sm_commands(_Acc, From, #jid{lserver = LServer} = To, ?NS_COMMANDS, Lang) ->
- ejabberd_hooks:run_fold(adhoc_sm_items, LServer, {result, []}, [From, To, Lang]);
+get_sm_commands(_Acc, From, #jid{ldomain = LServer} = To, ?NS_ADHOC_s, Lang) ->
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ ejabberd_hooks:run_fold(adhoc_sm_items, LServer, {result, []}, [FromOld, ToOld, Lang]);
get_sm_commands(Acc, _From, _To, _Node, _Lang) ->
Acc.
@@ -136,17 +143,17 @@ get_sm_commands(Acc, _From, _To, _Node, _Lang) ->
%-------------------------------------------------------------------------
%% On disco info request to the ad-hoc node, return automation/command-list.
-get_local_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
- [{xmlelement, "identity",
- [{"category", "automation"},
- {"type", "command-list"},
- {"name", translate:translate(Lang, "Commands")}], []} | Acc];
+get_local_identity(Acc, _From, _To, ?NS_ADHOC_s, Lang) ->
+ [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs =
+ [#xmlattr{name = 'category', value = "automation"},
+ #xmlattr{name = 'type', value = "command-list"},
+ #xmlattr{name = 'name', value = translate:translate(Lang, "Commands")}]} | Acc];
get_local_identity(Acc, _From, _To, "ping", Lang) ->
- [{xmlelement, "identity",
- [{"category", "automation"},
- {"type", "command-node"},
- {"name", translate:translate(Lang, "Ping")}], []} | Acc];
+ [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs =
+ [#xmlattr{name = 'category', value = "automation"},
+ #xmlattr{name = 'type', value = "command-node"},
+ #xmlattr{name = 'name', value = translate:translate(Lang, "Ping")}]} | Acc];
get_local_identity(Acc, _From, _To, _Node, _Lang) ->
Acc.
@@ -154,11 +161,11 @@ get_local_identity(Acc, _From, _To, _Node, _Lang) ->
%-------------------------------------------------------------------------
%% On disco info request to the ad-hoc node, return automation/command-list.
-get_sm_identity(Acc, _From, _To, ?NS_COMMANDS, Lang) ->
- [{xmlelement, "identity",
- [{"category", "automation"},
- {"type", "command-list"},
- {"name", translate:translate(Lang, "Commands")}], []} | Acc];
+get_sm_identity(Acc, _From, _To, ?NS_ADHOC_s, Lang) ->
+ [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs =
+ [#xmlattr{name = 'category', value = "automation"},
+ #xmlattr{name = 'type', value = "command-list"},
+ #xmlattr{name = 'name', value = translate:translate(Lang, "Commands")}]} | Acc];
get_sm_identity(Acc, _From, _To, _Node, _Lang) ->
Acc.
@@ -170,15 +177,15 @@ get_local_features(Acc, _From, _To, "", _Lang) ->
{result, I} -> I;
_ -> []
end,
- {result, Feats ++ [?NS_COMMANDS]};
+ {result, Feats ++ [?NS_ADHOC_s]};
-get_local_features(_Acc, _From, _To, ?NS_COMMANDS, _Lang) ->
+get_local_features(_Acc, _From, _To, ?NS_ADHOC_s, _Lang) ->
%% override all lesser features...
{result, []};
get_local_features(_Acc, _From, _To, "ping", _Lang) ->
%% override all lesser features...
- {result, [?NS_COMMANDS]};
+ {result, [?NS_ADHOC_s]};
get_local_features(Acc, _From, _To, _Node, _Lang) ->
Acc.
@@ -190,9 +197,9 @@ get_sm_features(Acc, _From, _To, "", _Lang) ->
{result, I} -> I;
_ -> []
end,
- {result, Feats ++ [?NS_COMMANDS]};
+ {result, Feats ++ [?NS_ADHOC_s]};
-get_sm_features(_Acc, _From, _To, ?NS_COMMANDS, _Lang) ->
+get_sm_features(_Acc, _From, _To, ?NS_ADHOC_s, _Lang) ->
%% override all lesser features...
{result, []};
@@ -209,39 +216,41 @@ process_sm_iq(From, To, IQ) ->
process_adhoc_request(From, To, IQ, adhoc_sm_commands).
-process_adhoc_request(From, To, #iq{sub_el = SubEl} = IQ, Hook) ->
+process_adhoc_request(From, To, IQ, Hook) ->
?DEBUG("About to parse ~p...", [IQ]),
case adhoc:parse_request(IQ) of
{error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]};
+ exmpp_iq:error(IQ, Error);
#adhoc_request{} = AdhocRequest ->
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
case ejabberd_hooks:run_fold(Hook, Host, empty,
- [From, To, AdhocRequest]) of
+ [FromOld, ToOld, AdhocRequest]) of
ignore ->
ignore;
empty ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]};
+ exmpp_iq:error(IQ, 'item-not-found');
{error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]};
+ exmpp_iq:error(IQ, Error);
Command ->
- IQ#iq{type = result, sub_el = [Command]}
+ exmpp_iq:result(IQ, Command)
end
end.
-ping_item(Acc, _From, #jid{server = Server} = _To, Lang) ->
+ping_item(Acc, _From, #jid{domain = Server} = _To, Lang) ->
Items = case Acc of
{result, I} ->
I;
_ ->
[]
end,
- Nodes = [{xmlelement, "item",
- [{"jid", Server},
- {"node", "ping"},
- {"name", translate:translate(Lang, "Ping")}],
- []}],
+ Nodes = [#xmlel{ns = ?NS_DISCO_INFO, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = Server},
+ #xmlattr{name = 'node', value = "ping"},
+ #xmlattr{name = 'name', value = translate:translate(Lang, "Ping")}]}],
{result, Items ++ Nodes}.
@@ -259,7 +268,7 @@ ping_command(_Acc, _From, _To,
Lang,
"Pong")}]});
true ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
ping_command(Acc, _From, _To, _Request) ->
diff --git a/src/mod_announce.erl b/src/mod_announce.erl
index 438f834a2..5a744e6e0 100644
--- a/src/mod_announce.erl
+++ b/src/mod_announce.erl
@@ -43,8 +43,9 @@
announce_commands/4,
announce_items/4]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("adhoc.hrl").
-record(motd, {server, packet}).
@@ -52,6 +53,8 @@
-define(PROCNAME, ejabberd_announce).
+-define(NS_ADMIN_s, "http://jabber.org/protocol/admin").
+
-define(NS_ADMINL(Sub), ["http:","jabber.org","protocol","admin", Sub]).
tokenize(Node) -> string:tokens(Node, "/#").
@@ -129,38 +132,38 @@ stop(Host) ->
%% Announcing via messages to a custom resource
announce(From, To, Packet) ->
case To of
- #jid{luser = "", lresource = Res} ->
- {xmlelement, Name, _Attrs, _Els} = Packet,
- Proc = gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME),
+ #jid{lnode = undefined, lresource = Res} ->
+ Name = Packet#xmlel.name,
+ Proc = gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME),
case {Res, Name} of
- {"announce/all", "message"} ->
+ {"announce/all", 'message'} ->
Proc ! {announce_all, From, To, Packet},
stop;
- {"announce/all-hosts/all", "message"} ->
+ {"announce/all-hosts/all", 'message'} ->
Proc ! {announce_all_hosts_all, From, To, Packet},
stop;
- {"announce/online", "message"} ->
+ {"announce/online", 'message'} ->
Proc ! {announce_online, From, To, Packet},
stop;
- {"announce/all-hosts/online", "message"} ->
+ {"announce/all-hosts/online", 'message'} ->
Proc ! {announce_all_hosts_online, From, To, Packet},
stop;
- {"announce/motd", "message"} ->
+ {"announce/motd", 'message'} ->
Proc ! {announce_motd, From, To, Packet},
stop;
- {"announce/all-hosts/motd", "message"} ->
+ {"announce/all-hosts/motd", 'message'} ->
Proc ! {announce_all_hosts_motd, From, To, Packet},
stop;
- {"announce/motd/update", "message"} ->
+ {"announce/motd/update", 'message'} ->
Proc ! {announce_motd_update, From, To, Packet},
stop;
- {"announce/all-hosts/motd/update", "message"} ->
+ {"announce/all-hosts/motd/update", 'message'} ->
Proc ! {announce_all_hosts_motd_update, From, To, Packet},
stop;
- {"announce/motd/delete", "message"} ->
+ {"announce/motd/delete", 'message'} ->
Proc ! {announce_motd_delete, From, To, Packet},
stop;
- {"announce/all-hosts/motd/delete", "message"} ->
+ {"announce/all-hosts/motd/delete", 'message'} ->
Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
stop;
_ ->
@@ -173,10 +176,10 @@ announce(From, To, Packet) ->
%%-------------------------------------------------------------------------
%% Announcing via ad-hoc commands
-define(INFO_COMMAND(Lang, Node),
- [{xmlelement, "identity",
- [{"category", "automation"},
- {"type", "command-node"},
- {"name", get_title(Lang, Node)}], []}]).
+ [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs =
+ [#xmlattr{name = 'category', value = "automation"},
+ #xmlattr{name = 'type', value = "command-node"},
+ #xmlattr{name = 'name', value = get_title(Lang, Node)}]}]).
disco_identity(Acc, _From, _To, Node, Lang) ->
LNode = tokenize(Node),
@@ -210,12 +213,12 @@ disco_identity(Acc, _From, _To, Node, Lang) ->
-define(INFO_RESULT(Allow, Feats),
case Allow of
deny ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
allow ->
{result, Feats}
end).
-disco_features(Acc, From, #jid{lserver = LServer} = _To,
+disco_features(Acc, From, #jid{ldomain = LServer} = _To,
"announce", _Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
@@ -226,13 +229,13 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To,
case {acl:match_rule(LServer, Access1, From),
acl:match_rule(global, Access2, From)} of
{deny, deny} ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
_ ->
{result, []}
end
end;
-disco_features(Acc, From, #jid{lserver = LServer} = _To,
+disco_features(Acc, From, #jid{ldomain = LServer} = _To,
Node, _Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
@@ -243,26 +246,26 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To,
AccessGlobal = gen_mod:get_module_opt(global, ?MODULE, access, none),
AllowGlobal = acl:match_rule(global, AccessGlobal, From),
case Node of
- ?NS_ADMIN ++ "#announce" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#announce-all" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#set-motd" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#edit-motd" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#delete-motd" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#announce-allhosts" ->
- ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#announce-all-allhosts" ->
- ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#set-motd-allhosts" ->
- ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#edit-motd-allhosts" ->
- ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
- ?NS_ADMIN ++ "#delete-motd-allhosts" ->
- ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]);
+ ?NS_ADMIN_s ++ "#announce" ->
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#announce-all" ->
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#set-motd" ->
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#edit-motd" ->
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#delete-motd" ->
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#announce-allhosts" ->
+ ?INFO_RESULT(AllowGlobal, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#announce-all-allhosts" ->
+ ?INFO_RESULT(AllowGlobal, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#set-motd-allhosts" ->
+ ?INFO_RESULT(AllowGlobal, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#edit-motd-allhosts" ->
+ ?INFO_RESULT(AllowGlobal, [?NS_ADHOC_s]);
+ ?NS_ADMIN_s ++ "#delete-motd-allhosts" ->
+ ?INFO_RESULT(AllowGlobal, [?NS_ADHOC_s]);
_ ->
Acc
end
@@ -271,21 +274,20 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To,
%%-------------------------------------------------------------------------
-define(NODE_TO_ITEM(Lang, Server, Node),
- {xmlelement, "item",
- [{"jid", Server},
- {"node", Node},
- {"name", get_title(Lang, Node)}],
- []}).
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = Server},
+ #xmlattr{name = 'node', value = Node},
+ #xmlattr{name = 'name', value = get_title(Lang, Node)}]}).
-define(ITEMS_RESULT(Allow, Items),
case Allow of
deny ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
allow ->
{result, Items}
end).
-disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To,
+disco_items(Acc, From, #jid{ldomain = LServer, domain = Server} = _To,
"", Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
@@ -307,7 +309,7 @@ disco_items(Acc, From, #jid{lserver = LServer, server = Server} = _To,
end
end;
-disco_items(Acc, From, #jid{lserver = LServer} = To, "announce", Lang) ->
+disco_items(Acc, From, #jid{ldomain = LServer} = To, "announce", Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@@ -315,7 +317,7 @@ disco_items(Acc, From, #jid{lserver = LServer} = To, "announce", Lang) ->
announce_items(Acc, From, To, Lang)
end;
-disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
+disco_items(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@@ -325,25 +327,25 @@ disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
AccessGlobal = gen_mod:get_module_opt(global, ?MODULE, access, none),
AllowGlobal = acl:match_rule(global, AccessGlobal, From),
case Node of
- ?NS_ADMIN ++ "#announce" ->
+ ?NS_ADMIN_s ++ "#announce" ->
?ITEMS_RESULT(Allow, []);
- ?NS_ADMIN ++ "#announce-all" ->
+ ?NS_ADMIN_s ++ "#announce-all" ->
?ITEMS_RESULT(Allow, []);
- ?NS_ADMIN ++ "#set-motd" ->
+ ?NS_ADMIN_s ++ "#set-motd" ->
?ITEMS_RESULT(Allow, []);
- ?NS_ADMIN ++ "#edit-motd" ->
+ ?NS_ADMIN_s ++ "#edit-motd" ->
?ITEMS_RESULT(Allow, []);
- ?NS_ADMIN ++ "#delete-motd" ->
+ ?NS_ADMIN_s ++ "#delete-motd" ->
?ITEMS_RESULT(Allow, []);
- ?NS_ADMIN ++ "#announce-allhosts" ->
+ ?NS_ADMIN_s ++ "#announce-allhosts" ->
?ITEMS_RESULT(AllowGlobal, []);
- ?NS_ADMIN ++ "#announce-all-allhosts" ->
+ ?NS_ADMIN_s ++ "#announce-all-allhosts" ->
?ITEMS_RESULT(AllowGlobal, []);
- ?NS_ADMIN ++ "#set-motd-allhosts" ->
+ ?NS_ADMIN_s ++ "#set-motd-allhosts" ->
?ITEMS_RESULT(AllowGlobal, []);
- ?NS_ADMIN ++ "#edit-motd-allhosts" ->
+ ?NS_ADMIN_s ++ "#edit-motd-allhosts" ->
?ITEMS_RESULT(AllowGlobal, []);
- ?NS_ADMIN ++ "#delete-motd-allhosts" ->
+ ?NS_ADMIN_s ++ "#delete-motd-allhosts" ->
?ITEMS_RESULT(AllowGlobal, []);
_ ->
Acc
@@ -352,26 +354,26 @@ disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
%%-------------------------------------------------------------------------
-announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang) ->
+announce_items(Acc, From, #jid{ldomain = LServer, domain = Server} = _To, Lang) ->
Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
Nodes1 = case acl:match_rule(LServer, Access1, From) of
allow ->
- [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce"),
- ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-all"),
- ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#set-motd"),
- ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#edit-motd"),
- ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#delete-motd")];
+ [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#announce"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#announce-all"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#set-motd"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#edit-motd"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#delete-motd")];
deny ->
[]
end,
Access2 = gen_mod:get_module_opt(global, ?MODULE, access, none),
Nodes2 = case acl:match_rule(global, Access2, From) of
allow ->
- [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-allhosts"),
- ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#announce-all-allhosts"),
- ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#set-motd-allhosts"),
- ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#edit-motd-allhosts"),
- ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN ++ "#delete-motd-allhosts")];
+ [?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#announce-allhosts"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#announce-all-allhosts"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#set-motd-allhosts"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#edit-motd-allhosts"),
+ ?NODE_TO_ITEM(Lang, Server, ?NS_ADMIN_s ++ "#delete-motd-allhosts")];
deny ->
[]
end,
@@ -391,13 +393,13 @@ announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang)
commands_result(Allow, From, To, Request) ->
case Allow of
deny ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
allow ->
announce_commands(From, To, Request)
end.
-announce_commands(Acc, From, #jid{lserver = LServer} = To,
+announce_commands(Acc, From, #jid{ldomain = LServer} = To,
#adhoc_request{ node = Node} = Request) ->
LNode = tokenize(Node),
F = fun() ->
@@ -453,7 +455,7 @@ announce_commands(From, To,
#adhoc_response{status = canceled});
XData == false, ActionIsExecute ->
%% User requests form
- Elements = generate_adhoc_form(Lang, Node, To#jid.lserver),
+ Elements = generate_adhoc_form(Lang, Node, To#jid.ldomain),
adhoc:produce_response(
Request,
#adhoc_response{status = executing,
@@ -462,26 +464,26 @@ announce_commands(From, To,
%% User returns form.
case jlib:parse_xdata_submit(XData) of
invalid ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
Fields ->
handle_adhoc_form(From, To, Request, Fields)
end;
true ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end.
-define(VVALUE(Val),
- {xmlelement, "value", [], [{xmlcdata, Val}]}).
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Val)}]}).
-define(VVALUEL(Val),
case Val of
"" -> [];
_ -> [?VVALUE(Val)]
end).
-define(TVFIELD(Type, Var, Val),
- {xmlelement, "field", [{"type", Type},
- {"var", Var}],
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'var', value = Var}], children =
?VVALUEL(Val)}).
--define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN)).
+-define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN_s)).
generate_adhoc_form(Lang, Node, ServerHost) ->
LNode = tokenize(Node),
@@ -491,31 +493,29 @@ generate_adhoc_form(Lang, Node, ServerHost) ->
true ->
{[], []}
end,
- {xmlelement, "x",
- [{"xmlns", ?NS_XDATA},
- {"type", "form"}],
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs =
+ [#xmlattr{name = 'type', value = "form"}], children =
[?HFIELD(),
- {xmlelement, "title", [], [{xmlcdata, get_title(Lang, Node)}]}]
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children = [#xmlcdata{cdata = list_to_binary(get_title(Lang, Node))}]}]
++
if (LNode == ?NS_ADMINL("delete-motd"))
or (LNode == ?NS_ADMINL("delete-motd-allhosts")) ->
- [{xmlelement, "field",
- [{"var", "confirm"},
- {"type", "boolean"},
- {"label", translate:translate(Lang, "Really delete message of the day?")}],
- [{xmlelement, "value",
- [],
- [{xmlcdata, "true"}]}]}];
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "confirm"},
+ #xmlattr{name = 'type', value = "boolean"},
+ #xmlattr{name = 'label', value = translate:translate(Lang, "Really delete message of the day?")}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children =
+ [#xmlcdata{cdata = <<"true">>}]}]}];
true ->
- [{xmlelement, "field",
- [{"var", "subject"},
- {"type", "text-single"},
- {"label", translate:translate(Lang, "Subject")}],
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "subject"},
+ #xmlattr{name = 'type', value = "text-single"},
+ #xmlattr{name = 'label', value = translate:translate(Lang, "Subject")}], children =
?VVALUEL(OldSubject)},
- {xmlelement, "field",
- [{"var", "body"},
- {"type", "text-multi"},
- {"label", translate:translate(Lang, "Message body")}],
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "body"},
+ #xmlattr{name = 'type', value = "text-multi"},
+ #xmlattr{name = 'label', value = translate:translate(Lang, "Message body")}], children =
?VVALUEL(OldBody)}]
end}.
@@ -529,7 +529,7 @@ join_lines([], Acc) ->
%% Remove last newline
lists:flatten(lists:reverse(tl(Acc))).
-handle_adhoc_form(From, #jid{lserver = LServer} = To,
+handle_adhoc_form(From, #jid{ldomain = LServer} = To,
#adhoc_request{lang = Lang,
node = Node,
sessionid = SessionID},
@@ -560,30 +560,30 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To,
node = Node,
sessionid = SessionID,
status = completed},
- Packet = {xmlelement, "message", [{"type", "normal"}],
+ Packet = #xmlel{ns = ?NS_JABBER_CLIENT, name = 'message', attrs = [#xmlattr{name = 'type', value = "normal"}], children =
if Subject /= [] ->
- [{xmlelement, "subject", [],
- [{xmlcdata, Subject}]}];
+ [#xmlel{ns = ?NS_JABBER_CLIENT, name = 'subject', children =
+ [#xmlcdata{cdata = list_to_binary(Subject)}]}];
true ->
[]
end ++
if Body /= [] ->
- [{xmlelement, "body", [],
- [{xmlcdata, Body}]}];
+ [#xmlel{ns = ?NS_JABBER_CLIENT, name = 'body', children =
+ [#xmlcdata{cdata = list_to_binary(Body)}]}];
true ->
[]
end},
Proc = gen_mod:get_module_proc(LServer, ?PROCNAME),
case {Node, Body} of
- {?NS_ADMIN ++ "#delete-motd", _} ->
+ {?NS_ADMIN_s ++ "#delete-motd", _} ->
if Confirm ->
Proc ! {announce_motd_delete, From, To, Packet},
adhoc:produce_response(Response);
true ->
adhoc:produce_response(Response)
end;
- {?NS_ADMIN ++ "#delete-motd-allhosts", _} ->
+ {?NS_ADMIN_s ++ "#delete-motd-allhosts", _} ->
if Confirm ->
Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
adhoc:produce_response(Response);
@@ -593,79 +593,78 @@ handle_adhoc_form(From, #jid{lserver = LServer} = To,
{_, []} ->
%% An announce message with no body is definitely an operator error.
%% Throw an error and give him/her a chance to send message again.
- {error, ?ERRT_NOT_ACCEPTABLE(
- Lang,
- "No body provided for announce message")};
+ {error, exmpp_stanza:error(?NS_JABBER_CLIENT, 'not-acceptable',
+ {"en", "No body provided for announce message"})};
%% Now send the packet to ?PROCNAME.
%% We don't use direct announce_* functions because it
%% leads to large delay in response and queries processing
- {?NS_ADMIN ++ "#announce", _} ->
+ {?NS_ADMIN_s ++ "#announce", _} ->
Proc ! {announce_online, From, To, Packet},
adhoc:produce_response(Response);
- {?NS_ADMIN ++ "#announce-allhosts", _} ->
+ {?NS_ADMIN_s ++ "#announce-allhosts", _} ->
Proc ! {announce_all_hosts_online, From, To, Packet},
adhoc:produce_response(Response);
- {?NS_ADMIN ++ "#announce-all", _} ->
+ {?NS_ADMIN_s ++ "#announce-all", _} ->
Proc ! {announce_all, From, To, Packet},
adhoc:produce_response(Response);
- {?NS_ADMIN ++ "#announce-all-allhosts", _} ->
+ {?NS_ADMIN_s ++ "#announce-all-allhosts", _} ->
Proc ! {announce_all_hosts_all, From, To, Packet},
adhoc:produce_response(Response);
- {?NS_ADMIN ++ "#set-motd", _} ->
+ {?NS_ADMIN_s ++ "#set-motd", _} ->
Proc ! {announce_motd, From, To, Packet},
adhoc:produce_response(Response);
- {?NS_ADMIN ++ "#set-motd-allhosts", _} ->
+ {?NS_ADMIN_s ++ "#set-motd-allhosts", _} ->
Proc ! {announce_all_hosts_motd, From, To, Packet},
adhoc:produce_response(Response);
- {?NS_ADMIN ++ "#edit-motd", _} ->
+ {?NS_ADMIN_s ++ "#edit-motd", _} ->
Proc ! {announce_motd_update, From, To, Packet},
adhoc:produce_response(Response);
- {?NS_ADMIN ++ "#edit-motd-allhosts", _} ->
+ {?NS_ADMIN_s ++ "#edit-motd-allhosts", _} ->
Proc ! {announce_all_hosts_motd_update, From, To, Packet},
adhoc:produce_response(Response);
_ ->
%% This can't happen, as we haven't registered any other
%% command nodes.
- {error, ?ERR_INTERNAL_SERVER_ERROR}
+ {error, 'internal-server-error'}
end.
get_title(Lang, "announce") ->
translate:translate(Lang, "Announcements");
-get_title(Lang, ?NS_ADMIN ++ "#announce-all") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#announce-all") ->
translate:translate(Lang, "Send announcement to all users");
-get_title(Lang, ?NS_ADMIN ++ "#announce-all-allhosts") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#announce-all-allhosts") ->
translate:translate(Lang, "Send announcement to all users on all hosts");
-get_title(Lang, ?NS_ADMIN ++ "#announce") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#announce") ->
translate:translate(Lang, "Send announcement to all online users");
-get_title(Lang, ?NS_ADMIN ++ "#announce-allhosts") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#announce-allhosts") ->
translate:translate(Lang, "Send announcement to all online users on all hosts");
-get_title(Lang, ?NS_ADMIN ++ "#set-motd") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#set-motd") ->
translate:translate(Lang, "Set message of the day and send to online users");
-get_title(Lang, ?NS_ADMIN ++ "#set-motd-allhosts") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#set-motd-allhosts") ->
translate:translate(Lang, "Set message of the day on all hosts and send to online users");
-get_title(Lang, ?NS_ADMIN ++ "#edit-motd") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#edit-motd") ->
translate:translate(Lang, "Update message of the day (don't send)");
-get_title(Lang, ?NS_ADMIN ++ "#edit-motd-allhosts") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#edit-motd-allhosts") ->
translate:translate(Lang, "Update message of the day on all hosts (don't send)");
-get_title(Lang, ?NS_ADMIN ++ "#delete-motd") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#delete-motd") ->
translate:translate(Lang, "Delete message of the day");
-get_title(Lang, ?NS_ADMIN ++ "#delete-motd-allhosts") ->
+get_title(Lang, ?NS_ADMIN_s ++ "#delete-motd-allhosts") ->
translate:translate(Lang, "Delete message of the day on all hosts").
%%-------------------------------------------------------------------------
announce_all(From, To, Packet) ->
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
- Local = jlib:make_jid("", To#jid.server, ""),
+ Local = exmpp_jid:make_jid(To#jid.domain),
lists:foreach(
fun({User, Server}) ->
- Dest = jlib:make_jid(User, Server, ""),
+ Dest = exmpp_jid:make_jid(User, Server),
ejabberd_router:route(Local, Dest, Packet)
end, ejabberd_auth:get_vh_registered_users(Host))
end.
@@ -674,27 +673,27 @@ announce_all_hosts_all(From, To, Packet) ->
Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
case acl:match_rule(global, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
- Local = jlib:make_jid("", To#jid.server, ""),
+ Local = exmpp_jid:make_jid(To#jid.domain),
lists:foreach(
fun({User, Server}) ->
- Dest = jlib:make_jid(User, Server, ""),
+ Dest = exmpp_jid:make_jid(User, Server),
ejabberd_router:route(Local, Dest, Packet)
end, ejabberd_auth:dirty_get_registered_users())
end.
announce_online(From, To, Packet) ->
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
announce_online1(ejabberd_sm:get_vh_session_list(Host),
- To#jid.server,
+ To#jid.domain,
Packet)
end.
@@ -702,28 +701,28 @@ announce_all_hosts_online(From, To, Packet) ->
Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
case acl:match_rule(global, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
announce_online1(ejabberd_sm:dirty_get_sessions_list(),
- To#jid.server,
+ To#jid.domain,
Packet)
end.
announce_online1(Sessions, Server, Packet) ->
- Local = jlib:make_jid("", Server, ""),
+ Local = exmpp_jid:make_jid(Server),
lists:foreach(
fun({U, S, R}) ->
- Dest = jlib:make_jid(U, S, R),
+ Dest = exmpp_jid:make_jid(U, S, R),
ejabberd_router:route(Local, Dest, Packet)
end, Sessions).
announce_motd(From, To, Packet) ->
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
announce_motd(Host, Packet)
@@ -733,7 +732,7 @@ announce_all_hosts_motd(From, To, Packet) ->
Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
case acl:match_rule(global, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
Hosts = ?MYHOSTS,
@@ -753,11 +752,11 @@ announce_motd(Host, Packet) ->
mnesia:transaction(F).
announce_motd_update(From, To, Packet) ->
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
announce_motd_update(Host, Packet)
@@ -767,7 +766,7 @@ announce_all_hosts_motd_update(From, To, Packet) ->
Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
case acl:match_rule(global, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
Hosts = ?MYHOSTS,
@@ -782,11 +781,11 @@ announce_motd_update(LServer, Packet) ->
mnesia:transaction(F).
announce_motd_delete(From, To, Packet) ->
- Host = To#jid.lserver,
+ Host = To#jid.ldomain,
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
announce_motd_delete(Host)
@@ -796,7 +795,7 @@ announce_all_hosts_motd_delete(From, To, Packet) ->
Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
case acl:match_rule(global, Access, From) of
deny ->
- Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN),
+ Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
Hosts = ?MYHOSTS,
@@ -818,7 +817,7 @@ announce_motd_delete(LServer) ->
end,
mnesia:transaction(F).
-send_motd(#jid{luser = LUser, lserver = LServer} = JID) ->
+send_motd(#jid{lnode = LUser, ldomain = LServer} = JID) ->
case catch mnesia:dirty_read({motd, LServer}) of
[#motd{packet = Packet}] ->
US = {LUser, LServer},
@@ -826,7 +825,7 @@ send_motd(#jid{luser = LUser, lserver = LServer} = JID) ->
[#motd_users{}] ->
ok;
_ ->
- Local = jlib:make_jid("", LServer, ""),
+ Local = exmpp_jid:make_jid(LServer),
ejabberd_router:route(Local, JID, Packet),
F = fun() ->
mnesia:write(#motd_users{us = US})
@@ -840,8 +839,8 @@ send_motd(#jid{luser = LUser, lserver = LServer} = JID) ->
get_stored_motd(LServer) ->
case catch mnesia:dirty_read({motd, LServer}) of
[#motd{packet = Packet}] ->
- {xml:get_subtag_cdata(Packet, "subject"),
- xml:get_subtag_cdata(Packet, "body")};
+ {exmpp_xml:get_cdata_as_list(exmpp_xml:get_element_by_name(Packet, 'subject')),
+ exmpp_xml:get_cdata_as_list(exmpp_xml:get_element_by_name(Packet, 'body'))};
_ ->
{"", ""}
end.
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index e012794dd..c8925277e 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -45,8 +45,10 @@
adhoc_sm_items/4,
adhoc_sm_commands/4]).
+
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("adhoc.hrl").
-define(T(Lang, Text), translate:translate(Lang, Text)).
@@ -54,6 +56,8 @@
%% Copied from ejabberd_sm.erl
-record(session, {sid, usr, us, priority, info}).
+-define(NS_ADMIN_s, "http://jabber.org/protocol/admin").
+
start(Host, _Opts) ->
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_items, 50),
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 50),
@@ -78,33 +82,33 @@ stop(Host) ->
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 50),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_items, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS).
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC_s),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC_s).
%%%-----------------------------------------------------------------------
-define(INFO_IDENTITY(Category, Type, Name, Lang),
- [{xmlelement, "identity",
- [{"category", Category},
- {"type", Type},
- {"name", ?T(Lang, Name)}], []}]).
+ [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs =
+ [#xmlattr{name = 'category', value = Category},
+ #xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'name', value = ?T(Lang, Name)}]}]).
-define(INFO_COMMAND(Name, Lang),
?INFO_IDENTITY("automation", "command-node", Name, Lang)).
-define(NODEJID(To, Name, Node),
- {xmlelement, "item",
- [{"jid", jlib:jid_to_string(To)},
- {"name", ?T(Lang, Name)},
- {"node", Node}], []}).
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(To)},
+ #xmlattr{name = 'name', value = ?T(Lang, Name)},
+ #xmlattr{name = 'node', value = Node}]}).
-define(NODE(Name, Node),
- {xmlelement, "item",
- [{"jid", Server},
- {"name", ?T(Lang, Name)},
- {"node", Node}], []}).
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = Server},
+ #xmlattr{name = 'name', value = ?T(Lang, Name)},
+ #xmlattr{name = 'node', value = Node}]}).
--define(NS_ADMINX(Sub), ?NS_ADMIN++"#"++Sub).
+-define(NS_ADMINX(Sub), ?NS_ADMIN_s++"#"++Sub).
-define(NS_ADMINL(Sub), ["http:","jabber.org","protocol","admin", Sub]).
tokenize(Node) -> string:tokens(Node, "/#").
@@ -172,12 +176,12 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
-define(INFO_RESULT(Allow, Feats),
case Allow of
deny ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
allow ->
{result, Feats}
end).
-get_sm_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
+get_sm_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@@ -185,13 +189,13 @@ get_sm_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
Allow = acl:match_rule(LServer, configure, From),
case Node of
"config" ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
_ ->
Acc
end
end.
-get_local_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
+get_local_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@@ -216,29 +220,29 @@ get_local_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
["stopped nodes"] ->
?INFO_RESULT(Allow, []);
["running nodes", _ENode] ->
- ?INFO_RESULT(Allow, [?NS_STATS]);
+ ?INFO_RESULT(Allow, [?NS_STATS_s]);
["running nodes", _ENode, "DB"] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
["running nodes", _ENode, "modules"] ->
?INFO_RESULT(Allow, []);
["running nodes", _ENode, "modules", _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
["running nodes", _ENode, "backup"] ->
?INFO_RESULT(Allow, []);
["running nodes", _ENode, "backup", _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
["running nodes", _ENode, "import"] ->
?INFO_RESULT(Allow, []);
["running nodes", _ENode, "import", _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
["running nodes", _ENode, "restart"] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
["running nodes", _ENode, "shutdown"] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
["config", _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
["http:" | _] ->
- ?INFO_RESULT(Allow, [?NS_COMMANDS]);
+ ?INFO_RESULT(Allow, [?NS_ADHOC_s]);
_ ->
Acc
end
@@ -246,17 +250,17 @@ get_local_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
%%%-----------------------------------------------------------------------
-adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To, Lang) ->
+adhoc_sm_items(Acc, From, #jid{ldomain = LServer} = To, Lang) ->
case acl:match_rule(LServer, configure, From) of
allow ->
Items = case Acc of
{result, Its} -> Its;
empty -> []
end,
- Nodes = [{xmlelement, "item",
- [{"jid", jlib:jid_to_string(To)},
- {"name", ?T(Lang, "Configuration")},
- {"node", "config"}], []}],
+ Nodes = [#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(To)},
+ #xmlattr{name = 'name', value = ?T(Lang, "Configuration")},
+ #xmlattr{name = 'node', value = "config"}]}],
{result, Items ++ Nodes};
_ ->
Acc
@@ -265,7 +269,7 @@ adhoc_sm_items(Acc, From, #jid{lserver = LServer} = To, Lang) ->
%%%-----------------------------------------------------------------------
get_sm_items(Acc, From,
- #jid{user = User, server = Server, lserver = LServer} = To,
+ #jid{node = User, domain = Server, ldomain = LServer} = To,
Node, Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
@@ -283,7 +287,7 @@ get_sm_items(Acc, From,
{allow, "config"} ->
{result, []};
{_, "config"} ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
_ ->
Acc
end
@@ -292,14 +296,14 @@ get_sm_items(Acc, From,
get_user_resources(User, Server) ->
Rs = ejabberd_sm:get_user_resources(User, Server),
lists:map(fun(R) ->
- {xmlelement, "item",
- [{"jid", User ++ "@" ++ Server ++ "/" ++ R},
- {"name", User}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(User, Server, R)},
+ #xmlattr{name = 'name', value = User}]}
end, lists:sort(Rs)).
%%%-----------------------------------------------------------------------
-adhoc_local_items(Acc, From, #jid{lserver = LServer, server = Server} = To,
+adhoc_local_items(Acc, From, #jid{ldomain = LServer, domain = Server} = To,
Lang) ->
case acl:match_rule(LServer, configure, From) of
allow ->
@@ -311,10 +315,10 @@ adhoc_local_items(Acc, From, #jid{lserver = LServer, server = Server} = To,
Nodes = recursively_get_local_items(LServer, "", Server, Lang),
Nodes1 = lists:filter(
fun(N) ->
- Nd = xml:get_tag_attr_s("node", N),
+ Nd = exmpp_xml:get_attribute(N, 'node'),
F = get_local_features([], From, To, Nd, Lang),
case F of
- {result, [?NS_COMMANDS]} ->
+ {result, [?NS_ADHOC_s]} ->
true;
_ ->
false
@@ -342,8 +346,8 @@ recursively_get_local_items(LServer, Node, Server, Lang) ->
Nodes = lists:flatten(
lists:map(
fun(N) ->
- S = xml:get_tag_attr_s("jid", N),
- Nd = xml:get_tag_attr_s("node", N),
+ S = exmpp_xml:get_attribute(N, 'jid'),
+ Nd = exmpp_xml:get_attribute(N, 'node'),
if (S /= Server) or (Nd == "") ->
[];
true ->
@@ -361,7 +365,7 @@ recursively_get_local_items(LServer, Node, Server, Lang) ->
Fallback;
allow ->
case get_local_items(LServer, LNode,
- jlib:jid_to_string(To), Lang) of
+ exmpp_jid:jid_to_string(To), Lang) of
{result, Res} ->
{result, Res};
{error, Error} ->
@@ -369,7 +373,7 @@ recursively_get_local_items(LServer, Node, Server, Lang) ->
end
end).
-get_local_items(Acc, From, #jid{lserver = LServer} = To, "", Lang) ->
+get_local_items(Acc, From, #jid{ldomain = LServer} = To, "", Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@@ -384,7 +388,7 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To, "", Lang) ->
{result, Items};
allow ->
case get_local_items(LServer, [],
- jlib:jid_to_string(To), Lang) of
+ exmpp_jid:jid_to_string(To), Lang) of
{result, Res} ->
{result, Items ++ Res};
{error, _Error} ->
@@ -393,7 +397,7 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To, "", Lang) ->
end
end;
-get_local_items(Acc, From, #jid{lserver = LServer} = To, Node, Lang) ->
+get_local_items(Acc, From, #jid{ldomain = LServer} = To, Node, Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@@ -402,45 +406,45 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To, Node, Lang) ->
Allow = acl:match_rule(LServer, configure, From),
case LNode of
["config"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["user"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["online users"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["all users"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["all users", [$@ | _]] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["outgoing s2s" | _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["stopped nodes"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "DB"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "modules"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "modules", _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "backup"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "backup", _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "import"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "import", _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "restart"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["running nodes", _ENode, "shutdown"] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
["config", _] ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
?NS_ADMINL(_) ->
- ?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN});
+ ?ITEMS_RESULT(Allow, LNode, {error, 'forbidden'});
_ ->
Acc
end
@@ -493,7 +497,7 @@ get_local_items(Host, ["all users"], _Server, _Lang) ->
get_local_items(Host, ["all users", [$@ | Diap]], _Server, _Lang) ->
case catch ejabberd_auth:get_vh_registered_users(Host) of
{'EXIT', _Reason} ->
- ?ERR_INTERNAL_SERVER_ERROR;
+ {error, 'internal-server-error'};
Users ->
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
case catch begin
@@ -502,13 +506,13 @@ get_local_items(Host, ["all users", [$@ | Diap]], _Server, _Lang) ->
N2 = list_to_integer(S2),
Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
lists:map(fun({S, U}) ->
- {xmlelement, "item",
- [{"jid", U ++ "@" ++ S},
- {"name", U ++ "@" ++ S}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(U, S)},
+ #xmlattr{name = 'name', value = exmpp_jid:jid_to_string(U, S)}]}
end, Sub)
end of
{'EXIT', _Reason} ->
- ?ERR_NOT_ACCEPTABLE;
+ {error, 'not-acceptable'};
Res ->
{result, Res}
end
@@ -576,7 +580,7 @@ get_local_items(_Host, ["running nodes", _ENode, "shutdown"], _Server, _Lang) ->
{result, []};
get_local_items(_Host, _, _Server, _Lang) ->
- {error, ?ERR_ITEM_NOT_FOUND}.
+ {error, 'item-not-found'}.
get_online_vh_users(Host) ->
@@ -586,9 +590,9 @@ get_online_vh_users(Host) ->
USRs ->
SURs = lists:sort([{S, U, R} || {U, S, R} <- USRs]),
lists:map(fun({S, U, R}) ->
- {xmlelement, "item",
- [{"jid", U ++ "@" ++ S ++ "/" ++ R},
- {"name", U ++ "@" ++ S}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(U, S, R)},
+ #xmlattr{name = 'name', value = exmpp_jid:jid_to_string(U, S)}]}
end, SURs)
end.
@@ -601,9 +605,9 @@ get_all_vh_users(Host) ->
case length(SUsers) of
N when N =< 100 ->
lists:map(fun({S, U}) ->
- {xmlelement, "item",
- [{"jid", U ++ "@" ++ S},
- {"name", U ++ "@" ++ S}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(U, S)},
+ #xmlattr{name = 'name', value = exmpp_jid:jid_to_string(U, S)}]}
end, SUsers);
N ->
NParts = trunc(math:sqrt(N * 0.618)) + 1,
@@ -622,10 +626,10 @@ get_all_vh_users(Host) ->
FU ++ "@" ++ FS ++
" -- " ++
LU ++ "@" ++ LS,
- {xmlelement, "item",
- [{"jid", Host},
- {"node", "all users/" ++ Node},
- {"name", Name}], []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = Host},
+ #xmlattr{name = 'node', value = "all users/" ++ Node},
+ #xmlattr{name = 'name', value = Name}]}
end, lists:seq(1, N, M))
end
end.
@@ -640,14 +644,13 @@ get_outgoing_s2s(Host, Lang) ->
Host == FH orelse lists:suffix(DotHost, FH)],
lists:map(
fun(T) ->
- {xmlelement, "item",
- [{"jid", Host},
- {"node", "outgoing s2s/" ++ T},
- {"name",
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = Host},
+ #xmlattr{name = 'node', value = "outgoing s2s/" ++ T},
+ #xmlattr{name = 'name', value =
lists:flatten(
io_lib:format(
- ?T(Lang, "To ~s"), [T]))}],
- []}
+ ?T(Lang, "To ~s"), [T]))}]}
end, lists:usort(TConns))
end.
@@ -658,14 +661,13 @@ get_outgoing_s2s(Host, Lang, To) ->
Connections ->
lists:map(
fun({F, _T}) ->
- {xmlelement, "item",
- [{"jid", Host},
- {"node", "outgoing s2s/" ++ To ++ "/" ++ F},
- {"name",
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = Host},
+ #xmlattr{name = 'node', value = "outgoing s2s/" ++ To ++ "/" ++ F},
+ #xmlattr{name = 'name', value =
lists:flatten(
io_lib:format(
- ?T(Lang, "From ~s"), [F]))}],
- []}
+ ?T(Lang, "From ~s"), [F]))}]}
end, lists:keysort(1, lists:filter(fun(E) ->
element(2, E) == To
end, Connections)))
@@ -680,11 +682,10 @@ get_running_nodes(Server, _Lang) ->
lists:map(
fun(N) ->
S = atom_to_list(N),
- {xmlelement, "item",
- [{"jid", Server},
- {"node", "running nodes/" ++ S},
- {"name", S}],
- []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = Server},
+ #xmlattr{name = 'node', value = "running nodes/" ++ S},
+ #xmlattr{name = 'name', value = S}]}
end, lists:sort(DBNodes))
end.
@@ -698,11 +699,10 @@ get_stopped_nodes(_Lang) ->
lists:map(
fun(N) ->
S = atom_to_list(N),
- {xmlelement, "item",
- [{"jid", ?MYNAME},
- {"node", "stopped nodes/" ++ S},
- {"name", S}],
- []}
+ #xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
+ [#xmlattr{name = 'jid', value = ?MYNAME},
+ #xmlattr{name = 'node', value = "stopped nodes/" ++ S},
+ #xmlattr{name = 'name', value = S}]}
end, lists:sort(DBNodes))
end.
@@ -711,12 +711,12 @@ get_stopped_nodes(_Lang) ->
-define(COMMANDS_RESULT(Allow, From, To, Request),
case Allow of
deny ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
allow ->
adhoc_local_commands(From, To, Request)
end).
-adhoc_local_commands(Acc, From, #jid{lserver = LServer} = To,
+adhoc_local_commands(Acc, From, #jid{ldomain = LServer} = To,
#adhoc_request{node = Node} = Request) ->
LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From),
@@ -741,7 +741,7 @@ adhoc_local_commands(Acc, From, #jid{lserver = LServer} = To,
Acc
end.
-adhoc_local_commands(From, #jid{lserver = LServer} = _To,
+adhoc_local_commands(From, #jid{ldomain = LServer} = _To,
#adhoc_request{lang = Lang,
node = Node,
sessionid = SessionID,
@@ -779,7 +779,7 @@ adhoc_local_commands(From, #jid{lserver = LServer} = _To,
%% User returns form.
case jlib:parse_xdata_submit(XData) of
invalid ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
Fields ->
case catch set_form(From, LServer, LNode, Lang, Fields) of
{result, Res} ->
@@ -790,58 +790,58 @@ adhoc_local_commands(From, #jid{lserver = LServer} = _To,
elements = Res,
status = completed});
{'EXIT', _} ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
{error, Error} ->
{error, Error}
end
end;
true ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end.
-define(TVFIELD(Type, Var, Val),
- {xmlelement, "field", [{"type", Type},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
--define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN)).
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'var', value = Var}],
+ children = [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Val)}]}]}).
+-define(HFIELD(), ?TVFIELD("hidden", "FORM_TYPE", ?NS_ADMIN_s)).
-define(TLFIELD(Type, Label, Var),
- {xmlelement, "field", [{"type", Type},
- {"label", ?T(Lang, Label)},
- {"var", Var}], []}).
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'label', value = ?T(Lang, Label)},
+ #xmlattr{name = 'var', value = Var}]}).
-define(XFIELD(Type, Label, Var, Val),
- {xmlelement, "field", [{"type", Type},
- {"label", ?T(Lang, Label)},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'label', value = ?T(Lang, Label)},
+ #xmlattr{name = 'var', value = Var}],
+ children = [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Val)}]}]}).
-define(XMFIELD(Type, Label, Var, Vals),
- {xmlelement, "field", [{"type", Type},
- {"label", ?T(Lang, Label)},
- {"var", Var}],
- [{xmlelement, "value", [], [{xmlcdata,Val}]} || Val <- Vals]}).
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = Type},
+ #xmlattr{name = 'label', value = ?T(Lang, Label)},
+ #xmlattr{name = 'var', value = Var}],
+ children = [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Val)}]} || Val <- Vals]}).
-define(TABLEFIELD(Table, Val),
- {xmlelement, "field", [{"type", "list-single"},
- {"label", atom_to_list(Table)},
- {"var", atom_to_list(Table)}],
- [{xmlelement, "value", [], [{xmlcdata, atom_to_list(Val)}]},
- {xmlelement, "option", [{"label",
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = "list-single"},
+ #xmlattr{name = 'label', value = atom_to_list(Table)},
+ #xmlattr{name = 'var', value = atom_to_list(Table)}],
+ children = [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(atom_to_list(Val))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', attrs = [#xmlattr{name = 'label', value =
?T(Lang, "RAM copy")}],
- [{xmlelement, "value", [], [{xmlcdata, "ram_copies"}]}]},
- {xmlelement, "option", [{"label",
+ children = [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"ram_copies">>}]}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', attrs = [#xmlattr{name = 'label', value =
?T(Lang,
"RAM and disc copy")}],
- [{xmlelement, "value", [], [{xmlcdata, "disc_copies"}]}]},
- {xmlelement, "option", [{"label",
+ children = [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"disc_copies">>}]}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', attrs = [#xmlattr{name = 'label', value =
?T(Lang,
"Disc only copy")}],
- [{xmlelement, "value", [], [{xmlcdata, "disc_only_copies"}]}]},
- {xmlelement, "option", [{"label",
+ children = [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"disc_only_copies">>}]}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', attrs = [#xmlattr{name = 'label', value =
?T(Lang, "Remote copy")}],
- [{xmlelement, "value", [], [{xmlcdata, "unknown"}]}]}
+ children = [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"unknown">>}]}]}
]}).
@@ -849,24 +849,24 @@ adhoc_local_commands(From, #jid{lserver = LServer} = _To,
get_form(_Host, ["running nodes", ENode, "DB"], Lang) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
case rpc:call(Node, mnesia, system_info, [tables]) of
{badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
Tables ->
STables = lists:sort(Tables),
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
Lang, "Database Tables Configuration at ") ++
- ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- ?T(
- Lang, "Choose storage type of tables")}]} |
+ ENode)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Choose storage type of tables"))}]} |
lists:map(
fun(Table) ->
case rpc:call(Node,
@@ -886,23 +886,23 @@ get_form(_Host, ["running nodes", ENode, "DB"], Lang) ->
get_form(Host, ["running nodes", ENode, "modules", "stop"], Lang) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
case rpc:call(Node, gen_mod, loaded_modules, [Host]) of
{badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
Modules ->
SModules = lists:sort(Modules),
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Stop Modules at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- ?T(
- Lang, "Choose modules to stop")}]} |
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Stop Modules at ") ++ ENode)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Choose modules to stop"))}]} |
lists:map(fun(M) ->
S = atom_to_list(M),
?XFIELD("boolean", S, S, "0")
@@ -912,104 +912,104 @@ get_form(Host, ["running nodes", ENode, "modules", "stop"], Lang) ->
end;
get_form(_Host, ["running nodes", ENode, "modules", "start"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Start Modules at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- ?T(
- Lang, "Enter list of {Module, [Options]}")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Start Modules at ") ++ ENode)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Enter list of {Module, [Options]}"))}]},
?XFIELD("text-multi", "List of modules to start", "modules", "[].")
]}]};
get_form(_Host, ["running nodes", ENode, "backup", "backup"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Backup to File at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- ?T(
- Lang, "Enter path to backup file")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Backup to File at ") ++ ENode)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Enter path to backup file"))}]},
?XFIELD("text-single", "Path to File", "path", "")
]}]};
get_form(_Host, ["running nodes", ENode, "backup", "restore"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Restore Backup from File at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- ?T(
- Lang, "Enter path to backup file")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Restore Backup from File at ") ++ ENode)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Enter path to backup file"))}]},
?XFIELD("text-single", "Path to File", "path", "")
]}]};
get_form(_Host, ["running nodes", ENode, "backup", "textfile"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Dump Backup to Text File at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- ?T(
- Lang, "Enter path to text file")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Dump Backup to Text File at ") ++ ENode)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Enter path to text file"))}]},
?XFIELD("text-single", "Path to File", "path", "")
]}]};
get_form(_Host, ["running nodes", ENode, "import", "file"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Import User from File at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- ?T(
- Lang, "Enter path to jabberd1.4 spool file")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Import User from File at ") ++ ENode)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Enter path to jabberd1.4 spool file"))}]},
?XFIELD("text-single", "Path to File", "path", "")
]}]};
get_form(_Host, ["running nodes", ENode, "import", "dir"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Import Users from Dir at ") ++ ENode}]},
- {xmlelement, "instructions", [],
- [{xmlcdata,
- ?T(
- Lang, "Enter path to jabberd1.4 spool dir")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Import Users from Dir at ") ++ ENode)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'instructions', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Enter path to jabberd1.4 spool dir"))}]},
?XFIELD("text-single", "Path to Dir", "path", "")
]}]};
get_form(_Host, ["running nodes", _ENode, "restart"], Lang) ->
Make_option =
fun(LabelNum, LabelUnit, Value)->
- {xmlelement, "option",
- [{"label", LabelNum ++ ?T(Lang, LabelUnit)}],
- [{xmlelement, "value", [], [{xmlcdata, Value}]}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', attrs =
+ [#xmlattr{name = 'label', value = LabelNum ++ ?T(Lang, LabelUnit)}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Value)}]}]}
end,
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "Restart Service")}]},
- {xmlelement, "field",
- [{"type", "list-single"},
- {"label", ?T(Lang, "Time delay")},
- {"var", "delay"}],
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "Restart Service"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "list-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Time delay")},
+ #xmlattr{name = 'var', value = "delay"}], children =
[Make_option("", "immediately", "1"),
Make_option("15 ", "seconds", "15"),
Make_option("30 ", "seconds", "30"),
@@ -1022,39 +1022,36 @@ get_form(_Host, ["running nodes", _ENode, "restart"], Lang) ->
Make_option("10 ", "minutes", "600"),
Make_option("15 ", "minutes", "900"),
Make_option("30 ", "minutes", "1800"),
- {xmlelement, "required", [], []}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'required'}
]},
- {xmlelement, "field",
- [{"type", "fixed"},
- {"label", ?T(Lang, "Send announcement to all online users on all hosts")}],
- []},
- {xmlelement, "field",
- [{"var", "subject"},
- {"type", "text-single"},
- {"label", ?T(Lang, "Subject")}],
- []},
- {xmlelement, "field",
- [{"var", "announcement"},
- {"type", "text-multi"},
- {"label", ?T(Lang, "Message body")}],
- []}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "fixed"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Send announcement to all online users on all hosts")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "subject"},
+ #xmlattr{name = 'type', value = "text-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Subject")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "announcement"},
+ #xmlattr{name = 'type', value = "text-multi"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Message body")}]}
]}]};
get_form(_Host, ["running nodes", _ENode, "shutdown"], Lang) ->
Make_option =
fun(LabelNum, LabelUnit, Value)->
- {xmlelement, "option",
- [{"label", LabelNum ++ ?T(Lang, LabelUnit)}],
- [{xmlelement, "value", [], [{xmlcdata, Value}]}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', attrs =
+ [#xmlattr{name = 'label', value = LabelNum ++ ?T(Lang, LabelUnit)}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Value)}]}]}
end,
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "Shut Down Service")}]},
- {xmlelement, "field",
- [{"type", "list-single"},
- {"label", ?T(Lang, "Time delay")},
- {"var", "delay"}],
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "Shut Down Service"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "list-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Time delay")},
+ #xmlattr{name = 'var', value = "delay"}], children =
[Make_option("", "immediately", "1"),
Make_option("15 ", "seconds", "15"),
Make_option("30 ", "seconds", "30"),
@@ -1067,38 +1064,35 @@ get_form(_Host, ["running nodes", _ENode, "shutdown"], Lang) ->
Make_option("10 ", "minutes", "600"),
Make_option("15 ", "minutes", "900"),
Make_option("30 ", "minutes", "1800"),
- {xmlelement, "required", [], []}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'required'}
]},
- {xmlelement, "field",
- [{"type", "fixed"},
- {"label", ?T(Lang, "Send announcement to all online users on all hosts")}],
- []},
- {xmlelement, "field",
- [{"var", "subject"},
- {"type", "text-single"},
- {"label", ?T(Lang, "Subject")}],
- []},
- {xmlelement, "field",
- [{"var", "announcement"},
- {"type", "text-multi"},
- {"label", ?T(Lang, "Message body")}],
- []}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "fixed"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Send announcement to all online users on all hosts")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "subject"},
+ #xmlattr{name = 'type', value = "text-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Subject")}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'var', value = "announcement"},
+ #xmlattr{name = 'type', value = "text-multi"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Message body")}]}
]}]};
get_form(Host, ["config", "acls"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Access Control List Configuration")}]},
- {xmlelement, "field", [{"type", "text-multi"},
- {"label",
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Access Control List Configuration"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'type', value = "text-multi"},
+ #xmlattr{name = 'label', value =
?T(
Lang, "Access control lists")},
- {"var", "acls"}],
- lists:map(fun(S) ->
- {xmlelement, "value", [], [{xmlcdata, S}]}
+ #xmlattr{name = 'var', value = "acls"}],
+ children = lists:map(fun(S) ->
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(S)}]}
end,
string:tokens(
lists:flatten(
@@ -1114,19 +1108,19 @@ get_form(Host, ["config", "acls"], Lang) ->
]}]};
get_form(Host, ["config", "access"], Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Access Configuration")}]},
- {xmlelement, "field", [{"type", "text-multi"},
- {"label",
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Access Configuration"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =[#xmlattr{name = 'type', value = "text-multi"},
+ #xmlattr{name = 'label', value =
?T(
Lang, "Access rules")},
- {"var", "access"}],
- lists:map(fun(S) ->
- {xmlelement, "value", [], [{xmlcdata, S}]}
+ #xmlattr{name = 'var', value = "access"}],
+ children = lists:map(fun(S) ->
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'value', children =[#xmlcdata{cdata = list_to_binary(S)}]}
end,
string:tokens(
lists:flatten(
@@ -1142,141 +1136,137 @@ get_form(Host, ["config", "access"], Lang) ->
]}]};
get_form(_Host, ?NS_ADMINL("add-user"), Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "Add User")}]},
- {xmlelement, "field",
- [{"type", "jid-single"},
- {"label", ?T(Lang, "Jabber ID")},
- {"var", "accountjid"}],
- [{xmlelement, "required", [], []}]},
- {xmlelement, "field",
- [{"type", "text-private"},
- {"label", ?T(Lang, "Password")},
- {"var", "password"}],
- [{xmlelement, "required", [], []}]},
- {xmlelement, "field",
- [{"type", "text-private"},
- {"label", ?T(Lang, "Password Verification")},
- {"var", "password-verify"}],
- [{xmlelement, "required", [], []}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "Add User"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Jabber ID")},
+ #xmlattr{name = 'var', value = "accountjid"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "text-private"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Password")},
+ #xmlattr{name = 'var', value = "password"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "text-private"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Password Verification")},
+ #xmlattr{name = 'var', value = "password-verify"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]}
]}]};
get_form(_Host, ?NS_ADMINL("delete-user"), Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "Delete User")}]},
- {xmlelement, "field",
- [{"type", "jid-multi"},
- {"label", ?T(Lang, "Jabber ID")},
- {"var", "accountjids"}],
- [{xmlelement, "required", [], []}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "Delete User"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-multi"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Jabber ID")},
+ #xmlattr{name = 'var', value = "accountjids"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]}
]}]};
get_form(_Host, ?NS_ADMINL("end-user-session"), Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "End User Session")}]},
- {xmlelement, "field",
- [{"type", "jid-single"},
- {"label", ?T(Lang, "Jabber ID")},
- {"var", "accountjid"}],
- [{xmlelement, "required", [], []}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "End User Session"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = list_to_binary(?T(Lang, "Jabber ID"))},
+ #xmlattr{name = 'var', value = "accountjid"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]}
]}]};
get_form(_Host, ?NS_ADMINL("get-user-password"), Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "Get User Password")}]},
- {xmlelement, "field",
- [{"type", "jid-single"},
- {"label", ?T(Lang, "Jabber ID")},
- {"var", "accountjid"}],
- [{xmlelement, "required", [], []}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "Get User Password"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Jabber ID")},
+ #xmlattr{name = 'var', value = "accountjid"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]}
]}]};
get_form(_Host, ?NS_ADMINL("change-user-password"), Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "Get User Password")}]},
- {xmlelement, "field",
- [{"type", "jid-single"},
- {"label", ?T(Lang, "Jabber ID")},
- {"var", "accountjid"}],
- [{xmlelement, "required", [], []}]},
- {xmlelement, "field",
- [{"type", "text-private"},
- {"label", ?T(Lang, "Password")},
- {"var", "password"}],
- [{xmlelement, "required", [], []}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "Get User Password"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Jabber ID")},
+ #xmlattr{name = 'var', value = "accountjid"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "text-private"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Password")},
+ #xmlattr{name = 'var', value = "password"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]}
]}]};
get_form(_Host, ?NS_ADMINL("get-user-lastlogin"), Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "Get User Last Login Time")}]},
- {xmlelement, "field",
- [{"type", "jid-single"},
- {"label", ?T(Lang, "Jabber ID")},
- {"var", "accountjid"}],
- [{xmlelement, "required", [], []}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "Get User Last Login Time"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Jabber ID")},
+ #xmlattr{name = 'var', value = "accountjid"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]}
]}]};
get_form(_Host, ?NS_ADMINL("user-stats"), Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata, ?T(Lang, "Get User Statistics")}]},
- {xmlelement, "field",
- [{"type", "jid-single"},
- {"label", ?T(Lang, "Jabber ID")},
- {"var", "accountjid"}],
- [{xmlelement, "required", [], []}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata = list_to_binary(?T(Lang, "Get User Statistics"))}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Jabber ID")},
+ #xmlattr{name = 'var', value = "accountjid"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'required'}]}
]}]};
get_form(Host, ?NS_ADMINL("get-registered-users-num"), Lang) ->
[Num] = io_lib:format("~p", [ejabberd_auth:get_vh_registered_users_number(Host)]),
{result, completed,
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA}],
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement,
- "field",
- [{"type", "jid-single"},
- {"label", ?T(Lang, "Number of registered users")},
- {"var", "registeredusersnum"}],
- [{xmlelement, "value", [], [{xmlcdata, Num}]}]
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Number of registered users")},
+ #xmlattr{name = 'var', value = "registeredusersnum"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Num)}]}]
}]}]};
get_form(Host, ?NS_ADMINL("get-online-users-num"), Lang) ->
Num = io_lib:format("~p", [length(ejabberd_sm:get_vh_session_list(Host))]),
{result, completed,
- [{xmlelement, "x",
- [{"xmlns", ?NS_XDATA}],
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement,
- "field",
- [{"type", "jid-single"},
- {"label", ?T(Lang, "Number of online users")},
- {"var", "onlineusersnum"}],
- [{xmlelement, "value", [], [{xmlcdata, Num}]}]
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "jid-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Number of online users")},
+ #xmlattr{name = 'var', value = "onlineusersnum"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Num)}]}]
}]}]};
get_form(_Host, _, _Lang) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
+ {error, 'service-unavailable'}.
set_form(_From, _Host, ["running nodes", ENode, "DB"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
lists:foreach(
fun({SVar, SVals}) ->
@@ -1310,7 +1300,7 @@ set_form(_From, _Host, ["running nodes", ENode, "DB"], _Lang, XData) ->
set_form(_From, Host, ["running nodes", ENode, "modules", "stop"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
lists:foreach(
fun({Var, Vals}) ->
@@ -1328,11 +1318,11 @@ set_form(_From, Host, ["running nodes", ENode, "modules", "stop"], _Lang, XData)
set_form(_From, Host, ["running nodes", ENode, "modules", "start"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
case lists:keysearch("modules", 1, XData) of
false ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
{value, {_, Strings}} ->
String = lists:foldl(fun(S, Res) ->
Res ++ S ++ "\n"
@@ -1350,13 +1340,13 @@ set_form(_From, Host, ["running nodes", ENode, "modules", "start"], _Lang, XData
end, Modules),
{result, []};
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end
end;
@@ -1364,22 +1354,22 @@ set_form(_From, Host, ["running nodes", ENode, "modules", "start"], _Lang, XData
set_form(_From, _Host, ["running nodes", ENode, "backup", "backup"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
case lists:keysearch("path", 1, XData) of
false ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
{value, {_, [String]}} ->
case rpc:call(Node, mnesia, backup, [String]) of
{badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
{error, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
_ ->
{result, []}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end
end;
@@ -1387,22 +1377,22 @@ set_form(_From, _Host, ["running nodes", ENode, "backup", "backup"], _Lang, XDat
set_form(_From, _Host, ["running nodes", ENode, "backup", "restore"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
case lists:keysearch("path", 1, XData) of
false ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
{value, {_, [String]}} ->
case rpc:call(Node, ejabberd_admin, restore, [String]) of
{badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
{error, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
_ ->
{result, []}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end
end;
@@ -1410,22 +1400,22 @@ set_form(_From, _Host, ["running nodes", ENode, "backup", "restore"], _Lang, XDa
set_form(_From, _Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
case lists:keysearch("path", 1, XData) of
false ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
{value, {_, [String]}} ->
case rpc:call(Node, ejabberd_ctl, dump_to_textfile, [String]) of
{badrpc, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
{error, _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
_ ->
{result, []}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end
end;
@@ -1433,16 +1423,16 @@ set_form(_From, _Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XD
set_form(_From, _Host, ["running nodes", ENode, "import", "file"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
case lists:keysearch("path", 1, XData) of
false ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
{value, {_, [String]}} ->
rpc:call(Node, jd2ejd, import_file, [String]),
{result, []};
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end
end;
@@ -1450,16 +1440,16 @@ set_form(_From, _Host, ["running nodes", ENode, "import", "file"], _Lang, XData)
set_form(_From, _Host, ["running nodes", ENode, "import", "dir"], _Lang, XData) ->
case search_running_node(ENode) of
false ->
- {error, ?ERR_ITEM_NOT_FOUND};
+ {error, 'item-not-found'};
Node ->
case lists:keysearch("path", 1, XData) of
false ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
{value, {_, [String]}} ->
rpc:call(Node, jd2ejd, import_dir, [String]),
{result, []};
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end
end;
@@ -1483,16 +1473,16 @@ set_form(_From, Host, ["config", "acls"], _Lang, XData) ->
ok ->
{result, []};
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
set_form(_From, Host, ["config", "access"], _Lang, XData) ->
@@ -1528,25 +1518,25 @@ set_form(_From, Host, ["config", "access"], _Lang, XData) ->
{atomic, _} ->
{result, []};
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
_ ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end;
set_form(_From, _Host, ?NS_ADMINL("add-user"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
Password = get_value("password", XData),
Password = get_value("password-verify", XData),
- AccountJID = jlib:string_to_jid(AccountString),
- User = AccountJID#jid.luser,
- Server = AccountJID#jid.lserver,
+ AccountJID = exmpp_jid:string_to_jid(AccountString),
+ User = AccountJID#jid.lnode,
+ Server = AccountJID#jid.ldomain,
true = lists:member(Server, ?MYHOSTS),
ejabberd_auth:try_register(User, Server, Password),
{result, []};
@@ -1556,10 +1546,10 @@ set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
[_|_] = AccountStringList,
ASL2 = lists:map(
fun(AccountString) ->
- JID = jlib:string_to_jid(AccountString),
- [_|_] = JID#jid.luser,
- User = JID#jid.luser,
- Server = JID#jid.lserver,
+ JID = exmpp_jid:string_to_jid(AccountString),
+ [_|_] = JID#jid.lnode,
+ User = JID#jid.lnode,
+ Server = JID#jid.ldomain,
true = ejabberd_auth:is_user_exists(User, Server),
{User, Server}
end,
@@ -1569,13 +1559,13 @@ set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
- JID = jlib:string_to_jid(AccountString),
- [_|_] = JID#jid.luser,
- LUser = JID#jid.luser,
- LServer = JID#jid.lserver,
+ JID = exmpp_jid:string_to_jid(AccountString),
+ [_|_] = JID#jid.lnode,
+ LUser = JID#jid.lnode,
+ LServer = JID#jid.ldomain,
%% Code copied from ejabberd_sm.erl
case JID#jid.lresource of
- [] ->
+ undefined ->
SIDs = mnesia:dirty_select(session,
[{#session{sid = '$1', usr = {LUser, LServer, '_'}, _ = '_'}, [], ['$1']}]),
[Pid ! replaced || {_, Pid} <- SIDs];
@@ -1588,13 +1578,13 @@ set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
- JID = jlib:string_to_jid(AccountString),
- [_|_] = JID#jid.luser,
- User = JID#jid.luser,
- Server = JID#jid.lserver,
+ JID = exmpp_jid:string_to_jid(AccountString),
+ [_|_] = JID#jid.lnode,
+ User = JID#jid.lnode,
+ Server = JID#jid.ldomain,
Password = ejabberd_auth:get_password(User, Server),
true = is_list(Password),
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
?XFIELD("jid-single", "Jabber ID", "accountjid", AccountString),
?XFIELD("text-single", "Password", "password", Password)
@@ -1603,20 +1593,20 @@ set_form(_From, _Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
Password = get_value("password", XData),
- JID = jlib:string_to_jid(AccountString),
- [_|_] = JID#jid.luser,
- User = JID#jid.luser,
- Server = JID#jid.lserver,
+ JID = exmpp_jid:string_to_jid(AccountString),
+ [_|_] = JID#jid.lnode,
+ User = JID#jid.lnode,
+ Server = JID#jid.ldomain,
true = ejabberd_auth:is_user_exists(User, Server),
ejabberd_auth:set_password(User, Server, Password),
{result, []};
set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
- JID = jlib:string_to_jid(AccountString),
- [_|_] = JID#jid.luser,
- User = JID#jid.luser,
- Server = JID#jid.lserver,
+ JID = exmpp_jid:string_to_jid(AccountString),
+ [_|_] = JID#jid.lnode,
+ User = JID#jid.lnode,
+ Server = JID#jid.ldomain,
%% Code copied from web/ejabberd_web_admin.erl
%% TODO: Update time format to XEP-0202: Entity Time
@@ -1642,7 +1632,7 @@ set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
_ ->
?T(Lang, "Online")
end,
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs = [#xmlattr{name = 'type', value = "result"}], children =
[?HFIELD(),
?XFIELD("jid-single", "Jabber ID", "accountjid", AccountString),
?XFIELD("text-single", "Last login", "lastlogin", FLast)
@@ -1650,10 +1640,10 @@ set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("user-stats"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
- JID = jlib:string_to_jid(AccountString),
- [_|_] = JID#jid.luser,
- User = JID#jid.luser,
- Server = JID#jid.lserver,
+ JID = exmpp_jid:string_to_jid(AccountString),
+ [_|_] = JID#jid.lnode,
+ User = JID#jid.lnode,
+ Server = JID#jid.ldomain,
Resources = ejabberd_sm:get_user_resources(User, Server),
IPs1 = [ejabberd_sm:get_user_ip(User, Server, Resource) || Resource <- Resources],
@@ -1662,7 +1652,7 @@ set_form(_From, _Host, ?NS_ADMINL("user-stats"), Lang, XData) ->
Items = ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}]),
Rostersize = integer_to_list(erlang:length(Items)),
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
?XFIELD("jid-single", "Jabber ID", "accountjid", AccountString),
?XFIELD("text-single", "Roster size", "rostersize", Rostersize),
@@ -1671,7 +1661,7 @@ set_form(_From, _Host, ?NS_ADMINL("user-stats"), Lang, XData) ->
]}]};
set_form(_From, _Host, _, _Lang, _XData) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
+ {error, 'service-unavailable'}.
get_value(Field, XData) ->
hd(get_values(Field, XData)).
@@ -1697,13 +1687,13 @@ stop_node(From, Host, ENode, Action, XData) ->
Delay = list_to_integer(get_value("delay", XData)),
Subject = case get_value("subject", XData) of
[] -> [];
- S -> [{xmlelement, "field", [{"var","subject"}],
- [{xmlelement,"value",[],[{xmlcdata,S}]}]}]
+ S -> [#xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'var', value = "subject"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(S)}]}]}]
end,
Announcement = case get_values("announcement", XData) of
[] -> [];
- As -> [{xmlelement, "field", [{"var","body"}],
- [{xmlelement,"value",[],[{xmlcdata,Line}]} || Line <- As] }]
+ As -> [#xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs = [#xmlattr{name = 'var', value = "body"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = list_to_binary(Line)}]} || Line <- As] }]
end,
case Subject ++ Announcement of
[] -> ok;
@@ -1711,14 +1701,14 @@ stop_node(From, Host, ENode, Action, XData) ->
Request = #adhoc_request{
node = ?NS_ADMINX("announce-allhosts"),
action = "complete",
- xdata = {xmlelement, "x",
- [{"xmlns","jabber:x:data"},{"type","submit"}],
+ xdata = #xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs =
+ [#xmlattr{name = 'type', value = "submit"}], children =
SubEls},
- others= [{xmlelement, "x",
- [{"xmlns","jabber:x:data"},{"type","submit"}],
+ others= [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs =
+ [#xmlattr{name = 'type', value = "submit"}], children =
SubEls}]
},
- To = jlib:make_jid("", Host, ""),
+ To = exmpp_jid:make_jid(Host),
mod_announce:announce_commands(empty, From, To, Request)
end,
Time = timer:seconds(Delay),
@@ -1740,14 +1730,14 @@ get_last_info(User, Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
adhoc_sm_commands(_Acc, From,
- #jid{user = User, server = Server, lserver = LServer} = _To,
+ #jid{node = User, domain = Server, ldomain = LServer} = _To,
#adhoc_request{lang = Lang,
node = "config",
action = Action,
xdata = XData} = Request) ->
case acl:match_rule(LServer, configure, From) of
deny ->
- {error, ?ERR_FORBIDDEN};
+ {error, 'forbidden'};
allow ->
%% If the "action" attribute is not present, it is
%% understood as "execute". If there was no
@@ -1775,12 +1765,12 @@ adhoc_sm_commands(_Acc, From,
%% User returns form.
case jlib:parse_xdata_submit(XData) of
invalid ->
- {error, ?ERR_BAD_REQUEST};
+ {error, 'bad-request'};
Fields ->
set_sm_form(User, Server, "config", Request, Fields)
end;
true ->
- {error, ?ERR_BAD_REQUEST}
+ {error, 'bad-request'}
end
end;
@@ -1788,30 +1778,30 @@ adhoc_sm_commands(Acc, _From, _To, _Request) ->
Acc.
get_sm_form(User, Server, "config", Lang) ->
- {result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
+ {result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
- {xmlelement, "title", [],
- [{xmlcdata,
- ?T(
- Lang, "Administration of ") ++ User}]},
- {xmlelement, "field",
- [{"type", "list-single"},
- {"label", ?T(Lang, "Action on user")},
- {"var", "action"}],
- [{xmlelement, "value", [], [{xmlcdata, "edit"}]},
- {xmlelement, "option",
- [{"label", ?T(Lang, "Edit Properties")}],
- [{xmlelement, "value", [], [{xmlcdata, "edit"}]}]},
- {xmlelement, "option",
- [{"label", ?T(Lang, "Remove User")}],
- [{xmlelement, "value", [], [{xmlcdata, "remove"}]}]}
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
+ [#xmlcdata{cdata =
+ list_to_binary(?T(
+ Lang, "Administration of ") ++ User)}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'field', attrs =
+ [#xmlattr{name = 'type', value = "list-single"},
+ #xmlattr{name = 'label', value = ?T(Lang, "Action on user")},
+ #xmlattr{name = 'var', value = "action"}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"edit">>}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', attrs =
+ [#xmlattr{name = 'label', value = ?T(Lang, "Edit Properties")}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"edit">>}]}]},
+ #xmlel{ns = ?NS_DATA_FORMS, name = 'option', attrs =
+ [#xmlattr{name = 'label', value = ?T(Lang, "Remove User")}], children =
+ [#xmlel{ns = ?NS_DATA_FORMS, name = 'value', children = [#xmlcdata{cdata = <<"remove">>}]}]}
]},
?XFIELD("text-private", "Password", "password",
ejabberd_auth:get_password_s(User, Server))
]}]};
get_sm_form(_User, _Server, _Node, _Lang) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
+ {error, 'service-unavailable'}.
set_sm_form(User, Server, "config",
@@ -1829,17 +1819,17 @@ set_sm_form(User, Server, "config",
ejabberd_auth:set_password(User, Server, Password),
adhoc:produce_response(Response);
_ ->
- {error, ?ERR_NOT_ACCEPTABLE}
+ {error, 'not-acceptable'}
end;
{value, {_, ["remove"]}} ->
catch ejabberd_auth:remove_user(User, Server),
adhoc:produce_response(Response);
_ ->
- {error, ?ERR_NOT_ACCEPTABLE}
+ {error, 'not-acceptable'}
end;
set_sm_form(_User, _Server, _Node, _Request, _Fields) ->
- {error, ?ERR_SERVICE_UNAVAILABLE}.
+ {error, 'service-unavailable'}.
From d9a493561b8cf0f186ab7502e97c3e1ad1fee81c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 6 Aug 2008 13:44:58 +0000
Subject: [PATCH 053/582] Convert to exmpp.
SVN Revision: 1513
---
ChangeLog | 6 ++
src/gen_iq_handler.erl | 4 +
src/mod_configure2.erl | 81 +++++++++-------
src/mod_echo.erl | 21 ++--
src/mod_last.erl | 68 ++++++-------
src/mod_last_odbc.erl | 71 +++++++-------
src/mod_offline.erl | 205 +++++++++++++++++++++------------------
src/mod_offline_odbc.erl | 188 +++++++++++++++++------------------
8 files changed, 330 insertions(+), 314 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 8e9dce87a..0ef9fe049 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-08-06 Jean-Sébastien Pédron
+
+ * src/mod_offline.erl, src/mod_offline_odbc.erl, src/mod_echo.erl,
+ src/mod_last.erl, src/mod_configure2.erl, src/mod_last_odbc.erl,
+ src/gen_iq_handler.erl: Convert to exmpp.
+
2008-07-25 Jean-Sébastien Pédron
* src/adhoc.erl, src/mod_configure.erl, src/mod_announce.erl,
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index 33d445942..97a24efbb 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -63,7 +63,11 @@
mod_annouce,
mod_caps,
mod_configure,
+ mod_configure2,
mod_disco,
+ mod_echo,
+ mod_offline,
+ mod_offline_odbc,
mod_roster,
mod_vcard
]).
diff --git a/src/mod_configure2.erl b/src/mod_configure2.erl
index db84c43b7..2b6874112 100644
--- a/src/mod_configure2.erl
+++ b/src/mod_configure2.erl
@@ -33,30 +33,36 @@
stop/1,
process_local_iq/3]).
--include("ejabberd.hrl").
--include("jlib.hrl").
+-include_lib("exmpp/include/exmpp.hrl").
--define(NS_ECONFIGURE, "http://ejabberd.jabberstudio.org/protocol/configure").
+-include("ejabberd.hrl").
+
+% XXX The namespace used in this module isn't known by Exmpp: if the
+% known list isn't updated by Ejabberd, some element names will be
+% represented with strings.
+% XXX This module currently supposed that they'll be atoms.
+
+-define(NS_ECONFIGURE, 'http://ejabberd.jabberstudio.org/protocol/configure').
+-define(NS_ECONFIGURE_s, "http://ejabberd.jabberstudio.org/protocol/configure").
start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE_s,
?MODULE, process_local_iq, IQDisc),
ok.
stop(Host) ->
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE).
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE_s).
-process_local_iq(From, To, #iq{type = Type, lang = _Lang, sub_el = SubEl} = IQ) ->
- case acl:match_rule(To#jid.lserver, configure, From) of
+process_local_iq(From, To, IQ) ->
+ case acl:match_rule(To#jid.ldomain, configure, From) of
deny ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
allow ->
- case Type of
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_FEATURE_NOT_IMPLEMENTED]};
+ exmpp_iq:error(IQ, 'feature-not-implemented');
%%case xml:get_tag_attr_s("type", SubEl) of
%% "cancel" ->
%% IQ#iq{type = result,
@@ -90,56 +96,57 @@ process_local_iq(From, To, #iq{type = Type, lang = _Lang, sub_el = SubEl} = IQ)
%% sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
%%end;
get ->
- case process_get(SubEl) of
+ case process_get(IQ#xmlel.children) of
{result, Res} ->
- IQ#iq{type = result, sub_el = [Res]};
+ exmpp_iq:result(IQ, Res);
{error, Error} ->
- IQ#iq{type = error, sub_el = [SubEl, Error]}
+ exmpp_iq:error(IQ, Error)
end
end
end.
-process_get({xmlelement, "info", _Attrs, _SubEls}) ->
+process_get(#xmlel{ns = ?NS_ECONFIGURE, name = 'info'}) ->
S2SConns = ejabberd_s2s:dirty_get_connections(),
TConns = lists:usort([element(2, C) || C <- S2SConns]),
- Attrs = [{"registered-users",
+ Attrs = [#xmlattr{name = 'registered-users', value =
integer_to_list(mnesia:table_info(passwd, size))},
- {"online-users",
+ #xmlattr{name = 'online-users', value =
integer_to_list(mnesia:table_info(presence, size))},
- {"running-nodes",
+ #xmlattr{name = 'running-nodes', value =
integer_to_list(length(mnesia:system_info(running_db_nodes)))},
- {"stopped-nodes",
+ #xmlattr{name = 'stopped-nodes', value =
integer_to_list(
length(lists:usort(mnesia:system_info(db_nodes) ++
mnesia:system_info(extra_db_nodes)) --
mnesia:system_info(running_db_nodes)))},
- {"outgoing-s2s-servers", integer_to_list(length(TConns))}],
- {result, {xmlelement, "info",
- [{"xmlns", ?NS_ECONFIGURE} | Attrs], []}};
-process_get({xmlelement, "welcome-message", Attrs, _SubEls}) ->
+ #xmlattr{name = 'outgoing-s2s-servers', value =
+ integer_to_list(length(TConns))}],
+ {result, #xmlel{ns = ?NS_ECONFIGURE, name = 'info', attrs = Attrs}};
+process_get(#xmlel{ns = ?NS_ECONFIGURE, name = 'welcome-message', attrs = Attrs}) ->
{Subj, Body} = case ejabberd_config:get_local_option(welcome_message) of
{_Subj, _Body} = SB -> SB;
_ -> {"", ""}
end,
- {result, {xmlelement, "welcome-message", Attrs,
- [{xmlelement, "subject", [], [{xmlcdata, Subj}]},
- {xmlelement, "body", [], [{xmlcdata, Body}]}]}};
-process_get({xmlelement, "registration-watchers", Attrs, _SubEls}) ->
+ {result, #xmlel{ns = ?NS_ECONFIGURE, name = 'welcome-message',
+ attrs = Attrs, children =
+ [#xmlel{ns = ?NS_ECONFIGURE, name = 'subject', children = [#xmlcdata{cdata = list_to_binary(Subj)}]},
+ #xmlel{ns = ?NS_ECONFIGURE, name = 'body', children = [#xmlcdata{cdata = list_to_binary(Body)}]}]}};
+process_get(#xmlel{ns = ?NS_ECONFIGURE, name = 'registration-watchers', attrs = Attrs}) ->
SubEls =
case ejabberd_config:get_local_option(registration_watchers) of
JIDs when is_list(JIDs) ->
lists:map(fun(JID) ->
- {xmlelement, "jid", [], [{xmlcdata, JID}]}
+ #xmlel{ns = ?NS_ECONFIGURE, name = 'jid', children = [#xmlcdata{cdata = list_to_binary(JID)}]}
end, JIDs);
_ ->
[]
end,
- {result, {xmlelement, "registration_watchers", Attrs, SubEls}};
-process_get({xmlelement, "acls", Attrs, _SubEls}) ->
+ {result, #xmlel{ns = ?NS_ECONFIGURE, name = 'registration_watchers', attrs = Attrs, children = SubEls}};
+process_get(#xmlel{ns = ?NS_ECONFIGURE, name = 'acls', attrs = Attrs}) ->
Str = lists:flatten(io_lib:format("~p.", [ets:tab2list(acl)])),
- {result, {xmlelement, "acls", Attrs, [{xmlcdata, Str}]}};
-process_get({xmlelement, "access", Attrs, _SubEls}) ->
+ {result, #xmlel{ns = ?NS_ECONFIGURE, name = 'acls', attrs = Attrs, children = [#xmlcdata{cdata = list_to_binary(Str)}]}};
+process_get(#xmlel{ns = ?NS_ECONFIGURE, name = 'access', attrs = Attrs}) ->
Str =
lists:flatten(
io_lib:format(
@@ -149,22 +156,22 @@ process_get({xmlelement, "access", Attrs, _SubEls}) ->
[],
[{{access, '$1', '$2'}}]}])
])),
- {result, {xmlelement, "access", Attrs, [{xmlcdata, Str}]}};
-process_get({xmlelement, "last", Attrs, _SubEls}) ->
+ {result, #xmlel{ns = ?NS_ECONFIGURE, name = 'access', attrs = Attrs, children = [#xmlcdata{cdata = list_to_binary(Str)}]}};
+process_get(#xmlel{ns = ?NS_ECONFIGURE, name = 'last', attrs = Attrs}) ->
case catch mnesia:dirty_select(
last_activity, [{{last_activity, '_', '$1', '_'}, [], ['$1']}]) of
{'EXIT', _Reason} ->
- {error, ?ERR_INTERNAL_SERVER_ERROR};
+ {error, 'internal-server-error'};
Vals ->
{MegaSecs, Secs, _MicroSecs} = now(),
TimeStamp = MegaSecs * 1000000 + Secs,
Str = lists:flatten(
lists:append(
[[integer_to_list(TimeStamp - V), " "] || V <- Vals])),
- {result, {xmlelement, "last", Attrs, [{xmlcdata, Str}]}}
+ {result, #xmlel{ns = ?NS_ECONFIGURE, name = 'last', attrs = Attrs, children = [#xmlcdata{cdata = list_to_binary(Str)}]}}
end;
%%process_get({xmlelement, Name, Attrs, SubEls}) ->
%% {result, };
process_get(_) ->
- {error, ?ERR_BAD_REQUEST}.
+ {error, 'bad-request'}.
diff --git a/src/mod_echo.erl b/src/mod_echo.erl
index 22875adcd..f2540081c 100644
--- a/src/mod_echo.erl
+++ b/src/mod_echo.erl
@@ -37,8 +37,9 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-record(state, {host}).
@@ -117,8 +118,8 @@ handle_cast(_Msg, State) ->
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({route, From, To, Packet}, State) ->
- Packet2 = case From#jid.user of
- "" -> jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST);
+ Packet2 = case From#jid.node of
+ <<>> -> exmpp_stanza:reply_with_error(Packet, 'bad-request');
_ -> Packet
end,
do_client_version(disabled, To, From), % Put 'enabled' to enable it
@@ -171,16 +172,16 @@ code_change(_OldVsn, State, _Extra) ->
do_client_version(disabled, _From, _To) ->
ok;
do_client_version(enabled, From, To) ->
- ToS = jlib:jid_to_string(To),
%% It is important to identify this process and packet
Random_resource = integer_to_list(random:uniform(100000)),
From2 = From#jid{resource = Random_resource,
lresource = Random_resource},
%% Build an iq:query request
- Packet = {xmlelement, "iq",
- [{"to", ToS}, {"type", "get"}],
- [{xmlelement, "query", [{"xmlns", ?NS_VERSION}], []}]},
+ Request = #xmlel{ns = ?NS_SOFT_VERSION, name = 'query'},
+ Packet = exmpp_stanza:set_recipient(
+ exmpp_iq:get(?NS_JABBER_CLIENT, Request),
+ To),
%% Send the request
ejabberd_router:route(From2, To, Packet),
@@ -189,15 +190,15 @@ do_client_version(enabled, From, To) ->
%% It is very important to only accept a packet which is the
%% response to the request that he sent
Els = receive {route, To, From2, IQ} ->
- {xmlelement, "query", _, List} = xml:get_subtag(IQ, "query"),
+ #xmlel{ns = ?NS_SOFT_VERSION, name = 'query', children = List} = exmpp_iq:get_payload(IQ),
List
after 5000 -> % Timeout in miliseconds: 5 seconds
[]
end,
- Values = [{Name, Value} || {xmlelement,Name,[],[{xmlcdata,Value}]} <- Els],
+ Values = [{Name, binary_to_list(Value)} || #xmlel{name = Name, children = [#xmlcdata{cdata = Value}]} <- Els],
%% Print in log
Values_string1 = [io_lib:format("~n~s: ~p", [N, V]) || {N, V} <- Values],
Values_string2 = lists:concat(Values_string1),
- ?INFO_MSG("Information of the client: ~s~s", [ToS, Values_string2]).
+ ?INFO_MSG("Information of the client: ~s~s", [exmpp_jid:jid_to_string(To), Values_string2]).
diff --git a/src/mod_last.erl b/src/mod_last.erl
index 3ed5964c7..dee915f86 100644
--- a/src/mod_last.erl
+++ b/src/mod_last.erl
@@ -38,8 +38,9 @@
get_last_info/2,
remove_user/2]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("mod_privacy.hrl").
-record(last_activity, {us, timestamp, status}).
@@ -51,9 +52,9 @@ start(Host, Opts) ->
[{disc_copies, [node()]},
{attributes, record_info(fields, last_activity)}]),
update_table(),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY_s,
?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY_s,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(remove_user, Host,
?MODULE, remove_user, 50),
@@ -65,30 +66,28 @@ stop(Host) ->
?MODULE, remove_user, 50),
ejabberd_hooks:delete(unset_presence_hook, Host,
?MODULE, on_presence_update, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST).
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY_s),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY_s).
-process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
+process_local_iq(_From, _To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
get ->
Sec = trunc(element(1, erlang:statistics(wall_clock))/1000),
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_LAST},
- {"seconds", integer_to_list(Sec)}],
- []}]}
+ Response = #xmlel{ns = ?NS_LAST_ACTIVITY, name = 'query', attrs =
+ [#xmlattr{name = 'seconds', value = integer_to_list(Sec)}]},
+ exmpp_iq:result(IQ, Response)
end.
-process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
+process_sm_iq(From, To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
get ->
- User = To#jid.luser,
- Server = To#jid.lserver,
+ User = To#jid.lnode,
+ Server = To#jid.ldomain,
{Subscription, _Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, Server,
@@ -104,36 +103,33 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
allow,
[User, Server, UserListRecord,
{From, To,
- {xmlelement, "presence", [], []}},
+ exmpp_presence:available()},
out]) of
allow ->
- get_last(IQ, SubEl, User, Server);
+ get_last(IQ, User, Server);
deny ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
+ exmpp_iq:error(IQ, 'not-allowed')
end;
true ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
+ exmpp_iq:error(IQ, 'not-allowed')
end
end.
%% TODO: This function could use get_last_info/2
-get_last(IQ, SubEl, LUser, LServer) ->
+get_last(IQ, LUser, LServer) ->
case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of
{'EXIT', _Reason} ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
+ exmpp_iq:error(IQ, 'internal-server-error');
[] ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
+ exmpp_iq:error(IQ, 'service-unavailable');
[#last_activity{timestamp = TimeStamp, status = Status}] ->
{MegaSecs, Secs, _MicroSecs} = now(),
TimeStamp2 = MegaSecs * 1000000 + Secs,
Sec = TimeStamp2 - TimeStamp,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_LAST},
- {"seconds", integer_to_list(Sec)}],
- [{xmlcdata, Status}]}]}
+ Response = #xmlel{ns = ?NS_LAST_ACTIVITY, name = 'query',
+ attrs = [#xmlattr{name = 'seconds', value = integer_to_list(Sec)}],
+ children = [#xmlcdata{cdata = list_to_binary(Status)}]},
+ exmpp_iq:result(IQ, Response)
end.
@@ -144,8 +140,8 @@ on_presence_update(User, Server, _Resource, Status) ->
store_last_info(User, Server, TimeStamp, Status).
store_last_info(User, Server, TimeStamp, Status) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
F = fun() ->
mnesia:write(#last_activity{us = US,
@@ -166,8 +162,8 @@ get_last_info(LUser, LServer) ->
end.
remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
F = fun() ->
mnesia:delete({last_activity, US})
diff --git a/src/mod_last_odbc.erl b/src/mod_last_odbc.erl
index 053876766..76489b4c0 100644
--- a/src/mod_last_odbc.erl
+++ b/src/mod_last_odbc.erl
@@ -38,15 +38,16 @@
get_last_info/2,
remove_user/2]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("mod_privacy.hrl").
start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY_s,
?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY_s,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(remove_user, Host,
?MODULE, remove_user, 50),
@@ -58,29 +59,27 @@ stop(Host) ->
?MODULE, remove_user, 50),
ejabberd_hooks:delete(unset_presence_hook, Host,
?MODULE, on_presence_update, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST).
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY_s),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY_s).
-process_local_iq(_From, _To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
+process_local_iq(_From, _To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
get ->
Sec = trunc(element(1, erlang:statistics(wall_clock))/1000),
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_LAST},
- {"seconds", integer_to_list(Sec)}],
- []}]}
+ Response = #xmlel{ns = ?NS_LAST_ACTIVITY, name = 'query', attrs =
+ [#xmlattr{name = 'seconds', value = integer_to_list(Sec)}]},
+ exmpp_iq:result(IQ, Response)
end.
-process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
- case Type of
+process_sm_iq(From, To, IQ) ->
+ case exmpp_iq:get_type(IQ) of
set ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ exmpp_iq:error(IQ, 'not-allowed');
get ->
- User = To#jid.luser,
- Server = To#jid.lserver,
+ User = To#jid.lnode,
+ Server = To#jid.ldomain,
{Subscription, _Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, Server,
@@ -96,42 +95,38 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
allow,
[User, Server, UserListRecord,
{From, To,
- {xmlelement, "presence", [], []}},
+ exmpp_presence:available()},
out]) of
allow ->
- get_last(IQ, SubEl, User, Server);
+ get_last(IQ, User, Server);
deny ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
+ exmpp_iq:error(IQ, 'not-allowed')
end;
true ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
+ exmpp_iq:error(IQ, 'not-allowed')
end
end.
%% TODO: This function could use get_last_info/2
-get_last(IQ, SubEl, LUser, LServer) ->
+get_last(IQ, LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_last(LServer, Username) of
{'EXIT', _Reason} ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]};
+ exmpp_iq:error(IQ, 'internal-server-error');
{selected, ["seconds","state"], []} ->
- IQ#iq{type = error, sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]};
+ exmpp_iq:error(IQ, 'service-unavailable');
{selected, ["seconds","state"], [{STimeStamp, Status}]} ->
case catch list_to_integer(STimeStamp) of
TimeStamp when is_integer(TimeStamp) ->
{MegaSecs, Secs, _MicroSecs} = now(),
TimeStamp2 = MegaSecs * 1000000 + Secs,
Sec = TimeStamp2 - TimeStamp,
- IQ#iq{type = result,
- sub_el = [{xmlelement, "query",
- [{"xmlns", ?NS_LAST},
- {"seconds", integer_to_list(Sec)}],
- [{xmlcdata, Status}]}]};
+ Response = #xmlel{ns = ?NS_LAST_ACTIVITY, name = 'query',
+ attrs = [#xmlattr{name = 'seconds', value = integer_to_list(Sec)}],
+ children = [#xmlcdata{cdata = list_to_binary(Status)}]},
+ exmpp_iq:result(IQ, Response);
_ ->
- IQ#iq{type = error,
- sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
+ exmpp_iq:error(IQ, 'internal-server-error')
end
end.
@@ -141,8 +136,8 @@ on_presence_update(User, Server, _Resource, Status) ->
store_last_info(User, Server, TimeStamp, Status).
store_last_info(User, Server, TimeStamp, Status) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
State = ejabberd_odbc:escape(Status),
@@ -166,7 +161,7 @@ get_last_info(LUser, LServer) ->
end.
remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
odbc_queries:del_last(LServer, Username).
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index 3a751c328..283d68607 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -41,8 +41,9 @@
webadmin_page/3,
webadmin_user/4]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("web/ejabberd_http.hrl").
-include("web/ejabberd_web_admin.hrl").
@@ -51,6 +52,11 @@
-define(PROCNAME, ejabberd_offline).
-define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, ?NS_JABBER_CLIENT).
+-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
+
start(Host, Opts) ->
mnesia:create_table(offline_msg,
[{disc_only_copies, [node()]},
@@ -142,23 +148,25 @@ stop(Host) ->
{wait, Proc}.
store_packet(From, To, Packet) ->
- Type = xml:get_tag_attr_s("type", Packet),
+ Type = exmpp_stanza:get_type(Packet),
if
(Type /= "error") and (Type /= "groupchat") and
(Type /= "headline") ->
case check_event(From, To, Packet) of
true ->
- #jid{luser = LUser, lserver = LServer} = To,
+ #jid{lnode = LUser, ldomain = LServer} = To,
TimeStamp = now(),
- {xmlelement, _Name, _Attrs, Els} = Packet,
- Expire = find_x_expire(TimeStamp, Els),
- gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) !
+ Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
+ % XXX OLD FORMAT: Packet is stored in the old format.
+ PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME) !
#offline_msg{us = {LUser, LServer},
timestamp = TimeStamp,
expire = Expire,
from = From,
to = To,
- packet = Packet},
+ packet = PacketOld},
stop;
_ ->
ok
@@ -168,31 +176,28 @@ store_packet(From, To, Packet) ->
end.
check_event(From, To, Packet) ->
- {xmlelement, Name, Attrs, Els} = Packet,
- case find_x_event(Els) of
+ case find_x_event(Packet#xmlel.children) of
false ->
true;
El ->
- case xml:get_subtag(El, "id") of
- false ->
- case xml:get_subtag(El, "offline") of
- false ->
+ case exmpp_xml:get_element(El, 'id') of
+ undefined ->
+ case exmpp_xml:get_element(El, 'offline') of
+ undefined ->
true;
_ ->
- ID = case xml:get_tag_attr_s("id", Packet) of
- "" ->
- {xmlelement, "id", [], []};
+ ID = case exmpp_stanza:get_id(Packet) of
+ undefined ->
+ #xmlel{ns = ?NS_MESSAGE_EVENT, name = 'id'};
S ->
- {xmlelement, "id", [],
- [{xmlcdata, S}]}
+ #xmlel{ns = ?NS_MESSAGE_EVENT, name = 'id',
+ children = [#xmlcdata{cdata =
+ list_to_binary(S)}]}
end,
+ X = #xmlel{ns = ?NS_MESSAGE_EVENT, name = 'x', children =
+ [ID, #xmlel{ns = ?NS_MESSAGE_EVENT, name = 'offline'}]},
ejabberd_router:route(
- To, From, {xmlelement, Name, Attrs,
- [{xmlelement, "x",
- [{"xmlns", ?NS_EVENT}],
- [ID,
- {xmlelement, "offline", [], []}]}]
- }),
+ To, From, exmpp_xml:set_children(Packet, [X])),
true
end;
_ ->
@@ -202,44 +207,34 @@ check_event(From, To, Packet) ->
find_x_event([]) ->
false;
-find_x_event([{xmlcdata, _} | Els]) ->
- find_x_event(Els);
-find_x_event([El | Els]) ->
- case xml:get_tag_attr_s("xmlns", El) of
- ?NS_EVENT ->
- El;
- _ ->
- find_x_event(Els)
- end.
+find_x_event([#xmlel{ns = ?NS_MESSAGE_EVENT} = El | _Els]) ->
+ El;
+find_x_event([_ | Els]) ->
+ find_x_event(Els).
find_x_expire(_, []) ->
never;
-find_x_expire(TimeStamp, [{xmlcdata, _} | Els]) ->
- find_x_expire(TimeStamp, Els);
-find_x_expire(TimeStamp, [El | Els]) ->
- case xml:get_tag_attr_s("xmlns", El) of
- ?NS_EXPIRE ->
- Val = xml:get_tag_attr_s("seconds", El),
- case catch list_to_integer(Val) of
- {'EXIT', _} ->
- never;
- Int when Int > 0 ->
- {MegaSecs, Secs, MicroSecs} = TimeStamp,
- S = MegaSecs * 1000000 + Secs + Int,
- MegaSecs1 = S div 1000000,
- Secs1 = S rem 1000000,
- {MegaSecs1, Secs1, MicroSecs};
- _ ->
- never
- end;
+find_x_expire(TimeStamp, [#xmlel{ns = ?NS_MESSAGE_EXPIRE} = El | _Els]) ->
+ Val = exmpp_xml:get_attribute(El, 'seconds', ""),
+ case catch list_to_integer(Val) of
+ {'EXIT', _} ->
+ never;
+ Int when Int > 0 ->
+ {MegaSecs, Secs, MicroSecs} = TimeStamp,
+ S = MegaSecs * 1000000 + Secs + Int,
+ MegaSecs1 = S div 1000000,
+ Secs1 = S rem 1000000,
+ {MegaSecs1, Secs1, MicroSecs};
_ ->
- find_x_expire(TimeStamp, Els)
- end.
+ never
+ end;
+find_x_expire(TimeStamp, [_ | Els]) ->
+ find_x_expire(TimeStamp, Els).
resend_offline_messages(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
F = fun() ->
Rs = mnesia:wread({offline_msg, US}),
@@ -250,16 +245,22 @@ resend_offline_messages(User, Server) ->
{atomic, Rs} ->
lists:foreach(
fun(R) ->
- {xmlelement, Name, Attrs, Els} = R#offline_msg.packet,
+ Packet = case R#offline_msg.packet of
+ #xmlelement{} = P ->
+ exmpp_xml:xmlelement_to_xmlel(P,
+ [?DEFAULT_NS], ?PREFIXED_NS);
+ #xmlel{} = P ->
+ P
+ end,
+ % XXX OLD FORMAT: Convert From & To.
ejabberd_sm !
{route,
- R#offline_msg.from,
- R#offline_msg.to,
- {xmlelement, Name, Attrs,
- Els ++
- [jlib:timestamp_to_xml(
+ jlib:from_old_jid(R#offline_msg.from),
+ jlib:from_old_jid(R#offline_msg.to),
+ exmpp_xml:append_child(Packet,
+ jlib:timestamp_to_xml(
calendar:now_to_universal_time(
- R#offline_msg.timestamp))]}}
+ R#offline_msg.timestamp)))}
end,
lists:keysort(#offline_msg.timestamp, Rs));
_ ->
@@ -267,8 +268,8 @@ resend_offline_messages(User, Server) ->
end.
pop_offline_messages(Ls, User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
F = fun() ->
Rs = mnesia:wread({offline_msg, US}),
@@ -280,15 +281,21 @@ pop_offline_messages(Ls, User, Server) ->
TS = now(),
Ls ++ lists:map(
fun(R) ->
- {xmlelement, Name, Attrs, Els} = R#offline_msg.packet,
+ Packet = case R#offline_msg.packet of
+ #xmlelement{} = P ->
+ exmpp_xml:xmlelement_to_xmlel(P,
+ [?DEFAULT_NS], ?PREFIXED_NS);
+ #xmlel{} = P ->
+ P
+ end,
+ % XXX OLD FORMAT: Convert From & To.
{route,
- R#offline_msg.from,
- R#offline_msg.to,
- {xmlelement, Name, Attrs,
- Els ++
- [jlib:timestamp_to_xml(
+ jlib:from_old_jid(R#offline_msg.from),
+ jlib:from_old_jid(R#offline_msg.to),
+ exmpp_xml:append_child(Packet,
+ jlib:timestamp_to_xml(
calendar:now_to_universal_time(
- R#offline_msg.timestamp))]}}
+ R#offline_msg.timestamp)))}
end,
lists:filter(
fun(R) ->
@@ -343,8 +350,8 @@ remove_old_messages(Days) ->
mnesia:transaction(F).
remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
F = fun() ->
mnesia:delete({offline_msg, US})
@@ -371,10 +378,15 @@ update_table() ->
F1 = fun() ->
mnesia:write_lock_table(mod_offline_tmp_table),
mnesia:foldl(
- fun(#offline_msg{us = U} = R, _) ->
+ fun(#offline_msg{us = U, packet = P} = R, _) ->
+ New_R = R#offline_msg{
+ us = {U, Host},
+ packet = exmpp_xml:xmlelement_to_xmlel(P,
+ [?DEFAULT_NS], ?PREFIXED_NS)
+ },
mnesia:dirty_write(
mod_offline_tmp_table,
- R#offline_msg{us = {U, Host}})
+ New_R)
end, ok, offline_msg)
end,
mnesia:transaction(F1),
@@ -402,8 +414,7 @@ update_table() ->
mnesia:transform_table(
offline_msg,
fun({_, U, TS, F, T, P}) ->
- {xmlelement, _Name, _Attrs, Els} = P,
- Expire = find_x_expire(TS, Els),
+ Expire = find_x_expire(TS, P#xmlelement.children),
#offline_msg{us = U,
timestamp = TS,
expire = Expire,
@@ -442,14 +453,21 @@ update_table() ->
%% Warn senders that their messages have been discarded:
discard_warn_sender(Msgs) ->
lists:foreach(
- fun(#offline_msg{from=From, to=To, packet=Packet}) ->
+ fun(#offline_msg{from=From, to=To, packet=Packet0}) ->
+ Packet = case Packet0 of
+ #xmlelement{} = P ->
+ exmpp_xml:xmlelement_to_xmlel(P,
+ [?DEFAULT_NS], ?PREFIXED_NS);
+ #xmlel{} = P ->
+ P
+ end,
ErrText = "Your contact offline message queue is full. The message has been discarded.",
- Lang = xml:get_tag_attr_s("xml:lang", Packet),
- Err = jlib:make_error_reply(
- Packet, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)),
+ Error = exmpp_stanza:error('resource-constraint',
+ {"en", ErrText}),
+ Err = exmpp_stanza:reply_with_error(Packet, Error),
ejabberd_router:route(
- To,
- From, Err)
+ jlib:from_old_jid(To),
+ jlib:from_old_jid(From), Err)
end, Msgs).
@@ -464,14 +482,14 @@ webadmin_page(_, Host,
webadmin_page(Acc, _, _) -> Acc.
user_queue(User, Server, Query, Lang) ->
- US = {jlib:nodeprep(User), jlib:nameprep(Server)},
+ US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
Res = user_queue_parse_query(US, Query),
Msgs = lists:keysort(#offline_msg.timestamp,
mnesia:dirty_read({offline_msg, US})),
FMsgs =
lists:map(
fun(#offline_msg{timestamp = TimeStamp, from = From, to = To,
- packet = {xmlelement, Name, Attrs, Els}} = Msg) ->
+ packet = Packet} = Msg) ->
ID = jlib:encode_base64(binary_to_list(term_to_binary(Msg))),
{{Year, Month, Day}, {Hour, Minute, Second}} =
calendar:now_to_local_time(TimeStamp),
@@ -479,11 +497,14 @@ user_queue(User, Server, Query, Lang) ->
io_lib:format(
"~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
[Year, Month, Day, Hour, Minute, Second])),
- SFrom = jlib:jid_to_string(From),
- STo = jlib:jid_to_string(To),
- Attrs2 = jlib:replace_from_to_attrs(SFrom, STo, Attrs),
- Packet = {xmlelement, Name, Attrs2, Els},
- FPacket = ejabberd_web_admin:pretty_print_xml(Packet),
+ SFrom = exmpp_jid:jid_to_string(jlib:from_old_jid(From)),
+ STo = exmpp_jid:jid_to_string(jlib:from_old_jid(To)),
+ Packet0 = exmpp_xml:xmlelement_to_xmlel(Packet,
+ [?DEFAULT_NS], ?PREFIXED_NS),
+ Packet1 = exmpp_stanza:set_jids(Packet0, SFrom, STo),
+ FPacket = exmpp_xml:node_to_list(
+ exmpp_xml:indent_document(Packet1, <<" ">>),
+ [?DEFAULT_NS], ?PREFIXED_NS),
?XE("tr",
[?XAE("td", [{"class", "valign"}], [?INPUT("checkbox", "selected", ID)]),
?XAC("td", [{"class", "valign"}], Time),
@@ -547,10 +568,10 @@ user_queue_parse_query(US, Query) ->
end.
us_to_list({User, Server}) ->
- jlib:jid_to_string({User, Server, ""}).
+ exmpp_jid:jid_to_string(User, Server).
webadmin_user(Acc, User, Server, Lang) ->
- US = {jlib:nodeprep(User), jlib:nameprep(Server)},
+ US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
QueueLen = length(mnesia:dirty_read({offline_msg, US})),
FQueueLen = [?AC("queue/",
integer_to_list(QueueLen))],
diff --git a/src/mod_offline_odbc.erl b/src/mod_offline_odbc.erl
index c3d0513d0..a8831aa0d 100644
--- a/src/mod_offline_odbc.erl
+++ b/src/mod_offline_odbc.erl
@@ -40,8 +40,9 @@
webadmin_page/3,
webadmin_user/4]).
+-include_lib("exmpp/include/exmpp.hrl").
+
-include("ejabberd.hrl").
--include("jlib.hrl").
-include("web/ejabberd_http.hrl").
-include("web/ejabberd_web_admin.hrl").
@@ -50,6 +51,11 @@
-define(PROCNAME, ejabberd_offline).
-define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
+% These are the namespace already declared by the stream opening. This is
+% used at serialization time.
+-define(DEFAULT_NS, ?NS_JABBER_CLIENT).
+-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
+
start(Host, Opts) ->
ejabberd_hooks:add(offline_message_hook, Host,
?MODULE, store_packet, 50),
@@ -93,24 +99,20 @@ loop(Host, MaxOfflineMsgs) ->
fun(M) ->
Username =
ejabberd_odbc:escape(
- (M#offline_msg.to)#jid.luser),
+ (M#offline_msg.to)#jid.lnode),
From = M#offline_msg.from,
To = M#offline_msg.to,
- {xmlelement, Name, Attrs, Els} =
- M#offline_msg.packet,
- Attrs2 = jlib:replace_from_to_attrs(
- jlib:jid_to_string(From),
- jlib:jid_to_string(To),
- Attrs),
- Packet = {xmlelement, Name, Attrs2,
- Els ++
- [jlib:timestamp_to_xml(
+ Packet0 = exmpp_stanza:set_jids(
+ From,
+ To,
+ M#offline_msg.packet),
+ Packet1 = exmpp_xml:append_child(Packet0,
+ jlib:timestamp_to_xml(
calendar:now_to_universal_time(
- M#offline_msg.timestamp))]},
+ M#offline_msg.timestamp))),
XML =
ejabberd_odbc:escape(
- lists:flatten(
- xml:element_to_string(Packet))),
+ exmpp_xml:document_to_string(Packet1)),
odbc_queries:add_spool_sql(Username, XML)
end, Msgs),
case catch odbc_queries:add_spool(Host, Query) of
@@ -152,17 +154,16 @@ stop(Host) ->
ok.
store_packet(From, To, Packet) ->
- Type = xml:get_tag_attr_s("type", Packet),
+ Type = exmpp_stanza_:get_type(Packet, 'type'),
if
(Type /= "error") and (Type /= "groupchat") and
(Type /= "headline") ->
case check_event(From, To, Packet) of
true ->
- #jid{luser = LUser} = To,
+ #jid{lnode = LUser} = To,
TimeStamp = now(),
- {xmlelement, _Name, _Attrs, Els} = Packet,
- Expire = find_x_expire(TimeStamp, Els),
- gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) !
+ Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
+ gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME) !
#offline_msg{user = LUser,
timestamp = TimeStamp,
expire = Expire,
@@ -178,31 +179,27 @@ store_packet(From, To, Packet) ->
end.
check_event(From, To, Packet) ->
- {xmlelement, Name, Attrs, Els} = Packet,
- case find_x_event(Els) of
+ case find_x_event(Packet#xmlel.children) of
false ->
true;
El ->
- case xml:get_subtag(El, "id") of
- false ->
- case xml:get_subtag(El, "offline") of
- false ->
+ case exmpp_xml:get_element(El, 'id') of
+ undefined ->
+ case exmpp_xml:get_element(El, 'offline') of
+ undefined ->
true;
_ ->
- ID = case xml:get_tag_attr_s("id", Packet) of
+ ID = case exmpp_xml:get_attribute(Packet, 'id', "") of
"" ->
- {xmlelement, "id", [], []};
+ #xmlel{ns = ?NS_MESSAGE_EVENT, name = 'id'};
S ->
- {xmlelement, "id", [],
- [{xmlcdata, S}]}
+ #xmlel{ns = ?NS_MESSAGE_EVENT, name = 'id',
+ children = [#xmlcdata{cdata = list_to_binary(S)}]}
end,
+ X = #xmlel{ns = ?NS_MESSAGE_EVENT, name = 'x', children =
+ [ID, #xmlel{ns = ?NS_MESSAGE_EVENT, name = 'offline'}]},
ejabberd_router:route(
- To, From, {xmlelement, Name, Attrs,
- [{xmlelement, "x",
- [{"xmlns", ?NS_EVENT}],
- [ID,
- {xmlelement, "offline", [], []}]}]
- }),
+ To, From, exmpp_xml:set_children(Packet, [X])),
true
end;
_ ->
@@ -212,64 +209,49 @@ check_event(From, To, Packet) ->
find_x_event([]) ->
false;
-find_x_event([{xmlcdata, _} | Els]) ->
- find_x_event(Els);
-find_x_event([El | Els]) ->
- case xml:get_tag_attr_s("xmlns", El) of
- ?NS_EVENT ->
- El;
- _ ->
- find_x_event(Els)
- end.
+find_x_event([#xmlel{ns = ?NS_MESSAGE_EVENT} = El | _Els]) ->
+ El;
+find_x_event([_ | Els]) ->
+ find_x_event(Els).
find_x_expire(_, []) ->
never;
-find_x_expire(TimeStamp, [{xmlcdata, _} | Els]) ->
- find_x_expire(TimeStamp, Els);
-find_x_expire(TimeStamp, [El | Els]) ->
- case xml:get_tag_attr_s("xmlns", El) of
- ?NS_EXPIRE ->
- Val = xml:get_tag_attr_s("seconds", El),
- case catch list_to_integer(Val) of
- {'EXIT', _} ->
- never;
- Int when Int > 0 ->
- {MegaSecs, Secs, MicroSecs} = TimeStamp,
- S = MegaSecs * 1000000 + Secs + Int,
- MegaSecs1 = S div 1000000,
- Secs1 = S rem 1000000,
- {MegaSecs1, Secs1, MicroSecs};
- _ ->
- never
- end;
+find_x_expire(TimeStamp, [#xmlel{ns = ?NS_MESSAGE_EXPIRE} = El | _Els]) ->
+ Val = exmpp_xml:get_attribute(El, 'seconds', ""),
+ case catch list_to_integer(Val) of
+ {'EXIT', _} ->
+ never;
+ Int when Int > 0 ->
+ {MegaSecs, Secs, MicroSecs} = TimeStamp,
+ S = MegaSecs * 1000000 + Secs + Int,
+ MegaSecs1 = S div 1000000,
+ Secs1 = S rem 1000000,
+ {MegaSecs1, Secs1, MicroSecs};
_ ->
- find_x_expire(TimeStamp, Els)
- end.
+ never
+ end;
+find_x_expire(TimeStamp, [_ | Els]) ->
+ find_x_expire(TimeStamp, Els).
pop_offline_messages(Ls, User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
EUser = ejabberd_odbc:escape(LUser),
case odbc_queries:get_and_del_spool_msg_t(LServer, EUser) of
{atomic, {selected, ["username","xml"], Rs}} ->
Ls ++ lists:flatmap(
fun({_, XML}) ->
- case xml_stream:parse_element(XML) of
- {error, _Reason} ->
- [];
- El ->
- To = jlib:string_to_jid(
- xml:get_tag_attr_s("to", El)),
- From = jlib:string_to_jid(
- xml:get_tag_attr_s("from", El)),
- if
- (To /= error) and
- (From /= error) ->
- [{route, From, To, El}];
- true ->
- []
- end
+ try
+ [El] = exmpp_xml:parse_document(XML, [namespace, name_as_atom]),
+ To = exmpp_jid:list_to_jid(
+ exmpp_stanza:get_recipient(El)),
+ From = exmpp_jid:list_to_jid(
+ exmpp_stanza:get_sender(El)),
+ [{route, From, To, El}]
+ catch
+ _ ->
+ []
end
end, Rs);
_ ->
@@ -278,8 +260,8 @@ pop_offline_messages(Ls, User, Server) ->
remove_user(User, Server) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
odbc_queries:del_spool_msg(LServer, Username).
@@ -294,9 +276,9 @@ discard_warn_sender(Msgs) ->
lists:foreach(
fun(#offline_msg{from=From, to=To, packet=Packet}) ->
ErrText = "Your contact offline message queue is full. The message has been discarded.",
- Lang = xml:get_tag_attr_s("xml:lang", Packet),
- Err = jlib:make_error_reply(
- Packet, ?ERRT_RESOURCE_CONSTRAINT(Lang, ErrText)),
+ Error = exmpp_stanza:error('resource-constraint',
+ {"en", ErrText}),
+ Err = exmpp_stanza:reply_with_error(Packet, Error),
ejabberd_router:route(
To,
From, Err)
@@ -314,8 +296,8 @@ webadmin_page(_, Host,
webadmin_page(Acc, _, _) -> Acc.
user_queue(User, Server, Query, Lang) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
US = {LUser, LServer},
Res = user_queue_parse_query(Username, LServer, Query),
@@ -327,11 +309,12 @@ user_queue(User, Server, Query, Lang) ->
{selected, ["username", "xml"], Rs} ->
lists:flatmap(
fun({_, XML}) ->
- case xml_stream:parse_element(XML) of
- {error, _Reason} ->
- [];
- El ->
+ try exmpp_xml:parse_document(XML, [namespace, name_as_atom]) of
+ [El] ->
[El]
+ catch
+ _ ->
+ []
end
end, Rs);
_ ->
@@ -339,10 +322,12 @@ user_queue(User, Server, Query, Lang) ->
end,
FMsgs =
lists:map(
- fun({xmlelement, _Name, _Attrs, _Els} = Msg) ->
+ fun(#xmlel{} = Msg) ->
ID = jlib:encode_base64(binary_to_list(term_to_binary(Msg))),
Packet = Msg,
- FPacket = ejabberd_web_admin:pretty_print_xml(Packet),
+ FPacket = exmpp_xml:node_to_list(
+ exmpp_xml:indent_document(Packet, <<" ">>),
+ [?DEFAULT_NS], ?PREFIXED_NS),
?XE("tr",
[?XAE("td", [{"class", "valign"}], [?INPUT("checkbox", "selected", ID)]),
?XAE("td", [{"class", "valign"}], [?XC("pre", FPacket)])]
@@ -386,11 +371,12 @@ user_queue_parse_query(Username, LServer, Query) ->
{selected, ["xml", "seq"], Rs} ->
lists:flatmap(
fun({XML, Seq}) ->
- case xml_stream:parse_element(XML) of
- {error, _Reason} ->
- [];
- El ->
+ try exmpp_xml:parse_document(XML, [namespace, name_as_atom]) of
+ [El] ->
[{El, Seq}]
+ catch
+ _ ->
+ []
end
end, Rs);
_ ->
@@ -421,11 +407,11 @@ user_queue_parse_query(Username, LServer, Query) ->
end.
us_to_list({User, Server}) ->
- jlib:jid_to_string({User, Server, ""}).
+ exmpp_jid:jid_to_list(User, Server).
webadmin_user(Acc, User, Server, Lang) ->
- LUser = jlib:nodeprep(User),
- LServer = jlib:nameprep(Server),
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
QueueLen = case catch ejabberd_odbc:sql_query(
LServer,
From cb20c9b0d7049c94f08f5ddbaf5570624a0f69e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 6 Aug 2008 13:46:23 +0000
Subject: [PATCH 054/582] Update to use the new exmpp_xml:get_attribute/{3,4}
API.
SVN Revision: 1514
---
ChangeLog | 4 ++++
src/adhoc.erl | 6 +++---
src/mod_caps.erl | 8 ++++----
src/mod_configure.erl | 6 +++---
src/mod_disco.erl | 18 +++++++++---------
src/mod_roster.erl | 4 ++--
6 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0ef9fe049..792cc377f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,10 @@
src/mod_last.erl, src/mod_configure2.erl, src/mod_last_odbc.erl,
src/gen_iq_handler.erl: Convert to exmpp.
+ * src/adhoc.erl, src/mod_configure.erl, src/mod_roster.erl,
+ src/mod_disco.erl, src/mod_caps.erl: Update to use the new
+ exmpp_xml:get_attribute/{3,4} API.
+
2008-07-25 Jean-Sébastien Pédron
* src/adhoc.erl, src/mod_configure.erl, src/mod_announce.erl,
diff --git a/src/adhoc.erl b/src/adhoc.erl
index a35dc763f..b338df068 100644
--- a/src/adhoc.erl
+++ b/src/adhoc.erl
@@ -45,9 +45,9 @@ parse_request(IQ) ->
{set, ?NS_ADHOC} ->
?DEBUG("entering parse_request...", []),
Lang = exmpp_stanza:get_lang(IQ),
- Node = exmpp_xml:get_attribute(SubEl, 'node'),
- SessionID = exmpp_xml:get_attribute(SubEl, 'sessionid'),
- Action = exmpp_xml:get_attribute(SubEl, 'action'),
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
+ SessionID = exmpp_xml:get_attribute(SubEl, 'sessionid', ""),
+ Action = exmpp_xml:get_attribute(SubEl, 'action', ""),
XData = find_xdata_el(SubEl),
AllEls = SubEl#xmlel.ns,
if XData ->
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 9b3bef70b..3cb1b8530 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -69,9 +69,9 @@
read_caps(Els) ->
read_caps(Els, nothing).
read_caps([#xmlel{ns = ?NS_CAPS, name = 'c'} = El | Tail], _Result) ->
- Node = exmpp_xml:get_attribute(El, 'node'),
- Version = exmpp_xml:get_attribute(El, 'ver'),
- Exts = string:tokens(exmpp_xml:get_attribute(El, 'ext'), " "),
+ Node = exmpp_xml:get_attribute(El, 'node', ""),
+ Version = exmpp_xml:get_attribute(El, 'ver', ""),
+ Exts = string:tokens(exmpp_xml:get_attribute(El, 'ext', ""), " "),
read_caps(Tail, #caps{node = Node, version = Version, exts = Exts});
read_caps([#xmlel{ns = ?NS_MUC_USER, name = 'x'} | _Tail], _Result) ->
nothing;
@@ -226,7 +226,7 @@ handle_cast({disco_response, From, _To, IQ},
{ok, {Node, SubNode}} ->
Features =
lists:flatmap(fun(#xmlel{name = 'feature'} = F) ->
- [exmpp_xml:get_attribute(F, 'var')];
+ [exmpp_xml:get_attribute(F, 'var', "")];
(_) ->
[]
end, Els),
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index c8925277e..f62d1926a 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -315,7 +315,7 @@ adhoc_local_items(Acc, From, #jid{ldomain = LServer, domain = Server} = To,
Nodes = recursively_get_local_items(LServer, "", Server, Lang),
Nodes1 = lists:filter(
fun(N) ->
- Nd = exmpp_xml:get_attribute(N, 'node'),
+ Nd = exmpp_xml:get_attribute(N, 'node', ""),
F = get_local_features([], From, To, Nd, Lang),
case F of
{result, [?NS_ADHOC_s]} ->
@@ -346,8 +346,8 @@ recursively_get_local_items(LServer, Node, Server, Lang) ->
Nodes = lists:flatten(
lists:map(
fun(N) ->
- S = exmpp_xml:get_attribute(N, 'jid'),
- Nd = exmpp_xml:get_attribute(N, 'node'),
+ S = exmpp_xml:get_attribute(N, 'jid', ""),
+ Nd = exmpp_xml:get_attribute(N, 'node', ""),
if (S /= Server) or (Nd == "") ->
[];
true ->
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index 9700a6546..a2e9e4feb 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -132,7 +132,7 @@ process_local_iq_items(From, To, IQ) ->
exmpp_iq:error(IQ, 'not-allowed');
get ->
SubEl = exmpp_iq:get_request(IQ),
- Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
Host = To#jid.ldomain,
Lang = exmpp_stanza:get_lang(IQ),
@@ -166,7 +166,7 @@ process_local_iq_info(From, To, IQ) ->
get ->
Host = To#jid.ldomain,
SubEl = exmpp_iq:get_request(IQ),
- Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
Lang = exmpp_stanza:get_lang(IQ),
% XXX OLD FORMAT: From, To.
FromOld = jlib:to_old_jid(From),
@@ -290,7 +290,7 @@ process_sm_iq_items(From, To, IQ) ->
#jid{lnode = LTo, ldomain = ToServer} = To,
#jid{lnode = LFrom, ldomain = LServer} = From,
Self = (LTo == LFrom) andalso (ToServer == LServer),
- Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
if
Self, Node /= [] ->
%% Here, we treat disco publish attempts to your own JID.
@@ -307,7 +307,7 @@ process_sm_iq_items(From, To, IQ) ->
end;
get ->
Host = To#jid.ldomain,
- Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
Lang = exmpp_stanza:get_lang(IQ),
% XXX OLD FORMAT: From, To.
FromOld = jlib:to_old_jid(From),
@@ -366,7 +366,7 @@ process_sm_iq_info(From, To, IQ) ->
get ->
Host = To#jid.ldomain,
SubEl = exmpp_iq:get_request(IQ),
- Node = exmpp_xml:get_attribute(SubEl, 'node'),
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
Lang = exmpp_stanza:get_lang(IQ),
% XXX OLD FORMAT: From, To.
FromOld = jlib:to_old_jid(From),
@@ -441,10 +441,10 @@ process_disco_publish(User, Node, Items) ->
F = fun() ->
lists:foreach(
fun(#xmlel{} = Item) ->
- Action = exmpp_xml:get_attribute(Item, 'action'),
- Jid = exmpp_xml:get_attribute(Item, 'jid'),
- PNode = exmpp_xml:get_attribute(Item, 'node'),
- Name = exmpp_xml:get_attribute(Item, 'name'),
+ Action = exmpp_xml:get_attribute(Item, 'action', ""),
+ Jid = exmpp_xml:get_attribute(Item, 'jid', ""),
+ PNode = exmpp_xml:get_attribute(Item, 'node', ""),
+ Name = exmpp_xml:get_attribute(Item, 'name', ""),
?INFO_MSG("Disco publish: ~p ~p ~p ~p ~p ~p~n",
[User, Action, Node, Jid, PNode, Name]),
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 4e7e5ecab..9d7211cc9 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -194,7 +194,7 @@ process_iq_set(From, To, IQ) ->
process_item_set(From, To, #xmlel{} = Item) ->
try
- JID1 = exmpp_jid:string_to_jid(exmpp_xml:get_attribute(Item, 'jid')),
+ JID1 = exmpp_jid:string_to_jid(exmpp_xml:get_attribute(Item, 'jid', "")),
% XXX OLD FORMAT: old JID (with empty strings).
#jid{node = User, lnode = LUser, ldomain = LServer} =
jlib:to_old_jid(From),
@@ -587,7 +587,7 @@ set_items(User, Server, SubEl) ->
process_item_set_t(LUser, LServer, #xmlel{} = El) ->
try
- JID1 = exmpp_jid:string_to_jid(exmpp_xml:get_attribute(El, 'jid')),
+ JID1 = exmpp_jid:string_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
LJID = {JID1#jid.lnode, JID1#jid.ldomain, JID1#jid.lresource},
Item = #roster{usj = {LUser, LServer, LJID},
From 85c2097ece8016e6abb7bad3ccd89c82de3852b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 6 Aug 2008 13:51:42 +0000
Subject: [PATCH 055/582] Update to use the new names used in exmpp_jid.
SVN Revision: 1515
---
ChangeLog | 6 ++++++
src/ejabberd_c2s.erl | 16 ++++++++--------
src/ejabberd_s2s_in.erl | 8 ++++----
src/ejabberd_s2s_out.erl | 4 ++--
src/ejabberd_service.erl | 2 +-
src/mod_adhoc.erl | 2 +-
src/mod_caps.erl | 4 ++--
src/mod_configure.erl | 36 ++++++++++++++++++------------------
src/mod_disco.erl | 2 +-
src/mod_echo.erl | 2 +-
src/mod_offline.erl | 6 +++---
src/mod_roster.erl | 22 +++++++++++-----------
src/mod_vcard.erl | 4 ++--
13 files changed, 60 insertions(+), 54 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 792cc377f..8e2e1f4bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,12 @@
src/mod_disco.erl, src/mod_caps.erl: Update to use the new
exmpp_xml:get_attribute/{3,4} API.
+ * src/ejabberd_c2s.erl, src/ejabberd_s2s_in.erl,
+ src/ejabberd_s2s_out.erl, src/ejabberd_service.erl, src/mod_adhoc.erl,
+ src/mod_caps.erl, src/mod_configure.erl, src/mod_disco.erl,
+ src/mod_echo.erl, src/mod_offline.erl, src/mod_roster.erl,
+ src/mod_vcard.erl: Update to use the new names used in exmpp_jid.
+
2008-07-25 Jean-Sébastien Pédron
* src/adhoc.erl, src/mod_configure.erl, src/mod_announce.erl,
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index da1239064..d006e2a5a 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -398,7 +398,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
?INFO_MSG(
"(~w) Accepted legacy authentication for ~s",
[StateData#state.socket,
- exmpp_jid:jid_to_string(JID)]),
+ exmpp_jid:jid_to_list(JID)]),
SID = {now(), self()},
Conn = get_conn_type(StateData),
Info = [{ip, StateData#state.ip}, {conn, Conn},
@@ -435,7 +435,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
?INFO_MSG(
"(~w) Failed legacy authentication for ~s",
[StateData#state.socket,
- exmpp_jid:jid_to_string(JID)]),
+ exmpp_jid:jid_to_list(JID)]),
Res = exmpp_iq:error_without_original(El,
'not-authorized'),
send_element(StateData, Res),
@@ -445,7 +445,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
?INFO_MSG(
"(~w) Forbidden legacy authentication for ~s",
[StateData#state.socket,
- exmpp_jid:jid_to_string(JID)]),
+ exmpp_jid:jid_to_list(JID)]),
Res = exmpp_iq:error_without_original(El,
'not-allowed'),
send_element(StateData, Res),
@@ -713,7 +713,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
allow ->
?INFO_MSG("(~w) Opened session for ~s",
[StateData#state.socket,
- exmpp_jid:jid_to_string(JID)]),
+ exmpp_jid:jid_to_list(JID)]),
SID = {now(), self()},
Conn = get_conn_type(StateData),
Info = [{ip, StateData#state.ip}, {conn, Conn},
@@ -750,7 +750,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
StateData#state.server, [JIDOld]),
?INFO_MSG("(~w) Forbidden session for ~s",
[StateData#state.socket,
- exmpp_jid:jid_to_string(JID)]),
+ exmpp_jid:jid_to_list(JID)]),
Err = exmpp_server_session:error(El, 'not-allowed'),
send_element(StateData, Err),
fsm_next_state(wait_for_session, StateData)
@@ -787,7 +787,7 @@ session_established({xmlstreamelement, El}, StateData) ->
undefined ->
exmpp_jid:make_bare_jid(User, Server);
_ ->
- exmpp_jid:string_to_jid(To)
+ exmpp_jid:list_to_jid(To)
end,
NewEl = case exmpp_stanza:get_lang(El) of
undefined ->
@@ -1237,7 +1237,7 @@ terminate(_Reason, StateName, StateData) ->
replaced ->
?INFO_MSG("(~w) Replaced session for ~s",
[StateData#state.socket,
- exmpp_jid:jid_to_string(StateData#state.jid)]),
+ exmpp_jid:jid_to_list(StateData#state.jid)]),
From = StateData#state.jid,
Packet = exmpp_presence:unavailable(),
Packet1 = exmpp_presence:set_status(Packet,
@@ -1255,7 +1255,7 @@ terminate(_Reason, StateName, StateData) ->
_ ->
?INFO_MSG("(~w) Close session for ~s",
[StateData#state.socket,
- exmpp_jid:jid_to_string(StateData#state.jid)]),
+ exmpp_jid:jid_to_list(StateData#state.jid)]),
EmptySet = ?SETS:new(),
case StateData of
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index c0c863c1e..4804ff551 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -371,7 +371,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
error;
F ->
try
- exmpp_jid:string_to_jid(F)
+ exmpp_jid:list_to_jid(F)
catch
_Exception1 -> error
end
@@ -381,7 +381,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
error;
T ->
try
- exmpp_jid:string_to_jid(T)
+ exmpp_jid:list_to_jid(T)
catch
_Exception2 -> error
end
@@ -621,7 +621,7 @@ get_cert_domains(Cert) ->
end,
if
D /= error ->
- case exmpp_jid:string_to_jid(D) of
+ case exmpp_jid:list_to_jid(D) of
#jid{lnode = undefined,
ldomain = LD,
lresource = undefined} ->
@@ -674,7 +674,7 @@ get_cert_domains(Cert) ->
[]
end;
({dNSName, D}) when is_list(D) ->
- case exmpp_jid:string_to_jid(D) of
+ case exmpp_jid:list_to_jid(D) of
#jid{lnode = undefined,
ldomain = LD,
lresource = undefined} ->
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index baa5d23f5..5859b89cf 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -809,8 +809,8 @@ bounce_element(El, Condition) ->
"result" -> ok;
_ ->
Err = exmpp_stanza:reply_with_error(El, Condition),
- From = exmpp_jid:string_to_jid(exmpp_stanza:get_sender(El)),
- To = exmpp_jid:string_to_jid(exmpp_stanza:get_recipient(El)),
+ From = exmpp_jid:list_to_jid(exmpp_stanza:get_sender(El)),
+ To = exmpp_jid:list_to_jid(exmpp_stanza:get_recipient(El)),
% No namespace conversion (:server <-> :client) is done.
% This is handled by C2S and S2S send_element functions.
ejabberd_router:route(To, From, Err)
diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl
index b6a977ce6..302211f07 100644
--- a/src/ejabberd_service.erl
+++ b/src/ejabberd_service.erl
@@ -223,7 +223,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
%% when accept packets from any address.
%% In this case, the component can send packet of
%% behalf of the server users.
- false -> exmpp_jid:string_to_jid(From);
+ false -> exmpp_jid:list_to_jid(From);
%% The default is the standard behaviour in XEP-0114
_ ->
FromJID1 = exmpp_jib:string_to_jid(From),
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl
index 87f66899b..c96c3e580 100644
--- a/src/mod_adhoc.erl
+++ b/src/mod_adhoc.erl
@@ -124,7 +124,7 @@ get_sm_commands(Acc, _From, #jid{ldomain = LServer} = To, "", Lang) ->
end,
Nodes = [#xmlel{ns = ?NS_DISCO_ITEMS,
name = 'item', attrs =
- [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(To)},
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(To)},
#xmlattr{name = 'node', value = ?NS_ADHOC_s},
#xmlattr{name = 'name', value = translate:translate(Lang, "Commands")}]
}],
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 3cb1b8530..a04a27f0a 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -254,9 +254,9 @@ handle_cast({disco_response, From, _To, IQ},
?ERROR_MSG("ID '~s' matches no query", [ID])
end;
%gen_server:cast(self(), visit_feature_queries),
- %?DEBUG("Error IQ reponse from ~s:~n~p", [exmpp_jid:jid_to_string(From), SubEls]);
+ %?DEBUG("Error IQ reponse from ~s:~n~p", [exmpp_jid:jid_to_list(From), SubEls]);
{result, _} ->
- ?DEBUG("Invalid IQ contents from ~s:~n~p", [exmpp_jid:jid_to_string(From), IQ#xmlel.children]);
+ ?DEBUG("Invalid IQ contents from ~s:~n~p", [exmpp_jid:jid_to_list(From), IQ#xmlel.children]);
_ ->
%% Can't do anything about errors
ok
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index f62d1926a..c362963a6 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -98,7 +98,7 @@ stop(Host) ->
-define(NODEJID(To, Name, Node),
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
- [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(To)},
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(To)},
#xmlattr{name = 'name', value = ?T(Lang, Name)},
#xmlattr{name = 'node', value = Node}]}).
@@ -258,7 +258,7 @@ adhoc_sm_items(Acc, From, #jid{ldomain = LServer} = To, Lang) ->
empty -> []
end,
Nodes = [#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
- [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(To)},
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(To)},
#xmlattr{name = 'name', value = ?T(Lang, "Configuration")},
#xmlattr{name = 'node', value = "config"}]}],
{result, Items ++ Nodes};
@@ -297,7 +297,7 @@ get_user_resources(User, Server) ->
Rs = ejabberd_sm:get_user_resources(User, Server),
lists:map(fun(R) ->
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
- [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(User, Server, R)},
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(User, Server, R)},
#xmlattr{name = 'name', value = User}]}
end, lists:sort(Rs)).
@@ -365,7 +365,7 @@ recursively_get_local_items(LServer, Node, Server, Lang) ->
Fallback;
allow ->
case get_local_items(LServer, LNode,
- exmpp_jid:jid_to_string(To), Lang) of
+ exmpp_jid:jid_to_list(To), Lang) of
{result, Res} ->
{result, Res};
{error, Error} ->
@@ -388,7 +388,7 @@ get_local_items(Acc, From, #jid{ldomain = LServer} = To, "", Lang) ->
{result, Items};
allow ->
case get_local_items(LServer, [],
- exmpp_jid:jid_to_string(To), Lang) of
+ exmpp_jid:jid_to_list(To), Lang) of
{result, Res} ->
{result, Items ++ Res};
{error, _Error} ->
@@ -507,8 +507,8 @@ get_local_items(Host, ["all users", [$@ | Diap]], _Server, _Lang) ->
Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
lists:map(fun({S, U}) ->
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
- [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(U, S)},
- #xmlattr{name = 'name', value = exmpp_jid:jid_to_string(U, S)}]}
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(U, S)},
+ #xmlattr{name = 'name', value = exmpp_jid:jid_to_list(U, S)}]}
end, Sub)
end of
{'EXIT', _Reason} ->
@@ -591,8 +591,8 @@ get_online_vh_users(Host) ->
SURs = lists:sort([{S, U, R} || {U, S, R} <- USRs]),
lists:map(fun({S, U, R}) ->
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
- [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(U, S, R)},
- #xmlattr{name = 'name', value = exmpp_jid:jid_to_string(U, S)}]}
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(U, S, R)},
+ #xmlattr{name = 'name', value = exmpp_jid:jid_to_list(U, S)}]}
end, SURs)
end.
@@ -606,8 +606,8 @@ get_all_vh_users(Host) ->
N when N =< 100 ->
lists:map(fun({S, U}) ->
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
- [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_string(U, S)},
- #xmlattr{name = 'name', value = exmpp_jid:jid_to_string(U, S)}]}
+ [#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(U, S)},
+ #xmlattr{name = 'name', value = exmpp_jid:jid_to_list(U, S)}]}
end, SUsers);
N ->
NParts = trunc(math:sqrt(N * 0.618)) + 1,
@@ -1534,7 +1534,7 @@ set_form(_From, _Host, ?NS_ADMINL("add-user"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
Password = get_value("password", XData),
Password = get_value("password-verify", XData),
- AccountJID = exmpp_jid:string_to_jid(AccountString),
+ AccountJID = exmpp_jid:list_to_jid(AccountString),
User = AccountJID#jid.lnode,
Server = AccountJID#jid.ldomain,
true = lists:member(Server, ?MYHOSTS),
@@ -1546,7 +1546,7 @@ set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
[_|_] = AccountStringList,
ASL2 = lists:map(
fun(AccountString) ->
- JID = exmpp_jid:string_to_jid(AccountString),
+ JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
@@ -1559,7 +1559,7 @@ set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
- JID = exmpp_jid:string_to_jid(AccountString),
+ JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
LUser = JID#jid.lnode,
LServer = JID#jid.ldomain,
@@ -1578,7 +1578,7 @@ set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
- JID = exmpp_jid:string_to_jid(AccountString),
+ JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
@@ -1593,7 +1593,7 @@ set_form(_From, _Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
Password = get_value("password", XData),
- JID = exmpp_jid:string_to_jid(AccountString),
+ JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
@@ -1603,7 +1603,7 @@ set_form(_From, _Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
- JID = exmpp_jid:string_to_jid(AccountString),
+ JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
@@ -1640,7 +1640,7 @@ set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("user-stats"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
- JID = exmpp_jid:string_to_jid(AccountString),
+ JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index a2e9e4feb..517ef7a90 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -418,7 +418,7 @@ get_user_resources(User, Server) ->
lists:map(fun(R) ->
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [
#xmlattr{name = 'jid', value =
- exmpp_jid:jid_to_string(User, Server, R)},
+ exmpp_jid:jid_to_list(User, Server, R)},
#xmlattr{name = 'name', value = User}
]}
end, lists:sort(Rs)).
diff --git a/src/mod_echo.erl b/src/mod_echo.erl
index f2540081c..fc043370c 100644
--- a/src/mod_echo.erl
+++ b/src/mod_echo.erl
@@ -200,5 +200,5 @@ do_client_version(enabled, From, To) ->
%% Print in log
Values_string1 = [io_lib:format("~n~s: ~p", [N, V]) || {N, V} <- Values],
Values_string2 = lists:concat(Values_string1),
- ?INFO_MSG("Information of the client: ~s~s", [exmpp_jid:jid_to_string(To), Values_string2]).
+ ?INFO_MSG("Information of the client: ~s~s", [exmpp_jid:jid_to_list(To), Values_string2]).
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index 283d68607..3712dadbf 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -497,8 +497,8 @@ user_queue(User, Server, Query, Lang) ->
io_lib:format(
"~w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
[Year, Month, Day, Hour, Minute, Second])),
- SFrom = exmpp_jid:jid_to_string(jlib:from_old_jid(From)),
- STo = exmpp_jid:jid_to_string(jlib:from_old_jid(To)),
+ SFrom = exmpp_jid:jid_to_list(jlib:from_old_jid(From)),
+ STo = exmpp_jid:jid_to_list(jlib:from_old_jid(To)),
Packet0 = exmpp_xml:xmlelement_to_xmlel(Packet,
[?DEFAULT_NS], ?PREFIXED_NS),
Packet1 = exmpp_stanza:set_jids(Packet0, SFrom, STo),
@@ -568,7 +568,7 @@ user_queue_parse_query(US, Query) ->
end.
us_to_list({User, Server}) ->
- exmpp_jid:jid_to_string(User, Server).
+ exmpp_jid:jid_to_list(User, Server).
webadmin_user(Acc, User, Server, Lang) ->
US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 9d7211cc9..57cc60f14 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -156,7 +156,7 @@ get_user_roster(Acc, US) ->
item_to_xml(Item) ->
{U, S, R} = Item#roster.jid,
Attrs1 = exmpp_xml:set_attribute_in_list([],
- 'jid', exmpp_jid:jid_to_string(U, S, R)),
+ 'jid', exmpp_jid:jid_to_list(U, S, R)),
Attrs2 = case Item#roster.name of
"" ->
Attrs1;
@@ -194,7 +194,7 @@ process_iq_set(From, To, IQ) ->
process_item_set(From, To, #xmlel{} = Item) ->
try
- JID1 = exmpp_jid:string_to_jid(exmpp_xml:get_attribute(Item, 'jid', "")),
+ JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(Item, 'jid', "")),
% XXX OLD FORMAT: old JID (with empty strings).
#jid{node = User, lnode = LUser, ldomain = LServer} =
jlib:to_old_jid(From),
@@ -276,7 +276,7 @@ process_item_attrs(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of
'jid' ->
try
- JID1 = exmpp_jid:string_to_jid(Val),
+ JID1 = exmpp_jid:list_to_jid(Val),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
process_item_attrs(Item#roster{jid = JID}, Attrs)
catch
@@ -587,7 +587,7 @@ set_items(User, Server, SubEl) ->
process_item_set_t(LUser, LServer, #xmlel{} = El) ->
try
- JID1 = exmpp_jid:string_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
+ JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
LJID = {JID1#jid.lnode, JID1#jid.ldomain, JID1#jid.lresource},
Item = #roster{usj = {LUser, LServer, LJID},
@@ -612,7 +612,7 @@ process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of
'jid' ->
try
- JID1 = exmpp_jid:string_to_jid(Val),
+ JID1 = exmpp_jid:list_to_jid(Val),
JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
catch
@@ -664,9 +664,9 @@ get_in_pending_subscriptions(Ls, User, Server) ->
end,
{U, S, R} = R#roster.jid,
Attrs1 = exmpp_stanza:set_sender_in_list([],
- exmpp_jid:jid_to_string(U, S, R)),
+ exmpp_jid:jid_to_list(U, S, R)),
Attrs2 = exmpp_stanza:set_recipient_in_list(Attrs1,
- exmpp_jid:jid_to_string(JID)),
+ exmpp_jid:jid_to_list(JID)),
Pres1 = exmpp_presence:subscribe(),
Pres2 = Pres1#xmlel{attrs = Attrs2},
exmpp_presence:set_status(Pres2, Status)
@@ -815,7 +815,7 @@ user_roster(User, Server, Query, Lang) ->
{U, S, R} = R#roster.jid,
?XE("tr",
[?XAC("td", [{"class", "valign"}],
- catch exmpp_jid:jid_to_string(U, S, R)),
+ catch exmpp_jid:jid_to_list(U, S, R)),
?XAC("td", [{"class", "valign"}],
R#roster.name),
?XAC("td", [{"class", "valign"}],
@@ -861,7 +861,7 @@ user_roster_parse_query(User, Server, Items, Query) ->
error;
{value, {_, SJID}} ->
try
- JID = exmpp_jid:string_to_jid(SJID),
+ JID = exmpp_jid:list_to_jid(SJID),
user_roster_subscribe_jid(User, Server, JID),
ok
catch
@@ -911,7 +911,7 @@ user_roster_item_parse_query(User, Server, Items, Query) ->
{value, _} ->
UJID = exmpp_jid:make_bare_jid(User, Server),
Attrs1 = exmpp_xml:set_attribute_in_list([],
- 'jid', exmpp_jid:jid_to_string(JID)),
+ 'jid', exmpp_jid:jid_to_list(JID)),
Attrs2 = exmpp_xml:set_attribute_in_list(Attrs1,
'subscription', "remove"),
Item = #xmlel{ns = ?NS_ROSTER, name = 'item',
@@ -933,7 +933,7 @@ user_roster_item_parse_query(User, Server, Items, Query) ->
nothing.
us_to_list({User, Server}) ->
- exmpp_jid:bare_jid_to_string(User, Server).
+ exmpp_jid:bare_jid_to_list(User, Server).
webadmin_user(Acc, _User, _Server, Lang) ->
Acc ++ [?XE("h3", [?ACT("roster/", "Roster")])].
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 9f980dd70..cf0690637 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -303,7 +303,7 @@ set_vcard(User, LServer, VCARD) ->
#xmlel{ns = ?NS_DATA_FORMS, name = 'x', attrs =
[#xmlattr{name = 'type', value = "form"}], children =
[#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
- [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "Search users in ") ++ exmpp_jid:jid_to_string(JID))}]},
+ [#xmlcdata{cdata = list_to_binary(translate:translate(Lang, "Search users in ") ++ exmpp_jid:jid_to_list(JID))}]},
#xmlel{ns = ?NS_SEARCH, name = 'instructions', children =
[#xmlcdata{cdata = list_to_binary(translate:translate(Lang,
"Fill in the form to search "
@@ -459,7 +459,7 @@ search_result(Lang, JID, ServerHost, Data) ->
[#xmlel{ns = ?NS_DATA_FORMS, name = 'title', children =
[#xmlcdata{cdata = list_to_binary(
translate:translate(Lang, "Search Results for ") ++
- exmpp_jid:jid_to_string(JID))}]},
+ exmpp_jid:jid_to_list(JID))}]},
#xmlel{ns = ?NS_DATA_FORMS, name = 'reported', children =
[?TLFIELD("text-single", "Jabber ID", "jid"),
?TLFIELD("text-single", "Full Name", "fn"),
From 44d3e844a343555d415471de53116f555c97cd4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Thu, 14 Aug 2008 13:32:31 +0000
Subject: [PATCH 056/582] Accept 'undefined' as a language and treat it as the
empty string.
SVN Revision: 1522
---
ChangeLog | 5 +++++
src/translate.erl | 3 ++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index 8e2e1f4bf..900d7ce0b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2008-08-14 Jean-Sébastien Pédron
+
+ * translate.erl (ascii_tolower): Accept 'undefined' as a language and
+ treat it as the empty string.
+
2008-08-06 Jean-Sébastien Pédron
* src/mod_offline.erl, src/mod_offline_odbc.erl, src/mod_echo.erl,
diff --git a/src/translate.erl b/src/translate.erl
index bc0af1399..bc1d9e0c9 100644
--- a/src/translate.erl
+++ b/src/translate.erl
@@ -159,5 +159,6 @@ ascii_tolower([C | Cs]) when C >= $A, C =< $Z ->
ascii_tolower([C | Cs]) ->
[C | ascii_tolower(Cs)];
ascii_tolower([]) ->
+ [];
+ascii_tolower(undefined) ->
[].
-
From 5e78c535726295d655bce8fe4a78a61b9abc0900 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Thu, 14 Aug 2008 13:34:30 +0000
Subject: [PATCH 057/582] Remove the compatibility layer and always call
modules with the new #iq record from Exmpp.
SVN Revision: 1523
---
ChangeLog | 4 +++
src/ejabberd_local.erl | 36 +++++++-------------
src/ejabberd_sm.erl | 22 ++++--------
src/gen_iq_handler.erl | 76 ++++++++----------------------------------
4 files changed, 36 insertions(+), 102 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 900d7ce0b..18826707f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@
* translate.erl (ascii_tolower): Accept 'undefined' as a language and
treat it as the empty string.
+ * src/gen_iq_handler.erl, src/ejabberd_local.erl, src/ejabberd_sm.erl:
+ Remove the compatibility layer and always call modules with the new
+ #iq record from Exmpp.
+
2008-08-06 Jean-Sébastien Pédron
* src/mod_offline.erl, src/mod_offline_odbc.erl, src/mod_echo.erl,
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index f047569f9..f06b821e6 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -74,47 +74,35 @@ start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
process_iq(From, To, Packet) ->
- case exmpp_iq:get_kind(Packet) of
- request ->
+ case exmpp_iq:xmlel_to_iq(Packet) of
+ #iq{kind = request, ns = XMLNS} = IQ_Rec ->
Host = To#jid.ldomain,
- Request = exmpp_iq:get_request(Packet),
- XMLNS = exmpp_xml:get_ns_as_list(Request),
case ets:lookup(?IQTABLE, {XMLNS, Host}) of
[{_, Module, Function}] ->
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- % XXX OLD FORMAT: IQ_Rec is an #iq.
- IQ_Rec = jlib:iq_query_info(Packet),
- ResIQ = Module:Function(FromOld, ToOld, IQ_Rec),
+ ResIQ = Module:Function(From, To, IQ_Rec),
if
ResIQ /= ignore ->
- % XXX OLD FORMAT: ResIQ.
- ReplyOld = jlib:iq_to_xml(ResIQ),
- Reply = exmpp_xml:xmlelement_to_xmlel(ReplyOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
- ejabberd_router:route(
- To, From, Reply);
+ Reply = exmpp_iq:iq_to_xmlel(ResIQ, To, From),
+ ejabberd_router:route(To, From, Reply);
true ->
ok
end;
[{_, Module, Function, Opts}] ->
gen_iq_handler:handle(Host, Module, Function, Opts,
- From, To, Packet);
+ From, To, IQ_Rec);
[] ->
- Err = exmpp_iq:error(Packet, 'feature-not-implemented'),
+ Err = exmpp_iq:error(Packet, 'feature-not-implemented'),
ejabberd_router:route(To, From, Err)
end;
- response ->
- process_iq_reply(From, To, Packet);
+ #iq{kind = response} = IQ_Rec ->
+ process_iq_reply(From, To, IQ_Rec);
_ ->
- Err = exmpp_iq:error(Packet, 'bad-request'),
+ Err = exmpp_iq:error(Packet, 'bad-request'),
ejabberd_router:route(To, From, Err),
ok
end.
-process_iq_reply(From, To, Packet) ->
- ID = exmpp_stanza:get_id(Packet),
+process_iq_reply(From, To, #iq{id = ID} = IQ_Rec) ->
case catch mnesia:dirty_read(iq_response, ID) of
[] ->
ok;
@@ -131,7 +119,7 @@ process_iq_reply(From, To, Packet) ->
end,
case mnesia:transaction(F) of
{atomic, {Module, Function}} ->
- Module:Function(From, To, Packet);
+ Module:Function(From, To, IQ_Rec);
_ ->
ok
end
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 9300958d5..d9bc3c185 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -665,37 +665,27 @@ get_max_user_sessions(LUser, Host) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
process_iq(From, To, Packet) ->
- case exmpp_iq:get_kind(Packet) of
- request ->
+ case exmpp_iq:xmlel_to_iq(Packet) of
+ #iq{kind = request, ns = XMLNS} = IQ_Rec ->
Host = To#jid.ldomain,
- Request = exmpp_iq:get_request(Packet),
- XMLNS = exmpp_xml:get_ns_as_list(Request),
case ets:lookup(sm_iqtable, {XMLNS, Host}) of
[{_, Module, Function}] ->
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- % XXX OLD FORMAT: IQ_Rec is an #iq.
- IQ_Rec = jlib:iq_query_info(Packet),
- ResIQ = Module:Function(FromOld, ToOld, IQ_Rec),
+ ResIQ = Module:Function(From, To, IQ_Rec),
if
ResIQ /= ignore ->
- % XXX OLD FORMAT: ResIQ.
- ReplyOld = jlib:iq_to_xml(ResIQ),
- Reply = exmpp_xml:xmlelement_to_xmlel(ReplyOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
+ Reply = exmpp_iq:iq_to_xmlel(ResIQ, To, From),
ejabberd_router:route(To, From, Reply);
true ->
ok
end;
[{_, Module, Function, Opts}] ->
gen_iq_handler:handle(Host, Module, Function, Opts,
- From, To, Packet);
+ From, To, IQ_Rec);
[] ->
Err = exmpp_iq:error(Packet, 'service-unavailable'),
ejabberd_router:route(To, From, Err)
end;
- response ->
+ #iq{type = response} ->
ok;
_ ->
Err = exmpp_iq:error(Packet, 'bad-request'),
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index 97a24efbb..b3e3beca5 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -49,13 +49,6 @@
module,
function}).
-% XXX OLD FORMAT: Re-include jlib.hrl (after clean-up).
--record(iq, {id = "",
- type,
- xmlns = "",
- lang = "",
- sub_el}).
-
% XXX OLD FORMAT: modules not in the following list will receive
% old format strudctures.
-define(CONVERTED_MODULES, [
@@ -121,60 +114,33 @@ stop_iq_handler(_Module, _Function, Opts) ->
ok
end.
-handle(Host, Module, Function, Opts, From, To, IQ) ->
+handle(Host, Module, Function, Opts, From, To, IQ_Rec) ->
case Opts of
no_queue ->
- process_iq(Host, Module, Function, From, To, IQ);
+ process_iq(Host, Module, Function, From, To, IQ_Rec);
{one_queue, Pid} ->
- Pid ! {process_iq, From, To, IQ};
+ Pid ! {process_iq, From, To, IQ_Rec};
{queues, Pids} ->
Pid = lists:nth(erlang:phash(now(), length(Pids)), Pids),
- Pid ! {process_iq, From, To, IQ};
+ Pid ! {process_iq, From, To, IQ_Rec};
parallel ->
spawn(?MODULE, process_iq,
- [Host, Module, Function, From, To, IQ]);
+ [Host, Module, Function, From, To, IQ_Rec]);
_ ->
todo
end.
-process_iq(Host, Module, Function, FromOld, ToOld, IQ_Rec)
- when is_record(IQ_Rec, iq) ->
- catch throw(for_stacktrace), % To have a stacktrace.
- io:format("~nIQ HANDLER: old #iq for ~s:~s:~n~p~n~p~n~n",
- [Module, Function, IQ_Rec, erlang:get_stacktrace()]),
- From = jlib:from_old_jid(FromOld),
- To = jlib:from_old_jid(ToOld),
- IQOld = jlib:iq_to_xml(IQ_Rec),
- IQOld1 = IQOld#xmlelement{children = [IQOld#xmlelement.children]},
- IQ = exmpp_xml:xmlelement_to_xmlel(IQOld1,
- [?NS_JABBER_CLIENT],
- [{?NS_XMPP, ?NS_XMPP_pfx},
- {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
- process_iq(Host, Module, Function, From, To, IQ);
-process_iq(_Host, Module, Function, From, To, IQ) ->
- Ret = case lists:member(Module, ?CONVERTED_MODULES) of
- true ->
- catch Module:Function(From, To, IQ);
- false ->
- {FromOld, ToOld, IQ_Rec} = convert_to_old_structs(
- Module, Function, From, To, IQ),
- catch Module:Function(FromOld, ToOld, IQ_Rec)
- end,
- case Ret of
- {'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
+process_iq(_Host, Module, Function, From, To, IQ_Rec) ->
+ try Module:Function(From, To, IQ_Rec) of
ignore ->
ok;
- ResIQ when is_record(ResIQ, iq) ->
- ReplyOld = jlib:iq_to_xml(ResIQ),
- Reply = exmpp_xml:xmlelement_to_xmlel(ReplyOld,
- [?NS_JABBER_CLIENT],
- [{?NS_XMPP, ?NS_XMPP_pfx},
- {?NS_DIALBACK, ?NS_DIALBACK_pfx}]),
- ejabberd_router:route(To, From, Reply);
- Reply ->
+ ResIQ ->
+ Reply = exmpp_iq:iq_to_xmlel(ResIQ, To, From),
ejabberd_router:route(To, From, Reply)
+ catch
+ _Class:Reason ->
+ ?ERROR_MSG("~p~n~p~n", [Reason, erlang:get_stacktrace()])
end.
%%====================================================================
@@ -221,11 +187,11 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
-handle_info({process_iq, From, To, IQ},
+handle_info({process_iq, From, To, IQ_Rec},
#state{host = Host,
module = Module,
function = Function} = State) ->
- process_iq(Host, Module, Function, From, To, IQ),
+ process_iq(Host, Module, Function, From, To, IQ_Rec),
{noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
@@ -250,17 +216,3 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-
-convert_to_old_structs(Mod, Fun, From, To, IQ) ->
- catch throw(for_stacktrace), % To have a stacktrace.
- io:format("~nIQ HANDLER: ~s:~s expects old #iq:~n~p~n~p~n~n",
- [Mod, Fun, IQ, erlang:get_stacktrace()]),
- if
- is_record(IQ, iq) ->
- {From, To, IQ};
- true ->
- F = jlib:to_old_jid(From),
- T = jlib:to_old_jid(To),
- I_Rec = jlib:iq_query_info(IQ),
- {F, T, I_Rec}
- end.
From d8c3aae412d3dd99c8895a0aeae215d888702def Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Thu, 14 Aug 2008 13:36:11 +0000
Subject: [PATCH 058/582] Convert to the new #iq record from Exmpp.
SVN Revision: 1524
---
ChangeLog | 5 +
src/adhoc.erl | 8 +-
src/mod_adhoc.erl | 30 ++---
src/mod_configure.erl | 4 +-
src/mod_configure2.erl | 18 +--
src/mod_disco.erl | 294 ++++++++++++++++++++---------------------
src/mod_last.erl | 96 +++++++-------
src/mod_roster.erl | 38 +++---
src/mod_vcard.erl | 112 +++++++---------
9 files changed, 286 insertions(+), 319 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 18826707f..d45411378 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,11 @@
Remove the compatibility layer and always call modules with the new
#iq record from Exmpp.
+ * src/mod_roster.erl, src/mod_vcard.erl, src/adhoc.erl,
+ src/mod_adhoc.erl, src/mod_configure.erl, src/mod_configure2.erl,
+ src/mod_disco.erl, src/mod_last.erl: Convert to the new #iq record
+ from Exmpp.
+
2008-08-06 Jean-Sébastien Pédron
* src/mod_offline.erl, src/mod_offline_odbc.erl, src/mod_echo.erl,
diff --git a/src/adhoc.erl b/src/adhoc.erl
index b338df068..0382062b0 100644
--- a/src/adhoc.erl
+++ b/src/adhoc.erl
@@ -38,18 +38,16 @@
%% Parse an ad-hoc request. Return either an adhoc_request record or
%% an {error, ErrorType} tuple.
-parse_request(IQ) ->
+parse_request(#iq{type = Type, ns = NS, payload = SubEl, lang = Lang}) ->
try
- SubEl = exmpp_iq:get_request(IQ),
- case {exmpp_iq:get_type(IQ), SubEl#xmlel.ns} of
+ case {Type, NS} of
{set, ?NS_ADHOC} ->
?DEBUG("entering parse_request...", []),
- Lang = exmpp_stanza:get_lang(IQ),
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
SessionID = exmpp_xml:get_attribute(SubEl, 'sessionid', ""),
Action = exmpp_xml:get_attribute(SubEl, 'action', ""),
XData = find_xdata_el(SubEl),
- AllEls = SubEl#xmlel.ns,
+ AllEls = exmpp_xml:get_child_elements(SubEl),
if XData ->
Others = lists:delete(XData, AllEls);
true ->
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl
index c96c3e580..ad255f827 100644
--- a/src/mod_adhoc.erl
+++ b/src/mod_adhoc.erl
@@ -50,9 +50,9 @@
start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ADHOC_s,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ADHOC,
?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ADHOC_s,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ADHOC,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
@@ -74,8 +74,8 @@ stop(Host) ->
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 99),
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC_s),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC_s).
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC),
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC).
%-------------------------------------------------------------------------
@@ -208,19 +208,19 @@ get_sm_features(Acc, _From, _To, _Node, _Lang) ->
%-------------------------------------------------------------------------
-process_local_iq(From, To, IQ) ->
- process_adhoc_request(From, To, IQ, adhoc_local_commands).
+process_local_iq(From, To, IQ_Rec) ->
+ process_adhoc_request(From, To, IQ_Rec, adhoc_local_commands).
-process_sm_iq(From, To, IQ) ->
- process_adhoc_request(From, To, IQ, adhoc_sm_commands).
+process_sm_iq(From, To, IQ_Rec) ->
+ process_adhoc_request(From, To, IQ_Rec, adhoc_sm_commands).
-process_adhoc_request(From, To, IQ, Hook) ->
- ?DEBUG("About to parse ~p...", [IQ]),
- case adhoc:parse_request(IQ) of
+process_adhoc_request(From, To, IQ_Rec, Hook) ->
+ ?DEBUG("About to parse ~p...", [IQ_Rec]),
+ case adhoc:parse_request(IQ_Rec) of
{error, Error} ->
- exmpp_iq:error(IQ, Error);
+ exmpp_iq:error(IQ_Rec, Error);
#adhoc_request{} = AdhocRequest ->
Host = To#jid.ldomain,
% XXX OLD FORMAT: From, To.
@@ -231,11 +231,11 @@ process_adhoc_request(From, To, IQ, Hook) ->
ignore ->
ignore;
empty ->
- exmpp_iq:error(IQ, 'item-not-found');
+ exmpp_iq:error(IQ_Rec, 'item-not-found');
{error, Error} ->
- exmpp_iq:error(IQ, Error);
+ exmpp_iq:error(IQ_Rec, Error);
Command ->
- exmpp_iq:result(IQ, Command)
+ exmpp_iq:result(IQ_Rec, Command)
end
end.
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index c362963a6..f960eb08e 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -82,8 +82,8 @@ stop(Host) ->
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 50),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_items, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC_s),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC_s).
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC).
%%%-----------------------------------------------------------------------
diff --git a/src/mod_configure2.erl b/src/mod_configure2.erl
index 2b6874112..9acec3fc1 100644
--- a/src/mod_configure2.erl
+++ b/src/mod_configure2.erl
@@ -47,22 +47,22 @@
start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE_s,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE,
?MODULE, process_local_iq, IQDisc),
ok.
stop(Host) ->
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE_s).
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ECONFIGURE).
-process_local_iq(From, To, IQ) ->
+process_local_iq(From, To, #iq{type = Type, payload = Request} = IQ_Rec) ->
case acl:match_rule(To#jid.ldomain, configure, From) of
deny ->
- exmpp_iq:error(IQ, 'not-allowed');
+ exmpp_iq:error(IQ_Rec, 'not-allowed');
allow ->
- case exmpp_iq:get_type(IQ) of
+ case Type of
set ->
- exmpp_iq:error(IQ, 'feature-not-implemented');
+ exmpp_iq:error(IQ_Rec, 'feature-not-implemented');
%%case xml:get_tag_attr_s("type", SubEl) of
%% "cancel" ->
%% IQ#iq{type = result,
@@ -96,11 +96,11 @@ process_local_iq(From, To, IQ) ->
%% sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
%%end;
get ->
- case process_get(IQ#xmlel.children) of
+ case process_get(Request) of
{result, Res} ->
- exmpp_iq:result(IQ, Res);
+ exmpp_iq:result(IQ_Rec, Res);
{error, Error} ->
- exmpp_iq:error(IQ, Error)
+ exmpp_iq:error(IQ_Rec, Error)
end
end
end.
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index 517ef7a90..6907a4176 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -63,13 +63,13 @@ start(Host, Opts) ->
ejabberd_local:refresh_iq_handlers(),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, atom_to_list(?NS_DISCO_ITEMS),
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
?MODULE, process_local_iq_items, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, atom_to_list(?NS_DISCO_INFO),
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
?MODULE, process_local_iq_info, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_DISCO_ITEMS),
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS,
?MODULE, process_sm_iq_items, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_DISCO_INFO),
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO,
?MODULE, process_sm_iq_info, IQDisc),
catch ets:new(disco_features, [named_table, ordered_set, public]),
@@ -101,10 +101,10 @@ stop(Host) ->
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 100),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_services, 100),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, atom_to_list(?NS_DISCO_ITEMS)),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, atom_to_list(?NS_DISCO_INFO)),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_DISCO_ITEMS)),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_DISCO_INFO)),
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_INFO),
catch ets:match_delete(disco_features, {{'_', Host}}),
catch ets:match_delete(disco_extra_domains, {{'_', Host}}),
ok.
@@ -126,75 +126,67 @@ unregister_extra_domain(Host, Domain) ->
catch ets:new(disco_extra_domains, [named_table, ordered_set, public]),
ets:delete(disco_extra_domains, {Domain, Host}).
-process_local_iq_items(From, To, IQ) ->
- case exmpp_iq:get_type(IQ) of
- set ->
- exmpp_iq:error(IQ, 'not-allowed');
- get ->
- SubEl = exmpp_iq:get_request(IQ),
- Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
- Host = To#jid.ldomain,
- Lang = exmpp_stanza:get_lang(IQ),
+process_local_iq_items(From, To, #iq{type = get, payload = SubEl,
+ lang = Lang} = IQ_Rec) ->
+ Host = To#jid.ldomain,
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- case ejabberd_hooks:run_fold(disco_local_items,
- Host,
- empty,
- [FromOld, ToOld, Node, Lang]) of
- {result, Items} ->
- % XXX OLD FORMAT: Items might be an #xmlelement.
- ANode = case Node of
- "" -> [];
- _ -> [#xmlattr{name = 'node', value = Node}]
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ case ejabberd_hooks:run_fold(disco_local_items,
+ Host,
+ empty,
+ [FromOld, ToOld, Node, Lang]) of
+ {result, Items} ->
+ % XXX OLD FORMAT: Items might be an #xmlelement.
+ ANode = case Node of
+ "" -> [];
+ _ -> [#xmlattr{name = 'node', value = Node}]
+ end,
+ Result = #xmlel{ns = ?NS_DISCO_ITEMS, name = 'query',
+ attrs = ANode, children = Items},
+ exmpp_iq:result(IQ_Rec, Result);
+ {error, Error} ->
+ % XXX OLD FORMAT: Error.
+ exmpp_iq:error(IQ_Rec, Error)
+ end;
+process_local_iq_items(_From, _To, #iq{type = set} = IQ_Rec) ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed').
+
+
+process_local_iq_info(From, To, #iq{type = get, payload = SubEl,
+ lang = Lang} = IQ_Rec) ->
+ Host = To#jid.ldomain,
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ % XXX OLD FORMAT: Identity might be an #xmlelement.
+ Identity = ejabberd_hooks:run_fold(disco_local_identity,
+ Host,
+ [],
+ [FromOld, ToOld, Node, Lang]),
+ % XXX OLD FORMAT: From, To.
+ case ejabberd_hooks:run_fold(disco_local_features,
+ Host,
+ empty,
+ [FromOld, ToOld, Node, Lang]) of
+ {result, Features} ->
+ ANode = case Node of
+ "" -> [];
+ _ -> [#xmlattr{name = 'node', value = Node}]
end,
- Result = #xmlel{ns = ?NS_DISCO_ITEMS, name = 'query',
- attrs = ANode, children = Items},
- exmpp_iq:result(IQ, Result);
- {error, Error} ->
- % XXX OLD FORMAT: Error.
- exmpp_iq:error(IQ, Error)
- end
- end.
-
-
-process_local_iq_info(From, To, IQ) ->
- case exmpp_iq:get_type(IQ) of
- set ->
- exmpp_iq:error(IQ, 'not-allowed');
- get ->
- Host = To#jid.ldomain,
- SubEl = exmpp_iq:get_request(IQ),
- Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
- Lang = exmpp_stanza:get_lang(IQ),
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- % XXX OLD FORMAT: Identity might be an #xmlelement.
- Identity = ejabberd_hooks:run_fold(disco_local_identity,
- Host,
- [],
- [FromOld, ToOld, Node, Lang]),
- % XXX OLD FORMAT: From, To.
- case ejabberd_hooks:run_fold(disco_local_features,
- Host,
- empty,
- [FromOld, ToOld, Node, Lang]) of
- {result, Features} ->
- ANode = case Node of
- "" -> [];
- _ -> [#xmlattr{name = 'node', value = Node}]
- end,
- Result = #xmlel{ns = ?NS_DISCO_INFO, name = 'query',
- attrs = ANode,
- children = Identity ++ lists:map(fun feature_to_xml/1,
- Features)},
- exmpp_iq:result(IQ, Result);
- {error, Error} ->
- exmpp_iq:error(IQ, Error)
- end
- end.
+ Result = #xmlel{ns = ?NS_DISCO_INFO, name = 'query',
+ attrs = ANode,
+ children = Identity ++ lists:map(fun feature_to_xml/1,
+ Features)},
+ exmpp_iq:result(IQ_Rec, Result);
+ {error, Error} ->
+ exmpp_iq:error(IQ_Rec, Error)
+ end;
+process_local_iq_info(_From, _To, #iq{type = set} = IQ_Rec) ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed').
get_local_identity(Acc, _From, _To, [], _Lang) ->
Acc ++ [#xmlel{ns = ?NS_DISCO_INFO, name = 'identity', attrs = [
@@ -232,6 +224,10 @@ feature_to_xml({{Feature, _Host}}) ->
feature_to_xml(Feature) when is_list(Feature) ->
#xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [
#xmlattr{name = 'var', value = Feature}
+ ]};
+feature_to_xml(Feature) when is_atom(Feature) ->
+ #xmlel{ns = ?NS_DISCO_INFO, name = 'feature', attrs = [
+ #xmlattr{name = 'var', value = atom_to_list(Feature)}
]}.
domain_to_xml({Domain}) ->
@@ -283,50 +279,46 @@ get_vh_services(Host) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-process_sm_iq_items(From, To, IQ) ->
- SubEl = exmpp_iq:get_request(IQ),
- case exmpp_iq:get_type(IQ) of
- set ->
- #jid{lnode = LTo, ldomain = ToServer} = To,
- #jid{lnode = LFrom, ldomain = LServer} = From,
- Self = (LTo == LFrom) andalso (ToServer == LServer),
- Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
- if
- Self, Node /= [] ->
- %% Here, we treat disco publish attempts to your own JID.
- Items = SubEl#xmlel.children,
- case process_disco_publish({LFrom, LServer}, Node, Items) of
- ok ->
- exmpp_iq:result(IQ);
- {error, Err} ->
- exmpp_iq:error(IQ, Err)
- end;
-
- true ->
- exmpp_iq:error(IQ, 'not-allowed')
+process_sm_iq_items(From, To, #iq{type = get, payload = SubEl,
+ lang = Lang} = IQ_Rec) ->
+ Host = To#jid.ldomain,
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ case ejabberd_hooks:run_fold(disco_sm_items,
+ Host,
+ empty,
+ [FromOld, ToOld, Node, Lang]) of
+ {result, Items} ->
+ ANode = case Node of
+ "" -> [];
+ _ -> [#xmlattr{name = 'node', value = Node}]
+ end,
+ Result = #xmlel{ns = ?NS_DISCO_ITEMS, name = 'query',
+ attrs = ANode, children = Items},
+ exmpp_iq:result(IQ_Rec, Result);
+ {error, Error} ->
+ exmpp_iq:error(IQ_Rec, Error)
+ end;
+process_sm_iq_items(From, To, #iq{type = set, payload = SubEl} = IQ_Rec) ->
+ #jid{lnode = LTo, ldomain = ToServer} = To,
+ #jid{lnode = LFrom, ldomain = LServer} = From,
+ Self = (LTo == LFrom) andalso (ToServer == LServer),
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
+ if
+ Self, Node /= [] ->
+ %% Here, we treat disco publish attempts to your own JID.
+ Items = SubEl#xmlel.children,
+ case process_disco_publish({LFrom, LServer}, Node, Items) of
+ ok ->
+ exmpp_iq:result(IQ_Rec);
+ {error, Err} ->
+ exmpp_iq:error(IQ_Rec, Err)
end;
- get ->
- Host = To#jid.ldomain,
- Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
- Lang = exmpp_stanza:get_lang(IQ),
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- case ejabberd_hooks:run_fold(disco_sm_items,
- Host,
- empty,
- [FromOld, ToOld, Node, Lang]) of
- {result, Items} ->
- ANode = case Node of
- "" -> [];
- _ -> [#xmlattr{name = 'node', value = Node}]
- end,
- Result = #xmlel{ns = ?NS_DISCO_ITEMS, name = 'query',
- attrs = ANode, children = Items},
- exmpp_iq:result(IQ, Result);
- {error, Error} ->
- exmpp_iq:error(IQ, Error)
- end
+
+ true ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed')
end.
get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
@@ -359,41 +351,37 @@ get_sm_items(empty, From, To, _Node, _Lang) ->
{error, 'not-allowed'}
end.
-process_sm_iq_info(From, To, IQ) ->
- case exmpp_iq:get_type(IQ) of
- set ->
- exmpp_iq:error(IQ, 'not-allowed');
- get ->
- Host = To#jid.ldomain,
- SubEl = exmpp_iq:get_request(IQ),
- Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
- Lang = exmpp_stanza:get_lang(IQ),
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- % XXX OLD FORMAT: Identity might be an #xmlelement.
- Identity = ejabberd_hooks:run_fold(disco_sm_identity,
- Host,
- [],
- [FromOld, ToOld, Node, Lang]),
- case ejabberd_hooks:run_fold(disco_sm_features,
- Host,
- empty,
- [FromOld, ToOld, Node, Lang]) of
- {result, Features} ->
- ANode = case Node of
- "" -> [];
- _ -> [#xmlattr{name = 'node', value = Node}]
- end,
- Result = #xmlel{ns = ?NS_DISCO_INFO, name = 'query',
- attrs = ANode,
- children = Identity ++ lists:map(fun feature_to_xml/1,
- Features)},
- exmpp_iq:result(IQ, Result);
- {error, Error} ->
- exmpp_iq:error(IQ, Error)
- end
- end.
+process_sm_iq_info(From, To, #iq{type = get, payload = SubEl,
+ lang = Lang} = IQ_Rec) ->
+ Host = To#jid.ldomain,
+ Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
+ % XXX OLD FORMAT: From, To.
+ FromOld = jlib:to_old_jid(From),
+ ToOld = jlib:to_old_jid(To),
+ % XXX OLD FORMAT: Identity might be an #xmlelement.
+ Identity = ejabberd_hooks:run_fold(disco_sm_identity,
+ Host,
+ [],
+ [FromOld, ToOld, Node, Lang]),
+ case ejabberd_hooks:run_fold(disco_sm_features,
+ Host,
+ empty,
+ [FromOld, ToOld, Node, Lang]) of
+ {result, Features} ->
+ ANode = case Node of
+ "" -> [];
+ _ -> [#xmlattr{name = 'node', value = Node}]
+ end,
+ Result = #xmlel{ns = ?NS_DISCO_INFO, name = 'query',
+ attrs = ANode,
+ children = Identity ++ lists:map(fun feature_to_xml/1,
+ Features)},
+ exmpp_iq:result(IQ_Rec, Result);
+ {error, Error} ->
+ exmpp_iq:error(IQ_Rec, Error)
+ end;
+process_sm_iq_info(_From, _To, #iq{type = set} = IQ_Rec) ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed').
get_sm_identity(Acc, _From, _To, _Node, _Lang) ->
Acc.
diff --git a/src/mod_last.erl b/src/mod_last.erl
index dee915f86..b35ea1150 100644
--- a/src/mod_last.erl
+++ b/src/mod_last.erl
@@ -52,9 +52,9 @@ start(Host, Opts) ->
[{disc_copies, [node()]},
{attributes, record_info(fields, last_activity)}]),
update_table(),
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY_s,
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY,
?MODULE, process_local_iq, IQDisc),
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY_s,
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(remove_user, Host,
?MODULE, remove_user, 50),
@@ -66,62 +66,56 @@ stop(Host) ->
?MODULE, remove_user, 50),
ejabberd_hooks:delete(unset_presence_hook, Host,
?MODULE, on_presence_update, 50),
- gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY_s),
- gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY_s).
+ gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY),
+ gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY).
-process_local_iq(_From, _To, IQ) ->
- case exmpp_iq:get_type(IQ) of
- set ->
- exmpp_iq:error(IQ, 'not-allowed');
- get ->
- Sec = trunc(element(1, erlang:statistics(wall_clock))/1000),
- Response = #xmlel{ns = ?NS_LAST_ACTIVITY, name = 'query', attrs =
- [#xmlattr{name = 'seconds', value = integer_to_list(Sec)}]},
- exmpp_iq:result(IQ, Response)
- end.
+process_local_iq(_From, _To, #iq{type = get} = IQ_Rec) ->
+ Sec = trunc(element(1, erlang:statistics(wall_clock))/1000),
+ Response = #xmlel{ns = ?NS_LAST_ACTIVITY, name = 'query', attrs =
+ [#xmlattr{name = 'seconds', value = integer_to_list(Sec)}]},
+ exmpp_iq:result(IQ_Rec, Response);
+process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed').
-process_sm_iq(From, To, IQ) ->
- case exmpp_iq:get_type(IQ) of
- set ->
- exmpp_iq:error(IQ, 'not-allowed');
- get ->
- User = To#jid.lnode,
- Server = To#jid.ldomain,
- {Subscription, _Groups} =
- ejabberd_hooks:run_fold(
- roster_get_jid_info, Server,
- {none, []}, [User, Server, From]),
- if
- (Subscription == both) or (Subscription == from) ->
- UserListRecord = ejabberd_hooks:run_fold(
- privacy_get_user_list, Server,
- #userlist{},
- [User, Server]),
- case ejabberd_hooks:run_fold(
- privacy_check_packet, Server,
- allow,
- [User, Server, UserListRecord,
- {From, To,
- exmpp_presence:available()},
- out]) of
- allow ->
- get_last(IQ, User, Server);
- deny ->
- exmpp_iq:error(IQ, 'not-allowed')
- end;
- true ->
- exmpp_iq:error(IQ, 'not-allowed')
- end
- end.
+process_sm_iq(From, To, #iq{type = get} = IQ_Rec) ->
+ User = To#jid.lnode,
+ Server = To#jid.ldomain,
+ {Subscription, _Groups} =
+ ejabberd_hooks:run_fold(
+ roster_get_jid_info, Server,
+ {none, []}, [User, Server, From]),
+ if
+ (Subscription == both) or (Subscription == from) ->
+ UserListRecord = ejabberd_hooks:run_fold(
+ privacy_get_user_list, Server,
+ #userlist{},
+ [User, Server]),
+ case ejabberd_hooks:run_fold(
+ privacy_check_packet, Server,
+ allow,
+ [User, Server, UserListRecord,
+ {From, To,
+ exmpp_presence:available()},
+ out]) of
+ allow ->
+ get_last(IQ_Rec, User, Server);
+ deny ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed')
+ end;
+ true ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed')
+ end;
+process_sm_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed').
%% TODO: This function could use get_last_info/2
-get_last(IQ, LUser, LServer) ->
+get_last(IQ_Rec, LUser, LServer) ->
case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of
{'EXIT', _Reason} ->
- exmpp_iq:error(IQ, 'internal-server-error');
+ exmpp_iq:error(IQ_Rec, 'internal-server-error');
[] ->
- exmpp_iq:error(IQ, 'service-unavailable');
+ exmpp_iq:error(IQ_Rec, 'service-unavailable');
[#last_activity{timestamp = TimeStamp, status = Status}] ->
{MegaSecs, Secs, _MicroSecs} = now(),
TimeStamp2 = MegaSecs * 1000000 + Secs,
@@ -129,7 +123,7 @@ get_last(IQ, LUser, LServer) ->
Response = #xmlel{ns = ?NS_LAST_ACTIVITY, name = 'query',
attrs = [#xmlattr{name = 'seconds', value = integer_to_list(Sec)}],
children = [#xmlcdata{cdata = list_to_binary(Status)}]},
- exmpp_iq:result(IQ, Response)
+ exmpp_iq:result(IQ_Rec, Response)
end.
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index 57cc60f14..e67eb58c6 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -78,8 +78,7 @@ start(Host, Opts) ->
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(webadmin_user, Host,
?MODULE, webadmin_user, 50),
- % XXX OLD FORMAT: NS as string.
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_ROSTER),
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
?MODULE, process_iq, IQDisc).
stop(Host) ->
@@ -103,41 +102,38 @@ stop(Host) ->
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(webadmin_user, Host,
?MODULE, webadmin_user, 50),
- % XXX OLD FORMAT: NS as string.
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
- atom_to_list(?NS_ROSTER)).
+ ?NS_ROSTER).
-process_iq(From, To, IQ) ->
+process_iq(From, To, IQ_Rec) ->
#jid{ldomain = LServer} = From,
case lists:member(LServer, ?MYHOSTS) of
true ->
- process_local_iq(From, To, IQ);
+ process_local_iq(From, To, IQ_Rec);
_ ->
- exmpp_iq:error(IQ, 'item-not-found')
+ exmpp_iq:error(IQ_Rec, 'item-not-found')
end.
-process_local_iq(From, To, IQ) ->
- case exmpp_iq:get_type(IQ) of
- set ->
- process_iq_set(From, To, IQ);
- get ->
- process_iq_get(From, To, IQ)
- end.
+process_local_iq(From, To, #iq{type = get} = IQ_Rec) ->
+ process_iq_get(From, To, IQ_Rec);
+process_local_iq(From, To, #iq{type = set} = IQ_Rec) ->
+ process_iq_set(From, To, IQ_Rec).
-process_iq_get(From, To, IQ) ->
+process_iq_get(From, To, IQ_Rec) ->
LUser = From#jid.lnode,
LServer = From#jid.ldomain,
US = {LUser, LServer},
case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
Items when is_list(Items) ->
XItems = lists:map(fun item_to_xml/1, Items),
- exmpp_iq:result(IQ, #xmlel{ns = ?NS_ROSTER, name = 'query',
- children = XItems});
+ Result = #xmlel{ns = ?NS_ROSTER, name = 'query',
+ children = XItems},
+ exmpp_iq:result(IQ_Rec, Result);
_ ->
- exmpp_iq:error(IQ, 'internal-server-error')
+ exmpp_iq:error(IQ_Rec, 'internal-server-error')
end.
get_user_roster(Acc, US) ->
@@ -183,14 +179,14 @@ item_to_xml(Item) ->
#xmlel{ns = ?NS_ROSTER, name = 'item', attrs = Attrs4, children = SubEls}.
-process_iq_set(From, To, IQ) ->
- case exmpp_iq:get_request(IQ) of
+process_iq_set(From, To, #iq{payload = Request} = IQ_Rec) ->
+ case Request of
#xmlel{children = Els} ->
lists:foreach(fun(El) -> process_item_set(From, To, El) end, Els);
_ ->
ok
end,
- exmpp_iq:result(IQ).
+ exmpp_iq:result(IQ_Rec).
process_item_set(From, To, #xmlel{} = Item) ->
try
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index cf0690637..0447d5920 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -84,11 +84,9 @@ start(Host, Opts) ->
ejabberd_hooks:add(remove_user, Host,
?MODULE, remove_user, 50),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
- % XXX OLD FORMAT: NS as string.
- gen_iq_handler:add_iq_handler(ejabberd_local, Host, atom_to_list(?NS_VCARD),
+ gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
?MODULE, process_local_iq, IQDisc),
- % XXX OLD FORMAT: NS as string.
- gen_iq_handler:add_iq_handler(ejabberd_sm, Host, atom_to_list(?NS_VCARD),
+ gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"),
@@ -126,12 +124,10 @@ loop(Host, ServerHost) ->
stop(Host) ->
ejabberd_hooks:delete(remove_user, Host,
?MODULE, remove_user, 50),
- % XXX OLD FORMAT: NS as string.
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
- atom_to_list(?NS_VCARD)),
- % XXX OLD FORMAT: NS as string.
+ ?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
- atom_to_list(?NS_VCARD)),
+ ?NS_VCARD),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
Proc ! stop,
@@ -155,63 +151,53 @@ get_sm_features(Acc, _From, _To, Node, _Lang) ->
Acc
end.
-process_local_iq(_From, _To, IQ) ->
- case exmpp_iq:get_type(IQ) of
- set ->
- exmpp_iq:error(IQ, 'not-allowed');
- get ->
- Lang = case exmpp_stanza:get_lang(IQ) of
- undefined -> "";
- L -> L
- end,
- Result = #xmlel{ns = ?NS_VCARD, name = 'vCard', children = [
- exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'FN'},
- "ejabberd"),
- exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'URL'},
- ?EJABBERD_URI),
- exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'DESC'},
- translate:translate(Lang, "Erlang Jabber Server") ++
- "\nCopyright (c) 2002-2008 ProcessOne"),
- exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'BDAY'},
- "2002-11-16")
- ]},
- exmpp_iq:result(IQ, Result)
- end.
+process_local_iq(_From, _To, #iq{type = get, lang = Lang} = IQ_Rec) ->
+ Result = #xmlel{ns = ?NS_VCARD, name = 'vCard', children = [
+ exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'FN'},
+ "ejabberd"),
+ exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'URL'},
+ ?EJABBERD_URI),
+ exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'DESC'},
+ translate:translate(Lang, "Erlang Jabber Server") ++
+ "\nCopyright (c) 2002-2008 ProcessOne"),
+ exmpp_xml:set_cdata(#xmlel{ns = ?NS_VCARD, name = 'BDAY'},
+ "2002-11-16")
+ ]},
+ exmpp_iq:result(IQ_Rec, Result);
+process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed').
-process_sm_iq(From, To, IQ) ->
- case exmpp_iq:get_type(IQ) of
- set ->
- #jid{node = User, ldomain = LServer} = From,
- case lists:member(LServer, ?MYHOSTS) of
- true ->
- set_vcard(User, LServer, exmpp_iq:get_request(IQ)),
- exmpp_iq:result(IQ);
- false ->
- exmpp_iq:error(IQ, 'not-allowed')
- end;
- get ->
- #jid{lnode = LUser, ldomain = LServer} = To,
- US = {LUser, LServer},
- F = fun() ->
- mnesia:read({vcard, US})
- end,
- Els = case mnesia:transaction(F) of
- {atomic, Rs} ->
- lists:map(fun(R) ->
- case R#vcard.vcard of
- #xmlel{} = E ->
- E;
- #xmlelement{} = E ->
- % XXX OLD FORMAT: Base contains old elements.
- io:format("VCARD: Old element in base: ~p~n", [E]),
- exmpp_xml:xmlelement_to_xmlel(E, [?NS_VCARD], [])
- end
- end, Rs);
- {aborted, _Reason} ->
- []
- end,
- exmpp_iq:result(IQ, Els)
+process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
+ #jid{lnode = LUser, ldomain = LServer} = To,
+ US = {LUser, LServer},
+ F = fun() ->
+ mnesia:read({vcard, US})
+ end,
+ [VCard | _] = case mnesia:transaction(F) of
+ {atomic, Rs} ->
+ lists:map(fun(R) ->
+ case R#vcard.vcard of
+ #xmlel{} = E ->
+ E;
+ #xmlelement{} = E ->
+ % XXX OLD FORMAT: Base contains old elements.
+ io:format("VCARD: Old element in base: ~p~n", [E]),
+ exmpp_xml:xmlelement_to_xmlel(E, [?NS_VCARD], [])
+ end
+ end, Rs);
+ {aborted, _Reason} ->
+ []
+ end,
+ exmpp_iq:result(IQ_Rec, VCard);
+process_sm_iq(From, _To, #iq{type = set, payload = Request} = IQ_Rec) ->
+ #jid{node = User, ldomain = LServer} = From,
+ case lists:member(LServer, ?MYHOSTS) of
+ true ->
+ set_vcard(User, LServer, Request),
+ exmpp_iq:result(IQ_Rec);
+ false ->
+ exmpp_iq:error(IQ_Rec, 'not-allowed')
end.
set_vcard(User, LServer, VCARD) ->
From ab75683bc9265990678b149c6d5599fd2129ecec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 26 Aug 2008 12:56:45 +0000
Subject: [PATCH 059/582] short_jid/1 and short_bare_jid/1 now produce a short
JID from the user-provided JID parts. To obtain a short JID from the
STRINGPREP'd parts, use the new short_prepd_jid/1 and short_prepd_bare_jid/1
functions.
SVN Revision: 1543
---
ChangeLog | 7 +++++++
src/jlib.erl | 22 +++++++++++++++++-----
2 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d45411378..a17316813 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-08-26 Jean-Sébastien Pédron
+
+ * src/jlib.erl: short_jid/1 and short_bare_jid/1 now produce a short
+ JID from the user-provided JID parts. To obtain a short JID from the
+ STRINGPREP'd parts, use the new short_prepd_jid/1 and
+ short_prepd_bare_jid/1 functions.
+
2008-08-14 Jean-Sébastien Pédron
* translate.erl (ascii_tolower): Accept 'undefined' as a language and
diff --git a/src/jlib.erl b/src/jlib.erl
index 698e704e4..2268f326c 100644
--- a/src/jlib.erl
+++ b/src/jlib.erl
@@ -64,7 +64,9 @@
from_old_jid/1,
to_old_jid/1,
short_jid/1,
- short_bare_jid/1]).
+ short_bare_jid/1,
+ short_prepd_jid/1,
+ short_prepd_bare_jid/1]).
-include("jlib.hrl").
@@ -761,10 +763,20 @@ to_old_jid(#jid{user = Node, resource = Resource,
JID#jid{user = Node1, resource = Resource1,
luser = LNode1, lresource = LResource1}.
-short_jid(JID) ->
- JID1 = to_old_jid(JID),
- {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}.
+short_jid(JID1) ->
+ %JID1 = to_old_jid(JID),
+ {JID1#jid.user, JID1#jid.server, JID1#jid.resource}.
short_bare_jid(JID) ->
- JID1 = to_old_jid(exmpp_jid:jid_to_bare_jid(JID)),
+ %JID1 = to_old_jid(exmpp_jid:jid_to_bare_jid(JID)),
+ JID1 = exmpp_jid:jid_to_bare_jid(JID),
+ {JID1#jid.user, JID1#jid.server, JID1#jid.resource}.
+
+short_prepd_jid(JID1) ->
+ %JID1 = to_old_jid(JID),
+ {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}.
+
+short_prepd_bare_jid(JID) ->
+ %JID1 = to_old_jid(exmpp_jid:jid_to_bare_jid(JID)),
+ JID1 = exmpp_jid:jid_to_bare_jid(JID),
{JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}.
From 5aead429644bb0a6e2c5b7bd21ee7c2521a6fc0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 26 Aug 2008 12:58:13 +0000
Subject: [PATCH 060/582] Use the new short_prepd_jid/1 function from jlib.
SVN Revision: 1544
---
ChangeLog | 2 ++
src/acl.erl | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/ChangeLog b/ChangeLog
index a17316813..fc115fe9e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,8 @@
STRINGPREP'd parts, use the new short_prepd_jid/1 and
short_prepd_bare_jid/1 functions.
+ * src/acl.erl: Use the new short_prepd_jid/1 function from jlib.
+
2008-08-14 Jean-Sébastien Pédron
* translate.erl (ascii_tolower): Accept 'undefined' as a language and
diff --git a/src/acl.erl b/src/acl.erl
index e65c34c4a..21bacf618 100644
--- a/src/acl.erl
+++ b/src/acl.erl
@@ -158,7 +158,7 @@ match_acl(ACL, JID, Host) ->
all -> true;
none -> false;
_ ->
- {User, Server, Resource} = jlib:short_jid(JID),
+ {User, Server, Resource} = jlib:short_prepd_jid(JID),
lists:any(fun(#acl{aclspec = Spec}) ->
case Spec of
all ->
From 80fcd2eb566628e25da5190cf2cec4a477948961 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 26 Aug 2008 13:00:35 +0000
Subject: [PATCH 061/582] Remove commented-out code and use proper variable
names.
SVN Revision: 1545
---
ChangeLog | 3 ++-
src/jlib.erl | 20 ++++++++------------
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index fc115fe9e..c011e84b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,7 +3,8 @@
* src/jlib.erl: short_jid/1 and short_bare_jid/1 now produce a short
JID from the user-provided JID parts. To obtain a short JID from the
STRINGPREP'd parts, use the new short_prepd_jid/1 and
- short_prepd_bare_jid/1 functions.
+ short_prepd_bare_jid/1 functions. Remove commented-out code and use
+ proper variable names.
* src/acl.erl: Use the new short_prepd_jid/1 function from jlib.
diff --git a/src/jlib.erl b/src/jlib.erl
index 2268f326c..acf08a550 100644
--- a/src/jlib.erl
+++ b/src/jlib.erl
@@ -763,20 +763,16 @@ to_old_jid(#jid{user = Node, resource = Resource,
JID#jid{user = Node1, resource = Resource1,
luser = LNode1, lresource = LResource1}.
-short_jid(JID1) ->
- %JID1 = to_old_jid(JID),
- {JID1#jid.user, JID1#jid.server, JID1#jid.resource}.
+short_jid(JID) ->
+ {JID#jid.user, JID#jid.server, JID#jid.resource}.
short_bare_jid(JID) ->
- %JID1 = to_old_jid(exmpp_jid:jid_to_bare_jid(JID)),
- JID1 = exmpp_jid:jid_to_bare_jid(JID),
- {JID1#jid.user, JID1#jid.server, JID1#jid.resource}.
+ Bare_JID = exmpp_jid:jid_to_bare_jid(JID),
+ {Bare_JID#jid.user, Bare_JID#jid.server, Bare_JID#jid.resource}.
-short_prepd_jid(JID1) ->
- %JID1 = to_old_jid(JID),
- {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}.
+short_prepd_jid(JID) ->
+ {JID#jid.luser, JID#jid.lserver, JID#jid.lresource}.
short_prepd_bare_jid(JID) ->
- %JID1 = to_old_jid(exmpp_jid:jid_to_bare_jid(JID)),
- JID1 = exmpp_jid:jid_to_bare_jid(JID),
- {JID1#jid.luser, JID1#jid.lserver, JID1#jid.lresource}.
+ Bare_JID = exmpp_jid:jid_to_bare_jid(JID),
+ {Bare_JID#jid.luser, Bare_JID#jid.lserver, Bare_JID#jid.lresource}.
From 9f0d79da9a750ce4da28e3d833dc2b6b008ac74e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 26 Aug 2008 13:38:49 +0000
Subject: [PATCH 062/582] o Use the new functions from jlib. o Remove the
compatibility code. It's becoming confusing to handle every case every where.
Also, in JIDs (normal and short), the atom "undefined' is expected, not the
empty string anymore!
SVN Revision: 1546
---
ChangeLog | 13 ++-
src/ejabberd_c2s.erl | 235 ++++++++++-----------------------------
src/ejabberd_local.erl | 7 +-
src/ejabberd_router.erl | 22 +---
src/ejabberd_s2s.erl | 7 +-
src/ejabberd_s2s_in.erl | 23 ++--
src/ejabberd_s2s_out.erl | 10 +-
src/ejabberd_sm.erl | 44 ++------
8 files changed, 99 insertions(+), 262 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c011e84b1..32a5d3c7a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,9 +4,18 @@
JID from the user-provided JID parts. To obtain a short JID from the
STRINGPREP'd parts, use the new short_prepd_jid/1 and
short_prepd_bare_jid/1 functions. Remove commented-out code and use
- proper variable names.
+ proper variable names. Those functions use the atom 'undefined' and
+ NOT the empty string anymore!
- * src/acl.erl: Use the new short_prepd_jid/1 function from jlib.
+ * src/acl.erl, src/ejabberd_router.erl: Use the new functions from
+ jlib.
+
+ * src/ejabberd_router.erl, src/ejabberd_local.erl,
+ src/ejabberd_sm.erl, src/ejabberd_s2s.erl, src/ejabberd_s2s_in.erl,
+ src/ejabberd_s2s_out.erl, src/ejabberd_c2s.erl: Remove the
+ compatibility code. It's becoming confusing to handle every case every
+ where. Also, in JIDs (normal and short), the atom "undefined' is
+ expected, not the empty string anymore!
2008-08-14 Jean-Sébastien Pédron
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index d006e2a5a..6c86d1149 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -76,7 +76,7 @@
tls_options = [],
authenticated = false,
jid,
- user = "", server = ?MYNAME, resource = "",
+ user = undefined, server = ?MYNAME, resource = undefined,
sid,
pres_t = ?SETS:new(),
pres_f = ?SETS:new(),
@@ -273,12 +273,10 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
false ->
[]
end,
- % XXX OLD FORMAT: Other_Feats.
- Other_FeatsOld = ejabberd_hooks:run_fold(
+ Other_Feats = ejabberd_hooks:run_fold(
c2s_stream_features,
Server,
[], []),
- Other_Feats = [exmpp_xml:xmlelement_to_xmlel(F, [?DEFAULT_NS], ?PREFIXED_NS) || F <- Other_FeatsOld],
send_element(StateData,
exmpp_stream:features(
TLSFeature ++
@@ -292,7 +290,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
lang = Lang});
_ ->
case StateData#state.resource of
- "" ->
+ undefined ->
send_element(
StateData,
exmpp_stream:features([
@@ -413,7 +411,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = jlib:short_bare_jid(JID),
+ LJID = jlib:short_prepd_bare_jid(JID),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList = ejabberd_hooks:run_fold(
@@ -728,7 +726,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
StateData#state.server,
{[], []},
[U, StateData#state.server]),
- LJID = jlib:short_bare_jid(JID),
+ LJID = jlib:short_prepd_bare_jid(JID),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList =
@@ -744,10 +742,8 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
pres_t = ?SETS:from_list(Ts1),
privacy_list = PrivList});
_ ->
- % XXX OLD FORMAT: Jid.
- JIDOld = jlib:to_old_jid(JID),
ejabberd_hooks:run(forbidden_session_hook,
- StateData#state.server, [JIDOld]),
+ StateData#state.server, [JID]),
?INFO_MSG("(~w) Forbidden session for ~s",
[StateData#state.socket,
exmpp_jid:jid_to_list(JID)]),
@@ -801,22 +797,15 @@ session_established({xmlstreamelement, El}, StateData) ->
end,
NewState = case El of
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'presence'} ->
- % XXX OLD FORMAT: NewEl.
- PresenceElOld = ejabberd_hooks:run_fold(
+ PresenceEl = ejabberd_hooks:run_fold(
c2s_update_presence,
Server,
- exmpp_xml:xmlel_to_xmlelement(NewEl,
- [?DEFAULT_NS], ?PREFIXED_NS),
+ NewEl,
[User, Server]),
- PresenceEl = exmpp_xml:xmlelement_to_xmlel(PresenceElOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
- % XXX OLD FORMAT: PresenceElOld, *JID.
- FromJIDOld = jlib:to_old_jid(FromJID),
- ToJIDOld = jlib:to_old_jid(ToJID),
ejabberd_hooks:run(
user_send_packet,
Server,
- [FromJIDOld, ToJIDOld, PresenceElOld]),
+ [FromJID, ToJID, PresenceEl]),
case ToJID of
#jid{node = User,
domain = Server,
@@ -830,43 +819,29 @@ session_established({xmlstreamelement, El}, StateData) ->
StateData)
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'iq'} ->
- % XXX OLD FORMAT: JIDs.
- FromJIDOld = jlib:to_old_jid(FromJID),
- ToJIDOld = jlib:to_old_jid(ToJID),
- case exmpp_iq:get_payload(El) of
- #xmlel{ns = ?NS_PRIVACY} ->
+ case exmpp_iq:xmlel_to_iq(El) of
+ #iq{kind = request, ns = ?NS_PRIVACY} = IQ_Rec ->
process_privacy_iq(
- FromJID, ToJID, El, StateData);
+ FromJID, ToJID, IQ_Rec, StateData);
_ ->
- % XXX OLD FORMAT: NewElOld.
- NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
- [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(
user_send_packet,
Server,
- [FromJIDOld, ToJIDOld, NewElOld]),
+ [FromJID, ToJID, NewEl]),
ejabberd_router:route(
FromJID, ToJID, NewEl),
StateData
end;
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'message'} ->
- % XXX OLD FORMAT: NewElOld, JIDs.
- NewElOld = exmpp_xml:xmlel_to_xmlelement(NewEl,
- [?DEFAULT_NS], ?PREFIXED_NS),
- FromJIDOld = jlib:to_old_jid(FromJID),
- ToJIDOld = jlib:to_old_jid(ToJID),
ejabberd_hooks:run(user_send_packet,
Server,
- [FromJIDOld, ToJIDOld, NewElOld]),
+ [FromJID, ToJID, NewEl]),
ejabberd_router:route(FromJID, ToJID, NewEl),
StateData;
_ ->
StateData
end,
- % XXX OLD FORMAT: El.
- ElOld = exmpp_xml:xmlel_to_xmlelement(El,
- [?DEFAULT_NS], ?PREFIXED_NS),
- ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, ElOld}]),
+ ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, El}]),
fsm_next_state(session_established, NewState)
catch
throw:{stringprep, _, _, _} ->
@@ -879,10 +854,7 @@ session_established({xmlstreamelement, El}, StateData) ->
Err = exmpp_stanza:reply_with_error(El, 'jid-malformed'),
send_element(StateData, Err)
end,
- % XXX OLD FORMAT: ElOld1.
- ElOld1 = exmpp_xml:xmlel_to_xmlelement(El,
- [?DEFAULT_NS], ?PREFIXED_NS),
- ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, ElOld1}]),
+ ejabberd_hooks:run(c2s_loop_debug, [{xmlstreamelement, El}]),
fsm_next_state(session_established, StateData);
throw:Exception ->
io:format("SESSION ESTABLISHED: Exception=~p~n", [Exception]),
@@ -963,9 +935,8 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available,
- % XXX OLF FORMAT: short JID with empty string(s).
Pred = fun({U, S, _R} = User, _Caps) ->
- ?SETS:is_element({U, S, ""},
+ ?SETS:is_element({U, S, undefined},
Subscribed) orelse
?SETS:is_element(User, Subscribed)
end,
@@ -994,19 +965,14 @@ handle_info(replaced, _StateName, StateData) ->
send_element(StateData, exmpp_stream:error('conflict')),
send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData#state{authenticated = replaced}};
-handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
- %% XXX OLD FORMAT: From, To and Packet are in the old format.
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
- From = jlib:from_old_jid(FromOld),
- To = jlib:from_old_jid(ToOld),
+handle_info({route, From, To, Packet}, StateName, StateData) ->
{Pass, NewAttrs, NewState} =
case Packet of
#xmlel{attrs = Attrs} when ?IS_PRESENCE(Packet) ->
case exmpp_presence:get_type(Packet) of
'probe' ->
- LFrom = jlib:short_jid(From),
- LBFrom = jlib:short_bare_jid(From),
+ LFrom = jlib:short_prepd_jid(From),
+ LBFrom = jlib:short_prepd_bare_jid(From),
NewStateData =
case ?SETS:is_element(
LFrom, StateData#state.pres_a) orelse
@@ -1038,7 +1004,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
process_presence_probe(From, To, NewStateData),
{false, Attrs, NewStateData};
'error' ->
- LFrom = jlib:short_jid(From),
+ LFrom = jlib:short_prepd_jid(From),
NewA = remove_element(LFrom,
StateData#state.pres_a),
{true, Attrs, StateData#state{pres_a = NewA}};
@@ -1055,18 +1021,17 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
'unsubscribed' ->
{true, Attrs, StateData};
_ ->
- % XXX OLD FORMAT: From, To, Packet.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, ToOld, PacketOld},
+ {From, To, Packet},
in]) of
allow ->
- LFrom = jlib:short_jid(From),
- LBFrom = jlib:short_bare_jid(From),
+ LFrom = jlib:short_prepd_jid(From),
+ LBFrom = jlib:short_prepd_bare_jid(From),
%% Note contact availability
Els = Packet#xmlel.children,
Caps = mod_caps:read_caps(Els),
@@ -1144,9 +1109,7 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
case exmpp_iq:get_request(Packet) of
#xmlel{ns = ?NS_VCARD} ->
Host = StateData#state.server,
- % XXX OLD FORMAT: sm_iqtable contains strings
- % for namespaces.
- case ets:lookup(sm_iqtable, {atom_to_list(?NS_VCARD), Host}) of
+ case ets:lookup(sm_iqtable, {?NS_VCARD, Host}) of
[{_, Module, Function, Opts}] ->
gen_iq_handler:handle(Host, Module, Function, Opts,
From, To, Packet);
@@ -1156,14 +1119,13 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
end,
{false, Attrs, StateData};
_ ->
- % XXX OLD FORMAT: From, To and Packet.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, ToOld, PacketOld},
+ {From, To, Packet},
in]) of
allow ->
{true, Attrs, StateData};
@@ -1177,14 +1139,13 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
{true, Attrs, StateData}
end;
#xmlel{attrs = Attrs} when ?IS_MESSAGE(Packet) ->
- % XXX OLD FORMAT: From, To and Packet.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, ToOld, PacketOld},
+ {From, To, Packet},
in]) of
allow ->
{true, Attrs, StateData};
@@ -1203,19 +1164,13 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
Attrs3 = exmpp_stanza:set_recipient_in_attrs(Attrs2, To),
FixedPacket = Packet#xmlel{attrs = Attrs3},
send_element(StateData, FixedPacket),
- % XXX OLD FORMAT: JID, From, To, FixedPacket.
- JIDOld = jlib:to_old_jid(StateData#state.jid),
- FixedPacketOld = exmpp_xml:xmlel_to_xmlelement(FixedPacket,
- [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(user_receive_packet,
StateData#state.server,
- [JIDOld, FromOld, ToOld, FixedPacketOld]),
- % XXX OLD FORMAT: From, To, FixedPacket.
- ejabberd_hooks:run(c2s_loop_debug, [{route, FromOld, ToOld, PacketOld}]),
+ [StateData#state.jid, From, To, FixedPacket]),
+ ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
fsm_next_state(StateName, NewState);
true ->
- % XXX OLD FORMAT: From, To, FixedPacket.
- ejabberd_hooks:run(c2s_loop_debug, [{route, FromOld, ToOld, PacketOld}]),
+ ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]),
fsm_next_state(StateName, NewState)
end;
handle_info({'DOWN', Monitor, _Type, _Object, _Info}, _StateName, StateData)
@@ -1353,8 +1308,8 @@ get_conn_type(StateData) ->
end.
process_presence_probe(From, To, StateData) ->
- LFrom = jlib:short_jid(From),
- LBFrom = jlib:short_bare_jid(From),
+ LFrom = jlib:short_prepd_jid(From),
+ LBFrom = jlib:short_prepd_bare_jid(From),
case StateData#state.pres_last of
undefined ->
ok;
@@ -1375,25 +1330,19 @@ process_presence_probe(From, To, StateData) ->
if
Cond1 ->
Packet = StateData#state.pres_last,
- % XXX OLD FORMAT: From, To, Packet.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {ToOld, FromOld, PacketOld},
+ {To, From, Packet},
out]) of
deny ->
ok;
allow ->
Pid=element(2, StateData#state.sid),
- % XXX OLD FORMAT: From, To.
- ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [FromOld, ToOld, Pid]),
+ ejabberd_hooks:run(presence_probe_hook, StateData#state.server, [From, To, Pid]),
%% Don't route a presence probe to oneself
case From == To of
false ->
@@ -1491,11 +1440,9 @@ presence_update(From, Packet, StateData) ->
NewState =
if
FromUnavail ->
- % XXX OLD FORMAT: JID.
- JIDOld = jlib:to_old_jid(StateData#state.jid),
ejabberd_hooks:run(user_available_hook,
StateData#state.server,
- [JIDOld]),
+ [StateData#state.jid]),
if NewPriority >= 0 ->
resend_offline_messages(StateData),
resend_subscription_requests(StateData);
@@ -1525,15 +1472,10 @@ presence_update(From, Packet, StateData) ->
end.
presence_track(From, To, Packet, StateData) ->
- LTo = jlib:short_jid(To),
+ LTo = jlib:short_prepd_jid(To),
User = StateData#state.user,
Server = StateData#state.server,
BFrom = exmpp_jid:jid_to_bare_jid(From),
- % XXX OLD FORMAT: From, To, Packet.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
case exmpp_presence:get_type(Packet) of
'unavailable' ->
ejabberd_router:route(From, To, Packet),
@@ -1548,31 +1490,27 @@ presence_track(From, To, Packet, StateData) ->
StateData#state{pres_i = I,
pres_a = A};
'subscribe' ->
- % XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
- [User, Server, ToOld, subscribe]),
+ [User, Server, To, subscribe]),
ejabberd_router:route(BFrom, To, Packet),
StateData;
'subscribed' ->
- % XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
- [User, Server, ToOld, subscribed]),
+ [User, Server, To, subscribed]),
ejabberd_router:route(BFrom, To, Packet),
StateData;
'unsubscribe' ->
- % XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
- [User, Server, ToOld, unsubscribe]),
+ [User, Server, To, unsubscribe]),
ejabberd_router:route(BFrom, To, Packet),
StateData;
'unsubscribed' ->
- % XXX OLD FORMAT: To.
ejabberd_hooks:run(roster_out_subscription,
Server,
- [User, Server, ToOld, unsubscribed]),
+ [User, Server, To, unsubscribed]),
ejabberd_router:route(BFrom, To, Packet),
StateData;
'error' ->
@@ -1582,14 +1520,13 @@ presence_track(From, To, Packet, StateData) ->
ejabberd_router:route(From, To, Packet),
StateData;
_ ->
- % XXX OLD FORMAT: From, To, Packet.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, ToOld, PacketOld},
+ {From, To, Packet},
out]) of
deny ->
ok;
@@ -1605,18 +1542,13 @@ presence_track(From, To, Packet, StateData) ->
presence_broadcast(StateData, From, JIDSet, Packet) ->
lists:foreach(fun({U, S, R}) ->
FJID = exmpp_jid:make_jid(U, S, R),
- % XXX OLD FORMAT: From, FJID, Packet.
- FJIDOld = jlib:to_old_jid(FJID),
- FromOld = jlib:to_old_jid(From),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, FJIDOld, PacketOld},
+ {From, FJID, Packet},
out]) of
deny ->
ok;
@@ -1626,24 +1558,18 @@ presence_broadcast(StateData, From, JIDSet, Packet) ->
end, ?SETS:to_list(JIDSet)).
presence_broadcast_to_trusted(StateData, From, T, A, Packet) ->
- % XXX OLD FORMAT: From, Packet.
- FromOld = jlib:to_old_jid(From),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
lists:foreach(
fun({U, S, R} = JID) ->
case ?SETS:is_element(JID, T) of
true ->
FJID = exmpp_jid:make_jid(U, S, R),
- % XXX OLD FORMAT: FJID.
- FJIDOld = jlib:to_old_jid(FJID),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, FJIDOld, PacketOld},
+ {From, FJID, Packet},
out]) of
deny ->
ok;
@@ -1675,18 +1601,13 @@ presence_broadcast_first(From, StateData, Packet) ->
As = ?SETS:fold(
fun({U, S, R} = JID, A) ->
FJID = exmpp_jid:make_jid(U, S, R),
- % XXX OLD FORMAT: From, FJID, Packet.
- FromOld = jlib:to_old_jid(From),
- FJIDOld = jlib:to_old_jid(FJID),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, FJIDOld, PacketOld},
+ {From, FJID, Packet},
out]) of
deny ->
ok;
@@ -1711,7 +1632,7 @@ remove_element(E, Set) ->
roster_change(IJID, ISubscription, StateData) ->
- LIJID = jlib:short_jid(IJID),
+ LIJID = jlib:short_prepd_jid(IJID),
IsFrom = (ISubscription == both) or (ISubscription == from),
IsTo = (ISubscription == both) or (ISubscription == to),
OldIsFrom = ?SETS:is_element(LIJID, StateData#state.pres_f),
@@ -1734,9 +1655,6 @@ roster_change(IJID, ISubscription, StateData) ->
?DEBUG("roster changed for ~p~n", [StateData#state.user]),
From = StateData#state.jid,
To = IJID,
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
Cond1 = (not StateData#state.pres_invis) and IsFrom
and (not OldIsFrom),
Cond2 = (not IsFrom) and OldIsFrom
@@ -1745,17 +1663,13 @@ roster_change(IJID, ISubscription, StateData) ->
if
Cond1 ->
?DEBUG("C1: ~p~n", [LIJID]),
- % XXX OLD FORMAT: P.
- POld = exmpp_xml:xmlelement_to_xmlel(P,
- [?DEFAULT_NS], ?PREFIXED_NS),
- % XXX OLD FORMAT: From, To, P.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, ToOld, POld},
+ {From, To, P},
out]) of
deny ->
ok;
@@ -1770,17 +1684,13 @@ roster_change(IJID, ISubscription, StateData) ->
Cond2 ->
?DEBUG("C2: ~p~n", [LIJID]),
PU = exmpp_presence:unavailable(),
- % XXX OLD FORMAT: PU.
- PUOld = exmpp_xml:xmlelement_to_xmlel(PU,
- [?DEFAULT_NS], ?PREFIXED_NS),
- % XXX OLD FORMAT: From, To, PU.
case ejabberd_hooks:run_fold(
privacy_check_packet, StateData#state.server,
allow,
[StateData#state.user,
StateData#state.server,
StateData#state.privacy_list,
- {FromOld, ToOld, PUOld},
+ {From, To, PU},
out]) of
deny ->
ok;
@@ -1813,26 +1723,21 @@ update_priority(Priority, Packet, StateData) ->
Info).
process_privacy_iq(From, To,
- El,
+ #iq{type = Type} = IQ_Rec,
StateData) ->
- % XXX OLD FORMAT: IQ_Rec is an #iq.
- IQ_Rec = jlib:iq_query_info(El),
- % XXX OLD FORMAT: JIDs.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
{Res, NewStateData} =
- case exmpp_iq:get_type(El) of
+ case Type of
get ->
R = ejabberd_hooks:run_fold(
privacy_iq_get, StateData#state.server,
{error, ?ERR_FEATURE_NOT_IMPLEMENTED},
- [FromOld, ToOld, IQ_Rec, StateData#state.privacy_list]),
+ [From, To, IQ_Rec, StateData#state.privacy_list]),
{R, StateData};
set ->
case ejabberd_hooks:run_fold(
privacy_iq_set, StateData#state.server,
{error, ?ERR_FEATURE_NOT_IMPLEMENTED},
- [FromOld, ToOld, IQ_Rec]) of
+ [From, To, IQ_Rec]) of
{result, R, NewPrivList} ->
{{result, R},
StateData#state{privacy_list = NewPrivList}};
@@ -1841,14 +1746,10 @@ process_privacy_iq(From, To,
end,
IQRes =
case Res of
- {result, ResultOld} ->
- Result = exmpp_xml:xmlelement_to_xmlel(ResultOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
- exmpp_iq:result(El, Result);
- {error, ErrorOld} ->
- Error = exmpp_xml:xmlelement_to_xmlel(ErrorOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
- exmpp_iq:error(El, Error)
+ {result, Result} ->
+ exmpp_iq:result(IQ_Rec, Result);
+ {error, Error} ->
+ exmpp_iq:error(IQ_Rec, Error)
end,
ejabberd_router:route(
To, From, IQRes),
@@ -1863,18 +1764,16 @@ resend_offline_messages(#state{user = User,
[],
[User, Server]) of
Rs when list(Rs) ->
- % XXX OLD FORMAT: From, To, Packet.
- % XXX OLD FORMAT ON DISK!
lists:foreach(
fun({route,
- FromOld, ToOld, PacketOld}) ->
+ From, To, Packet}) ->
Pass = case ejabberd_hooks:run_fold(
privacy_check_packet, Server,
allow,
[User,
Server,
PrivList,
- {FromOld, ToOld, PacketOld},
+ {From, To, Packet},
in]) of
allow ->
true;
@@ -1883,11 +1782,6 @@ resend_offline_messages(#state{user = User,
end,
if
Pass ->
- % XXX OLD FORMAT: From, To, Packet.
- From = jlib:from_old_jid(FromOld),
- To = jlib:from_old_jid(ToOld),
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
Attrs1 = exmpp_stanza:set_sender_in_attrs(
Packet#xmlel.attrs, From),
Attrs2 = exmpp_stanza:set_recipient_in_attrs(
@@ -1907,11 +1801,7 @@ resend_subscription_requests(#state{user = User,
Server,
[],
[User, Server]),
- % XXX OLD FORMAT: XMLPacket.
- % XXX OLD FORMAT ON DISK!
- lists:foreach(fun(XMLPacketOld) ->
- XMLPacket = exmpp_xml:xmlelement_to_xmlel(
- XMLPacketOld, [?DEFAULT_NS], ?PREFIXED_NS),
+ lists:foreach(fun(XMLPacket) ->
send_element(StateData,
XMLPacket)
end,
@@ -1920,14 +1810,13 @@ resend_subscription_requests(#state{user = User,
process_unauthenticated_stanza(StateData, El) ->
case exmpp_iq:get_kind(El) of
request ->
- % XXX OLD FORMAT: IQ_Rec is an #iq.
- IQ_Rec = jlib:iq_query_info(El),
- ResOld = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
+ IQ_Rec = exmpp_iq:xmlel_to_iq(El),
+ Res = ejabberd_hooks:run_fold(c2s_unauthenticated_iq,
StateData#state.server,
empty,
[StateData#state.server, IQ_Rec,
StateData#state.ip]),
- case ResOld of
+ case Res of
empty ->
% The only reasonable IQ's here are auth and register IQ's
% They contain secrets, so don't include subelements to response
@@ -1938,8 +1827,6 @@ process_unauthenticated_stanza(StateData, El) ->
Res2 = exmpp_stanza:remove_recipient(Res1),
send_element(StateData, Res2);
_ ->
- Res = exmpp_xml:xmlelement_to_xmlel(ResOld,
- [?DEFAULT_NS], ?PREFIXED_NS),
send_element(StateData, Res)
end;
_ ->
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index f06b821e6..d77eb6968 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -321,14 +321,9 @@ do_route(From, To, Packet) ->
"error" -> ok;
"result" -> ok;
_ ->
- % XXX OLD FORMAT: From, To, Packet.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(local_send_to_resource_hook,
To#jid.ldomain,
- [FromOld, ToOld, PacketOld])
+ [From, To, Packet])
end
end.
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index cd7f02002..04bc76285 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -321,19 +321,9 @@ code_change(_OldVsn, State, _Extra) ->
do_route(OrigFrom, OrigTo, OrigPacket) ->
?DEBUG("route~n\tfrom ~p~n\tto ~p~n\tpacket ~p~n",
[OrigFrom, OrigTo, OrigPacket]),
- % XXX OLD FORMAT: OrigFrom, OrigTo, OrigPacket.
- OrigFromOld = jlib:to_old_jid(OrigFrom),
- OrigToOld = jlib:to_old_jid(OrigTo),
- OrigPacketOld = exmpp_xml:xmlel_to_xmlelement(OrigPacket,
- [?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
case ejabberd_hooks:run_fold(filter_packet,
- {OrigFromOld, OrigToOld, OrigPacketOld}, []) of
- {FromOld, ToOld, PacketOld} ->
- % XXX OLD FORMAT: From, To, Packet.
- From = jlib:from_old_jid(FromOld),
- To = jlib:from_old_jid(ToOld),
- Packet = exmpp_xml:xmlelement_to_xmlel(PacketOld,
- [?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ {OrigFrom, OrigTo, OrigPacket}, []) of
+ {From, To, Packet} ->
LDstDomain = To#jid.ldomain,
case mnesia:dirty_read(route, LDstDomain) of
[] ->
@@ -358,12 +348,12 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
{domain_balancing, LDstDomain}) of
undefined -> now();
random -> now();
- source -> jlib:short_jid(From);
- destination -> jlib:short_jid(To);
+ source -> jlib:short_prepd_jid(From);
+ destination -> jlib:short_prepd_jid(To);
bare_source ->
- jlib:short_bare_jid(From);
+ jlib:short_prepd_bare_jid(From);
bare_destination ->
- jlib:short_bare_jid(To)
+ jlib:short_prepd_bare_jid(To)
end,
case get_component_number(LDstDomain) of
undefined ->
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index b8af4251f..492484c31 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -283,15 +283,10 @@ do_route(From, To, Packet) ->
NewPacket1 = exmpp_stanza:set_sender(Packet, From),
NewPacket = exmpp_stanza:set_recipient(NewPacket1, To),
#jid{ldomain = MyServer} = From,
- % XXX OLD FORMAT: From, To, NewPacket.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- NewPacketOld = exmpp_xml:xmlel_to_xmlelement(NewPacket,
- [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(
s2s_send_packet,
MyServer,
- [FromOld, ToOld, NewPacketOld]),
+ [From, To, NewPacket]),
send_element(Pid, NewPacket),
ok;
{aborted, _Reason} ->
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 4804ff551..2fdcbac28 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -386,11 +386,8 @@ stream_established({xmlstreamelement, El}, StateData) ->
_Exception2 -> error
end
end,
- % XXX OLD FORMAT: El.
- % XXX No namespace conversion (:server <-> :client) is done.
+ % No namespace conversion (:server <-> :client) is done.
% This is handled by C2S and S2S send_element functions.
- ElOld = exmpp_xml:xmlel_to_xmlelement(El,
- [?DEFAULT_NS], ?PREFIXED_NS),
if
(To /= error) and (From /= error) ->
LFrom = From#jid.ldomain,
@@ -407,13 +404,10 @@ stream_established({xmlstreamelement, El}, StateData) ->
if ((Name == 'iq') or
(Name == 'message') or
(Name == 'presence')) ->
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
ejabberd_hooks:run(
s2s_receive_packet,
LFrom,
- [FromOld, ToOld, ElOld]),
+ [From, To, El]),
ejabberd_router:route(
From, To, El);
true ->
@@ -430,13 +424,10 @@ stream_established({xmlstreamelement, El}, StateData) ->
if ((Name == 'iq') or
(Name == 'message') or
(Name == 'presence')) ->
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
ejabberd_hooks:run(
s2s_receive_packet,
LFrom,
- [FromOld, ToOld, ElOld]),
+ [From, To, El]),
ejabberd_router:route(
From, To, El);
true ->
@@ -449,7 +440,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
true ->
error
end,
- ejabberd_hooks:run(s2s_loop_debug, [{xmlstreamelement, ElOld}]),
+ ejabberd_hooks:run(s2s_loop_debug, [{xmlstreamelement, El}]),
{next_state, stream_established, StateData#state{timer = Timer}}
end;
@@ -656,11 +647,11 @@ get_cert_domains(Cert) ->
case 'XmppAddr':decode(
'XmppAddr', XmppAddr) of
{ok, D} when is_binary(D) ->
- case jlib:string_to_jid(
+ case exmpp_jid:list_to_jid(
binary_to_list(D)) of
- #jid{lnode = "",
+ #jid{lnode = undefined,
ldomain = LD,
- lresource = ""} ->
+ lresource = undefined} ->
case idna:domain_utf8_to_ascii(LD) of
false ->
[];
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index 5859b89cf..bbd792a2f 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -716,10 +716,7 @@ handle_info({send_text, Text}, StateName, StateData) ->
{next_state, StateName, StateData#state{timer = Timer},
get_timeout_interval(StateName)};
-handle_info({send_element, ElOld}, StateName, StateData) ->
- % XXX OLD FORMAT: El.
- El = exmpp_xml:xmlelement_to_xmlel(ElOld,
- [?NS_JABBER_CLIENT], ?PREFIXED_NS),
+handle_info({send_element, El}, StateName, StateData) ->
case StateName of
stream_established ->
cancel_timer(StateData#state.timer),
@@ -839,10 +836,7 @@ cancel_timer(Timer) ->
bounce_messages(Condition) ->
receive
- {send_element, ElOld} ->
- % XXX OLD FORMAT: El.
- El = exmpp_xml:xmlelement_to_xmlel(ElOld,
- [?NS_JABBER_CLIENT], ?PREFIXED_NS),
+ {send_element, El} ->
bounce_element(El, Condition),
bounce_messages(Condition)
after 0 ->
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index d9bc3c185..3cec22f04 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -107,10 +107,8 @@ open_session(SID, User, Server, Resource, Info) ->
set_session(SID, User, Server, Resource, undefined, Info),
check_for_sessions_to_replace(User, Server, Resource),
JID = exmpp_jid:make_jid(User, Server, Resource),
- % XXX OLD FORMAT: JID.
- JIDOld = jlib:to_old_jid(JID),
ejabberd_hooks:run(sm_register_connection_hook, JID#jid.ldomain,
- [SID, JIDOld, Info]).
+ [SID, JID, Info]).
close_session(SID, User, Server, Resource) ->
Info = case mnesia:dirty_read({session, SID}) of
@@ -122,10 +120,8 @@ close_session(SID, User, Server, Resource) ->
end,
mnesia:sync_dirty(F),
JID = exmpp_jid:make_jid(User, Server, Resource),
- % XXX OLD FORMAT: JID.
- JIDOld = jlib:to_old_jid(JID),
ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.ldomain,
- [SID, JIDOld, Info]).
+ [SID, JID, Info]).
check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
case ejabberd_auth:is_user_exists(User, Server) of
@@ -188,11 +184,8 @@ get_user_info(User, Server, Resource) ->
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
set_session(SID, User, Server, Resource, Priority, Info),
- % XXX OLD FORMAT: Presence.
- PresenceOld = exmpp_xml:xmlel_to_xmlelement(Presence,
- [?DEFAULT_NS], ?PREFIXED_NS),
ejabberd_hooks:run(set_presence_hook, exmpp_stringprep:nameprep(Server),
- [User, Server, Resource, PresenceOld]).
+ [User, Server, Resource, Presence]).
unset_presence(SID, User, Server, Resource, Status, Info) ->
set_session(SID, User, Server, Resource, undefined, Info),
@@ -408,9 +401,6 @@ do_route(From, To, Packet) ->
[From, To, Packet, 8]),
#jid{node = User, domain = Server,
lnode = LUser, ldomain = LServer, lresource = LResource} = To,
- % XXX OLD FORMAT: From, To.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
case LResource of
undefined ->
case Packet of
@@ -419,36 +409,32 @@ do_route(From, To, Packet) ->
case exmpp_presence:get_type(Packet) of
'subscribe' ->
Reason = exmpp_presence:get_status(Packet),
- % XXX OLD FORMAT: From.
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
- [User, Server, FromOld, subscribe, Reason]),
+ [User, Server, From, subscribe, Reason]),
true};
'subscribed' ->
- % XXX OLD FORMAT: From.
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
- [User, Server, FromOld, subscribed, ""]),
+ [User, Server, From, subscribed, ""]),
true};
'unsubscribe' ->
- % XXX OLD FORMAT: From.
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
- [User, Server, FromOld, unsubscribe, ""]),
+ [User, Server, From, unsubscribe, ""]),
true};
'unsubscribed' ->
- % XXX OLD FORMAT: From.
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
false,
- [User, Server, FromOld, unsubscribed, ""]),
+ [User, Server, From, unsubscribed, ""]),
true};
_ ->
{true, false}
@@ -504,10 +490,7 @@ do_route(From, To, Packet) ->
Session = lists:max(Ss),
Pid = element(2, Session#session.sid),
?DEBUG("sending to process ~p~n", [Pid]),
- % XXX OLD FORMAT: From, To, Packet.
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
- Pid ! {route, FromOld, ToOld, PacketOld}
+ Pid ! {route, From, To, Packet}
end
end.
@@ -515,11 +498,6 @@ route_message(From, To, Packet) ->
LUser = To#jid.lnode,
LServer = To#jid.ldomain,
PrioRes = get_user_present_resources(LUser, LServer),
- % XXX OLD FORMAT: From, To, Packet.
- FromOld = jlib:to_old_jid(From),
- ToOld = jlib:to_old_jid(To),
- PacketOld = exmpp_xml:xmlel_to_xmlelement(Packet,
- [?DEFAULT_NS], ?PREFIXED_NS),
case catch lists:max(PrioRes) of
{Priority, _R} when is_integer(Priority), Priority >= 0 ->
lists:foreach(
@@ -535,8 +513,7 @@ route_message(From, To, Packet) ->
Session = lists:max(Ss),
Pid = element(2, Session#session.sid),
?DEBUG("sending to process ~p~n", [Pid]),
- % XXX OLD FORMAT: From, To, Packet.
- Pid ! {route, FromOld, ToOld, PacketOld}
+ Pid ! {route, From, To, Packet}
end;
%% Ignore other priority:
({_Prio, _Res}) ->
@@ -554,10 +531,9 @@ route_message(From, To, Packet) ->
_ ->
case ejabberd_auth:is_user_exists(LUser, LServer) of
true ->
- % XXX OLD FORMAT: From, To, Packet.
ejabberd_hooks:run(offline_message_hook,
LServer,
- [FromOld, ToOld, PacketOld]);
+ [From, To, Packet]);
_ ->
Err = exmpp_stanza:reply_with_error(
Packet, 'service-unaivailable'),
From 4e39f4cab1355329646d0ddb8bd6a33cb94f3e89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 26 Aug 2008 13:59:04 +0000
Subject: [PATCH 063/582] o Remove compatibility code. Use the atom
'undefined' in JIDs (normal and short). o Add try/catch blocks where Exmpp
can raise exceptions. o Remove some unused code. o Convert on-disk Mnesia
database: JIDs, extra XML elements and askmessage are concerned. o By
default, 'askmessage' is now an empty binary instead of an empty string, for
consistency's sake. o Fix some bugs.
SVN Revision: 1547
---
ChangeLog | 8 +
src/mod_roster.erl | 548 ++++++++++++++++++++++++++-------------------
src/mod_roster.hrl | 2 +-
3 files changed, 322 insertions(+), 236 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 32a5d3c7a..b733ab458 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,6 +17,14 @@
where. Also, in JIDs (normal and short), the atom "undefined' is
expected, not the empty string anymore!
+ * src/mod_roster.hrl, src/mod_roster.erl: Remove compatibility code.
+ Use the atom 'undefined' in JIDs (normal and short). Add try/catch
+ blocks where Exmpp can raise exceptions. Remove some unused code.
+ Convert on-disk Mnesia database: JIDs, extra XML elements and
+ askmessage are concerned. By default, 'askmessage' is now an empty
+ binary instead of an empty string, for consistency's sake. Fix some
+ bugs.
+
2008-08-14 Jean-Sébastien Pédron
* translate.erl (ascii_tolower): Accept 'undefined' as a language and
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index e67eb58c6..ec43d595a 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -123,9 +123,7 @@ process_local_iq(From, To, #iq{type = set} = IQ_Rec) ->
process_iq_get(From, To, IQ_Rec) ->
- LUser = From#jid.lnode,
- LServer = From#jid.ldomain,
- US = {LUser, LServer},
+ US = {From#jid.lnode, From#jid.ldomain},
case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
Items when is_list(Items) ->
XItems = lists:map(fun item_to_xml/1, Items),
@@ -188,14 +186,12 @@ process_iq_set(From, To, #iq{payload = Request} = IQ_Rec) ->
end,
exmpp_iq:result(IQ_Rec).
-process_item_set(From, To, #xmlel{} = Item) ->
+process_item_set(From, To, #xmlel{} = El) ->
try
- JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(Item, 'jid', "")),
- % XXX OLD FORMAT: old JID (with empty strings).
- #jid{node = User, lnode = LUser, ldomain = LServer} =
- jlib:to_old_jid(From),
- JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
- LJID = jlib:short_jid(JID1),
+ JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
+ #jid{node = User, lnode = LUser, ldomain = LServer} = From,
+ JID = jlib:short_jid(JID1),
+ LJID = jlib:short_prepd_jid(JID1),
F = fun() ->
Res = mnesia:read({roster, {LUser, LServer, LJID}}),
Item = case Res of
@@ -209,8 +205,8 @@ process_item_set(From, To, #xmlel{} = Item) ->
groups = [],
xs = []}
end,
- Item1 = process_item_attrs(Item, Item#xmlel.attrs),
- Item2 = process_item_els(Item1, Item#xmlel.children),
+ Item1 = process_item_attrs(Item, El#xmlel.attrs),
+ Item2 = process_item_els(Item1, El#xmlel.children),
case Item2#roster.subscription of
remove ->
mnesia:delete({roster, {LUser, LServer, LJID}});
@@ -270,15 +266,6 @@ process_item_set(_From, _To, _) ->
process_item_attrs(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of
- 'jid' ->
- try
- JID1 = exmpp_jid:list_to_jid(Val),
- JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
- process_item_attrs(Item#roster{jid = JID}, Attrs)
- catch
- _ ->
- process_item_attrs(Item, Attrs)
- end;
'name' ->
process_item_attrs(Item#roster{name = Val}, Attrs);
'subscription' ->
@@ -319,7 +306,7 @@ process_item_els(Item, []) ->
push_item(User, Server, From, Item) ->
- ejabberd_sm:route(exmpp_jid:make_bare_jid(""),
+ ejabberd_sm:route(#jid{},
exmpp_jid:make_bare_jid(User, Server),
#xmlel{name = 'broadcast', children =
[{item,
@@ -340,12 +327,17 @@ push_item(User, Server, Resource, From, Item) ->
ResIQ).
get_subscription_lists(_, User, Server) ->
- LUser = exmpp_stringprep:nodeprep(User),
- LServer = exmpp_stringprep:nameprep(Server),
- US = {LUser, LServer},
- case mnesia:dirty_index_read(roster, US, #roster.us) of
- Items when is_list(Items) ->
- fill_subscription_lists(Items, [], []);
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ US = {LUser, LServer},
+ case mnesia:dirty_index_read(roster, US, #roster.us) of
+ Items when is_list(Items) ->
+ fill_subscription_lists(Items, [], []);
+ _ ->
+ {[], []}
+ end
+ catch
_ ->
{[], []}
end.
@@ -378,84 +370,87 @@ out_subscription(User, Server, JID, Type) ->
process_subscription(out, User, Server, JID, Type, []).
process_subscription(Direction, User, Server, JID1, Type, Reason) ->
- LUser = exmpp_stringprep:nodeprep(User),
- LServer = exmpp_stringprep:nameprep(Server),
- US = {LUser, LServer},
- LJID = jlib:short_jid(JID1),
- F = fun() ->
- Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of
- [] ->
- JID = {JID1#jid.node,
- JID1#jid.domain,
- JID1#jid.resource},
- #roster{usj = {LUser, LServer, LJID},
- us = US,
- jid = JID};
- [I] ->
- I
- end,
- NewState = case Direction of
- out ->
- out_state_change(Item#roster.subscription,
- Item#roster.ask,
- Type);
- in ->
- in_state_change(Item#roster.subscription,
- Item#roster.ask,
- Type)
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ US = {LUser, LServer},
+ LJID = jlib:short_prepd_jid(JID1),
+ F = fun() ->
+ Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of
+ [] ->
+ JID = jlib:short_jid(JID1),
+ #roster{usj = {LUser, LServer, LJID},
+ us = US,
+ jid = JID};
+ [I] ->
+ I
end,
- AutoReply = case Direction of
- out ->
- none;
- in ->
- in_auto_reply(Item#roster.subscription,
- Item#roster.ask,
- Type)
- end,
- AskMessage = case NewState of
- {_, both} -> Reason;
- {_, in} -> Reason;
- _ -> ""
- end,
- case NewState of
- none ->
- {none, AutoReply};
- {none, none} when Item#roster.subscription == none,
- Item#roster.ask == in ->
- mnesia:delete({roster, {LUser, LServer, LJID}}),
- {none, AutoReply};
- {Subscription, Pending} ->
- NewItem = Item#roster{subscription = Subscription,
- ask = Pending,
- askmessage = list_to_binary(AskMessage)},
- mnesia:write(NewItem),
- {{push, NewItem}, AutoReply}
- end
- end,
- case mnesia:transaction(F) of
- {atomic, {Push, AutoReply}} ->
- case AutoReply of
- none ->
- ok;
- _ ->
- ejabberd_router:route(
- exmpp_jid:make_bare_jid(User, Server), JID1,
- exmpp_presence:AutoReply())
+ NewState = case Direction of
+ out ->
+ out_state_change(Item#roster.subscription,
+ Item#roster.ask,
+ Type);
+ in ->
+ in_state_change(Item#roster.subscription,
+ Item#roster.ask,
+ Type)
+ end,
+ AutoReply = case Direction of
+ out ->
+ none;
+ in ->
+ in_auto_reply(Item#roster.subscription,
+ Item#roster.ask,
+ Type)
+ end,
+ AskMessage = case NewState of
+ {_, both} -> Reason;
+ {_, in} -> Reason;
+ _ -> ""
+ end,
+ case NewState of
+ none ->
+ {none, AutoReply};
+ {none, none} when Item#roster.subscription == none,
+ Item#roster.ask == in ->
+ mnesia:delete({roster, {LUser, LServer, LJID}}),
+ {none, AutoReply};
+ {Subscription, Pending} ->
+ NewItem = Item#roster{subscription = Subscription,
+ ask = Pending,
+ askmessage = list_to_binary(AskMessage)},
+ mnesia:write(NewItem),
+ {{push, NewItem}, AutoReply}
+ end
end,
- case Push of
- {push, Item} ->
- if
- Item#roster.subscription == none,
- Item#roster.ask == in ->
- ok;
- true ->
- push_item(User, Server,
- exmpp_jid:make_bare_jid(User, Server), Item)
- end,
- true;
- none ->
- false
- end;
+ case mnesia:transaction(F) of
+ {atomic, {Push, AutoReply}} ->
+ case AutoReply of
+ none ->
+ ok;
+ _ ->
+ ejabberd_router:route(
+ exmpp_jid:make_bare_jid(User, Server), JID1,
+ exmpp_presence:AutoReply())
+ end,
+ case Push of
+ {push, Item} ->
+ if
+ Item#roster.subscription == none,
+ Item#roster.ask == in ->
+ ok;
+ true ->
+ push_item(User, Server,
+ exmpp_jid:make_bare_jid(User, Server), Item)
+ end,
+ true;
+ none ->
+ false
+ end;
+ _ ->
+ false
+ end
+ catch
_ ->
false
end.
@@ -557,35 +552,44 @@ in_auto_reply(_, _, _) -> none.
remove_user(User, Server) ->
- LUser = exmpp_stringpre:nodeprep(User),
- LServer = exmpp_stringprep:nameprep(Server),
- US = {LUser, LServer},
- F = fun() ->
- lists:foreach(fun(R) ->
- mnesia:delete_object(R)
- end,
- mnesia:index_read(roster, US, #roster.us))
- end,
- mnesia:transaction(F).
+ try
+ LUser = exmpp_stringpre:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ US = {LUser, LServer},
+ F = fun() ->
+ lists:foreach(fun(R) ->
+ mnesia:delete_object(R)
+ end,
+ mnesia:index_read(roster, US, #roster.us))
+ end,
+ mnesia:transaction(F)
+ catch
+ _ ->
+ ok
+ end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-set_items(User, Server, SubEl) ->
- {xmlelement, _Name, _Attrs, Els} = SubEl,
- LUser = exmpp_stringprep:nodeprep(User),
- LServer = exmpp_stringprep:nameprep(Server),
- F = fun() ->
- lists:foreach(fun(El) ->
- process_item_set_t(LUser, LServer, El)
- end, Els)
- end,
- mnesia:transaction(F).
+set_items(User, Server, #xmlel{children = Els}) ->
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ F = fun() ->
+ lists:foreach(fun(El) ->
+ process_item_set_t(LUser, LServer, El)
+ end, Els)
+ end,
+ mnesia:transaction(F)
+ catch
+ _ ->
+ ok
+ end.
process_item_set_t(LUser, LServer, #xmlel{} = El) ->
try
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
- JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
- LJID = {JID1#jid.lnode, JID1#jid.ldomain, JID1#jid.lresource},
+ JID = jlib:short_jid(JID1),
+ LJID = jlib:short_prepd_jid(JID1),
Item = #roster{usj = {LUser, LServer, LJID},
us = {LUser, LServer},
jid = JID},
@@ -606,15 +610,6 @@ process_item_set_t(_LUser, _LServer, _) ->
process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
case Attr of
- 'jid' ->
- try
- JID1 = exmpp_jid:list_to_jid(Val),
- JID = {JID1#jid.node, JID1#jid.domain, JID1#jid.resource},
- process_item_attrs_ws(Item#roster{jid = JID}, Attrs)
- catch
- _ ->
- process_item_attrs_ws(Item, Attrs)
- end;
'name' ->
process_item_attrs_ws(Item#roster{name = Val}, Attrs);
'subscription' ->
@@ -650,14 +645,9 @@ get_in_pending_subscriptions(Ls, User, Server) ->
US = {JID#jid.lnode, JID#jid.ldomain},
case mnesia:dirty_index_read(roster, US, #roster.us) of
Result when list(Result) ->
- Ls ++ lists:map(
+ Ls ++ lists:map(
fun(R) ->
Message = R#roster.askmessage,
- Status = if is_binary(Message) ->
- binary_to_list(Message);
- true ->
- ""
- end,
{U, S, R} = R#roster.jid,
Attrs1 = exmpp_stanza:set_sender_in_list([],
exmpp_jid:jid_to_list(U, S, R)),
@@ -665,7 +655,7 @@ get_in_pending_subscriptions(Ls, User, Server) ->
exmpp_jid:jid_to_list(JID)),
Pres1 = exmpp_presence:subscribe(),
Pres2 = Pres1#xmlel{attrs = Attrs2},
- exmpp_presence:set_status(Pres2, Status)
+ exmpp_presence:set_status(Pres2, Message)
end,
lists:filter(
fun(R) ->
@@ -684,27 +674,32 @@ get_in_pending_subscriptions(Ls, User, Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_jid_info(_, User, Server, JID) ->
- LUser = exmpp_stringprep:nodeprep(User),
- LJID = jlib:short_jid(JID),
- LServer = exmpp_stringprep:nameprep(Server),
- case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of
- [#roster{subscription = Subscription, groups = Groups}] ->
- {Subscription, Groups};
+ try
+ LUser = exmpp_stringprep:nodeprep(User),
+ LServer = exmpp_stringprep:nameprep(Server),
+ LJID = jlib:short_prepd_jid(JID),
+ case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of
+ [#roster{subscription = Subscription, groups = Groups}] ->
+ {Subscription, Groups};
+ _ ->
+ LRJID = jlib:short_prepd_bare_jid(JID),
+ if
+ LRJID == LJID ->
+ {none, []};
+ true ->
+ case catch mnesia:dirty_read(
+ roster, {LUser, LServer, LRJID}) of
+ [#roster{subscription = Subscription,
+ groups = Groups}] ->
+ {Subscription, Groups};
+ _ ->
+ {none, []}
+ end
+ end
+ end
+ catch
_ ->
- LRJID = jlib:short_jid(exmpp_jid:jid_to_bare_jid(JID)),
- if
- LRJID == LJID ->
- {none, []};
- true ->
- case catch mnesia:dirty_read(
- roster, {LUser, LServer, LRJID}) of
- [#roster{subscription = Subscription,
- groups = Groups}] ->
- {Subscription, Groups};
- _ ->
- {none, []}
- end
- end
+ {none, []}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -714,7 +709,7 @@ update_table() ->
Fields = record_info(fields, roster),
case mnesia:table_info(roster, attributes) of
Fields ->
- ok;
+ convert_to_exmpp();
[uj, user, jid, name, subscription, ask, groups, xattrs, xs] ->
convert_table1(Fields);
[usj, us, jid, name, subscription, ask, groups, xattrs, xs] ->
@@ -742,11 +737,18 @@ convert_table1(Fields) ->
F1 = fun() ->
mnesia:write_lock_table(mod_roster_tmp_table),
mnesia:foldl(
- fun(#roster{usj = {U, JID}, us = U} = R, _) ->
+ fun(#roster{usj = {U, {JID_U, JID_S, JID_R}}, us = U, xs = XS, askmessage = AM} = R, _) ->
+ U1 = convert_jid_to_exmpp(U),
+ JID_U1 = convert_jid_to_exmpp(JID_U),
+ JID_R1 = convert_jid_to_exmpp(JID_R),
+ JID1 = {JID_U1, JID_S, JID_R1},
+ XS1 = convert_xs_to_exmpp(XS),
+ AM1 = convert_askmessage_to_exmpp(AM),
mnesia:dirty_write(
mod_roster_tmp_table,
- R#roster{usj = {U, Host, JID},
- us = {U, Host}})
+ R#roster{usj = {U1, Host, JID1},
+ us = {U1, Host}, xs = XS1,
+ askmessage = AM1})
end, ok, roster)
end,
mnesia:transaction(F1),
@@ -766,9 +768,74 @@ convert_table1(Fields) ->
convert_table2(Fields) ->
?INFO_MSG("Converting roster table from "
"{usj, us, jid, name, subscription, ask, groups, xattrs, xs} format", []),
- mnesia:transform_table(roster, ignore, Fields).
+ mnesia:transform_table(roster, ignore, Fields),
+ convert_to_exmpp().
+convert_to_exmpp() ->
+ Fun = fun() ->
+ case mnesia:first(roster) of
+ '$end_of_table' ->
+ none;
+ Key ->
+ case mnesia:read({roster, Key}) of
+ [#roster{jid = {_, _, undefined}}] ->
+ none;
+ [#roster{jid = {_, _, ""}}] ->
+ mnesia:foldl(fun convert_to_exmpp2/2,
+ done, roster, write)
+ end
+ end
+ end,
+ Ret = mnesia:transaction(Fun),
+ io:format("Conversion return value: ~p~n", [Ret]).
+
+convert_to_exmpp2(#roster{
+ usj = {USJ_U, USJ_S, {USJ_JU, USJ_JS, USJ_JR}} = Key,
+ us = {US_U, US_S},
+ jid = {JID_U, JID_S, JID_R},
+ xs = XS, askmessage = AM} = R, Acc) ->
+ % Remove old entry.
+ mnesia:delete({roster, Key}),
+ % Convert "" to undefined in JIDs.
+ USJ_U1 = convert_jid_to_exmpp(USJ_U),
+ USJ_JU1 = convert_jid_to_exmpp(USJ_JU),
+ USJ_JR1 = convert_jid_to_exmpp(USJ_JR),
+ US_U1 = convert_jid_to_exmpp(US_U),
+ JID_U1 = convert_jid_to_exmpp(JID_U),
+ JID_R1 = convert_jid_to_exmpp(JID_R),
+ % Convert xs.
+ XS1 = convert_xs_to_exmpp(XS),
+ % Convert askmessage.
+ AM1 = convert_askmessage_to_exmpp(AM),
+ % Prepare the new record.
+ New_R = R#roster{
+ usj = {USJ_U1, USJ_S, {USJ_JU1, USJ_JS, USJ_JR1}},
+ us = {US_U1, US_S},
+ jid = {JID_U1, JID_S, JID_R1},
+ xs = XS1, askmessage = AM1},
+ % Write the new record.
+ mnesia:write(New_R),
+ Acc.
+
+convert_jid_to_exmpp("") -> undefined;
+convert_jid_to_exmpp(V) -> V.
+
+convert_xs_to_exmpp(Els) ->
+ convert_xs_to_exmpp(Els, []).
+
+convert_xs_to_exmpp([El | Rest], Result) ->
+ New_El = exmpp_xml:xmlelement_to_xmlel(El,
+ [?NS_JABBER_CLIENT], [{?NS_XMPP, ?NS_XMPP_pfx}]),
+ convert_xs_to_exmpp(Rest, [New_El | Result]);
+convert_xs_to_exmpp([], Result) ->
+ lists:reverse(Result).
+
+convert_askmessage_to_exmpp(AM) when is_binary(AM) ->
+ AM;
+convert_askmessage_to_exmpp(AM) ->
+ list_to_binary(AM).
+
webadmin_page(_, Host,
#request{us = _US,
path = ["user", U, "roster"],
@@ -780,74 +847,85 @@ webadmin_page(_, Host,
webadmin_page(Acc, _, _) -> Acc.
user_roster(User, Server, Query, Lang) ->
- US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
- Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
- Res = user_roster_parse_query(User, Server, Items1, Query),
- Items = mnesia:dirty_index_read(roster, US, #roster.us),
- SItems = lists:sort(Items),
- FItems =
- case SItems of
- [] ->
- [?CT("None")];
- _ ->
- [?XE("table",
- [?XE("thead",
- [?XE("tr",
- [?XCT("td", "Jabber ID"),
- ?XCT("td", "Nickname"),
- ?XCT("td", "Subscription"),
- ?XCT("td", "Pending"),
- ?XCT("td", "Groups")
- ])]),
- ?XE("tbody",
- lists:map(
- fun(R) ->
- Groups =
- lists:flatmap(
- fun(Group) ->
- [?C(Group), ?BR]
- end, R#roster.groups),
- Pending = ask_to_pending(R#roster.ask),
- {U, S, R} = R#roster.jid,
- ?XE("tr",
- [?XAC("td", [{"class", "valign"}],
- catch exmpp_jid:jid_to_list(U, S, R)),
- ?XAC("td", [{"class", "valign"}],
- R#roster.name),
- ?XAC("td", [{"class", "valign"}],
- atom_to_list(R#roster.subscription)),
- ?XAC("td", [{"class", "valign"}],
- atom_to_list(Pending)),
- ?XAE("td", [{"class", "valign"}], Groups),
- if
- Pending == in ->
- ?XAE("td", [{"class", "valign"}],
- [?INPUTT("submit",
- "validate" ++
- ejabberd_web_admin:term_to_id(R#roster.jid),
- "Validate")]);
- true ->
- ?X("td")
- end,
- ?XAE("td", [{"class", "valign"}],
- [?INPUTT("submit",
- "remove" ++
- ejabberd_web_admin:term_to_id(R#roster.jid),
- "Remove")])])
- end, SItems))])]
- end,
- [?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
- case Res of
- ok -> [?CT("Submitted"), ?P];
- error -> [?CT("Bad format"), ?P];
- nothing -> []
- end ++
- [?XAE("form", [{"action", ""}, {"method", "post"}],
- FItems ++
- [?P,
- ?INPUT("text", "newjid", ""), ?C(" "),
- ?INPUTT("submit", "addjid", "Add Jabber ID")
- ])].
+ try
+ US = {exmpp_stringprep:nodeprep(User), exmpp_stringprep:nameprep(Server)},
+ Items1 = mnesia:dirty_index_read(roster, US, #roster.us),
+ Res = user_roster_parse_query(User, Server, Items1, Query),
+ Items = mnesia:dirty_index_read(roster, US, #roster.us),
+ SItems = lists:sort(Items),
+ FItems =
+ case SItems of
+ [] ->
+ [?CT("None")];
+ _ ->
+ [?XE("table",
+ [?XE("thead",
+ [?XE("tr",
+ [?XCT("td", "Jabber ID"),
+ ?XCT("td", "Nickname"),
+ ?XCT("td", "Subscription"),
+ ?XCT("td", "Pending"),
+ ?XCT("td", "Groups")
+ ])]),
+ ?XE("tbody",
+ lists:map(
+ fun(R) ->
+ Groups =
+ lists:flatmap(
+ fun(Group) ->
+ [?C(Group), ?BR]
+ end, R#roster.groups),
+ Pending = ask_to_pending(R#roster.ask),
+ {U, S, R} = R#roster.jid,
+ ?XE("tr",
+ [?XAC("td", [{"class", "valign"}],
+ catch exmpp_jid:jid_to_list(U, S, R)),
+ ?XAC("td", [{"class", "valign"}],
+ R#roster.name),
+ ?XAC("td", [{"class", "valign"}],
+ atom_to_list(R#roster.subscription)),
+ ?XAC("td", [{"class", "valign"}],
+ atom_to_list(Pending)),
+ ?XAE("td", [{"class", "valign"}], Groups),
+ if
+ Pending == in ->
+ ?XAE("td", [{"class", "valign"}],
+ [?INPUTT("submit",
+ "validate" ++
+ ejabberd_web_admin:term_to_id(R#roster.jid),
+ "Validate")]);
+ true ->
+ ?X("td")
+ end,
+ ?XAE("td", [{"class", "valign"}],
+ [?INPUTT("submit",
+ "remove" ++
+ ejabberd_web_admin:term_to_id(R#roster.jid),
+ "Remove")])])
+ end, SItems))])]
+ end,
+ [?XC("h1", ?T("Roster of ") ++ us_to_list(US))] ++
+ case Res of
+ ok -> [?CT("Submitted"), ?P];
+ error -> [?CT("Bad format"), ?P];
+ nothing -> []
+ end ++
+ [?XAE("form", [{"action", ""}, {"method", "post"}],
+ FItems ++
+ [?P,
+ ?INPUT("text", "newjid", ""), ?C(" "),
+ ?INPUTT("submit", "addjid", "Add Jabber ID")
+ ])]
+ catch
+ _ ->
+ [?XC("h1", ?T("Roster of ") ++ us_to_list({User, Server}))] ++
+ [?CT("Bad format"), ?P] ++
+ [?XAE("form", [{"action", ""}, {"method", "post"}],
+ [?P,
+ ?INPUT("text", "newjid", ""), ?C(" "),
+ ?INPUTT("submit", "addjid", "Add Jabber ID")
+ ])]
+ end.
user_roster_parse_query(User, Server, Items, Query) ->
case lists:keysearch("addjid", 1, Query) of
diff --git a/src/mod_roster.hrl b/src/mod_roster.hrl
index 2a2e8bc72..380a4e246 100644
--- a/src/mod_roster.hrl
+++ b/src/mod_roster.hrl
@@ -26,6 +26,6 @@
subscription = none,
ask = none,
groups = [],
- askmessage = [],
+ askmessage = <<>>,
xs = []}).
From 8baed0864116721743803e58fdfd86af90d38993 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 27 Aug 2008 09:45:01 +0000
Subject: [PATCH 064/582] Remove a debugging io:format/2.
SVN Revision: 1551
---
ChangeLog | 4 ++++
src/mod_roster.erl | 3 +--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b733ab458..1242e3a29 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2008-08-27 Jean-Sébastien Pédron
+
+ * src/mod_roster.erl: Remove a debugging io:format/2.
+
2008-08-26 Jean-Sébastien Pédron
* src/jlib.erl: short_jid/1 and short_bare_jid/1 now produce a short
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index ec43d595a..fe2c740fe 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -787,8 +787,7 @@ convert_to_exmpp() ->
end
end
end,
- Ret = mnesia:transaction(Fun),
- io:format("Conversion return value: ~p~n", [Ret]).
+ mnesia:transaction(Fun).
convert_to_exmpp2(#roster{
usj = {USJ_U, USJ_S, {USJ_JU, USJ_JS, USJ_JR}} = Key,
From 02e6bf875967e6ea5ba6ca8f02e57172d5ad1b60 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 27 Aug 2008 09:46:25 +0000
Subject: [PATCH 065/582] handle_cast({disco_response, ...}, ...) now receives
an #iq record: update the code to handle this.
SVN Revision: 1552
---
ChangeLog | 3 +++
src/mod_caps.erl | 13 ++++++-------
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 1242e3a29..5400cdd0c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,9 @@
* src/mod_roster.erl: Remove a debugging io:format/2.
+ * src/mod_caps.erl: handle_cast({disco_response, ...}, ...) now
+ receives an #iq record: update the code to handle this.
+
2008-08-26 Jean-Sébastien Pédron
* src/jlib.erl: short_jid/1 and short_bare_jid/1 now produce a short
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index a04a27f0a..852ae7e48 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -217,10 +217,9 @@ handle_cast({note_caps, From,
?ERROR_MSG("Transaction failed: ~p", [Error]),
{noreply, State}
end;
-handle_cast({disco_response, From, _To, IQ},
+handle_cast({disco_response, From, _To, #iq{id = ID, type = Type, payload = Payload}},
#state{disco_requests = Requests} = State) ->
- ID = exmpp_stanza:get_id(IQ),
- case {exmpp_iq:get_type(IQ), exmpp_iq:get_payload(IQ)} of
+ case {Type, Payload} of
{result, #xmlel{name = 'query', children = Els}} ->
case ?DICT:find(ID, Requests) of
{ok, {Node, SubNode}} ->
@@ -255,8 +254,8 @@ handle_cast({disco_response, From, _To, IQ},
end;
%gen_server:cast(self(), visit_feature_queries),
%?DEBUG("Error IQ reponse from ~s:~n~p", [exmpp_jid:jid_to_list(From), SubEls]);
- {result, _} ->
- ?DEBUG("Invalid IQ contents from ~s:~n~p", [exmpp_jid:jid_to_list(From), IQ#xmlel.children]);
+ {result, Payload} ->
+ ?DEBUG("Invalid IQ contents from ~s:~n~p", [exmpp_jid:jid_to_list(From), Payload]);
_ ->
%% Can't do anything about errors
ok
@@ -287,10 +286,10 @@ handle_cast(visit_feature_queries, #state{feature_queries = FeatureQueries} = St
end, [], FeatureQueries),
{noreply, State#state{feature_queries = NewFeatureQueries}}.
-handle_disco_response(From, To, IQ) ->
+handle_disco_response(From, To, IQ_Rec) ->
#jid{ldomain = Host} = To,
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
- gen_server:cast(Proc, {disco_response, From, To, IQ}).
+ gen_server:cast(Proc, {disco_response, From, To, IQ_Rec}).
handle_info(_Info, State) ->
{noreply, State}.
From 414948d822ec504bbfb331e334d32d6080f355d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Wed, 27 Aug 2008 12:39:49 +0000
Subject: [PATCH 066/582] VCard are now stored as #xmlel. Mnesia tables are
converted during startup.
SVN Revision: 1553
---
ChangeLog | 3 +++
src/mod_vcard.erl | 43 ++++++++++++++++++++++++++++---------------
2 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 5400cdd0c..c03ba622c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,9 @@
* src/mod_caps.erl: handle_cast({disco_response, ...}, ...) now
receives an #iq record: update the code to handle this.
+ * src/mod_vcard.erl: VCard are now stored as #xmlel. Mnesia tables are
+ converted during startup.
+
2008-08-26 Jean-Sébastien Pédron
* src/jlib.erl: short_jid/1 and short_bare_jid/1 now produce a short
diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl
index 0447d5920..69fbcae7f 100644
--- a/src/mod_vcard.erl
+++ b/src/mod_vcard.erl
@@ -142,10 +142,10 @@ get_sm_features(Acc, _From, _To, Node, _Lang) ->
case Acc of
{result, Features} ->
% XXX OLD FORMAT: NS as string.
- {result, [atom_to_list(?NS_VCARD) | Features]};
+ {result, [?NS_VCARD_s | Features]};
empty ->
% XXX OLD FORMAT: NS as string.
- {result, [atom_to_list(?NS_VCARD)]}
+ {result, [?NS_VCARD_s]}
end;
_ ->
Acc
@@ -177,14 +177,7 @@ process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
[VCard | _] = case mnesia:transaction(F) of
{atomic, Rs} ->
lists:map(fun(R) ->
- case R#vcard.vcard of
- #xmlel{} = E ->
- E;
- #xmlelement{} = E ->
- % XXX OLD FORMAT: Base contains old elements.
- io:format("VCARD: Old element in base: ~p~n", [E]),
- exmpp_xml:xmlelement_to_xmlel(E, [?NS_VCARD], [])
- end
+ R#vcard.vcard
end, Rs);
{aborted, _Reason} ->
[]
@@ -249,10 +242,7 @@ set_vcard(User, LServer, VCARD) ->
US = {LUser, LServer},
F = fun() ->
- % XXX OLD FORMAT: We keep persistent data in the old format
- % for now.
- VCARDOld = exmpp_xml:xmlel_to_xmlelement(VCARD, [?NS_VCARD], []),
- mnesia:write(#vcard{us = US, vcard = VCARDOld}),
+ mnesia:write(#vcard{us = US, vcard = VCARD}),
mnesia:write(
#vcard_search{us = US,
user = {User, LServer},
@@ -673,7 +663,7 @@ update_vcard_table() ->
Fields = record_info(fields, vcard),
case mnesia:table_info(vcard, attributes) of
Fields ->
- ok;
+ convert_to_exmpp();
[user, vcard] ->
?INFO_MSG("Converting vcard table from "
"{user, vcard} format", []),
@@ -712,6 +702,29 @@ update_vcard_table() ->
end.
+convert_to_exmpp() ->
+ Fun = fun() ->
+ case mnesia:first(vcard) of
+ '$end_of_table' ->
+ none;
+ Key ->
+ case mnesia:read({vcard, Key}) of
+ [#vcard{vcard = #xmlel{}}] ->
+ none;
+ [#vcard{vcard = #xmlelement{}}] ->
+ mnesia:foldl(fun convert_to_exmpp2/2,
+ done, vcard, write)
+ end
+ end
+ end,
+ mnesia:transaction(Fun).
+
+convert_to_exmpp2(#vcard{vcard = ElOld} = VCard, Acc) ->
+ El0 = exmpp_xml:xmlelement_to_xmlel(ElOld, [?NS_VCARD], []),
+ El = exmpp_xml:remove_whitespaces_deeply(El0),
+ mnesia:write(VCard#vcard{vcard = El}),
+ Acc.
+
update_vcard_search_table() ->
Fields = record_info(fields, vcard_search),
case mnesia:table_info(vcard_search, attributes) of
From 4eaa8e19c9b6427596cda4734a0f719baf97d6b7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20P=C3=A9dron?=
Date: Tue, 16 Sep 2008 14:39:57 +0000
Subject: [PATCH 067/582] Merge from trunk (r1457 to r1563).
SVN Revision: 1564
---
ChangeLog | 272 ++-
README | 6 +-
contrib/ejabberd-modules.repo | 4 +-
.../extract_translations.erl | 121 +-
.../prepare-translation.sh | 172 +-
doc/api/overview.edoc | 2 +-
doc/guide.html | 186 +-
doc/guide.tex | 217 ++-
doc/release_notes_2.0.2.txt | 34 +
src/Makefile.in | 3 +
src/acl.erl | 2 +-
src/adhoc.erl | 2 +-
src/adhoc.hrl | 2 +-
src/configure.erl | 2 +-
src/cyrsasl.erl | 2 +-
src/cyrsasl_anonymous.erl | 2 +-
src/cyrsasl_plain.erl | 2 +-
src/ejabberd.erl | 2 +-
src/ejabberd.hrl | 2 +-
src/ejabberd_admin.erl | 2 +-
src/ejabberd_app.erl | 4 +-
src/ejabberd_auth.erl | 11 +-
src/ejabberd_auth_anonymous.erl | 2 +-
src/ejabberd_auth_external.erl | 7 +-
src/ejabberd_auth_internal.erl | 7 +-
src/ejabberd_auth_ldap.erl | 2 +-
src/ejabberd_auth_odbc.erl | 9 +-
src/ejabberd_auth_pam.erl | 2 +-
src/ejabberd_c2s.erl | 20 +-
src/ejabberd_c2s_config.erl | 2 +-
src/ejabberd_check.erl | 24 +-
src/ejabberd_config.erl | 12 +-
src/ejabberd_config.hrl | 2 +-
src/ejabberd_ctl.erl | 11 +-
src/ejabberd_ctl.hrl | 2 +-
src/ejabberd_frontend_socket.erl | 2 +-
src/ejabberd_hooks.erl | 2 +-
src/ejabberd_listener.erl | 2 +-
src/ejabberd_local.erl | 2 +-
src/ejabberd_logger_h.erl | 2 +-
src/ejabberd_loglevel.erl | 2 +-
src/ejabberd_node_groups.erl | 2 +-
src/ejabberd_rdbms.erl | 2 +-
src/ejabberd_receiver.erl | 2 +-
src/ejabberd_router.erl | 8 +-
src/ejabberd_s2s.erl | 2 +-
src/ejabberd_s2s_in.erl | 2 +-
src/ejabberd_s2s_out.erl | 2 +-
src/ejabberd_service.erl | 14 +-
src/ejabberd_sm.erl | 2 +-
src/ejabberd_socket.erl | 2 +-
src/ejabberd_sup.erl | 2 +-
src/ejabberd_system_monitor.erl | 2 +-
src/ejabberd_tmp_sup.erl | 2 +-
src/ejabberd_update.erl | 2 +-
src/ejabberd_zlib/ejabberd_zlib.erl | 2 +-
src/ejabberd_zlib/ejabberd_zlib_drv.c | 2 +-
src/ejd2odbc.erl | 2 +-
src/eldap/eldap.hrl | 2 +-
src/eldap/eldap_filter.erl | 2 +-
src/eldap/eldap_pool.erl | 2 +-
src/eldap/eldap_utils.erl | 2 +-
src/extauth.erl | 2 +-
src/gen_iq_handler.erl | 2 +-
src/gen_mod.erl | 23 +-
src/idna.erl | 2 +-
src/jd2ejd.erl | 2 +-
src/jlib.erl | 2 +-
src/jlib.hrl | 2 +-
src/mod_adhoc.erl | 2 +-
src/mod_announce.erl | 2 +-
src/mod_caps.erl | 2 +-
src/mod_configure.erl | 2 +-
src/mod_configure2.erl | 2 +-
src/mod_disco.erl | 2 +-
src/mod_echo.erl | 2 +-
src/mod_ip_blacklist.erl | 2 +-
src/mod_irc/iconv.erl | 2 +-
src/mod_irc/iconv_erl.c | 2 +-
src/mod_irc/mod_irc.erl | 2 +-
src/mod_irc/mod_irc_connection.erl | 2 +-
src/mod_last.erl | 2 +-
src/mod_last_odbc.erl | 14 +-
src/mod_muc/mod_muc.erl | 2 +-
src/mod_muc/mod_muc_log.erl | 233 ++-
src/mod_muc/mod_muc_room.erl | 186 +-
src/mod_offline.erl | 2 +-
src/mod_offline_odbc.erl | 4 +-
src/mod_privacy.erl | 2 +-
src/mod_privacy.hrl | 2 +-
src/mod_privacy_odbc.erl | 52 +-
src/mod_private.erl | 2 +-
src/mod_private_odbc.erl | 2 +-
src/mod_proxy65/mod_proxy65.erl | 2 +-
src/mod_proxy65/mod_proxy65.hrl | 2 +-
src/mod_proxy65/mod_proxy65_lib.erl | 12 +-
src/mod_proxy65/mod_proxy65_service.erl | 2 +-
src/mod_proxy65/mod_proxy65_sm.erl | 2 +-
src/mod_proxy65/mod_proxy65_stream.erl | 4 +-
src/mod_pubsub/gen_pubsub_node.erl | 8 +-
src/mod_pubsub/gen_pubsub_nodetree.erl | 8 +-
src/mod_pubsub/mod_pubsub.erl | 97 +-
src/mod_pubsub/node.template | 8 +-
src/mod_pubsub/node_buddy.erl | 8 +-
src/mod_pubsub/node_club.erl | 8 +-
src/mod_pubsub/node_default.erl | 24 +-
src/mod_pubsub/node_dispatch.erl | 10 +-
src/mod_pubsub/node_pep.erl | 31 +-
src/mod_pubsub/node_private.erl | 8 +-
src/mod_pubsub/node_public.erl | 8 +-
src/mod_pubsub/node_zoo.erl | 27 +-
src/mod_pubsub/nodetree_default.erl | 13 +-
src/mod_pubsub/nodetree_virtual.erl | 8 +-
src/mod_pubsub/pubsub.hrl | 8 +-
src/mod_register.erl | 27 +-
src/mod_roster.erl | 2 +-
src/mod_roster.hrl | 2 +-
src/mod_roster_odbc.erl | 2 +-
src/mod_service_log.erl | 2 +-
src/mod_shared_roster.erl | 2 +-
src/mod_stats.erl | 2 +-
src/mod_time.erl | 2 +-
src/mod_vcard.erl | 2 +-
src/mod_vcard_ldap.erl | 2 +-
src/mod_vcard_odbc.erl | 4 +-
src/mod_version.erl | 2 +-
src/msgs/ca.msg | 727 ++++----
src/msgs/ca.po | 1497 +++++++++++++++
src/msgs/cs.msg | 747 ++++----
src/msgs/cs.po | 1487 +++++++++++++++
src/msgs/de.msg | 727 ++++----
src/msgs/de.po | 1504 +++++++++++++++
src/msgs/ejabberd.pot | 1467 +++++++++++++++
src/msgs/eo.msg | 731 ++++----
src/msgs/eo.po | 1493 +++++++++++++++
src/msgs/es.msg | 726 ++++----
src/msgs/es.po | 1502 +++++++++++++++
src/msgs/fr.msg | 729 ++++----
src/msgs/fr.po | 1512 +++++++++++++++
src/msgs/gl.msg | 721 ++++----
src/msgs/gl.po | 1500 +++++++++++++++
src/msgs/it.msg | 727 ++++----
src/msgs/it.po | 1506 +++++++++++++++
src/msgs/ja.msg | 718 ++++----
src/msgs/ja.po | 1484 +++++++++++++++
src/msgs/nl.msg | 722 ++++----
src/msgs/nl.po | 1508 +++++++++++++++
src/msgs/no.msg | 727 ++++----
src/msgs/no.po | 1493 +++++++++++++++
src/msgs/pl.msg | 764 ++++----
src/msgs/pl.po | 1500 +++++++++++++++
src/msgs/pt-br.msg | 745 ++++----
src/msgs/pt-br.po | 1499 +++++++++++++++
src/msgs/pt.msg | 394 ++--
src/msgs/pt.po | 1626 +++++++++++++++++
src/msgs/ru.msg | 730 ++++----
src/msgs/ru.po | 1496 +++++++++++++++
src/msgs/sk.msg | 763 ++++----
src/msgs/sk.po | 1493 +++++++++++++++
src/msgs/sv.msg | 639 ++++---
src/msgs/sv.po | 1495 +++++++++++++++
src/msgs/th.msg | 702 ++++---
src/msgs/th.po | 1488 +++++++++++++++
src/msgs/tr.msg | 734 ++++----
src/msgs/tr.po | 1497 +++++++++++++++
src/msgs/uk.msg | 733 ++++----
src/msgs/uk.po | 1498 +++++++++++++++
src/msgs/vi.msg | 702 ++++---
src/msgs/vi.po | 1510 +++++++++++++++
src/msgs/wa.msg | 716 ++++----
src/msgs/wa.po | 1505 +++++++++++++++
src/msgs/zh.msg | 730 ++++----
src/msgs/zh.po | 1476 +++++++++++++++
src/odbc/ejabberd_odbc.erl | 37 +-
src/odbc/ejabberd_odbc_sup.erl | 2 +-
src/odbc/{mssql.sql => mssql2000.sql} | 2 +-
src/odbc/mssql2005.sql | 1053 +++++++++++
src/odbc/mysql.sql | 2 +-
src/odbc/odbc_queries.erl | 4 +-
src/odbc/pg.sql | 2 +-
src/p1_fsm.erl | 4 +-
src/p1_mnesia.erl | 4 +-
src/pam/epam.c | 2 +-
src/pam/epam.erl | 2 +-
src/randoms.erl | 2 +-
src/sha.erl | 2 +-
src/shaper.erl | 2 +-
src/stringprep/stringprep.erl | 2 +-
src/stringprep/stringprep_drv.c | 2 +-
src/stringprep/stringprep_sup.erl | 2 +-
src/tls/tls.erl | 2 +-
src/tls/tls_drv.c | 2 +-
src/translate.erl | 2 +-
src/treap.erl | 2 +-
src/web/ejabberd_http.erl | 72 +-
src/web/ejabberd_http.hrl | 8 +-
src/web/ejabberd_http_poll.erl | 2 +-
src/web/ejabberd_web.erl | 2 +-
src/web/ejabberd_web_admin.erl | 2 +-
src/web/ejabberd_web_admin.hrl | 2 +-
src/xml.erl | 2 +-
src/xml_stream.erl | 2 +-
202 files changed, 46384 insertions(+), 9369 deletions(-)
create mode 100644 doc/release_notes_2.0.2.txt
create mode 100644 src/msgs/ca.po
create mode 100644 src/msgs/cs.po
create mode 100644 src/msgs/de.po
create mode 100644 src/msgs/ejabberd.pot
create mode 100644 src/msgs/eo.po
create mode 100644 src/msgs/es.po
create mode 100644 src/msgs/fr.po
create mode 100644 src/msgs/gl.po
create mode 100644 src/msgs/it.po
create mode 100644 src/msgs/ja.po
create mode 100644 src/msgs/nl.po
create mode 100644 src/msgs/no.po
create mode 100644 src/msgs/pl.po
create mode 100644 src/msgs/pt-br.po
create mode 100644 src/msgs/pt.po
create mode 100644 src/msgs/ru.po
create mode 100644 src/msgs/sk.po
create mode 100644 src/msgs/sv.po
create mode 100644 src/msgs/th.po
create mode 100644 src/msgs/tr.po
create mode 100644 src/msgs/uk.po
create mode 100644 src/msgs/vi.po
create mode 100644 src/msgs/wa.po
create mode 100644 src/msgs/zh.po
rename src/odbc/{mssql.sql => mssql2000.sql} (96%)
create mode 100644 src/odbc/mssql2005.sql
diff --git a/ChangeLog b/ChangeLog
index c03ba622c..b7c0329aa 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2008-09-16 Jean-Sébastien Pédron
+
+ Merge from trunk (r1457 to r1563).
+
+2008-09-15 Badlop
+
+ * doc/guide.tex: Fix explanation of mod_muc's anonymous
+ option. Make clear that an ejabberd_service can only serve a
+ single external component. Provide Mnesia directory when setting
+ clustering (thanks to Matthew Reilly)
+
+2008-09-12 Badlop
+
+ * src/web/ejabberd_http.hrl: Provide Host, Port, Headers and
+ Transfer Protocol in request (thanks to Eric Cestari)(EJAB-560)
+ * src/web/ejabberd_http.erl: Likewise
+
+2008-09-02 Badlop
+
+ * doc/guide.tex: Fix mod_proxy configuration example
+ * doc/guide.html: Likewise
+
+2008-09-02 Mickael Remond
+
+ * src/odbc/mssql2000.sql: Script for MSSQL 2000
+ * src/odbc/mssql2005.sql: Script for MSSQL 2005 (EJAB-535)
+ * src/odbc/mssql.sql: removed
+
2008-08-27 Jean-Sébastien Pédron
* src/mod_roster.erl: Remove a debugging io:format/2.
@@ -5,8 +33,14 @@
* src/mod_caps.erl: handle_cast({disco_response, ...}, ...) now
receives an #iq record: update the code to handle this.
- * src/mod_vcard.erl: VCard are now stored as #xmlel. Mnesia tables are
- converted during startup.
+ * src/mod_vcard.erl: VCards are now stored as #xmlel. Mnesia tables
+ are converted during startup.
+
+2008-08-27 Christophe Romain
+
+ * src/mod_pubsub/mod_pubsub.erl: send last published events now
+ supports PEP events from unavailable users nodes (EJAB-698)
+ * src/ejabberd_c2s.erl: Likewise
2008-08-26 Jean-Sébastien Pédron
@@ -35,6 +69,81 @@
binary instead of an empty string, for consistency's sake. Fix some
bugs.
+2008-08-26 Badlop
+
+ * doc/release_notes_2.0.2.txt: Update for final release
+
+ * doc/guide.tex: Windows binary installer requires MSVC++ 5
+ * doc/guide.html: Likewise
+
+2008-08-26 Christophe Romain
+
+ * src/mod_pubsub/mod_pubsub.erl: get_items bugfix (EJAB-716)
+
+2008-08-25 Christophe Romain
+
+ * src/mod_privacy_odbc.erl: Prevent case_clause error when
+ ejabber_odbc:sql_query returns {error, Reason}
+ * src/mod_vcard_odbc.erl: Likewise
+ * src/mod_last_odbc.erl: Likewise
+ * src/mod_offline_odbc.erl: Likewise
+
+2008-08-25 Badlop
+
+ * src/ejabberd_check.erl: Detect correctly MSSQL and ODBC
+ configuration (EJAB-710)
+
+2008-08-24 Geoff Cant
+
+ * src/mod_mud/mod_muc_room.erl: is_visitor/2 fix - use get_role
+ not get_affiliation
+
+2008-08-22 Badlop
+
+ * src/ejabberd_router.erl: Fix call to mnesia match_object
+
+2008-08-21 Badlop
+
+ * doc/guide.tex: Fix names of chatroom to room, user to occupant
+ * doc/guide.html: Likewise
+
+2008-08-18 Badlop
+
+ * src/mod_muc/mod_muc_log.erl: MUC log files options: plaintext
+ format; filename with only room name (EJAB-596)
+ * doc/guide.tex: Document both options
+ * doc/guide.html: Likewise
+
+ * src/mod_register.erl: Change password using mod_register always
+ returns success regardless of real result (EJAB-723)
+ * src/ejabberd_auth.erl: Likewise
+ * src/ejabberd_auth_external.erl: Likewise
+ * src/ejabberd_auth_internal.erl: Likewise
+ * src/ejabberd_auth_odbc.erl: Likewise
+
+2008-08-18 Christophe Romain
+
+ * src/mod_pubsub/node_dispatch.erl: Fix call to unexported function
+ nodetree_default:get_subnodes/2
+
+2008-08-17 Badlop
+
+ * contrib/extract_translations/extract_translations.erl: Use
+ Gettext PO for translators, export to ejabberd MSG (EJAB-648)
+ * contrib/extract_translations/prepare-translation.sh: Likewise
+ * doc/guide.tex: Likewise
+ * doc/guide.html: Likewise
+ * src/Makefile.in: New option 'make translations'
+ * src/msgs/ejabberd.pot: Template translation file
+ * src/msgs/*.po: Generated from old MSG files
+ * src/msgs/*.msg: Automatic exported from PO files
+
+2008-08-16 Badlop
+
+ * src/msgs/sv.msg: Fixed formatting typos
+
+ * src/gen_mod.erl: Export stop_module_keep_config/2 (EJAB-706)
+
2008-08-14 Jean-Sébastien Pédron
* translate.erl (ascii_tolower): Accept 'undefined' as a language and
@@ -49,6 +158,25 @@
src/mod_disco.erl, src/mod_last.erl: Convert to the new #iq record
from Exmpp.
+2008-08-13 Badlop
+
+ * doc/guide.tex: Explain that LDAP is read-only storage (thanks to
+ Evgeniy Khramtsov)
+ * doc/guide.html: Likewise
+
+2008-08-10 Badlop
+
+ * src/msgs/eo.msg: Updated (thanks to Andreas van Cranenburgh)
+ * src/msgs/nl.msg: Updated (thanks to Andreas van Cranenburgh)
+ * src/msgs/sk.msg: Updated (thanks to Marek Becka)
+ * src/msgs/sv.msg: Updated (thanks to Thore Alstromer and Heysan)
+
+2008-08-09 Badlop
+
+ * src/ejabberd_service.erl: Fix XEP-0114 compliance: define xmlns
+ in header of error response; include in response the JID of served
+ component not server (thanks to Sergei Golovan)(EJAB-717)
+
2008-08-06 Jean-Sébastien Pédron
* src/mod_offline.erl, src/mod_offline_odbc.erl, src/mod_echo.erl,
@@ -65,11 +193,131 @@
src/mod_echo.erl, src/mod_offline.erl, src/mod_roster.erl,
src/mod_vcard.erl: Update to use the new names used in exmpp_jid.
+2008-08-04 Jerome Sautret
+
+ * src/odbc/ejabberd_odbc.erl: Restart the database connection when
+ it's lost or it reaches timeout with MySQL. Set transaction isolation level
+ to SERIALIZABLE when establishing connection to MySQL.
+
+2008-08-01 Badlop
+
+ * doc/release_notes_2.0.2.txt: Added for ejabberd 2.0.2-beta1
+
+ * src/web/ejabberd_http.erl: Temporary solution for check of
+ packet size when HTTPS (EJAB-611)(EJAB-507)(EJAB-574)
+
+2008-07-31 Badlop
+
+ * src/msgs/uk.msg: Fix: each string in a single line
+ * src/msgs/wa.msg: Likewise
+
+ * src/msgs/es.msg: Fix typo
+ * src/msgs/gl.msg: Likewise
+ * src/msgs/pt-br.msg: Likewise
+
+ * src/msgs/zh.msg: Fix some translations (thanks to Zhan Caibao)
+
+ * src/msgs/ca.msg: Updated (thanks to Badlop)
+ * src/msgs/cs.msg: Updated (thanks to Lukas Poliuvk)
+ * src/msgs/de.msg: Updated (thanks to Nikolaus Polak)
+ * src/msgs/es.msg: Updated (thanks to Badlop)
+ * src/msgs/fr.msg: Updated (thanks to Christophe Romain)
+ * src/msgs/it.msg: Updated (thanks to Luca Brivio)
+ * src/msgs/ja.msg: Updated (thanks to Tsukasa Hamano)
+ * src/msgs/no.msg: Updated (thanks to Stian B. Barmen)
+ * src/msgs/pl.msg: Updated (thanks to Zbyszek Zolkiewski)
+ * src/msgs/pt-br.msg: Updated (thanks to Otavio Fernandes)
+ * src/msgs/ru.msg: Updated (thanks to Evgeniy Khramtsov)
+ * src/msgs/tr.msg: Updated (thanks to Doruk Fisek)
+ * src/msgs/uk.msg: Updated (thanks to Ruslan Rakhmanin)
+ * src/msgs/wa.msg: Updated (thanks to Pablo Saratxaga)
+ * src/msgs/zh.msg: Updated (thanks to Shelley Shyan)
+
+ * README: Update location where mnesia, ebin and priv directories
+ are installed; install headers and doc (EJAB-696)
+
+ * doc/guide.tex: Update Process-one name to ProcessOne (EJAB-708)
+ * doc/guide.html: Likewise
+ * doc/api/overview.edoc: Likewise
+ * src/*/*.erl: Likewise
+ * src/*/*.hrl: Likewise
+ * src/*/*.c: Likewise
+ * src/odbc/*.sql: Likewise
+
+2008-07-30 Badlop
+
+ * src/mod_muc/mod_muc_room.erl: Support Reasons for all
+ affiliation and role changes (EJAB-306)
+
+ * src/gen_mod.erl: When ejabberd is kindly stopped, don't forget
+ modules configuration (EJAB-706)
+ * src/ejabberd_app.erl: Likewise
+
+2008-07-28 Badlop
+
+ * doc/guide.tex: Document how to get error message when ejabberd
+ crash dumps at start (EJAB-660)
+ * doc/guide.html: Likewise
+
2008-07-25 Jean-Sébastien Pédron
* src/adhoc.erl, src/mod_configure.erl, src/mod_announce.erl,
src/mod_adhoc.erl, src/gen_iq_handler.erl: Convert to exmpp.
+2008-07-25 Christophe Romain
+
+ * src/mod_pubsub/mod_pubsub.erl: Speedup startup with many pubsub
+ nodes (EJAB-669)
+ * src/mod_pubsub/nodetree_default.erl: Likewise
+
+2008-07-24 Badlop
+
+ * doc/guide.tex: Include example PAM configuration file
+ ejabberd.pam (thanks to Evgeniy Khramtsov)(EJAB-704)
+ * doc/guide.html: Likewise
+
+ * src/mod_proxy65/mod_proxy65_lib.erl: Send protocol compliant
+ SOCKS5 reply; this breaks support of uncompliant Psi<0.10 (thanks
+ to Felix Geyer)(EJAB-632)
+ * src/mod_proxy65/mod_proxy65_stream.erl: Likewise
+
+ * src/mod_register.erl: When a registration is blocked due to IP
+ limitation, return description in error stanza (EJAB-692)
+
+2008-07-24 Christophe Romain
+
+ * src/mod_pubsub/mod_pubsub.erl: Allow owner to subscribe/get its own
+ node (EJAB-705)
+
+2008-07-24 Badlop
+
+ * doc/guide.tex: Document room options allow_visitor_nickchange
+ and allow_visitor_status (EJAB-624)
+ * doc/guide.html: Likewise
+
+2008-07-23 Geoff Cant
+
+ * src/mod_muc/mod_muc_room.erl: new room options,
+ allow_visitor_presence and allow_visitor_nickchange to
+ block/enable visitors to broadcast presence updates to the room
+ (EJAB-624).
+ * src/mod_muc/mod_muc_room.erl: renaming allow_visitor_presence to
+ allow_visitor_status and altering effect (when false) to remove
+ custom status tags in presence broadcasts to muc rooms by
+ visitors.
+
+2008-07-23 Christophe Romain
+
+ * src/mod_pubsub/mod_pubsub.erl: remove_user hook removes
+ subscriptions (EJAB-684), send the last published and not the
+ first published item (EJAB-675), remove the pubsub/nodes tree,
+ subscribing to a node sends only last items (EJAB-700)
+ * src/mod_pubsub/node_pep.erl: added acl and jid match on node
+ creation permission (EJAB-663)
+ * src/mod_pubsub/node_default.erl: fix node creation permission
+ issue for service
+ * src/mod_pubsub/node_zoo.erl: Likewise
+
2008-07-22 Jean-Sébastien Pédron
* src/mod_disco.erl, src/gen_iq_handler.erl: Convert to exmpp.
@@ -80,6 +328,15 @@
* src/ejabberd_local.erl (process_iq_reply): IQ handler are now always
called with arguments in the new format.
+2008-07-22 Badlop
+
+ * src/ejabberd_config.erl: If syntax mistake in config file, show
+ specific error message (EJAB-616)
+
+2008-07-22 Alexey Shchepin
+
+ * src/odbc/odbc_queries.erl: Fixed a typo
+
2008-07-21 Jean-Sébastien Pédron
* src/gen_iq_handler.erl: Prepare gen_iq_handler to pass arguments in
@@ -94,6 +351,15 @@
* src/jlib.erl: Add support for #xmlel to parse_xdata_submit/1 and
friends. This fixes the user search in mod_vcard.
+2008-07-03 Jerome Sautret
+
+ * src/ejabberd_ctl.erl: Call reopen_log_hook for each virtual host.
+
+2008-07-17 Badlop
+
+ * src/mod_muc/mod_muc_room.erl: Fix to allow a server admin to add
+ himself as owner of a room (EJAB-687)
+
2008-07-17 Jean-Sébastien Pédron
Merge revisions from 1444 to revision 1457 from trunk.
@@ -243,7 +509,7 @@
automatically (EJAB-407)
* src/mod_roster.erl: Likewise
-
+
* src/mod_muc/mod_muc_log.erl: Fix XHTML compliance: ensure some
language is set, include ID attribute in each message, add
microseconds to ensure unique value (EJAB-497)
diff --git a/README b/README
index df5c68281..e798e9095 100644
--- a/README
+++ b/README
@@ -30,9 +30,11 @@ To install ejabberd, run this command with system administrator rights
sudo make install
These commands will:
- - Install a startup script: /sbin/ejabberdctl
- - Install ejabberd in /var/lib/ejabberd/
- Install the configuration files in /etc/ejabberd/
+ - Install ejabberd binary, header and runtime files in /lib/ejabberd/
+ - Install the administration script: /sbin/ejabberdctl
+ - Install ejabberd documentation in /share/doc/ejabberd/
+ - Create a spool directory: /var/lib/ejabberd/
- Create a directory for log files: /var/log/ejabberd/
diff --git a/contrib/ejabberd-modules.repo b/contrib/ejabberd-modules.repo
index d25d350e0..a38715e90 100644
--- a/contrib/ejabberd-modules.repo
+++ b/contrib/ejabberd-modules.repo
@@ -1,5 +1,5 @@
% List of ejabberd-modules to add for ejabberd packaging (source archive and installer)
%
% HTTP-binding:
-https://svn.process-one.net/ejabberd-modules/http_bind/tags/ejabberd-2.0.0-beta1
-https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/tags/ejabberd-2.0.0-beta1
+https://svn.process-one.net/ejabberd-modules/http_bind/trunk
+https://svn.process-one.net/ejabberd-modules/mod_http_fileserver/trunk
diff --git a/contrib/extract_translations/extract_translations.erl b/contrib/extract_translations/extract_translations.erl
index 5c727e785..1f38cd08e 100644
--- a/contrib/extract_translations/extract_translations.erl
+++ b/contrib/extract_translations/extract_translations.erl
@@ -20,9 +20,14 @@
start() ->
ets:new(translations, [named_table, public]),
+ ets:new(translations_obsolete, [named_table, public]),
ets:new(files, [named_table, public]),
ets:new(vars, [named_table, public]),
case init:get_plain_arguments() of
+ ["-srcmsg2po", Dir, File] ->
+ print_po_header(File),
+ Status = process(Dir, File, srcmsg2po),
+ halt(Status);
["-unused", Dir, File] ->
Status = process(Dir, File, unused),
halt(Status);
@@ -50,7 +55,11 @@ process(Dir, File, Used) ->
unused ->
ets:foldl(fun({Key, _}, _) ->
io:format("~p~n", [Key])
- end, ok, translations);
+ end, ok, translations);
+ srcmsg2po ->
+ ets:foldl(fun({Key, Trans}, _) ->
+ print_translation_obsolete(Key, Trans)
+ end, ok, translations_obsolete);
_ ->
ok
end,
@@ -74,46 +83,52 @@ parse_form(Dir, File, Form, Used) ->
{call,
_,
{remote, _, {atom, _, translate}, {atom, _, translate}},
- [_, {string, _, Str}]
+ [_, {string, Line, Str}]
} ->
- process_string(Dir, File, Str, Used);
+ process_string(Dir, File, Line, Str, Used);
{call,
_,
{remote, _, {atom, _, translate}, {atom, _, translate}},
[_, {var, _, Name}]
} ->
case ets:lookup(vars, Name) of
- [{_Name, Value}] ->
- process_string(Dir, File, Value, Used);
+ [{_Name, Value, Line}] ->
+ process_string(Dir, File, Line, Value, Used);
_ ->
ok
end;
{match,
_,
{var, _, Name},
- {string, _, Value}
+ {string, Line, Value}
} ->
- ets:insert(vars, {Name, Value});
+ ets:insert(vars, {Name, Value, Line});
L when is_list(L) ->
lists:foreach(
fun(F) ->
- parse_form(Dir, File, F, Used)
+ parse_form(Dir, File, F, Used)
end, L);
T when is_tuple(T) ->
lists:foreach(
fun(F) ->
- parse_form(Dir, File, F, Used)
+ parse_form(Dir, File, F, Used)
end, tuple_to_list(T));
_ ->
ok
end.
-process_string(_Dir, File, Str, Used) ->
+process_string(_Dir, _File, _Line, "", _Used) ->
+ ok;
+
+process_string(_Dir, File, Line, Str, Used) ->
case {ets:lookup(translations, Str), Used} of
{[{_Key, _Trans}], unused} ->
ets:delete(translations, Str);
{[{_Key, _Trans}], used} ->
ok;
+ {[{_Key, Trans}], srcmsg2po} ->
+ ets:delete(translations_obsolete, Str),
+ print_translation(File, Line, Str, Trans);
{_, used} ->
case ets:lookup(files, File) of
[{_}] ->
@@ -127,6 +142,15 @@ process_string(_Dir, File, Str, Used) ->
_ -> io:format("{~p, \"\"}.~n", [Str])
end,
ets:insert(translations, {Str, ""});
+ {_, srcmsg2po} ->
+ case ets:lookup(files, File) of
+ [{_}] ->
+ ok;
+ _ ->
+ ets:insert(files, {File})
+ end,
+ ets:insert(translations, {Str, ""}),
+ print_translation(File, Line, Str, "");
_ ->
ok
end.
@@ -140,7 +164,8 @@ load_file(File) ->
"" ->
ok;
_ ->
- ets:insert(translations, {Orig, Trans})
+ ets:insert(translations, {Orig, Trans}),
+ ets:insert(translations_obsolete, {Orig, Trans})
end
end, Terms);
Err ->
@@ -191,3 +216,77 @@ print_usage() ->
" extract_translations . ./msgs/ru.msg~n"
).
+
+%%%
+%%% Gettext
+%%%
+
+print_po_header(File) ->
+ MsgProps = get_msg_header_props(File),
+ {Language, [LastT | AddT]} = prepare_props(MsgProps),
+ application:load(ejabberd),
+ {ok, Version} = application:get_key(ejabberd, vsn),
+ print_po_header(Version, Language, LastT, AddT).
+
+get_msg_header_props(File) ->
+ {ok, F} = file:open(File, [read]),
+ Lines = get_msg_header_props(F, []),
+ file:close(F),
+ Lines.
+
+get_msg_header_props(F, Lines) ->
+ String = io:get_line(F, ""),
+ case io_lib:fread("% ", String) of
+ {ok, [], RemString} ->
+ case io_lib:fread("~s", RemString) of
+ {ok, [Key], Value} when Value /= "\n" ->
+ %% The first character in Value is a blankspace:
+ %% And the last characters are 'slash n'
+ ValueClean = string:substr(Value, 2, string:len(Value)-2),
+ get_msg_header_props(F, Lines ++ [{Key, ValueClean}]);
+ _ ->
+ get_msg_header_props(F, Lines)
+ end;
+ _ ->
+ Lines
+ end.
+
+prepare_props(MsgProps) ->
+ Language = proplists:get_value("Language:", MsgProps),
+ Authors = proplists:get_all_values("Author:", MsgProps),
+ {Language, Authors}.
+
+print_po_header(Version, Language, LastTranslator, AdditionalTranslatorsList) ->
+ AdditionalTranslatorsString = build_additional_translators(AdditionalTranslatorsList),
+ HeaderString =
+ "msgid \"\"\n"
+ "msgstr \"\"\n"
+ "\"Project-Id-Version: " ++ Version ++ "\\n\"\n"
+ ++ "\"X-Language: " ++ Language ++ "\\n\"\n"
+ "\"Last-Translator: " ++ LastTranslator ++ "\\n\"\n"
+ ++ AdditionalTranslatorsString ++
+ "\"MIME-Version: 1.0\\n\"\n"
+ "\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
+ "\"Content-Transfer-Encoding: 8bit\\n\"\n",
+ io:format("~s~n", [HeaderString]).
+
+build_additional_translators(List) ->
+ lists:foldl(
+ fun(T, Str) ->
+ Str ++ "\"X-Additional-Translator: " ++ T ++ "\\n\"\n"
+ end,
+ "",
+ List).
+
+print_translation(File, Line, Str, StrT) ->
+ {ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
+ {ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
+ io:format("#: ~s:~p~nmsgid \"~s\"~nmsgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
+
+print_translation_obsolete(Str, StrT) ->
+ File = "unknown.erl",
+ Line = 1,
+ {ok, StrQ, _} = regexp:gsub(Str, "\"", "\\\""),
+ {ok, StrTQ, _} = regexp:gsub(StrT, "\"", "\\\""),
+ io:format("#: ~s:~p~n#~~ msgid \"~s\"~n#~~ msgstr \"~s\"~n~n", [File, Line, StrQ, StrTQ]).
+
diff --git a/contrib/extract_translations/prepare-translation.sh b/contrib/extract_translations/prepare-translation.sh
index 2fd895bf5..d1c435fbe 100755
--- a/contrib/extract_translations/prepare-translation.sh
+++ b/contrib/extract_translations/prepare-translation.sh
@@ -8,10 +8,10 @@ prepare_dirs ()
# Where is Erlang binary
ERL=`which erl`
- EJA_DIR=`pwd`/../..
+ EJA_DIR=`pwd`/..
EXTRACT_DIR=$EJA_DIR/contrib/extract_translations/
- EXTRACT_ERL=extract_translations.erl
- EXTRACT_BEAM=extract_translations.beam
+ EXTRACT_ERL=$EXTRACT_DIR/extract_translations.erl
+ EXTRACT_BEAM=$EXTRACT_DIR/extract_translations.beam
SRC_DIR=$EJA_DIR/src
MSGS_DIR=$SRC_DIR/msgs
@@ -22,9 +22,7 @@ prepare_dirs ()
if !([[ -x $EXTRACT_BEAM ]])
then
- echo -n "Compiling extract_translations.erl: "
sh -c "cd $EXTRACT_DIR; $ERL -compile $EXTRACT_ERL"
- echo "ok"
fi
}
@@ -140,6 +138,116 @@ find_unused_full ()
cd ..
}
+extract_lang_srcmsg2po ()
+{
+ LANG_CODE=$1
+ MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
+ PO_PATH=$MSGS_DIR/$LANG_CODE.po
+
+ $ERL -pa $EXTRACT_DIR -pa $SRC_DIR -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$PO_PATH.1
+ sed -e 's/ \[\]$/ \"\"/g;' $PO_PATH.1 > $PO_PATH.2
+ msguniq --sort-by-file $PO_PATH.2 --output-file=$PO_PATH
+
+ rm $PO_PATH.*
+}
+
+extract_lang_src2pot ()
+{
+ LANG_CODE=ejabberd
+ MSGS_PATH=$MSGS_DIR/$LANG_CODE.msg
+ POT_PATH=$MSGS_DIR/$LANG_CODE.pot
+
+ echo -n "" >$MSGS_PATH
+ echo "% Language: Language Name" >>$MSGS_PATH
+ echo "% Author: Translator name and contact method" >>$MSGS_PATH
+ echo "" >>$MSGS_PATH
+
+ cd $SRC_DIR
+ $ERL -pa $EXTRACT_DIR -pa $SRC_DIR -noinput -noshell -s extract_translations -s init stop -extra -srcmsg2po . $MSGS_PATH >$POT_PATH.1
+ sed -e 's/ \[\]$/ \"\"/g;' $POT_PATH.1 > $POT_PATH.2
+ msguniq --sort-by-file $POT_PATH.2 --output-file=$POT_PATH
+
+ rm $POT_PATH.*
+ rm $MSGS_PATH
+}
+
+extract_lang_popot2po ()
+{
+ LANG_CODE=$1
+ PO_PATH=$MSGS_DIR/$LANG_CODE.po
+ POT_PATH=$MSGS_DIR/ejabberd.pot
+
+ msgmerge $PO_PATH $POT_PATH >$PO_PATH.translate 2>/dev/null
+ mv $PO_PATH.translate $PO_PATH
+}
+
+extract_lang_po2msg ()
+{
+ LANG_CODE=$1
+ PO_PATH=$LANG_CODE.po
+ MS_PATH=$PO_PATH.ms
+ MSGID_PATH=$PO_PATH.msgid
+ MSGSTR_PATH=$PO_PATH.msgstr
+ MSGS_PATH=$LANG_CODE.msg
+
+ cd $MSGS_DIR
+
+ # Check PO has correct ~
+ # Let's convert to C format so we can use msgfmt
+ PO_TEMP=$LANG_CODE.po.temp
+ cat $PO_PATH | sed 's/%/perc/g' | sed 's/~/%/g' | sed 's/#:.*/#, c-format/g' >$PO_TEMP
+ msgfmt $PO_TEMP --check-format
+ result=$?
+ rm $PO_TEMP
+ if [ $result -ne 0 ] ; then
+ exit 1
+ fi
+
+ msgattrib $PO_PATH --translated --no-fuzzy --no-obsolete --no-location --no-wrap | grep "^msg" | tail --lines=+3 >$MS_PATH
+ grep "^msgid" $PO_PATH.ms | sed 's/^msgid //g' >$MSGID_PATH
+ grep "^msgstr" $PO_PATH.ms | sed 's/^msgstr //g' >$MSGSTR_PATH
+ paste $MSGID_PATH $MSGSTR_PATH --delimiter=, | awk '{print "{" $0 "}."}' | sort -g >$MSGS_PATH
+
+ rm $MS_PATH
+ rm $MSGID_PATH
+ rm $MSGSTR_PATH
+}
+
+extract_lang_updateall ()
+{
+ echo "Generating POT"
+ extract_lang_src2pot
+
+ cd $MSGS_DIR
+ echo ""
+ echo -e "File Missing Language Last translator"
+ echo -e "---- ------- -------- ---------------"
+ for i in *.msg; do
+ LANG_CODE=${i%.msg}
+ echo -n $LANG_CODE | awk '{printf "%-6s", $1 }'
+
+ # Convert old MSG file to PO
+ PO=$LANG_CODE.po
+ [ -f $PO ] || extract_lang_srcmsg2po $LANG_CODE
+
+ extract_lang_popot2po $LANG_CODE
+ extract_lang_po2msg $LANG_CODE
+
+ MISSING=`msgfmt --statistics $PO 2>&1 | awk '{printf "%5s", $4 }'`
+ echo -n " $MISSING"
+
+ LANGUAGE=`grep "Language:" $PO | sed 's/\"X-Language: //g' | sed 's/\\\\n\"//g' | awk '{printf "%-12s", $1}'`
+ echo -n " $LANGUAGE"
+
+ LASTAUTH=`grep "Last-Translator" $PO | sed 's/\"Last-Translator: //g' | sed 's/\\\\n\"//g'`
+ echo " $LASTAUTH"
+ done
+ echo ""
+ rm messages.mo
+
+ cd ..
+}
+
translation_instructions ()
{
echo ""
@@ -158,34 +266,56 @@ translation_instructions ()
echo " $MSGS_PATH"
}
+prepare_dirs
case "$1" in
- -help)
- echo "Options:"
- echo " -langall"
- echo " -lang LANGUAGE_FILE"
- echo ""
- echo "Example:"
- echo " ./prepare-translation.sh -lang es.msg"
- exit 0
- ;;
-lang)
LANGU=$2
- prepare_dirs
extract_lang $LANGU
shift
shift
;;
-langall)
- prepare_dirs
extract_lang_all
shift
;;
- *)
- echo "unknown option: '$1 $2'"
+ -srcmsg2po)
+ LANG_CODE=$2
+ extract_lang_srcmsg2po $LANG_CODE
shift
shift
;;
+ -popot2po)
+ LANG_CODE=$2
+ extract_lang_popot2po $LANG_CODE
+ shift
+ shift
+ ;;
+ -src2pot)
+ extract_lang_src2pot
+ shift
+ ;;
+ -po2msg)
+ LANG_CODE=$2
+ extract_lang_po2msg $LANG_CODE
+ shift
+ shift
+ ;;
+ -updateall)
+ extract_lang_updateall
+ shift
+ ;;
+ *)
+ echo "Options:"
+ echo " -langall"
+ echo " -lang LANGUAGE_FILE"
+ echo " -srcmsg2po LANGUAGE Construct .msg file using source code to PO file"
+ echo " -src2pot Generate template POT file from source code"
+ echo " -popot2po LANGUAGE Update PO file with template POT file"
+ echo " -po2msg LANGUAGE Export PO file to MSG file"
+ echo " -updateall Generate POT and update all PO"
+ echo ""
+ echo "Example:"
+ echo " ./prepare-translation.sh -lang es.msg"
+ exit 0
+ ;;
esac
-
-echo ""
-echo "End."
diff --git a/doc/api/overview.edoc b/doc/api/overview.edoc
index 55f7b1f68..89815c8c0 100644
--- a/doc/api/overview.edoc
+++ b/doc/api/overview.edoc
@@ -1,6 +1,6 @@
@author Mickael Remond
[http://www.process-one.net/]
-@copyright 2007 Process-one
+@copyright 2007 ProcessOne
@version {@vsn}, {@date} {@time}
@title ejabberd Development API Documentation
diff --git a/doc/guide.html b/doc/guide.html
index 02ea12132..97e0f9248 100644
--- a/doc/guide.html
+++ b/doc/guide.html
@@ -272,9 +272,9 @@ Support for virtual hosting.
Probably the easiest way to install an ejabberd instant messaging server
-is using the binary installer published by Process-one.
+is using the binary installer published by ProcessOne.
The binary installers of released ejabberd versions
-are available in the Process-one ejabberd downloads page:
+are available in the ProcessOne ejabberd downloads page:
http://www.process-one.net/en/ejabberd/downloads
The installer will deploy and configure a full featured ejabberd
server and does not require any extra dependencies.
In *nix systems, remember to set executable the binary installer before starting it. For example:
chmod +x ejabberd-2.0.0_1-linux-x86-installer.bin
@@ -290,7 +290,19 @@ go to the Windows service settings and set ejabberd to be automatically started.
Note that the Windows service is a feature still in development,
and for example it doesn’t read the file ejabberdctl.cfg.On a *nix system, if you want ejabberd to be started as daemon at boot time,
copy ejabberd.init from the ’bin’ directory to something like /etc/init.d/ejabberd
-(depending on your distribution) and call /etc/inid.d/ejabberd start to start it.
The ejabberdctl administration script is included in the bin directory.
+(depending on your distribution) and call /etc/inid.d/ejabberd start to start it.
If ejabberd doesn’t start correctly in Windows,
+try to start it using the shortcut in desktop or start menu.
+If the window shows error 14001, the solution is to install:
+"Microsoft Visual C++ 2005 SP1 Redistributable Package".
+You can download it from
+www.microsoft.com.
+Then uninstall ejabberd and install it again.
If ejabberd doesn’t start correctly and a crash dump is generated,
+there was a severe problem.
+You can try starting ejabberd with
+the script bin/live.bat in Windows,
+or with the command bin/ejabberdctl live in other Operating Systems.
+This way you see the error message provided by Erlang
+and can identify what is exactly the problem.
The ejabberdctl administration script is included in the bin directory.
Please refer to the section 4.1 for details about ejabberdctl,
and configurable options to fine tune the Erlang runtime system.
Some Operating Systems provide a specific ejabberd package adapted to
@@ -324,7 +336,7 @@ GNU Make
GNU Iconv 1.8 or higher, for the IRC Transport (mod_irc). Optional. Not needed on systems with GNU Libc.
-
Released versions of ejabberd are available in the Process-one ejabberd downloads page:
+
Released versions of ejabberd are available in the ProcessOne ejabberd downloads page:
http://www.process-one.net/en/ejabberd/downloads
Alternatively, the latest development version can be retrieved from the Subversion repository using this command:
svn co http://svn.process-one.net/ejabberd/trunk ejabberd
@@ -405,7 +417,12 @@ Node ejabberd@localhost is started. Status: started
ejabberd is running
ejabberdctl stop
-
Please refer to the section 4.1 for details about ejabberdctl,
+
If ejabberd doesn’t start correctly and a crash dump is generated,
+there was a severe problem.
+You can try starting ejabberd with
+the command ejabberdctl live
+to see the error message provided by Erlang
+and can identify what is exactly the problem.
Please refer to the section 4.1 for details about ejabberdctl,
and configurable options to fine tune the Erlang runtime system.
The command to compile ejabberd in BSD systems is:
@@ -976,8 +993,12 @@ version, you can kill(1) epam process periodically to reduce i
consumption: ejabberd will restart this process immediately.
epam program tries to turn off delays on authentication failures.
However, some PAM modules ignore this behavior and rely on their own configuration options.
-The example configuration file ejabberd.pam shows how to turn off delays in
-pam_unix.so module. It is not a ready to use configuration file: you must use it
+You can create a configuration file ejabberd.pam.
+This example shows how to turn off delays in pam_unix.so module:
+#%PAM-1.0
+auth sufficient pam_unix.so likeauth nullok nodelay
+account sufficient pam_unix.so
+
That is not a ready to use configuration file: you must use it
as a hint when building your own PAM configuration instead. Note that if you want to disable
delays on authentication failures in the PAM configuration file, you have to restrict access
to this file, so a malicious user can’t use your configuration to perform brute-force
@@ -1113,7 +1134,7 @@ To define a shaper named ‘normal’ with traffic speed limi
The option language defines the default language of server strings that
-can be seen by Jabber clients. If a Jabber client do not support
+can be seen by Jabber clients. If a Jabber client does not support
xml:lang, the specified language is used. The default value is
en. In order to take effect there must be a translation file
<language>.msg in ejabberd’s msgs directory.
Examples:
@@ -1122,7 +1143,7 @@ To set Russian as default language:
{language, "ru"}.
To set Spanish as default language:
{language, "es"}.
-
+Appendix A provides more details about internationalization and localization.
The option include_config_file in a configuration file instructs ejabberd to include other configuration files immediately.
The basic usage is:
{include_config_file, <filename>}.
@@ -1422,7 +1443,9 @@ module loaded!
ejabberd has built-in LDAP support. You can authenticate users against LDAP
server and use LDAP directory as vCard storage. Shared rosters are not supported
-yet.
+yet.Note that ejabberd treats LDAP as a read-only storage:
+it is possible to consult data, but not possible to
+create accounts, change password or edit vCard that is stored in LDAP.
Parameters:
-
ldap_servers
- List of IP addresses or DNS names of your
@@ -1928,23 +1951,22 @@ connected user was last active on the server, or to query the uptime of the
the processing discipline for Last activity (jabber:iq:last) IQ queries (see section 3.3.2).
-
With this module enabled, your server will support Multi-User Chat
-(XEP-0045). End users will be able to join text conferences.
Some of the features of Multi-User Chat:
+
This module provides a Multi-User Chat (XEP-0045) service.
+Users can discover existing rooms, join or create them.
+Occupants of a room can chat in public or have private chats.
Some of the features of Multi-User Chat:
-
-Sending private messages to room participants.
-
- Inviting users.
-
- Setting a conference topic.
+Sending public and private messages to room occupants.
+
- Inviting other users to a room.
+
- Setting a room subject.
- Creating password protected rooms.
-
- Kicking and banning participants.
+
- Kicking and banning occupants.
The MUC service allows any Jabber ID to register a nickname,
so nobody else can use that nickname in any room in the MUC service.
To register a nickname, open the Service Discovery in your
-Jabber client and Register in the MUC service.
The MUC service allows the service administrator to send a message
-to all existing chatrooms.
-To do so, send the message to the Jabber ID of the MUC service.
This module supports clustering and load
+Jabber client and register in the MUC service.
This module supports clustering and load
balancing. One module can be started per cluster node. Rooms are
distributed at creation time on all available MUC module
-instances. The multi-user chat module is clustered but the room
+instances. The multi-user chat module is clustered but the rooms
themselves are not clustered nor fault-tolerant: if the node managing a
set of rooms goes down, the rooms disappear and they will be recreated
on an available node on first connection attempt.
Module options:
@@ -1956,19 +1978,19 @@ hostname of the virtual host with the prefix ‘conference.’
is replaced at start time with the real virtual host name.
access You can specify who is allowed to use
-the Multi-User Chat service (by default, everyone is allowed to use it).
+the Multi-User Chat service. By default everyone is allowed to use it.
access_create To configure who is
allowed to create new rooms at the Multi-User Chat service, this option
-can be used (by default, everybody is allowed to create rooms).
+can be used. By default everybody is allowed to create rooms.
access_persistent To configure who is
-allowed to modify the ’persistent’ chatroom option
-(by default, everybody is allowed to modify that option).
+allowed to modify the ’persistent’ room option.
+By default everybody is allowed to modify that option.
access_admin This option specifies
-who is allowed to administrate the Multi-User Chat service (the default
+who is allowed to administrate the Multi-User Chat service. The default
value is none, which means that only the room creator can
-administer his room).
+administer his room.
The administrators can send a normal message to the service JID,
-and it will be shown in every active room as a service message.
+and it will be shown in all active rooms as a service message.
The administrators can send a groupchat message to the JID of an active room,
and the message will be shown in the room as a service message.
history_size A small history of
@@ -1978,44 +2000,43 @@ to keep and send to users joining the room. The value is an
integer. Setting the value to 0 disables the history feature
and, as a result, nothing is kept in memory. The default value is
20. This value is global and thus affects all rooms on the
-server.
+service.
max_users This option defines at
-the server level, the maximum number of users allowed per MUC
+the service level, the maximum number of users allowed per
room. It can be lowered in each room configuration but cannot be
-increased in individual MUC room configuration. The default value is
+increased in individual room configuration. The default value is
200.
max_users_admin_threshold
This option defines the
-number of MUC admins or owners to allow to enter the room even if
-the maximum number of allowed users is reached. The default limits
-is 5. In most cases this default value is the best setting.
+number of service admins or room owners allowed to enter the room when
+the maximum number of allowed occupants was reached. The default limit
+is 5.
max_user_conferences
- This option define the maximum
-number of chat room any given user will be able to join. The default
+ This option defines the maximum
+number of rooms that any given user can join. The default value
is 10. This option is used to prevent possible abuses. Note that
-this is a soft limits: Some users can sometime join more conferences
+this is a soft limit: some users can sometimes join more conferences
in cluster configurations.
min_message_interval
This option defines the minimum interval between two messages send
-by a user in seconds. This option is global and valid for all chat
+by an occupant in seconds. This option is global and valid for all
rooms. A decimal value can be used. When this option is not defined,
message rate is not limited. This feature can be used to protect a
-MUC service from users abuses and limit number of messages that will
+MUC service from occupant abuses and limit number of messages that will
be broadcasted by the service. A good value for this minimum message
-interval is 0.4 second. If a user tries to send messages faster, an
-error is send back explaining that the message have been discarded
+interval is 0.4 second. If an occupant tries to send messages faster, an
+error is send back explaining that the message has been discarded
and describing the reason why the message is not acceptable.
min_presence_interval
This option defines the
-minimum of time between presence changes coming from a given user in
-seconds. This option is global and valid for all chat rooms. A
+minimum of time between presence changes coming from a given occupant in
+seconds. This option is global and valid for all rooms. A
decimal value can be used. When this option is not defined, no
restriction is applied. This option can be used to protect a MUC
-service for users abuses, as fastly changing a user presence will
-result in possible large presence packet broadcast. If a user tries
+service for occupants abuses. If an occupant tries
to change its presence more often than the specified interval, the
presence is cached by ejabberd and only the last presence is
-broadcasted to all users in the room after expiration of the
+broadcasted to all occupants in the room after expiration of the
interval delay. Intermediate presence packets are silently
discarded. A good value for this option is 4 seconds.
default_room_options
@@ -2028,6 +2049,12 @@ The available room options and the default values are:
{allow_private_messages, true} Occupants can send private messages to other occupants.
{allow_query_users, true} Occupants can send IQ queries to other occupants.
{allow_user_invites, false} Allow occupants to send invitations.
+{allow_visitor_nickchange, true} Allow visitors to
+change nickname.
+{allow_visitor_status, true} Allow visitors to send
+status text in presence updates. If disallowed, the status
+text is stripped before broadcasting the presence update to all
+the room occupants.
{anonymous, true} Occupants are allowed to see the real JIDs of other occupants.
{logging, false} The public messages are logged using mod_muc_log.
{max_users, 200} Maximum number of occupants in the room.
@@ -2097,8 +2124,8 @@ and the default value of 20 history messages will be send to the users.
{access_admin, muc_admins}]},
...
]}.
-In the following example, MUC anti abuse options are used. A
-user cannot send more than one message every 0.4 seconds and cannot
+In the following example, MUC anti abuse options are used. An
+occupant cannot send more than one message every 0.4 seconds and cannot
change its presence more than once every 4 seconds. No ACLs are
defined, but some user restriction could be added as well:{modules,
[
@@ -2108,7 +2135,7 @@ defined, but some user restriction could be added as well:
...
]}.
This example shows how to use default_room_options to make sure
-newly created chatrooms have by default those options.
+the newly created rooms have by default those options.
{modules,
[
...
@@ -2128,17 +2155,17 @@ newly created chatrooms have by default those options.
]}.
-
This module enables optional logging of Multi-User Chat (MUC) conversations to
-HTML. Once you enable this module, users can join a chatroom using a MUC capable
+
This module enables optional logging of Multi-User Chat (MUC) public conversations to
+HTML. Once you enable this module, users can join a room using a MUC capable
Jabber client, and if they have enough privileges, they can request the
-configuration form in which they can set the option to enable chatroom logging.
Features:
+configuration form in which they can set the option to enable room logging.
Features:
-
-Chatroom details are added on top of each page: room title, JID,
+Room details are added on top of each page: room title, JID,
author, subject and configuration.
-
-The room JID in the generated HTML is a link to join the chatroom (using
+The room JID in the generated HTML is a link to join the room (using
XMPP URI).
-
- Subject and chatroom configuration changes are tracked and displayed.
+
- Subject and room configuration changes are tracked and displayed.
- Joins, leaves, nick changes, kicks, bans and ‘/me’ are tracked and
displayed, including the reason if available.
- Generated HTML files are XHTML 1.0 Transitional and CSS compliant.
@@ -2151,7 +2178,7 @@ displayed, including the reason if available.
Options:
-
access_log
-
-This option restricts which users are allowed to enable or disable chatroom
+This option restricts which occupants are allowed to enable or disable room
logging. The default value is muc_admin. Note for this default setting
you need to have an access rule for muc_admin in order to take effect.
- cssfile
-
@@ -2161,34 +2188,46 @@ file or if they need to use the embedded CSS file. Allowed values are
include the embedded CSS code. With the latter, you can specify the URL of the
custom CSS file (for example: ‘http://example.com/my.css’). The default value
is false.
+
- dirname
-
+Allows to configure the name of the room directory.
+Allowed values are room_jid and room_name.
+With the first value, the room directory name will be the full room JID.
+With the latter, the room directory name will be only the room name,
+not including the MUC service name.
+The default value is room_jid.
- dirtype
-
The type of the created directories can be specified with this option. Allowed
values are subdirs and plain. With the first value,
subdirectories are created for each year and month. With the latter, the
names of the log files contain the full date, and there are no subdirectories.
The default value is subdirs.
+
- file_format
-
+Define the format of the log files:
+html stores in HTML format,
+plaintext stores in plain text.
+The default value is html.
- outdir
-
This option sets the full path to the directory in which the HTML files should
be stored. Make sure the ejabberd daemon user has write access on that
directory. The default value is "www/muc".
-
- timezone
-
-The time zone for the logs is configurable with this option. Allowed values
-are local and universal. With the first value, the local time,
-as reported to Erlang by the operating system, will be used. With the latter,
-GMT/UTC time will be used. The default value is local.
- spam_prevention
-
To prevent spam, the spam_prevention option adds a special attribute
to links that prevent their indexation by search engines. The default value
is true, which mean that nofollow attributes will be added to user
submitted links.
+
- timezone
-
+The time zone for the logs is configurable with this option. Allowed values
+are local and universal. With the first value, the local time,
+as reported to Erlang by the operating system, will be used. With the latter,
+GMT/UTC time will be used. The default value is local.
- top_link
-
With this option you can customize the link on the top right corner of each
log file. The syntax of this option is {"URL", "Text"}. The default
value is {"/", "Home"}.
Examples:
-
-In the first example any chatroom owner can enable logging, and a
-custom CSS file will be used (http://example.com/my.css). Further, the names
+In the first example any room owner can enable logging, and a
+custom CSS file will be used (http://example.com/my.css). The names
of the log files will contain the full date, and there will be no
subdirectories. The log files will be stored in /var/www/muclogs, and the
time zone will be GMT/UTC. Finally, the top link will be
@@ -2202,6 +2241,7 @@ time zone will be GMT/UTC. Finally, the top link will be
{access_log, muc},
{cssfile, "http://example.com/my.css"},
{dirtype, plain},
+ {dirname, room_jid},
{outdir, "/var/www/muclogs"},
{timezone, universal},
{spam_prevention, true},
@@ -2211,7 +2251,7 @@ time zone will be GMT/UTC. Finally, the top link will be
]}.
- In the second example only admin1@example.org and
admin2@example.net can enable logging, and the embedded CSS file will be
-used. Further, the names of the log files will only contain the day (number),
+used. The names of the log files will only contain the day (number),
and there will be subdirectories for each year and month. The log files will
be stored in /var/www/muclogs, and the local time will be used. Finally, the
top link will be the default
<a href="/">Home</a>
.
@@ -2324,8 +2364,8 @@ The simpliest configuration of the module:
{access, proxy65_access, [{allow, proxy_users}, {deny, all}]}.
{acl, admin, {user, "admin", "example.org"}}.
-{shaper, normal, {maxrate, 10240}}. %% 10 Kbytes/sec
-{access, proxy65_shaper, [{none, admin}, {normal, all}]}.
+{shaper, proxyrate, {maxrate, 10240}}. %% 10 Kbytes/sec
+{access, proxy65_shaper, [{none, admin}, {proxyrate, proxy_users}]}.
{modules,
[
@@ -2652,7 +2692,9 @@ and that all virtual hosts will be searched instead of only the current one:
ejabberd can map LDAP attributes to vCard fields. This behaviour is
implemented in the mod_vcard_ldap module. This module does not depend on the
-authentication method (see 3.2.5).
The mod_vcard_ldap module has
+authentication method (see 3.2.5).
Note that ejabberd treats LDAP as a read-only storage:
+it is possible to consult data, but not possible to
+create accounts, change password or edit vCard that is stored in LDAP.
The mod_vcard_ldap module has
its own optional parameters. The first group of parameters has the same
meaning as the top-level LDAP parameters to set the authentication method:
ldap_servers, ldap_port, ldap_rootdn,
@@ -3221,7 +3263,15 @@ so it is important to use it with extremely care.
There are some simple and safe examples in the article
Interconnecting Erlang Nodes
To exit the shell, close the window or press the keys: control+c control+c.
-
All built-in modules support the xml:lang attribute inside IQ queries.
+
The source code of ejabberd supports localization.
+The translators can edit the
+gettext .po files
+using any capable program (KBabel, Lokalize, Poedit...) or a simple text editor.
Then gettext
+is used to extract, update and export those .po files to the .msg format read by ejabberd.
+To perform those management tasks, in the src/ directory execute make translations.
+The translatable strings are extracted from source code to generate the file ejabberd.pot.
+This file is merged with each .po file to produce updated .po files.
+Finally those .po files are exported to .msg files, that have a format easily readable by ejabberd.
All built-in modules support the xml:lang attribute inside IQ queries.
Figure A.1, for example, shows the reply to the following query:
<iq id='5'
to='example.org'
@@ -3262,7 +3312,7 @@ Alexey Shchepin (xmpp:aleksey@jabber.ru- Vsevolod Pelipas (xmpp:vsevoload@jabber.ru)
Ejabberd Installation and Operation Guide.
-Copyright © 2003 — 2008 Process-one
This document is free software; you can redistribute it and/or
+Copyright © 2003 — 2008 ProcessOne
This document is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This document is distributed in the hope that it will be useful,
diff --git a/doc/guide.tex b/doc/guide.tex
index 17cfbeb80..7d5631f9c 100644
--- a/doc/guide.tex
+++ b/doc/guide.tex
@@ -5,7 +5,7 @@
\usepackage{graphics}
\usepackage{hevea}
\usepackage[pdftex,colorlinks,unicode,urlcolor=blue,linkcolor=blue,
- pdftitle=Ejabberd\ Installation\ and\ Operation\ Guide,pdfauthor=Process-one,pdfsubject=ejabberd,pdfkeywords=ejabberd,
+ pdftitle=Ejabberd\ Installation\ and\ Operation\ Guide,pdfauthor=ProcessOne,pdfsubject=ejabberd,pdfkeywords=ejabberd,
pdfpagelabels=false]{hyperref}
\usepackage{makeidx}
%\usepackage{showidx} % Only for verifying the index entries.
@@ -208,9 +208,9 @@ ejabberd Development Team
\makesection{install.binary}{Installing \ejabberd{} with Binary Installer}
Probably the easiest way to install an \ejabberd{} instant messaging server
-is using the binary installer published by Process-one.
+is using the binary installer published by ProcessOne.
The binary installers of released \ejabberd{} versions
-are available in the Process-one \ejabberd{} downloads page:
+are available in the ProcessOne \ejabberd{} downloads page:
\ahrefurl{http://www.process-one.net/en/ejabberd/downloads}
The installer will deploy and configure a full featured \ejabberd{}
@@ -241,6 +241,22 @@ On a *nix system, if you want ejabberd to be started as daemon at boot time,
copy \term{ejabberd.init} from the 'bin' directory to something like \term{/etc/init.d/ejabberd}
(depending on your distribution) and call \term{/etc/inid.d/ejabberd start} to start it.
+If \term{ejabberd} doesn't start correctly in Windows,
+try to start it using the shortcut in desktop or start menu.
+If the window shows error 14001, the solution is to install:
+"Microsoft Visual C++ 2005 SP1 Redistributable Package".
+You can download it from
+\footahref{http://www.microsoft.com/}{www.microsoft.com}.
+Then uninstall \ejabberd{} and install it again.
+
+If \term{ejabberd} doesn't start correctly and a crash dump is generated,
+there was a severe problem.
+You can try starting \term{ejabberd} with
+the script \term{bin/live.bat} in Windows,
+or with the command \term{bin/ejabberdctl live} in other Operating Systems.
+This way you see the error message provided by Erlang
+and can identify what is exactly the problem.
+
The \term{ejabberdctl} administration script is included in the \term{bin} directory.
Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl},
and configurable options to fine tune the Erlang runtime system.
@@ -294,7 +310,7 @@ To compile \ejabberd{} on a `Unix-like' operating system, you need:
\makesubsection{download}{Download Source Code}
\ind{install!download}
-Released versions of \ejabberd{} are available in the Process-one \ejabberd{} downloads page:
+Released versions of \ejabberd{} are available in the ProcessOne \ejabberd{} downloads page:
\ahrefurl{http://www.process-one.net/en/ejabberd/downloads}
\ind{Subversion repository}
@@ -415,6 +431,13 @@ ejabberd is running
ejabberdctl stop
\end{verbatim}
+If \term{ejabberd} doesn't start correctly and a crash dump is generated,
+there was a severe problem.
+You can try starting \term{ejabberd} with
+the command \term{ejabberdctl live}
+to see the error message provided by Erlang
+and can identify what is exactly the problem.
+
Please refer to the section~\ref{ejabberdctl} for details about \term{ejabberdctl},
and configurable options to fine tune the Erlang runtime system.
@@ -727,7 +750,7 @@ The available modules, their purpose and the options allowed by each one are:
Handles incoming s2s connections.\\
Options: \texttt{inet6}, \texttt{ip}, \texttt{max\_stanza\_size}
\titem{\texttt{ejabberd\_service}}
- Interacts with \footahref{http://www.ejabberd.im/tutorials-transports}{external components}
+ Interacts with an \footahref{http://www.ejabberd.im/tutorials-transports}{external component}
(as defined in the Jabber Component Protocol (\xepref{0114}).\\
Options: \texttt{access}, \texttt{hosts}, \texttt{inet6},
\texttt{ip}, \texttt{shaper}, \texttt{service\_check\_from}
@@ -749,9 +772,10 @@ This is a detailed description of each option allowed by the listening modules:
external components. The option can be either \term{true} or
\term{false}. The default value is \term{true} which conforms to \xepref{0114}.
\titem{\{hosts, [Hostnames], [HostOptions]\}} \ind{options!hosts}
- This option of \term{ejabberd\_service} allows to define one or more hostnames
- of external Jabber components that provide a service.
- In \term{HostOptions} it is possible to define the password required to those components
+ The external Jabber component that connects to this \term{ejabberd\_service}
+ can serve one or more hostnames.
+ In \term{HostOptions} you can define options for the component;
+ currently the only allowed option is the password required to the component
when attempt to connect to ejabberd: \poption{\{password, Secret\}}.
Note that you cannot define in a single \term{ejabberd\_service} components of
different services: add an \term{ejabberd\_service} for each service,
@@ -1159,8 +1183,14 @@ version, you can \term{kill(1)} \term{epam} process periodically to reduce its m
consumption: \ejabberd{} will restart this process immediately.
\item \term{epam} program tries to turn off delays on authentication failures.
However, some PAM modules ignore this behavior and rely on their own configuration options.
-The example configuration file \term{ejabberd.pam} shows how to turn off delays in
-\term{pam\_unix.so} module. It is not a ready to use configuration file: you must use it
+You can create a configuration file \term{ejabberd.pam}.
+This example shows how to turn off delays in \term{pam\_unix.so} module:
+\begin{verbatim}
+#%PAM-1.0
+auth sufficient pam_unix.so likeauth nullok nodelay
+account sufficient pam_unix.so
+\end{verbatim}
+That is not a ready to use configuration file: you must use it
as a hint when building your own PAM configuration instead. Note that if you want to disable
delays on authentication failures in the PAM configuration file, you have to restrict access
to this file, so a malicious user can't use your configuration to perform brute-force
@@ -1371,7 +1401,7 @@ Examples:
\ind{options!language}\ind{language}
The option \option{language} defines the default language of server strings that
-can be seen by \Jabber{} clients. If a \Jabber{} client do not support
+can be seen by \Jabber{} clients. If a \Jabber{} client does not support
\option{xml:lang}, the specified language is used. The default value is
\term{en}. In order to take effect there must be a translation file
\term{.msg} in \ejabberd{}'s \term{msgs} directory.
@@ -1388,6 +1418,9 @@ Examples:
\end{verbatim}
\end{itemize}
+Appendix \ref{i18ni10n} provides more details about internationalization and localization.
+
+
\makesubsection{includeconfigfile}{Include Additional Configuration Files}
\ind{options!includeconfigfile}\ind{includeconfigfile}
@@ -1890,6 +1923,11 @@ module loaded!
server and use LDAP directory as vCard storage. Shared rosters are not supported
yet.
+Note that \ejabberd{} treats LDAP as a read-only storage:
+it is possible to consult data, but not possible to
+create accounts, change password or edit vCard that is stored in LDAP.
+
+
\makesubsubsection{ldapconnection}{Connection}
Parameters:
@@ -2534,31 +2572,28 @@ Options:
\makesubsection{modmuc}{\modmuc{}}
\ind{modules!\modmuc{}}\ind{protocols!XEP-0045: Multi-User Chat}\ind{conferencing}
-With this module enabled, your server will support Multi-User Chat
-(\xepref{0045}). End users will be able to join text conferences.
+This module provides a Multi-User Chat (\xepref{0045}) service.
+Users can discover existing rooms, join or create them.
+Occupants of a room can chat in public or have private chats.
Some of the features of Multi-User Chat:
\begin{itemize}
-\item Sending private messages to room participants.
-\item Inviting users.
-\item Setting a conference topic.
+\item Sending public and private messages to room occupants.
+\item Inviting other users to a room.
+\item Setting a room subject.
\item Creating password protected rooms.
-\item Kicking and banning participants.
+\item Kicking and banning occupants.
\end{itemize}
The MUC service allows any Jabber ID to register a nickname,
so nobody else can use that nickname in any room in the MUC service.
To register a nickname, open the Service Discovery in your
-Jabber client and Register in the MUC service.
-
-The MUC service allows the service administrator to send a message
-to all existing chatrooms.
-To do so, send the message to the Jabber ID of the MUC service.
+Jabber client and register in the MUC service.
This module supports clustering and load
balancing. One module can be started per cluster node. Rooms are
distributed at creation time on all available MUC module
-instances. The multi-user chat module is clustered but the room
+instances. The multi-user chat module is clustered but the rooms
themselves are not clustered nor fault-tolerant: if the node managing a
set of rooms goes down, the rooms disappear and they will be recreated
on an available node on first connection attempt.
@@ -2567,19 +2602,19 @@ Module options:
\begin{description}
\hostitem{conference}
\titem{access} \ind{options!access}You can specify who is allowed to use
- the Multi-User Chat service (by default, everyone is allowed to use it).
+ the Multi-User Chat service. By default everyone is allowed to use it.
\titem{access\_create} \ind{options!access\_create}To configure who is
allowed to create new rooms at the Multi-User Chat service, this option
- can be used (by default, everybody is allowed to create rooms).
+ can be used. By default everybody is allowed to create rooms.
\titem{access\_persistent} \ind{options!access\_persistent}To configure who is
- allowed to modify the 'persistent' chatroom option
- (by default, everybody is allowed to modify that option).
+ allowed to modify the 'persistent' room option.
+ By default everybody is allowed to modify that option.
\titem{access\_admin} \ind{options!access\_admin}This option specifies
- who is allowed to administrate the Multi-User Chat service (the default
+ who is allowed to administrate the Multi-User Chat service. The default
value is \term{none}, which means that only the room creator can
- administer his room).
+ administer his room.
The administrators can send a normal message to the service JID,
- and it will be shown in every active room as a service message.
+ and it will be shown in all active rooms as a service message.
The administrators can send a groupchat message to the JID of an active room,
and the message will be shown in the room as a service message.
\titem{history\_size} \ind{options!history\_size}A small history of
@@ -2589,44 +2624,43 @@ Module options:
integer. Setting the value to \term{0} disables the history feature
and, as a result, nothing is kept in memory. The default value is
\term{20}. This value is global and thus affects all rooms on the
- server.
+ service.
\titem{max\_users} \ind{options!max\_users} This option defines at
- the server level, the maximum number of users allowed per MUC
+ the service level, the maximum number of users allowed per
room. It can be lowered in each room configuration but cannot be
- increased in individual MUC room configuration. The default value is
+ increased in individual room configuration. The default value is
200.
\titem{max\_users\_admin\_threshold}
\ind{options!max\_users\_admin\_threshold} This option defines the
- number of MUC admins or owners to allow to enter the room even if
- the maximum number of allowed users is reached. The default limits
- is 5. In most cases this default value is the best setting.
+ number of service admins or room owners allowed to enter the room when
+ the maximum number of allowed occupants was reached. The default limit
+ is 5.
\titem{max\_user\_conferences}
- \ind{options!max\_user\_conferences} This option define the maximum
- number of chat room any given user will be able to join. The default
+ \ind{options!max\_user\_conferences} This option defines the maximum
+ number of rooms that any given user can join. The default value
is 10. This option is used to prevent possible abuses. Note that
- this is a soft limits: Some users can sometime join more conferences
+ this is a soft limit: some users can sometimes join more conferences
in cluster configurations.
\titem{min\_message\_interval} \ind{options!min\_message\_interval}
This option defines the minimum interval between two messages send
- by a user in seconds. This option is global and valid for all chat
+ by an occupant in seconds. This option is global and valid for all
rooms. A decimal value can be used. When this option is not defined,
message rate is not limited. This feature can be used to protect a
- MUC service from users abuses and limit number of messages that will
+ MUC service from occupant abuses and limit number of messages that will
be broadcasted by the service. A good value for this minimum message
- interval is 0.4 second. If a user tries to send messages faster, an
- error is send back explaining that the message have been discarded
+ interval is 0.4 second. If an occupant tries to send messages faster, an
+ error is send back explaining that the message has been discarded
and describing the reason why the message is not acceptable.
\titem{min\_presence\_interval}
\ind{options!min\_presence\_interval} This option defines the
- minimum of time between presence changes coming from a given user in
- seconds. This option is global and valid for all chat rooms. A
+ minimum of time between presence changes coming from a given occupant in
+ seconds. This option is global and valid for all rooms. A
decimal value can be used. When this option is not defined, no
restriction is applied. This option can be used to protect a MUC
- service for users abuses, as fastly changing a user presence will
- result in possible large presence packet broadcast. If a user tries
+ service for occupants abuses. If an occupant tries
to change its presence more often than the specified interval, the
presence is cached by \ejabberd{} and only the last presence is
- broadcasted to all users in the room after expiration of the
+ broadcasted to all occupants in the room after expiration of the
interval delay. Intermediate presence packets are silently
discarded. A good value for this option is 4 seconds.
\titem{default\_room\_options} \ind{options!default\_room\_options}
@@ -2639,7 +2673,15 @@ Module options:
\titem{\{allow\_private\_messages, true\}} Occupants can send private messages to other occupants.
\titem{\{allow\_query\_users, true\}} Occupants can send IQ queries to other occupants.
\titem{\{allow\_user\_invites, false\}} Allow occupants to send invitations.
- \titem{\{anonymous, true\}} Occupants are allowed to see the real JIDs of other occupants.
+ \titem{\{allow\_visitor\_nickchange, true\}} Allow visitors to
+ change nickname.
+ \titem{\{allow\_visitor\_status, true\}} Allow visitors to send
+ status text in presence updates. If disallowed, the \term{status}
+ text is stripped before broadcasting the presence update to all
+ the room occupants.
+ \titem{\{anonymous, true\}} The room is anonymous:
+ occupants don't see the real JIDs of other occupants.
+ Note that the room moderators can always see the real JIDs of the occupants.
\titem{\{logging, false\}} The public messages are logged using \term{mod\_muc\_log}.
\titem{\{max\_users, 200\}} Maximum number of occupants in the room.
\titem{\{members\_by\_default, true\}} The occupants that enter the room are participants by default, so they have 'voice'.
@@ -2715,8 +2757,8 @@ Examples:
]}.
\end{verbatim}
-\item In the following example, MUC anti abuse options are used. A
-user cannot send more than one message every 0.4 seconds and cannot
+\item In the following example, MUC anti abuse options are used. An
+occupant cannot send more than one message every 0.4 seconds and cannot
change its presence more than once every 4 seconds. No ACLs are
defined, but some user restriction could be added as well:
@@ -2731,7 +2773,7 @@ defined, but some user restriction could be added as well:
\end{verbatim}
\item This example shows how to use \option{default\_room\_options} to make sure
- newly created chatrooms have by default those options.
+ the newly created rooms have by default those options.
\begin{verbatim}
{modules,
[
@@ -2756,19 +2798,19 @@ defined, but some user restriction could be added as well:
\makesubsection{modmuclog}{\modmuclog{}}
\ind{modules!\modmuclog{}}
-This module enables optional logging of Multi-User Chat (MUC) conversations to
-HTML. Once you enable this module, users can join a chatroom using a MUC capable
+This module enables optional logging of Multi-User Chat (MUC) public conversations to
+HTML. Once you enable this module, users can join a room using a MUC capable
Jabber client, and if they have enough privileges, they can request the
-configuration form in which they can set the option to enable chatroom logging.
+configuration form in which they can set the option to enable room logging.
Features:
\begin{itemize}
-\item Chatroom details are added on top of each page: room title, JID,
+\item Room details are added on top of each page: room title, JID,
author, subject and configuration.
\item \ind{protocols!RFC 5122: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)}
- The room JID in the generated HTML is a link to join the chatroom (using
+ The room JID in the generated HTML is a link to join the room (using
\footahref{http://www.xmpp.org/rfcs/rfc5122.html}{XMPP URI}).
-\item Subject and chatroom configuration changes are tracked and displayed.
+\item Subject and room configuration changes are tracked and displayed.
\item Joins, leaves, nick changes, kicks, bans and `/me' are tracked and
displayed, including the reason if available.
\item Generated HTML files are XHTML 1.0 Transitional and CSS compliant.
@@ -2783,7 +2825,7 @@ Features:
Options:
\begin{description}
\titem{access\_log}\ind{options!access\_log}
- This option restricts which users are allowed to enable or disable chatroom
+ This option restricts which occupants are allowed to enable or disable room
logging. The default value is \term{muc\_admin}. Note for this default setting
you need to have an access rule for \term{muc\_admin} in order to take effect.
\titem{cssfile}\ind{options!cssfile}
@@ -2793,26 +2835,38 @@ Options:
include the embedded CSS code. With the latter, you can specify the URL of the
custom CSS file (for example: `http://example.com/my.css'). The default value
is \term{false}.
+\titem{dirname}\ind{options!dirname}
+ Allows to configure the name of the room directory.
+ Allowed values are \term{room\_jid} and \term{room\_name}.
+ With the first value, the room directory name will be the full room JID.
+ With the latter, the room directory name will be only the room name,
+ not including the MUC service name.
+ The default value is \term{room\_jid}.
\titem{dirtype}\ind{options!dirtype}
The type of the created directories can be specified with this option. Allowed
values are \term{subdirs} and \term{plain}. With the first value,
subdirectories are created for each year and month. With the latter, the
names of the log files contain the full date, and there are no subdirectories.
The default value is \term{subdirs}.
+\titem{file\_format}\ind{options!file\_format}
+ Define the format of the log files:
+ \term{html} stores in HTML format,
+ \term{plaintext} stores in plain text.
+ The default value is \term{html}.
\titem{outdir}\ind{options!outdir}
This option sets the full path to the directory in which the HTML files should
be stored. Make sure the \ejabberd{} daemon user has write access on that
directory. The default value is \term{"www/muc"}.
-\titem{timezone}\ind{options!timezone}
- The time zone for the logs is configurable with this option. Allowed values
- are \term{local} and \term{universal}. With the first value, the local time,
- as reported to Erlang by the operating system, will be used. With the latter,
- GMT/UTC time will be used. The default value is \term{local}.
\titem{spam\_prevention}\ind{options!spam\_prevention}
To prevent spam, the \term{spam\_prevention} option adds a special attribute
to links that prevent their indexation by search engines. The default value
is \term{true}, which mean that nofollow attributes will be added to user
submitted links.
+\titem{timezone}\ind{options!timezone}
+ The time zone for the logs is configurable with this option. Allowed values
+ are \term{local} and \term{universal}. With the first value, the local time,
+ as reported to Erlang by the operating system, will be used. With the latter,
+ GMT/UTC time will be used. The default value is \term{local}.
\titem{top\_link}\ind{options!top\_link}
With this option you can customize the link on the top right corner of each
log file. The syntax of this option is \term{\{"URL", "Text"\}}. The default
@@ -2821,8 +2875,8 @@ Options:
Examples:
\begin{itemize}
-\item In the first example any chatroom owner can enable logging, and a
- custom CSS file will be used (http://example.com/my.css). Further, the names
+\item In the first example any room owner can enable logging, and a
+ custom CSS file will be used (http://example.com/my.css). The names
of the log files will contain the full date, and there will be no
subdirectories. The log files will be stored in /var/www/muclogs, and the
time zone will be GMT/UTC. Finally, the top link will be
@@ -2837,6 +2891,7 @@ Examples:
{access_log, muc},
{cssfile, "http://example.com/my.css"},
{dirtype, plain},
+ {dirname, room_jid},
{outdir, "/var/www/muclogs"},
{timezone, universal},
{spam_prevention, true},
@@ -2847,7 +2902,7 @@ Examples:
\end{verbatim}
\item In the second example only \jid{admin1@example.org} and
\jid{admin2@example.net} can enable logging, and the embedded CSS file will be
- used. Further, the names of the log files will only contain the day (number),
+ used. The names of the log files will only contain the day (number),
and there will be subdirectories for each year and month. The log files will
be stored in /var/www/muclogs, and the local time will be used. Finally, the
top link will be the default \verb|Home|.
@@ -2986,8 +3041,8 @@ Examples:
{access, proxy65_access, [{allow, proxy_users}, {deny, all}]}.
{acl, admin, {user, "admin", "example.org"}}.
-{shaper, normal, {maxrate, 10240}}. %% 10 Kbytes/sec
-{access, proxy65_shaper, [{none, admin}, {normal, all}]}.
+{shaper, proxyrate, {maxrate, 10240}}. %% 10 Kbytes/sec
+{access, proxy65_shaper, [{none, admin}, {proxyrate, proxy_users}]}.
{modules,
[
@@ -3411,6 +3466,10 @@ Examples:
implemented in the \modvcardldap{} module. This module does not depend on the
authentication method (see~\ref{ldapauth}).
+Note that \ejabberd{} treats LDAP as a read-only storage:
+it is possible to consult data, but not possible to
+create accounts, change password or edit vCard that is stored in LDAP.
+
The \modvcardldap{} module has
its own optional parameters. The first group of parameters has the same
meaning as the top-level LDAP parameters to set the authentication method:
@@ -4052,6 +4111,7 @@ following steps:
\begin{verbatim}
erl -sname ejabberd \
+ -mnesia dir "/var/lib/ejabberd/" \
-mnesia extra_db_nodes "['ejabberd@first']" \
-s mnesia
\end{verbatim}
@@ -4060,6 +4120,11 @@ erl -sname ejabberd \
You can check this by running the command `\verb|mnesia:info().|'. You
should see a lot of remote tables and a line like the following:
+ Note: the Mnesia directory may be different in your system.
+ To know where does ejabberd expect Mnesia to be installed by default,
+ call \ref{ejabberdctl} without options and it will show some help,
+ including the Mnesia database spool dir.
+
\begin{verbatim}
running db nodes = [ejabberd@first, ejabberd@second]
\end{verbatim}
@@ -4227,6 +4292,18 @@ To exit the shell, close the window or press the keys: control+c control+c.
\makechapter{i18ni10n}{Internationalization and Localization}
\ind{xml:lang}\ind{internationalization}\ind{localization}\ind{i18n}\ind{l10n}
+The source code of \ejabberd{} supports localization.
+The translators can edit the
+\footahref{http://www.gnu.org/software/gettext/}{gettext} .po files
+using any capable program (KBabel, Lokalize, Poedit...) or a simple text editor.
+
+Then gettext
+is used to extract, update and export those .po files to the .msg format read by \ejabberd{}.
+To perform those management tasks, in the \term{src/} directory execute \term{make translations}.
+The translatable strings are extracted from source code to generate the file \term{ejabberd.pot}.
+This file is merged with each .po file to produce updated .po files.
+Finally those .po files are exported to .msg files, that have a format easily readable by \ejabberd{}.
+
All built-in modules support the \texttt{xml:lang} attribute inside IQ queries.
Figure~\ref{fig:discorus}, for example, shows the reply to the following query:
\begin{verbatim}
@@ -4284,7 +4361,7 @@ Thanks to all people who contributed to this guide:
\makechapter{copyright}{Copyright Information}
Ejabberd Installation and Operation Guide.\\
-Copyright \copyright{} 2003 --- 2008 Process-one
+Copyright \copyright{} 2003 --- 2008 ProcessOne
This document is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/doc/release_notes_2.0.2.txt b/doc/release_notes_2.0.2.txt
new file mode 100644
index 000000000..767ae1367
--- /dev/null
+++ b/doc/release_notes_2.0.2.txt
@@ -0,0 +1,34 @@
+
+ Release Notes
+ ejabberd 2.0.2
+ 28 August 2008
+
+ ejabberd 2.0.2 is the second bug fix release for ejabberd 2.0.x branch.
+
+ ejabberd 2.0.2 includes many bugfixes and a few improvements.
+ A complete list of changes can be retrieved from:
+ http://redir.process-one.net/ejabberd-2.0.2
+
+ The new code can be downloaded from ejabberd download page:
+ http://www.process-one.net/en/ejabberd/
+
+
+ Recent changes include:
+
+- Anti-abuse feature: client blacklist support by IP.
+- Guide: new section Securing ejabberd; improved usability.
+- LDAP filter optimisation: ability to filter user in ejabberd and not LDAP.
+- MUC improvements: room options to restrict visitors; broadcast reasons.
+- Privacy rules: fix MySQL storage.
+- Pub/Sub and PEP: many improvements in implementation and protocol compliance.
+- Proxy65: send valid SOCKS5 reply (removed support for Psi < 0.10).
+- Web server embedded: better support for HTTPS.
+- Binary installers: SMP on Windows; don't remove config when uninstalling.
+
+
+ Bug reports
+
+ You can officially report bugs on ProcessOne support site:
+ http://support.process-one.net/
+
+END
diff --git a/src/Makefile.in b/src/Makefile.in
index 5dabf5431..93d29fc60 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -157,6 +157,9 @@ $(ERLSHLIBS): %.so: %.c
-o $@ \
$(DYNAMIC_LIB_CFLAGS)
+translations:
+ ../contrib/extract_translations/prepare-translation.sh -updateall
+
install: all
#
# Configuration files
diff --git a/src/acl.erl b/src/acl.erl
index 21bacf618..c21e62488 100644
--- a/src/acl.erl
+++ b/src/acl.erl
@@ -5,7 +5,7 @@
%%% Created : 18 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/adhoc.erl b/src/adhoc.erl
index 0382062b0..26ea5a7c2 100644
--- a/src/adhoc.erl
+++ b/src/adhoc.erl
@@ -5,7 +5,7 @@
%%% Created : 31 Oct 2005 by Magnus Henoch
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/adhoc.hrl b/src/adhoc.hrl
index 5dbc515bc..ab8a6f163 100644
--- a/src/adhoc.hrl
+++ b/src/adhoc.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/configure.erl b/src/configure.erl
index b9447c28d..379c79a82 100644
--- a/src/configure.erl
+++ b/src/configure.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl
index e942aa3e8..7813df772 100644
--- a/src/cyrsasl.erl
+++ b/src/cyrsasl.erl
@@ -5,7 +5,7 @@
%%% Created : 8 Mar 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/cyrsasl_anonymous.erl b/src/cyrsasl_anonymous.erl
index 4f1219882..fb033b3a7 100644
--- a/src/cyrsasl_anonymous.erl
+++ b/src/cyrsasl_anonymous.erl
@@ -6,7 +6,7 @@
%%% Created : 23 Aug 2005 by Magnus Henoch
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/cyrsasl_plain.erl b/src/cyrsasl_plain.erl
index c0ca708d8..1533c463d 100644
--- a/src/cyrsasl_plain.erl
+++ b/src/cyrsasl_plain.erl
@@ -5,7 +5,7 @@
%%% Created : 8 Mar 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd.erl b/src/ejabberd.erl
index de2727ca0..86113d97b 100644
--- a/src/ejabberd.erl
+++ b/src/ejabberd.erl
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd.hrl b/src/ejabberd.hrl
index d7b16f1e2..658037274 100644
--- a/src/ejabberd.hrl
+++ b/src/ejabberd.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl
index 44b7213ea..a0f101703 100644
--- a/src/ejabberd_admin.erl
+++ b/src/ejabberd_admin.erl
@@ -9,7 +9,7 @@
%%% Created : 7 May 2006 by Mickael Remond
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl
index 8f335ad5b..e64c58635 100644
--- a/src/ejabberd_app.erl
+++ b/src/ejabberd_app.erl
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -152,7 +152,7 @@ stop_modules() ->
Modules ->
lists:foreach(
fun({Module, _Args}) ->
- gen_mod:stop_module(Host, Module)
+ gen_mod:stop_module_keep_config(Host, Module)
end, Modules)
end
end, ?MYHOSTS).
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl
index 358d44ae0..33a575e30 100644
--- a/src/ejabberd_auth.erl
+++ b/src/ejabberd_auth.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -127,9 +127,12 @@ check_password_with_authmodule(User, Server, Password, StreamID, Digest) ->
[AuthMod | _] -> {true, AuthMod}
end.
-%% We do not allow empty password:
+%% @spec (User::string(), Server::string(), Password::string()) ->
+%% ok | {error, ErrorType}
+%% where ErrorType = empty_password | not_allowed | invalid_jid
set_password(_User, _Server, "") ->
- {error, not_allowed};
+ %% We do not allow empty password
+ {error, empty_password};
set_password(User, Server, Password) ->
lists:foldl(
fun(M, {error, _}) ->
@@ -138,8 +141,8 @@ set_password(User, Server, Password) ->
Res
end, {error, not_allowed}, auth_modules(Server)).
-%% We do not allow empty password:
try_register(_User, _Server, "") ->
+ %% We do not allow empty password
{error, not_allowed};
try_register(User, Server, Password) ->
case is_user_exists(User,Server) of
diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl
index 8ba4d7336..955a0dc06 100644
--- a/src/ejabberd_auth_anonymous.erl
+++ b/src/ejabberd_auth_anonymous.erl
@@ -5,7 +5,7 @@
%%% Created : 17 Feb 2006 by Mickael Remond
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl
index 9684944a6..b86a94bb8 100644
--- a/src/ejabberd_auth_external.erl
+++ b/src/ejabberd_auth_external.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -61,7 +61,10 @@ check_password(User, Server, Password, _StreamID, _Digest) ->
check_password(User, Server, Password).
set_password(User, Server, Password) ->
- extauth:set_password(User, Server, Password).
+ case extauth:set_password(User, Server, Password) of
+ true -> ok;
+ _ -> {error, unknown_problem}
+ end.
try_register(_User, _Server, _Password) ->
{error, not_allowed}.
diff --git a/src/ejabberd_auth_internal.erl b/src/ejabberd_auth_internal.erl
index 71d9086d7..cec18b319 100644
--- a/src/ejabberd_auth_internal.erl
+++ b/src/ejabberd_auth_internal.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -98,6 +98,8 @@ check_password(User, Server, Password, StreamID, Digest) ->
false
end.
+%% @spec (User::string(), Server::string(), Password::string()) ->
+%% ok | {error, invalid_jid}
set_password(User, Server, Password) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
@@ -110,7 +112,8 @@ set_password(User, Server, Password) ->
mnesia:write(#passwd{us = US,
password = Password})
end,
- mnesia:transaction(F)
+ {atomic, ok} = mnesia:transaction(F),
+ ok
end.
try_register(User, Server, Password) ->
diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl
index d576a82fd..303300e48 100644
--- a/src/ejabberd_auth_ldap.erl
+++ b/src/ejabberd_auth_ldap.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_auth_odbc.erl b/src/ejabberd_auth_odbc.erl
index 06ae695ea..26eca6ab3 100644
--- a/src/ejabberd_auth_odbc.erl
+++ b/src/ejabberd_auth_odbc.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Dec 2004 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -103,13 +103,18 @@ check_password(User, Server, Password, StreamID, Digest) ->
false
end.
+%% @spec (User::string(), Server::string(), Password::string()) ->
+%% ok | {error, invalid_jid}
set_password(User, Server, Password) ->
try
LUser = exmpp_stringprep:nodeprep(User),
Username = ejabberd_odbc:escape(LUser),
Pass = ejabberd_odbc:escape(Password),
LServer = exmpp_stringprep:nameprep(Server),
- catch odbc_queries:set_password_t(LServer, Username, Pass)
+ case catch odbc_queries:set_password_t(LServer, Username, Pass) of
+ {atomic, ok} -> ok;
+ Other -> {error, Other}
+ end
catch
_ ->
{error, invalid_jid}
diff --git a/src/ejabberd_auth_pam.erl b/src/ejabberd_auth_pam.erl
index 810ab7cf5..f26296d33 100644
--- a/src/ejabberd_auth_pam.erl
+++ b/src/ejabberd_auth_pam.erl
@@ -5,7 +5,7 @@
%%% Created : 5 Jul 2007 by Evgeniy Khramtsov
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index 6c86d1149..5b00509f3 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -37,6 +37,7 @@
send_element/2,
socket_type/0,
get_presence/1,
+ get_subscribed/1,
get_subscribed_and_online/1]).
%% gen_fsm callbacks
@@ -201,6 +202,9 @@ init([{SockMod, Socket}, Opts]) ->
%% Return list of all available resources of contacts,
%% in form [{JID, Caps}].
+get_subscribed(FsmRef) ->
+ gen_fsm:sync_send_all_state_event(
+ FsmRef, get_subscribed, 1000).
get_subscribed_and_online(FsmRef) ->
gen_fsm:sync_send_all_state_event(
FsmRef, get_subscribed_and_online, 1000).
@@ -932,6 +936,20 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
Reply = {User, Resource, atom_to_list(Show), Status},
fsm_reply(Reply, StateName, StateData);
+handle_sync_event(get_subscribed, _From, StateName, StateData) ->
+ Subscribed = StateData#state.pres_f,
+ Online = StateData#state.pres_available,
+ Pred = fun(User, _Caps) ->
+ ?SETS:is_element(jlib:jid_remove_resource(User),
+ Subscribed) orelse
+ ?SETS:is_element(User, Subscribed)
+ end,
+ SubscribedAndOnline = ?DICT:filter(Pred, Online),
+ SubscribedWithCaps = ?SETS:fold(fun(User, Acc) ->
+ [{User, undefined}|Acc]
+ end, ?DICT:to_list(SubscribedAndOnline), Subscribed),
+ {reply, SubscribedWithCaps, StateName, StateData};
+
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available,
diff --git a/src/ejabberd_c2s_config.erl b/src/ejabberd_c2s_config.erl
index 35fa5a82d..4c1dae8fc 100644
--- a/src/ejabberd_c2s_config.erl
+++ b/src/ejabberd_c2s_config.erl
@@ -6,7 +6,7 @@
%%% Created : 2 Nov 2007 by Mickael Remond
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_check.erl b/src/ejabberd_check.erl
index 16aa78c68..260c54175 100644
--- a/src/ejabberd_check.erl
+++ b/src/ejabberd_check.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Feb 2008 by Mickael Remond
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -39,19 +39,21 @@
libs() ->
ok.
-%% Consistency check on ejabberd configuration
+%% @doc Consistency check on ejabberd configuration
config() ->
check_database_modules().
check_database_modules() ->
[check_database_module(M)||M<-get_db_used()].
+check_database_module(odbc) ->
+ check_modules(odbc, [odbc, odbc_app, odbc_sup, ejabberd_odbc, ejabberd_odbc_sup, odbc_queries]);
check_database_module(mysql) ->
check_modules(mysql, [mysql, mysql_auth, mysql_conn, mysql_recv]);
check_database_module(pgsql) ->
check_modules(pgsql, [pgsql, pgsql_proto, pgsql_tcp, pgsql_util]).
-%% Issue a critical error and throw an exit if needing module is
+%% @doc Issue a critical error and throw an exit if needing module is
%% missing.
check_modules(DB, Modules) ->
case get_missing_modules(Modules) of
@@ -63,7 +65,7 @@ check_modules(DB, Modules) ->
end.
-%% Return the list of undefined modules
+%% @doc Return the list of undefined modules
get_missing_modules(Modules) ->
lists:filter(fun(Module) ->
case catch Module:module_info() of
@@ -73,7 +75,7 @@ get_missing_modules(Modules) ->
end
end, Modules).
-%% Return the list of databases used
+%% @doc Return the list of databases used
get_db_used() ->
%% Retrieve domains with a database configured:
Domains =
@@ -86,14 +88,22 @@ get_db_used() ->
case check_odbc_option(
ejabberd_config:get_local_option(
{auth_method, Domain})) of
- true -> [element(1, DB)|Acc];
+ true -> [get_db_type(DB)|Acc];
_ -> Acc
end
end,
[], Domains),
lists:usort(DBs).
-%% Return true if odbc option is used
+%% @doc Depending in the DB definition, return which type of DB this is.
+%% Note that MSSQL is detected as ODBC.
+%% @spec (DB) -> mysql | pgsql | odbc
+get_db_type(DB) when is_tuple(DB) ->
+ element(1, DB);
+get_db_type(DB) when is_list(DB) ->
+ odbc.
+
+%% @doc Return true if odbc option is used
check_odbc_option(odbc) ->
true;
check_odbc_option(AuthMethods) when is_list(AuthMethods) ->
diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl
index c18cfe6de..182b4a216 100644
--- a/src/ejabberd_config.erl
+++ b/src/ejabberd_config.erl
@@ -5,7 +5,7 @@
%%% Created : 14 Dec 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -95,10 +95,14 @@ get_plain_terms_file(File1) ->
case file:consult(File) of
{ok, Terms} ->
include_config_files(Terms);
- {error, Reason} ->
- ExitText = lists:flatten(File ++ ": around line "
+ {error, {_LineNumber, erl_parse, _ParseMessage} = Reason} ->
+ ExitText = lists:flatten(File ++ " approximately in the line "
++ file:format_error(Reason)),
- ?ERROR_MSG("Problem loading ejabberd config file:~n~s", [ExitText]),
+ ?ERROR_MSG("Problem loading ejabberd config file ~n~s", [ExitText]),
+ exit(ExitText);
+ {error, Reason} ->
+ ExitText = lists:flatten(File ++ ": " ++ file:format_error(Reason)),
+ ?ERROR_MSG("Problem loading ejabberd config file ~n~s", [ExitText]),
exit(ExitText)
end.
diff --git a/src/ejabberd_config.hrl b/src/ejabberd_config.hrl
index aa783ea5e..982bbe23f 100644
--- a/src/ejabberd_config.hrl
+++ b/src/ejabberd_config.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl
index 9a84b592e..c66b93a38 100644
--- a/src/ejabberd_ctl.erl
+++ b/src/ejabberd_ctl.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Jan 2004 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
-%%%
+%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
@@ -99,6 +99,9 @@ process(["restart"]) ->
process(["reopen-log"]) ->
ejabberd_hooks:run(reopen_log_hook, []),
+ lists:foreach(fun(Host) ->
+ ejabberd_hooks:run(reopen_log_hook, Host, [Host])
+ end, ?MYHOSTS),
%% TODO: Use the Reopen log API for logger_h ?
ejabberd_logger_h:reopen_log(),
?STATUS_SUCCESS;
@@ -158,7 +161,7 @@ process(["load", Path]) ->
end;
process(["restore", Path]) ->
- case ejabberd_admin:restore(Path) of
+ case ejabberd_admin:restore(Path) of
{atomic, _} ->
?STATUS_SUCCESS;
{error, Reason} ->
@@ -384,7 +387,7 @@ dump_to_textfile(yes, {ok, F}) ->
end, Tabs1),
Defs = lists:map(
fun(T) -> {T, [{record_name, mnesia:table_info(T, record_name)},
- {attributes, mnesia:table_info(T, attributes)}]}
+ {attributes, mnesia:table_info(T, attributes)}]}
end,
Tabs),
io:format(F, "~p.~n", [{tables, Defs}]),
diff --git a/src/ejabberd_ctl.hrl b/src/ejabberd_ctl.hrl
index e8daef90b..9b5ec0a4b 100644
--- a/src/ejabberd_ctl.hrl
+++ b/src/ejabberd_ctl.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_frontend_socket.erl b/src/ejabberd_frontend_socket.erl
index 5874afa6d..320968f70 100644
--- a/src/ejabberd_frontend_socket.erl
+++ b/src/ejabberd_frontend_socket.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Aug 2006 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_hooks.erl b/src/ejabberd_hooks.erl
index 7fc2f07f0..0609e20d4 100644
--- a/src/ejabberd_hooks.erl
+++ b/src/ejabberd_hooks.erl
@@ -5,7 +5,7 @@
%%% Created : 8 Aug 2004 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl
index b65a33785..e8bddf00e 100644
--- a/src/ejabberd_listener.erl
+++ b/src/ejabberd_listener.erl
@@ -5,7 +5,7 @@
%%% Created : 16 Nov 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index d77eb6968..232ce8415 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -5,7 +5,7 @@
%%% Created : 30 Nov 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_logger_h.erl b/src/ejabberd_logger_h.erl
index a3af991bc..2e750ca34 100644
--- a/src/ejabberd_logger_h.erl
+++ b/src/ejabberd_logger_h.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Oct 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_loglevel.erl b/src/ejabberd_loglevel.erl
index 0f482b6fe..59c415196 100644
--- a/src/ejabberd_loglevel.erl
+++ b/src/ejabberd_loglevel.erl
@@ -9,7 +9,7 @@
%%% Created : 29 Nov 2006 by Mickael Remond
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_node_groups.erl b/src/ejabberd_node_groups.erl
index 6386a7e93..d5d8ce068 100644
--- a/src/ejabberd_node_groups.erl
+++ b/src/ejabberd_node_groups.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Nov 2006 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_rdbms.erl b/src/ejabberd_rdbms.erl
index 540ffce0b..0eff6c3ca 100644
--- a/src/ejabberd_rdbms.erl
+++ b/src/ejabberd_rdbms.erl
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl
index 5fdad76af..6d5b30ec3 100644
--- a/src/ejabberd_receiver.erl
+++ b/src/ejabberd_receiver.erl
@@ -5,7 +5,7 @@
%%% Created : 10 Nov 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl
index 04bc76285..658f674fc 100644
--- a/src/ejabberd_router.erl
+++ b/src/ejabberd_router.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Nov 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -161,9 +161,9 @@ unregister_route(Domain) ->
mnesia:transaction(F);
_ ->
F = fun() ->
- case mnesia:match(#route{domain = LDomain,
- pid = Pid,
- _ = '_'}) of
+ case mnesia:match_object(#route{domain=LDomain,
+ pid = Pid,
+ _ = '_'}) of
[R] ->
I = R#route.local_hint,
mnesia:write(
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index 492484c31..53cc65e28 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -5,7 +5,7 @@
%%% Created : 7 Dec 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl
index 2fdcbac28..8ac32bf63 100644
--- a/src/ejabberd_s2s_in.erl
+++ b/src/ejabberd_s2s_in.erl
@@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl
index bbd792a2f..b73336245 100644
--- a/src/ejabberd_s2s_out.erl
+++ b/src/ejabberd_s2s_out.erl
@@ -5,7 +5,7 @@
%%% Created : 6 Dec 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl
index 302211f07..8f16a6f6e 100644
--- a/src/ejabberd_service.erl
+++ b/src/ejabberd_service.erl
@@ -1,11 +1,11 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_service.erl
%%% Author : Alexey Shchepin
-%%% Purpose : External component management
+%%% Purpose : External component management (XEP-0114)
%%% Created : 6 Dec 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -147,11 +147,15 @@ init([{SockMod, Socket}, Opts]) ->
%% {stop, Reason, NewStateData}
%%----------------------------------------------------------------------
-wait_for_stream({xmlstreamstart, #xmlel{ns = NS}}, StateData) ->
- % TODO
+wait_for_stream({xmlstreamstart, #xmlel{ns = NS, attrs = Attrs}}, StateData) ->
case NS of
?NS_COMPONENT_ACCEPT ->
- Opening_Reply = exmpp_stream:opening_reply(?MYNAME,
+ %% Note: XEP-0114 requires to check that destination is a Jabber
+ %% component served by this Jabber server.
+ %% However several transports don't respect that,
+ %% so ejabberd doesn't check 'to' attribute (EJAB-717)
+ To = exmpp_stanza:get_recipient_from_attrs(Attrs),
+ Opening_Reply = exmpp_stream:opening_reply(xml:crypt(To),
?NS_COMPONENT_ACCEPT,
{0, 0}, StateData#state.streamid),
send_element(StateData, Opening_Reply),
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index 3cec22f04..2d24d17a5 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Nov 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl
index 389b3a106..115ffc750 100644
--- a/src/ejabberd_socket.erl
+++ b/src/ejabberd_socket.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Aug 2006 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_sup.erl b/src/ejabberd_sup.erl
index 596dd7fa6..01efbfd76 100644
--- a/src/ejabberd_sup.erl
+++ b/src/ejabberd_sup.erl
@@ -5,7 +5,7 @@
%%% Created : 31 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl
index eb1e305b2..e9a1a8ba3 100644
--- a/src/ejabberd_system_monitor.erl
+++ b/src/ejabberd_system_monitor.erl
@@ -5,7 +5,7 @@
%%% Created : 21 Mar 2007 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_tmp_sup.erl b/src/ejabberd_tmp_sup.erl
index 733af4c26..7438f6628 100644
--- a/src/ejabberd_tmp_sup.erl
+++ b/src/ejabberd_tmp_sup.erl
@@ -5,7 +5,7 @@
%%% Created : 18 Jul 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_update.erl b/src/ejabberd_update.erl
index 3f878337c..787f93fd7 100644
--- a/src/ejabberd_update.erl
+++ b/src/ejabberd_update.erl
@@ -5,7 +5,7 @@
%%% Created : 27 Jan 2006 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_zlib/ejabberd_zlib.erl b/src/ejabberd_zlib/ejabberd_zlib.erl
index 22bcaa8dd..18d5a3abf 100644
--- a/src/ejabberd_zlib/ejabberd_zlib.erl
+++ b/src/ejabberd_zlib/ejabberd_zlib.erl
@@ -5,7 +5,7 @@
%%% Created : 19 Jan 2006 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/ejabberd_zlib/ejabberd_zlib_drv.c b/src/ejabberd_zlib/ejabberd_zlib_drv.c
index abb3183c0..d1442d773 100644
--- a/src/ejabberd_zlib/ejabberd_zlib_drv.c
+++ b/src/ejabberd_zlib/ejabberd_zlib_drv.c
@@ -1,5 +1,5 @@
/*
- * ejabberd, Copyright (C) 2002-2008 Process-one
+ * ejabberd, Copyright (C) 2002-2008 ProcessOne
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
diff --git a/src/ejd2odbc.erl b/src/ejd2odbc.erl
index 2528e323d..c1399f987 100644
--- a/src/ejd2odbc.erl
+++ b/src/ejd2odbc.erl
@@ -5,7 +5,7 @@
%%% Created : 22 Aug 2005 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/eldap/eldap.hrl b/src/eldap/eldap.hrl
index 75f6f76ef..d006c14df 100644
--- a/src/eldap/eldap.hrl
+++ b/src/eldap/eldap.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/eldap/eldap_filter.erl b/src/eldap/eldap_filter.erl
index 771f909a6..2feed1083 100644
--- a/src/eldap/eldap_filter.erl
+++ b/src/eldap/eldap_filter.erl
@@ -6,7 +6,7 @@
%%% Author: Evgeniy Khramtsov
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/eldap/eldap_pool.erl b/src/eldap/eldap_pool.erl
index 13b45402a..7b9024de3 100644
--- a/src/eldap/eldap_pool.erl
+++ b/src/eldap/eldap_pool.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Nov 2006 by Evgeniy Khramtsov
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/eldap/eldap_utils.erl b/src/eldap/eldap_utils.erl
index 465d9ffe5..1f6d156d3 100644
--- a/src/eldap/eldap_utils.erl
+++ b/src/eldap/eldap_utils.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Oct 2006 by Mickael Remond
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/extauth.erl b/src/extauth.erl
index 3819fcddf..c4acb305d 100644
--- a/src/extauth.erl
+++ b/src/extauth.erl
@@ -5,7 +5,7 @@
%%% Created : 30 Jul 2004 by Leif Johansson
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl
index b3e3beca5..a1f100c45 100644
--- a/src/gen_iq_handler.erl
+++ b/src/gen_iq_handler.erl
@@ -5,7 +5,7 @@
%%% Created : 22 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/gen_mod.erl b/src/gen_mod.erl
index 29fbb1104..bbc4e860d 100644
--- a/src/gen_mod.erl
+++ b/src/gen_mod.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -30,6 +30,7 @@
-export([start/0,
start_module/3,
stop_module/2,
+ stop_module_keep_config/2,
get_opt/2,
get_opt/3,
get_opt_host/3,
@@ -72,22 +73,34 @@ start_module(Host, Module, Opts) ->
ok
end.
+%% @doc Stop the module in a host, and forget its configuration.
stop_module(Host, Module) ->
+ case stop_module_keep_config(Host, Module) of
+ error ->
+ error;
+ ok ->
+ del_module_mnesia(Host, Module)
+ end.
+
+%% @doc Stop the module in a host, but keep its configuration.
+%% As the module configuration is kept in the Mnesia local_config table,
+%% when ejabberd is restarted the module will be started again.
+%% This function is useful when ejabberd is being stopped
+%% and it stops all modules.
+stop_module_keep_config(Host, Module) ->
case catch Module:stop(Host) of
{'EXIT', Reason} ->
- ?ERROR_MSG("~p", [Reason]);
+ ?ERROR_MSG("~p", [Reason]),
+ error;
{wait, ProcList} when is_list(ProcList) ->
lists:foreach(fun wait_for_process/1, ProcList),
- del_module_mnesia(Host, Module),
ets:delete(ejabberd_modules, {Module, Host}),
ok;
{wait, Process} ->
wait_for_process(Process),
- del_module_mnesia(Host, Module),
ets:delete(ejabberd_modules, {Module, Host}),
ok;
_ ->
- del_module_mnesia(Host, Module),
ets:delete(ejabberd_modules, {Module, Host}),
ok
end.
diff --git a/src/idna.erl b/src/idna.erl
index 6ad8c54cb..319262349 100644
--- a/src/idna.erl
+++ b/src/idna.erl
@@ -5,7 +5,7 @@
%%% Created : 10 Apr 2004 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl
index 9fac9c11f..193566cde 100644
--- a/src/jd2ejd.erl
+++ b/src/jd2ejd.erl
@@ -5,7 +5,7 @@
%%% Created : 2 Feb 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/jlib.erl b/src/jlib.erl
index acf08a550..288e5f6c6 100644
--- a/src/jlib.erl
+++ b/src/jlib.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/jlib.hrl b/src/jlib.hrl
index 3ea10b157..39731b14a 100644
--- a/src/jlib.hrl
+++ b/src/jlib.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl
index ad255f827..b1a2a7bf7 100644
--- a/src/mod_adhoc.erl
+++ b/src/mod_adhoc.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Nov 2005 by Magnus Henoch
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_announce.erl b/src/mod_announce.erl
index 5a744e6e0..e59e65fdb 100644
--- a/src/mod_announce.erl
+++ b/src/mod_announce.erl
@@ -5,7 +5,7 @@
%%% Created : 11 Aug 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_caps.erl b/src/mod_caps.erl
index 852ae7e48..d58b23587 100644
--- a/src/mod_caps.erl
+++ b/src/mod_caps.erl
@@ -5,7 +5,7 @@
%%% Created : 7 Oct 2006 by Magnus Henoch
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
index f960eb08e..b1cb0cced 100644
--- a/src/mod_configure.erl
+++ b/src/mod_configure.erl
@@ -5,7 +5,7 @@
%%% Created : 19 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_configure2.erl b/src/mod_configure2.erl
index 9acec3fc1..919927c38 100644
--- a/src/mod_configure2.erl
+++ b/src/mod_configure2.erl
@@ -5,7 +5,7 @@
%%% Created : 26 Oct 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index 6907a4176..e1539fbd3 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -5,7 +5,7 @@
%%% Created : 1 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_echo.erl b/src/mod_echo.erl
index fc043370c..9e9748b55 100644
--- a/src/mod_echo.erl
+++ b/src/mod_echo.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Jan 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_ip_blacklist.erl b/src/mod_ip_blacklist.erl
index 6a0cc3947..17280857e 100644
--- a/src/mod_ip_blacklist.erl
+++ b/src/mod_ip_blacklist.erl
@@ -7,7 +7,7 @@
%%% {mod_ip_blacklist, []}
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_irc/iconv.erl b/src/mod_irc/iconv.erl
index 9c500978e..77c1ea56c 100644
--- a/src/mod_irc/iconv.erl
+++ b/src/mod_irc/iconv.erl
@@ -5,7 +5,7 @@
%%% Created : 16 Feb 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_irc/iconv_erl.c b/src/mod_irc/iconv_erl.c
index 3cf82f4d5..3835aecbd 100644
--- a/src/mod_irc/iconv_erl.c
+++ b/src/mod_irc/iconv_erl.c
@@ -1,5 +1,5 @@
/*
- * ejabberd, Copyright (C) 2002-2008 Process-one
+ * ejabberd, Copyright (C) 2002-2008 ProcessOne
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
diff --git a/src/mod_irc/mod_irc.erl b/src/mod_irc/mod_irc.erl
index 4b2ae6adf..dd86037b9 100644
--- a/src/mod_irc/mod_irc.erl
+++ b/src/mod_irc/mod_irc.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Feb 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl
index f62d99bde..244f5300d 100644
--- a/src/mod_irc/mod_irc_connection.erl
+++ b/src/mod_irc/mod_irc_connection.erl
@@ -5,7 +5,7 @@
%%% Created : 15 Feb 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_last.erl b/src/mod_last.erl
index b35ea1150..cfdfa65e9 100644
--- a/src/mod_last.erl
+++ b/src/mod_last.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Oct 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_last_odbc.erl b/src/mod_last_odbc.erl
index 76489b4c0..f2ac26114 100644
--- a/src/mod_last_odbc.erl
+++ b/src/mod_last_odbc.erl
@@ -5,7 +5,7 @@
%%% Created : 24 Oct 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -111,8 +111,6 @@ process_sm_iq(From, To, IQ) ->
get_last(IQ, LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_last(LServer, Username) of
- {'EXIT', _Reason} ->
- exmpp_iq:error(IQ, 'internal-server-error');
{selected, ["seconds","state"], []} ->
exmpp_iq:error(IQ, 'service-unavailable');
{selected, ["seconds","state"], [{STimeStamp, Status}]} ->
@@ -127,7 +125,9 @@ get_last(IQ, LUser, LServer) ->
exmpp_iq:result(IQ, Response);
_ ->
exmpp_iq:error(IQ, 'internal-server-error')
- end
+ end;
+ _ ->
+ exmpp_iq:error(IQ, 'internal-server-error')
end.
on_presence_update(User, Server, _Resource, Status) ->
@@ -147,8 +147,6 @@ store_last_info(User, Server, TimeStamp, Status) ->
get_last_info(LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_last(LServer, Username) of
- {'EXIT', _Reason} ->
- not_found;
{selected, ["seconds","state"], []} ->
not_found;
{selected, ["seconds","state"], [{STimeStamp, Status}]} ->
@@ -157,7 +155,9 @@ get_last_info(LUser, LServer) ->
{ok, TimeStamp, Status};
_ ->
not_found
- end
+ end;
+ _ ->
+ not_found
end.
remove_user(User, Server) ->
diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl
index 90a74b70f..812c8de97 100644
--- a/src/mod_muc/mod_muc.erl
+++ b/src/mod_muc/mod_muc.erl
@@ -5,7 +5,7 @@
%%% Created : 19 Mar 2003 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/src/mod_muc/mod_muc_log.erl b/src/mod_muc/mod_muc_log.erl
index 9ab8d4ce2..e76904193 100644
--- a/src/mod_muc/mod_muc_log.erl
+++ b/src/mod_muc/mod_muc_log.erl
@@ -5,7 +5,7 @@
%%% Created : 12 Mar 2006 by Alexey Shchepin
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2008 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -52,6 +52,8 @@
-record(state, {host,
out_dir,
dir_type,
+ dir_name,
+ file_format,
css_file,
access,
lang,
@@ -113,6 +115,8 @@ check_access_log(Host, From) ->
init([Host, Opts]) ->
OutDir = gen_mod:get_opt(outdir, Opts, "www/muc"),
DirType = gen_mod:get_opt(dirtype, Opts, subdirs),
+ DirName = gen_mod:get_opt(dirname, Opts, room_jid),
+ FileFormat = gen_mod:get_opt(file_format, Opts, html), % Allowed values: html|plaintext
CSSFile = gen_mod:get_opt(cssfile, Opts, false),
AccessLog = gen_mod:get_opt(access_log, Opts, muc_admin),
Timezone = gen_mod:get_opt(timezone, Opts, local),
@@ -129,6 +133,8 @@ init([Host, Opts]) ->
{ok, #state{host = Host,
out_dir = OutDir,
dir_type = DirType,
+ dir_name = DirName,
+ file_format = FileFormat,
css_file = CSSFile,
access = AccessLog,
lang = Lang,
@@ -231,10 +237,10 @@ add_to_log2(kickban, {Nick, Reason, Code}, Room, Opts, State) ->
%%----------------------------------------------------------------------
%% Core
-build_filename_string(TimeStamp, OutDir, RoomJID, DirType) ->
+build_filename_string(TimeStamp, OutDir, RoomJID, DirType, DirName, FileFormat) ->
{{Year, Month, Day}, _Time} = TimeStamp,
- % Directory and file names
+ %% Directory and file names
{Dir, Filename, Rel} =
case DirType of
subdirs ->
@@ -248,55 +254,75 @@ build_filename_string(TimeStamp, OutDir, RoomJID, DirType) ->
[Year, Month, Day])),
{"", Date, "."}
end,
- Fd = filename:join([OutDir, RoomJID, Dir]),
- Fn = filename:join([Fd, Filename ++ ".html"]),
- Fnrel = filename:join([Rel, Dir, Filename ++ ".html"]),
+
+ RoomString = case DirName of
+ room_jid -> RoomJID;
+ room_name -> get_room_name(RoomJID)
+ end,
+ Extension = case FileFormat of
+ html -> ".html";
+ plaintext -> ".txt"
+ end,
+ Fd = filename:join([OutDir, RoomString, Dir]),
+ Fn = filename:join([Fd, Filename ++ Extension]),
+ Fnrel = filename:join([Rel, Dir, Filename ++ Extension]),
{Fd, Fn, Fnrel}.
-% calculate day before
+get_room_name(RoomJID) ->
+ JID = jlib:string_to_jid(RoomJID),
+ JID#jid.user.
+
+%% calculate day before
get_timestamp_daydiff(TimeStamp, Daydiff) ->
{Date1, HMS} = TimeStamp,
Date2 = calendar:gregorian_days_to_date(
calendar:date_to_gregorian_days(Date1) + Daydiff),
{Date2, HMS}.
-% Try to close the previous day log, if it exists
-close_previous_log(Fn, Images_dir) ->
+%% Try to close the previous day log, if it exists
+close_previous_log(Fn, Images_dir, FileFormat) ->
case file:read_file_info(Fn) of
{ok, _} ->
{ok, F} = file:open(Fn, [append]),
- %fw(F, "ejabberd/mod_muc log
"),
- fw(F, ""),
- fw(F, "
", [Images_dir]),
- fw(F, "
", [Images_dir]),
- fw(F, "
"),
- fw(F, " ", [Images_dir]),
- fw(F, " ", [Images_dir]),
- fw(F, "