From c1d479f8631e76993f1bd441e28a2b5cd2800551 Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 13 Oct 2011 17:56:19 +0200 Subject: [PATCH 01/30] Set ejabberd version to 2.1.x --- doc/dev.html | 4 ++-- doc/features.html | 4 ++-- doc/guide.html | 4 ++-- doc/version.tex | 2 +- src/ejabberd.app | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/dev.html b/doc/dev.html index adc826cc7..b86448c56 100644 --- a/doc/dev.html +++ b/doc/dev.html @@ -2,7 +2,7 @@ "http://www.w3.org/TR/REC-html40/loose.dtd"> -Ejabberd 2.1.9 Developers Guide +<TITLE>Ejabberd 2.1.x Developers Guide @@ -49,7 +49,7 @@ TD P{margin:0px;}

-

Ejabberd 2.1.9 Developers Guide

Alexey Shchepin
+

Ejabberd 2.1.x Developers Guide

Alexey Shchepin
mailto:alexey@sevcom.net
xmpp:aleksey@jabber.ru

diff --git a/doc/features.html b/doc/features.html index 520514375..503ac0d3f 100644 --- a/doc/features.html +++ b/doc/features.html @@ -2,7 +2,7 @@ "http://www.w3.org/TR/REC-html40/loose.dtd"> -Ejabberd 2.1.9 Feature Sheet +<TITLE>Ejabberd 2.1.x Feature Sheet @@ -50,7 +50,7 @@ SPAN{width:20%; float:right; text-align:left; margin-left:auto;}

-

Ejabberd 2.1.9 Feature Sheet

Sander Devrieze
+

Ejabberd 2.1.x Feature Sheet

Sander Devrieze
mailto:s.devrieze@pandora.be
xmpp:sander@devrieze.dyndns.org

diff --git a/doc/guide.html b/doc/guide.html index c2eb4bf6d..58f5cb2c2 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -6,7 +6,7 @@ - ejabberd 2.1.9 + ejabberd 2.1.x Installation and Operation Guide @@ -76,7 +76,7 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}


- +
ejabberd 2.1.9
ejabberd 2.1.x
 
Installation and Operation Guide

