diff options
Diffstat (limited to 'src')
144 files changed, 1483 insertions, 603 deletions
diff --git a/src/acl.erl b/src/acl.erl index 53256fcbd..8d9692ffb 100644 --- a/src/acl.erl +++ b/src/acl.erl @@ -5,7 +5,7 @@ %%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/adhoc.erl b/src/adhoc.erl index 800a0a302..a68b54d89 100644 --- a/src/adhoc.erl +++ b/src/adhoc.erl @@ -5,7 +5,7 @@ %%% Created : 31 Oct 2005 by Magnus Henoch <henoch@dtek.chalmers.se> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/cyrsasl.erl b/src/cyrsasl.erl index db2160ca9..764473bab 100644 --- a/src/cyrsasl.erl +++ b/src/cyrsasl.erl @@ -5,7 +5,7 @@ %%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/cyrsasl_anonymous.erl b/src/cyrsasl_anonymous.erl index 67e12b8c6..51d5db9d8 100644 --- a/src/cyrsasl_anonymous.erl +++ b/src/cyrsasl_anonymous.erl @@ -6,7 +6,7 @@ %%% Created : 23 Aug 2005 by Magnus Henoch <henoch@dtek.chalmers.se> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/cyrsasl_digest.erl b/src/cyrsasl_digest.erl index d6a2afdf1..10f964130 100644 --- a/src/cyrsasl_digest.erl +++ b/src/cyrsasl_digest.erl @@ -5,7 +5,7 @@ %%% Created : 11 Mar 2003 by Alexey Shchepin <alexey@sevcom.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/cyrsasl_plain.erl b/src/cyrsasl_plain.erl index 4f530e8f5..d2fb373e4 100644 --- a/src/cyrsasl_plain.erl +++ b/src/cyrsasl_plain.erl @@ -5,7 +5,7 @@ %%% Created : 8 Mar 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/cyrsasl_scram.erl b/src/cyrsasl_scram.erl index 1175af1e9..1fd7c1be5 100644 --- a/src/cyrsasl_scram.erl +++ b/src/cyrsasl_scram.erl @@ -5,7 +5,7 @@ %%% Created : 7 Aug 2011 by Stephen Röttger <stephen.roettger@googlemail.com> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -76,9 +76,11 @@ mech_step(#state{step = 2} = State, ClientIn) -> UserName -> case parse_attribute(ClientNonceAttribute) of {$r, ClientNonce} -> - case (State#state.get_password)(UserName) of + {Ret, _AuthModule} = (State#state.get_password)(UserName), + case {Ret, jlib:resourceprep(Ret)} of {false, _} -> {error, <<"not-authorized">>, UserName}; - {Ret, _AuthModule} -> + {_, error} when is_binary(Ret) -> ?WARNING_MSG("invalid plain password", []), {error, <<"not-authorized">>, UserName}; + {Ret, _} -> {StoredKey, ServerKey, Salt, IterationCount} = if is_tuple(Ret) -> Ret; true -> diff --git a/src/ejabberd.erl b/src/ejabberd.erl index ebe2b170c..64ac5a0da 100644 --- a/src/ejabberd.erl +++ b/src/ejabberd.erl @@ -5,7 +5,7 @@ %%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl index 3174b8523..8b6e27b82 100644 --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -5,7 +5,7 @@ %%% Created : 7 May 2006 by Mickael Remond <mremond@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -31,6 +31,7 @@ status/0, reopen_log/0, stop_kindly/2, send_service_message_all_mucs/2, registered_vhosts/0, + reload_config/0, %% Erlang update_list/0, update/1, %% Accounts @@ -134,6 +135,11 @@ commands() -> module = ?MODULE, function = registered_vhosts, args = [], result = {vhosts, {list, {vhost, string}}}}, + #ejabberd_commands{name = reload_config, tags = [server], + desc = "Reload ejabberd configuration file into memory", + module = ?MODULE, function = reload_config, + args = [], + result = {res, rescode}}, #ejabberd_commands{name = import_file, tags = [mnesia], desc = "Import user data from jabberd14 spool file", @@ -252,9 +258,10 @@ reopen_log() -> %%% Stop Kindly %%% -stop_kindly(DelaySeconds, AnnouncementText) -> - Subject = io_lib:format("Server stop in ~p seconds!", [DelaySeconds]), - WaitingDesc = io_lib:format("Waiting ~p seconds", [DelaySeconds]), +stop_kindly(DelaySeconds, AnnouncementTextString) -> + Subject = list_to_binary(io_lib:format("Server stop in ~p seconds!", [DelaySeconds])), + WaitingDesc = list_to_binary(io_lib:format("Waiting ~p seconds", [DelaySeconds])), + AnnouncementText = list_to_binary(AnnouncementTextString), Steps = [ {"Stopping ejabberd port listeners", ejabberd_listener, stop_listeners, []}, @@ -351,6 +358,11 @@ registered_users(Host) -> registered_vhosts() -> ?MYHOSTS. +reload_config() -> + ejabberd_config:reload_file(), + acl:start(), + shaper:start(). + %%% %%% Migration management %%% diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl index 379f728d6..957aa5d46 100644 --- a/src/ejabberd_app.erl +++ b/src/ejabberd_app.erl @@ -5,7 +5,7 @@ %%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index f716bbb35..34d4a52b2 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -5,7 +5,7 @@ %%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -300,7 +300,7 @@ get_password_with_authmodule(User, Server) -> -spec is_user_exists(binary(), binary()) -> boolean(). -is_user_exists(User, <<"">>) -> +is_user_exists(_User, <<"">>) -> false; is_user_exists(User, Server) -> diff --git a/src/ejabberd_auth_anonymous.erl b/src/ejabberd_auth_anonymous.erl index c8c9cb153..cb320dea5 100644 --- a/src/ejabberd_auth_anonymous.erl +++ b/src/ejabberd_auth_anonymous.erl @@ -5,7 +5,7 @@ %%% Created : 17 Feb 2006 by Mickael Remond <mremond@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl index 74263f748..0aa825f73 100644 --- a/src/ejabberd_auth_external.erl +++ b/src/ejabberd_auth_external.erl @@ -5,7 +5,7 @@ %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_auth_internal.erl b/src/ejabberd_auth_internal.erl index 48bd6bd96..415c21713 100644 --- a/src/ejabberd_auth_internal.erl +++ b/src/ejabberd_auth_internal.erl @@ -5,7 +5,7 @@ %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -77,10 +77,7 @@ update_reg_users_counter_table(Server) -> mnesia:sync_dirty(F). plain_password_required() -> - case is_scrammed() of - false -> false; - true -> true - end. + is_scrammed(). store_type() -> case is_scrammed() of @@ -150,7 +147,7 @@ set_password(User, Server, Password) -> ok end. -%% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid} | {aborted, Reason} +%% @spec (User, Server, Password) -> {atomic, ok} | {atomic, exists} | {error, invalid_jid} | {error, not_allowed} | {error, Reason} try_register(User, Server, PasswordList) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl index 7eba6ef32..3055d1044 100644 --- a/src/ejabberd_auth_ldap.erl +++ b/src/ejabberd_auth_ldap.erl @@ -5,7 +5,7 @@ %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_auth_odbc.erl b/src/ejabberd_auth_odbc.erl index 57cef930a..aea039c1b 100644 --- a/src/ejabberd_auth_odbc.erl +++ b/src/ejabberd_auth_odbc.erl @@ -5,7 +5,7 @@ %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_auth_pam.erl b/src/ejabberd_auth_pam.erl index 9c73d97f8..f3fdf628d 100644 --- a/src/ejabberd_auth_pam.erl +++ b/src/ejabberd_auth_pam.erl @@ -5,7 +5,7 @@ %%% Created : 5 Jul 2007 by Evgeniy Khramtsov <xram@jabber.ru> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl index e5d901cfc..fb9be2c3e 100644 --- a/src/ejabberd_auth_riak.erl +++ b/src/ejabberd_auth_riak.erl @@ -5,7 +5,7 @@ %%% Created : 12 Nov 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2012 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -17,10 +17,9 @@ %%% 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 +%%% 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. %%% %%%---------------------------------------------------------------------- diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index c762fc0e1..7632cb121 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -5,7 +5,7 @@ %%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -2848,9 +2848,8 @@ send_stanza_and_ack_req(StateData, Stanza) -> AckReq = #xmlel{name = <<"r">>, attrs = [{<<"xmlns">>, StateData#state.mgmt_xmlns}], children = []}, - StanzaS = xml:element_to_binary(Stanza), - AckReqS = xml:element_to_binary(AckReq), - send_text(StateData, [StanzaS, AckReqS]). + send_element(StateData, Stanza), + send_element(StateData, AckReq). mgmt_queue_add(StateData, El) -> NewNum = case StateData#state.mgmt_stanzas_out of diff --git a/src/ejabberd_c2s_config.erl b/src/ejabberd_c2s_config.erl index 3c65d562b..a971f0af4 100644 --- a/src/ejabberd_c2s_config.erl +++ b/src/ejabberd_c2s_config.erl @@ -6,7 +6,7 @@ %%% Created : 2 Nov 2007 by Mickael Remond <mremond@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index ab91ccb04..110da1f69 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -5,7 +5,7 @@ %%% Created : 26 Apr 2008 by Evgeniy Khramtsov <xramtsov@gmail.com> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -549,10 +549,11 @@ get_transfer_protocol(PortString) -> get_port_listeners(PortNumber) -> AllListeners = ejabberd_config:get_option(listen, fun(V) -> V end), - lists:filter(fun ({{Port, _Ip, _Netp}, _Module1, - _Opts1}) - when Port == PortNumber -> - true; + lists:filter(fun (Listener) when is_list(Listener) -> + case proplists:get_value(port, Listener) of + PortNumber -> true; + _ -> false + end; (_) -> false end, AllListeners). @@ -562,12 +563,11 @@ get_captcha_transfer_protocol([]) -> "is not a ejabberd_http listener with " "'captcha' option. Change the port number " "or specify http:// in that option.">>); -get_captcha_transfer_protocol([{{_Port, _Ip, tcp}, - ejabberd_http, Opts} - | Listeners]) -> - case lists:member(captcha, Opts) of +get_captcha_transfer_protocol([Listener | Listeners]) when is_list(Listener) -> + case proplists:get_value(module, Listener) == ejabberd_http andalso + proplists:get_bool(captcha, Listener) of true -> - case lists:member(tls, Opts) of + case proplists:get_bool(tls, Listener) of true -> https; false -> http end; diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl index 8d9ec0cb0..c279f2d0f 100644 --- a/src/ejabberd_commands.erl +++ b/src/ejabberd_commands.erl @@ -5,7 +5,7 @@ %%% Created : 20 May 2008 by Badlop <badlop@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -399,7 +399,14 @@ check_auth({User, Server, Password}) -> check_access(all, _) -> true; check_access(Access, Auth) -> - {ok, User, Server} = check_auth(Auth), + case check_auth(Auth) of + {ok, User, Server} -> + check_access(Access, User, Server); + _ -> + false + end. + +check_access(Access, User, Server) -> %% Check this user has access permission case acl:match_rule(Server, Access, jlib:make_jid(User, Server, <<"">>)) of allow -> true; diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 5b3b5ad1d..54a635905 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -5,7 +5,7 @@ %%% Created : 14 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -26,7 +26,7 @@ -module(ejabberd_config). -author('alexey@process-one.net'). --export([start/0, load_file/1, read_file/1, +-export([start/0, load_file/1, reload_file/0, read_file/1, add_global_option/2, add_local_option/2, get_global_option/2, get_local_option/2, get_global_option/3, get_local_option/3, @@ -125,6 +125,12 @@ load_file(File) -> State = read_file(File), set_opts(State). +-spec reload_file() -> ok. + +reload_file() -> + Config = get_ejabberd_config_path(), + load_file(Config). + -spec convert_to_yaml(file:filename()) -> ok | {error, any()}. convert_to_yaml(File) -> @@ -184,7 +190,7 @@ consult(File) -> {ok, []} -> {ok, []}; {ok, [Document|_]} -> - {ok, Document}; + {ok, parserl(Document)}; {error, Err} -> Msg1 = "Cannot load " ++ File ++ ": ", Msg2 = p1_yaml:format_error(Err), @@ -201,6 +207,17 @@ consult(File) -> end end. +parserl(<<"> ", Term/binary>>) -> + {ok, A2, _} = erl_scan:string(binary_to_list(Term)), + {ok, A3} = erl_parse:parse_term(A2), + A3; +parserl({A, B}) -> + {parserl(A), parserl(B)}; +parserl([El|Tail]) -> + [parserl(El) | parserl(Tail)]; +parserl(Other) -> + Other. + %% @doc Convert configuration filename to absolute path. %% Input is an absolute or relative path to an ejabberd configuration file. %% And returns an absolute path to the configuration file. @@ -690,26 +707,40 @@ replace_module(mod_roster_odbc) -> {mod_roster, odbc}; replace_module(mod_shared_roster_odbc) -> {mod_shared_roster, odbc}; replace_module(mod_vcard_odbc) -> {mod_vcard, odbc}; replace_module(mod_vcard_xupdate_odbc) -> {mod_vcard_xupdate, odbc}; -replace_module(Module) -> Module. - -replace_modules(Modules) -> - lists:map( - fun({Module, Opts}) -> - case replace_module(Module) of - {NewModule, DBType} -> - emit_deprecation_warning(Module, NewModule, DBType), - NewOpts = [{db_type, DBType} | - lists:keydelete(db_type, 1, Opts)], - {NewModule, transform_module_options(Module, NewOpts)}; - NewModule -> - if Module /= NewModule -> - emit_deprecation_warning(Module, NewModule); - true -> - ok - end, - {NewModule, transform_module_options(Module, Opts)} - end - end, Modules). +replace_module(Module) -> + case is_elixir_module(Module) of + true -> expand_elixir_module(Module); + false -> Module + end. + +replace_modules(Modules) -> lists:map( fun({Module, Opts}) -> case + replace_module(Module) of {NewModule, DBType} -> + emit_deprecation_warning(Module, NewModule, DBType), NewOpts = + [{db_type, DBType} | lists:keydelete(db_type, 1, Opts)], + {NewModule, transform_module_options(Module, NewOpts)}; NewModule + -> if Module /= NewModule -> emit_deprecation_warning(Module, + NewModule); true -> ok end, {NewModule, + transform_module_options(Module, Opts)} end end, Modules). + +%% Elixir module naming +%% ==================== + +%% If module name start with uppercase letter, this is an Elixir module: +is_elixir_module(Module) -> + case atom_to_list(Module) of + [H|_] when H >= 65, H =< 90 -> true; + _ ->false + end. + +%% We assume we know this is an elixir module +expand_elixir_module(Module) -> + case atom_to_list(Module) of + %% Module name already specified as an Elixir from Erlang module name + "Elixir." ++ _ -> Module; + %% if start with uppercase letter, this is an Elixir module: Append 'Elixir.' to module name. + ModuleString -> + list_to_atom("Elixir." ++ ModuleString) + end. strings_to_binary([]) -> []; @@ -992,5 +1023,10 @@ emit_deprecation_warning(Module, NewModule, DBType) -> " instead", [Module, NewModule, DBType]). emit_deprecation_warning(Module, NewModule) -> - ?WARNING_MSG("Module ~s is deprecated, use ~s instead", - [Module, NewModule]). + case is_elixir_module(NewModule) of + %% Do not emit deprecation warning for Elixir + true -> ok; + false -> + ?WARNING_MSG("Module ~s is deprecated, use ~s instead", + [Module, NewModule]) + end. diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index eda1c4970..6ab383b12 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -5,7 +5,7 @@ %%% Created : 11 Jan 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -210,7 +210,7 @@ process(Args) -> %% @spec (Args::[string()], AccessCommands) -> {String::string(), Code::integer()} process2(["--auth", User, Server, Pass | Args], AccessCommands) -> - process2(Args, {User, Server, Pass}, AccessCommands); + process2(Args, {list_to_binary(User), list_to_binary(Server), list_to_binary(Pass)}, AccessCommands); process2(Args, AccessCommands) -> process2(Args, noauth, AccessCommands). diff --git a/src/ejabberd_frontend_socket.erl b/src/ejabberd_frontend_socket.erl index d6ef3617d..b169572b3 100644 --- a/src/ejabberd_frontend_socket.erl +++ b/src/ejabberd_frontend_socket.erl @@ -5,7 +5,7 @@ %%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_hooks.erl b/src/ejabberd_hooks.erl index 87c26c5ed..c1cdefcb2 100644 --- a/src/ejabberd_hooks.erl +++ b/src/ejabberd_hooks.erl @@ -5,7 +5,7 @@ %%% Created : 8 Aug 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl index 162d5ac73..b624bf447 100644 --- a/src/ejabberd_http.erl +++ b/src/ejabberd_http.erl @@ -5,7 +5,7 @@ %%% Created : 27 Feb 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -109,11 +109,6 @@ init({SockMod, Socket}, Opts) -> {p1_tls, TLSSocket}; true -> {SockMod, Socket} end, - case SockMod1 of - gen_tcp -> - inet:setopts(Socket1, [{packet, http_bin}, {recbuf, 8192}]); - _ -> ok - end, Captcha = case proplists:get_bool(captcha, Opts) of true -> [{[<<"captcha">>], ejabberd_captcha}]; false -> [] @@ -182,22 +177,10 @@ receive_headers(#state{trail = Trail} = State) -> SockMod = State#state.sockmod, Socket = State#state.socket, Data = SockMod:recv(Socket, 0, 300000), - case State#state.sockmod of - gen_tcp -> - NewState = process_header(State, Data), - case NewState#state.end_of_request of - true -> - ok; - _ -> - receive_headers(NewState) - end; - _ -> - case Data of - {ok, D} -> - parse_headers(State#state{trail = <<Trail/binary, D/binary>>}); - {error, _} -> - ok - end + case Data of + {error, _} -> ok; + {ok, D} -> + parse_headers(State#state{trail = <<Trail/binary, D/binary>>}) end. parse_headers(#state{trail = <<>>} = State) -> @@ -270,6 +253,11 @@ process_header(State, Data) -> {ok, {http_header, _, 'Host' = Name, _, Host}} -> State#state{request_host = Host, request_headers = add_header(Name, Host, State)}; + {ok, {http_header, _, Name, _, Value}} when is_binary(Name) -> + State#state{request_headers = + add_header(normalize_header_name(Name), + Value, + State)}; {ok, {http_header, _, Name, _, Value}} -> State#state{request_headers = add_header(Name, Value, State)}; @@ -280,7 +268,7 @@ process_header(State, Data) -> []), throw(http_request_no_host_header); {ok, http_eoh} -> - ?DEBUG("(~w) http query: ~w ~s~n", + ?DEBUG("(~w) http query: ~w ~p~n", [State#state.socket, State#state.request_method, element(2, State#state.request_path)]), {HostProvided, Port, TP} = @@ -294,18 +282,17 @@ process_header(State, Data) -> send_text(State2, Out), case State2#state.request_keepalive of true -> - case SockMod of - gen_tcp -> inet:setopts(Socket, [{packet, http_bin}]); - _ -> ok - end, #state{sockmod = SockMod, socket = Socket, + options = State#state.options, request_handlers = State#state.request_handlers}; _ -> #state{end_of_request = true, + options = State#state.options, request_handlers = State#state.request_handlers} end; _ -> #state{end_of_request = true, + options = State#state.options, request_handlers = State#state.request_handlers} end. @@ -342,48 +329,93 @@ get_transfer_protocol(SockMod, HostPort) -> %% XXX bard: search through request handlers looking for one that %% matches the requested URL path, and pass control to it. If none is %% found, answer with HTTP 404. -process([], _) -> - ejabberd_web:error(not_found); -process(Handlers, Request) -> - %% Only the first element in the path prefix is checked - [{HandlerPathPrefix, HandlerModule} | HandlersLeft] = - Handlers, - case lists:prefix(HandlerPathPrefix, - Request#request.path) - or (HandlerPathPrefix == Request#request.path) - of - true -> - ?DEBUG("~p matches ~p", - [Request#request.path, HandlerPathPrefix]), - LocalPath = lists:nthtail(length(HandlerPathPrefix), - Request#request.path), - ?DEBUG("~p", [Request#request.headers]), - R = HandlerModule:process(LocalPath, Request), - ejabberd_hooks:run(http_request_debug, - [{LocalPath, Request}]), - R; - false -> process(HandlersLeft, Request) + +process([], _, _, _, _) -> ejabberd_web:error(not_found); +process(Handlers, Request, Socket, SockMod, Trail) -> + {HandlerPathPrefix, HandlerModule, HandlerOpts, HandlersLeft} = + case Handlers of + [{Pfx, Mod} | Tail] -> + {Pfx, Mod, [], Tail}; + [{Pfx, Mod, Opts} | Tail] -> + {Pfx, Mod, Opts, Tail} + end, + + case (lists:prefix(HandlerPathPrefix, Request#request.path) or + (HandlerPathPrefix==Request#request.path)) of + true -> + ?DEBUG("~p matches ~p", [Request#request.path, HandlerPathPrefix]), + %% LocalPath is the path "local to the handler", i.e. if + %% the handler was registered to handle "/test/" and the + %% requested path is "/test/foo/bar", the local path is + %% ["foo", "bar"] + LocalPath = lists:nthtail(length(HandlerPathPrefix), Request#request.path), + R = try + HandlerModule:socket_handoff( + LocalPath, Request, Socket, SockMod, Trail, HandlerOpts) + catch error:undef -> + HandlerModule:process(LocalPath, Request) + end, + ejabberd_hooks:run(http_request_debug, [{LocalPath, Request}]), + R; + false -> + process(HandlersLeft, Request, Socket, SockMod, Trail) end. -process_request(#state{request_method = Method, options = Options, - request_path = {abs_path, Path}, request_auth = Auth, - request_lang = Lang, request_handlers = RequestHandlers, - request_host = Host, request_port = Port, - request_tp = TP, request_headers = RequestHeaders, - sockmod = SockMod, - socket = Socket} = State) - when Method=:='GET' orelse Method=:='HEAD' orelse Method=:='DELETE' orelse Method=:='OPTIONS' -> - case (catch url_decode_q_split(Path)) of - {'EXIT', _} -> +extract_path_query(#state{request_method = Method, + request_path = {abs_path, Path}}) + when Method =:= 'GET' orelse + Method =:= 'HEAD' orelse + Method =:= 'DELETE' orelse Method =:= 'OPTIONS' -> + case catch url_decode_q_split(Path) of + {'EXIT', _} -> false; + {NPath, Query} -> + LPath = normalize_path([NPE + || NPE <- str:tokens(path_decode(NPath), <<"/">>)]), + LQuery = case catch parse_urlencoded(Query) of + {'EXIT', _Reason} -> []; + LQ -> LQ + end, + {LPath, LQuery, <<"">>} + end; +extract_path_query(#state{request_method = Method, + request_path = {abs_path, Path}, + request_content_length = Len, + sockmod = _SockMod, + socket = _Socket} = State) + when (Method =:= 'POST' orelse Method =:= 'PUT') andalso + is_integer(Len) -> + Data = recv_data(State, Len), + ?DEBUG("client data: ~p~n", [Data]), + case catch url_decode_q_split(Path) of + {'EXIT', _} -> false; + {NPath, _Query} -> + LPath = normalize_path([NPE + || NPE <- str:tokens(path_decode(NPath), <<"/">>)]), + LQuery = case catch parse_urlencoded(Data) of + {'EXIT', _Reason} -> []; + LQ -> LQ + end, + {LPath, LQuery, Data} + end; +extract_path_query(_State) -> + false. + +process_request(#state{request_method = Method, + request_auth = Auth, + request_lang = Lang, + sockmod = SockMod, + socket = Socket, + options = Options, + request_host = Host, + request_port = Port, + request_tp = TP, + request_headers = RequestHeaders, + request_handlers = RequestHandlers, + trail = Trail} = State) -> + case extract_path_query(State) of + false -> make_bad_request(State); - {NPath, Query} -> - LPath = normalize_path([NPE || NPE <- str:tokens(path_decode(NPath), <<"/">>)]), - LQuery = case (catch parse_urlencoded(Query)) of - {'EXIT', _Reason} -> - []; - LQ -> - LQ - end, + {LPath, LQuery, Data} -> {ok, IPHere} = case SockMod of gen_tcp -> @@ -393,92 +425,36 @@ process_request(#state{request_method = Method, options = Options, end, XFF = proplists:get_value('X-Forwarded-For', RequestHeaders, []), IP = analyze_ip_xff(IPHere, XFF, Host), - Request = #request{method = Method, - path = LPath, - opts = Options, - q = LQuery, - auth = Auth, - lang = Lang, - host = Host, - port = Port, - tp = TP, - headers = RequestHeaders, - ip = IP}, - %% XXX bard: This previously passed control to - %% ejabberd_web:process_get, now passes it to a local - %% procedure (process) that handles dispatching based on - %% URL path prefix. - case process(RequestHandlers, Request) of - El when element(1, El) == xmlel -> - make_xhtml_output(State, 200, [], El); - {Status, Headers, El} when - element(1, El) == xmlel -> - make_xhtml_output(State, Status, Headers, El); - Output when is_list(Output) or is_binary(Output) -> - make_text_output(State, 200, [], Output); - {Status, Headers, Output} when is_list(Output) or is_binary(Output) -> - make_text_output(State, Status, Headers, Output) - end - end; -process_request(#state{request_method = Method, options = Options, - request_path = {abs_path, Path}, request_auth = Auth, - request_content_length = Len, request_lang = Lang, - sockmod = SockMod, socket = Socket, request_host = Host, - request_port = Port, request_tp = TP, - request_headers = RequestHeaders, - request_handlers = RequestHandlers} = - State) - when (Method =:= 'POST' orelse Method =:= 'PUT') andalso - is_integer(Len) -> - {ok, IPHere} = case SockMod of - gen_tcp -> inet:peername(Socket); - _ -> SockMod:peername(Socket) - end, - XFF = proplists:get_value('X-Forwarded-For', - RequestHeaders, []), - IP = analyze_ip_xff(IPHere, XFF, Host), - case SockMod of - gen_tcp -> inet:setopts(Socket, [{packet, 0}]); - _ -> ok - end, - Data = recv_data(State, Len), - ?DEBUG("client data: ~p~n", [Data]), - case (catch url_decode_q_split(Path)) of - {'EXIT', _} -> - make_bad_request(State); - {NPath, _Query} -> - LPath = normalize_path([NPE || NPE <- str:tokens(path_decode(NPath), <<"/">>)]), - LQuery = case (catch parse_urlencoded(Data)) of - {'EXIT', _Reason} -> - []; - LQ -> - LQ - end, - Request = #request{method = Method, - path = LPath, - q = LQuery, + Request = #request{method = Method, + path = LPath, + q = LQuery, + auth = Auth, + data = Data, + lang = Lang, + host = Host, + port = Port, + tp = TP, opts = Options, - auth = Auth, - data = Data, - lang = Lang, - host = Host, - port = Port, - tp = TP, - headers = RequestHeaders, - ip = IP}, - case process(RequestHandlers, Request) of - El when element(1, El) == xmlel -> - make_xhtml_output(State, 200, [], El); - {Status, Headers, El} when - element(1, El) == xmlel -> - make_xhtml_output(State, Status, Headers, El); - Output when is_list(Output) or is_binary(Output) -> - make_text_output(State, 200, [], Output); - {Status, Headers, Output} when is_list(Output) or is_binary(Output) -> - make_text_output(State, Status, Headers, Output) + headers = RequestHeaders, + ip = IP}, + case process(RequestHandlers, Request, Socket, SockMod, Trail) of + El when is_record(El, xmlel) -> + make_xhtml_output(State, 200, [], El); + {Status, Headers, El} + when is_record(El, xmlel) -> + make_xhtml_output(State, Status, Headers, El); + Output when is_binary(Output) or is_list(Output) -> + make_text_output(State, 200, [], Output); + {Status, Headers, Output} + when is_binary(Output) or is_list(Output) -> + make_text_output(State, Status, Headers, Output); + {Status, Reason, Headers, Output} + when is_binary(Output) or is_list(Output) -> + make_text_output(State, Status, Reason, Headers, Output); + _ -> + none end - end; -process_request(State) -> make_bad_request(State). + end. make_bad_request(State) -> %% Support for X-Forwarded-From @@ -833,6 +809,26 @@ old_integer_to_hex(I) when I >= 16 -> N = trunc(I / 16), old_integer_to_hex(N) ++ old_integer_to_hex(I rem 16). +% The following code is mostly taken from yaws_ssl.erl + +toupper(C) when C >= $a andalso C =< $z -> C - 32; +toupper(C) -> C. + +tolower(C) when C >= $A andalso C =< $Z -> C + 32; +tolower(C) -> C. + +normalize_header_name(Name) -> + normalize_header_name(Name, [], true). + +normalize_header_name(<<"">>, Acc, _) -> + iolist_to_binary(Acc); +normalize_header_name(<<"-", Rest/binary>>, Acc, _) -> + normalize_header_name(Rest, [Acc, "-"], true); +normalize_header_name(<<C:8, Rest/binary>>, Acc, true) -> + normalize_header_name(Rest, [Acc, toupper(C)], false); +normalize_header_name(<<C:8, Rest/binary>>, Acc, false) -> + normalize_header_name(Rest, [Acc, tolower(C)], false). + normalize_path(Path) -> normalize_path(Path, []). diff --git a/src/ejabberd_http_poll.erl b/src/ejabberd_http_poll.erl index 9e65045cc..174c78211 100644 --- a/src/ejabberd_http_poll.erl +++ b/src/ejabberd_http_poll.erl @@ -5,7 +5,7 @@ %%% Created : 4 Mar 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_http_ws.erl b/src/ejabberd_http_ws.erl new file mode 100644 index 000000000..e64212b86 --- /dev/null +++ b/src/ejabberd_http_ws.erl @@ -0,0 +1,339 @@ +%%%---------------------------------------------------------------------- +%%% File : ejabberd_websocket.erl +%%% Author : Eric Cestari <ecestari@process-one.net> +%%% Purpose : XMPP Websocket support +%%% Created : 09-10-2010 by Eric Cestari <ecestari@process-one.net> +%%% +%%% +%%% ejabberd, Copyright (C) 2002-2015 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +%%% +%%%---------------------------------------------------------------------- +-module(ejabberd_http_ws). + +-author('ecestari@process-one.net'). + +-behaviour(gen_fsm). + +% External exports +-export([start/1, start_link/1, init/1, handle_event/3, + handle_sync_event/4, code_change/4, handle_info/3, + terminate/3, send_xml/2, setopts/2, sockname/1, peername/1, + controlling_process/2, become_controller/2, close/1, + socket_handoff/6]). + +-include("ejabberd.hrl"). +-include("logger.hrl"). + +-include("jlib.hrl"). + +-include("ejabberd_http.hrl"). + +-define(PING_INTERVAL, 60). +-define(WEBSOCKET_TIMEOUT, 300). + +-record(state, + {socket :: ws_socket(), + ping_interval = ?PING_INTERVAL :: pos_integer(), + ping_timer = make_ref() :: reference(), + pong_expected :: boolean(), + timeout = ?WEBSOCKET_TIMEOUT :: pos_integer(), + timer = make_ref() :: reference(), + input = [] :: list(), + waiting_input = false :: false | pid(), + last_receiver :: pid(), + ws :: {#ws{}, pid()}, + rfc_compilant = undefined :: boolean() | undefined}). + +%-define(DBGFSM, true). + +-ifdef(DBGFSM). + +-define(FSMOPTS, [{debug, [trace]}]). + +-else. + +-define(FSMOPTS, []). + +-endif. + +-type ws_socket() :: {http_ws, pid(), {inet:ip_address(), inet:port_number()}}. +-export_type([ws_socket/0]). + +start(WS) -> + supervisor:start_child(ejabberd_wsloop_sup, [WS]). + +start_link(WS) -> + gen_fsm:start_link(?MODULE, [WS], ?FSMOPTS). + +send_xml({http_ws, FsmRef, _IP}, Packet) -> + gen_fsm:sync_send_all_state_event(FsmRef, + {send_xml, Packet}). + +setopts({http_ws, FsmRef, _IP}, Opts) -> + case lists:member({active, once}, Opts) of + true -> + gen_fsm:send_all_state_event(FsmRef, + {activate, self()}); + _ -> ok + end. + +sockname(_Socket) -> {ok, {{0, 0, 0, 0}, 0}}. + +peername({http_ws, _FsmRef, IP}) -> {ok, IP}. + +controlling_process(_Socket, _Pid) -> ok. + +become_controller(FsmRef, C2SPid) -> + gen_fsm:send_all_state_event(FsmRef, + {become_controller, C2SPid}). + +close({http_ws, FsmRef, _IP}) -> + catch gen_fsm:sync_send_all_state_event(FsmRef, close). + +socket_handoff(LocalPath, Request, Socket, SockMod, Buf, Opts) -> + ejabberd_websocket:socket_handoff(LocalPath, Request, Socket, SockMod, + Buf, Opts, ?MODULE, fun get_human_html_xmlel/0). + +%%% Internal + +init([{#ws{ip = IP}, _} = WS]) -> + Opts = [{xml_socket, true} | ejabberd_c2s_config:get_c2s_limits()], + PingInterval = ejabberd_config:get_option( + {websocket_ping_interval, ?MYNAME}, + fun(I) when is_integer(I), I>=0 -> I end, + ?PING_INTERVAL) * 1000, + WSTimeout = ejabberd_config:get_option( + {websocket_timeout, ?MYNAME}, + fun(I) when is_integer(I), I>0 -> I end, + ?WEBSOCKET_TIMEOUT) * 1000, + Socket = {http_ws, self(), IP}, + ?DEBUG("Client connected through websocket ~p", + [Socket]), + ejabberd_socket:start(ejabberd_c2s, ?MODULE, Socket, + Opts), + Timer = erlang:start_timer(WSTimeout, self(), []), + {ok, loop, + #state{socket = Socket, timeout = WSTimeout, + timer = Timer, ws = WS, + ping_interval = PingInterval}}. + +handle_event({activate, From}, StateName, StateData) -> + case StateData#state.input of + [] -> + {next_state, StateName, + StateData#state{waiting_input = From}}; + Input -> + Receiver = From, + Receiver ! {tcp, StateData#state.socket, Input}, + {next_state, StateName, + StateData#state{input = [], waiting_input = false, + last_receiver = Receiver}} + end. + +handle_sync_event({send_xml, Packet}, _From, StateName, + #state{ws = {_, WsPid}, rfc_compilant = R} = StateData) -> + Packet2 = case {case R of undefined -> true; V -> V end, Packet} of + {true, {xmlstreamstart, _, Attrs}} -> + Attrs2 = [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-framing">>} | + lists:keydelete(<<"xmlns">>, 1, lists:keydelete(<<"xmlns:stream">>, 1, Attrs))], + {xmlstreamelement, #xmlel{name = <<"open">>, attrs = Attrs2}}; + {true, {xmlstreamend, _}} -> + {xmlstreamelement, #xmlel{name = <<"close">>, + attrs = [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-framing">>}]}}; + {true, {xmlstreamraw, <<"\r\n\r\n">>}} -> % cdata ping + skip; + {true, {xmlstreamelement, #xmlel{name=Name2} = El2}} -> + El3 = case Name2 of + <<"stream:", _/binary>> -> + xml:replace_tag_attr(<<"xmlns:stream">>, ?NS_STREAM, El2); + _ -> + case xml:get_tag_attr_s(<<"xmlns">>, El2) of + <<"">> -> + xml:replace_tag_attr(<<"xmlns">>, <<"jabber:client">>, El2); + _ -> + El2 + end + end, + {xmlstreamelement , El3}; + _ -> + Packet + end, + case Packet2 of + {xmlstreamstart, Name, Attrs3} -> + B = xml:element_to_binary(#xmlel{name = Name, attrs = Attrs3}), + WsPid ! {send, <<(binary:part(B, 0, byte_size(B)-2))/binary, ">">>}; + {xmlstreamend, Name} -> + WsPid ! {send, <<"</", Name/binary, ">">>}; + {xmlstreamelement, El} -> + WsPid ! {send, xml:element_to_binary(El)}; + {xmlstreamraw, Bin} -> + WsPid ! {send, Bin}; + {xmlstreamcdata, Bin2} -> + WsPid ! {send, Bin2}; + skip -> + ok + end, + {reply, ok, StateName, StateData}; +handle_sync_event(close, _From, _StateName, StateData) -> + {stop, normal, StateData}. + +handle_info(closed, _StateName, StateData) -> + {stop, normal, StateData}; +handle_info({received, Packet}, StateName, StateDataI) -> + {StateData, Parsed} = parse(StateDataI, Packet), + SD = case StateData#state.waiting_input of + false -> + Input = StateData#state.input ++ Parsed, + StateData#state{input = Input}; + Receiver -> + Receiver ! {tcp, StateData#state.socket, Parsed}, + setup_timers(StateData#state{waiting_input = false, + last_receiver = Receiver}) + end, + {next_state, StateName, SD}; +handle_info(PingPong, StateName, StateData) when PingPong == ping orelse + PingPong == pong -> + StateData2 = setup_timers(StateData), + {next_state, StateName, + StateData2#state{pong_expected = false}}; +handle_info({timeout, Timer, _}, _StateName, + #state{timer = Timer} = StateData) -> + {stop, normal, StateData}; +handle_info({timeout, Timer, _}, StateName, + #state{ping_timer = Timer, ws = {_, WsPid}} = StateData) -> + case StateData#state.pong_expected of + false -> + cancel_timer(StateData#state.ping_timer), + PingTimer = erlang:start_timer(StateData#state.ping_interval, + self(), []), + WsPid ! {ping, <<>>}, + {next_state, StateName, + StateData#state{ping_timer = PingTimer, pong_expected = true}}; + true -> + {stop, normal, StateData} + end; +handle_info(_, StateName, StateData) -> + {next_state, StateName, StateData}. + +code_change(_OldVsn, StateName, StateData, _Extra) -> + {ok, StateName, StateData}. + +terminate(_Reason, _StateName, StateData) -> + case StateData#state.waiting_input of + false -> ok; + Receiver -> + ?DEBUG("C2S Pid : ~p", [Receiver]), + Receiver ! {tcp_closed, StateData#state.socket} + end, + ok. + +setup_timers(StateData) -> + cancel_timer(StateData#state.timer), + Timer = erlang:start_timer(StateData#state.timeout, + self(), []), + cancel_timer(StateData#state.ping_timer), + PingTimer = case {StateData#state.ping_interval, StateData#state.rfc_compilant} of + {0, _} -> StateData#state.ping_timer; + {_, false} -> StateData#state.ping_timer; + {V, _} -> erlang:start_timer(V, self(), []) + end, + StateData#state{timer = Timer, ping_timer = PingTimer, + pong_expected = false}. + +cancel_timer(Timer) -> + erlang:cancel_timer(Timer), + receive {timeout, Timer, _} -> ok after 0 -> ok end. + +get_human_html_xmlel() -> + Heading = <<"ejabberd ", (jlib:atom_to_binary(?MODULE))/binary>>, + #xmlel{name = <<"html">>, + attrs = + [{<<"xmlns">>, <<"http://www.w3.org/1999/xhtml">>}], + children = + [#xmlel{name = <<"head">>, attrs = [], + children = + [#xmlel{name = <<"title">>, attrs = [], + children = [{xmlcdata, Heading}]}]}, + #xmlel{name = <<"body">>, attrs = [], + children = + [#xmlel{name = <<"h1">>, attrs = [], + children = [{xmlcdata, Heading}]}, + #xmlel{name = <<"p">>, attrs = [], + children = + [{xmlcdata, <<"An implementation of ">>}, + #xmlel{name = <<"a">>, + attrs = + [{<<"href">>, + <<"http://tools.ietf.org/html/rfc6455">>}], + children = + [{xmlcdata, + <<"WebSocket protocol">>}]}]}, + #xmlel{name = <<"p">>, attrs = [], + children = + [{xmlcdata, + <<"This web page is only informative. To " + "use WebSocket connection you need a Jabber/XMPP " + "client that supports it.">>}]}]}]}. + + +parse(#state{rfc_compilant = C} = State, Data) -> + case C of + undefined -> + P = xml_stream:new(self()), + P2 = xml_stream:parse(P, Data), + xml_stream:close(P2), + case parsed_items([]) of + error -> + {State#state{rfc_compilant = true}, <<"parse error">>}; + [] -> + {State#state{rfc_compilant = true}, <<"parse error">>}; + [{xmlstreamstart, <<"open">>, _} | _] -> + parse(State#state{rfc_compilant = true}, Data); + _ -> + parse(State#state{rfc_compilant = false}, Data) + end; + true -> + El = xml_stream:parse_element(Data), + case El of + #xmlel{name = <<"open">>, attrs = Attrs} -> + Attrs2 = [{<<"xmlns:stream">>, ?NS_STREAM}, {<<"xmlns">>, <<"jabber:client">>} | + lists:keydelete(<<"xmlns">>, 1, lists:keydelete(<<"xmlns:stream">>, 1, Attrs))], + {State, [{xmlstreamstart, <<"stream:stream">>, Attrs2}]}; + #xmlel{name = <<"close">>} -> + {State, [{xmlstreamend, <<"stream:stream">>}]}; + {error, _} -> + {State, <<"parse error">>}; + _ -> + {State, [El]} + end; + false -> + {State, Data} + end. + +parsed_items(List) -> + receive + {'$gen_event', El} + when element(1, El) == xmlel; + element(1, El) == xmlstreamstart; + element(1, El) == xmlstreamelement; + element(1, El) == xmlstreamend -> + parsed_items([El | List]); + {'$gen_event', {xmlstreamerror, _}} -> + error + after 0 -> + lists:reverse(List) + end. diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl index 515cf7348..7db5ab826 100644 --- a/src/ejabberd_listener.erl +++ b/src/ejabberd_listener.erl @@ -5,7 +5,7 @@ %%% Created : 16 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl index fd9ef1ca9..cec39ced2 100644 --- a/src/ejabberd_local.erl +++ b/src/ejabberd_local.erl @@ -5,7 +5,7 @@ %%% Created : 30 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_logger.erl b/src/ejabberd_logger.erl index 65899c8f6..59beca16d 100644 --- a/src/ejabberd_logger.erl +++ b/src/ejabberd_logger.erl @@ -6,7 +6,7 @@ %%% @end %%% Created : 12 May 2013 by Evgeniy Khramtsov <ekhramtsov@process-one.net> %%% -%%% ejabberd, Copyright (C) 2013 ProcessOne +%%% ejabberd, Copyright (C) 2013-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -61,9 +61,9 @@ get_log_path() -> -ifdef(LAGER). -get_pos_integer_env(Name, Default) -> +get_integer_env(Name, Default) -> case application:get_env(ejabberd, Name) of - {ok, I} when is_integer(I), I>0 -> + {ok, I} when is_integer(I), I>=0 -> I; undefined -> Default; @@ -73,7 +73,7 @@ get_pos_integer_env(Name, Default) -> [Name, Junk, Default]), Default end. -get_pos_string_env(Name, Default) -> +get_string_env(Name, Default) -> case application:get_env(ejabberd, Name) of {ok, L} when is_list(L) -> L; @@ -94,10 +94,10 @@ start() -> Dir = filename:dirname(ConsoleLog), ErrorLog = filename:join([Dir, "error.log"]), CrashLog = filename:join([Dir, "crash.log"]), - LogRotateDate = get_pos_string_env(log_rotate_date, ""), - LogRotateSize = get_pos_integer_env(log_rotate_size, 10*1024*1024), - LogRotateCount = get_pos_integer_env(log_rotate_count, 1), - LogRateLimit = get_pos_integer_env(log_rate_limit, 100), + LogRotateDate = get_string_env(log_rotate_date, ""), + LogRotateSize = get_integer_env(log_rotate_size, 10*1024*1024), + LogRotateCount = get_integer_env(log_rotate_count, 1), + LogRateLimit = get_integer_env(log_rate_limit, 100), application:set_env(lager, error_logger_hwm, LogRateLimit), application:set_env( lager, handlers, diff --git a/src/ejabberd_node_groups.erl b/src/ejabberd_node_groups.erl index ae1db531f..da0bffe99 100644 --- a/src/ejabberd_node_groups.erl +++ b/src/ejabberd_node_groups.erl @@ -5,7 +5,7 @@ %%% Created : 1 Nov 2006 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_odbc.erl b/src/ejabberd_odbc.erl index 78be623d4..5828912d5 100644 --- a/src/ejabberd_odbc.erl +++ b/src/ejabberd_odbc.erl @@ -5,7 +5,7 @@ %%% Created : 8 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -62,7 +62,7 @@ start_interval = 0 :: non_neg_integer(), host = <<"">> :: binary(), max_pending_requests_len :: non_neg_integer(), - pending_requests = {0, queue:new()} :: {non_neg_integer(), queue()}}). + pending_requests = {0, queue:new()} :: {non_neg_integer(), ?TQUEUE}}). -define(STATE_KEY, ejabberd_odbc_state). diff --git a/src/ejabberd_odbc_sup.erl b/src/ejabberd_odbc_sup.erl index d05fd139e..602e7e03b 100644 --- a/src/ejabberd_odbc_sup.erl +++ b/src/ejabberd_odbc_sup.erl @@ -5,7 +5,7 @@ %%% Created : 22 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl index d4a06de9c..9a9659270 100644 --- a/src/ejabberd_piefxis.erl +++ b/src/ejabberd_piefxis.erl @@ -9,7 +9,7 @@ %%% @doc %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_rdbms.erl b/src/ejabberd_rdbms.erl index 7c2b5e9ce..e71728da5 100644 --- a/src/ejabberd_rdbms.erl +++ b/src/ejabberd_rdbms.erl @@ -5,7 +5,7 @@ %%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl index 86cd3e8f9..819e6d898 100644 --- a/src/ejabberd_receiver.erl +++ b/src/ejabberd_receiver.erl @@ -5,7 +5,7 @@ %%% Created : 10 Nov 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_regexp.erl b/src/ejabberd_regexp.erl index dff8bee1b..86ebd1846 100644 --- a/src/ejabberd_regexp.erl +++ b/src/ejabberd_regexp.erl @@ -5,7 +5,7 @@ %%% Created : 8 Dec 2011 by Badlop %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_riak.erl b/src/ejabberd_riak.erl index d80a77d3e..c8084674f 100644 --- a/src/ejabberd_riak.erl +++ b/src/ejabberd_riak.erl @@ -4,7 +4,7 @@ %%% Interface for Riak database %%% @end %%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net> -%%% @copyright (C) 2002-2014 ProcessOne +%%% @copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -16,10 +16,9 @@ %%% 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 +%%% 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. %%% %%%------------------------------------------------------------------- -module(ejabberd_riak). diff --git a/src/ejabberd_riak_sup.erl b/src/ejabberd_riak_sup.erl index 513ad785f..871af5a06 100644 --- a/src/ejabberd_riak_sup.erl +++ b/src/ejabberd_riak_sup.erl @@ -5,7 +5,7 @@ %%% Created : 29 Dec 2011 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2011 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -17,10 +17,9 @@ %%% 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 +%%% 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. %%% %%%---------------------------------------------------------------------- diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index 70a01ee4e..76ef71dc4 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -5,7 +5,7 @@ %%% Created : 27 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index eb9894350..a7b3234fd 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -5,7 +5,7 @@ %%% Created : 7 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 6c594185a..1b40f03c2 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -5,7 +5,7 @@ %%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -58,7 +58,7 @@ server = <<"">> :: binary(), authenticated = false :: boolean(), auth_domain = <<"">> :: binary(), - connections = (?DICT):new() :: dict(), + connections = (?DICT):new() :: ?TDICT, timer = make_ref() :: reference()}). %-define(DBGFSM, true). diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 052729314..97164326d 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -5,7 +5,7 @@ %%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -77,7 +77,7 @@ try_auth = true :: boolean(), myname = <<"">> :: binary(), server = <<"">> :: binary(), - queue = queue:new() :: queue(), + queue = queue:new() :: ?TQUEUE, delay_to_retry = undefined_delay :: undefined_delay | non_neg_integer(), new = false :: false | binary(), verify = false :: false | {pid(), binary(), binary()}, diff --git a/src/ejabberd_service.erl b/src/ejabberd_service.erl index 04b29d380..1fbc18ff2 100644 --- a/src/ejabberd_service.erl +++ b/src/ejabberd_service.erl @@ -5,7 +5,7 @@ %%% Created : 6 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 12f2a7708..b3a46ba2d 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -5,7 +5,7 @@ %%% Created : 24 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -604,7 +604,7 @@ do_route(From, To, #xmlel{} = Packet) -> ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) end; - _ -> ?DEBUG("packet droped~n", []) + _ -> ?DEBUG("packet dropped~n", []) end; Ss -> Session = lists:max(Ss), diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl index 165c53f23..c74ef9aec 100644 --- a/src/ejabberd_socket.erl +++ b/src/ejabberd_socket.erl @@ -5,7 +5,7 @@ %%% Created : 23 Aug 2006 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_stun.erl b/src/ejabberd_stun.erl index 89cbebf84..11347d604 100644 --- a/src/ejabberd_stun.erl +++ b/src/ejabberd_stun.erl @@ -5,6 +5,23 @@ %%% %%% @end %%% Created : 8 May 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% +%%% ejabberd, Copyright (C) 2013-2015 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + %%%------------------------------------------------------------------- -module(ejabberd_stun). diff --git a/src/ejabberd_sup.erl b/src/ejabberd_sup.erl index c89a068b7..35c79f429 100644 --- a/src/ejabberd_sup.erl +++ b/src/ejabberd_sup.erl @@ -5,7 +5,7 @@ %%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl index 368c5a0ff..df8d9d51a 100644 --- a/src/ejabberd_system_monitor.erl +++ b/src/ejabberd_system_monitor.erl @@ -5,7 +5,7 @@ %%% Created : 21 Mar 2007 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_tmp_sup.erl b/src/ejabberd_tmp_sup.erl index 9bc2046a9..5852e666d 100644 --- a/src/ejabberd_tmp_sup.erl +++ b/src/ejabberd_tmp_sup.erl @@ -5,7 +5,7 @@ %%% Created : 18 Jul 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -36,4 +36,4 @@ init(Module) -> {ok, {{simple_one_for_one, 10, 1}, [{undefined, {Module, start_link, []}, temporary, - brutal_kill, worker, [Module]}]}}. + 1000, worker, [Module]}]}}. diff --git a/src/ejabberd_update.erl b/src/ejabberd_update.erl index 17db47fb1..5b6795c4b 100644 --- a/src/ejabberd_update.erl +++ b/src/ejabberd_update.erl @@ -5,7 +5,7 @@ %%% Created : 27 Jan 2006 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_web.erl b/src/ejabberd_web.erl index 43119fead..61cd079ab 100644 --- a/src/ejabberd_web.erl +++ b/src/ejabberd_web.erl @@ -6,7 +6,7 @@ %%% Created : 28 Feb 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl index 56172fa16..b6e7a9024 100644 --- a/src/ejabberd_web_admin.erl +++ b/src/ejabberd_web_admin.erl @@ -5,7 +5,7 @@ %%% Created : 9 Apr 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -340,7 +340,7 @@ make_xhtml(Els, Host, Node, Lang, JID) -> ?XAE(<<"div">>, [{<<"id">>, <<"copyrightouter">>}], [?XAE(<<"div">>, [{<<"id">>, <<"copyright">>}], [?XC(<<"p">>, - <<"ejabberd (c) 2002-2014 ProcessOne">>)])])])]}}. + <<"ejabberd (c) 2002-2015 ProcessOne">>)])])])]}}. get_base_path(global, cluster) -> <<"/admin/">>; get_base_path(Host, cluster) -> diff --git a/src/ejabberd_websocket.erl b/src/ejabberd_websocket.erl new file mode 100644 index 000000000..8cd1b2289 --- /dev/null +++ b/src/ejabberd_websocket.erl @@ -0,0 +1,403 @@ +%%%---------------------------------------------------------------------- +%%% File : ejabberd_websocket.erl +%%% Author : Eric Cestari <ecestari@process-one.net> +%%% Purpose : XMPP Websocket support +%%% Created : 09-10-2010 by Eric Cestari <ecestari@process-one.net> +%%% +%%% Some code lifted from MISULTIN - WebSocket misultin_websocket.erl - >-|-|-(°> +%%% (http://github.com/ostinelli/misultin/blob/master/src/misultin_websocket.erl) +%%% Copyright (C) 2010, Roberto Ostinelli <roberto@ostinelli.net>, Joe Armstrong. +%%% All rights reserved. +%%% +%%% Code portions from Joe Armstrong have been originally taken under MIT license at the address: +%%% <http://armstrongonsoftware.blogspot.com/2009/12/comet-is-dead-long-live-websockets.html> +%%% +%%% BSD License +%%% +%%% Redistribution and use in source and binary forms, with or without modification, are permitted provided +%%% that the following conditions are met: +%%% +%%% * Redistributions of source code must retain the above copyright notice, this list of conditions and the +%%% following disclaimer. +%%% * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and +%%% the following disclaimer in the documentation and/or other materials provided with the distribution. +%%% * Neither the name of the authors nor the names of its contributors may be used to endorse or promote +%%% products derived from this software without specific prior written permission. +%%% +%%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +%%% WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +%%% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +%%% ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +%%% TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +%%% HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +%%% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +%%% POSSIBILITY OF SUCH DAMAGE. +%%% ========================================================================================================== +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne +%%%---------------------------------------------------------------------- + +-module(ejabberd_websocket). + +-author('ecestari@process-one.net'). + +-export([check/2, socket_handoff/8]). + +-include("ejabberd.hrl"). +-include("logger.hrl"). + +-include("jlib.hrl"). + +-include("ejabberd_http.hrl"). + +-define(CT_XML, {<<"Content-Type">>, <<"text/xml; charset=utf-8">>}). +-define(CT_PLAIN, {<<"Content-Type">>, <<"text/plain">>}). + +-define(AC_ALLOW_ORIGIN, {<<"Access-Control-Allow-Origin">>, <<"*">>}). +-define(AC_ALLOW_METHODS, {<<"Access-Control-Allow-Methods">>, <<"GET, OPTIONS">>}). +-define(AC_ALLOW_HEADERS, {<<"Access-Control-Allow-Headers">>, <<"Content-Type">>}). +-define(AC_MAX_AGE, {<<"Access-Control-Max-Age">>, <<"86400">>}). + +-define(OPTIONS_HEADER, [?CT_PLAIN, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_METHODS, + ?AC_ALLOW_HEADERS, ?AC_MAX_AGE]). +-define(HEADER, [?CT_XML, ?AC_ALLOW_ORIGIN, ?AC_ALLOW_HEADERS]). + +check(_Path, Headers) -> + RequiredHeaders = [{'Upgrade', <<"websocket">>}, + {'Connection', ignore}, {'Host', ignore}, + {<<"Sec-Websocket-Key">>, ignore}, + {<<"Sec-Websocket-Version">>, <<"13">>}], + + F = fun ({Tag, Val}) -> + case lists:keyfind(Tag, 1, Headers) of + false -> true; % header not found, keep in list + {_, HVal} -> + case Val of + ignore -> false; % ignore value -> ok, remove from list + HVal -> false; % expected val -> ok, remove from list + _ -> + true % val is different, keep in list + end + end + end, + case lists:filter(F, RequiredHeaders) of + [] -> true; + _MissingHeaders -> false + end. + +socket_handoff(LocalPath, #request{method = 'GET', ip = IP, q = Q, path = Path, + headers = Headers, host = Host, port = Port}, + Socket, SockMod, Buf, _Opts, HandlerModule, InfoMsgFun) -> + case check(LocalPath, Headers) of + true -> + WS = #ws{socket = Socket, + sockmod = SockMod, + ip = IP, + q = Q, + host = Host, + port = Port, + path = Path, + headers = Headers, + local_path = LocalPath, + buf = Buf}, + + connect(WS, HandlerModule); + _ -> + {200, ?HEADER, InfoMsgFun()} + end; +socket_handoff(_, #request{method = 'OPTIONS'}, _, _, _, _, _, _) -> + {200, ?OPTIONS_HEADER, []}; +socket_handoff(_, #request{method = 'HEAD'}, _, _, _, _, _, _) -> + {200, ?HEADER, []}; +socket_handoff(_, _, _, _, _, _, _, _) -> + {400, ?HEADER, #xmlel{name = <<"h1">>, + children = [{xmlcdata, <<"400 Bad Request">>}]}}. + +connect(#ws{socket = Socket, sockmod = SockMod} = Ws, WsLoop) -> + {NewWs, HandshakeResponse} = handshake(Ws), + SockMod:send(Socket, HandshakeResponse), + + ?DEBUG("Sent handshake response : ~p", + [HandshakeResponse]), + Ws0 = {Ws, self()}, + {ok, WsHandleLoopPid} = WsLoop:start_link(Ws0), + erlang:monitor(process, WsHandleLoopPid), + + case NewWs#ws.buf of + <<>> -> + ok; + Data -> + self() ! {raw, Socket, Data} + end, + + % set opts + case SockMod of + gen_tcp -> + inet:setopts(Socket, [{packet, 0}, {active, true}]); + _ -> + SockMod:setopts(Socket, [{packet, 0}, {active, true}]) + end, + ws_loop(none, Socket, WsHandleLoopPid, SockMod). + +handshake(#ws{headers = Headers} = State) -> + {_, Key} = lists:keyfind(<<"Sec-Websocket-Key">>, 1, + Headers), + SubProtocolHeader = case find_subprotocol(Headers) of + false -> + []; + V -> + [<<"Sec-Websocket-Protocol:">>, V, <<"\r\n">>] + end, + Hash = jlib:encode_base64( + p1_sha:sha1(<<Key/binary, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11">>)), + {State, [<<"HTTP/1.1 101 Switching Protocols\r\n">>, + <<"Upgrade: websocket\r\n">>, + <<"Connection: Upgrade\r\n">>, + SubProtocolHeader, + <<"Sec-WebSocket-Accept: ">>, Hash, <<"\r\n\r\n">>]}. + +find_subprotocol(Headers) -> + case lists:keysearch(<<"Sec-Websocket-Protocol">>, 1, Headers) of + false -> + case lists:keysearch(<<"Websocket-Protocol">>, 1, Headers) of + false -> + false; + {value, {_, Protocol2}} -> + Protocol2 + end; + {value, {_, Protocol}} -> + Protocol + end. + + +ws_loop(FrameInfo, Socket, WsHandleLoopPid, SocketMode) -> + receive + {DataType, _Socket, Data} when DataType =:= tcp orelse DataType =:= raw -> + case handle_data(DataType, FrameInfo, Data, Socket, WsHandleLoopPid, SocketMode) of + {error, Error} -> + ?DEBUG("tls decode error ~p", [Error]), + websocket_close(Socket, WsHandleLoopPid, SocketMode, 1002); % protocol error + {NewFrameInfo, ToSend} -> + lists:foreach(fun(Pkt) -> SocketMode:send(Socket, Pkt) + end, ToSend), + ws_loop(NewFrameInfo, Socket, WsHandleLoopPid, SocketMode) + end; + {tcp_closed, _Socket} -> + ?DEBUG("tcp connection was closed, exit", []), + websocket_close(Socket, WsHandleLoopPid, SocketMode, 0); + {'DOWN', Ref, process, WsHandleLoopPid, Reason} -> + Code = case Reason of + normal -> + 1000; % normal close + _ -> + ?ERROR_MSG("linked websocket controlling loop crashed " + "with reason: ~p", + [Reason]), + 1011 % internal error + end, + erlang:demonitor(Ref), + websocket_close(Socket, WsHandleLoopPid, SocketMode, Code); + {send, Data} -> + SocketMode:send(Socket, encode_frame(Data, 1)), + ws_loop(FrameInfo, Socket, WsHandleLoopPid, + SocketMode); + {ping, Data} -> + SocketMode:send(Socket, encode_frame(Data, 9)), + ws_loop(FrameInfo, Socket, WsHandleLoopPid, + SocketMode); + shutdown -> + ?DEBUG("shutdown request received, closing websocket " + "with pid ~p", + [self()]), + websocket_close(Socket, WsHandleLoopPid, SocketMode, 1001); % going away + _Ignored -> + ?WARNING_MSG("received unexpected message, ignoring: ~p", + [_Ignored]), + ws_loop(FrameInfo, Socket, WsHandleLoopPid, + SocketMode) + end. + +encode_frame(Data, Opcode) -> + case byte_size(Data) of + S1 when S1 < 126 -> + <<1:1, 0:3, Opcode:4, 0:1, S1:7, Data/binary>>; + S2 when S2 < 65536 -> + <<1:1, 0:3, Opcode:4, 0:1, 126:7, S2:16, Data/binary>>; + S3 -> + <<1:1, 0:3, Opcode:4, 0:1, 127:7, S3:64, Data/binary>> + end. + +-record(frame_info, + {mask = none, offset = 0, left, final_frame = true, + opcode, unprocessed = <<>>, unmasked = <<>>, + unmasked_msg = <<>>}). + +decode_header(<<Final:1, _:3, Opcode:4, 0:1, + Len:7, Data/binary>>) + when Len < 126 -> + {Len, Final, Opcode, none, Data}; +decode_header(<<Final:1, _:3, Opcode:4, 0:1, + 126:7, Len:16/integer, Data/binary>>) -> + {Len, Final, Opcode, none, Data}; +decode_header(<<Final:1, _:3, Opcode:4, 0:1, + 127:7, Len:64/integer, Data/binary>>) -> + {Len, Final, Opcode, none, Data}; +decode_header(<<Final:1, _:3, Opcode:4, 1:1, + Len:7, Mask:4/binary, Data/binary>>) + when Len < 126 -> + {Len, Final, Opcode, Mask, Data}; +decode_header(<<Final:1, _:3, Opcode:4, 1:1, + 126:7, Len:16/integer, Mask:4/binary, Data/binary>>) -> + {Len, Final, Opcode, Mask, Data}; +decode_header(<<Final:1, _:3, Opcode:4, 1:1, + 127:7, Len:64/integer, Mask:4/binary, Data/binary>>) -> + {Len, Final, Opcode, Mask, Data}; +decode_header(_) -> none. + +unmask_int(Offset, _, <<>>, Acc) -> + {Acc, Offset}; +unmask_int(0, <<M:32>> = Mask, + <<N:32, Rest/binary>>, Acc) -> + unmask_int(0, Mask, Rest, + <<Acc/binary, (M bxor N):32>>); +unmask_int(0, <<M:8, _/binary>> = Mask, + <<N:8, Rest/binary>>, Acc) -> + unmask_int(1, Mask, Rest, + <<Acc/binary, (M bxor N):8>>); +unmask_int(1, <<_:8, M:8, _/binary>> = Mask, + <<N:8, Rest/binary>>, Acc) -> + unmask_int(2, Mask, Rest, + <<Acc/binary, (M bxor N):8>>); +unmask_int(2, <<_:16, M:8, _/binary>> = Mask, + <<N:8, Rest/binary>>, Acc) -> + unmask_int(3, Mask, Rest, + <<Acc/binary, (M bxor N):8>>); +unmask_int(3, <<_:24, M:8>> = Mask, + <<N:8, Rest/binary>>, Acc) -> + unmask_int(0, Mask, Rest, + <<Acc/binary, (M bxor N):8>>). + +unmask(#frame_info{mask = none} = State, Data) -> + {State, Data}; +unmask(#frame_info{mask = Mask, offset = Offset} = State, Data) -> + {Unmasked, NewOffset} = unmask_int(Offset, Mask, + Data, <<>>), + {State#frame_info{offset = NewOffset}, Unmasked}. + +process_frame(none, Data) -> + process_frame(#frame_info{}, Data); +process_frame(#frame_info{left = Left} = FrameInfo, <<>>) when Left > 0 -> + {FrameInfo, [], []}; +process_frame(#frame_info{unprocessed = none, + unmasked = UnmaskedPre, left = Left} = + State, + Data) + when byte_size(Data) < Left -> + {State2, Unmasked} = unmask(State, Data), + {State2#frame_info{left = Left - byte_size(Data), + unmasked = [UnmaskedPre, Unmasked]}, + [], []}; +process_frame(#frame_info{unprocessed = none, + unmasked = UnmaskedPre, opcode = Opcode, + final_frame = Final, left = Left, + unmasked_msg = UnmaskedMsg} = + FrameInfo, + Data) -> + <<ToProcess:(Left)/binary, Unprocessed/binary>> = Data, + {_, Unmasked} = unmask(FrameInfo, ToProcess), + case Final of + true -> + {FrameInfo3, Recv, Send} = process_frame(#frame_info{}, + Unprocessed), + case Opcode of + X when X < 3 -> + {FrameInfo3, + [iolist_to_binary([UnmaskedMsg, UnmaskedPre, Unmasked]) + | Recv], + Send}; + 9 -> % Ping + Frame = encode_frame(Unprocessed, 10), + {FrameInfo3#frame_info{unmasked_msg = UnmaskedMsg}, [ping | Recv], + [Frame | Send]}; + 10 -> % Pong + {FrameInfo3, [pong | Recv], Send}; + 8 -> % Close + CloseCode = case Unmasked of + <<Code:16/integer-big, Message/binary>> -> + ?DEBUG("WebSocket close op: ~p ~s", + [Code, Message]), + Code; + <<Code:16/integer-big>> -> + ?DEBUG("WebSocket close op: ~p", [Code]), + Code; + _ -> + ?DEBUG("WebSocket close op unknown: ~p", + [Unmasked]), + 1000 + end, + + Frame = encode_frame(<<CloseCode:16/integer-big>>, 8), + {FrameInfo3#frame_info{unmasked_msg=UnmaskedMsg}, Recv, + [Frame | Send]}; + _ -> + {FrameInfo3#frame_info{unmasked_msg = UnmaskedMsg}, Recv, + Send} + end; + _ -> + process_frame(#frame_info{unmasked_msg = + [UnmaskedMsg, UnmaskedPre, + Unmasked]}, + Unprocessed) + end; +process_frame(#frame_info{unprocessed = <<>>} = + FrameInfo, + Data) -> + case decode_header(Data) of + none -> + {FrameInfo#frame_info{unprocessed = Data}, [], []}; + {Len, Final, Opcode, Mask, Rest} -> + process_frame(FrameInfo#frame_info{mask = Mask, + final_frame = Final == 1, + left = Len, opcode = Opcode, + unprocessed = none}, + Rest) + end; +process_frame(#frame_info{unprocessed = + UnprocessedPre} = + FrameInfo, + Data) -> + process_frame(FrameInfo#frame_info{unprocessed = <<>>}, + <<UnprocessedPre/binary, Data/binary>>). + +handle_data(tcp, FrameInfo, Data, Socket, WsHandleLoopPid, p1_tls) -> + case p1_tls:recv_data(Socket, Data) of + {ok, NewData} -> + handle_data_int(FrameInfo, NewData, Socket, WsHandleLoopPid, p1_tls); + {error, Error} -> + {error, Error} + end; +handle_data(_, FrameInfo, Data, Socket, WsHandleLoopPid, SockMod) -> + handle_data_int(FrameInfo, Data, Socket, WsHandleLoopPid, SockMod). + +handle_data_int(FrameInfo, Data, _Socket, WsHandleLoopPid, _SocketMode) -> + {NewFrameInfo, Recv, Send} = process_frame(FrameInfo, Data), + lists:foreach(fun (El) -> + case El of + pong -> + WsHandleLoopPid ! pong; + ping -> + WsHandleLoopPid ! ping; + _ -> + WsHandleLoopPid ! {received, El} + end + end, + Recv), + {NewFrameInfo, Send}. + +websocket_close(Socket, WsHandleLoopPid, + SocketMode, CloseCode) when CloseCode > 0 -> + Frame = encode_frame(<<CloseCode:16/integer-big>>, 8), + SocketMode:send(Socket, Frame), + websocket_close(Socket, WsHandleLoopPid, SocketMode, 0); +websocket_close(Socket, WsHandleLoopPid, SocketMode, _CloseCode) -> + WsHandleLoopPid ! closed, + SocketMode:close(Socket). diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl index b59001819..b1bd164a6 100644 --- a/src/ejabberd_xmlrpc.erl +++ b/src/ejabberd_xmlrpc.erl @@ -360,23 +360,17 @@ build_fault_response(Code, ParseString, ParseArgs) -> FaultString = "Error " ++ integer_to_list(Code) ++ "\n" ++ lists:flatten(io_lib:format(ParseString, ParseArgs)), ?WARNING_MSG(FaultString, []), - {false, {response, {fault, Code, FaultString}}}. + {false, {response, {fault, Code, list_to_binary(FaultString)}}}. do_command(AccessCommands, Auth, Command, AttrL, ArgsF, ResultF) -> ArgsFormatted = format_args(AttrL, ArgsF), - AuthBin = convert_auth(Auth), Result = - ejabberd_commands:execute_command(AccessCommands, AuthBin, + ejabberd_commands:execute_command(AccessCommands, Auth, Command, ArgsFormatted), ResultFormatted = format_result(Result, ResultF), {command_result, ResultFormatted}. -convert_auth(noauth) -> - noauth; -convert_auth({UserT, ServerT, PasswordT}) -> - {list_to_binary(UserT), list_to_binary(ServerT), list_to_binary(PasswordT)}. - %%----------------------------- %% Format arguments %%----------------------------- diff --git a/src/ejd2odbc.erl b/src/ejd2odbc.erl index a5c10560d..907814813 100644 --- a/src/ejd2odbc.erl +++ b/src/ejd2odbc.erl @@ -5,7 +5,7 @@ %%% Created : 22 Aug 2005 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/eldap.erl b/src/eldap.erl index 0f1a1a445..5e084b01b 100644 --- a/src/eldap.erl +++ b/src/eldap.erl @@ -139,8 +139,8 @@ passwd = <<"">> :: binary(), id = 0 :: non_neg_integer(), bind_timer = make_ref() :: reference(), - dict = dict:new() :: dict(), - req_q = queue:new() :: queue()}). + dict = dict:new() :: ?TDICT, + req_q = queue:new() :: ?TQUEUE}). %%%---------------------------------------------------------------------- %%% API @@ -828,7 +828,7 @@ send_command(Command, From, S) -> Message = #'LDAPMessage'{messageID = Id, protocolOp = {Name, Request}}, ?DEBUG("~p~n", [{Name, Request}]), - {ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', + {ok, Bytes} = 'ELDAPv3':encode('LDAPMessage', Message), case (S#eldap.sockmod):send(S#eldap.fd, Bytes) of ok -> @@ -863,11 +863,10 @@ gen_req({modify_dn, Entry, NewRDN, DelOldRDN, #'ModifyDNRequest'{entry = Entry, newrdn = NewRDN, deleteoldrdn = DelOldRDN, newSuperior = NewSup}}; gen_req({modify_passwd, DN, Passwd}) -> - {ok, ReqVal} = asn1rt:encode('ELDAPv3', - 'PasswdModifyRequestValue', - #'PasswdModifyRequestValue'{userIdentity = DN, - newPasswd = - Passwd}), + {ok, ReqVal} = 'ELDAPv3':encode('PasswdModifyRequestValue', + #'PasswdModifyRequestValue'{userIdentity = DN, + newPasswd = + Passwd}), {extendedReq, #'ExtendedRequest'{requestName = ?passwdModifyOID, requestValue = iolist_to_binary(ReqVal)}}; @@ -887,7 +886,7 @@ gen_req({bind, RootDN, Passwd}) -> %% {'EXIT', Reason} - Broke %%----------------------------------------------------------------------- recvd_packet(Pkt, S) -> - case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of + case 'ELDAPv3':decode('LDAPMessage', Pkt) of {ok, Msg} -> Op = Msg#'LDAPMessage'.protocolOp, ?DEBUG("~p", [Op]), @@ -1005,7 +1004,7 @@ get_op_rec(Id, Dict) -> %% {'EXIT', Reason} - Broken packet %%----------------------------------------------------------------------- recvd_wait_bind_response(Pkt, S) -> - case asn1rt:decode('ELDAPv3', 'LDAPMessage', Pkt) of + case 'ELDAPv3':decode('LDAPMessage', Pkt) of {ok, Msg} -> ?DEBUG("~p", [Msg]), check_id(S#eldap.id, Msg#'LDAPMessage'.messageID), @@ -1152,7 +1151,7 @@ bind_request(Socket, S) -> Message = #'LDAPMessage'{messageID = Id, protocolOp = {bindRequest, Req}}, ?DEBUG("Bind Request Message:~p~n", [Message]), - {ok, Bytes} = asn1rt:encode('ELDAPv3', 'LDAPMessage', + {ok, Bytes} = 'ELDAPv3':encode('LDAPMessage', Message), case (S#eldap.sockmod):send(Socket, Bytes) of ok -> {ok, S#eldap{id = Id}}; diff --git a/src/eldap_filter.erl b/src/eldap_filter.erl index fc2a31219..e8ce625c8 100644 --- a/src/eldap_filter.erl +++ b/src/eldap_filter.erl @@ -6,7 +6,7 @@ %%% Author: Evgeniy Khramtsov <ekhramtsov@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/eldap_pool.erl b/src/eldap_pool.erl index 87bb3182f..51761c070 100644 --- a/src/eldap_pool.erl +++ b/src/eldap_pool.erl @@ -5,7 +5,7 @@ %%% Created : 12 Nov 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/eldap_utils.erl b/src/eldap_utils.erl index e6e874a63..eb6601623 100644 --- a/src/eldap_utils.erl +++ b/src/eldap_utils.erl @@ -5,7 +5,7 @@ %%% Created : 12 Oct 2006 by Mickael Remond <mremond@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/extauth.erl b/src/extauth.erl index 51b4611be..eb936ddf9 100644 --- a/src/extauth.erl +++ b/src/extauth.erl @@ -5,7 +5,7 @@ %%% Created : 30 Jul 2004 by Leif Johansson <leifj@it.su.se> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index d8dffa0e9..bbad1eca7 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -5,7 +5,7 @@ %%% Created : 22 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 00a716746..645e3142d 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -6,7 +6,7 @@ %%% Created : 24 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/gen_pubsub_node.erl b/src/gen_pubsub_node.erl index a1252f9f8..da8cd6a0e 100644 --- a/src/gen_pubsub_node.erl +++ b/src/gen_pubsub_node.erl @@ -11,12 +11,12 @@ %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/gen_pubsub_nodetree.erl b/src/gen_pubsub_nodetree.erl index e343f4581..8cbe1d3df 100644 --- a/src/gen_pubsub_nodetree.erl +++ b/src/gen_pubsub_nodetree.erl @@ -11,12 +11,12 @@ %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/idna.erl b/src/idna.erl index ec62d4c7a..dd19ad988 100644 --- a/src/idna.erl +++ b/src/idna.erl @@ -5,7 +5,7 @@ %%% Created : 10 Apr 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/jd2ejd.erl b/src/jd2ejd.erl index 1a75b1739..bfa52bb2a 100644 --- a/src/jd2ejd.erl +++ b/src/jd2ejd.erl @@ -5,7 +5,7 @@ %%% Created : 2 Feb 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/jlib.erl b/src/jlib.erl index dd2cc38dc..76886a7dc 100644 --- a/src/jlib.erl +++ b/src/jlib.erl @@ -5,7 +5,7 @@ %%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -57,6 +57,7 @@ %% TODO: Remove once XEP-0091 is Obsolete %% TODO: Remove once XEP-0091 is Obsolete +-include("ejabberd.hrl"). -include("jlib.hrl"). -export_type([jid/0]). @@ -601,12 +602,13 @@ rsm_encode_count(Count, Arr) -> children = [{xmlcdata, i2l(Count)}]} | Arr]. --spec add_delay_info(xmlel(), erlang:timestamp(), binary()) -> xmlel(). +-spec add_delay_info(xmlel(), jid() | ljid() | binary(), erlang:timestamp()) + -> xmlel(). add_delay_info(El, From, Time) -> add_delay_info(El, From, Time, <<"">>). --spec add_delay_info(xmlel(), erlang:timestamp(), binary(), +-spec add_delay_info(xmlel(), jid() | ljid() | binary(), erlang:timestamp(), binary()) -> xmlel(). add_delay_info(El, From, Time, Desc) -> @@ -615,8 +617,8 @@ add_delay_info(El, From, Time, Desc) -> El2 = add_delay_info(El1, From, Time, Desc, <<"x">>, ?NS_DELAY91), El2. --spec add_delay_info(xmlel(), erlang:timestamp(), binary(), binary(), binary(), - binary()) -> xmlel(). +-spec add_delay_info(xmlel(), jid() | ljid() | binary(), erlang:timestamp(), + binary(), binary(), binary()) -> xmlel(). add_delay_info(El, From, Time, Desc, Name, XMLNS) -> case xml:get_subtag_with_xmlns(El, Name, XMLNS) of @@ -647,7 +649,7 @@ add_delay_info(El, From, Time, Desc, Name, XMLNS) -> xml:append_subtags(NewEl, [NewDelayTag]) end. --spec create_delay_tag(erlang:timestamp(), jid() | binary(), binary(), +-spec create_delay_tag(erlang:timestamp(), jid() | ljid() | binary(), binary(), binary()) -> xmlel() | error. create_delay_tag(TimeStamp, FromJID, Desc, XMLNS) when is_tuple(FromJID) -> @@ -717,11 +719,16 @@ now_to_utc_string({MegaSecs, Secs, MicroSecs}, Precision) -> {{Year, Month, Day}, {Hour, Minute, Second}} = calendar:now_to_universal_time({MegaSecs, Secs, MicroSecs}), - FracOfSec = round(MicroSecs / math:pow(10, 6 - Precision)), - list_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT~2..0B:~2..0B:~2..0B.~*." - ".0BZ", - [Year, Month, Day, Hour, Minute, Second, - Precision, FracOfSec])). + Max = round(math:pow(10, Precision)), + case round(MicroSecs / math:pow(10, 6 - Precision)) of + Max -> + now_to_utc_string({MegaSecs, Secs + 1, 0}, Precision); + FracOfSec -> + list_to_binary(io_lib:format("~4..0B-~2..0B-~2..0BT" + "~2..0B:~2..0B:~2..0B.~*..0BZ", + [Year, Month, Day, Hour, Minute, Second, + Precision, FracOfSec])) + end. -spec now_to_local_string(erlang:timestamp()) -> binary(). @@ -966,7 +973,7 @@ i2l(L, N) when is_binary(L) -> _ -> i2l(<<$0, L/binary>>, N) end. --spec queue_drop_while(fun((term()) -> boolean()), queue()) -> queue(). +-spec queue_drop_while(fun((term()) -> boolean()), ?TQUEUE) -> ?TQUEUE. queue_drop_while(F, Q) -> case queue:peek(Q) of diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index 47ce625b3..ec41e73f5 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -5,7 +5,7 @@ %%% Created : 15 Nov 2005 by Magnus Henoch <henoch@dtek.chalmers.se> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_announce.erl b/src/mod_announce.erl index 40204da80..0e7c9fa32 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -5,7 +5,7 @@ %%% Created : 11 Aug 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index 0f57ce723..07e9027b6 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -5,7 +5,7 @@ %%% Created : 24 Aug 2008 by Stephan Maka <stephan@spaceboyz.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 1002df444..a96379e6d 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -5,7 +5,7 @@ %%% Created : 7 Oct 2006 by Magnus Henoch <henoch@dtek.chalmers.se> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -17,10 +17,9 @@ %%% 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 +%%% 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. %%% %%% 2009, improvements from ProcessOne to support correct PEP handling %%% through s2s, use less memory, and speedup global caps handling diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 267ed84bb..24c09bffd 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -7,7 +7,7 @@ %%% {mod_carboncopy, []} %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -153,9 +153,7 @@ check_and_forward(JID, To, Packet, Direction)-> end; _ -> ok - end; - -check_and_forward(_JID, _To, _Packet, _)-> ok. + end. remove_connection(User, Server, Resource, _Status)-> disable(Server, User, Resource), @@ -167,19 +165,16 @@ remove_connection(User, Server, Resource, _Status)-> send_copies(JID, To, Packet, Direction)-> {U, S, R} = jlib:jid_tolower(JID), PrioRes = ejabberd_sm:get_user_present_resources(U, S), + {_, AvailRs} = lists:unzip(PrioRes), {MaxPrio, MaxRes} = case catch lists:max(PrioRes) of {Prio, Res} -> {Prio, Res}; _ -> {0, undefined} end, + %% unavailable resources are handled like bare JIDs IsBareTo = case {Direction, To} of {received, #jid{lresource = <<>>}} -> true; - {received, #jid{lresource = LRes}} -> - %% unavailable resources are handled like bare JIDs - case lists:keyfind(LRes, 2, PrioRes) of - false -> true; - _ -> false - end; + {received, #jid{lresource = LRes}} -> not lists:member(LRes, AvailRs); _ -> false end, %% list of JIDs that should receive a carbon copy of this message (excluding the @@ -188,7 +183,8 @@ send_copies(JID, To, Packet, Direction)-> {true, MaxRes} -> OrigTo = fun(Res) -> lists:member({MaxPrio, Res}, PrioRes) end, [ {jlib:make_jid({U, S, CCRes}), CC_Version} - || {CCRes, CC_Version} <- list(U, S), not OrigTo(CCRes) ]; + || {CCRes, CC_Version} <- list(U, S), + lists:member(CCRes, AvailRs), not OrigTo(CCRes) ]; {true, _} -> %% The message was sent to our bare JID, and we currently have %% multiple resources with the same highest priority, so the session @@ -198,7 +194,8 @@ send_copies(JID, To, Packet, Direction)-> []; {false, _} -> [ {jlib:make_jid({U, S, CCRes}), CC_Version} - || {CCRes, CC_Version} <- list(U, S), CCRes /= R ] + || {CCRes, CC_Version} <- list(U, S), + lists:member(CCRes, AvailRs), CCRes /= R ] %TargetJIDs = lists:delete(JID, [ jlib:make_jid({U, S, CCRes}) || CCRes <- list(U, S) ]), end, diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl index 69e76c24e..fd72c02f6 100644 --- a/src/mod_client_state.erl +++ b/src/mod_client_state.erl @@ -5,7 +5,7 @@ %%% Created : 11 Sep 2014 by Holger Weiss %%% %%% -%%% ejabberd, Copyright (C) 2014 ProcessOne +%%% ejabberd, Copyright (C) 2014-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_configure.erl b/src/mod_configure.erl index fab594ca1..9e6e83e1c 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -5,7 +5,7 @@ %%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_configure2.erl b/src/mod_configure2.erl index 0d7d727f2..b70f8fe51 100644 --- a/src/mod_configure2.erl +++ b/src/mod_configure2.erl @@ -5,7 +5,7 @@ %%% Created : 26 Oct 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 1f0afc3dd..40f0f8e06 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -5,7 +5,7 @@ %%% Created : 1 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_echo.erl b/src/mod_echo.erl index db8771084..63dc8c81b 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -5,7 +5,7 @@ %%% Created : 15 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_fail2ban.erl b/src/mod_fail2ban.erl index b246e402c..7c9eba88a 100644 --- a/src/mod_fail2ban.erl +++ b/src/mod_fail2ban.erl @@ -5,6 +5,23 @@ %%% %%% @end %%% Created : 15 Aug 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% +%%% ejabberd, Copyright (C) 2014-2015 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + %%%------------------------------------------------------------------- -module(mod_fail2ban). diff --git a/src/mod_http_bind.erl b/src/mod_http_bind.erl index 2dcac1419..773ef241f 100644 --- a/src/mod_http_bind.erl +++ b/src/mod_http_bind.erl @@ -5,7 +5,7 @@ %%% Created : Tue Feb 20 13:15:52 CET 2007 %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl index 1011dd07f..97738355e 100644 --- a/src/mod_http_fileserver.erl +++ b/src/mod_http_fileserver.erl @@ -5,7 +5,7 @@ %%% Created : %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_ip_blacklist.erl b/src/mod_ip_blacklist.erl index 1dd641ce5..6225343c0 100644 --- a/src/mod_ip_blacklist.erl +++ b/src/mod_ip_blacklist.erl @@ -7,7 +7,7 @@ %%% {mod_ip_blacklist, []} %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_irc.erl b/src/mod_irc.erl index f6e7bb774..2cc57786c 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -5,7 +5,7 @@ %%% Created : 15 Feb 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -466,7 +466,7 @@ iq_get_vcard(Lang) -> [{xmlcdata, <<(translate:translate(Lang, <<"ejabberd IRC module">>))/binary, - "\nCopyright (c) 2003-2014 ProcessOne">>}]}]. + "\nCopyright (c) 2003-2015 ProcessOne">>}]}]. command_items(ServerHost, Host, Lang) -> lists:map(fun ({Node, Name, _Function}) -> diff --git a/src/mod_irc_connection.erl b/src/mod_irc_connection.erl index f150d9f53..2180ebd2b 100644 --- a/src/mod_irc_connection.erl +++ b/src/mod_irc_connection.erl @@ -5,7 +5,7 @@ %%% Created : 15 Feb 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -51,12 +51,12 @@ encoding = <<"">> :: binary(), port = 0 :: inet:port_number(), password = <<"">> :: binary(), - queue = queue:new() :: queue(), + queue = queue:new() :: ?TQUEUE, user = #jid{} :: jid(), host = <<"">> :: binary(), server = <<"">> :: binary(), nick = <<"">> :: binary(), - channels = dict:new() :: dict(), + channels = dict:new() :: ?TDICT, nickchannel :: binary(), mod = mod_irc :: atom(), inbuf = <<"">> :: binary(), diff --git a/src/mod_last.erl b/src/mod_last.erl index a20da3130..038378c7b 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -5,7 +5,7 @@ %%% Created : 24 Oct 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_muc.erl b/src/mod_muc.erl index b844a01e0..a0c6c34e6 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -5,7 +5,7 @@ %%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -1092,7 +1092,7 @@ iq_get_vcard(Lang) -> [{xmlcdata, <<(translate:translate(Lang, <<"ejabberd MUC module">>))/binary, - "\nCopyright (c) 2003-2014 ProcessOne">>}]}]. + "\nCopyright (c) 2003-2015 ProcessOne">>}]}]. broadcast_service_message(Host, Msg) -> diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index fa99ed923..626cf745e 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -5,7 +5,7 @@ %%% Created : 12 Mar 2006 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 95d437bfc..aae90af4b 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -5,7 +5,7 @@ %%% Created : 19 Mar 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -752,6 +752,9 @@ handle_sync_event({change_config, Config}, _From, handle_sync_event({change_state, NewStateData}, _From, StateName, _StateData) -> {reply, {ok, NewStateData}, StateName, NewStateData}; +handle_sync_event({process_item_change, Item, UJID}, _From, StateName, StateData) -> + NSD = process_item_change(Item, StateData, UJID), + {reply, {ok, NSD}, StateName, NSD}; handle_sync_event(_Event, _From, StateName, StateData) -> Reply = ok, {reply, Reply, StateName, StateData}. @@ -2612,114 +2615,7 @@ process_admin_items_set(UJID, Items, Lang, StateData) -> "room ~s:~n ~p", [jlib:jid_to_string(UJID), jlib:jid_to_string(StateData#state.jid), Res]), - NSD = lists:foldl(fun (E, SD) -> - case catch case E of - {JID, affiliation, owner, _} - when JID#jid.luser == - <<"">> -> - %% If the provided JID does not have username, - %% forget the affiliation completely - SD; - {JID, role, none, Reason} -> - catch - send_kickban_presence(UJID, JID, - Reason, - <<"307">>, - SD), - set_role(JID, none, SD); - {JID, affiliation, none, - Reason} -> - case - (SD#state.config)#config.members_only - of - true -> - catch - send_kickban_presence(UJID, JID, - Reason, - <<"321">>, - none, - SD), - SD1 = - set_affiliation(JID, - none, - SD), - set_role(JID, none, - SD1); - _ -> - SD1 = - set_affiliation(JID, - none, - SD), - send_update_presence(JID, - SD1), - SD1 - end; - {JID, affiliation, outcast, - Reason} -> - catch - send_kickban_presence(UJID, JID, - Reason, - <<"301">>, - outcast, - SD), - set_affiliation(JID, - outcast, - set_role(JID, - none, - SD), - Reason); - {JID, affiliation, A, Reason} - when (A == admin) or - (A == owner) -> - SD1 = set_affiliation(JID, - A, - SD, - Reason), - SD2 = set_role(JID, - moderator, - SD1), - send_update_presence(JID, - Reason, - SD2), - SD2; - {JID, affiliation, member, - Reason} -> - SD1 = set_affiliation(JID, - member, - SD, - Reason), - SD2 = set_role(JID, - participant, - SD1), - send_update_presence(JID, - Reason, - SD2), - SD2; - {JID, role, Role, Reason} -> - SD1 = set_role(JID, Role, - SD), - catch - send_new_presence(JID, - Reason, - SD1), - SD1; - {JID, affiliation, A, - _Reason} -> - SD1 = set_affiliation(JID, - A, - SD), - send_update_presence(JID, - SD1), - SD1 - end - of - {'EXIT', ErrReason} -> - ?ERROR_MSG("MUC ITEMS SET ERR: ~p~n", - [ErrReason]), - SD; - NSD -> NSD - end - end, + NSD = lists:foldl(process_item_change(UJID), StateData, lists:flatten(Res)), case (NSD#state.config)#config.persistent of true -> @@ -2732,6 +2628,79 @@ process_admin_items_set(UJID, Items, Lang, StateData) -> Err -> Err end. +process_item_change(UJID) -> + fun(E, SD) -> + process_item_change(E, SD, UJID) + end. + +process_item_change(E, SD, UJID) -> + case catch case E of + {JID, affiliation, owner, _} when JID#jid.luser == <<"">> -> + %% If the provided JID does not have username, + %% forget the affiliation completely + SD; + {JID, role, none, Reason} -> + catch + send_kickban_presence(UJID, JID, + Reason, + <<"307">>, + SD), + set_role(JID, none, SD); + {JID, affiliation, none, Reason} -> + case (SD#state.config)#config.members_only of + true -> + catch + send_kickban_presence(UJID, JID, + Reason, + <<"321">>, + none, + SD), + SD1 = set_affiliation(JID, none, SD), + set_role(JID, none, SD1); + _ -> + SD1 = set_affiliation(JID, none, SD), + send_update_presence(JID, SD1), + SD1 + end; + {JID, affiliation, outcast, Reason} -> + catch + send_kickban_presence(UJID, JID, + Reason, + <<"301">>, + outcast, + SD), + set_affiliation(JID, + outcast, + set_role(JID, none, SD), + Reason); + {JID, affiliation, A, Reason} + when (A == admin) or (A == owner) -> + SD1 = set_affiliation(JID, A, SD, Reason), + SD2 = set_role(JID, moderator, SD1), + send_update_presence(JID, Reason, SD2), + SD2; + {JID, affiliation, member, Reason} -> + SD1 = set_affiliation(JID, member, SD, Reason), + SD2 = set_role(JID, participant, SD1), + send_update_presence(JID, Reason, SD2), + SD2; + {JID, role, Role, Reason} -> + SD1 = set_role(JID, Role, SD), + catch + send_new_presence(JID, Reason, SD1), + SD1; + {JID, affiliation, A, _Reason} -> + SD1 = set_affiliation(JID, A, SD), + send_update_presence(JID, SD1), + SD1 + end + of + {'EXIT', ErrReason} -> + ?ERROR_MSG("MUC ITEMS SET ERR: ~p~n", [ErrReason]), + SD; + NSD -> NSD + end. + find_changed_items(_UJID, _UAffiliation, _URole, [], _Lang, _StateData, Res) -> {result, Res}; diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 4ac3f18f8..b0582bc20 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -5,7 +5,7 @@ %%% Created : 5 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_ping.erl b/src/mod_ping.erl index 15bfd08de..f493dccb8 100644 --- a/src/mod_ping.erl +++ b/src/mod_ping.erl @@ -5,7 +5,7 @@ %%% Created : 11 Jul 2009 by Brian Cully <bjc@kublai.com> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -63,7 +63,7 @@ send_pings = ?DEFAULT_SEND_PINGS :: boolean(), ping_interval = ?DEFAULT_PING_INTERVAL :: non_neg_integer(), timeout_action = none :: none | kill, - timers = (?DICT):new() :: dict()}). + timers = (?DICT):new() :: ?TDICT}). %%==================================================================== %% API diff --git a/src/mod_pres_counter.erl b/src/mod_pres_counter.erl index d40d54596..e904ab95f 100644 --- a/src/mod_pres_counter.erl +++ b/src/mod_pres_counter.erl @@ -5,7 +5,7 @@ %%% Created : 23 Sep 2010 by Ahmed Omar %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 9c9ec919f..c83a953c4 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -5,7 +5,7 @@ %%% Created : 21 Jul 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_private.erl b/src/mod_private.erl index 9fdf09dd8..cedcb2787 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -5,7 +5,7 @@ %%% Created : 16 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_proxy65.erl b/src/mod_proxy65.erl index 17da3660b..6eced10b8 100644 --- a/src/mod_proxy65.erl +++ b/src/mod_proxy65.erl @@ -5,7 +5,7 @@ %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_proxy65_lib.erl b/src/mod_proxy65_lib.erl index e43ceb7e8..6c5967688 100644 --- a/src/mod_proxy65_lib.erl +++ b/src/mod_proxy65_lib.erl @@ -5,7 +5,7 @@ %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl index 9f66cf7d2..1e7735c58 100644 --- a/src/mod_proxy65_service.erl +++ b/src/mod_proxy65_service.erl @@ -5,7 +5,7 @@ %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -247,7 +247,7 @@ iq_vcard(Lang) -> [{xmlcdata, <<(translate:translate(Lang, <<"ejabberd SOCKS5 Bytestreams module">>))/binary, - "\nCopyright (c) 2003-2014 ProcessOne">>}]}]. + "\nCopyright (c) 2003-2015 ProcessOne">>}]}]. parse_options(ServerHost, Opts) -> MyHost = gen_mod:get_opt_host(ServerHost, Opts, diff --git a/src/mod_proxy65_sm.erl b/src/mod_proxy65_sm.erl index fc8cd3649..367f7f0bd 100644 --- a/src/mod_proxy65_sm.erl +++ b/src/mod_proxy65_sm.erl @@ -5,7 +5,7 @@ %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_proxy65_stream.erl b/src/mod_proxy65_stream.erl index 958aeaa1f..663fbf729 100644 --- a/src/mod_proxy65_stream.erl +++ b/src/mod_proxy65_stream.erl @@ -4,7 +4,7 @@ %%% Purpose : Bytestream process. %%% Created : 12 Oct 2006 by Evgeniy Khramtsov <xram@jabber.ru> %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index 504739c6a..08e351462 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -13,11 +13,11 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} @@ -1991,7 +1991,7 @@ iq_get_vcard(Lang) -> [{xmlcdata, <<(translate:translate(Lang, <<"ejabberd Publish-Subscribe module">>))/binary, - "\nCopyright (c) 2004-2014 ProcessOne">>}]}]. + "\nCopyright (c) 2004-2015 ProcessOne">>}]}]. -spec(iq_pubsub/6 :: ( diff --git a/src/mod_pubsub_odbc.erl b/src/mod_pubsub_odbc.erl index e3e736f5f..4b9787821 100644 --- a/src/mod_pubsub_odbc.erl +++ b/src/mod_pubsub_odbc.erl @@ -13,11 +13,11 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} @@ -1612,7 +1612,7 @@ iq_get_vcard(Lang) -> [{xmlcdata, <<(translate:translate(Lang, <<"ejabberd Publish-Subscribe module">>))/binary, - "\nCopyright (c) 2004-2014 ProcessOne">>}]}]. + "\nCopyright (c) 2004-2015 ProcessOne">>}]}]. -spec(iq_pubsub/6 :: ( @@ -2354,7 +2354,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) -> {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, Reply}; Error -> diff --git a/src/mod_register.erl b/src/mod_register.erl index 21e088b5a..cd68af936 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -5,7 +5,7 @@ %%% Created : 8 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_register_web.erl b/src/mod_register_web.erl index ee3ff0069..fb94923f6 100644 --- a/src/mod_register_web.erl +++ b/src/mod_register_web.erl @@ -5,7 +5,7 @@ %%% Created : 4 May 2008 by Badlop <badlop@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -142,7 +142,7 @@ process([<<"change_password">>], {404, [], ErrorText} end; -process(Path, _Request) -> +process(_Path, _Request) -> {404, [], "Not Found"}. %%%---------------------------------------------------------------------- diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 7bd171ffb..e60337cda 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -5,7 +5,7 @@ %%% Created : 11 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_service_log.erl b/src/mod_service_log.erl index dd4800baa..7a23b4013 100644 --- a/src/mod_service_log.erl +++ b/src/mod_service_log.erl @@ -5,7 +5,7 @@ %%% Created : 24 Aug 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 916285660..16800ded4 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -5,7 +5,7 @@ %%% Created : 5 Mar 2005 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -835,12 +835,13 @@ add_user_to_group(Host, US, Group) -> (?MODULE):set_group_opts(Host, Group, GroupOpts ++ MoreGroupOpts); nomatch -> - push_user_to_displayed(LUser, LServer, Group, Host, - both), - push_displayed_to_user(LUser, LServer, Group, Host, - both), - add_user_to_group(Host, US, Group, - gen_mod:db_type(Host, ?MODULE)) + DisplayedToGroups = displayed_to_groups(Group, Host), + DisplayedGroups = get_displayed_groups(Group, LServer), + push_user_to_displayed(LUser, LServer, Group, Host, both, DisplayedToGroups), + push_displayed_to_user(LUser, LServer, Host, both, DisplayedGroups), + broadcast_user_to_displayed(LUser, LServer, Host, both, DisplayedToGroups), + broadcast_displayed_to_user(LUser, LServer, Host, both, DisplayedGroups), + add_user_to_group(Host, US, Group, gen_mod:db_type(Host, ?MODULE)) end. add_user_to_group(Host, US, Group, mnesia) -> @@ -865,12 +866,17 @@ add_user_to_group(Host, US, Group, odbc) -> end, ejabberd_odbc:sql_transaction(Host, F). -push_displayed_to_user(LUser, LServer, Group, Host, - Subscription) -> +get_displayed_groups(Group, LServer) -> GroupsOpts = groups_with_opts(LServer), GroupOpts = proplists:get_value(Group, GroupsOpts, []), - DisplayedGroups = proplists:get_value(displayed_groups, - GroupOpts, []), + proplists:get_value(displayed_groups, GroupOpts, []). + +broadcast_displayed_to_user(LUser, LServer, Host, Subscription, DisplayedGroups) -> + [broadcast_members_to_user(LUser, LServer, DGroup, Host, + Subscription) + || DGroup <- DisplayedGroups]. + +push_displayed_to_user(LUser, LServer, Host, Subscription, DisplayedGroups) -> [push_members_to_user(LUser, LServer, DGroup, Host, Subscription) || DGroup <- DisplayedGroups]. @@ -894,10 +900,10 @@ remove_user_from_group(Host, US, Group) -> nomatch -> Result = remove_user_from_group(Host, US, Group, gen_mod:db_type(Host, ?MODULE)), - push_user_to_displayed(LUser, LServer, Group, Host, - remove), - push_displayed_to_user(LUser, LServer, Group, Host, - remove), + DisplayedToGroups = displayed_to_groups(Group, Host), + DisplayedGroups = get_displayed_groups(Group, LServer), + push_user_to_displayed(LUser, LServer, Group, Host, remove, DisplayedToGroups), + push_displayed_to_user(LUser, LServer, Host, remove, DisplayedGroups), Result end. @@ -930,10 +936,17 @@ push_members_to_user(LUser, LServer, Group, Host, end, Members). +broadcast_members_to_user(LUser, LServer, Group, Host, Subscription) -> + Members = get_group_users(Host, Group), + lists:foreach( + fun({U, S}) -> + broadcast_subscription(U, S, {LUser, LServer, <<"">>}, Subscription) + end, Members). + register_user(User, Server) -> Groups = get_user_groups({User, Server}), [push_user_to_displayed(User, Server, Group, Server, - both) + both, displayed_to_groups(Group, Server)) || Group <- Groups]. remove_user(User, Server) -> @@ -965,17 +978,18 @@ push_user_to_members(User, Server, Subscription) -> end, lists:usort(SpecialGroups ++ UserGroups)). -push_user_to_displayed(LUser, LServer, Group, Host, - Subscription) -> +push_user_to_displayed(LUser, LServer, Group, Host, Subscription, DisplayedToGroupsOpts) -> GroupsOpts = groups_with_opts(Host), GroupOpts = proplists:get_value(Group, GroupsOpts, []), GroupName = proplists:get_value(name, GroupOpts, Group), - DisplayedToGroupsOpts = displayed_to_groups(Group, - Host), [push_user_to_group(LUser, LServer, GroupD, Host, GroupName, Subscription) || {GroupD, _Opts} <- DisplayedToGroupsOpts]. +broadcast_user_to_displayed(LUser, LServer, Host, Subscription, DisplayedToGroupsOpts) -> + [broadcast_user_to_group(LUser, LServer, GroupD, Host, Subscription) + || {GroupD, _Opts} <- DisplayedToGroupsOpts]. + push_user_to_group(LUser, LServer, Group, Host, GroupName, Subscription) -> lists:foreach(fun ({U, S}) @@ -987,6 +1001,13 @@ push_user_to_group(LUser, LServer, Group, Host, end, get_group_users(Host, Group)). +broadcast_user_to_group(LUser, LServer, Group, Host, Subscription) -> + lists:foreach( + fun({U, S}) when (U == LUser) and (S == LServer) -> ok; + ({U, S}) -> + broadcast_subscription(LUser, LServer, {U, S, <<"">>}, Subscription) + end, get_group_users(Host, Group)). + %% Get list of groups to which this group is displayed displayed_to_groups(GroupName, LServer) -> GroupsOpts = groups_with_opts(LServer), @@ -997,11 +1018,7 @@ displayed_to_groups(GroupName, LServer) -> end, GroupsOpts). -push_item(User, Server, From, Item) -> - ejabberd_sm:route(From, - jlib:make_jid(User, Server, <<"">>), - {broadcast, {item, Item#roster.jid, - Item#roster.subscription}}), +push_item(User, Server, Item) -> Stanza = jlib:iq_to_xml(#iq{type = set, xmlns = ?NS_ROSTER, id = <<"push", (randoms:get_string())/binary>>, @@ -1022,8 +1039,7 @@ push_roster_item(User, Server, ContactU, ContactS, us = {User, Server}, jid = {ContactU, ContactS, <<"">>}, name = <<"">>, subscription = Subscription, ask = none, groups = [GroupName]}, - push_item(User, Server, - jlib:make_jid(<<"">>, Server, <<"">>), Item). + push_item(User, Server, Item). item_to_xml(Item) -> Attrs1 = [{<<"jid">>, @@ -1067,14 +1083,16 @@ user_available(New) -> case length(Resources) of %% first session for this user 1 -> - OnlineGroups = get_special_users_groups_online(LServer), + UserGroups = get_user_groups({LUser, LServer}), lists:foreach(fun (OG) -> ?DEBUG("user_available: pushing ~p @ ~p grp ~p", [LUser, LServer, OG]), - push_user_to_displayed(LUser, LServer, OG, - LServer, both) + DisplayedToGroups = displayed_to_groups(OG, LServer), + DisplayedGroups = get_displayed_groups(OG, LServer), + broadcast_displayed_to_user(LUser, LServer, LServer, both, DisplayedGroups), + broadcast_user_to_displayed(LUser, LServer, LServer, both, DisplayedToGroups) end, - OnlineGroups); + UserGroups); _ -> ok end. @@ -1089,9 +1107,9 @@ unset_presence(LUser, LServer, Resource, Status) -> OnlineGroups = get_special_users_groups_online(LServer), lists:foreach(fun (OG) -> push_user_to_displayed(LUser, LServer, OG, - LServer, remove), - push_displayed_to_user(LUser, LServer, OG, - LServer, remove) + LServer, remove, displayed_to_groups(OG, LServer)), + push_displayed_to_user(LUser, LServer, + LServer, remove, displayed_to_groups(OG, LServer)) end, OnlineGroups); _ -> ok @@ -1306,6 +1324,11 @@ shared_roster_group_parse_query(Host, Group, Query) -> true -> [{online_users, true}]; false -> [] end, + CurrentDisplayedGroups = get_displayed_groups(Group, Host), + AddedDisplayedGroups = DispGroups -- CurrentDisplayedGroups, + RemovedDisplayedGroups = CurrentDisplayedGroups -- DispGroups, + displayed_groups_update(OldMembers, RemovedDisplayedGroups, remove), + displayed_groups_update(OldMembers, AddedDisplayedGroups, both), (?MODULE):set_group_opts(Host, Group, NameOpt ++ DispGroupsOpt ++ @@ -1346,6 +1369,25 @@ split_grouphost(Host, Group) -> [_] -> {Host, Group} end. +broadcast_subscription(User, Server, ContactJid, Subscription) -> + ejabberd_sm:route( + jlib:make_jid(<<"">>, Server, <<"">>), + jlib:make_jid(User, Server, <<"">>), + {broadcast, {item, ContactJid, + Subscription}}). + +displayed_groups_update(Members, DisplayedGroups, Subscription) -> + lists:foreach(fun({U, S}) -> + push_displayed_to_user(U, S, S, Subscription, DisplayedGroups), + case Subscription of + both -> + broadcast_displayed_to_user(U, S, S, to, DisplayedGroups), + broadcast_displayed_to_user(U, S, S, from, DisplayedGroups); + Subscr -> + broadcast_displayed_to_user(U, S, S, Subscr, DisplayedGroups) + end + end, Members). + make_jid_s(U, S) -> ejabberd_odbc:escape(jlib:jid_to_string(jlib:jid_tolower(jlib:make_jid(U, S, diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl index 6bf7c9f7d..af85e4d40 100644 --- a/src/mod_shared_roster_ldap.erl +++ b/src/mod_shared_roster_ldap.erl @@ -7,7 +7,7 @@ %%% Created : 5 Mar 2005 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_sic.erl b/src/mod_sic.erl index 46dfbebc1..ed44f8500 100644 --- a/src/mod_sic.erl +++ b/src/mod_sic.erl @@ -5,7 +5,7 @@ %%% Created : 6 Mar 2010 by Karim Gemayel <karim.gemayel@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_sip.erl b/src/mod_sip.erl index bf57de75c..f7f2b8ed0 100644 --- a/src/mod_sip.erl +++ b/src/mod_sip.erl @@ -5,6 +5,23 @@ %%% %%% @end %%% Created : 21 Apr 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% +%%% ejabberd, Copyright (C) 2014-2015 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + %%%------------------------------------------------------------------- -module(mod_sip). diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl index b2f76dbb3..6168d997c 100644 --- a/src/mod_sip_proxy.erl +++ b/src/mod_sip_proxy.erl @@ -5,6 +5,23 @@ %%% %%% @end %%% Created : 21 Apr 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% +%%% ejabberd, Copyright (C) 2014-2015 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + %%%------------------------------------------------------------------- -module(mod_sip_proxy). diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index 298c7108b..a534c61ce 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -5,6 +5,23 @@ %%% %%% @end %%% Created : 23 Apr 2014 by Evgeny Khramtsov <ekhramtsov@process-one.net> +%%% +%%% ejabberd, Copyright (C) 2014-2015 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., +%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + %%%------------------------------------------------------------------- -module(mod_sip_registrar). diff --git a/src/mod_stats.erl b/src/mod_stats.erl index 15caa31ca..4317e9e92 100644 --- a/src/mod_stats.erl +++ b/src/mod_stats.erl @@ -5,7 +5,7 @@ %%% Created : 11 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_time.erl b/src/mod_time.erl index 119661c33..c82fde41c 100644 --- a/src/mod_time.erl +++ b/src/mod_time.erl @@ -6,7 +6,7 @@ %%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 8afac260b..7d2860ee6 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -5,7 +5,7 @@ %%% Created : 2 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -162,7 +162,7 @@ process_local_iq(_From, _To, [{xmlcdata, <<(translate:translate(Lang, <<"Erlang Jabber Server">>))/binary, - "\nCopyright (c) 2002-2014 ProcessOne">>}]}, + "\nCopyright (c) 2002-2015 ProcessOne">>}]}, #xmlel{name = <<"BDAY">>, attrs = [], children = [{xmlcdata, <<"2002-11-16">>}]}]}]} @@ -574,7 +574,7 @@ iq_get_vcard(Lang) -> [{xmlcdata, <<(translate:translate(Lang, <<"ejabberd vCard module">>))/binary, - "\nCopyright (c) 2003-2014 ProcessOne">>}]}]. + "\nCopyright (c) 2003-2015 ProcessOne">>}]}]. find_xdata_el(#xmlel{children = SubEls}) -> find_xdata_el1(SubEls). diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index 96ba25ac9..61db38976 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -5,7 +5,7 @@ %%% Created : 2 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as @@ -220,7 +220,7 @@ process_local_iq(_From, _To, [{xmlcdata, <<(translate:translate(Lang, <<"Erlang Jabber Server">>))/binary, - "\nCopyright (c) 2002-2014 ProcessOne">>}]}, + "\nCopyright (c) 2002-2015 ProcessOne">>}]}, #xmlel{name = <<"BDAY">>, attrs = [], children = [{xmlcdata, <<"2002-11-16">>}]}]}]} @@ -581,7 +581,7 @@ iq_get_vcard(Lang) -> [{xmlcdata, <<(translate:translate(Lang, <<"ejabberd vCard module">>))/binary, - "\nCopyright (c) 2003-2014 ProcessOne">>}]}]. + "\nCopyright (c) 2003-2015 ProcessOne">>}]}]. -define(LFIELD(Label, Var), #xmlel{name = <<"field">>, diff --git a/src/mod_version.erl b/src/mod_version.erl index 1aa026c51..e46262a2a 100644 --- a/src/mod_version.erl +++ b/src/mod_version.erl @@ -5,7 +5,7 @@ %%% Created : 18 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/node.template b/src/node.template index 45744c059..89b4a310a 100644 --- a/src/node.template +++ b/src/node.template @@ -11,11 +11,11 @@ %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_buddy.erl b/src/node_buddy.erl index 6db076935..e7ab2799c 100644 --- a/src/node_buddy.erl +++ b/src/node_buddy.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_club.erl b/src/node_club.erl index 5e6581ad8..f91723030 100644 --- a/src/node_club.erl +++ b/src/node_club.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_dispatch.erl b/src/node_dispatch.erl index 81fe20d2b..3bf20cc63 100644 --- a/src/node_dispatch.erl +++ b/src/node_dispatch.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_flat.erl b/src/node_flat.erl index e28fd3477..ff37f13e5 100644 --- a/src/node_flat.erl +++ b/src/node_flat.erl @@ -13,11 +13,11 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_flat_odbc.erl b/src/node_flat_odbc.erl index d299c8d52..1baf38e71 100644 --- a/src/node_flat_odbc.erl +++ b/src/node_flat_odbc.erl @@ -13,11 +13,11 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_hometree.erl b/src/node_hometree.erl index f59d8d9c0..6f3c4de74 100644 --- a/src/node_hometree.erl +++ b/src/node_hometree.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_hometree_odbc.erl b/src/node_hometree_odbc.erl index 9a4a3b2e7..0678b9898 100644 --- a/src/node_hometree_odbc.erl +++ b/src/node_hometree_odbc.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_mb.erl b/src/node_mb.erl index 6587b5c07..efcacf6e8 100644 --- a/src/node_mb.erl +++ b/src/node_mb.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Eric Cestari <eric@ohmforce.com> %%% @version {@vsn}, {@date} {@time} %%% @end diff --git a/src/node_pep.erl b/src/node_pep.erl index 47afee945..f6575dafa 100644 --- a/src/node_pep.erl +++ b/src/node_pep.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_pep_odbc.erl b/src/node_pep_odbc.erl index 4c7d8909b..39b936aad 100644 --- a/src/node_pep_odbc.erl +++ b/src/node_pep_odbc.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_private.erl b/src/node_private.erl index 61f6d6a68..12459e595 100644 --- a/src/node_private.erl +++ b/src/node_private.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/node_public.erl b/src/node_public.erl index bcabec6eb..cbb7baffb 100644 --- a/src/node_public.erl +++ b/src/node_public.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/nodetree_tree.erl b/src/nodetree_tree.erl index 1dc7fa9fb..7a9b46bcc 100644 --- a/src/nodetree_tree.erl +++ b/src/nodetree_tree.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/nodetree_tree_odbc.erl b/src/nodetree_tree_odbc.erl index 1a5a4317f..eb966109b 100644 --- a/src/nodetree_tree_odbc.erl +++ b/src/nodetree_tree_odbc.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/nodetree_virtual.erl b/src/nodetree_virtual.erl index 9e2e31f9f..abe88560f 100644 --- a/src/nodetree_virtual.erl +++ b/src/nodetree_virtual.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/odbc_queries.erl b/src/odbc_queries.erl index 09549c0a2..1fa16b896 100644 --- a/src/odbc_queries.erl +++ b/src/odbc_queries.erl @@ -5,7 +5,7 @@ %%% Created : by Mickael Remond <mremond@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/pubsub_db_odbc.erl b/src/pubsub_db_odbc.erl index 320a58c90..f22ee1968 100644 --- a/src/pubsub_db_odbc.erl +++ b/src/pubsub_db_odbc.erl @@ -11,9 +11,9 @@ %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% @author Pablo Polvorin <pablo.polvorin@process-one.net> %%% @version {@vsn}, {@date} {@time} diff --git a/src/pubsub_index.erl b/src/pubsub_index.erl index 9859141df..94efa0e96 100644 --- a/src/pubsub_index.erl +++ b/src/pubsub_index.erl @@ -13,12 +13,12 @@ %%% %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% -%%% @copyright 2006-2014 ProcessOne +%%% @copyright 2006-2015 ProcessOne %%% @author Christophe Romain <christophe.romain@process-one.net> %%% [http://www.process-one.net/] %%% @version {@vsn}, {@date} {@time} diff --git a/src/pubsub_subscription.erl b/src/pubsub_subscription.erl index 64bb8c2da..1e3f18e7b 100644 --- a/src/pubsub_subscription.erl +++ b/src/pubsub_subscription.erl @@ -11,9 +11,9 @@ %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% @author Brian Cully <bjc@kublai.com> %%% @version {@vsn}, {@date} {@time} diff --git a/src/pubsub_subscription_odbc.erl b/src/pubsub_subscription_odbc.erl index f0efcefb5..b54733aaa 100644 --- a/src/pubsub_subscription_odbc.erl +++ b/src/pubsub_subscription_odbc.erl @@ -11,9 +11,9 @@ %%% under the License. %%% %%% The Initial Developer of the Original Code is ProcessOne. -%%% Portions created by ProcessOne are Copyright 2006-2014, ProcessOne +%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne %%% All Rights Reserved.'' -%%% This software is copyright 2006-2014, ProcessOne. +%%% This software is copyright 2006-2015, ProcessOne. %%% %%% @author Pablo Polvorin <pablo.polvorin@process-one.net> %%% @author based on pubsub_subscription.erl by Brian Cully <bjc@kublai.com> diff --git a/src/randoms.erl b/src/randoms.erl index db2d20ccd..950f29fc3 100644 --- a/src/randoms.erl +++ b/src/randoms.erl @@ -5,7 +5,7 @@ %%% Created : 13 Dec 2002 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/scram.erl b/src/scram.erl index 19684cb46..c8c85e8d5 100644 --- a/src/scram.erl +++ b/src/scram.erl @@ -5,7 +5,7 @@ %%% Created : 7 Aug 2011 by Stephen Röttger <stephen.roettger@googlemail.com> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/shaper.erl b/src/shaper.erl index 4904d391e..a85c4f111 100644 --- a/src/shaper.erl +++ b/src/shaper.erl @@ -5,7 +5,7 @@ %%% Created : 9 Feb 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/str.erl b/src/str.erl index cd0325e84..80d7b05b0 100644 --- a/src/str.erl +++ b/src/str.erl @@ -5,7 +5,7 @@ %%% Created : 23 Feb 2012 by Evgeniy Khramtsov <ekhramtsov@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/translate.erl b/src/translate.erl index 846b33e06..9e48e0b7a 100644 --- a/src/translate.erl +++ b/src/translate.erl @@ -5,7 +5,7 @@ %%% Created : 6 Jan 2003 by Alexey Shchepin <alexey@process-one.net> %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as diff --git a/src/win32_dns.erl b/src/win32_dns.erl index d3f25648b..f0e4b5f28 100644 --- a/src/win32_dns.erl +++ b/src/win32_dns.erl @@ -5,7 +5,7 @@ %%% Created : 5 Mar 2009 by Geoff Cant %%% %%% -%%% ejabberd, Copyright (C) 2002-2014 ProcessOne +%%% ejabberd, Copyright (C) 2002-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or %%% modify it under the terms of the GNU General Public License as |