diff --git a/doc/version.tex b/doc/version.tex index ebaed03ec..905ac86f2 100644 --- a/doc/version.tex +++ b/doc/version.tex @@ -1,2 +1,2 @@ % ejabberd version (automatically generated). -\newcommand{\version}{2.1.9} +\newcommand{\version}{2.1.x} diff --git a/src/ejabberd.app b/src/ejabberd.app index ea755a7b9..3fb342fe8 100644 --- a/src/ejabberd.app +++ b/src/ejabberd.app @@ -2,7 +2,7 @@ {application, ejabberd, [{description, "ejabberd"}, - {vsn, "2.1.9"}, + {vsn, "2.1.x"}, {modules, [acl, adhoc, configure, From 96800e9b7573616732c9cfbf9917849aa80fdccc Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Fri, 14 Oct 2011 16:57:51 +1000 Subject: [PATCH 02/30] Get rid of useless mnesia transaction (EJAB-1502) --- src/web/ejabberd_http_bind.erl | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/web/ejabberd_http_bind.erl b/src/web/ejabberd_http_bind.erl index 6244bf12f..63b608682 100644 --- a/src/web/ejabberd_http_bind.erl +++ b/src/web/ejabberd_http_bind.erl @@ -283,19 +283,16 @@ handle_session_start(Pid, XmppDomain, Sid, Rid, Attrs, end, XmppVersion = xml:get_attr_s("xmpp:version", Attrs), ?DEBUG("Create session: ~p", [Sid]), - mnesia:transaction( - fun() -> - mnesia:write( - #http_bind{id = Sid, - pid = Pid, - to = {XmppDomain, - XmppVersion}, - hold = Hold, - wait = Wait, - process_delay = Pdelay, - version = Version - }) - end), + mnesia:dirty_write( + #http_bind{id = Sid, + pid = Pid, + to = {XmppDomain, + XmppVersion}, + hold = Hold, + wait = Wait, + process_delay = Pdelay, + version = Version + }), handle_http_put(Sid, Rid, Attrs, Payload, PayloadSize, true, IP). %%%---------------------------------------------------------------------- From 98b150e1a4818e133c70540c696f30f49a41b44b Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 20 Oct 2011 15:45:17 +0200 Subject: [PATCH 03/30] Fix extraction of language name from PO files --- contrib/extract_translations/extract_translations.erl | 2 +- contrib/extract_translations/prepare-translation.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/extract_translations/extract_translations.erl b/contrib/extract_translations/extract_translations.erl index 488357ba6..3efaace85 100644 --- a/contrib/extract_translations/extract_translations.erl +++ b/contrib/extract_translations/extract_translations.erl @@ -254,7 +254,7 @@ get_msg_header_props(F, Lines) -> end. prepare_props(MsgProps) -> - Language = proplists:get_value("Language:", MsgProps), + Language = proplists:get_value("X-Language:", MsgProps), Authors = proplists:get_all_values("Author:", MsgProps), {Language, Authors}. diff --git a/contrib/extract_translations/prepare-translation.sh b/contrib/extract_translations/prepare-translation.sh index 7a40fee78..9f2d54ad6 100755 --- a/contrib/extract_translations/prepare-translation.sh +++ b/contrib/extract_translations/prepare-translation.sh @@ -91,7 +91,7 @@ extract_lang_all () cd $MSGS_DIR for i in $( ls *.msg ) ; do MISSING=`cat $i.translate | grep "\", \"\"}." | wc -l` - LANGUAGE=`grep "Language:" $i.translate | sed 's/% Language: //g'` + LANGUAGE=`grep "X-Language:" $i.translate | sed 's/% Language: //g'` LASTAUTH=`grep "Author:" $i.translate | head -n 1 | sed 's/% Author: //g'` echo -e "$i\t$MISSING\t$LANGUAGE\t$LASTAUTH" done @@ -258,7 +258,7 @@ extract_lang_updateall () 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}'` + LANGUAGE=`grep "X-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'` From 1a419972d265f7aa099a486ad446e8a43e938f21 Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 20 Oct 2011 16:28:53 +0200 Subject: [PATCH 04/30] Fix previous commit about language name --- contrib/extract_translations/extract_translations.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/extract_translations/extract_translations.erl b/contrib/extract_translations/extract_translations.erl index 3efaace85..488357ba6 100644 --- a/contrib/extract_translations/extract_translations.erl +++ b/contrib/extract_translations/extract_translations.erl @@ -254,7 +254,7 @@ get_msg_header_props(F, Lines) -> end. prepare_props(MsgProps) -> - Language = proplists:get_value("X-Language:", MsgProps), + Language = proplists:get_value("Language:", MsgProps), Authors = proplists:get_all_values("Author:", MsgProps), {Language, Authors}. From 0656377165f73ca7f201b6059bc44c78faebda72 Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 3 Nov 2011 19:46:59 +0100 Subject: [PATCH 05/30] Support to update modules in R14B04 and higher --- src/ejabberd_update.erl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/ejabberd_update.erl b/src/ejabberd_update.erl index fc3c3306a..f88af2aca 100644 --- a/src/ejabberd_update.erl +++ b/src/ejabberd_update.erl @@ -41,7 +41,7 @@ update() -> case update_info() of {ok, Dir, _UpdatedBeams, _Script, LowLevelScript, _Check} -> Eval = - release_handler_1:eval_script( + eval_script( LowLevelScript, [], [{ejabberd, "", filename:join(Dir, "..")}]), ?INFO_MSG("eval: ~p~n", [Eval]), @@ -58,7 +58,7 @@ update(ModulesToUpdate) -> [A || A <- UpdatedBeamsAll, B <- ModulesToUpdate, A == B], {_, LowLevelScript, _} = build_script(Dir, UpdatedBeamsNow), Eval = - release_handler_1:eval_script( + eval_script( LowLevelScript, [], [{ejabberd, "", filename:join(Dir, "..")}]), ?INFO_MSG("eval: ~p~n", [Eval]), @@ -67,6 +67,16 @@ update(ModulesToUpdate) -> {error, Reason} end. +%% OTP R14B03 and older provided release_handler_1:eval_script/3 +%% But OTP R14B04 and newer provide release_handler_1:eval_script/5 +eval_script(Script, Apps, LibDirs) -> + case lists:member({eval_script, 5}, release_handler_1:module_info(exports)) of + true -> + release_handler_1:eval_script(Script, Apps, LibDirs, [], []); + false -> + release_handler_1:eval_script(Script, Apps, LibDirs) + end. + %% Get information about the modified modules update_info() -> Dir = filename:dirname(code:which(ejabberd)), @@ -134,6 +144,10 @@ build_script(Dir, UpdatedBeams) -> ?DEBUG("script: ~p~n", [Script]), ?DEBUG("low level script: ~p~n", [LowLevelScript]), ?DEBUG("check: ~p~n", [Check]); + {ok, []} -> + ?DEBUG("script: ~p~n", [Script]), + ?DEBUG("low level script: ~p~n", [LowLevelScript]), + ?DEBUG("check: ~p~n", [Check]); _ -> ?ERROR_MSG("script: ~p~n", [Script]), ?ERROR_MSG("low level script: ~p~n", [LowLevelScript]), From 944791e88805fc6f7f18f3236648e1f061299833 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Wed, 9 Nov 2011 15:09:02 +1000 Subject: [PATCH 06/30] Fix presence problem after first unavailable (thanks to Christopher Faulet) (EJAB-1466) --- src/ejabberd_c2s.erl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index b093648d2..1c08b47c8 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -1785,10 +1785,10 @@ presence_update(From, Packet, StateData) -> FromUnavail = (StateData#state.pres_last == undefined) or StateData#state.pres_invis, ?DEBUG("from unavail = ~p~n", [FromUnavail]), + NewStateData = StateData#state{pres_last = Packet, + pres_invis = false, + pres_timestamp = Timestamp}, NewState = - NewStateData = StateData#state{pres_last = Packet, - pres_invis = false, - pres_timestamp = Timestamp}, if FromUnavail -> ejabberd_hooks:run(user_available_hook, From 07cfc000ea6e4b419393a928946e4f7a2e22d411 Mon Sep 17 00:00:00 2001 From: Badlop Date: Tue, 15 Nov 2011 16:46:00 +0100 Subject: [PATCH 07/30] Comment section 6.3.1 because it has no content at all --- doc/guide.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/guide.tex b/doc/guide.tex index afbbbd997..6d12ed2cd 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -5685,7 +5685,8 @@ domain. \makesection{servicelb}{Service Load-Balancing} \ind{component load-balancing} -\makesubsection{componentlb}{Components Load-Balancing} +% This section never had content, should it? +% \makesubsection{componentlb}{Components Load-Balancing} \makesubsection{domainlb}{Domain Load-Balancing Algorithm} \ind{options!domain\_balancing} From 1f97740cfa9ba1609a84098368b852fc63efdba7 Mon Sep 17 00:00:00 2001 From: Badlop Date: Sat, 26 Nov 2011 17:03:24 +0100 Subject: [PATCH 08/30] Avoid a possible race condition --- src/mod_ip_blacklist.erl | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/mod_ip_blacklist.erl b/src/mod_ip_blacklist.erl index eac61a766..718a25b1e 100644 --- a/src/mod_ip_blacklist.erl +++ b/src/mod_ip_blacklist.erl @@ -33,6 +33,7 @@ %% API: -export([start/2, + preinit/2, init/1, stop/1]). -export([update_bl_c2s/0]). @@ -49,14 +50,20 @@ -record(bl_c2s, {ip}). %% Start once for all vhost -start(Host, Opts) -> - case whereis(?PROCNAME) of - undefined -> - ?DEBUG("Starting mod_ip_blacklist ~p ~p~n", [Host, Opts]), - register(?PROCNAME, - spawn(?MODULE, init, [#state{}])); - _ -> - ok +start(_Host, _Opts) -> + Pid = spawn(?MODULE, preinit, [self(), #state{}]), + receive {ok, Pid, PreinitResult} -> + PreinitResult + end. + +preinit(Parent, State) -> + Pid = self(), + try register(?PROCNAME, Pid) of + true -> + Parent ! {ok, Pid, true}, + init(State) + catch error:_ -> + Parent ! {ok, Pid, true} end. %% TODO: From ee968b5573770dcf2ab5dacb01416758b2fa0b9a Mon Sep 17 00:00:00 2001 From: Badlop Date: Sat, 26 Nov 2011 17:08:10 +0100 Subject: [PATCH 09/30] Fix error in mod_vcard when lowercasing some vjud search result fields (EJAB-1490) --- src/mod_vcard.erl | 46 +++++++++++++++++++++--------------------- src/mod_vcard_odbc.erl | 24 +++++++++++----------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 77dc30b15..1820f64b8 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -219,17 +219,17 @@ set_vcard(User, LServer, VCARD) -> 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), + LFN = string:to_lower(FN), + LFamily = string:to_lower(Family), + LGiven = string:to_lower(Given), + LMiddle = string:to_lower(Middle), + LNickname = string:to_lower(Nickname), + LBDay = string:to_lower(BDay), + LCTRY = string:to_lower(CTRY), + LLocality = string:to_lower(Locality), + LEMail = string:to_lower(EMail), + LOrgName = string:to_lower(OrgName), + LOrgUnit = string:to_lower(OrgUnit), US = {LUser, LServer}, @@ -541,7 +541,7 @@ filter_fields([], Match, _LServer) -> Match; filter_fields([{SVar, [Val]} | Ds], Match, LServer) when is_list(Val) and (Val /= "") -> - LVal = stringprep:tolower(Val), + LVal = string:to_lower(Val), NewMatch = case SVar of "user" -> case gen_mod:get_module_opt(LServer, ?MODULE, @@ -618,17 +618,17 @@ set_vcard_t(R, _) -> OrgUnit = xml:get_path_s(VCARD, [{elem, "ORG"}, {elem, "ORGUNIT"}, cdata]), {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), + LFN = string:to_lower(FN), + LFamily = string:to_lower(Family), + LGiven = string:to_lower(Given), + LMiddle = string:to_lower(Middle), + LNickname = string:to_lower(Nickname), + LBDay = string:to_lower(BDay), + LCTRY = string:to_lower(CTRY), + LLocality = string:to_lower(Locality), + LEMail = string:to_lower(EMail), + LOrgName = string:to_lower(OrgName), + LOrgUnit = string:to_lower(OrgUnit), if (LUser == error) or diff --git a/src/mod_vcard_odbc.erl b/src/mod_vcard_odbc.erl index c35f27362..a4c23624c 100644 --- a/src/mod_vcard_odbc.erl +++ b/src/mod_vcard_odbc.erl @@ -186,17 +186,17 @@ set_vcard(User, LServer, VCARD) -> 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), + LFN = string:to_lower(FN), + LFamily = string:to_lower(Family), + LGiven = string:to_lower(Given), + LMiddle = string:to_lower(Middle), + LNickname = string:to_lower(Nickname), + LBDay = string:to_lower(BDay), + LCTRY = string:to_lower(CTRY), + LLocality = string:to_lower(Locality), + LEMail = string:to_lower(EMail), + LOrgName = string:to_lower(OrgName), + LOrgUnit = string:to_lower(OrgUnit), if (LUser == error) or @@ -531,7 +531,7 @@ filter_fields([], Match, _LServer) -> end; filter_fields([{SVar, [Val]} | Ds], Match, LServer) when is_list(Val) and (Val /= "") -> - LVal = stringprep:tolower(Val), + LVal = string:to_lower(Val), NewMatch = case SVar of "user" -> make_val(Match, "lusername", LVal); "fn" -> make_val(Match, "lfn", LVal); From b89d4c7476373207e5397ceb7b0a014fdd372758 Mon Sep 17 00:00:00 2001 From: Badlop Date: Sat, 26 Nov 2011 17:20:06 +0100 Subject: [PATCH 10/30] Use httpc instead of the deprecated http --- src/mod_ip_blacklist.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod_ip_blacklist.erl b/src/mod_ip_blacklist.erl index 718a25b1e..f8e73e1d3 100644 --- a/src/mod_ip_blacklist.erl +++ b/src/mod_ip_blacklist.erl @@ -92,7 +92,7 @@ loop(_State) -> %% TODO: Support comment lines starting by % update_bl_c2s() -> ?INFO_MSG("Updating C2S Blacklist", []), - case http:request(?BLC2S) of + case httpc:request(?BLC2S) of {ok, {{_Version, 200, _Reason}, _Headers, Body}} -> IPs = string:tokens(Body,"\n"), ets:delete_all_objects(bl_c2s), From 89e4e822bfac0b6a4e88faf12bdc8543cf693a65 Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Tue, 29 Nov 2011 14:13:13 +0100 Subject: [PATCH 11/30] add hooks for node creation/deletion (EJAB-1470) --- src/mod_pubsub/mod_pubsub.erl | 29 ++++++-- src/mod_pubsub/mod_pubsub_odbc.erl | 29 ++++++-- src/mod_pubsub/pubsub_odbc.patch | 102 ++++++++++++++--------------- 3 files changed, 95 insertions(+), 65 deletions(-) diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl index d7643c21c..2944a9a2a 100644 --- a/src/mod_pubsub/mod_pubsub.erl +++ b/src/mod_pubsub/mod_pubsub.erl @@ -219,6 +219,7 @@ init([ServerHost, Opts]) -> ejabberd_router:register_route(Host), update_node_database(Host, ServerHost), update_state_database(Host, ServerHost), + put(server_host, ServerHost), % not clean, but needed to plug hooks at any location init_nodes(Host, ServerHost, NodeTree, Plugins), State = #state{host = Host, server_host = ServerHost, @@ -1783,13 +1784,16 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> case transaction(CreateNode, transaction) of {result, {NodeId, SubsByDepth, {Result, broadcast}}} -> broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth), + ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), case Result of default -> {result, Reply}; _ -> {result, Result} end; - {result, {_NodeId, _SubsByDepth, default}} -> + {result, {NodeId, _SubsByDepth, default}} -> + ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), {result, Reply}; - {result, {_NodeId, _SubsByDepth, Result}} -> + {result, {NodeId, _SubsByDepth, Result}} -> + ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), {result, Result}; Error -> %% in case we change transaction to sync_dirty... @@ -1834,27 +1838,38 @@ delete_node(Host, Node, Owner) -> end end, Reply = [], + ServerHost = get(server_host), % not clean, but prevent many API changes case transaction(Host, Node, Action, transaction) of - {result, {_, {SubsByDepth, {Result, broadcast, Removed}}}} -> + {result, {_TNode, {SubsByDepth, {Result, broadcast, Removed}}}} -> lists:foreach(fun({RNode, _RSubscriptions}) -> {RH, RN} = RNode#pubsub_node.nodeid, NodeId = RNode#pubsub_node.id, Type = RNode#pubsub_node.type, Options = RNode#pubsub_node.options, - broadcast_removed_node(RH, RN, NodeId, Type, Options, SubsByDepth) + broadcast_removed_node(RH, RN, NodeId, Type, Options, SubsByDepth), + ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, RH, RN, NodeId]) end, Removed), case Result of default -> {result, Reply}; _ -> {result, Result} end; - {result, {_, {_, {Result, _Removed}}}} -> + {result, {_TNode, {_, {Result, Removed}}}} -> + lists:foreach(fun({RNode, _RSubscriptions}) -> + {RH, RN} = RNode#pubsub_node.nodeid, + NodeId = RNode#pubsub_node.id, + ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, RH, RN, NodeId]) + end, Removed), case Result of default -> {result, Reply}; _ -> {result, Result} end; - {result, {_, {_, default}}} -> + {result, {TNode, {_, default}}} -> + NodeId = TNode#pubsub_node.id, + ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, Host, Node, NodeId]), {result, Reply}; - {result, {_, {_, Result}}} -> + {result, {TNode, {_, Result}}} -> + NodeId = TNode#pubsub_node.id, + ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, Host, Node, NodeId]), {result, Result}; Error -> Error diff --git a/src/mod_pubsub/mod_pubsub_odbc.erl b/src/mod_pubsub/mod_pubsub_odbc.erl index b8cf4899b..1851ed322 100644 --- a/src/mod_pubsub/mod_pubsub_odbc.erl +++ b/src/mod_pubsub/mod_pubsub_odbc.erl @@ -217,6 +217,7 @@ init([ServerHost, Opts]) -> ok end, ejabberd_router:register_route(Host), + put(server_host, ServerHost), % not clean, but needed to plug hooks at any location init_nodes(Host, ServerHost, NodeTree, Plugins), State = #state{host = Host, server_host = ServerHost, @@ -1598,13 +1599,16 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> case transaction(Host, CreateNode, transaction) of {result, {NodeId, SubsByDepth, {Result, broadcast}}} -> broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth), + ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), case Result of default -> {result, Reply}; _ -> {result, Result} end; - {result, {_NodeId, _SubsByDepth, default}} -> + {result, {NodeId, _SubsByDepth, default}} -> + ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), {result, Reply}; - {result, {_NodeId, _SubsByDepth, Result}} -> + {result, {NodeId, _SubsByDepth, Result}} -> + ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), {result, Result}; Error -> %% in case we change transaction to sync_dirty... @@ -1649,27 +1653,38 @@ delete_node(Host, Node, Owner) -> end end, Reply = [], + ServerHost = get(server_host), % not clean, but prevent many API changes case transaction(Host, Node, Action, transaction) of - {result, {_, {SubsByDepth, {Result, broadcast, Removed}}}} -> + {result, {_TNode, {SubsByDepth, {Result, broadcast, Removed}}}} -> lists:foreach(fun({RNode, _RSubscriptions}) -> {RH, RN} = RNode#pubsub_node.nodeid, NodeId = RNode#pubsub_node.id, Type = RNode#pubsub_node.type, Options = RNode#pubsub_node.options, - broadcast_removed_node(RH, RN, NodeId, Type, Options, SubsByDepth) + broadcast_removed_node(RH, RN, NodeId, Type, Options, SubsByDepth), + ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, RH, RN, NodeId]) end, Removed), case Result of default -> {result, Reply}; _ -> {result, Result} end; - {result, {_, {_, {Result, _Removed}}}} -> + {result, {_TNode, {_, {Result, Removed}}}} -> + lists:foreach(fun({RNode, _RSubscriptions}) -> + {RH, RN} = RNode#pubsub_node.nodeid, + NodeId = RNode#pubsub_node.id, + ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, RH, RN, NodeId]) + end, Removed), case Result of default -> {result, Reply}; _ -> {result, Result} end; - {result, {_, {_, default}}} -> + {result, {TNode, {_, default}}} -> + NodeId = TNode#pubsub_node.id, + ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, Host, Node, NodeId]), {result, Reply}; - {result, {_, {_, Result}}} -> + {result, {TNode, {_, Result}}} -> + NodeId = TNode#pubsub_node.id, + ejabberd_hooks:run(pubsub_delete_node, ServerHost, [ServerHost, Host, Node, NodeId]), {result, Result}; Error -> Error diff --git a/src/mod_pubsub/pubsub_odbc.patch b/src/mod_pubsub/pubsub_odbc.patch index cfa58640f..3e9b515c7 100644 --- a/src/mod_pubsub/pubsub_odbc.patch +++ b/src/mod_pubsub/pubsub_odbc.patch @@ -1,5 +1,5 @@ ---- mod_pubsub.erl 2011-09-21 14:37:16.000000000 +0200 -+++ mod_pubsub_odbc.erl 2011-09-21 14:37:36.000000000 +0200 +--- mod_pubsub.erl 2011-11-29 14:10:41.000000000 +0100 ++++ mod_pubsub_odbc.erl 2011-11-29 14:12:01.000000000 +0100 @@ -42,7 +42,7 @@ %%% 6.2.3.1, 6.2.3.5, and 6.3. For information on subscription leases see %%% XEP-0060 section 12.18. @@ -46,10 +46,10 @@ ejabberd_router:register_route(Host), - update_node_database(Host, ServerHost), - update_state_database(Host, ServerHost), + put(server_host, ServerHost), % not clean, but needed to plug hooks at any location init_nodes(Host, ServerHost, NodeTree, Plugins), State = #state{host = Host, - server_host = ServerHost, -@@ -282,207 +280,14 @@ +@@ -283,207 +281,14 @@ init_nodes(Host, ServerHost, _NodeTree, Plugins) -> %% TODO, this call should be done plugin side @@ -260,7 +260,7 @@ send_loop(State) -> receive {presence, JID, Pid} -> -@@ -493,17 +298,15 @@ +@@ -494,17 +299,15 @@ %% for each node From is subscribed to %% and if the node is so configured, send the last published item to From lists:foreach(fun(PType) -> @@ -284,7 +284,7 @@ true -> % resource not concerned about that subscription ok -@@ -622,7 +425,8 @@ +@@ -623,7 +426,8 @@ disco_identity(_Host, <<>>, _From) -> [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}]; disco_identity(Host, Node, From) -> @@ -294,7 +294,7 @@ case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, [{xmlelement, "identity", [{"category", "pubsub"}, {"type", "pep"}], []}, -@@ -657,7 +461,8 @@ +@@ -658,7 +462,8 @@ [?NS_PUBSUB | [?NS_PUBSUB++"#"++Feature || Feature <- features("pep")]]; disco_features(Host, Node, From) -> @@ -304,7 +304,7 @@ case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> {result, [?NS_PUBSUB -@@ -682,7 +487,8 @@ +@@ -683,7 +488,8 @@ Acc. disco_items(Host, <<>>, From) -> @@ -314,7 +314,7 @@ case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, _} -> [{xmlelement, "item", -@@ -700,13 +506,14 @@ +@@ -701,13 +507,14 @@ _ -> Acc end end, @@ -331,7 +331,7 @@ case get_allowed_items_call(Host, Idx, From, Type, Options, Owners) of {result, Items} -> {result, [{xmlelement, "item", -@@ -792,10 +599,10 @@ +@@ -793,10 +600,10 @@ lists:foreach(fun(PType) -> {result, Subscriptions} = node_action(Host, PType, get_entity_subscriptions, [Host, Entity]), lists:foreach(fun @@ -344,7 +344,7 @@ true -> node_action(Host, PType, unsubscribe_node, [NodeId, Entity, JID, all]); false -> -@@ -963,7 +770,8 @@ +@@ -964,7 +771,8 @@ sub_el = SubEl} = IQ -> {xmlelement, _, QAttrs, _} = SubEl, Node = xml:get_attr_s("node", QAttrs), @@ -354,7 +354,7 @@ {result, IQRes} -> jlib:iq_to_xml( IQ#iq{type = result, -@@ -1076,7 +884,7 @@ +@@ -1077,7 +885,7 @@ [] -> ["leaf"]; %% No sub-nodes: it's a leaf node _ -> @@ -363,7 +363,7 @@ {result, []} -> ["collection"]; {result, _} -> ["leaf", "collection"]; _ -> [] -@@ -1092,8 +900,9 @@ +@@ -1093,8 +901,9 @@ []; true -> [{xmlelement, "feature", [{"var", ?NS_PUBSUB}], []} | @@ -375,7 +375,7 @@ end, features(Type))] end, %% TODO: add meta-data info (spec section 5.4) -@@ -1122,8 +931,9 @@ +@@ -1123,8 +932,9 @@ {xmlelement, "feature", [{"var", ?NS_PUBSUB}], []}, {xmlelement, "feature", [{"var", ?NS_COMMANDS}], []}, {xmlelement, "feature", [{"var", ?NS_VCARD}], []}] ++ @@ -387,7 +387,7 @@ end, features(Host, Node))}; <> -> command_disco_info(Host, Node, From); -@@ -1133,7 +943,7 @@ +@@ -1134,7 +944,7 @@ node_disco_info(Host, Node, From) end. @@ -396,7 +396,7 @@ case tree_action(Host, get_subnodes, [Host, <<>>, From]) of Nodes when is_list(Nodes) -> {result, lists:map( -@@ -1150,23 +960,24 @@ +@@ -1151,23 +961,24 @@ Other -> Other end; @@ -427,7 +427,7 @@ end, Nodes = lists:map( fun(#pubsub_node{nodeid = {_, SubNode}, options = SubOptions}) -> -@@ -1184,7 +995,7 @@ +@@ -1185,7 +996,7 @@ {result, Name} = node_call(Type, get_item_name, [Host, Node, RN]), {xmlelement, "item", [{"jid", Host}, {"name", Name}], []} end, NodeItems), @@ -436,7 +436,7 @@ end, case transaction(Host, Node, Action, sync_dirty) of {result, {_, Result}} -> {result, Result}; -@@ -1295,7 +1106,8 @@ +@@ -1296,7 +1107,8 @@ (_, Acc) -> Acc end, [], xml:remove_cdata(Els)), @@ -446,7 +446,7 @@ {get, "subscriptions"} -> get_subscriptions(Host, Node, From, Plugins); {get, "affiliations"} -> -@@ -1318,7 +1130,9 @@ +@@ -1319,7 +1131,9 @@ iq_pubsub_owner(Host, ServerHost, From, IQType, SubEl, Lang) -> {xmlelement, _, _, SubEls} = SubEl, @@ -457,7 +457,7 @@ case Action of [{xmlelement, Name, Attrs, Els}] -> Node = string_to_node(xml:get_attr_s("node", Attrs)), -@@ -1448,7 +1262,8 @@ +@@ -1449,7 +1263,8 @@ _ -> [] end end, @@ -467,7 +467,7 @@ sync_dirty) of {result, Res} -> Res; Err -> Err -@@ -1487,7 +1302,7 @@ +@@ -1488,7 +1303,7 @@ %%% authorization handling @@ -476,7 +476,7 @@ Lang = "en", %% TODO fix Stanza = {xmlelement, "message", [], -@@ -1516,7 +1331,7 @@ +@@ -1517,7 +1332,7 @@ [{xmlelement, "value", [], [{xmlcdata, "false"}]}]}]}]}, lists:foreach(fun(Owner) -> ejabberd_router:route(service_jid(Host), jlib:make_jid(Owner), Stanza) @@ -485,7 +485,7 @@ find_authorization_response(Packet) -> {xmlelement, _Name, _Attrs, Els} = Packet, -@@ -1580,8 +1395,8 @@ +@@ -1581,8 +1396,8 @@ "true" -> true; _ -> false end, @@ -496,7 +496,7 @@ {result, Subscriptions} = node_call(Type, get_subscriptions, [NodeId, Subscriber]), if not IsApprover -> -@@ -1780,7 +1595,7 @@ +@@ -1781,7 +1596,7 @@ Reply = [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "create", nodeAttr(Node), []}]}], @@ -504,8 +504,8 @@ + case transaction(Host, CreateNode, transaction) of {result, {NodeId, SubsByDepth, {Result, broadcast}}} -> broadcast_created_node(Host, Node, NodeId, Type, NodeOptions, SubsByDepth), - case Result of -@@ -1883,7 +1698,7 @@ + ejabberd_hooks:run(pubsub_create_node, ServerHost, [ServerHost, Host, Node, NodeId, NodeOptions]), +@@ -1898,7 +1713,7 @@ %%
  • The node does not exist.
  • %% subscribe_node(Host, Node, From, JID, Configuration) -> @@ -514,7 +514,7 @@ {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, -@@ -1891,7 +1706,7 @@ +@@ -1906,7 +1721,7 @@ error -> {"", "", ""}; J -> jlib:jid_tolower(J) end, @@ -523,7 +523,7 @@ Features = features(Type), SubscribeFeature = lists:member("subscribe", Features), OptionsFeature = lists:member("subscription-options", Features), -@@ -1900,6 +1715,7 @@ +@@ -1915,6 +1730,7 @@ AccessModel = get_option(Options, access_model), SendLast = get_option(Options, send_last_published_item), AllowedGroups = get_option(Options, roster_groups_allowed, []), @@ -531,7 +531,7 @@ {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, Subscriber, Owners, AccessModel, AllowedGroups), if not SubscribeFeature -> -@@ -2021,12 +1837,9 @@ +@@ -2036,12 +1852,9 @@ Features = features(Type), PublishFeature = lists:member("publish", Features), PublishModel = get_option(Options, publish_model), @@ -545,7 +545,7 @@ PayloadCount = payload_xmlelements(Payload), PayloadSize = size(term_to_binary(Payload))-2, % size(term_to_binary([])) == 2 PayloadMaxSize = get_option(Options, max_payload_size), -@@ -2077,7 +1890,7 @@ +@@ -2092,7 +1905,7 @@ false -> ok end, @@ -554,7 +554,7 @@ case Result of default -> {result, Reply}; _ -> {result, Result} -@@ -2243,7 +2056,7 @@ +@@ -2258,7 +2071,7 @@ %%

    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. @@ -563,7 +563,7 @@ MaxItems = if SMaxItems == "" -> get_max_items_node(Host); -@@ -2257,12 +2070,13 @@ +@@ -2272,12 +2085,13 @@ {error, Error} -> {error, Error}; _ -> @@ -578,7 +578,7 @@ {PresenceSubscription, RosterGroup} = get_presence_and_roster_permissions(Host, From, Owners, AccessModel, AllowedGroups), if not RetreiveFeature -> -@@ -2275,11 +2089,11 @@ +@@ -2290,11 +2104,11 @@ node_call(Type, get_items, [NodeId, From, AccessModel, PresenceSubscription, RosterGroup, @@ -592,7 +592,7 @@ SendItems = case ItemIDs of [] -> Items; -@@ -2292,7 +2106,8 @@ +@@ -2307,7 +2121,8 @@ %% number of items sent to MaxItems: {result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}], [{xmlelement, "items", nodeAttr(Node), @@ -602,7 +602,7 @@ Error -> Error end -@@ -2314,10 +2129,15 @@ +@@ -2329,10 +2144,15 @@ Error -> Error end. get_allowed_items_call(Host, NodeIdx, From, Type, Options, Owners) -> @@ -619,7 +619,7 @@ %% @spec (Host, Node, NodeId, Type, LJID, Number) -> any() -@@ -2329,31 +2149,29 @@ +@@ -2344,31 +2164,29 @@ %% Number = last | integer() %% @doc

    Resend the items of a node to the user.

    %% @todo use cache-last-item feature @@ -670,7 +670,7 @@ ToSend = case node_action(Host, Type, get_items, [NodeId, LJID]) of {result, []} -> []; -@@ -2376,20 +2194,7 @@ +@@ -2391,20 +2209,7 @@ [{xmlelement, "items", nodeAttr(Node), itemsEls(ToSend)}]) end, @@ -692,7 +692,7 @@ %% @spec (Host, JID, Plugins) -> {error, Reason} | {result, Response} %% Host = host() -@@ -2491,7 +2296,8 @@ +@@ -2506,7 +2311,8 @@ error -> {error, ?ERR_BAD_REQUEST}; _ -> @@ -702,7 +702,7 @@ case lists:member(Owner, Owners) of true -> OwnerJID = jlib:make_jid(Owner), -@@ -2501,24 +2307,7 @@ +@@ -2516,24 +2322,7 @@ end, lists:foreach( fun({JID, Affiliation}) -> @@ -728,7 +728,7 @@ end, FilteredEntities), {result, []}; _ -> -@@ -2571,11 +2360,11 @@ +@@ -2586,11 +2375,11 @@ end. read_sub(Subscriber, Node, NodeID, SubID, Lang) -> @@ -742,7 +742,7 @@ OptionsEl = {xmlelement, "options", [{"jid", jlib:jid_to_string(Subscriber)}, {"subid", SubID}|nodeAttr(Node)], [XdataEl]}, -@@ -2601,7 +2390,7 @@ +@@ -2616,7 +2405,7 @@ end. set_options_helper(Configuration, JID, NodeID, SubID, Type) -> @@ -751,7 +751,7 @@ {result, GoodSubOpts} -> GoodSubOpts; _ -> invalid end, -@@ -2630,7 +2419,7 @@ +@@ -2645,7 +2434,7 @@ write_sub(_Subscriber, _NodeID, _SubID, invalid) -> {error, extended_error(?ERR_BAD_REQUEST, "invalid-options")}; write_sub(Subscriber, NodeID, SubID, Options) -> @@ -760,7 +760,7 @@ {error, notfound} -> {error, extended_error(?ERR_NOT_ACCEPTABLE, "invalid-subid")}; {result, _} -> -@@ -2798,8 +2587,8 @@ +@@ -2813,8 +2602,8 @@ {"subscription", subscription_to_string(Sub)} | nodeAttr(Node)], []}]}]}, ejabberd_router:route(service_jid(Host), jlib:make_jid(JID), Stanza) end, @@ -771,7 +771,7 @@ true -> Result = lists:foldl(fun({JID, Subscription, SubId}, Acc) -> -@@ -3154,7 +2943,7 @@ +@@ -3169,7 +2958,7 @@ {Depth, [{N, get_node_subs(N)} || N <- Nodes]} end, tree_call(Host, get_parentnodes_tree, [Host, Node, service_jid(Host)]))} end, @@ -780,7 +780,7 @@ {result, CollSubs} -> CollSubs; _ -> [] end. -@@ -3168,9 +2957,9 @@ +@@ -3183,9 +2972,9 @@ get_options_for_subs(NodeID, Subs) -> lists:foldl(fun({JID, subscribed, SubID}, Acc) -> @@ -792,7 +792,7 @@ _ -> Acc end; (_, Acc) -> -@@ -3359,6 +3148,30 @@ +@@ -3374,6 +3163,30 @@ Result end. @@ -823,7 +823,7 @@ %% @spec (Host, Options) -> MaxItems %% Host = host() %% Options = [Option] -@@ -3755,7 +3568,13 @@ +@@ -3770,7 +3583,13 @@ tree_action(Host, Function, Args) -> ?DEBUG("tree_action ~p ~p ~p",[Host,Function,Args]), Fun = fun() -> tree_call(Host, Function, Args) end, @@ -838,7 +838,7 @@ %% @doc

    node plugin call.

    node_call(Type, Function, Args) -> -@@ -3775,13 +3594,13 @@ +@@ -3790,13 +3609,13 @@ node_action(Host, Type, Function, Args) -> ?DEBUG("node_action ~p ~p ~p ~p",[Host,Type,Function,Args]), @@ -854,7 +854,7 @@ case tree_call(Host, get_node, [Host, Node]) of N when is_record(N, pubsub_node) -> case Action(N) of -@@ -3793,13 +3612,19 @@ +@@ -3808,13 +3627,19 @@ Error end end, Trans). @@ -878,7 +878,7 @@ {result, Result} -> {result, Result}; {error, Error} -> {error, Error}; {atomic, {result, Result}} -> {result, Result}; -@@ -3807,6 +3632,15 @@ +@@ -3822,6 +3647,15 @@ {aborted, Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{aborted, Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; @@ -894,7 +894,7 @@ {'EXIT', Reason} -> ?ERROR_MSG("transaction return internal error: ~p~n", [{'EXIT', Reason}]), {error, ?ERR_INTERNAL_SERVER_ERROR}; -@@ -3815,6 +3649,17 @@ +@@ -3830,6 +3664,17 @@ {error, ?ERR_INTERNAL_SERVER_ERROR} end. From 87df27109a18146ba8870a26eece1fbf51cd879b Mon Sep 17 00:00:00 2001 From: Pablo Polvorin Date: Thu, 1 Dec 2011 12:55:20 -0300 Subject: [PATCH 12/30] Fix bug on s2s shaper when TLS is used The shaper was not enabled if the remote server authenticates using a certificate instead of dialback. --- src/ejabberd_s2s_in.erl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 848e58c95..590b560bd 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -356,6 +356,12 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) -> [{"xmlns", ?NS_SASL}], []}), ?DEBUG("(~w) Accepted s2s authentication for ~s", [StateData#state.socket, AuthDomain]), + + %% acess rules are first checked against the globally defined ones, that have precedence over + %% domain-specific ones.. http://www.process-one.net/docs/ejabberd/guide_en.html#AccessRights + %% since there is allways a shaper defined globally for s2s, it doesn't matter the actual + %% local host, since the globall one will be used, even if this domain has a special rule + change_shaper(StateData, "", jlib:make_jid("", AuthDomain, "")), {next_state, wait_for_stream, StateData#state{streamid = new_id(), authenticated = true, From cf973f27bb62dbb1e5c89b062eae491a646860db Mon Sep 17 00:00:00 2001 From: Pablo Polvorin Date: Fri, 2 Dec 2011 15:30:20 -0300 Subject: [PATCH 13/30] Prevent overload of incomming s2s connections Three changes were introduced: 1) ejabberd_s2s_in now uses p1_fsm instead of gen_fsm. And uses the {max_queue, N} option to kill the process if its input queue grows too much. 2) If a ejabberd_s2s_in process is overload and killed, the server that originated that connection is not allowed to connect back to us for X seconds (set to 60seconds on the source) 3) The list of blocked (both statically and dynamically by the above method) host is now also checked for hosts authenticating by starttls+sasl. Previusly it was only used during dialback. --- src/ejabberd_s2s.erl | 40 +++++++++++++++++++++++++++++++++++++++- src/ejabberd_s2s_in.erl | 38 +++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index 1ca4b37f9..476233d7d 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -41,7 +41,11 @@ dirty_get_connections/0, allow_host/2, incoming_s2s_number/0, - outgoing_s2s_number/0 + outgoing_s2s_number/0, + clean_temporarily_blocked_table/0, + list_temporarily_blocked_hosts/0, + external_host_overloaded/1, + is_temporarly_blocked/1 ]). %% gen_server callbacks @@ -57,9 +61,14 @@ -define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER, 1). -define(DEFAULT_MAX_S2S_CONNECTIONS_NUMBER_PER_NODE, 1). +-define(S2S_OVERLOAD_BLOCK_PERIOD, 60). +%% once a server is temporarly blocked, it stay blocked for 60 seconds + -record(s2s, {fromto, pid, key}). -record(state, {}). +-record(temporarily_blocked, {host, timestamp}). + %%==================================================================== %% API %%==================================================================== @@ -79,6 +88,31 @@ route(From, To, Packet) -> ok end. +clean_temporarily_blocked_table() -> + mnesia:clear_table(temporarily_blocked). +list_temporarily_blocked_hosts() -> + ets:tab2list(temporarily_blocked). + +external_host_overloaded(Host) -> + ?INFO_MSG("Disabling connections from ~s for ~p seconds", [Host, ?S2S_OVERLOAD_BLOCK_PERIOD]), + mnesia:transaction( fun() -> + mnesia:write(#temporarily_blocked{host = Host, timestamp = now()}) + end). + +is_temporarly_blocked(Host) -> + case mnesia:dirty_read(temporarily_blocked, Host) of + [] -> false; + [#temporarily_blocked{timestamp = T}=Entry] -> + case timer:now_diff(now(), T) of + N when N > ?S2S_OVERLOAD_BLOCK_PERIOD * 1000 * 1000 -> + mnesia:dirty_delete_object(Entry), + false; + _ -> + true + end + end. + + remove_connection(FromTo, Pid, Key) -> case catch mnesia:dirty_match_object(s2s, #s2s{fromto = FromTo, pid = Pid, @@ -169,6 +203,7 @@ init([]) -> mnesia:add_table_copy(s2s, node(), ram_copies), mnesia:subscribe(system), ejabberd_commands:register_commands(commands()), + mnesia:create_table(temporarily_blocked, [{ram_copies, [node()]}, {attributes, record_info(fields, temporarily_blocked)}]), {ok, #state{}}. %%-------------------------------------------------------------------- @@ -486,6 +521,9 @@ update_tables() -> %% Check if host is in blacklist or white list allow_host(MyServer, S2SHost) -> + allow_host2(MyServer, S2SHost) andalso (not is_temporarly_blocked(S2SHost)). + +allow_host2(MyServer, S2SHost) -> Hosts = ?MYHOSTS, case lists:dropwhile( fun(ParentDomain) -> diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 590b560bd..2cfc1d460 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -27,7 +27,7 @@ -module(ejabberd_s2s_in). -author('alexey@process-one.net'). --behaviour(gen_fsm). +-behaviour(p1_fsm). %% External exports -export([start/2, @@ -92,10 +92,12 @@ -define(FSMOPTS, []). -endif. +-define(FSMLIMITS, [{max_queue, 2000}]). %% if queue grows more than this, we shutdown this connection. + %% Module start with or without supervisor: -ifdef(NO_TRANSIENT_SUPERVISORS). --define(SUPERVISOR_START, gen_fsm:start(ejabberd_s2s_in, [SockData, Opts], - ?FSMOPTS)). +-define(SUPERVISOR_START, p1_fsm:start(ejabberd_s2s_in, [SockData, Opts], + ?FSMOPTS ++ ?FSMLIMITS)). -else. -define(SUPERVISOR_START, supervisor:start_child(ejabberd_s2s_in_sup, [SockData, Opts])). @@ -131,7 +133,7 @@ start(SockData, Opts) -> ?SUPERVISOR_START. start_link(SockData, Opts) -> - gen_fsm:start_link(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS). + p1_fsm:start_link(ejabberd_s2s_in, [SockData, Opts], ?FSMOPTS ++ ?FSMLIMITS). socket_type() -> xml_stream. @@ -347,8 +349,9 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) -> error -> false end, + AllowRemoteHost = ejabberd_s2s:allow_host("", AuthDomain), if - AuthRes -> + AuthRes andalso AllowRemoteHost -> (StateData#state.sockmod):reset_stream( StateData#state.socket), send_element(StateData, @@ -590,14 +593,7 @@ handle_sync_event(get_state_infos, _From, StateName, StateData) -> catch _:_ -> {unknown,unknown} end, - Domains = case StateData#state.authenticated of - true -> - [StateData#state.auth_domain]; - false -> - Connections = StateData#state.connections, - [D || {{D, _}, established} <- - dict:to_list(Connections)] - end, + Domains = get_external_hosts(StateData), Infos = [ {direction, in}, {statename, StateName}, @@ -656,9 +652,25 @@ handle_info(_, StateName, StateData) -> %%---------------------------------------------------------------------- terminate(Reason, _StateName, StateData) -> ?DEBUG("terminated: ~p", [Reason]), + case Reason of + {process_limit, _} -> + [ejabberd_s2s:external_host_overloaded(Host) || Host <- get_external_hosts(StateData)]; + _ -> + ok + end, (StateData#state.sockmod):close(StateData#state.socket), ok. +get_external_hosts(StateData) -> + case StateData#state.authenticated of + true -> + [StateData#state.auth_domain]; + false -> + Connections = StateData#state.connections, + [D || {{D, _}, established} <- dict:to_list(Connections)] + end. + + %%%---------------------------------------------------------------------- %%% Internal functions %%%---------------------------------------------------------------------- From d30ad8ba2875a8a71261693da6c8b62ca8c73b47 Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 8 Dec 2011 12:39:58 +0100 Subject: [PATCH 14/30] Frontend module to Re and Regexp (EJAB-921) --- src/ejabberd_regexp.erl | 72 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/ejabberd_regexp.erl diff --git a/src/ejabberd_regexp.erl b/src/ejabberd_regexp.erl new file mode 100644 index 000000000..77bbae517 --- /dev/null +++ b/src/ejabberd_regexp.erl @@ -0,0 +1,72 @@ +%%%---------------------------------------------------------------------- +%%% File : ejabberd_regexp.erl +%%% Author : Badlop +%%% Purpose : Frontend to Re and Regexp OTP modules +%%% Created : 8 Dec 2011 by Badlop +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2011 ProcessOne +%%% +%%% This program 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 program is distributed in the hope that it will be useful, +%%% 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 +%%% 02111-1307 USA +%%% +%%%---------------------------------------------------------------------- + +-module(ejabberd_regexp). +-compile([export_all]). + +exec(ReM, ReF, ReA, RgM, RgF, RgA) -> + try apply(ReM, ReF, ReA) + catch + error:undef -> + apply(RgM, RgF, RgA); + A:B -> + {error, {A, B}} + end. + +run(String, Regexp) -> + case exec(re, run, [String, Regexp, [{capture, none}]], regexp, first_match, [String, Regexp]) of + {match, _, _} -> match; + {match, _} -> match; + match -> match; + nomatch -> nomatch; + {error, Error} -> {error, Error} + end. + +split(String, Regexp) -> + case exec(re, split, [String, Regexp, [{return, list}]], regexp, split, [String, Regexp]) of + {ok, FieldList} -> FieldList; + {error, Error} -> throw(Error); + A -> A + end. + +replace(String, Regexp, New) -> + case exec(re, replace, [String, Regexp, New, [{return, list}]], regexp, sub, [String, Regexp, New]) of + {ok, NewString, _RepCount} -> NewString; + {error, Error} -> throw(Error); + A -> A + end. + +greplace(String, Regexp, New) -> + case exec(re, replace, [String, Regexp, New, [global, {return, list}]], regexp, sub, [String, Regexp, New]) of + {ok, NewString, _RepCount} -> NewString; + {error, Error} -> throw(Error); + A -> A + end. + +sh_to_awk(ShRegExp) -> + case exec(xmerl_regexp, sh_to_awk, [ShRegExp], regexp, sh_to_awk, [ShRegExp]) of + A -> A + end. From 48308042b6d88f4c1b574b7af7f2f17a59eafae8 Mon Sep 17 00:00:00 2001 From: Badlop Date: Tue, 22 Nov 2011 23:11:21 +0100 Subject: [PATCH 15/30] Use the regexp frontend module (EJAB-921) --- src/acl.erl | 8 +++---- src/ejabberd_ctl.erl | 12 +++++----- src/ejabberd_s2s_in.erl | 8 +++---- src/gen_mod.erl | 4 ++-- src/mod_configure.erl | 2 +- src/mod_irc/mod_irc_connection.erl | 35 +++++++++++++----------------- src/mod_muc/mod_muc_log.erl | 23 ++++++++++---------- src/mod_shared_roster.erl | 10 ++++----- src/web/ejabberd_web_admin.erl | 7 +++--- 9 files changed, 51 insertions(+), 58 deletions(-) diff --git a/src/acl.erl b/src/acl.erl index 59173f004..7b23719e5 100644 --- a/src/acl.erl +++ b/src/acl.erl @@ -223,19 +223,19 @@ match_acl(ACL, JID, Host) -> end. is_regexp_match(String, RegExp) -> - case regexp:first_match(String, RegExp) of + case ejabberd_regexp:run(String, RegExp) of nomatch -> false; - {match, _, _} -> + match -> true; {error, ErrDesc} -> ?ERROR_MSG( "Wrong regexp ~p in ACL: ~p", - [RegExp, lists:flatten(regexp:format_error(ErrDesc))]), + [RegExp, ErrDesc]), false end. is_glob_match(String, Glob) -> - is_regexp_match(String, regexp:sh_to_awk(Glob)). + is_regexp_match(String, ejabberd_regexp:sh_to_awk(Glob)). diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index 189aa2c6b..40f421056 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -190,7 +190,7 @@ process(["help" | Mode]) -> print_usage_help(MaxC, ShCode), ?STATUS_SUCCESS; [CmdString | _] -> - {ok, CmdStringU, _} = regexp:gsub(CmdString, "-", "_"), + CmdStringU = ejabberd_regexp:greplace(CmdString, "-", "_"), print_usage_commands(CmdStringU, MaxC, ShCode), ?STATUS_SUCCESS end; @@ -281,7 +281,7 @@ try_call_command(Args, Auth, AccessCommands) -> %% @spec (Args::[string()], Auth, AccessCommands) -> string() | integer() | {string(), integer()} | {error, ErrorType} call_command([CmdString | Args], Auth, AccessCommands) -> - {ok, CmdStringU, _} = regexp:gsub(CmdString, "-", "_"), + CmdStringU = ejabberd_regexp:greplace(CmdString, "-", "_"), Command = list_to_atom(CmdStringU), case ejabberd_commands:get_command_format(Command) of {error, command_unknown} -> @@ -678,13 +678,13 @@ filter_commands(All, SubString) -> end. filter_commands_regexp(All, Glob) -> - RegExp = regexp:sh_to_awk(Glob), + RegExp = ejabberd_regexp:sh_to_awk(Glob), lists:filter( fun(Command) -> - case regexp:first_match(Command, RegExp) of - {match, _, _} -> + case ejabberd_regexp:run(Command, RegExp) of + match -> true; - _ -> + nomatch -> false end end, diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 2cfc1d460..c2db348af 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -823,11 +823,11 @@ match_labels([DL | DLabels], [PL | PLabels]) -> orelse (C == $-) orelse (C == $*) end, PL) of true -> - Regexp = regexp:sh_to_awk(PL), - case regexp:match(DL, Regexp) of - {match, _, _} -> + Regexp = ejabberd_regexp:sh_to_awk(PL), + case ejabberd_regexp:run(DL, Regexp) of + match -> match_labels(DLabels, PLabels); - _ -> + nomatch -> false end; false -> diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 0f577d31a..ff8b92c9b 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -186,11 +186,11 @@ get_module_opt(Host, Module, Opt, Default) -> get_module_opt_host(Host, Module, Default) -> Val = get_module_opt(Host, Module, host, Default), - element(2, regexp:gsub(Val, "@HOST@", Host)). + ejabberd_regexp:greplace(Val, "@HOST@", Host). get_opt_host(Host, Opts, Default) -> Val = get_opt(host, Opts, Default), - element(2, regexp:gsub(Val, "@HOST@", Host)). + ejabberd_regexp:greplace(Val, "@HOST@", Host). loaded_modules(Host) -> ets:select(ejabberd_modules, diff --git a/src/mod_configure.erl b/src/mod_configure.erl index 2d58d58e7..e760a3e4a 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -542,7 +542,7 @@ get_local_items({_, Host}, ["all users", [$@ | Diap]], _Server, _Lang) -> Users -> SUsers = lists:sort([{S, U} || {U, S} <- Users]), case catch begin - {ok, [S1, S2]} = regexp:split(Diap, "-"), + [S1, S2] = ejabberd_regexp:split(Diap, "-"), N1 = list_to_integer(S1), N2 = list_to_integer(S2), Sub = lists:sublist(SUsers, N1, N2 - N1 + 1), diff --git a/src/mod_irc/mod_irc_connection.erl b/src/mod_irc/mod_irc_connection.erl index da9d26ca8..92001aedb 100644 --- a/src/mod_irc/mod_irc_connection.erl +++ b/src/mod_irc/mod_irc_connection.erl @@ -625,7 +625,7 @@ handle_info({send_text, Text}, StateName, StateData) -> {next_state, StateName, StateData}; handle_info({tcp, _Socket, Data}, StateName, StateData) -> Buf = StateData#state.inbuf ++ binary_to_list(Data), - {ok, Strings} = regexp:split([C || C <- Buf, C /= $\r], "\n"), + Strings = ejabberd_regexp:split([C || C <- Buf, C /= $\r], "\n"), ?DEBUG("strings=~p~n", [Strings]), NewBuf = process_lines(StateData#state.encoding, Strings), {next_state, StateName, StateData#state{inbuf = NewBuf}}; @@ -797,7 +797,7 @@ process_channel_list_user(StateData, Chan, User) -> process_channel_topic(StateData, Chan, String) -> - {ok, Msg, _} = regexp:sub(String, ".*332[^:]*:", ""), + Msg = ejabberd_regexp:replace(String, ".*332[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( jlib:make_jid( @@ -831,7 +831,7 @@ process_channel_topic_who(StateData, Chan, String) -> error_nick_in_use(_StateData, String) -> - {ok, Msg, _} = regexp:sub(String, ".*433 +[^ ]* +", ""), + Msg = ejabberd_regexp:replace(String, ".*433 +[^ ]* +", ""), Msg1 = filter_message(Msg), {xmlelement, "error", [{"code", "409"}, {"type", "cancel"}], [{xmlelement, "conflict", [{"xmlns", ?NS_STANZAS}], []}, @@ -879,7 +879,7 @@ process_endofwhois(StateData, _String, Nick) -> [{xmlelement, "body", [], [{xmlcdata, "End of WHOIS"}]}]}). process_whois311(StateData, String, Nick, Ident, Irchost) -> - {ok, Fullname, _} = regexp:sub(String, ".*311[^:]*:", ""), + Fullname = ejabberd_regexp:replace(String, ".*311[^:]*:", ""), ejabberd_router:route( jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), @@ -891,7 +891,7 @@ process_whois311(StateData, String, Nick, Ident, Irchost) -> Ident, "@" , Irchost, " : " , Fullname])}]}]}). process_whois312(StateData, String, Nick, Ircserver) -> - {ok, Ircserverdesc, _} = regexp:sub(String, ".*312[^:]*:", ""), + Ircserverdesc = ejabberd_regexp:replace(String, ".*312[^:]*:", ""), ejabberd_router:route( jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), @@ -902,7 +902,7 @@ process_whois312(StateData, String, Nick, Ircserver) -> Ircserver, " : ", Ircserverdesc])}]}]}). process_whois319(StateData, String, Nick) -> - {ok, Chanlist, _} = regexp:sub(String, ".*319[^:]*:", ""), + Chanlist = ejabberd_regexp:replace(String, ".*319[^:]*:", ""), ejabberd_router:route( jlib:make_jid(lists:concat([Nick, "!", StateData#state.server]), StateData#state.host, ""), @@ -916,7 +916,7 @@ process_whois319(StateData, String, Nick) -> process_chanprivmsg(StateData, Chan, From, String) -> [FromUser | _] = string:tokens(From, "!"), - {ok, Msg, _} = regexp:sub(String, ".*PRIVMSG[^:]*:", ""), + Msg = ejabberd_regexp:replace(String, ".*PRIVMSG[^:]*:", ""), Msg1 = case Msg of [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> "/me " ++ Rest; @@ -935,7 +935,7 @@ process_chanprivmsg(StateData, Chan, From, String) -> process_channotice(StateData, Chan, From, String) -> [FromUser | _] = string:tokens(From, "!"), - {ok, Msg, _} = regexp:sub(String, ".*NOTICE[^:]*:", ""), + Msg = ejabberd_regexp:replace(String, ".*NOTICE[^:]*:", ""), Msg1 = case Msg of [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> "/me " ++ Rest; @@ -955,7 +955,7 @@ process_channotice(StateData, Chan, From, String) -> process_privmsg(StateData, _Nick, From, String) -> [FromUser | _] = string:tokens(From, "!"), - {ok, Msg, _} = regexp:sub(String, ".*PRIVMSG[^:]*:", ""), + Msg = ejabberd_regexp:replace(String, ".*PRIVMSG[^:]*:", ""), Msg1 = case Msg of [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> "/me " ++ Rest; @@ -973,7 +973,7 @@ process_privmsg(StateData, _Nick, From, String) -> process_notice(StateData, _Nick, From, String) -> [FromUser | _] = string:tokens(From, "!"), - {ok, Msg, _} = regexp:sub(String, ".*NOTICE[^:]*:", ""), + Msg = ejabberd_regexp:replace(String, ".*NOTICE[^:]*:", ""), Msg1 = case Msg of [1, $A, $C, $T, $I, $O, $N, $ | Rest] -> "/me " ++ Rest; @@ -1016,7 +1016,7 @@ process_userinfo(StateData, _Nick, From) -> process_topic(StateData, Chan, From, String) -> [FromUser | _] = string:tokens(From, "!"), - {ok, Msg, _} = regexp:sub(String, ".*TOPIC[^:]*:", ""), + Msg = ejabberd_regexp:replace(String, ".*TOPIC[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), @@ -1030,7 +1030,7 @@ process_topic(StateData, Chan, From, String) -> process_part(StateData, Chan, From, String) -> [FromUser | FromIdent] = string:tokens(From, "!"), - {ok, Msg, _} = regexp:sub(String, ".*PART[^:]*:", ""), + Msg = ejabberd_regexp:replace(String, ".*PART[^:]*:", ""), Msg1 = filter_message(Msg), ejabberd_router:route( jlib:make_jid(lists:concat([Chan, "%", StateData#state.server]), @@ -1059,7 +1059,7 @@ process_part(StateData, Chan, From, String) -> process_quit(StateData, From, String) -> [FromUser | FromIdent] = string:tokens(From, "!"), - {ok, Msg, _} = regexp:sub(String, ".*QUIT[^:]*:", ""), + Msg = ejabberd_regexp:replace(String, ".*QUIT[^:]*:", ""), Msg1 = filter_message(Msg), %%NewChans = dict:map( @@ -1215,7 +1215,7 @@ process_error(StateData, String) -> end, dict:fetch_keys(StateData#state.channels)). error_unknown_num(_StateData, String, Type) -> - {ok, Msg, _} = regexp:sub(String, ".*[45][0-9][0-9] +[^ ]* +", ""), + Msg = ejabberd_regexp:replace(String, ".*[45][0-9][0-9] +[^ ]* +", ""), Msg1 = filter_message(Msg), {xmlelement, "error", [{"code", "500"}, {"type", Type}], [{xmlelement, "undefined-condition", [{"xmlns", ?NS_STANZAS}], []}, @@ -1313,12 +1313,7 @@ filter_message(Msg) -> end, filter_mirc_colors(Msg)). filter_mirc_colors(Msg) -> - case regexp:gsub(Msg, "(\\003[0-9]+)(,[0-9]+)?", "") of - {ok, Msg2, _} -> - Msg2; - _ -> - Msg - end. + ejabberd_regexp:greplace(Msg, "(\\003[0-9]+)(,[0-9]+)?", ""). unixtime2string(Unixtime) -> Secs = Unixtime + calendar:datetime_to_gregorian_seconds( diff --git a/src/mod_muc/mod_muc_log.erl b/src/mod_muc/mod_muc_log.erl index 7560016a0..6cc4efff1 100644 --- a/src/mod_muc/mod_muc_log.erl +++ b/src/mod_muc/mod_muc_log.erl @@ -416,11 +416,11 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) -> io_lib:format("~s~s~s
    ", [Nick, ?T(" has set the subject to: "), htmlize(T,NoFollow,FileFormat)]); {body, T} -> - case {regexp:first_match(T, "^/me\s"), Nick} of + case {ejabberd_regexp:run(T, "^/me\s"), Nick} of {_, ""} -> io_lib:format("~s
    ", [htmlize(T,NoFollow,FileFormat)]); - {{match, _, _}, _} -> + {match, _} -> io_lib:format("~s ~s
    ", [Nick, string:substr(htmlize(T,FileFormat), 5)]); {nomatch, _} -> @@ -662,8 +662,7 @@ fw(F, S, O, FileFormat) -> html -> S1; plaintext -> - {ok, Res, _} = regexp:gsub(S1, "<[^>]*>", ""), - Res + ejabberd_regexp:greplace(S1, "<[^>]*>", "") end, io:format(F, S2, []). @@ -790,15 +789,15 @@ htmlize(S1, NoFollow, _FileFormat) -> S2_list). htmlize2(S1, NoFollow) -> - S2 = element(2, regexp:gsub(S1, "\\&", "\\&")), - S3 = element(2, regexp:gsub(S2, "<", "\\<")), - S4 = element(2, regexp:gsub(S3, ">", "\\>")), - S5 = element(2, regexp:gsub(S4, "((http|https|ftp)://|(mailto|xmpp):)[^] )\'\"}]+", - link_regexp(NoFollow))), + S2 = ejabberd_regexp:greplace(S1, "\\&", "\\&"), + S3 = ejabberd_regexp:greplace(S2, "<", "\\<"), + S4 = ejabberd_regexp:greplace(S3, ">", "\\>"), + S5 = ejabberd_regexp:greplace(S4, "((http|https|ftp)://|(mailto|xmpp):)[^] )\'\"}]+", + link_regexp(NoFollow)), %% Remove 'right-to-left override' unicode character 0x202e - S6 = element(2, regexp:gsub(S5, " ", "\\ \\ ")), - S7 = element(2, regexp:gsub(S6, "\\t", "\\ \\ \\ \\ ")), - element(2, regexp:gsub(S7, [226,128,174], "[RLO]")). + S6 = ejabberd_regexp:greplace(S5, " ", "\\ \\ "), + S7 = ejabberd_regexp:greplace(S6, "\\t", "\\ \\ \\ \\ "), + ejabberd_regexp:greplace(S7, [226,128,174], "[RLO]"). %% Regexp link %% Add the nofollow rel attribute when required diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 1043e86e3..7d4d293a3 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -614,8 +614,8 @@ is_user_in_group(US, Group, Host) -> %% @spec (Host::string(), {User::string(), Server::string()}, Group::string()) -> {atomic, ok} add_user_to_group(Host, US, Group) -> {LUser, LServer} = US, - case regexp:match(LUser, "^@.+@$") of - {match,_,_} -> + case ejabberd_regexp:run(LUser, "^@.+@$") of + match -> GroupOpts = mod_shared_roster:get_group_opts(Host, Group), MoreGroupOpts = case LUser of @@ -647,8 +647,8 @@ push_displayed_to_user(LUser, LServer, Group, Host, Subscription) -> remove_user_from_group(Host, US, Group) -> GroupHost = {Group, Host}, {LUser, LServer} = US, - case regexp:match(LUser, "^@.+@$") of - {match,_,_} -> + case ejabberd_regexp:run(LUser, "^@.+@$") of + match -> GroupOpts = mod_shared_roster:get_group_opts(Host, Group), NewGroupOpts = case LUser of @@ -967,7 +967,7 @@ shared_roster_group(Host, Group, Query, Lang) -> end ++ [[us_to_list(Member), $\n] || Member <- Members], FDisplayedGroups = [[DG, $\n] || DG <- DisplayedGroups], - DescNL = length(element(2, regexp:split(Description, "\n"))), + DescNL = length(ejabberd_regexp:split(Description, "\n")), FGroup = ?XAE("table", [{"class", "withtextareas"}], [?XE("tbody", diff --git a/src/web/ejabberd_web_admin.erl b/src/web/ejabberd_web_admin.erl index d08ad6371..75d0ee828 100644 --- a/src/web/ejabberd_web_admin.erl +++ b/src/web/ejabberd_web_admin.erl @@ -1239,13 +1239,12 @@ acl_spec_select(ID, Opt) -> term_to_string(T) -> StringParagraph = lists:flatten(io_lib:format("~1000000p", [T])), %% Remove from the string all the carriage returns characters - {ok, StringLine, _} = regexp:gsub(StringParagraph, "\\n ", ""), - StringLine. + ejabberd_regexp:greplace(StringParagraph, "\\n ", ""). %% @spec (T::any(), Cols::integer()) -> {NumLines::integer(), Paragraph::string()} term_to_paragraph(T, Cols) -> Paragraph = erl_prettypr:format(erl_syntax:abstract(T), [{paper, Cols}]), - {ok, FieldList} = regexp:split(Paragraph, "\n"), + FieldList = ejabberd_regexp:split(Paragraph, "\n"), NumLines = length(FieldList), {NumLines, Paragraph}. @@ -1558,7 +1557,7 @@ list_users_parse_query(Query, Host) -> list_users_in_diapason(Host, Diap, Lang, URLFunc) -> Users = ejabberd_auth:get_vh_registered_users(Host), SUsers = lists:sort([{S, U} || {U, S} <- Users]), - {ok, [S1, S2]} = regexp:split(Diap, "-"), + [S1, S2] = ejabberd_regexp:split(Diap, "-"), N1 = list_to_integer(S1), N2 = list_to_integer(S2), Sub = lists:sublist(SUsers, N1, N2 - N1 + 1), From d3369c83e7cc50cd80241b44d455b1c454d4943d Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 8 Dec 2011 12:50:40 +0100 Subject: [PATCH 16/30] Add callback function print_state/1 for behavior p1_fsm --- src/ejabberd_s2s_in.erl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index c2db348af..af3fd760a 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -44,6 +44,7 @@ handle_sync_event/4, code_change/4, handle_info/3, + print_state/1, terminate/3]). -include("ejabberd.hrl"). @@ -670,6 +671,13 @@ get_external_hosts(StateData) -> [D || {{D, _}, established} <- dict:to_list(Connections)] end. +%%---------------------------------------------------------------------- +%% Func: print_state/1 +%% Purpose: Prepare the state to be printed on error log +%% Returns: State to print +%%---------------------------------------------------------------------- +print_state(State) -> + State. %%%---------------------------------------------------------------------- %%% Internal functions From 13a9ca65a420f316aef0f5d33cef9c9639c804f5 Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 8 Dec 2011 16:35:31 +0100 Subject: [PATCH 17/30] Don't reveal invitee's resource when room informs invitor --- src/mod_muc/mod_muc_room.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl index 164805d9c..d12a91fab 100644 --- a/src/mod_muc/mod_muc_room.erl +++ b/src/mod_muc/mod_muc_room.erl @@ -4004,7 +4004,7 @@ check_decline_invitation(Packet) -> %% Send the decline to the inviter user. %% The original stanza must be slightly modified. send_decline_invitation({Packet, XEl, DEl, ToJID}, RoomJID, FromJID) -> - FromString = jlib:jid_to_string(FromJID), + FromString = jlib:jid_to_string(jlib:jid_remove_resource(FromJID)), {xmlelement, "decline", DAttrs, DEls} = DEl, DAttrs2 = lists:keydelete("to", 1, DAttrs), DAttrs3 = [{"from", FromString} | DAttrs2], From 37107af7b4c192c01a36aea17403ff4946b892fa Mon Sep 17 00:00:00 2001 From: Badlop Date: Thu, 8 Dec 2011 19:39:36 +0100 Subject: [PATCH 18/30] Fix command "update" to return response in the expected format --- src/ejabberd_admin.erl | 5 +++-- src/ejabberd_update.erl | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl index a11b4bf4a..134bd4465 100644 --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -299,14 +299,15 @@ update_list() -> [atom_to_list(Beam) || Beam <- UpdatedBeams]. update("all") -> - [update_module(ModStr) || ModStr <- update_list()]; + [update_module(ModStr) || ModStr <- update_list()], + {ok, []}; update(ModStr) -> update_module(ModStr). update_module(ModuleNameString) -> ModuleName = list_to_atom(ModuleNameString), case ejabberd_update:update([ModuleName]) of - {ok, Res} -> {ok, io_lib:format("Updated: ~p", [Res])}; + {ok, _Res} -> {ok, []}; {error, Reason} -> {error, Reason} end. diff --git a/src/ejabberd_update.erl b/src/ejabberd_update.erl index f88af2aca..6bb354818 100644 --- a/src/ejabberd_update.erl +++ b/src/ejabberd_update.erl @@ -44,7 +44,7 @@ update() -> eval_script( LowLevelScript, [], [{ejabberd, "", filename:join(Dir, "..")}]), - ?INFO_MSG("eval: ~p~n", [Eval]), + ?DEBUG("eval: ~p~n", [Eval]), Eval; {error, Reason} -> {error, Reason} @@ -61,7 +61,7 @@ update(ModulesToUpdate) -> eval_script( LowLevelScript, [], [{ejabberd, "", filename:join(Dir, "..")}]), - ?INFO_MSG("eval: ~p~n", [Eval]), + ?DEBUG("eval: ~p~n", [Eval]), Eval; {error, Reason} -> {error, Reason} From 262157c88d43b1fc42780c2f94aca38c76610777 Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 27 Jul 2011 10:20:22 +0200 Subject: [PATCH 19/30] Preliminary support for groupname@vhost in Displayed Groups (EJAB-506) --- doc/guide.tex | 5 +++-- src/mod_shared_roster.erl | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/doc/guide.tex b/doc/guide.tex index 6d12ed2cd..f13c58884 100644 --- a/doc/guide.tex +++ b/doc/guide.tex @@ -4118,8 +4118,9 @@ has a unique identification and the following parameters: which is only recommended for a small server with just a few hundred users. The special member directive \term{@online@} represents the online users in the virtual host. -\item[Displayed groups] A list of groups that will be in the rosters of this - group's members. +\item[Displayed groups] + A list of groups that will be in the rosters of this group's members. + A group of other vhost can be identified with \term{groupid@vhost} \end{description} Examples: diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 7d4d293a3..6aa746bfe 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -463,7 +463,8 @@ get_user_groups(US) -> [] end ++ get_special_users_groups(Host). -is_group_enabled(Host, Group) -> +is_group_enabled(Host1, Group1) -> + {Host, Group} = split_grouphost(Host1, Group1), case catch mnesia:dirty_read(sr_group, {Group, Host}) of [#sr_group{opts = Opts}] -> not lists:member(disabled, Opts); @@ -488,7 +489,8 @@ get_group_opt(Host, Group, Opt, Default) -> get_online_users(Host) -> lists:usort([{U, S} || {U, S, _} <- ejabberd_sm:get_vh_session_list(Host)]). -get_group_users(Host, Group) -> +get_group_users(Host1, Group1) -> + {Host, Group} = split_grouphost(Host1, Group1), case get_group_opt(Host, Group, all_users, false) of true -> ejabberd_auth:get_vh_registered_users(Host); @@ -531,7 +533,8 @@ get_group_explicit_users(Host, Group) -> [] end. -get_group_name(Host, Group) -> +get_group_name(Host1, Group1) -> + {Host, Group} = split_grouphost(Host1, Group1), get_group_opt(Host, Group, name, Group). %% Get list of names of groups that have @all@/@online@/etc in the memberlist @@ -1114,3 +1117,11 @@ get_opt(Opts, Opt, Default) -> us_to_list({User, Server}) -> jlib:jid_to_string({User, Server, ""}). + +split_grouphost(Host, Group) -> + case string:tokens(Group, "@") of + [GroupName, HostName] -> + {HostName, GroupName}; + [_] -> + {Host, Group} + end. From 298a4a3acf7a72ed27b3d405368c29b2ebad0f48 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 19 Dec 2011 16:01:04 +1000 Subject: [PATCH 20/30] Get rid of +driver option because it is incompatible with R15B --- src/eldap/Makefile.in | 2 +- src/eldap/Makefile.win32 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/eldap/Makefile.in b/src/eldap/Makefile.in index 158252670..8a0a0d768 100644 --- a/src/eldap/Makefile.in +++ b/src/eldap/Makefile.in @@ -6,7 +6,7 @@ CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ -ASN_FLAGS = -bber_bin +optimize +driver +ASN_FLAGS = -bber_bin +optimize ERLANG_CFLAGS = @ERLANG_CFLAGS@ ERLANG_LIBS = @ERLANG_LIBS@ diff --git a/src/eldap/Makefile.win32 b/src/eldap/Makefile.win32 index 228c9ba09..394055d41 100644 --- a/src/eldap/Makefile.win32 +++ b/src/eldap/Makefile.win32 @@ -6,7 +6,7 @@ EFLAGS = -I .. -pz .. OUTDIR = .. BEAMS = ..\eldap.beam ..\eldap_filter.beam ..\eldap_pool.beam ..\eldap_utils.beam ..\eldap_filter_yecc.beam -ASN_FLAGS = -bber_bin +optimize +driver +ASN_FLAGS = -bber_bin +optimize ALL : $(BEAMS) From 707bb0a3214137c998ebe7157785ba83bd82d2c2 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Mon, 19 Dec 2011 16:10:48 +1000 Subject: [PATCH 21/30] Replace regexp with ejabberd_regexp --- src/eldap/eldap_utils.erl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/eldap/eldap_utils.erl b/src/eldap/eldap_utils.erl index 66a1fcfef..056499d4a 100644 --- a/src/eldap/eldap_utils.erl +++ b/src/eldap/eldap_utils.erl @@ -94,17 +94,18 @@ get_user_part(String, Pattern) -> {'EXIT', _} -> {error, badmatch}; Result -> - case regexp:sub(Pattern, "%u", Result) of - {ok, StringRes, _} -> + case catch ejabberd_regexp:replace(Pattern, "%u", Result) of + {'EXIT', _} -> + {error, badmatch}; + StringRes -> case (string:to_lower(StringRes) == string:to_lower(String)) of true -> {ok, Result}; false -> {error, badmatch} - end; - _ -> {error, badmatch} - end + end + end end. make_filter(Data, UIDs) -> From 2029e39299aebe3c4882a26294f4caadc8881265 Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 21 Dec 2011 12:15:21 +0100 Subject: [PATCH 22/30] Support Erlang/OTP R15B driver (EJAB-1521) --- src/ejabberd_zlib/ejabberd_zlib_drv.c | 29 ++++++++++++++++++++++---- src/expat_erl.c | 30 +++++++++++++++++++++++---- src/mod_irc/iconv_erl.c | 30 +++++++++++++++++++++++---- src/stringprep/stringprep_drv.c | 30 +++++++++++++++++++++++---- src/tls/sha_drv.c | 30 +++++++++++++++++++++++---- src/tls/tls_drv.c | 30 +++++++++++++++++++++++---- 6 files changed, 155 insertions(+), 24 deletions(-) diff --git a/src/ejabberd_zlib/ejabberd_zlib_drv.c b/src/ejabberd_zlib/ejabberd_zlib_drv.c index ca3e7938a..bcd9ad304 100644 --- a/src/ejabberd_zlib/ejabberd_zlib_drv.c +++ b/src/ejabberd_zlib/ejabberd_zlib_drv.c @@ -23,6 +23,15 @@ #include #include +/* + * R15B changed several driver callbacks to use ErlDrvSizeT and + * ErlDrvSSizeT typedefs instead of int. + * This provides missing typedefs on older OTP versions. + */ +#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 +typedef int ErlDrvSizeT; +typedef int ErlDrvSSizeT; +#endif #define BUF_SIZE 1024 @@ -98,10 +107,10 @@ static void ejabberd_zlib_drv_stop(ErlDrvData handle) } -static int ejabberd_zlib_drv_control(ErlDrvData handle, +static ErlDrvSSizeT ejabberd_zlib_drv_control(ErlDrvData handle, unsigned int command, - char *buf, int len, - char **rbuf, int rlen) + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen) { ejabberd_zlib_data *d = (ejabberd_zlib_data *)handle; int err; @@ -187,7 +196,19 @@ ErlDrvEntry ejabberd_zlib_driver_entry = { NULL, /* handle */ ejabberd_zlib_drv_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ - NULL /* F_PTR outputv, reserved */ + NULL, /* F_PTR outputv, reserved */ + /* Added in Erlang/OTP R15B: */ + NULL, /* ready_async */ + NULL, /* flush */ + NULL, /* call */ + NULL, /* event */ + ERL_DRV_EXTENDED_MARKER, /* extended_marker */ + ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ + ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ + 0, /* driver_flags */ + NULL, /* handle2 */ + NULL, /* process_exit */ + NULL /* stop_select */ }; DRIVER_INIT(ejabberd_zlib_drv) /* must match name in driver_entry */ diff --git a/src/expat_erl.c b/src/expat_erl.c index 32826f2f7..1ea17e5ee 100644 --- a/src/expat_erl.c +++ b/src/expat_erl.c @@ -34,6 +34,16 @@ #define PARSE_COMMAND 0 #define PARSE_FINAL_COMMAND 1 +/* + * R15B changed several driver callbacks to use ErlDrvSizeT and + * ErlDrvSSizeT typedefs instead of int. + * This provides missing typedefs on older OTP versions. + */ +#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 +typedef int ErlDrvSizeT; +typedef int ErlDrvSSizeT; +#endif + ei_x_buff event_buf; ei_x_buff xmlns_buf; @@ -190,10 +200,10 @@ static void expat_erl_stop(ErlDrvData handle) driver_free((char*)handle); } -static int expat_erl_control(ErlDrvData drv_data, +static ErlDrvSSizeT expat_erl_control(ErlDrvData drv_data, unsigned int command, - char *buf, int len, - char **rbuf, int rlen) + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen) { expat_data* d = (expat_data*)drv_data; int res, errcode; @@ -251,7 +261,19 @@ ErlDrvEntry expat_driver_entry = { NULL, /* handle */ expat_erl_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ - NULL /* F_PTR outputv, reserved */ + NULL, /* F_PTR outputv, reserved */ + /* Added in Erlang/OTP R15B: */ + NULL, /* ready_async */ + NULL, /* flush */ + NULL, /* call */ + NULL, /* event */ + ERL_DRV_EXTENDED_MARKER, /* extended_marker */ + ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ + ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ + 0, /* driver_flags */ + NULL, /* handle2 */ + NULL, /* process_exit */ + NULL /* stop_select */ }; DRIVER_INIT(expat_erl) /* must match name in driver_entry */ diff --git a/src/mod_irc/iconv_erl.c b/src/mod_irc/iconv_erl.c index 9f4850074..cad415723 100644 --- a/src/mod_irc/iconv_erl.c +++ b/src/mod_irc/iconv_erl.c @@ -24,6 +24,16 @@ #include #include +/* + * R15B changed several driver callbacks to use ErlDrvSizeT and + * ErlDrvSSizeT typedefs instead of int. + * This provides missing typedefs on older OTP versions. + */ +#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 +typedef int ErlDrvSizeT; +typedef int ErlDrvSSizeT; +#endif + typedef struct { ErlDrvPort port; iconv_t cd; @@ -46,10 +56,10 @@ static void iconv_erl_stop(ErlDrvData handle) driver_free((char*)handle); } -static int iconv_erl_control(ErlDrvData drv_data, +static ErlDrvSSizeT iconv_erl_control(ErlDrvData drv_data, unsigned int command, - char *buf, int len, - char **rbuf, int rlen) + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen) { int i; int size; @@ -144,7 +154,19 @@ ErlDrvEntry iconv_driver_entry = { NULL, /* handle */ iconv_erl_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ - NULL /* F_PTR outputv, reserved */ + NULL, /* F_PTR outputv, reserved */ + /* Added in Erlang/OTP R15B: */ + NULL, /* ready_async */ + NULL, /* flush */ + NULL, /* call */ + NULL, /* event */ + ERL_DRV_EXTENDED_MARKER, /* extended_marker */ + ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ + ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ + 0, /* driver_flags */ + NULL, /* handle2 */ + NULL, /* process_exit */ + NULL /* stop_select */ }; DRIVER_INIT(iconv_erl) /* must match name in driver_entry */ diff --git a/src/stringprep/stringprep_drv.c b/src/stringprep/stringprep_drv.c index f4d98f842..e3246e80a 100644 --- a/src/stringprep/stringprep_drv.c +++ b/src/stringprep/stringprep_drv.c @@ -30,6 +30,16 @@ #define NODEPREP_COMMAND 2 #define RESOURCEPREP_COMMAND 3 +/* + * R15B changed several driver callbacks to use ErlDrvSizeT and + * ErlDrvSSizeT typedefs instead of int. + * This provides missing typedefs on older OTP versions. + */ +#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 +typedef int ErlDrvSizeT; +typedef int ErlDrvSSizeT; +#endif + typedef struct { ErlDrvPort port; } stringprep_data; @@ -194,10 +204,10 @@ static int compose(int ch1, int ch2) -static int stringprep_erl_control(ErlDrvData drv_data, +static ErlDrvSSizeT stringprep_erl_control(ErlDrvData drv_data, unsigned int command, - char *buf, int len, - char **rbuf, int rlen) + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen) { int i, j, pos=1; unsigned char c; @@ -400,7 +410,19 @@ ErlDrvEntry stringprep_driver_entry = { NULL, /* handle */ stringprep_erl_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ - NULL /* F_PTR outputv, reserved */ + NULL, /* F_PTR outputv, reserved */ + /* Added in Erlang/OTP R15B: */ + NULL, /* ready_async */ + NULL, /* flush */ + NULL, /* call */ + NULL, /* event */ + ERL_DRV_EXTENDED_MARKER, /* extended_marker */ + ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ + ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ + 0, /* driver_flags */ + NULL, /* handle2 */ + NULL, /* process_exit */ + NULL /* stop_select */ }; DRIVER_INIT(stringprep_erl) /* must match name in driver_entry */ diff --git a/src/tls/sha_drv.c b/src/tls/sha_drv.c index 22426703f..fc8fb9a49 100644 --- a/src/tls/sha_drv.c +++ b/src/tls/sha_drv.c @@ -24,16 +24,26 @@ #include #endif +/* + * R15B changed several driver callbacks to use ErlDrvSizeT and + * ErlDrvSSizeT typedefs instead of int. + * This provides missing typedefs on older OTP versions. + */ +#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 +typedef int ErlDrvSizeT; +typedef int ErlDrvSSizeT; +#endif + static ErlDrvData sha_drv_start(ErlDrvPort port, char *buf) { set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return NULL; } -static int sha_drv_control(ErlDrvData handle, +static ErlDrvSSizeT sha_drv_control(ErlDrvData handle, unsigned int command, - char *buf, int len, - char **rbuf, int rlen) + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen) { ErlDrvBinary *b = NULL; @@ -89,7 +99,19 @@ ErlDrvEntry sha_driver_entry = { NULL, /* handle */ sha_drv_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ - NULL /* F_PTR outputv, reserved */ + NULL, /* F_PTR outputv, reserved */ + /* Added in Erlang/OTP R15B: */ + NULL, /* ready_async */ + NULL, /* flush */ + NULL, /* call */ + NULL, /* event */ + ERL_DRV_EXTENDED_MARKER, /* extended_marker */ + ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ + ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ + 0, /* driver_flags */ + NULL, /* handle2 */ + NULL, /* process_exit */ + NULL /* stop_select */ }; DRIVER_INIT(sha_drv) /* must match name in driver_entry */ diff --git a/src/tls/tls_drv.c b/src/tls/tls_drv.c index bdb5446f2..c4210055a 100644 --- a/src/tls/tls_drv.c +++ b/src/tls/tls_drv.c @@ -44,6 +44,16 @@ typedef unsigned __int32 uint32_t; #define SSL_OP_NO_TICKET 0 #endif +/* + * R15B changed several driver callbacks to use ErlDrvSizeT and + * ErlDrvSSizeT typedefs instead of int. + * This provides missing typedefs on older OTP versions. + */ +#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 +typedef int ErlDrvSizeT; +typedef int ErlDrvSSizeT; +#endif + /* * str_hash is based on the public domain code from * http://www.burtleburtle.net/bob/hash/doobs.html @@ -305,10 +315,10 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) } -static int tls_drv_control(ErlDrvData handle, +static ErlDrvSSizeT tls_drv_control(ErlDrvData handle, unsigned int command, - char *buf, int len, - char **rbuf, int rlen) + char *buf, ErlDrvSizeT len, + char **rbuf, ErlDrvSizeT rlen) { tls_data *d = (tls_data *)handle; int res; @@ -503,7 +513,19 @@ ErlDrvEntry tls_driver_entry = { NULL, /* handle */ tls_drv_control, /* F_PTR control, port_command callback */ NULL, /* F_PTR timeout, reserved */ - NULL /* F_PTR outputv, reserved */ + NULL, /* F_PTR outputv, reserved */ + /* Added in Erlang/OTP R15B: */ + NULL, /* ready_async */ + NULL, /* flush */ + NULL, /* call */ + NULL, /* event */ + ERL_DRV_EXTENDED_MARKER, /* extended_marker */ + ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ + ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ + 0, /* driver_flags */ + NULL, /* handle2 */ + NULL, /* process_exit */ + NULL /* stop_select */ }; DRIVER_INIT(tls_drv) /* must match name in driver_entry */ From 919cdc27dba1b3c1c0a1f68d329815439f021321 Mon Sep 17 00:00:00 2001 From: Badlop Date: Wed, 21 Dec 2011 12:58:58 +0100 Subject: [PATCH 23/30] Fix update with stripped beams (thanks to Jose M Herrero)(EJAB-1520) --- src/ejabberd_update.erl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ejabberd_update.erl b/src/ejabberd_update.erl index 6bb354818..c6aed4db8 100644 --- a/src/ejabberd_update.erl +++ b/src/ejabberd_update.erl @@ -128,8 +128,10 @@ get_new_version(Module) -> get_current_version(Module) -> Attrs = Module:module_info(attributes), - {value, {vsn, CurVsn}} = lists:keysearch(vsn, 1, Attrs), - CurVsn. + case lists:keysearch(vsn, 1, Attrs) of + {value, {vsn, CurVsn}} -> CurVsn; + _ -> unknown_version + end. %% @spec(Dir::string(), UpdatedBeams::[atom()]) -> {Script,LowLevelScript,Check} build_script(Dir, UpdatedBeams) -> From 94350ddb3a37f4aa253f25231b8dfbd38ae8a064 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Wed, 21 Dec 2011 16:20:59 +0200 Subject: [PATCH 24/30] Corrected mod_blocking hooks return value, activate "Blocked Contacts" privacy list after it is changed --- src/mod_blocking.erl | 54 ++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index ea2c19cfb..00977e631 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -64,7 +64,7 @@ process_iq_get(_, From, _To, sub_el = {xmlelement, "blocklist", _, _}}, _) -> #jid{luser = LUser, lserver = LServer} = From, - process_blocklist_get(LUser, LServer); + {stop, process_blocklist_get(LUser, LServer)}; process_iq_get(Acc, _, _, _, _) -> Acc. @@ -72,20 +72,22 @@ process_iq_get(Acc, _, _, _, _) -> process_iq_set(_, From, _To, #iq{xmlns = ?NS_BLOCKING, sub_el = {xmlelement, SubElName, _, SubEls}}) -> #jid{luser = LUser, lserver = LServer} = From, - case {SubElName, xml:remove_cdata(SubEls)} of - {"block", []} -> - {error, ?ERR_BAD_REQUEST}; - {"block", Els} -> - JIDs = parse_blocklist_items(Els, []), - process_blocklist_block(LUser, LServer, JIDs); - {"unblock", []} -> - process_blocklist_unblock_all(LUser, LServer); - {"unblock", Els} -> - JIDs = parse_blocklist_items(Els, []), - process_blocklist_unblock(LUser, LServer, JIDs); - _ -> - {error, ?ERR_BAD_REQUEST} - end; + Res = + case {SubElName, xml:remove_cdata(SubEls)} of + {"block", []} -> + {error, ?ERR_BAD_REQUEST}; + {"block", Els} -> + JIDs = parse_blocklist_items(Els, []), + process_blocklist_block(LUser, LServer, JIDs); + {"unblock", []} -> + process_blocklist_unblock_all(LUser, LServer); + {"unblock", Els} -> + JIDs = parse_blocklist_items(Els, []), + process_blocklist_unblock(LUser, LServer, JIDs); + _ -> + {error, ?ERR_BAD_REQUEST} + end, + {stop, Res}; process_iq_set(Acc, _, _, _) -> Acc. @@ -196,9 +198,10 @@ process_blocklist_block(LUser, LServer, JIDs) -> {atomic, {error, _} = Error} -> Error; {atomic, {ok, Default, List}} -> + UserList = make_userlist(Default, List), broadcast_list_update(LUser, LServer, Default, List), broadcast_blocklist_event(LUser, LServer, {block, JIDs}), - {result, []}; + {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. @@ -238,9 +241,10 @@ process_blocklist_unblock_all(LUser, LServer) -> {atomic, ok} -> {result, []}; {atomic, {ok, Default, List}} -> - broadcast_list_update(LUser, LServer, Default, List), + UserList = make_userlist(Default, List), + broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, unblock_all), - {result, []}; + {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. @@ -284,22 +288,24 @@ process_blocklist_unblock(LUser, LServer, JIDs) -> {atomic, ok} -> {result, []}; {atomic, {ok, Default, List}} -> - broadcast_list_update(LUser, LServer, Default, List), + UserList = make_userlist(Default, List), + broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, {unblock, JIDs}), - {result, []}; + {result, [], UserList}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end. -broadcast_list_update(LUser, LServer, Name, List) -> +make_userlist(Name, List) -> NeedDb = is_list_needdb(List), + #userlist{name = Name, list = List, needdb = NeedDb}. + +broadcast_list_update(LUser, LServer, Name, UserList) -> ejabberd_router:route( jlib:make_jid(LUser, LServer, ""), jlib:make_jid(LUser, LServer, ""), {xmlelement, "broadcast", [], - [{privacy_list, - #userlist{name = Name, list = List, needdb = NeedDb}, - Name}]}). + [{privacy_list, UserList, Name}]}). broadcast_blocklist_event(LUser, LServer, Event) -> JID = jlib:make_jid(LUser, LServer, ""), From 3839f1055a3378992300dcad19edf8198c96a717 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Wed, 21 Dec 2011 18:27:24 +0200 Subject: [PATCH 25/30] Fixed the previous mod_blocking patch --- src/mod_blocking.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index 00977e631..7f3bd684e 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -199,7 +199,7 @@ process_blocklist_block(LUser, LServer, JIDs) -> Error; {atomic, {ok, Default, List}} -> UserList = make_userlist(Default, List), - broadcast_list_update(LUser, LServer, Default, List), + broadcast_list_update(LUser, LServer, Default, UserList), broadcast_blocklist_event(LUser, LServer, {block, JIDs}), {result, [], UserList}; _ -> From a3c58f28965fb6a858f1a6d347a9bd9548c6e927 Mon Sep 17 00:00:00 2001 From: Alexey Shchepin Date: Thu, 22 Dec 2011 16:35:56 +0200 Subject: [PATCH 26/30] Always allow packets from user's server and bare jid in mod_privacy* --- src/mod_privacy.erl | 21 +++++++++++++++++++++ src/mod_privacy_odbc.erl | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 38ecf138b..e100a8a15 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -559,6 +559,27 @@ get_user_list(_, User, Server) -> %% From is the sender, To is the destination. %% If Dir = out, User@Server is the sender account (From). %% If Dir = in, User@Server is the destination account (To). +check_packet(_, _User, _Server, + _UserList, + {#jid{luser = "", lserver = Server} = _From, + #jid{lserver = Server} = _To, + _}, + in) -> + allow; +check_packet(_, _User, _Server, + _UserList, + {#jid{lserver = Server} = _From, + #jid{luser = "", lserver = Server} = _To, + _}, + out) -> + allow; +check_packet(_, _User, _Server, + _UserList, + {#jid{luser = User, lserver = Server} = _From, + #jid{luser = User, lserver = Server} = _To, + _}, + _Dir) -> + allow; check_packet(_, User, Server, #userlist{list = List, needdb = NeedDb}, {From, To, {xmlelement, PName, Attrs, _}}, diff --git a/src/mod_privacy_odbc.erl b/src/mod_privacy_odbc.erl index 2df9ee27a..b8d8ec8d6 100644 --- a/src/mod_privacy_odbc.erl +++ b/src/mod_privacy_odbc.erl @@ -557,6 +557,27 @@ get_user_list(_, User, Server) -> %% From is the sender, To is the destination. %% If Dir = out, User@Server is the sender account (From). %% If Dir = in, User@Server is the destination account (To). +check_packet(_, _User, _Server, + _UserList, + {#jid{luser = "", lserver = Server} = _From, + #jid{lserver = Server} = _To, + _}, + in) -> + allow; +check_packet(_, _User, _Server, + _UserList, + {#jid{lserver = Server} = _From, + #jid{luser = "", lserver = Server} = _To, + _}, + out) -> + allow; +check_packet(_, _User, _Server, + _UserList, + {#jid{luser = User, lserver = Server} = _From, + #jid{luser = User, lserver = Server} = _To, + _}, + _Dir) -> + allow; check_packet(_, User, Server, #userlist{list = List, needdb = NeedDb}, {From, To, {xmlelement, PName, Attrs, _}}, From ce7b008b8f4526b489ff3f4beeb0a17bf90e3d19 Mon Sep 17 00:00:00 2001 From: Badlop Date: Fri, 23 Dec 2011 11:33:33 +0100 Subject: [PATCH 27/30] Use the regexp frontend module (EJAB-921) --- src/eldap/eldap_filter.erl | 42 ++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/eldap/eldap_filter.erl b/src/eldap/eldap_filter.erl index d2e1b66a4..f55df6f41 100644 --- a/src/eldap/eldap_filter.erl +++ b/src/eldap/eldap_filter.erl @@ -146,30 +146,36 @@ do_sub(S, [{RegExp, New, Times} | T]) -> do_sub(Result, T). do_sub(S, {RegExp, New}, Iter) -> - case regexp:sub(S, RegExp, New) of - {ok, NewS, 0} -> - NewS; - {ok, NewS, _} when Iter =< ?MAX_RECURSION -> - do_sub(NewS, {RegExp, New}, Iter+1); - {ok, _, _} when Iter > ?MAX_RECURSION -> - erlang:error(max_substitute_recursion); - _ -> - erlang:error(bad_regexp) + case ejabberd_regexp:run(S, RegExp) of + match -> + case ejabberd_regexp:replace(S, RegExp, New) of + NewS when Iter =< ?MAX_RECURSION -> + do_sub(NewS, {RegExp, New}, Iter+1); + _NewS when Iter > ?MAX_RECURSION -> + erlang:error(max_substitute_recursion) + end; + nomatch -> + S; + _ -> + erlang:error(bad_regexp) end; do_sub(S, {_, _, N}, _) when N<1 -> S; do_sub(S, {RegExp, New, Times}, Iter) -> - case regexp:sub(S, RegExp, New) of - {ok, NewS, 0} -> - NewS; - {ok, NewS, _} when Iter < Times -> - do_sub(NewS, {RegExp, New, Times}, Iter+1); - {ok, NewS, _} -> - NewS; - _ -> - erlang:error(bad_regexp) + case ejabberd_regexp:run(S, RegExp) of + match -> + case ejabberd_regexp:replace(S, RegExp, New) of + NewS when Iter < Times -> + do_sub(NewS, {RegExp, New, Times}, Iter+1); + NewS -> + NewS + end; + nomatch -> + S; + _ -> + erlang:error(bad_regexp) end. replace_amps(String) -> From 684cac274d85e12e62ca22e51613e9443860db33 Mon Sep 17 00:00:00 2001 From: Badlop Date: Fri, 23 Dec 2011 12:19:38 +0100 Subject: [PATCH 28/30] Support undefinition of ssl:seed in R15B --- src/eldap/eldap.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eldap/eldap.erl b/src/eldap/eldap.erl index aa22e1849..354ab297e 100644 --- a/src/eldap/eldap.erl +++ b/src/eldap/eldap.erl @@ -439,7 +439,7 @@ init([]) -> end; init({Hosts, Port, Rootdn, Passwd, Opts}) -> catch ssl:start(), - ssl:seed(randoms:get_string()), + catch ssl:seed(randoms:get_string()), Encrypt = case proplists:get_value(encrypt, Opts) of tls -> tls; _ -> none From 6edbbded40d3e86d500a2ed65dfff4eef3f399e1 Mon Sep 17 00:00:00 2001 From: Badlop Date: Fri, 23 Dec 2011 12:24:27 +0100 Subject: [PATCH 29/30] New release notes for 2.1.10 --- doc/release_notes_2.1.10.txt | 39 ++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 doc/release_notes_2.1.10.txt diff --git a/doc/release_notes_2.1.10.txt b/doc/release_notes_2.1.10.txt new file mode 100644 index 000000000..bf118594e --- /dev/null +++ b/doc/release_notes_2.1.10.txt @@ -0,0 +1,39 @@ + + Release Notes + ejabberd 2.1.10 + + ejabberd 2.1.10 includes a few bugfixes and improvements. + + Read more details about the changes in: + http://redir.process-one.net/ejabberd-2.1.10 + + Download the source code and installers from: + http://www.process-one.net/en/ejabberd/ + + + The major changes are: + +* Erlang/OTP compatibility +- Support Erlang/OTP R15B regexp and drivers (EJAB-1521) +- Fix modules update in R14B04 and higher +- Fix modules update of stripped beams (EJAB-1520) + +* XMPP Core +- Fix presence problem in C2S after first unavailable (EJAB-1466) +- Fix bug on S2S shaper when TLS is used +- Prevent overload of incoming S2S connections + +* XEPs +- BOSH: Get rid of useless mnesia transaction (EJAB-1502) +- MUC: Don't reveal invitee resource when room informs invitor +- Privacy: Activate "Blocked Contacts" to current c2s connection (EJAB-1519) +- Privacy: Always allow packets from user's server and bare jid (EJAB-1441) +- Pubsub: Add hooks for node creation/deletion (EJAB-1470) +- Shared Rosters: support groupname@vhost in Displayed Groups (EJAB-506) +- Vcard: Fix error when lowercasing some search results (EJAB-1490) + + + Bug reports + + You can officially report bugs on ProcessOne support site: + http://support.process-one.net/ From bcdae191417bbec40ec87d71b8143942da92f2f1 Mon Sep 17 00:00:00 2001 From: Badlop Date: Fri, 23 Dec 2011 12:27:30 +0100 Subject: [PATCH 30/30] Update ejabberd version number to 2.1.10 --- doc/dev.html | 4 ++-- doc/features.html | 4 ++-- doc/guide.html | 53 +++++++++++++++++++++++------------------------ doc/version.tex | 2 +- src/configure | 18 ++++++++-------- src/ejabberd.app | 2 +- 6 files changed, 41 insertions(+), 42 deletions(-) diff --git a/doc/dev.html b/doc/dev.html index b86448c56..83da3eb10 100644 --- a/doc/dev.html +++ b/doc/dev.html @@ -2,7 +2,7 @@ "http://www.w3.org/TR/REC-html40/loose.dtd"> -Ejabberd 2.1.x Developers Guide +<TITLE>Ejabberd 2.1.10 Developers Guide @@ -49,7 +49,7 @@ TD P{margin:0px;}

    -

    Ejabberd 2.1.x Developers Guide

    Alexey Shchepin
    +

    Ejabberd 2.1.10 Developers Guide

    Alexey Shchepin
    mailto:alexey@sevcom.net
    xmpp:aleksey@jabber.ru

    diff --git a/doc/features.html b/doc/features.html index 503ac0d3f..025511cd3 100644 --- a/doc/features.html +++ b/doc/features.html @@ -2,7 +2,7 @@ "http://www.w3.org/TR/REC-html40/loose.dtd"> -Ejabberd 2.1.x Feature Sheet +<TITLE>Ejabberd 2.1.10 Feature Sheet @@ -50,7 +50,7 @@ SPAN{width:20%; float:right; text-align:left; margin-left:auto;}

    -

    Ejabberd 2.1.x Feature Sheet

    Sander Devrieze
    +

    Ejabberd 2.1.10 Feature Sheet

    Sander Devrieze
    mailto:s.devrieze@pandora.be
    xmpp:sander@devrieze.dyndns.org

    diff --git a/doc/guide.html b/doc/guide.html index 58f5cb2c2..787ec960b 100644 --- a/doc/guide.html +++ b/doc/guide.html @@ -6,7 +6,7 @@ - ejabberd 2.1.x + ejabberd 2.1.10 Installation and Operation Guide @@ -76,7 +76,7 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}


    - +
    ejabberd 2.1.x
    ejabberd 2.1.10
     
    Installation and Operation Guide

    @@ -207,21 +207,20 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}
  • 6.2  Clustering Setup
  • 6.3  Service Load-Balancing
  • -
  • 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
  • Chapter 1  Introduction

    ejabberd is a free and open source instant messaging server written in Erlang/OTP.

    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.

    @@ -3251,8 +3250,9 @@ represents all the registered users in the virtual host; which is only recommended for a small server with just a few hundred users. The special member directive @online@ represents the online users in the virtual host. -
    Displayed groups
    A list of groups that will be in the rosters of this -group’s members. +
    Displayed groups
    +A list of groups that will be in the rosters of this group’s members. +A group of other vhost can be identified with groupid@vhost

    Examples:

    • Take the case of a computer club that wants all its members seeing each @@ -4359,9 +4359,8 @@ enabled only on one machine in the cluster.
    • You can repeat these steps for other machines supposed to serve this domain.

      6.3  Service Load-Balancing

      -

      -

      6.3.1  Components Load-Balancing

      -

      6.3.2  Domain Load-Balancing Algorithm

      +

      +

      6.3.1  Domain Load-Balancing Algorithm

      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", BalancingCriteria}.

      Several balancing criteria are available:

      • @@ -4370,12 +4369,12 @@ domain.

        -

        6.3.3  Load-Balancing Buckets

        +

        6.3.2  Load-Balancing Buckets

        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:

        {domain_balancing_component_number, "component.example.com", Number}.

        -

        Chapter 7  Debugging

        +

        Chapter 7  Debugging

        -

        7.1  Log Files

        An ejabberd node writes two log files: +

        7.1  Log Files

        An ejabberd node writes two log files:

        ejabberd.log
        is the ejabberd service log, with the messages reported by ejabberd code
        erlang.log
        is the Erlang/OTP system log, with the messages reported by Erlang/OTP using SASL (System Architecture Support Libraries) @@ -4400,12 +4399,12 @@ The ejabberdctl command reopen-log (please refer to section 4.1.1) reopens the log files, and also renames the old ones if you didn’t rename them.

        -

        7.2  Debug Console

        The Debug Console is an Erlang shell attached to an already running ejabberd server. +

        7.2  Debug Console

        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.

        -

        7.3  Watchdog Alerts

        +

        7.3  Watchdog Alerts

        ejabberd includes a watchdog mechanism that may be useful to developers when troubleshooting a problem related to memory usage. If a process in the ejabberd server consumes more memory than the configured threshold, @@ -4425,7 +4424,7 @@ or in a conversation with the watchdog alert bot.

        The syntax is: To remove all watchdog admins, set the option with an empty list:

        {watchdog_admins, []}.
         

        -

        Appendix A  Internationalization and Localization

        +

        Appendix A  Internationalization and Localization

        The source code of ejabberd supports localization. The translators can edit the gettext .po files @@ -4460,9 +4459,9 @@ HTTP header ‘Accept-Language: ru’


    -

    Appendix B  Release Notes

    +

    Appendix B  Release Notes

    Release notes are available from ejabberd Home Page

    -

    Appendix C  Acknowledgements

    Thanks to all people who contributed to this guide: +

    Appendix C  Acknowledgements

    Thanks to all people who contributed to this guide:

    -

    Appendix D  Copyright Information

    Ejabberd Installation and Operation Guide.
    +

    Appendix D  Copyright Information

    Ejabberd Installation and Operation Guide.
    Copyright © 2003 — 2010 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 diff --git a/doc/version.tex b/doc/version.tex index 905ac86f2..40b1b7baa 100644 --- a/doc/version.tex +++ b/doc/version.tex @@ -1,2 +1,2 @@ % ejabberd version (automatically generated). -\newcommand{\version}{2.1.x} +\newcommand{\version}{2.1.10} diff --git a/src/configure b/src/configure index 89e32a5f1..14bafa922 100755 --- a/src/configure +++ b/src/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for ejabberd 2.1.x. +# Generated by GNU Autoconf 2.68 for ejabberd 2.1.10. # # Report bugs to . # @@ -560,8 +560,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ejabberd' PACKAGE_TARNAME='ejabberd' -PACKAGE_VERSION='2.1.x' -PACKAGE_STRING='ejabberd 2.1.x' +PACKAGE_VERSION='2.1.10' +PACKAGE_STRING='ejabberd 2.1.10' PACKAGE_BUGREPORT='ejabberd@process-one.net' PACKAGE_URL='' @@ -1288,7 +1288,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 ejabberd 2.1.x to adapt to many kinds of systems. +\`configure' configures ejabberd 2.1.10 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1354,7 +1354,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of ejabberd 2.1.x:";; + short | recursive ) echo "Configuration of ejabberd 2.1.10:";; esac cat <<\_ACEOF @@ -1479,7 +1479,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -ejabberd configure 2.1.x +ejabberd configure 2.1.10 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1823,7 +1823,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 ejabberd $as_me 2.1.x, which was +It was created by ejabberd $as_me 2.1.10, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -5690,7 +5690,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by ejabberd $as_me 2.1.x, which was +This file was extended by ejabberd $as_me 2.1.10, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5743,7 +5743,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -ejabberd config.status 2.1.x +ejabberd config.status 2.1.10 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/src/ejabberd.app b/src/ejabberd.app index 3fb342fe8..3d4f50f84 100644 --- a/src/ejabberd.app +++ b/src/ejabberd.app @@ -2,7 +2,7 @@ {application, ejabberd, [{description, "ejabberd"}, - {vsn, "2.1.x"}, + {vsn, "2.1.10"}, {modules, [acl, adhoc, configure,