From 6aeb9dcb38921249cdfe453baeadcd03298d5d6e Mon Sep 17 00:00:00 2001 From: Christophe Romain Date: Wed, 7 Oct 2015 00:06:58 +0200 Subject: [PATCH] cosmetic cleanup --- include/ejabberd_http.hrl | 9 +- include/mod_offline.hrl | 11 + src/acl.erl | 39 +- src/ejabberd_admin.erl | 4 +- src/ejabberd_auth.erl | 5 +- src/ejabberd_auth_external.erl | 1 - src/ejabberd_c2s.erl | 754 ++++++++++++++---------------- src/ejabberd_captcha.erl | 42 +- src/ejabberd_cluster.erl | 53 +++ src/ejabberd_commands.erl | 12 +- src/ejabberd_config.erl | 2 +- src/ejabberd_ctl.erl | 7 +- src/ejabberd_frontend_socket.erl | 51 +- src/ejabberd_hooks.erl | 7 +- src/ejabberd_http.erl | 78 ++-- src/ejabberd_http_bind.erl | 155 +++--- src/ejabberd_local.erl | 54 +-- src/ejabberd_logger.erl | 1 - src/ejabberd_odbc.erl | 33 +- src/ejabberd_piefxis.erl | 25 +- src/ejabberd_receiver.erl | 69 +-- src/ejabberd_riak.erl | 2 + src/ejabberd_router.erl | 3 +- src/ejabberd_router_multicast.erl | 18 + src/ejabberd_s2s.erl | 71 +-- src/ejabberd_s2s_in.erl | 38 -- src/ejabberd_s2s_out.erl | 49 +- src/ejabberd_sm.erl | 62 +-- src/ejabberd_sm_redis.erl | 3 +- src/ejabberd_socket.erl | 11 +- src/ejabberd_system_monitor.erl | 19 +- src/ejabberd_update.erl | 25 +- src/ejabberd_web_admin.erl | 82 ++-- src/eldap.erl | 79 +--- src/gen_iq_handler.erl | 115 ++--- src/mod_carboncopy.erl | 32 +- src/mod_configure.erl | 21 +- src/mod_fail2ban.erl | 2 +- src/mod_irc.erl | 2 - src/mod_mam.erl | 532 ++++++++++----------- src/mod_muc.erl | 183 +++----- src/mod_muc_admin.erl | 1 - src/mod_muc_log.erl | 93 +--- src/mod_muc_room.erl | 76 +-- src/mod_multicast.erl | 75 +-- src/mod_offline.erl | 66 ++- src/mod_privacy.erl | 22 +- src/mod_proxy65_sm.erl | 5 +- src/mod_pubsub.erl | 18 +- src/mod_register.erl | 2 + src/mod_roster.erl | 1 - src/mod_shared_roster.erl | 27 +- src/mod_shared_roster_ldap.erl | 9 +- src/mod_sip.erl | 2 +- src/mod_sip_proxy.erl | 2 +- src/mod_sip_registrar.erl | 2 +- src/mod_stats.erl | 14 +- src/node_pep.erl | 3 +- src/node_pep_odbc.erl | 3 +- 59 files changed, 1275 insertions(+), 1907 deletions(-) create mode 100644 include/mod_offline.hrl create mode 100644 src/ejabberd_cluster.erl diff --git a/include/ejabberd_http.hrl b/include/ejabberd_http.hrl index 404427d7f..7e3d40ee1 100644 --- a/include/ejabberd_http.hrl +++ b/include/ejabberd_http.hrl @@ -19,7 +19,7 @@ %%%---------------------------------------------------------------------- -record(request, - {method, % :: method(), + {method :: method(), path = [] :: [binary()], q = [] :: [{binary() | nokey, binary()}], us = {<<>>, <<>>} :: {binary(), binary()}, @@ -30,11 +30,10 @@ ip :: {inet:ip_address(), inet:port_number()}, host = <<"">> :: binary(), port = 5280 :: inet:port_number(), - tp = http, % :: protocol(), opts = [] :: list(), + tp = http :: protocol(), headers = [] :: [{atom() | binary(), binary()}]}). - -record(ws, {socket :: inet:socket() | p1_tls:tls_socket(), sockmod = gen_tcp :: gen_tcp | p1_tls, @@ -47,3 +46,7 @@ q = [] :: [{binary() | nokey, binary()}], buf :: binary(), http_opts = [] :: list()}). + +-type method() :: 'GET' | 'HEAD' | 'DELETE' | 'OPTIONS' | 'PUT' | 'POST' | 'TRACE'. +-type protocol() :: http | https. +-type http_request() :: #request{}. diff --git a/include/mod_offline.hrl b/include/mod_offline.hrl new file mode 100644 index 000000000..c4c70604a --- /dev/null +++ b/include/mod_offline.hrl @@ -0,0 +1,11 @@ +-record(offline_msg, + {us = {<<"">>, <<"">>} :: {binary(), binary()}, + timestamp = now() :: erlang:timestamp() | '_', + expire = now() :: erlang:timestamp() | never | '_', + from = #jid{} :: jid() | '_', + to = #jid{} :: jid() | '_', + packet = #xmlel{} :: xmlel() | '_'}). + +-record(state, + {host = <<"">> :: binary(), + access_max_offline_messages}). diff --git a/src/acl.erl b/src/acl.erl index 021e4e2d4..d56292680 100644 --- a/src/acl.erl +++ b/src/acl.erl @@ -98,7 +98,7 @@ to_record(Host, ACLName, ACLSpec) -> -spec add(binary(), aclname(), aclspec()) -> ok | {error, any()}. add(Host, ACLName, ACLSpec) -> - {ResL, BadNodes} = rpc:multicall(mnesia:system_info(running_db_nodes), + {ResL, BadNodes} = ejabberd_cluster:multicall( ?MODULE, add_local, [Host, ACLName, ACLSpec]), case lists:keyfind(aborted, 1, ResL) of @@ -125,7 +125,7 @@ add_local(Host, ACLName, ACLSpec) -> -spec add_list(binary(), [acl()], boolean()) -> ok | {error, any()}. add_list(Host, ACLs, Clear) -> - {ResL, BadNodes} = rpc:multicall(mnesia:system_info(running_db_nodes), + {ResL, BadNodes} = ejabberd_cluster:multicall( ?MODULE, add_list_local, [Host, ACLs, Clear]), case lists:keyfind(aborted, 1, ResL) of @@ -167,16 +167,12 @@ add_list_local(Host, ACLs, Clear) -> access_name(), [access_rule()]) -> ok | {error, any()}. add_access(Host, Access, Rules) -> - case mnesia:transaction( - fun() -> - mnesia:write( - #access{name = {Access, Host}, - rules = Rules}) - end) of - {atomic, ok} -> - ok; - Err -> - {error, Err} + Obj = #access{name = {Access, Host}, rules = Rules}, + case mnesia:transaction(fun() -> mnesia:write(Obj) end) of + {atomic, ok} -> + ok; + Err -> + {error, Err} end. -spec load_from_config() -> ok. @@ -239,8 +235,7 @@ normalize_spec(Spec) -> {server_regexp, SR} -> {server_regexp, b(SR)}; {server_glob, S} -> {server_glob, b(S)}; {resource_glob, R} -> {resource_glob, b(R)}; - {ip, {Net, Mask}} -> - {ip, {Net, Mask}}; + {ip, {Net, Mask}} -> {ip, {Net, Mask}}; {ip, S} -> case parse_ip_netmask(b(S)) of {ok, Net, Mask} -> @@ -294,17 +289,15 @@ match_acl(none, _JID, _Host) -> match_acl(ACL, IP, Host) when tuple_size(IP) == 4; tuple_size(IP) == 8 -> lists:any( - fun(#acl{aclspec = {ip, {Net, Mask}}}) -> + fun({ip, {Net, Mask}}) -> is_ip_match(IP, Net, Mask); (_) -> false - end, - ets:lookup(acl, {ACL, Host}) ++ - ets:lookup(acl, {ACL, global})); + end, get_aclspecs(ACL, Host)); match_acl(ACL, JID, Host) -> {User, Server, Resource} = jlib:jid_tolower(JID), lists:any( - fun(#acl{aclspec = Spec}) -> + fun(Spec) -> case Spec of all -> true; {user, {U, S}} -> U == User andalso S == Server; @@ -350,7 +343,13 @@ match_acl(ACL, JID, Host) -> false end end, - ets:lookup(acl, {ACL, Host}) ++ + get_aclspecs(ACL, Host)). + +get_aclspecs(ACL, Host) -> + lists:flatmap( + fun(#acl{aclspec = Specs}) -> + Specs + end, ets:lookup(acl, {ACL, Host}) ++ ets:lookup(acl, {ACL, global})). is_regexp_match(String, RegExp) -> diff --git a/src/ejabberd_admin.erl b/src/ejabberd_admin.erl index dc4c10c87..2068f10c8 100644 --- a/src/ejabberd_admin.erl +++ b/src/ejabberd_admin.erl @@ -462,7 +462,7 @@ restore_mnesia(Path) -> %% Mnesia database restore %% This function is called from ejabberd_ctl, ejabberd_web_admin and -%% mod_configure/adhoc +%% mod_configure/adhoc restore(Path) -> mnesia:restore(Path, [{keep_tables,keep_tables()}, {default_op, skip_tables}]). @@ -477,7 +477,7 @@ keep_tables() -> %% Returns the list of modules tables in use, according to the list of actually %% loaded modules -keep_modules_tables() -> +keep_modules_tables() -> lists:map(fun(Module) -> module_tables(Module) end, gen_mod:loaded_modules(?MYNAME)). diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 03c117b6c..6fb3caa00 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -77,7 +77,7 @@ -callback get_password_s(binary(), binary()) -> binary() | {binary(), binary(), binary(), integer()}. start() -> -%% This is only executed by ejabberd_c2s for non-SASL auth client + %% This is only executed by ejabberd_c2s for non-SASL auth client lists:foreach(fun (Host) -> lists:foreach(fun (M) -> M:start(Host) end, auth_modules(Host)) @@ -187,7 +187,8 @@ try_register(User, Server, Password) -> case is_user_exists(User, Server) of true -> {atomic, exists}; false -> - case lists:member(jlib:nameprep(Server), ?MYHOSTS) of + LServer = jlib:nameprep(Server), + case lists:member(LServer, ?MYHOSTS) of true -> Res = lists:foldl(fun (_M, {atomic, ok} = Res) -> Res; (M, _) -> diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl index 4d11507ee..cc3a781ce 100644 --- a/src/ejabberd_auth_external.erl +++ b/src/ejabberd_auth_external.erl @@ -281,7 +281,6 @@ is_fresh_enough(TimeStampLast, CacheTime) -> get_last_access(User, Server) -> case ejabberd_sm:get_user_resources(User, Server) of [] -> -%% _US = {User, Server}, case get_last_info(User, Server) of mod_last_required -> mod_last_required; not_found -> never; diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index cb4bc02c9..c82f1a34c 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -203,8 +203,9 @@ start(SockData, Opts) -> ?SUPERVISOR_START. start_link(SockData, Opts) -> - ?GEN_FSM:start_link(ejabberd_c2s, [SockData, Opts], - fsm_limit_opts(Opts) ++ ?FSMOPTS). + (?GEN_FSM):start_link(ejabberd_c2s, + [SockData, Opts], + fsm_limit_opts(Opts) ++ ?FSMOPTS). socket_type() -> xml_stream. @@ -256,13 +257,6 @@ stop(FsmRef) -> (?GEN_FSM):send_event(FsmRef, closed). %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- -%%---------------------------------------------------------------------- -%% Func: init/1 -%% Returns: {ok, StateName, StateData} | -%% {ok, StateName, StateData, Timeout} | -%% ignore | -%% {stop, StopReason} -%%---------------------------------------------------------------------- init([{SockMod, Socket}, Opts]) -> Access = case lists:keysearch(access, 1, Opts) of {value, {_, A}} -> A; @@ -350,36 +344,29 @@ get_subscribed(FsmRef) -> (?GEN_FSM):sync_send_all_state_event(FsmRef, get_subscribed, 1000). -%%---------------------------------------------------------------------- -%% Func: StateName/2 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- - wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> DefaultLang = ?MYLANG, case xml:get_attr_s(<<"xmlns:stream">>, Attrs) of ?NS_STREAM -> - Server = - case StateData#state.server of - <<"">> -> - jlib:nameprep(xml:get_attr_s(<<"to">>, Attrs)); - S -> S - end, + Server = + case StateData#state.server of + <<"">> -> + jlib:nameprep(xml:get_attr_s(<<"to">>, Attrs)); + S -> S + end, Lang = case xml:get_attr_s(<<"xml:lang">>, Attrs) of - Lang1 when byte_size(Lang1) =< 35 -> - %% As stated in BCP47, 4.4.1: - %% Protocols or specifications that - %% specify limited buffer sizes for - %% language tags MUST allow for - %% language tags of at least 35 characters. - Lang1; - _ -> - %% Do not store long language tag to - %% avoid possible DoS/flood attacks - <<"">> - end, + Lang1 when byte_size(Lang1) =< 35 -> + %% As stated in BCP47, 4.4.1: + %% Protocols or specifications that + %% specify limited buffer sizes for + %% language tags MUST allow for + %% language tags of at least 35 characters. + Lang1; + _ -> + %% Do not store long language tag to + %% avoid possible DoS/flood attacks + <<"">> + end, IsBlacklistedIP = is_ip_blacklisted(StateData#state.ip, Lang), case lists:member(Server, ?MYHOSTS) of true when IsBlacklistedIP == false -> @@ -392,168 +379,162 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) -> TLS = StateData#state.tls, TLSEnabled = StateData#state.tls_enabled, TLSRequired = StateData#state.tls_required, - SASLState = - cyrsasl:server_new( - <<"jabber">>, Server, <<"">>, [], - fun(U) -> - ejabberd_auth:get_password_with_authmodule( - U, Server) - end, - fun(U, P) -> - ejabberd_auth:check_password_with_authmodule( - U, Server, P) - end, - fun(U, P, D, DG) -> - ejabberd_auth:check_password_with_authmodule( - U, Server, P, D, DG) - end), + SASLState = cyrsasl:server_new( + <<"jabber">>, Server, <<"">>, [], + fun (U) -> + ejabberd_auth:get_password_with_authmodule( + U, Server) + end, + fun (U, P) -> + ejabberd_auth:check_password_with_authmodule( + U, Server, P) + end, + fun (U, P, D, DG) -> + ejabberd_auth:check_password_with_authmodule( + U, Server, P, D, DG) + end), Mechs = case TLSEnabled or not TLSRequired of - true -> - Ms = lists:map(fun (S) -> - #xmlel{name = <<"mechanism">>, - attrs = [], - children = [{xmlcdata, S}]} - end, - cyrsasl:listmech(Server)), - [#xmlel{name = <<"mechanisms">>, - attrs = [{<<"xmlns">>, ?NS_SASL}], - children = Ms}]; - false -> - [] - end, + true -> + Ms = lists:map(fun (S) -> + #xmlel{name = <<"mechanism">>, + attrs = [], + children = [{xmlcdata, S}]} + end, + cyrsasl:listmech(Server)), + [#xmlel{name = <<"mechanisms">>, + attrs = [{<<"xmlns">>, ?NS_SASL}], + children = Ms}]; + false -> + [] + end, SockMod = - (StateData#state.sockmod):get_sockmod( - StateData#state.socket), + (StateData#state.sockmod):get_sockmod(StateData#state.socket), Zlib = StateData#state.zlib, - CompressFeature = - case Zlib andalso - ((SockMod == gen_tcp) orelse - (SockMod == p1_tls)) of - true -> - [#xmlel{name = <<"compression">>, - attrs = [{<<"xmlns">>, ?NS_FEATURE_COMPRESS}], - children = [#xmlel{name = <<"method">>, - attrs = [], - children = [{xmlcdata, <<"zlib">>}]}]}]; - _ -> - [] - end, + CompressFeature = case Zlib andalso + ((SockMod == gen_tcp) orelse (SockMod == p1_tls)) of + true -> + [#xmlel{name = <<"compression">>, + attrs = [{<<"xmlns">>, ?NS_FEATURE_COMPRESS}], + children = [#xmlel{name = <<"method">>, + attrs = [], + children = [{xmlcdata, <<"zlib">>}]}]}]; + _ -> + [] + end, TLSFeature = case (TLS == true) andalso - (TLSEnabled == false) andalso - (SockMod == gen_tcp) of - true -> - case TLSRequired of - true -> - [#xmlel{name = <<"starttls">>, - attrs = [{<<"xmlns">>, ?NS_TLS}], - children = [#xmlel{name = <<"required">>, - attrs = [], - children = []}]}]; - _ -> - [#xmlel{name = <<"starttls">>, - attrs = [{<<"xmlns">>, ?NS_TLS}], - children = []}] - end; - false -> - [] - end, + (TLSEnabled == false) andalso + (SockMod == gen_tcp) of + true -> + case TLSRequired of + true -> + [#xmlel{name = <<"starttls">>, + attrs = [{<<"xmlns">>, ?NS_TLS}], + children = [#xmlel{name = <<"required">>, + attrs = [], + children = []}]}]; + _ -> + [#xmlel{name = <<"starttls">>, + attrs = [{<<"xmlns">>, ?NS_TLS}], + children = []}] + end; + false -> + [] + end, StreamFeatures1 = TLSFeature ++ CompressFeature ++ Mechs, StreamFeatures = ejabberd_hooks:run_fold(c2s_stream_features, - Server, StreamFeatures1, [Server]), + Server, StreamFeatures1, [Server]), send_element(StateData, - #xmlel{name = <<"stream:features">>, - attrs = [], - children = - StreamFeatures}), + #xmlel{name = <<"stream:features">>, + attrs = [], + children = StreamFeatures}), fsm_next_state(wait_for_feature_request, - StateData#state{ - server = Server, - sasl_state = SASLState, - lang = Lang}); + StateData#state{server = Server, + sasl_state = SASLState, + lang = Lang}); _ -> case StateData#state.resource of - <<"">> -> - RosterVersioningFeature = - ejabberd_hooks:run_fold(roster_get_versioning_feature, - Server, [], - [Server]), - StreamManagementFeature = - case stream_mgmt_enabled(StateData) of - true -> - [#xmlel{name = <<"sm">>, - attrs = [{<<"xmlns">>, ?NS_STREAM_MGMT_2}], - children = []}, - #xmlel{name = <<"sm">>, - attrs = [{<<"xmlns">>, ?NS_STREAM_MGMT_3}], - children = []}]; - false -> - [] + <<"">> -> + RosterVersioningFeature = + ejabberd_hooks:run_fold(roster_get_versioning_feature, + Server, [], + [Server]), + StreamManagementFeature = + case stream_mgmt_enabled(StateData) of + true -> + [#xmlel{name = <<"sm">>, + attrs = [{<<"xmlns">>, ?NS_STREAM_MGMT_2}], + children = []}, + #xmlel{name = <<"sm">>, + attrs = [{<<"xmlns">>, ?NS_STREAM_MGMT_3}], + children = []}]; + false -> + [] end, - StreamFeatures1 = [#xmlel{name = <<"bind">>, - attrs = [{<<"xmlns">>, ?NS_BIND}], - children = []}, - #xmlel{name = <<"session">>, - attrs = [{<<"xmlns">>, ?NS_SESSION}], - children = []}] - ++ - RosterVersioningFeature ++ - StreamManagementFeature ++ - ejabberd_hooks:run_fold(c2s_post_auth_features, - Server, [], [Server]), - StreamFeatures = ejabberd_hooks:run_fold(c2s_stream_features, - Server, StreamFeatures1, [Server]), - send_element(StateData, - #xmlel{name = <<"stream:features">>, - attrs = [], - children = StreamFeatures}), - fsm_next_state(wait_for_bind, - StateData#state{server = Server, lang = Lang}); - _ -> - send_element(StateData, - #xmlel{name = <<"stream:features">>, - attrs = [], - children = []}), - fsm_next_state(wait_for_session, - StateData#state{server = Server, lang = Lang}) + StreamFeatures1 = [#xmlel{name = <<"bind">>, + attrs = [{<<"xmlns">>, ?NS_BIND}], + children = []}, + #xmlel{name = <<"session">>, + attrs = [{<<"xmlns">>, ?NS_SESSION}], + children = []}] + ++ + RosterVersioningFeature ++ + StreamManagementFeature ++ + ejabberd_hooks:run_fold(c2s_post_auth_features, + Server, [], [Server]), + StreamFeatures = ejabberd_hooks:run_fold(c2s_stream_features, + Server, StreamFeatures1, [Server]), + send_element(StateData, + #xmlel{name = <<"stream:features">>, + attrs = [], + children = StreamFeatures}), + fsm_next_state(wait_for_bind, + StateData#state{server = Server, lang = Lang}); + _ -> + send_element(StateData, + #xmlel{name = <<"stream:features">>, + attrs = [], + children = []}), + fsm_next_state(wait_for_session, + StateData#state{server = Server, lang = Lang}) end end; - _ -> - send_header(StateData, Server, <<"">>, DefaultLang), - if not StateData#state.tls_enabled and - StateData#state.tls_required -> - send_element(StateData, + _ -> + send_header(StateData, Server, <<"">>, DefaultLang), + if not StateData#state.tls_enabled and + StateData#state.tls_required -> + send_element(StateData, ?POLICY_VIOLATION_ERR(Lang, - <<"Use of STARTTLS required">>)), - send_trailer(StateData), - {stop, normal, StateData}; - true -> - fsm_next_state(wait_for_auth, + <<"Use of STARTTLS required">>)), + send_trailer(StateData), + {stop, normal, StateData}; + true -> + fsm_next_state(wait_for_auth, StateData#state{server = Server, - lang = Lang}) - end + lang = Lang}) + end + end; + true -> + IP = StateData#state.ip, + {true, LogReason, ReasonT} = IsBlacklistedIP, + ?INFO_MSG("Connection attempt from blacklisted IP ~s: ~s", + [jlib:ip_to_list(IP), LogReason]), + send_header(StateData, Server, <<"">>, DefaultLang), + send_element(StateData, ?POLICY_VIOLATION_ERR(Lang, ReasonT)), + send_trailer(StateData), + {stop, normal, StateData}; + _ -> + send_header(StateData, ?MYNAME, <<"">>, DefaultLang), + send_element(StateData, ?HOST_UNKNOWN_ERR), + send_trailer(StateData), + {stop, normal, StateData} end; - true -> - IP = StateData#state.ip, - {true, LogReason, ReasonT} = IsBlacklistedIP, - ?INFO_MSG("Connection attempt from blacklisted IP ~s: ~s", - [jlib:ip_to_list(IP), LogReason]), - send_header(StateData, Server, <<"">>, DefaultLang), - send_element(StateData, ?POLICY_VIOLATION_ERR(Lang, ReasonT)), - send_trailer(StateData), - {stop, normal, StateData}; _ -> send_header(StateData, ?MYNAME, <<"">>, DefaultLang), - send_element(StateData, ?HOST_UNKNOWN_ERR), + send_element(StateData, ?INVALID_NS_ERR), send_trailer(StateData), {stop, normal, StateData} - end; - _ -> - send_header(StateData, ?MYNAME, <<"">>, DefaultLang), - send_element(StateData, ?INVALID_NS_ERR), - send_trailer(StateData), - {stop, normal, StateData} end; wait_for_stream(timeout, StateData) -> {stop, normal, StateData}; @@ -574,151 +555,148 @@ wait_for_stream(closed, StateData) -> {stop, normal, StateData}. wait_for_auth({xmlstreamelement, #xmlel{name = Name} = El}, StateData) - when ?IS_STREAM_MGMT_TAG(Name) -> + when ?IS_STREAM_MGMT_TAG(Name) -> fsm_next_state(wait_for_auth, dispatch_stream_mgmt(El, StateData)); wait_for_auth({xmlstreamelement, El}, StateData) -> case is_auth_packet(El) of - {auth, _ID, get, {U, _, _, _}} -> - #xmlel{name = Name, attrs = Attrs} = - jlib:make_result_iq_reply(El), - case U of - <<"">> -> UCdata = []; - _ -> UCdata = [{xmlcdata, U}] - end, - Res = case - ejabberd_auth:plain_password_required(StateData#state.server) + {auth, _ID, get, {U, _, _, _}} -> + #xmlel{name = Name, attrs = Attrs} = jlib:make_result_iq_reply(El), + case U of + <<"">> -> UCdata = []; + _ -> UCdata = [{xmlcdata, U}] + end, + Res = case + ejabberd_auth:plain_password_required(StateData#state.server) + of + false -> + #xmlel{name = Name, attrs = Attrs, + children = + [#xmlel{name = <<"query">>, + attrs = [{<<"xmlns">>, ?NS_AUTH}], + children = + [#xmlel{name = <<"username">>, + attrs = [], + children = UCdata}, + #xmlel{name = <<"password">>, + attrs = [], children = []}, + #xmlel{name = <<"digest">>, + attrs = [], children = []}, + #xmlel{name = <<"resource">>, + attrs = [], + children = []}]}]}; + true -> + #xmlel{name = Name, attrs = Attrs, + children = + [#xmlel{name = <<"query">>, + attrs = [{<<"xmlns">>, ?NS_AUTH}], + children = + [#xmlel{name = <<"username">>, + attrs = [], + children = UCdata}, + #xmlel{name = <<"password">>, + attrs = [], children = []}, + #xmlel{name = <<"resource">>, + attrs = [], + children = []}]}]} + end, + send_element(StateData, Res), + fsm_next_state(wait_for_auth, StateData); + {auth, _ID, set, {_U, _P, _D, <<"">>}} -> + Err = jlib:make_error_reply(El, + ?ERR_AUTH_NO_RESOURCE_PROVIDED((StateData#state.lang))), + send_element(StateData, Err), + fsm_next_state(wait_for_auth, StateData); + {auth, _ID, set, {U, P, D, R}} -> + JID = jlib:make_jid(U, StateData#state.server, R), + case JID /= error andalso + acl:match_rule(StateData#state.server, + StateData#state.access, JID) + == allow + of + true -> + DGen = fun (PW) -> + p1_sha:sha(<<(StateData#state.streamid)/binary, PW/binary>>) + end, + case ejabberd_auth:check_password_with_authmodule(U, + StateData#state.server, + P, D, DGen) of - false -> - #xmlel{name = Name, attrs = Attrs, - children = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_AUTH}], - children = - [#xmlel{name = <<"username">>, - attrs = [], - children = UCdata}, - #xmlel{name = <<"password">>, - attrs = [], children = []}, - #xmlel{name = <<"digest">>, - attrs = [], children = []}, - #xmlel{name = <<"resource">>, - attrs = [], - children = []}]}]}; - true -> - #xmlel{name = Name, attrs = Attrs, - children = - [#xmlel{name = <<"query">>, - attrs = [{<<"xmlns">>, ?NS_AUTH}], - children = - [#xmlel{name = <<"username">>, - attrs = [], - children = UCdata}, - #xmlel{name = <<"password">>, - attrs = [], children = []}, - #xmlel{name = <<"resource">>, - attrs = [], - children = []}]}]} - end, - send_element(StateData, Res), - fsm_next_state(wait_for_auth, StateData); - {auth, _ID, set, {_U, _P, _D, <<"">>}} -> - Err = jlib:make_error_reply(El, - ?ERR_AUTH_NO_RESOURCE_PROVIDED((StateData#state.lang))), - send_element(StateData, Err), - fsm_next_state(wait_for_auth, StateData); - {auth, _ID, set, {U, P, D, R}} -> - JID = jlib:make_jid(U, StateData#state.server, R), - case JID /= error andalso - acl:match_rule(StateData#state.server, - StateData#state.access, JID) - == allow - of - true -> - DGen = fun (PW) -> - p1_sha:sha(<<(StateData#state.streamid)/binary, PW/binary>>) - end, - case ejabberd_auth:check_password_with_authmodule(U, - StateData#state.server, - P, D, DGen) - of - {true, AuthModule} -> - ?INFO_MSG("(~w) Accepted legacy authentication for ~s by ~p from ~s", - [StateData#state.socket, - jlib:jid_to_string(JID), AuthModule, - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [true, U, StateData#state.server, - StateData#state.ip]), - Conn = get_conn_type(StateData), - Info = [{ip, StateData#state.ip}, {conn, Conn}, + {true, AuthModule} -> + ?INFO_MSG("(~w) Accepted legacy authentication for ~s by ~p from ~s", + [StateData#state.socket, + jlib:jid_to_string(JID), AuthModule, + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [true, U, StateData#state.server, + StateData#state.ip]), + Conn = get_conn_type(StateData), + Info = [{ip, StateData#state.ip}, {conn, Conn}, {auth_module, AuthModule}], - Res = jlib:make_result_iq_reply( - El#xmlel{children = []}), - send_element(StateData, Res), - ejabberd_sm:open_session(StateData#state.sid, U, - StateData#state.server, R, - Info), - change_shaper(StateData, JID), - {Fs, Ts} = - ejabberd_hooks:run_fold(roster_get_subscription_lists, - StateData#state.server, - {[], []}, - [U, - StateData#state.server]), - LJID = - jlib:jid_tolower(jlib:jid_remove_resource(JID)), - Fs1 = [LJID | Fs], - Ts1 = [LJID | Ts], - PrivList = ejabberd_hooks:run_fold(privacy_get_user_list, - StateData#state.server, - #userlist{}, - [U, StateData#state.server]), - NewStateData = StateData#state{user = U, - resource = R, - jid = JID, - conn = Conn, - auth_module = AuthModule, - pres_f = (?SETS):from_list(Fs1), - pres_t = (?SETS):from_list(Ts1), - privacy_list = PrivList}, - fsm_next_state(session_established, NewStateData); - _ -> - ?INFO_MSG("(~w) Failed legacy authentication for ~s from ~s", - [StateData#state.socket, - jlib:jid_to_string(JID), - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [false, U, StateData#state.server, - StateData#state.ip]), - Err = jlib:make_error_reply(El, ?ERR_NOT_AUTHORIZED), - send_element(StateData, Err), - fsm_next_state(wait_for_auth, StateData) - end; - _ -> - if JID == error -> - ?INFO_MSG("(~w) Forbidden legacy authentication " - "for username '~s' with resource '~s'", - [StateData#state.socket, U, R]), - Err = jlib:make_error_reply(El, ?ERR_JID_MALFORMED), - send_element(StateData, Err), - fsm_next_state(wait_for_auth, StateData); - true -> - ?INFO_MSG("(~w) Forbidden legacy authentication " - "for ~s from ~s", - [StateData#state.socket, - jlib:jid_to_string(JID), - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), - ejabberd_hooks:run(c2s_auth_result, StateData#state.server, - [false, U, StateData#state.server, - StateData#state.ip]), - Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), - send_element(StateData, Err), - fsm_next_state(wait_for_auth, StateData) - end - end; - _ -> - process_unauthenticated_stanza(StateData, El), - fsm_next_state(wait_for_auth, StateData) + Res = jlib:make_result_iq_reply( + El#xmlel{children = []}), + send_element(StateData, Res), + ejabberd_sm:open_session(StateData#state.sid, U, + StateData#state.server, R, + Info), + change_shaper(StateData, JID), + {Fs, Ts} = + ejabberd_hooks:run_fold(roster_get_subscription_lists, + StateData#state.server, + {[], []}, + [U, StateData#state.server]), + LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)), + Fs1 = [LJID | Fs], + Ts1 = [LJID | Ts], + PrivList = ejabberd_hooks:run_fold(privacy_get_user_list, + StateData#state.server, + #userlist{}, + [U, StateData#state.server]), + NewStateData = StateData#state{user = U, + resource = R, + jid = JID, + conn = Conn, + auth_module = AuthModule, + pres_f = (?SETS):from_list(Fs1), + pres_t = (?SETS):from_list(Ts1), + privacy_list = PrivList}, + fsm_next_state(session_established, NewStateData); + _ -> + ?INFO_MSG("(~w) Failed legacy authentication for ~s from ~s", + [StateData#state.socket, + jlib:jid_to_string(JID), + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [false, U, StateData#state.server, + StateData#state.ip]), + Err = jlib:make_error_reply(El, ?ERR_NOT_AUTHORIZED), + send_element(StateData, Err), + fsm_next_state(wait_for_auth, StateData) + end; + _ -> + if JID == error -> + ?INFO_MSG("(~w) Forbidden legacy authentication " + "for username '~s' with resource '~s'", + [StateData#state.socket, U, R]), + Err = jlib:make_error_reply(El, ?ERR_JID_MALFORMED), + send_element(StateData, Err), + fsm_next_state(wait_for_auth, StateData); + true -> + ?INFO_MSG("(~w) Forbidden legacy authentication " + "for ~s from ~s", + [StateData#state.socket, + jlib:jid_to_string(JID), + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ejabberd_hooks:run(c2s_auth_result, StateData#state.server, + [false, U, StateData#state.server, + StateData#state.ip]), + Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), + send_element(StateData, Err), + fsm_next_state(wait_for_auth, StateData) + end + end; + _ -> + process_unauthenticated_stanza(StateData, El), + fsm_next_state(wait_for_auth, StateData) end; wait_for_auth(timeout, StateData) -> {stop, normal, StateData}; @@ -786,10 +764,10 @@ wait_for_feature_request({xmlstreamelement, El}, fsm_next_state(wait_for_sasl_response, StateData#state{sasl_state = NewSASLState}); {error, Error, Username} -> - ?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s", - [StateData#state.socket, - Username, StateData#state.server, - ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), + ?INFO_MSG("(~w) Failed authentication for ~s@~s from ~s", + [StateData#state.socket, + Username, StateData#state.server, + ejabberd_config:may_hide_data(jlib:ip_to_list(StateData#state.ip))]), ejabberd_hooks:run(c2s_auth_result, StateData#state.server, [false, Username, StateData#state.server, StateData#state.ip]), @@ -1121,46 +1099,45 @@ wait_for_session({xmlstreamelement, El}, StateData) -> R = NewStateData#state.resource, JID = NewStateData#state.jid, case acl:match_rule(NewStateData#state.server, - NewStateData#state.access, JID) of + NewStateData#state.access, JID) of allow -> ?INFO_MSG("(~w) Opened session for ~s", - [NewStateData#state.socket, - jlib:jid_to_string(JID)]), + [NewStateData#state.socket, jlib:jid_to_string(JID)]), Res = jlib:make_result_iq_reply(El#xmlel{children = []}), NewState = send_stanza(NewStateData, Res), change_shaper(NewState, JID), {Fs, Ts} = ejabberd_hooks:run_fold( - roster_get_subscription_lists, - NewState#state.server, - {[], []}, - [U, NewState#state.server]), + roster_get_subscription_lists, + NewState#state.server, + {[], []}, + [U, NewState#state.server]), LJID = jlib:jid_tolower(jlib:jid_remove_resource(JID)), Fs1 = [LJID | Fs], Ts1 = [LJID | Ts], PrivList = ejabberd_hooks:run_fold( - privacy_get_user_list, NewState#state.server, - #userlist{}, - [U, NewState#state.server]), + privacy_get_user_list, + NewState#state.server, + #userlist{}, + [U, NewState#state.server]), Conn = get_conn_type(NewState), Info = [{ip, NewState#state.ip}, {conn, Conn}, {auth_module, NewState#state.auth_module}], ejabberd_sm:open_session( - NewState#state.sid, U, NewState#state.server, R, Info), - UpdatedStateData = - NewState#state{ - conn = Conn, - pres_f = ?SETS:from_list(Fs1), - pres_t = ?SETS:from_list(Ts1), - privacy_list = PrivList}, + NewState#state.sid, U, NewState#state.server, R, Info), + UpdatedStateData = + NewState#state{ + conn = Conn, + pres_f = ?SETS:from_list(Fs1), + pres_t = ?SETS:from_list(Ts1), + privacy_list = PrivList}, fsm_next_state_pack(session_established, - UpdatedStateData); + UpdatedStateData); _ -> ejabberd_hooks:run(forbidden_session_hook, - NewStateData#state.server, [JID]), + NewStateData#state.server, [JID]), ?INFO_MSG("(~w) Forbidden session for ~s", - [NewStateData#state.socket, - jlib:jid_to_string(JID)]), + [NewStateData#state.socket, jlib:jid_to_string(JID)]), Err = jlib:make_error_reply(El, ?ERR_NOT_ALLOWED), send_element(NewStateData, Err), fsm_next_state(wait_for_session, NewStateData) @@ -1168,7 +1145,6 @@ wait_for_session({xmlstreamelement, El}, StateData) -> _ -> fsm_next_state(wait_for_session, NewStateData) end; - wait_for_session(timeout, StateData) -> {stop, normal, StateData}; wait_for_session({xmlstreamend, _Name}, StateData) -> @@ -1230,8 +1206,7 @@ session_established(closed, #state{mgmt_state = active} = StateData) -> session_established(closed, StateData) -> {stop, normal, StateData}. -%% Process packets sent by user (coming from user on c2s XMPP -%% connection) +%% Process packets sent by user (coming from user on c2s XMPP connection) session_established2(El, StateData) -> #xmlel{name = Name, attrs = Attrs} = El, NewStateData = update_num_stanzas_in(StateData, El), @@ -1323,37 +1298,9 @@ wait_for_resume(Event, StateData) -> ?DEBUG("Ignoring event while waiting for resumption: ~p", [Event]), fsm_next_state(wait_for_resume, StateData). -%%---------------------------------------------------------------------- -%% Func: StateName/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {reply, Reply, NextStateName, NextStateData} | -%% {reply, Reply, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} | -%% {stop, Reason, Reply, NewStateData} -%%---------------------------------------------------------------------- -%state_name(Event, From, StateData) -> -% Reply = ok, -% {reply, Reply, state_name, StateData}. - -%%---------------------------------------------------------------------- -%% Func: handle_event/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> fsm_next_state(StateName, StateData). -%%---------------------------------------------------------------------- -%% Func: handle_sync_event/4 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {reply, Reply, NextStateName, NextStateData} | -%% {reply, Reply, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} | -%% {stop, Reason, Reply, NewStateData} -%%---------------------------------------------------------------------- handle_sync_event({get_presence}, _From, StateName, StateData) -> User = StateData#state.user, @@ -1386,12 +1333,6 @@ handle_sync_event(_Event, _From, StateName, code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_info/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), ejabberd_hooks:run(c2s_loop_debug, [Text]), @@ -1446,7 +1387,8 @@ handle_info({route, _From, _To, {broadcast, Data}}, jlib:jid_remove_resource(StateData#state.jid), StateData#state.jid, jlib:iq_to_xml(PrivPushIQ)), - NewState = send_stanza(StateData, PrivPushEl), + NewState = send_stanza( + StateData, PrivPushEl), fsm_next_state(StateName, NewState#state{privacy_list = NewPL}) end; @@ -1682,7 +1624,8 @@ handle_info({route, From, To, From, To, Packet, in) of - allow -> {true, Attrs, StateData}; + allow -> + {true, Attrs, StateData}; deny -> case xml:get_attr_s(<<"type">>, Attrs) of <<"error">> -> ok; @@ -1700,14 +1643,14 @@ handle_info({route, From, To, end, if Pass -> Attrs2 = - jlib:replace_from_to_attrs(jlib:jid_to_string(From), - jlib:jid_to_string(To), NewAttrs), + jlib:replace_from_to_attrs(jlib:jid_to_string(From), + jlib:jid_to_string(To), NewAttrs), FixedPacket0 = #xmlel{name = Name, attrs = Attrs2, children = Els}, FixedPacket = ejabberd_hooks:run_fold( - user_receive_packet, - NewState#state.server, - FixedPacket0, - [NewState, NewState#state.jid, From, To]), + user_receive_packet, + NewState#state.server, + FixedPacket0, + [NewState, NewState#state.jid, From, To]), SentStateData = send_packet(NewState, FixedPacket), ejabberd_hooks:run(c2s_loop_debug, [{route, From, To, Packet}]), fsm_next_state(StateName, SentStateData); @@ -1798,23 +1741,11 @@ handle_info(Info, StateName, StateData) -> ?ERROR_MSG("Unexpected info: ~p", [Info]), fsm_next_state(StateName, StateData). - -%%---------------------------------------------------------------------- -%% Func: print_state/1 -%% Purpose: Prepare the state to be printed on error log -%% Returns: State to print -%%---------------------------------------------------------------------- print_state(State = #state{pres_t = T, pres_f = F, pres_a = A}) -> - State#state{pres_t = {pres_t, ?SETS:size(T)}, - pres_f = {pres_f, ?SETS:size(F)}, - pres_a = {pres_a, ?SETS:size(A)} - }. + State#state{pres_t = {pres_t, (?SETS):size(T)}, + pres_f = {pres_f, (?SETS):size(F)}, + pres_a = {pres_a, (?SETS):size(A)}}. -%%---------------------------------------------------------------------- -%% Func: terminate/3 -%% Purpose: Shutdown the fsm -%% Returns: any -%%---------------------------------------------------------------------- terminate(_Reason, StateName, StateData) -> case StateData#state.mgmt_state of resumed -> @@ -1986,7 +1917,7 @@ is_auth_packet(El) -> #iq{id = ID, type = Type, xmlns = ?NS_AUTH, sub_el = SubEl} -> #xmlel{children = Els} = SubEl, {auth, ID, Type, - get_auth_tags(Els, <<"">>, <<"">>, <<"">>, <<"">>)}; + get_auth_tags(Els, <<"">>, <<"">>, <<"">>, <<"">>)}; _ -> false end. @@ -2042,12 +1973,11 @@ process_presence_probe(From, To, StateData) -> undefined -> ok; _ -> - Cond = ?SETS:is_element(LFrom, StateData#state.pres_f) - orelse - ((LFrom /= LBFrom) andalso - ?SETS:is_element(LBFrom, StateData#state.pres_f)), - if - Cond -> + Cond = ((?SETS):is_element(LFrom, StateData#state.pres_f) + orelse + ((LFrom /= LBFrom) andalso + (?SETS):is_element(LBFrom, StateData#state.pres_f))), + if Cond -> %% To is the one sending the presence (the probe target) Packet = jlib:add_delay_info(StateData#state.pres_last, To, StateData#state.pres_timestamp), @@ -2283,11 +2213,11 @@ roster_change(IJID, ISubscription, StateData) -> OldIsFrom = (?SETS):is_element(LIJID, StateData#state.pres_f), FSet = if IsFrom -> (?SETS):add_element(LIJID, StateData#state.pres_f); - not IsFrom -> remove_element(LIJID, StateData#state.pres_f) + true -> remove_element(LIJID, StateData#state.pres_f) end, TSet = if IsTo -> (?SETS):add_element(LIJID, StateData#state.pres_t); - not IsTo -> remove_element(LIJID, StateData#state.pres_t) + true -> remove_element(LIJID, StateData#state.pres_t) end, case StateData#state.pres_last of undefined -> @@ -2543,12 +2473,12 @@ check_from(El, FromJID) -> #jid{} -> if (JID#jid.luser == FromJID#jid.luser) and - (JID#jid.lserver == FromJID#jid.lserver) and - (JID#jid.lresource == FromJID#jid.lresource) -> + (JID#jid.lserver == FromJID#jid.lserver) and + (JID#jid.lresource == FromJID#jid.lresource) -> El; (JID#jid.luser == FromJID#jid.luser) and - (JID#jid.lserver == FromJID#jid.lserver) and - (JID#jid.lresource == <<"">>) -> + (JID#jid.lserver == FromJID#jid.lserver) and + (JID#jid.lresource == <<"">>) -> El; true -> 'invalid-from' diff --git a/src/ejabberd_captcha.erl b/src/ejabberd_captcha.erl index 8a1de2ede..8815c4367 100644 --- a/src/ejabberd_captcha.erl +++ b/src/ejabberd_captcha.erl @@ -75,13 +75,6 @@ tref :: reference(), args :: any()}). -%%==================================================================== -%% API -%%==================================================================== -%%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). @@ -276,12 +269,6 @@ create_captcha_x(SID, To, Lang, Limiter, HeadEls, Err -> Err end. -%% @spec (Id::string(), Lang::string()) -> {FormEl, {ImgEl, TextEl, IdEl, KeyEl}} | captcha_not_found -%% where FormEl = xmlelement() -%% ImgEl = xmlelement() -%% TextEl = xmlelement() -%% IdEl = xmlelement() -%% KeyEl = xmlelement() -spec build_captcha_html(binary(), binary()) -> captcha_not_found | {xmlel(), {xmlel(), xmlel(), @@ -330,12 +317,6 @@ build_captcha_html(Id, Lang) -> _ -> captcha_not_found end. -%% @spec (Id::string(), ProvidedKey::string()) -> captcha_valid | captcha_non_valid | captcha_not_found --spec check_captcha(binary(), binary()) -> captcha_not_found | - captcha_valid | - captcha_non_valid. - - -spec process_reply(xmlel()) -> ok | {error, bad_match | not_found | malformed}. process_reply(#xmlel{} = El) -> @@ -405,9 +386,6 @@ process(_Handlers, process(_Handlers, _Request) -> ejabberd_web:error(not_found). -%%==================================================================== -%% gen_server callbacks -%%==================================================================== init([]) -> mnesia:delete_table(captcha), ets:new(captcha, @@ -454,16 +432,6 @@ terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- -%%-------------------------------------------------------------------- -%% Function: create_image() -> {ok, Type, Key, Image} | {error, Reason} -%% Type = "image/png" | "image/jpeg" | "image/gif" -%% Key = string() -%% Image = binary() -%% Reason = atom() -%%-------------------------------------------------------------------- create_image() -> create_image(undefined). create_image(Limiter) -> @@ -596,12 +564,6 @@ is_limited(Limiter) -> end end. -%%-------------------------------------------------------------------- -%% Function: cmd(Cmd) -> Data | {error, Reason} -%% Cmd = string() -%% Data = binary() -%% Description: os:cmd/1 replacement -%%-------------------------------------------------------------------- -define(CMD_TIMEOUT, 5000). -define(MAX_FILE_SIZE, 64 * 1024). @@ -663,6 +625,10 @@ lookup_captcha(Id) -> _ -> {error, enoent} end. +-spec check_captcha(binary(), binary()) -> captcha_not_found | + captcha_valid | + captcha_non_valid. + check_captcha(Id, ProvidedKey) -> case ets:lookup(captcha, Id) of [#captcha{pid = Pid, args = Args, key = ValidKey, diff --git a/src/ejabberd_cluster.erl b/src/ejabberd_cluster.erl new file mode 100644 index 000000000..5c3a0fc5b --- /dev/null +++ b/src/ejabberd_cluster.erl @@ -0,0 +1,53 @@ +%%%---------------------------------------------------------------------- +%%% File : ejabberd_cluster.erl +%%% Author : Christophe Romain +%%% Purpose : Ejabberd clustering management +%%% Created : 7 Oct 2015 by Christophe Romain +%%% +%%% +%%% 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_cluster). + +%% API +-export([get_nodes/0, call/4, multicall/3, multicall/4]). + +-include("ejabberd.hrl"). +-include("logger.hrl"). + +-spec get_nodes() -> [node()]. + +get_nodes() -> + mnesia:system_info(running_db_nodes). + +-spec call(node(), module(), atom(), [any()]) -> any(). + +call(Node, Module, Function, Args) -> + rpc:call(Node, Module, Function, Args, 5000). + +-spec multicall(module(), atom(), [any()]) -> {list(), [node()]}. + +multicall(Module, Function, Args) -> + multicall(get_nodes(), Module, Function, Args). + +-spec multicall([node()], module(), atom(), list()) -> {list(), [node()]}. + +multicall(Nodes, Module, Function, Args) -> + rpc:multicall(Nodes, Module, Function, Args, 5000). + diff --git a/src/ejabberd_commands.erl b/src/ejabberd_commands.erl index 34297e006..c50263286 100644 --- a/src/ejabberd_commands.erl +++ b/src/ejabberd_commands.erl @@ -326,7 +326,7 @@ execute_command(Name, Arguments) -> ) -> any(). %% @spec (AccessCommands, Auth, Name::atom(), Arguments) -> ResultTerm | {error, Error} -%% where +%% where %% AccessCommands = [{Access, CommandNames, Arguments}] %% Auth = {User::string(), Server::string(), Password::string(), Admin::boolean()} %% | noauth @@ -414,7 +414,7 @@ get_tags_commands() -> %% ----------------------------- %% @spec (AccessCommands, Auth, Method, Command, Arguments) -> ok -%% where +%% where %% AccessCommands = [ {Access, CommandNames, Arguments} ] %% Auth = {User::string(), Server::string(), Password::string()} | noauth %% Method = atom() @@ -479,8 +479,8 @@ check_auth(Command, {User, Server, {oauth, Token}, _}) -> check_auth(_Command, {User, Server, Password, _}) when is_binary(Password) -> %% Check the account exists and password is valid case ejabberd_auth:check_password(User, Server, Password) of - true -> {ok, User, Server}; - _ -> throw({error, invalid_account_data}) + true -> {ok, User, Server}; + _ -> throw({error, invalid_account_data}) end. check_access(Command, all, _) @@ -528,9 +528,9 @@ check_access_arguments(Command, ArgumentRestrictions, Arguments) -> tag_arguments(ArgsDefs, Args) -> lists:zipwith( - fun({ArgName, _ArgType}, ArgValue) -> + fun({ArgName, _ArgType}, ArgValue) -> {ArgName, ArgValue} - end, + end, ArgsDefs, Args). diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 0ff1706ae..8f3795cd3 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -192,7 +192,6 @@ env_binary_to_list(Application, Parameter) -> %% Returns a list of plain terms, %% in which the options 'include_config_file' were parsed %% and the terms in those files were included. -%% @spec(string()) -> [term()] %% @spec(iolist()) -> [term()] get_plain_terms_file(File) -> get_plain_terms_file(File, [{include_files, true}]). @@ -844,6 +843,7 @@ 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(mod_pubsub_odbc) -> {mod_pubsub, odbc}; replace_module(Module) -> case is_elixir_module(Module) of true -> expand_elixir_module(Module); diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index dd258833c..70e17b413 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -80,7 +80,7 @@ start() -> end end, Node = list_to_atom(SNode1), - Status = case rpc:call(Node, ?MODULE, process, [Args]) of + Status = case ejabberd_cluster:call(Node, ?MODULE, process, [Args]) of {badrpc, Reason} -> print("Failed RPC connection to the node ~p: ~p~n", [Node, Reason]), @@ -392,7 +392,10 @@ format_result(ElementsTuple, {_Name, {tuple, ElementsDef}}) -> fun({Element, ElementDef}) -> ["\t" | format_result(Element, ElementDef)] end, - ElementsAndDef)]. + ElementsAndDef)]; + +format_result(404, {_Name, _}) -> + make_status(not_found). make_status(ok) -> ?STATUS_SUCCESS; make_status(true) -> ?STATUS_SUCCESS; diff --git a/src/ejabberd_frontend_socket.erl b/src/ejabberd_frontend_socket.erl index b169572b3..ad227b039 100644 --- a/src/ejabberd_frontend_socket.erl +++ b/src/ejabberd_frontend_socket.erl @@ -58,10 +58,6 @@ %%==================================================================== %% API %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- start_link(Module, SockMod, Socket, Opts, Receiver) -> gen_server:start_link(?MODULE, [Module, SockMod, Socket, Opts, Receiver], []). @@ -137,18 +133,10 @@ peername(_FsmRef) -> %%gen_server:call(FsmRef, peername). {ok, {{0, 0, 0, 0}, 0}}. - %%==================================================================== %% gen_server callbacks %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Description: Initiates the server -%%-------------------------------------------------------------------- init([Module, SockMod, Socket, Opts, Receiver]) -> Node = ejabberd_node_groups:get_closest_node(backend), {SockMod2, Socket2} = check_starttls(SockMod, Socket, Receiver, Opts), @@ -159,15 +147,6 @@ init([Module, SockMod, Socket, Opts, Receiver]) -> socket = Socket2, receiver = Receiver}}. -%%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% Description: Handling call messages -%%-------------------------------------------------------------------- handle_call({starttls, TLSOpts}, _From, State) -> {ok, TLSSocket} = p1_tls:tcp_to_tls(State#state.socket, TLSOpts), ejabberd_receiver:starttls(State#state.receiver, TLSSocket), @@ -184,7 +163,6 @@ handle_call({starttls, TLSOpts, Data}, _From, State) -> {reply, Reply, State#state{socket = TLSSocket, sockmod = p1_tls}, ?HIBERNATE_TIMEOUT}; - handle_call({compress, Data}, _From, State) -> {ok, ZlibSocket} = ejabberd_receiver:compress(State#state.receiver, Data), @@ -238,21 +216,9 @@ handle_call(peername, _From, State) -> handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}. -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling cast messages -%%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State, ?HIBERNATE_TIMEOUT}. -%%-------------------------------------------------------------------- -%% Function: handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling all non call/cast messages -%%-------------------------------------------------------------------- handle_info(timeout, State) -> proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]), @@ -260,31 +226,16 @@ handle_info(timeout, State) -> handle_info(_Info, State) -> {noreply, State, ?HIBERNATE_TIMEOUT}. -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description: This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. -%%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} -%% Description: Convert process state when code is changed -%%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. -%%-------------------------------------------------------------------- -%%% Internal functions -%%-------------------------------------------------------------------- check_starttls(SockMod, Socket, Receiver, Opts) -> TLSEnabled = proplists:get_bool(tls, Opts), TLSOpts = lists:filter(fun({certfile, _}) -> true; (_) -> false end, Opts), - if - TLSEnabled -> + if TLSEnabled -> {ok, TLSSocket} = p1_tls:tcp_to_tls(Socket, TLSOpts), ejabberd_receiver:starttls(Receiver, TLSSocket), {p1_tls, TLSSocket}; diff --git a/src/ejabberd_hooks.erl b/src/ejabberd_hooks.erl index d136ba705..dd03e4ca4 100644 --- a/src/ejabberd_hooks.erl +++ b/src/ejabberd_hooks.erl @@ -58,9 +58,6 @@ -include("logger.hrl"). -%% Timeout of 5 seconds in calls to distributed hooks --define(TIMEOUT_DISTRIBUTED_HOOK, 5000). - -record(state, {}). -type local_hook() :: { Seq :: integer(), Module :: atom(), Function :: atom()}. -type distributed_hook() :: { Seq :: integer(), Node :: atom(), Module :: atom(), Function :: atom()}. @@ -310,7 +307,7 @@ run1([], _Hook, _Args) -> %% It is not attempted again in case of failure. Next hook will be executed run1([{_Seq, Node, Module, Function} | Ls], Hook, Args) -> %% MR: Should we have a safe rpc, like we have a safe apply or is bad_rpc enough ? - case rpc:call(Node, Module, Function, Args, ?TIMEOUT_DISTRIBUTED_HOOK) of + case ejabberd_cluster:call(Node, Module, Function, Args) of timeout -> ?ERROR_MSG("Timeout on RPC to ~p~nrunning hook: ~p", [Node, {Hook, Args}]), @@ -344,7 +341,7 @@ run1([{_Seq, Module, Function} | Ls], Hook, Args) -> run_fold1([], _Hook, Val, _Args) -> Val; run_fold1([{_Seq, Node, Module, Function} | Ls], Hook, Val, Args) -> - case rpc:call(Node, Module, Function, [Val | Args], ?TIMEOUT_DISTRIBUTED_HOOK) of + case ejabberd_cluster:call(Node, Module, Function, [Val | Args]) of {badrpc, Reason} -> ?ERROR_MSG("Bad RPC error to ~p: ~p~nrunning hook: ~p", [Node, Reason, {Hook, Args}]), diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl index 4c647ab58..d2649846b 100644 --- a/src/ejabberd_http.erl +++ b/src/ejabberd_http.erl @@ -166,7 +166,8 @@ init({SockMod, Socket}, Opts) -> {error, _} -> State end. -become_controller(_Pid) -> ok. +become_controller(_Pid) -> + ok. socket_type() -> raw. @@ -201,22 +202,20 @@ parse_headers(#state{request_method = Method, trail = Data} = State) -> PktType = case Method of - undefined -> http_bin; - _ -> httph_bin - end, + undefined -> http_bin; + _ -> httph_bin + end, case erlang:decode_packet(PktType, Data, []) of - {ok, Pkt, Rest} -> - NewState = process_header(State#state{trail = Rest}, {ok, Pkt}), + {ok, Pkt, Rest} -> + NewState = process_header(State#state{trail = Rest}, {ok, Pkt}), case NewState#state.end_of_request of - true -> - ok; - _ -> - parse_headers(NewState) + true -> ok; + _ -> parse_headers(NewState) end; - {more, _} -> - receive_headers(State#state{trail = Data}); - _ -> - ok + {more, _} -> + receive_headers(State#state{trail = Data}); + _ -> + ok end. process_header(State, Data) -> @@ -266,10 +265,8 @@ process_header(State, Data) -> 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)}; + 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)}; @@ -322,14 +319,6 @@ get_host_really_served(Default, Provided) -> false -> Default end. -%% @spec (SockMod, HostPort) -> {Host::string(), Port::integer(), TP} -%% where -%% SockMod = gen_tcp | tls -%% HostPort = string() -%% TP = http | https -%% @doc Given a socket and hostport header, return data of transfer protocol. -%% Note that HostPort can be a string of a host like "example.org", -%% or a string of a host and port like "example.org:5280". get_transfer_protocol(SockMod, HostPort) -> [Host | PortList] = str:tokens(HostPort, <<":">>), case {SockMod, PortList} of @@ -416,17 +405,17 @@ 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) -> + 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); @@ -476,7 +465,6 @@ process_request(#state{request_method = Method, end. make_bad_request(State) -> -%% Support for X-Forwarded-From make_xhtml_output(State, 400, [], ejabberd_web:make_xhtml([#xmlel{name = <<"h1">>, attrs = [], @@ -532,13 +520,13 @@ recv_data(State, Len, Acc) -> make_xhtml_output(State, Status, Headers, XHTML) -> Data = case lists:member(html, Headers) of - true -> - iolist_to_binary([?HTML_DOCTYPE, - xml:element_to_binary(XHTML)]); - _ -> - iolist_to_binary([?XHTML_DOCTYPE, - xml:element_to_binary(XHTML)]) - end, + true -> + iolist_to_binary([?HTML_DOCTYPE, + xml:element_to_binary(XHTML)]); + _ -> + iolist_to_binary([?XHTML_DOCTYPE, + xml:element_to_binary(XHTML)]) + end, Headers1 = case lists:keysearch(<<"Content-Type">>, 1, Headers) of diff --git a/src/ejabberd_http_bind.erl b/src/ejabberd_http_bind.erl index 42be52561..de3eb70db 100644 --- a/src/ejabberd_http_bind.erl +++ b/src/ejabberd_http_bind.erl @@ -1,11 +1,27 @@ %%%---------------------------------------------------------------------- %%% File : ejabberd_http_bind.erl %%% Author : Stefan Strigler -%%% Purpose : Implements XMPP over BOSH (XEP-0206) (formerly known as -%%% HTTP Binding) +%%% Purpose : Implements XMPP over BOSH (XEP-0206) %%% Created : 21 Sep 2005 by Stefan Strigler %%% Modified: may 2009 by Mickael Remond, Alexey Schepin -%%% Id : $Id: ejabberd_http_bind.erl 953 2009-05-07 10:40:40Z alexey $ +%%% +%%% +%%% 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_bind). @@ -78,7 +94,7 @@ wait_timer, ctime = 0, timer, - pause=0, + pause = 0, unprocessed_req_list = [], % list of request that have been delayed for proper reordering: {Request, PID} req_list = [], % list of requests (cache) max_inactivity, @@ -132,19 +148,15 @@ -define(PROCESS_DELAY_MAX, 1000). -%% Line copied from mod_http_bind.erl -define(PROCNAME_MHB, ejabberd_mod_http_bind). -%%%---------------------------------------------------------------------- -%%% API -%%%---------------------------------------------------------------------- -%% TODO: If compile with no supervisor option, start the session without -%% supervisor start(XMPPDomain, Sid, Key, IP, HOpts) -> ?DEBUG("Starting session", []), SupervisorProc = gen_mod:get_module_proc(XMPPDomain, ?PROCNAME_MHB), - case catch supervisor:start_child(SupervisorProc, [Sid, Key, IP, HOpts]) of - {ok, Pid} -> {ok, Pid}; + case catch supervisor:start_child(SupervisorProc, + [Sid, Key, IP, HOpts]) + of + {ok, Pid} -> {ok, Pid}; _ -> check_bind_module(XMPPDomain), {error, "Cannot start HTTP bind session"} end. @@ -222,7 +234,7 @@ process_request(Data, IP, HOpts) -> XmppDomain -> NXmppDomain = jlib:nameprep(XmppDomain), Sid = p1_sha:sha(term_to_binary({now(), make_ref()})), - case start(NXmppDomain, Sid, <<"">>, IP, HOpts) of + case start(NXmppDomain, Sid, <<"">>, IP, HOpts) of {error, _} -> {500, ?HEADER, <<" {updated, undefined}. %% Open a database connection to MySQL mysql_connect(Server, Port, DB, Username, Password) -> case p1_mysql_conn:start(binary_to_list(Server), Port, - binary_to_list(Username), binary_to_list(Password), - binary_to_list(DB), fun log/3) + binary_to_list(Username), + binary_to_list(Password), + binary_to_list(DB), fun log/3) of - {ok, Ref} -> - p1_mysql_conn:fetch(Ref, [<<"set names 'utf8';">>], - self()), - {ok, Ref}; - Err -> Err + {ok, Ref} -> + p1_mysql_conn:fetch( + Ref, [<<"set names 'utf8';">>], self()), + {ok, Ref}; + Err -> Err end. %% Convert MySQL query result to Erlang ODBC result formalism @@ -706,7 +703,7 @@ db_opts(Host) -> [odbc, <<"DSN=", Host/binary, ";UID=", Username/binary, ";PWD=", Pass/binary>>]; _ -> - [Type, Server, Port, DB, User, Pass] + [Type, Server, Port, DB, User, Pass] end end. diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl index 3b29aeefe..c5e6a4436 100644 --- a/src/ejabberd_piefxis.erl +++ b/src/ejabberd_piefxis.erl @@ -5,7 +5,6 @@ %%% Created : 17 Jul 2008 by Pablo Polvorin %%%------------------------------------------------------------------- %%% @author Evgeniy Khramtsov -%%% @copyright (C) 2012, Evgeniy Khramtsov %%% @doc %%% %%% @@ -714,31 +713,9 @@ make_xinclude(Fn) -> Base = filename:basename(Fn), io_lib:format("", [Base]). -%%%================================== -%%%% Export user -%% @spec (Fd, Username::string(), Host::string()) -> ok -%% @doc Extract user information and print it. -%% @spec (Username::string(), Host::string()) -> string() -%% @spec (InfoName::atom(), Username::string(), Host::string()) -> string() -%%%================================== -%%%% Interface with ejabberd offline storage -%% Copied from mod_offline.erl and customized -%%%================================== -%%%% Interface with ejabberd private storage -%%%================================== -%%%% Disk file access -%% @spec () -> string() -%% @spec (Dir::string(), FnT::string()) -> string() -%% @spec (FnT::string(), Host::string()) -> FnH::string() -%% @doc Make the filename for the host. -%% Example: ``("20080804-231550", "jabber.example.org") -> "20080804-231550_jabber_example_org.xml"'' -%% @spec (Fn::string()) -> {ok, Fd} -%% @spec (Fd) -> ok -%% @spec (Fd, String::string()) -> ok print(Fd, String) -> -%%%================================== -%%% vim: set filetype=erlang tabstop=8 foldmarker=%%%%,%%%= foldmethod=marker: file:write(Fd, String). opt_type(auth_password_format) -> fun (X) -> X end; opt_type(_) -> [auth_password_format]. + diff --git a/src/ejabberd_receiver.erl b/src/ejabberd_receiver.erl index 9652e5268..cd7c1d31a 100644 --- a/src/ejabberd_receiver.erl +++ b/src/ejabberd_receiver.erl @@ -58,13 +58,6 @@ -define(HIBERNATE_TIMEOUT, 90000). -%%==================================================================== -%% API -%%==================================================================== -%%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- -spec start_link(inet:socket(), atom(), shaper:shaper(), non_neg_integer() | infinity) -> ignore | {error, any()} | @@ -76,10 +69,6 @@ start_link(Socket, SockMod, Shaper, MaxStanzaSize) -> -spec start(inet:socket(), atom(), shaper:shaper()) -> undefined | pid(). -%%-------------------------------------------------------------------- -%% Function: start() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- start(Socket, SockMod, Shaper) -> start(Socket, SockMod, Shaper, infinity). @@ -127,13 +116,6 @@ close(Pid) -> %% gen_server callbacks %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Description: Initiates the server -%%-------------------------------------------------------------------- init([Socket, SockMod, Shaper, MaxStanzaSize]) -> ShaperState = shaper:new(Shaper), Timeout = case SockMod of @@ -145,15 +127,6 @@ init([Socket, SockMod, Shaper, MaxStanzaSize]) -> shaper_state = ShaperState, max_stanza_size = MaxStanzaSize, timeout = Timeout}}. -%%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% Description: Handling call messages -%%-------------------------------------------------------------------- handle_call({starttls, TLSSocket}, _From, #state{xml_stream_state = XMLStreamState, c2s_pid = C2SPid, @@ -163,15 +136,15 @@ handle_call({starttls, TLSSocket}, _From, undefined -> XMLStreamState; _ -> - xml_stream:new(C2SPid, - MaxStanzaSize) + xml_stream:new(C2SPid, MaxStanzaSize) end, NewState = State#state{socket = TLSSocket, sock_mod = p1_tls, xml_stream_state = NewXMLStreamState}, case p1_tls:recv_data(TLSSocket, <<"">>) of {ok, TLSData} -> - {reply, ok, process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT}; + {reply, ok, + process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT}; {error, _Reason} -> {stop, normal, ok, NewState} end; @@ -186,24 +159,23 @@ handle_call({compress, Data}, _From, true -> ok end, close_stream(XMLStreamState), - NewXMLStreamState = xml_stream:new(C2SPid, - MaxStanzaSize), + NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize), NewState = State#state{socket = ZlibSocket, sock_mod = ezlib, xml_stream_state = NewXMLStreamState}, case ezlib:recv_data(ZlibSocket, <<"">>) of {ok, ZlibData} -> - {reply, {ok, ZlibSocket}, - process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT}; - {error, _Reason} -> {stop, normal, ok, NewState} + {reply, {ok, ZlibSocket}, + process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT}; + {error, _Reason} -> + {stop, normal, ok, NewState} end; handle_call(reset_stream, _From, #state{xml_stream_state = XMLStreamState, c2s_pid = C2SPid, max_stanza_size = MaxStanzaSize} = State) -> close_stream(XMLStreamState), - NewXMLStreamState = xml_stream:new(C2SPid, - MaxStanzaSize), + NewXMLStreamState = xml_stream:new(C2SPid, MaxStanzaSize), Reply = ok, {reply, Reply, State#state{xml_stream_state = NewXMLStreamState}, @@ -218,12 +190,6 @@ handle_call({become_controller, C2SPid}, _From, State) -> handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State, ?HIBERNATE_TIMEOUT}. -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling cast messages -%%-------------------------------------------------------------------- handle_cast({change_shaper, Shaper}, State) -> NewShaperState = shaper:new(Shaper), {noreply, State#state{shaper_state = NewShaperState}, @@ -232,12 +198,6 @@ handle_cast(close, State) -> {stop, normal, State}; handle_cast(_Msg, State) -> {noreply, State, ?HIBERNATE_TIMEOUT}. -%%-------------------------------------------------------------------- -%% Function: handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling all non call/cast messages -%%-------------------------------------------------------------------- handle_info({Tag, _TCPSocket, Data}, #state{socket = Socket, sock_mod = SockMod} = State) when (Tag == tcp) or (Tag == ssl) or @@ -285,13 +245,6 @@ handle_info(timeout, State) -> handle_info(_Info, State) -> {noreply, State, ?HIBERNATE_TIMEOUT}. -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description: This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%%-------------------------------------------------------------------- terminate(_Reason, #state{xml_stream_state = XMLStreamState, c2s_pid = C2SPid} = @@ -304,10 +257,6 @@ terminate(_Reason, catch (State#state.sock_mod):close(State#state.socket), ok. -%%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} -%% Description: Convert process state when code is changed -%%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- diff --git a/src/ejabberd_riak.erl b/src/ejabberd_riak.erl index c8084674f..7f89775e0 100644 --- a/src/ejabberd_riak.erl +++ b/src/ejabberd_riak.erl @@ -6,6 +6,8 @@ %%% Created : 29 Dec 2011 by Alexey Shchepin %%% @copyright (C) 2002-2015 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 %%% published by the Free Software Foundation; either version 2 of the diff --git a/src/ejabberd_router.erl b/src/ejabberd_router.erl index 6a56a22ea..53ac7fb4c 100644 --- a/src/ejabberd_router.erl +++ b/src/ejabberd_router.erl @@ -226,7 +226,8 @@ dirty_get_all_domains() -> init([]) -> update_tables(), mnesia:create_table(route, - [{ram_copies, [node()]}, {type, bag}, + [{ram_copies, [node()]}, + {type, bag}, {attributes, record_info(fields, route)}]), mnesia:add_table_copy(route, node(), ram_copies), mnesia:subscribe({table, route, simple}), diff --git a/src/ejabberd_router_multicast.erl b/src/ejabberd_router_multicast.erl index 373d92272..226a34927 100644 --- a/src/ejabberd_router_multicast.erl +++ b/src/ejabberd_router_multicast.erl @@ -3,6 +3,24 @@ %%% Author : Badlop %%% Purpose : Multicast router %%% Created : 11 Aug 2007 by Badlop +%%% +%%% +%%% 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_router_multicast). diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl index b5604eb7c..9923eb121 100644 --- a/src/ejabberd_s2s.erl +++ b/src/ejabberd_s2s.erl @@ -85,13 +85,6 @@ -type temporarily_blocked() :: #temporarily_blocked{}. -%%==================================================================== -%% API -%%==================================================================== -%%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). @@ -162,7 +155,7 @@ remove_connection(FromTo, Pid, Key) -> have_connection(FromTo) -> case catch mnesia:dirty_read(s2s, FromTo) of - [_] -> + [_] -> true; _ -> false @@ -251,51 +244,26 @@ check_peer_certificate(SockMod, Sock, Peer) -> %% gen_server callbacks %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Description: Initiates the server -%%-------------------------------------------------------------------- init([]) -> update_tables(), - mnesia:create_table(s2s, [{ram_copies, [node()]}, {type, bag}, - {attributes, record_info(fields, s2s)}]), + mnesia:create_table(s2s, + [{ram_copies, [node()]}, + {type, bag}, + {attributes, record_info(fields, s2s)}]), mnesia:add_table_copy(s2s, node(), ram_copies), mnesia:subscribe(system), ejabberd_commands:register_commands(commands()), - mnesia:create_table(temporarily_blocked, [{ram_copies, [node()]}, {attributes, record_info(fields, temporarily_blocked)}]), + mnesia:create_table(temporarily_blocked, + [{ram_copies, [node()]}, + {attributes, record_info(fields, temporarily_blocked)}]), {ok, #state{}}. -%%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% Description: Handling call messages -%%-------------------------------------------------------------------- handle_call(_Request, _From, State) -> - Reply = ok, - {reply, Reply, State}. + {reply, ok, State}. -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling cast messages -%%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling all non call/cast messages -%%-------------------------------------------------------------------- handle_info({mnesia_system_event, {mnesia_down, Node}}, State) -> clean_table_from_bad_node(Node), {noreply, State}; @@ -309,27 +277,17 @@ handle_info({route, From, To, Packet}, State) -> {noreply, State}; handle_info(_Info, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description: This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%%-------------------------------------------------------------------- terminate(_Reason, _State) -> ejabberd_commands:unregister_commands(commands()), ok. -%%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} -%% Description: Convert process state when code is changed -%%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- + clean_table_from_bad_node(Node) -> F = fun() -> Es = mnesia:select( @@ -520,7 +478,8 @@ parent_domains(Domain) -> end, [], lists:reverse(str:tokens(Domain, <<".">>))). -send_element(Pid, El) -> Pid ! {send_element, El}. +send_element(Pid, El) -> + Pid ! {send_element, El}. %%%---------------------------------------------------------------------- %%% ejabberd commands @@ -566,10 +525,8 @@ update_tables() -> {'EXIT', _} -> ok end, case lists:member(local_s2s, mnesia:system_info(tables)) of - true -> - mnesia:delete_table(local_s2s); - false -> - ok + true -> mnesia:delete_table(local_s2s); + false -> ok end. %% Check if host is in blacklist or white list diff --git a/src/ejabberd_s2s_in.erl b/src/ejabberd_s2s_in.erl index 99a313ef6..d840c3158 100644 --- a/src/ejabberd_s2s_in.erl +++ b/src/ejabberd_s2s_in.erl @@ -111,9 +111,6 @@ -define(INVALID_XML_ERR, xml:element_to_binary(?SERR_XML_NOT_WELL_FORMED)). -%%%---------------------------------------------------------------------- -%%% API -%%%---------------------------------------------------------------------- start(SockData, Opts) -> ?SUPERVISOR_START. start_link(SockData, Opts) -> @@ -126,13 +123,6 @@ socket_type() -> xml_stream. %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- -%%---------------------------------------------------------------------- -%% Func: init/1 -%% Returns: {ok, StateName, StateData} | -%% {ok, StateName, StateData, Timeout} | -%% ignore | -%% {stop, StopReason} -%%---------------------------------------------------------------------- init([{SockMod, Socket}, Opts]) -> ?DEBUG("started: ~p", [{SockMod, Socket}]), Shaper = case lists:keysearch(shaper, 1, Opts) of @@ -567,20 +557,8 @@ stream_established(closed, StateData) -> % Reply = ok, % {reply, Reply, state_name, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_event/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_sync_event/4 -%% Returns: The associated StateData for this connection -%% {reply, Reply, NextStateName, NextStateData} -%% Reply = {state_infos, [{InfoName::atom(), InfoValue::any()] -%%---------------------------------------------------------------------- handle_sync_event(get_state_infos, _From, StateName, StateData) -> @@ -621,12 +599,6 @@ handle_sync_event(_Event, _From, StateName, code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_info/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), {next_state, StateName, StateData}; @@ -636,11 +608,6 @@ handle_info({timeout, Timer, _}, _StateName, handle_info(_, StateName, StateData) -> {next_state, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: terminate/3 -%% Purpose: Shutdown the fsm -%% Returns: any -%%---------------------------------------------------------------------- terminate(Reason, _StateName, StateData) -> ?DEBUG("terminated: ~p", [Reason]), case Reason of @@ -661,11 +628,6 @@ get_external_hosts(StateData) -> || {{D, _}, established} <- dict:to_list(Connections)] end. -%%---------------------------------------------------------------------- -%% Func: print_state/1 -%% Purpose: Prepare the state to be printed on error log -%% Returns: State to print -%%---------------------------------------------------------------------- print_state(State) -> State. %%%---------------------------------------------------------------------- diff --git a/src/ejabberd_s2s_out.erl b/src/ejabberd_s2s_out.erl index 65a60c402..bc815166f 100644 --- a/src/ejabberd_s2s_out.erl +++ b/src/ejabberd_s2s_out.erl @@ -37,7 +37,7 @@ start_connection/1, terminate_if_waiting_delay/2, stop_connection/1, - transform_options/1]). + transform_options/1]). -export([init/1, open_socket/2, wait_for_stream/2, wait_for_validation/2, wait_for_features/2, @@ -141,13 +141,6 @@ stop_connection(Pid) -> p1_fsm:send_event(Pid, closed). %%% Callback functions from p1_fsm %%%---------------------------------------------------------------------- -%%---------------------------------------------------------------------- -%% Func: init/1 -%% Returns: {ok, StateName, StateData} | -%% {ok, StateName, StateData, Timeout} | -%% ignore | -%% {stop, StopReason} -%%---------------------------------------------------------------------- init([From, Server, Type]) -> process_flag(trap_exit, true), ?DEBUG("started: ~p", [{From, Server, Type}]), @@ -222,12 +215,6 @@ init([From, Server, Type]) -> tls_options = TLSOpts, queue = queue:new(), myname = From, server = Server, new = New, verify = Verify, timer = Timer}}. -%%---------------------------------------------------------------------- -%% Func: StateName/2 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- open_socket(init, StateData) -> log_s2s_out(StateData#state.new, StateData#state.myname, StateData#state.server, StateData#state.tls), @@ -292,8 +279,6 @@ open_socket(timeout, StateData) -> open_socket(_, StateData) -> {next_state, open_socket, StateData}. -%%---------------------------------------------------------------------- -%% IPv4 open_socket1({_, _, _, _} = Addr, Port) -> open_socket2(inet, Addr, Port); %% IPv6 @@ -872,19 +857,7 @@ stream_established(closed, StateData) -> %% Reply = ok, %% {reply, Reply, state_name, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_event/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_event(_Event, StateName, StateData) -> -%%---------------------------------------------------------------------- -%% Func: handle_sync_event/4 -%% Returns: The associated StateData for this connection -%% {reply, Reply, NextStateName, NextStateData} -%% Reply = {state_infos, [{InfoName::atom(), InfoValue::any()] -%%---------------------------------------------------------------------- {next_state, StateName, StateData, get_timeout_interval(StateName)}. @@ -933,12 +906,6 @@ handle_sync_event(_Event, _From, StateName, code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_info/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_info({send_text, Text}, StateName, StateData) -> send_text(StateData, Text), cancel_timer(StateData#state.timer), @@ -995,11 +962,6 @@ handle_info(_, StateName, StateData) -> {next_state, StateName, StateData, get_timeout_interval(StateName)}. -%%---------------------------------------------------------------------- -%% Func: terminate/3 -%% Purpose: Shutdown the fsm -%% Returns: any -%%---------------------------------------------------------------------- terminate(Reason, StateName, StateData) -> ?DEBUG("terminated: ~p", [{Reason, StateName}]), case StateData#state.new of @@ -1018,11 +980,6 @@ terminate(Reason, StateName, StateData) -> end, ok. -%%---------------------------------------------------------------------- -%% Func: print_state/1 -%% Purpose: Prepare the state to be printed on error log -%% Returns: State to print -%%---------------------------------------------------------------------- print_state(State) -> State. %%%---------------------------------------------------------------------- @@ -1328,10 +1285,6 @@ wait_before_reconnect(StateData) -> D1 -> lists:min([D1 * 2, get_max_retry_delay()]) end, Timer = erlang:start_timer(Delay, self(), []), -%% @doc Get the maximum allowed delay for retry to reconnect (in miliseconds). -%% The default value is 5 minutes. -%% The option {s2s_max_retry_delay, Seconds} can be used (in seconds). -%% @spec () -> integer() {next_state, wait_before_retry, StateData#state{timer = Timer, delay_to_retry = Delay, queue = queue:new()}}. diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 58e2f3c65..772f075ec 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -95,10 +95,6 @@ %%==================================================================== %% API %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- -export_type([sid/0]). start() -> @@ -107,8 +103,7 @@ start() -> supervisor:start_child(ejabberd_sup, ChildSpec). start_link() -> - gen_server:start_link({local, ?MODULE}, ?MODULE, [], - []). + gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). -spec route(jid(), jid(), xmlel() | broadcast()) -> ok. @@ -149,6 +144,9 @@ close_session(SID, User, Server, Resource) -> ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.lserver, [SID, JID, Info]). +-spec check_in_subscription(any(), binary(), binary(), + any(), any(), any()) -> any(). + check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) -> case ejabberd_auth:is_user_exists(User, Server) of true -> Acc; @@ -268,6 +266,8 @@ dirty_get_sessions_list() -> Mod = get_sm_backend(), [S#session.usr || S <- Mod:get_sessions()]. +-spec dirty_get_my_sessions_list() -> [#session{}]. + dirty_get_my_sessions_list() -> Mod = get_sm_backend(), [S || S <- Mod:get_sessions(), node(element(2, S#session.sid)) == node()]. @@ -285,20 +285,20 @@ get_all_pids() -> Mod = get_sm_backend(), [element(2, S#session.sid) || S <- Mod:get_sessions()]. +-spec get_vh_session_number(binary()) -> non_neg_integer(). + get_vh_session_number(Server) -> LServer = jlib:nameprep(Server), Mod = get_sm_backend(), length(Mod:get_sessions(LServer)). register_iq_handler(Host, XMLNS, Module, Fun) -> - ejabberd_sm ! - {register_iq_handler, Host, XMLNS, Module, Fun}. + ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun}. -spec register_iq_handler(binary(), binary(), atom(), atom(), list()) -> any(). register_iq_handler(Host, XMLNS, Module, Fun, Opts) -> - ejabberd_sm ! - {register_iq_handler, Host, XMLNS, Module, Fun, Opts}. + ejabberd_sm ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}. -spec unregister_iq_handler(binary(), binary()) -> any(). @@ -310,13 +310,6 @@ unregister_iq_handler(Host, XMLNS) -> %% gen_server callbacks %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Description: Initiates the server -%%-------------------------------------------------------------------- init([]) -> Mod = get_sm_backend(), Mod:init(), @@ -333,32 +326,11 @@ init([]) -> ejabberd_commands:register_commands(commands()), {ok, #state{}}. -%%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% Description: Handling call messages -%%-------------------------------------------------------------------- handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling cast messages -%%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling all non call/cast messages -%%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, State) -> case catch do_route(From, To, Packet) of {'EXIT', Reason} -> @@ -388,27 +360,19 @@ handle_info({unregister_iq_handler, Host, XMLNS}, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description: This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%%-------------------------------------------------------------------- terminate(_Reason, _State) -> ejabberd_commands:unregister_commands(commands()), ok. -%%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} -%% Description: Convert process state when code is changed -%%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- +-spec set_session(sid(), binary(), binary(), binary(), + prio(), info()) -> ok. + set_session(SID, User, Server, Resource, Priority, Info) -> LUser = jlib:nodeprep(User), LServer = jlib:nameprep(Server), diff --git a/src/ejabberd_sm_redis.erl b/src/ejabberd_sm_redis.erl index a92845b81..1a3ce5ab8 100644 --- a/src/ejabberd_sm_redis.erl +++ b/src/ejabberd_sm_redis.erl @@ -131,7 +131,8 @@ get_sessions(LUser, LServer) -> [] end. --spec get_sessions(binary(), binary(), binary()) -> [#session{}]. +-spec get_sessions(binary(), binary(), binary()) -> + [#session{}]. get_sessions(LUser, LServer, LResource) -> USKey = us_to_key({LUser, LServer}), case eredis:q(?PROCNAME, ["HGETALL", USKey]) of diff --git a/src/ejabberd_socket.erl b/src/ejabberd_socket.erl index 29c7774e4..3ebd4cc23 100644 --- a/src/ejabberd_socket.erl +++ b/src/ejabberd_socket.erl @@ -67,15 +67,12 @@ -export_type([socket_state/0, sockmod/0]). --spec start(atom(), sockmod(), socket(), [{atom(), any()}]) -> any(). %%==================================================================== %% API %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: -%% Description: -%%-------------------------------------------------------------------- +-spec start(atom(), sockmod(), socket(), [{atom(), any()}]) -> any(). + start(Module, SockMod, Socket, Opts) -> case Module:socket_type() of xml_stream -> @@ -241,7 +238,3 @@ peername(#socket_state{sockmod = SockMod, _ -> SockMod:peername(Socket) end. -%%==================================================================== -%% Internal functions -%%==================================================================== -%==================================================================== diff --git a/src/ejabberd_system_monitor.erl b/src/ejabberd_system_monitor.erl index fe8c1d2bb..cfe97a73e 100644 --- a/src/ejabberd_system_monitor.erl +++ b/src/ejabberd_system_monitor.erl @@ -32,7 +32,7 @@ -behaviour(gen_server). %% API --export([start_link/0, process_command/3, +-export([start_link/0, process_command/3, register_hook/1, process_remote_command/1]). -export([init/1, handle_call/3, handle_cast/2, @@ -85,6 +85,10 @@ process_command(From, To, Packet) -> _ -> ok end. +register_hook(Host) -> + ejabberd_hooks:add(local_send_to_resource_hook, Host, + ?MODULE, process_command, 50). + %%==================================================================== %% gen_server callbacks %%==================================================================== @@ -100,11 +104,7 @@ init(Opts) -> LH = proplists:get_value(large_heap, Opts), process_flag(priority, high), erlang:system_monitor(self(), [{large_heap, LH}]), - lists:foreach(fun (Host) -> - ejabberd_hooks:add(local_send_to_resource_hook, Host, - ?MODULE, process_command, 50) - end, - ?MYHOSTS), + lists:foreach(fun register_hook/1, ?MYHOSTS), {ok, #state{}}. %%-------------------------------------------------------------------- @@ -245,8 +245,9 @@ s2s_out_info(Pid) -> [<<"Process type: s2s_out">>, case FromTo of [{From, To}] -> - list_to_binary(io_lib:format("\nS2S connection: from ~s to ~s", - [From, To])); + <<"\n", + (io_lib:format("S2S connection: from ~s to ~s", + [From, To]))/binary>>; _ -> <<"">> end, check_send_queue(Pid), <<"\n">>, @@ -310,7 +311,7 @@ help() -> "\n setlh ">>. remote_command(Node, Args, From, To) -> - Message = case rpc:call(Node, ?MODULE, + Message = case ejabberd_cluster:call(Node, ?MODULE, process_remote_command, [Args]) of {badrpc, Reason} -> diff --git a/src/ejabberd_update.erl b/src/ejabberd_update.erl index afcb62225..aebcbd225 100644 --- a/src/ejabberd_update.erl +++ b/src/ejabberd_update.erl @@ -67,9 +67,6 @@ update(ModulesToUpdate) -> {error, Reason} end. -%% OTP R14B03 and older provided release_handler_1:eval_script/3 -%% But OTP R14B04 and newer provide release_handler_1:eval_script/5 -%% Dialyzer reports a call to missing function; don't worry. eval_script(Script, Apps, LibDirs) -> release_handler_1:eval_script(Script, Apps, LibDirs, [], []). @@ -138,17 +135,17 @@ build_script(Dir, UpdatedBeams) -> LowLevelScript, [{ejabberd, "", filename:join(Dir, "..")}]), Check1 = case Check of - {ok, []} -> - ?DEBUG("script: ~p~n", [Script]), - ?DEBUG("low level script: ~p~n", [LowLevelScript]), - ?DEBUG("check: ~p~n", [Check]), - ok; - _ -> - ?ERROR_MSG("script: ~p~n", [Script]), - ?ERROR_MSG("low level script: ~p~n", [LowLevelScript]), - ?ERROR_MSG("check: ~p~n", [Check]), - error - end, + {ok, []} -> + ?DEBUG("script: ~p~n", [Script]), + ?DEBUG("low level script: ~p~n", [LowLevelScript]), + ?DEBUG("check: ~p~n", [Check]), + ok; + _ -> + ?ERROR_MSG("script: ~p~n", [Script]), + ?ERROR_MSG("low level script: ~p~n", [LowLevelScript]), + ?ERROR_MSG("check: ~p~n", [Check]), + error + end, {Script, LowLevelScript, Check1}. %% Copied from Erlang/OTP file: lib/sasl/src/systools.hrl diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl index 7df7ee090..c2a93e433 100644 --- a/src/ejabberd_web_admin.erl +++ b/src/ejabberd_web_admin.erl @@ -1062,8 +1062,9 @@ term_to_string(T) -> %% @spec (T::any(), Cols::integer()) -> {NumLines::integer(), Paragraph::string()} term_to_paragraph(T, Cols) -> - Paragraph = list_to_binary(erl_prettypr:format(erl_syntax:abstract(T), - [{paper, Cols}])), + P1 = erl_syntax:abstract(T), + P2 = erl_prettypr:format(P1, [{paper, Cols}]), + Paragraph = list_to_binary(P2), FieldList = ejabberd_regexp:split(Paragraph, <<"\n">>), NumLines = length(FieldList), {NumLines, Paragraph}. @@ -1799,7 +1800,7 @@ get_node(Host, Node, [], _Query, Lang) -> <<"Modules">>)])] ++ MenuItems2))]; get_node(global, Node, [<<"db">>], Query, Lang) -> - case rpc:call(Node, mnesia, system_info, [tables]) of + case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of {badrpc, _Reason} -> [?XCT(<<"h1">>, <<"RPC Call Error">>)]; Tables -> @@ -1811,7 +1812,7 @@ get_node(global, Node, [<<"db">>], Query, Lang) -> Rows = lists:map(fun (Table) -> STable = iolist_to_binary(atom_to_list(Table)), - TInfo = case rpc:call(Node, mnesia, + TInfo = case ejabberd_cluster:call(Node, mnesia, table_info, [Table, all]) of @@ -2031,7 +2032,7 @@ get_node(global, Node, [<<"backup">>], Query, Lang) -> [?INPUTT(<<"submit">>, <<"import_dir">>, <<"OK">>)])])])])])]; get_node(global, Node, [<<"ports">>], Query, Lang) -> - Ports = rpc:call(Node, ejabberd_config, + Ports = ejabberd_cluster:call(Node, ejabberd_config, get_local_option, [listen, {ejabberd_listener, validate_cfg}, []]), @@ -2045,7 +2046,7 @@ get_node(global, Node, [<<"ports">>], Query, Lang) -> {error, iolist_to_binary(io_lib:format("~p", [Reason]))}; _ -> nothing end, - NewPorts = lists:sort(rpc:call(Node, ejabberd_config, + NewPorts = lists:sort(ejabberd_cluster:call(Node, ejabberd_config, get_local_option, [listen, {ejabberd_listener, validate_cfg}, @@ -2068,7 +2069,7 @@ get_node(global, Node, [<<"ports">>], Query, Lang) -> [node_ports_to_xhtml(NewPorts, Lang)])]; get_node(Host, Node, [<<"modules">>], Query, Lang) when is_binary(Host) -> - Modules = rpc:call(Node, gen_mod, + Modules = ejabberd_cluster:call(Node, gen_mod, loaded_modules_with_opts, [Host]), Res = case catch node_modules_parse_query(Host, Node, Modules, Query) @@ -2077,7 +2078,7 @@ get_node(Host, Node, [<<"modules">>], Query, Lang) {'EXIT', Reason} -> ?INFO_MSG("~p~n", [Reason]), error; _ -> nothing end, - NewModules = lists:sort(rpc:call(Node, gen_mod, + NewModules = lists:sort(ejabberd_cluster:call(Node, gen_mod, loaded_modules_with_opts, [Host])), H1String = list_to_binary(io_lib:format(?T(<<"Modules at ~p">>), [Node])), (?H1GL(H1String, <<"modules-overview">>, @@ -2093,21 +2094,21 @@ get_node(Host, Node, [<<"modules">>], Query, Lang) [{<<"action">>, <<"">>}, {<<"method">>, <<"post">>}], [node_modules_to_xhtml(NewModules, Lang)])]; get_node(global, Node, [<<"stats">>], _Query, Lang) -> - UpTime = rpc:call(Node, erlang, statistics, + UpTime = ejabberd_cluster:call(Node, erlang, statistics, [wall_clock]), UpTimeS = list_to_binary(io_lib:format("~.3f", [element(1, UpTime) / 1000])), - CPUTime = rpc:call(Node, erlang, statistics, [runtime]), + CPUTime = ejabberd_cluster:call(Node, erlang, statistics, [runtime]), CPUTimeS = list_to_binary(io_lib:format("~.3f", [element(1, CPUTime) / 1000])), OnlineUsers = mnesia:table_info(session, size), - TransactionsCommitted = rpc:call(Node, mnesia, + TransactionsCommitted = ejabberd_cluster:call(Node, mnesia, system_info, [transaction_commits]), - TransactionsAborted = rpc:call(Node, mnesia, + TransactionsAborted = ejabberd_cluster:call(Node, mnesia, system_info, [transaction_failures]), - TransactionsRestarted = rpc:call(Node, mnesia, + TransactionsRestarted = ejabberd_cluster:call(Node, mnesia, system_info, [transaction_restarts]), - TransactionsLogged = rpc:call(Node, mnesia, system_info, + TransactionsLogged = ejabberd_cluster:call(Node, mnesia, system_info, [transaction_log_writes]), [?XC(<<"h1">>, list_to_binary(io_lib:format(?T(<<"Statistics of ~p">>), [Node]))), @@ -2142,12 +2143,12 @@ get_node(global, Node, [<<"stats">>], _Query, Lang) -> ?XAC(<<"td">>, [{<<"class">>, <<"alignright">>}], (pretty_string_int(TransactionsLogged)))])])])]; get_node(global, Node, [<<"update">>], Query, Lang) -> - rpc:call(Node, code, purge, [ejabberd_update]), + ejabberd_cluster:call(Node, code, purge, [ejabberd_update]), Res = node_update_parse_query(Node, Query), - rpc:call(Node, code, load_file, [ejabberd_update]), + ejabberd_cluster:call(Node, code, load_file, [ejabberd_update]), {ok, _Dir, UpdatedBeams, Script, LowLevelScript, Check} = - rpc:call(Node, ejabberd_update, update_info, []), + ejabberd_cluster:call(Node, ejabberd_update, update_info, []), Mods = case UpdatedBeams of [] -> ?CT(<<"None">>); _ -> @@ -2216,14 +2217,14 @@ get_node(Host, Node, NPath, Query, Lang) -> node_parse_query(Node, Query) -> case lists:keysearch(<<"restart">>, 1, Query) of {value, _} -> - case rpc:call(Node, init, restart, []) of + case ejabberd_cluster:call(Node, init, restart, []) of {badrpc, _Reason} -> error; _ -> ok end; _ -> case lists:keysearch(<<"stop">>, 1, Query) of {value, _} -> - case rpc:call(Node, init, stop, []) of + case ejabberd_cluster:call(Node, init, stop, []) of {badrpc, _Reason} -> error; _ -> ok end; @@ -2307,35 +2308,35 @@ node_backup_parse_query(Node, Query) -> {value, {_, Path}} -> Res = case Action of <<"store">> -> - rpc:call(Node, mnesia, backup, + ejabberd_cluster:call(Node, mnesia, backup, [binary_to_list(Path)]); <<"restore">> -> - rpc:call(Node, ejabberd_admin, + ejabberd_cluster:call(Node, ejabberd_admin, restore, [Path]); <<"fallback">> -> - rpc:call(Node, mnesia, + ejabberd_cluster:call(Node, mnesia, install_fallback, [binary_to_list(Path)]); <<"dump">> -> - rpc:call(Node, ejabberd_admin, + ejabberd_cluster:call(Node, ejabberd_admin, dump_to_textfile, [Path]); <<"load">> -> - rpc:call(Node, mnesia, + ejabberd_cluster:call(Node, mnesia, load_textfile, [binary_to_list(Path)]); <<"import_piefxis_file">> -> - rpc:call(Node, ejabberd_piefxis, + ejabberd_cluster:call(Node, ejabberd_piefxis, import_file, [Path]); <<"export_piefxis_dir">> -> - rpc:call(Node, ejabberd_piefxis, + ejabberd_cluster:call(Node, ejabberd_piefxis, export_server, [Path]); <<"export_piefxis_host_dir">> -> {value, {_, Host}} = lists:keysearch(<>, 1, Query), - rpc:call(Node, ejabberd_piefxis, + ejabberd_cluster:call(Node, ejabberd_piefxis, export_host, [Path, Host]); <<"export_sql_file">> -> @@ -2343,13 +2344,13 @@ node_backup_parse_query(Node, Query) -> lists:keysearch(<>, 1, Query), - rpc:call(Node, ejd2odbc, + ejabberd_cluster:call(Node, ejd2odbc, export, [Host, Path]); <<"import_file">> -> - rpc:call(Node, ejabberd_admin, + ejabberd_cluster:call(Node, ejabberd_admin, import_file, [Path]); <<"import_dir">> -> - rpc:call(Node, ejabberd_admin, + ejabberd_cluster:call(Node, ejabberd_admin, import_dir, [Path]) end, case Res of @@ -2474,10 +2475,10 @@ node_ports_parse_query(Node, Ports, Query) -> {ok, Tokens, _} = erl_scan:string(binary_to_list(SOpts) ++ "."), {ok, Opts} = erl_parse:parse_term(Tokens), - rpc:call(Node, ejabberd_listener, + ejabberd_cluster:call(Node, ejabberd_listener, delete_listener, [PortIpNetp2, Module1]), - R = rpc:call(Node, ejabberd_listener, + R = ejabberd_cluster:call(Node, ejabberd_listener, add_listener, [PortIpNetp2, Module, Opts]), throw({is_added, R}); @@ -2487,7 +2488,7 @@ node_ports_parse_query(Node, Ports, Query) -> 1, Query) of {value, _} -> - rpc:call(Node, ejabberd_listener, + ejabberd_cluster:call(Node, ejabberd_listener, delete_listener, [PortIpNetp, Module1]), throw(submitted); @@ -2520,7 +2521,7 @@ node_ports_parse_query(Node, Ports, Query) -> {Port2, _SPort, IP2, _SIP, _SSPort, NetProt2, OptsClean} = get_port_data({Port2, STIP2, NetProt2}, Opts), - R = rpc:call(Node, ejabberd_listener, add_listener, + R = ejabberd_cluster:call(Node, ejabberd_listener, add_listener, [{Port2, IP2, NetProt2}, Module, OptsClean]), throw({is_added, R}); _ -> ok @@ -2579,9 +2580,9 @@ node_modules_parse_query(Host, Node, Modules, Query) -> {ok, Tokens, _} = erl_scan:string(binary_to_list(<>)), {ok, Opts} = erl_parse:parse_term(Tokens), - rpc:call(Node, gen_mod, stop_module, + ejabberd_cluster:call(Node, gen_mod, stop_module, [Host, Module]), - rpc:call(Node, gen_mod, start_module, + ejabberd_cluster:call(Node, gen_mod, start_module, [Host, Module, Opts]), throw(submitted); _ -> @@ -2589,7 +2590,7 @@ node_modules_parse_query(Host, Node, Modules, Query) -> 1, Query) of {value, _} -> - rpc:call(Node, gen_mod, stop_module, + ejabberd_cluster:call(Node, gen_mod, stop_module, [Host, Module]), throw(submitted); _ -> ok @@ -2605,7 +2606,7 @@ node_modules_parse_query(Host, Node, Modules, Query) -> Module = jlib:binary_to_atom(SModule), {ok, Tokens, _} = erl_scan:string(binary_to_list(<>)), {ok, Opts} = erl_parse:parse_term(Tokens), - rpc:call(Node, gen_mod, start_module, + ejabberd_cluster:call(Node, gen_mod, start_module, [Host, Module, Opts]), throw(submitted); _ -> ok @@ -2618,7 +2619,7 @@ node_update_parse_query(Node, Query) -> proplists:get_all_values(<<"selected">>, Query), ModulesToUpdate = [jlib:binary_to_atom(M) || M <- ModulesToUpdateStrings], - case rpc:call(Node, ejabberd_update, update, + case ejabberd_cluster:call(Node, ejabberd_update, update, [ModulesToUpdate]) of {ok, _} -> ok; @@ -2893,7 +2894,8 @@ make_menu_item(item, 3, URI, Name, Lang) -> %%%================================== -%%% vim: set foldmethod=marker foldmarker=%%%%,%%%=: opt_type(access) -> fun (V) -> V end; opt_type(_) -> [access]. + +%%% vim: set foldmethod=marker foldmarker=%%%%,%%%=: diff --git a/src/eldap.erl b/src/eldap.erl index dbd561afd..f48b2d840 100644 --- a/src/eldap.erl +++ b/src/eldap.erl @@ -629,27 +629,10 @@ init([Hosts, Port, Rootdn, Passwd, Opts]) -> id = 0, dict = dict:new(), req_q = queue:new()}, 0}. -%%---------------------------------------------------------------------- -%% Func: StateName/2 -%% Called when gen_fsm:send_event/2,3 is invoked (async) -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- connecting(timeout, S) -> {ok, NextState, NewS} = connect_bind(S), {next_state, NextState, NewS}. -%%---------------------------------------------------------------------- -%% Func: StateName/3 -%% Called when gen_fsm:sync_send_event/2,3 is invoked. -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {reply, Reply, NextStateName, NextStateData} | -%% {reply, Reply, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} | -%% {stop, Reason, Reply, NewStateData} -%%---------------------------------------------------------------------- connecting(Event, From, S) -> Q = queue:in({Event, From}, S#eldap.req_q), {next_state, connecting, S#eldap{req_q = Q}}. @@ -678,34 +661,15 @@ handle_event(close, _StateName, S) -> handle_event(_Event, StateName, S) -> {next_state, StateName, S}. -%%---------------------------------------------------------------------- -%% Func: handle_sync_event/4 -%% Called when gen_fsm:sync_send_all_state_event/2,3 is invoked -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {reply, Reply, NextStateName, NextStateData} | -%% {reply, Reply, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} | -%% {stop, Reason, Reply, NewStateData} -%%---------------------------------------------------------------------- handle_sync_event(_Event, _From, StateName, S) -> {reply, {StateName, S}, StateName, S}. -%%---------------------------------------------------------------------- -%% Func: handle_info/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- - %% %% Packets arriving in various states %% handle_info({Tag, _Socket, Data}, connecting, S) when Tag == tcp; Tag == ssl -> - ?DEBUG("tcp packet received when disconnected!~n~p", - [Data]), + ?DEBUG("tcp packet received when disconnected!~n~p", [Data]), {next_state, connecting, S}; handle_info({Tag, _Socket, Data}, wait_bind_response, S) when Tag == tcp; Tag == ssl -> @@ -724,8 +688,7 @@ handle_info({Tag, _Socket, Data}, wait_bind_response, S) {next_state, connecting, close_and_retry(S)} end; handle_info({Tag, _Socket, Data}, StateName, S) - when (StateName == active orelse - StateName == active_bind) + when (StateName == active orelse StateName == active_bind) andalso (Tag == tcp orelse Tag == ssl) -> case catch recvd_packet(Data, S) of {response, Response, RequestType} -> @@ -766,8 +729,7 @@ handle_info({timeout, Timer, {cmd_timeout, Id}}, handle_info({timeout, retry_connect}, connecting, S) -> {ok, NextState, NewS} = connect_bind(S), {next_state, NextState, NewS}; -handle_info({timeout, _Timer, bind_timeout}, - wait_bind_response, S) -> +handle_info({timeout, _Timer, bind_timeout}, wait_bind_response, S) -> {next_state, connecting, close_and_retry(S)}; %% %% Make sure we don't fill the message queue with rubbish @@ -825,16 +787,14 @@ send_command(Command, From, S) -> Message = #'LDAPMessage'{messageID = Id, protocolOp = {Name, Request}}, ?DEBUG("~p~n", [{Name, ejabberd_config:may_hide_data(Request)}]), - {ok, Bytes} = 'ELDAPv3':encode('LDAPMessage', - Message), + {ok, Bytes} = 'ELDAPv3':encode('LDAPMessage', Message), case (S#eldap.sockmod):send(S#eldap.fd, Bytes) of ok -> - Timer = erlang:start_timer(?CMD_TIMEOUT, self(), - {cmd_timeout, Id}), - New_dict = dict:store(Id, - [{Timer, Command, From, Name}], S#eldap.dict), - {ok, S#eldap{id = Id, dict = New_dict}}; - Error -> Error + Timer = erlang:start_timer(?CMD_TIMEOUT, self(), {cmd_timeout, Id}), + New_dict = dict:store(Id, [{Timer, Command, From, Name}], S#eldap.dict), + {ok, S#eldap{id = Id, dict = New_dict}}; + Error -> + Error end. gen_req({search, A}) -> @@ -1148,8 +1108,7 @@ bind_request(Socket, S) -> Message = #'LDAPMessage'{messageID = Id, protocolOp = {bindRequest, Req}}, ?DEBUG("Bind Request Message:~p~n", [ejabberd_config:may_hide_data(Message)]), - {ok, Bytes} = 'ELDAPv3':encode('LDAPMessage', - Message), + {ok, Bytes} = 'ELDAPv3':encode('LDAPMessage', Message), case (S#eldap.sockmod):send(Socket, Bytes) of ok -> {ok, S#eldap{id = Id}}; Error -> Error @@ -1162,24 +1121,6 @@ next_host(Host, Hosts) -> % Find next in turn next_host(Host, Hosts, Hosts). -%%% -------------------------------------------------------------------- -%%% Verify the input data -%%% -------------------------------------------------------------------- -%%% -------------------------------------------------------------------- -%%% Get and Validate the initial configuration -%%% -------------------------------------------------------------------- -%% get_atom(Key, List) -> -%% case lists:keysearch(Key, 1, List) of -%% {value, {Key, Value}} when is_atom(Value) -> -%% Value; -%% {value, {Key, _Value}} -> -%% throw({error, "Bad Value in Config for " ++ atom_to_list(Key)}); -%% false -> -%% throw({error, "No Entry in Config for " ++ atom_to_list(Key)}) -%% end. -%%% -------------------------------------------------------------------- -%%% Other Stuff -%%% -------------------------------------------------------------------- next_host(Host, [Host], Hosts) -> hd(Hosts); % Wrap back to first next_host(Host, [Host | Tail], _Hosts) -> diff --git a/src/gen_iq_handler.erl b/src/gen_iq_handler.erl index c015b8939..2b712aadc 100644 --- a/src/gen_iq_handler.erl +++ b/src/gen_iq_handler.erl @@ -44,9 +44,9 @@ -record(state, {host, module, function}). -%%-type component() :: ejabberd_sm | ejabberd_local. +-type component() :: ejabberd_sm | ejabberd_local. -type type() :: no_queue | one_queue | pos_integer() | parallel. -%%-type opts() :: no_queue | {one_queue, pid()} | {queues, [pid()]} | parallel. +-type opts() :: no_queue | {one_queue, pid()} | {queues, [pid()]} | parallel. %%==================================================================== %% API @@ -62,33 +62,37 @@ start_link(Host, Module, Function) -> add_iq_handler(Component, Host, NS, Module, Function, Type) -> case Type of - no_queue -> - Component:register_iq_handler(Host, NS, Module, - Function, no_queue); - one_queue -> - {ok, Pid} = supervisor:start_child(ejabberd_iq_sup, - [Host, Module, Function]), - Component:register_iq_handler(Host, NS, Module, - Function, {one_queue, Pid}); - N when is_integer(N) -> - Pids = lists:map(fun (_) -> - {ok, Pid} = - supervisor:start_child(ejabberd_iq_sup, - [Host, Module, - Function]), - Pid - end, - lists:seq(1, N)), - Component:register_iq_handler(Host, NS, Module, - Function, {queues, Pids}); - parallel -> - Component:register_iq_handler(Host, NS, Module, - Function, parallel) + no_queue -> + Component:register_iq_handler(Host, NS, Module, + Function, no_queue); + one_queue -> + {ok, Pid} = supervisor:start_child(ejabberd_iq_sup, + [Host, Module, Function]), + Component:register_iq_handler(Host, NS, Module, + Function, {one_queue, Pid}); + N when is_integer(N) -> + Pids = lists:map(fun (_) -> + {ok, Pid} = + supervisor:start_child(ejabberd_iq_sup, + [Host, Module, + Function]), + Pid + end, + lists:seq(1, N)), + Component:register_iq_handler(Host, NS, Module, + Function, {queues, Pids}); + parallel -> + Component:register_iq_handler(Host, NS, Module, + Function, parallel) end. +-spec remove_iq_handler(component(), binary(), binary()) -> any(). + remove_iq_handler(Component, Host, NS) -> Component:unregister_iq_handler(Host, NS). +-spec stop_iq_handler(atom(), atom(), [pid()]) -> any(). + stop_iq_handler(_Module, _Function, Opts) -> case Opts of {one_queue, Pid} -> gen_server:call(Pid, stop); @@ -100,21 +104,25 @@ stop_iq_handler(_Module, _Function, Opts) -> _ -> ok end. +-spec handle(binary(), atom(), atom(), opts(), jid(), jid(), iq()) -> any(). + handle(Host, Module, Function, Opts, From, To, IQ) -> case Opts of - no_queue -> - process_iq(Host, Module, Function, From, To, IQ); - {one_queue, Pid} -> Pid ! {process_iq, From, To, IQ}; - {queues, Pids} -> - Pid = lists:nth(erlang:phash(now(), length(Pids)), - Pids), - Pid ! {process_iq, From, To, IQ}; - parallel -> - spawn(?MODULE, process_iq, + no_queue -> + process_iq(Host, Module, Function, From, To, IQ); + {one_queue, Pid} -> + Pid ! {process_iq, From, To, IQ}; + {queues, Pids} -> + Pid = lists:nth(erlang:phash(now(), length(Pids)), Pids), + Pid ! {process_iq, From, To, IQ}; + parallel -> + spawn(?MODULE, process_iq, [Host, Module, Function, From, To, IQ]); - _ -> todo + _ -> todo end. +-spec process_iq(binary(), atom(), atom(), jid(), jid(), iq()) -> any(). + process_iq(_Host, Module, Function, From, To, IQ) -> case catch Module:Function(From, To, IQ) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); @@ -146,44 +154,16 @@ transform_module_options(Opts) -> %% gen_server callbacks %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Description: Initiates the server -%%-------------------------------------------------------------------- init([Host, Module, Function]) -> {ok, #state{host = Host, module = Module, function = Function}}. -%%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% Description: Handling call messages -%%-------------------------------------------------------------------- handle_call(stop, _From, State) -> Reply = ok, {stop, normal, Reply, State}. -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling cast messages -%%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling all non call/cast messages -%%-------------------------------------------------------------------- handle_info({process_iq, From, To, IQ}, #state{host = Host, module = Module, function = Function} = @@ -192,19 +172,8 @@ handle_info({process_iq, From, To, IQ}, {noreply, State}; handle_info(_Info, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description: This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. -%%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} -%% Description: Convert process state when code is changed -%%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index 42c77f150..8fc2ca79e 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -25,6 +25,7 @@ %%% %%%---------------------------------------------------------------------- -module (mod_carboncopy). + -author ('ecestari@process-one.net'). -protocol({xep, 280, '0.8'}). @@ -112,7 +113,7 @@ iq_handler(From, _To, #iq{type=set, sub_el = #xmlel{name = Operation, children ?INFO_MSG("carbons disabled for user ~s@~s/~s", [U,S,R]), disable(S, U, R) end, - case Result of + case Result of ok -> ?DEBUG("carbons IQ result: ok", []), IQ#iq{type=result, sub_el=[]}; @@ -129,9 +130,8 @@ user_send_packet(Packet, _C2SState, From, To) -> user_receive_packet(Packet, _C2SState, JID, _From, To) -> check_and_forward(JID, To, Packet, received). - -% verifier si le trafic est local -% Modified from original version: + +% Modified from original version: % - registered to the user_send_packet hook, to be called only once even for multicast % - do not support "private" message mode, and do not modify the original packet in any way % - we also replicate "read" notifications @@ -145,8 +145,8 @@ check_and_forward(JID, To, Packet, Direction)-> send_copies(JID, To, Packet, Direction), Packet; true -> - %% stop the hook chain, we don't want mod_logdb to register - %% this message (duplicate) + %% stop the hook chain, we don't want logging modules to duplicates + %% this message {stop, Packet} end; _ -> @@ -156,7 +156,7 @@ check_and_forward(JID, To, Packet, Direction)-> remove_connection(User, Server, Resource, _Status)-> disable(Server, User, Resource), ok. - + %%% Internal %% Direction = received | sent @@ -208,31 +208,31 @@ send_copies(JID, To, Packet, Direction)-> ok. build_forward_packet(JID, Packet, Sender, Dest, Direction, ?NS_CARBONS_2) -> - #xmlel{name = <<"message">>, + #xmlel{name = <<"message">>, attrs = [{<<"xmlns">>, <<"jabber:client">>}, {<<"type">>, message_type(Packet)}, {<<"from">>, jlib:jid_to_string(Sender)}, {<<"to">>, jlib:jid_to_string(Dest)}], - children = [ - #xmlel{name = list_to_binary(atom_to_list(Direction)), + children = [ + #xmlel{name = list_to_binary(atom_to_list(Direction)), attrs = [{<<"xmlns">>, ?NS_CARBONS_2}], children = [ - #xmlel{name = <<"forwarded">>, + #xmlel{name = <<"forwarded">>, attrs = [{<<"xmlns">>, ?NS_FORWARD}], children = [ complete_packet(JID, Packet, Direction)]} ]} ]}; build_forward_packet(JID, Packet, Sender, Dest, Direction, ?NS_CARBONS_1) -> - #xmlel{name = <<"message">>, + #xmlel{name = <<"message">>, attrs = [{<<"xmlns">>, <<"jabber:client">>}, {<<"type">>, message_type(Packet)}, {<<"from">>, jlib:jid_to_string(Sender)}, {<<"to">>, jlib:jid_to_string(Dest)}], - children = [ - #xmlel{name = list_to_binary(atom_to_list(Direction)), + children = [ + #xmlel{name = list_to_binary(atom_to_list(Direction)), attrs = [{<<"xmlns">>, ?NS_CARBONS_1}]}, - #xmlel{name = <<"forwarded">>, + #xmlel{name = <<"forwarded">>, attrs = [{<<"xmlns">>, ?NS_FORWARD}], children = [complete_packet(JID, Packet, Direction)]} ]}. @@ -285,7 +285,7 @@ has_non_empty_body(Packet) -> xml:get_subtag_cdata(Packet, <<"body">>) =/= <<"">>. %% list {resource, cc_version} with carbons enabled for given user and host -list(User, Server)-> +list(User, Server) -> mnesia:dirty_select(?TABLE, [{#carboncopy{us = {User, Server}, resource = '$2', version = '$3'}, [], [{{'$2','$3'}}]}]). diff --git a/src/mod_configure.erl b/src/mod_configure.erl index 6b07c9840..3803ba1c9 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -985,7 +985,7 @@ get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>], case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> - case rpc:call(Node, mnesia, system_info, [tables]) of + case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; Tables -> @@ -1007,7 +1007,7 @@ get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>], ?T(Lang, <<"Choose storage type of tables">>)}]} | lists:map(fun (Table) -> - case rpc:call(Node, mnesia, + case ejabberd_cluster:call(Node, mnesia, table_info, [Table, storage_type]) @@ -1028,7 +1028,7 @@ get_form(Host, case search_running_node(ENode) of false -> {error, ?ERR_ITEM_NOT_FOUND}; Node -> - case rpc:call(Node, gen_mod, loaded_modules, [Host]) of + case ejabberd_cluster:call(Node, gen_mod, loaded_modules, [Host]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; Modules -> @@ -1607,7 +1607,7 @@ set_form(_From, Host, case Vals of [<<"1">>] -> Module = jlib:binary_to_atom(Var), - rpc:call(Node, gen_mod, stop_module, + ejabberd_cluster:call(Node, gen_mod, stop_module, [Host, Module]); _ -> ok end @@ -1634,7 +1634,7 @@ set_form(_From, Host, case erl_parse:parse_term(Tokens) of {ok, Modules} -> lists:foreach(fun ({Module, Args}) -> - rpc:call(Node, gen_mod, + ejabberd_cluster:call(Node, gen_mod, start_module, [Host, Module, Args]) end, @@ -1656,7 +1656,7 @@ set_form(_From, _Host, case lists:keysearch(<<"path">>, 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> - case rpc:call(Node, mnesia, backup, [String]) of + case ejabberd_cluster:call(Node, mnesia, backup, [String]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; @@ -1675,7 +1675,7 @@ set_form(_From, _Host, case lists:keysearch(<<"path">>, 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> - case rpc:call(Node, ejabberd_admin, restore, [String]) + case ejabberd_cluster:call(Node, ejabberd_admin, restore, [String]) of {badrpc, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; @@ -1695,7 +1695,7 @@ set_form(_From, _Host, case lists:keysearch(<<"path">>, 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> - case rpc:call(Node, ejabberd_admin, dump_to_textfile, + case ejabberd_cluster:call(Node, ejabberd_admin, dump_to_textfile, [String]) of {badrpc, _Reason} -> @@ -1715,7 +1715,7 @@ set_form(_From, _Host, case lists:keysearch(<<"path">>, 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> - rpc:call(Node, jd2ejd, import_file, [String]), + ejabberd_cluster:call(Node, jd2ejd, import_file, [String]), {result, []}; _ -> {error, ?ERR_BAD_REQUEST} end @@ -1729,7 +1729,7 @@ set_form(_From, _Host, case lists:keysearch(<<"path">>, 1, XData) of false -> {error, ?ERR_BAD_REQUEST}; {value, {_, [String]}} -> - rpc:call(Node, jd2ejd, import_dir, [String]), + ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]), {result, []}; _ -> {error, ?ERR_BAD_REQUEST} end @@ -1912,7 +1912,6 @@ set_form(From, Host, Server) of [] -> -%% _US = {User, Server}, case get_last_info(User, Server) of not_found -> ?T(Lang, <<"Never">>); {ok, Timestamp, _Status} -> diff --git a/src/mod_fail2ban.erl b/src/mod_fail2ban.erl index 67b705d9a..abfd1273f 100644 --- a/src/mod_fail2ban.erl +++ b/src/mod_fail2ban.erl @@ -1,11 +1,11 @@ %%%------------------------------------------------------------------- %%% @author Evgeny Khramtsov -%%% @copyright (C) 2014, Evgeny Khramtsov %%% @doc %%% %%% @end %%% Created : 15 Aug 2014 by Evgeny Khramtsov %%% +%%% %%% ejabberd, Copyright (C) 2014-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or diff --git a/src/mod_irc.erl b/src/mod_irc.erl index 255118483..31fb31707 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -784,8 +784,6 @@ set_form(ServerHost, Host, From, [], _Lang, XData) -> set_form(_ServerHost, _Host, _, _, _Lang, _XData) -> {error, ?ERR_SERVICE_UNAVAILABLE}. -%% Host = "irc.example.com" -%% ServerHost = "example.com" get_connection_params(Host, From, IRCServer) -> [_ | HostTail] = str:tokens(Host, <<".">>), ServerHost = str:join(HostTail, <<".">>), diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 0c85e7016..7781cff9a 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -43,27 +43,27 @@ -include("mod_muc_room.hrl"). -record(archive_msg, - {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$2', - id = <<>> :: binary() | '_', - timestamp = now() :: erlang:timestamp() | '_' | '$1', - peer = {<<"">>, <<"">>, <<"">>} :: ljid() | '_' | '$3', - bare_peer = {<<"">>, <<"">>, <<"">>} :: ljid() | '_' | '$3', + {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$2', + id = <<>> :: binary() | '_', + timestamp = now() :: erlang:timestamp() | '_' | '$1', + peer = {<<"">>, <<"">>, <<"">>} :: ljid() | '_' | '$3', + bare_peer = {<<"">>, <<"">>, <<"">>} :: ljid() | '_' | '$3', packet = #xmlel{} :: xmlel() | '_', nick = <<"">> :: binary(), type = chat :: chat | groupchat}). -record(archive_prefs, - {us = {<<"">>, <<"">>} :: {binary(), binary()}, - default = never :: never | always | roster, - always = [] :: [ljid()], - never = [] :: [ljid()]}). + {us = {<<"">>, <<"">>} :: {binary(), binary()}, + default = never :: never | always | roster, + always = [] :: [ljid()], + never = [] :: [ljid()]}). %%%=================================================================== %%% API %%%=================================================================== start(Host, Opts) -> IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1, - one_queue), + one_queue), DBType = gen_mod:db_type(Host, Opts), init_db(DBType, Host), init_cache(DBType, Opts), @@ -80,9 +80,9 @@ start(Host, Opts) -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_MAM_1, ?MODULE, process_iq_v0_3, IQDisc), ejabberd_hooks:add(user_receive_packet, Host, ?MODULE, - user_receive_packet, 500), + user_receive_packet, 500), ejabberd_hooks:add(user_send_packet, Host, ?MODULE, - user_send_packet, 500), + user_send_packet, 500), ejabberd_hooks:add(muc_filter_message, Host, ?MODULE, muc_filter_message, 50), ejabberd_hooks:add(muc_process_iq, Host, ?MODULE, @@ -95,21 +95,21 @@ start(Host, Opts) -> init_db(mnesia, _Host) -> mnesia:create_table(archive_msg, - [{disc_only_copies, [node()]}, - {type, bag}, - {attributes, record_info(fields, archive_msg)}]), + [{disc_only_copies, [node()]}, + {type, bag}, + {attributes, record_info(fields, archive_msg)}]), mnesia:create_table(archive_prefs, - [{disc_only_copies, [node()]}, - {attributes, record_info(fields, archive_prefs)}]); + [{disc_only_copies, [node()]}, + {attributes, record_info(fields, archive_prefs)}]); init_db(_, _) -> ok. init_cache(_DBType, Opts) -> MaxSize = gen_mod:get_opt(cache_size, Opts, - fun(I) when is_integer(I), I>0 -> I end, - 1000), + fun(I) when is_integer(I), I>0 -> I end, + 1000), LifeTime = gen_mod:get_opt(cache_life_time, Opts, - fun(I) when is_integer(I), I>0 -> I end, + fun(I) when is_integer(I), I>0 -> I end, timer:hours(1) div 1000), cache_tab:new(archive_prefs, [{max_size, MaxSize}, {life_time, LifeTime}]). @@ -144,9 +144,9 @@ remove_user(User, Server) -> remove_user(LUser, LServer, mnesia) -> US = {LUser, LServer}, F = fun () -> - mnesia:delete({archive_msg, US}), - mnesia:delete({archive_prefs, US}) - end, + mnesia:delete({archive_msg, US}), + mnesia:delete({archive_prefs, US}) + end, mnesia:transaction(F); remove_user(LUser, LServer, odbc) -> SUser = ejabberd_odbc:escape(LUser), @@ -162,25 +162,25 @@ user_receive_packet(Pkt, C2SState, JID, Peer, To) -> LServer = JID#jid.lserver, IsBareCopy = is_bare_copy(JID, To), case should_archive(Pkt) of - true when not IsBareCopy -> - NewPkt = strip_my_archived_tag(Pkt, LServer), + true when not IsBareCopy -> + NewPkt = strip_my_archived_tag(Pkt, LServer), case store_msg(C2SState, NewPkt, LUser, LServer, Peer, recv) of - {ok, ID} -> - Archived = #xmlel{name = <<"archived">>, - attrs = [{<<"by">>, LServer}, - {<<"xmlns">>, ?NS_MAM_TMP}, - {<<"id">>, ID}]}, + {ok, ID} -> + Archived = #xmlel{name = <<"archived">>, + attrs = [{<<"by">>, LServer}, + {<<"xmlns">>, ?NS_MAM_TMP}, + {<<"id">>, ID}]}, StanzaID = #xmlel{name = <<"stanza-id">>, attrs = [{<<"by">>, LServer}, - {<<"xmlns">>, ?NS_SID_0}, - {<<"id">>, ID}]}, + {<<"xmlns">>, ?NS_SID_0}, + {<<"id">>, ID}]}, NewEls = [Archived, StanzaID|NewPkt#xmlel.children], - NewPkt#xmlel{children = NewEls}; - _ -> - NewPkt - end; - _ -> - Pkt + NewPkt#xmlel{children = NewEls}; + _ -> + NewPkt + end; + _ -> + Pkt end. user_send_packet(Pkt, C2SState, JID, Peer) -> @@ -188,12 +188,12 @@ user_send_packet(Pkt, C2SState, JID, Peer) -> LServer = JID#jid.lserver, case should_archive(Pkt) of true -> - NewPkt = strip_my_archived_tag(Pkt, LServer), + NewPkt = strip_my_archived_tag(Pkt, LServer), store_msg(C2SState, jlib:replace_from_to(JID, Peer, NewPkt), LUser, LServer, Peer, send), - NewPkt; - false -> - Pkt + NewPkt; + false -> + Pkt end. muc_filter_message(Pkt, #state{config = Config} = MUCState, @@ -218,23 +218,23 @@ muc_filter_message(Pkt, #state{config = Config} = MUCState, % Query archive v0.2 process_iq_v0_2(#jid{lserver = LServer} = From, - #jid{lserver = LServer} = To, - #iq{type = get, sub_el = #xmlel{name = <<"query">>} = SubEl} = IQ) -> + #jid{lserver = LServer} = To, + #iq{type = get, sub_el = #xmlel{name = <<"query">>} = SubEl} = IQ) -> Fs = lists:flatmap( - fun(#xmlel{name = <<"start">>} = El) -> - [{<<"start">>, [xml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"end">>} = El) -> - [{<<"end">>, [xml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"with">>} = El) -> - [{<<"with">>, [xml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"withroom">>} = El) -> - [{<<"withroom">>, [xml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"withtext">>} = El) -> - [{<<"withtext">>, [xml:get_tag_cdata(El)]}]; - (#xmlel{name = <<"set">>}) -> - [{<<"set">>, SubEl}]; - (_) -> - [] + fun (#xmlel{name = <<"start">>} = El) -> + [{<<"start">>, [xml:get_tag_cdata(El)]}]; + (#xmlel{name = <<"end">>} = El) -> + [{<<"end">>, [xml:get_tag_cdata(El)]}]; + (#xmlel{name = <<"with">>} = El) -> + [{<<"with">>, [xml:get_tag_cdata(El)]}]; + (#xmlel{name = <<"withroom">>} = El) -> + [{<<"withroom">>, [xml:get_tag_cdata(El)]}]; + (#xmlel{name = <<"withtext">>} = El) -> + [{<<"withtext">>, [xml:get_tag_cdata(El)]}]; + (#xmlel{name = <<"set">>}) -> + [{<<"set">>, SubEl}]; + (_) -> + [] end, SubEl#xmlel.children), process_iq(LServer, From, To, IQ, SubEl, Fs, chat); process_iq_v0_2(From, To, IQ) -> @@ -242,8 +242,8 @@ process_iq_v0_2(From, To, IQ) -> % Query archive v0.3 process_iq_v0_3(#jid{lserver = LServer} = From, - #jid{lserver = LServer} = To, - #iq{type = set, sub_el = #xmlel{name = <<"query">>} = SubEl} = IQ) -> + #jid{lserver = LServer} = To, + #iq{type = set, sub_el = #xmlel{name = <<"query">>} = SubEl} = IQ) -> process_iq(LServer, From, To, IQ, SubEl, get_xdata_fields(SubEl), chat); process_iq_v0_3(From, To, IQ) -> process_iq(From, To, IQ). @@ -266,15 +266,15 @@ muc_process_iq(IQ, _MUCState, _From, _To) -> get_xdata_fields(SubEl) -> case {xml:get_subtag_with_xmlns(SubEl, <<"x">>, ?NS_XDATA), - xml:get_subtag_with_xmlns(SubEl, <<"set">>, ?NS_RSM)} of - {#xmlel{} = XData, false} -> - jlib:parse_xdata_submit(XData); - {#xmlel{} = XData, #xmlel{}} -> - [{<<"set">>, SubEl} | jlib:parse_xdata_submit(XData)]; - {false, #xmlel{}} -> - [{<<"set">>, SubEl}]; - {false, false} -> - [] + xml:get_subtag_with_xmlns(SubEl, <<"set">>, ?NS_RSM)} of + {#xmlel{} = XData, false} -> + jlib:parse_xdata_submit(XData); + {#xmlel{} = XData, #xmlel{}} -> + [{<<"set">>, SubEl} | jlib:parse_xdata_submit(XData)]; + {false, #xmlel{}} -> + [{<<"set">>, SubEl}]; + {false, false} -> + [] end. %%%=================================================================== @@ -283,32 +283,32 @@ get_xdata_fields(SubEl) -> % Preference setting (both v0.2 & v0.3) process_iq(#jid{luser = LUser, lserver = LServer}, - #jid{lserver = LServer}, - #iq{type = set, sub_el = #xmlel{name = <<"prefs">>} = SubEl} = IQ) -> + #jid{lserver = LServer}, + #iq{type = set, sub_el = #xmlel{name = <<"prefs">>} = SubEl} = IQ) -> try {case xml:get_tag_attr_s(<<"default">>, SubEl) of - <<"always">> -> always; - <<"never">> -> never; - <<"roster">> -> roster - end, - lists:foldl( - fun(#xmlel{name = <<"always">>, children = Els}, {A, N}) -> - {get_jids(Els) ++ A, N}; - (#xmlel{name = <<"never">>, children = Els}, {A, N}) -> - {A, get_jids(Els) ++ N}; - (_, {A, N}) -> - {A, N} - end, {[], []}, SubEl#xmlel.children)} of - {Default, {Always, Never}} -> - case write_prefs(LUser, LServer, LServer, Default, - lists:usort(Always), lists:usort(Never)) of - ok -> - IQ#iq{type = result, sub_el = []}; - _Err -> - IQ#iq{type = error, - sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} - end + <<"always">> -> always; + <<"never">> -> never; + <<"roster">> -> roster + end, + lists:foldl( + fun(#xmlel{name = <<"always">>, children = Els}, {A, N}) -> + {get_jids(Els) ++ A, N}; + (#xmlel{name = <<"never">>, children = Els}, {A, N}) -> + {A, get_jids(Els) ++ N}; + (_, {A, N}) -> + {A, N} + end, {[], []}, SubEl#xmlel.children)} of + {Default, {Always, Never}} -> + case write_prefs(LUser, LServer, LServer, Default, + lists:usort(Always), lists:usort(Never)) of + ok -> + IQ#iq{type = result, sub_el = []}; + _Err -> + IQ#iq{type = error, + sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} + end catch _:_ -> - IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} + IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} end; process_iq(_, _, #iq{sub_el = SubEl} = IQ) -> IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. @@ -344,64 +344,64 @@ process_iq(LServer, From, To, IQ, SubEl, Fs, MsgType) -> should_archive(#xmlel{name = <<"message">>} = Pkt) -> case {xml:get_attr_s(<<"type">>, Pkt#xmlel.attrs), - xml:get_subtag_cdata(Pkt, <<"body">>)} of - {<<"error">>, _} -> - false; - {<<"groupchat">>, _} -> + xml:get_subtag_cdata(Pkt, <<"body">>)} of + {<<"error">>, _} -> false; - {_, <<>>} -> - %% Empty body - false; - _ -> - true + {<<"groupchat">>, _} -> + false; + {_, <<>>} -> + %% Empty body + false; + _ -> + true end; should_archive(#xmlel{}) -> false. strip_my_archived_tag(Pkt, LServer) -> NewEls = lists:filter( - fun(#xmlel{name = Tag, attrs = Attrs}) - when Tag == <<"archived">>; Tag == <<"stanza-id">> -> - case catch jlib:nameprep( - xml:get_attr_s( - <<"by">>, Attrs)) of - LServer -> - false; - _ -> - true - end; - (_) -> - true - end, Pkt#xmlel.children), + fun(#xmlel{name = Tag, attrs = Attrs}) + when Tag == <<"archived">>; Tag == <<"stanza-id">> -> + case catch jlib:nameprep( + xml:get_attr_s( + <<"by">>, Attrs)) of + LServer -> + false; + _ -> + true + end; + (_) -> + true + end, Pkt#xmlel.children), Pkt#xmlel{children = NewEls}. should_archive_peer(C2SState, - #archive_prefs{default = Default, - always = Always, - never = Never}, - Peer) -> + #archive_prefs{default = Default, + always = Always, + never = Never}, + Peer) -> LPeer = jlib:jid_tolower(Peer), case lists:member(LPeer, Always) of - true -> - true; - false -> - case lists:member(LPeer, Never) of - true -> - false; - false -> - case Default of - always -> true; - never -> false; - roster -> - case ejabberd_c2s:get_subscription( - LPeer, C2SState) of - both -> true; - from -> true; - to -> true; - _ -> false - end - end - end + true -> + true; + false -> + case lists:member(LPeer, Never) of + true -> + false; + false -> + case Default of + always -> true; + never -> false; + roster -> + case ejabberd_c2s:get_subscription( + LPeer, C2SState) of + both -> true; + from -> true; + to -> true; + _ -> false + end + end + end end. should_archive_muc(_MUCState, _Peer) -> @@ -411,12 +411,12 @@ should_archive_muc(_MUCState, _Peer) -> store_msg(C2SState, Pkt, LUser, LServer, Peer, Dir) -> Prefs = get_prefs(LUser, LServer), case should_archive_peer(C2SState, Prefs, Peer) of - true -> + true -> US = {LUser, LServer}, store(Pkt, LServer, US, chat, Peer, <<"">>, Dir, - gen_mod:db_type(LServer, ?MODULE)); - false -> - pass + gen_mod:db_type(LServer, ?MODULE)); + false -> + pass end. store_muc(MUCState, Pkt, RoomJID, Peer, Nick) -> @@ -436,17 +436,17 @@ store(Pkt, _, {LUser, LServer}, Type, Peer, Nick, _Dir, mnesia) -> ID = jlib:integer_to_binary(now_to_usec(TS)), case mnesia:dirty_write( #archive_msg{us = {LUser, LServer}, - id = ID, - timestamp = TS, - peer = LPeer, - bare_peer = {PUser, PServer, <<>>}, + id = ID, + timestamp = TS, + peer = LPeer, + bare_peer = {PUser, PServer, <<>>}, type = Type, nick = Nick, - packet = Pkt}) of - ok -> - {ok, ID}; - Err -> - Err + packet = Pkt}) of + ok -> + {ok, ID}; + Err -> + Err end; store(Pkt, LServer, {LUser, LHost}, Type, Peer, Nick, _Dir, odbc) -> TSinteger = now_to_usec(now()), @@ -456,28 +456,28 @@ store(Pkt, LServer, {LUser, LHost}, Type, Peer, Nick, _Dir, odbc) -> groupchat -> jlib:jid_to_string({LUser, LHost, <<>>}) end, BarePeer = jlib:jid_to_string( - jlib:jid_tolower( - jlib:jid_remove_resource(Peer))), + jlib:jid_tolower( + jlib:jid_remove_resource(Peer))), LPeer = jlib:jid_to_string( - jlib:jid_tolower(Peer)), + jlib:jid_tolower(Peer)), XML = xml:element_to_binary(Pkt), Body = xml:get_subtag_cdata(Pkt, <<"body">>), case ejabberd_odbc:sql_query( - LServer, - [<<"insert into archive (username, timestamp, " - "peer, bare_peer, xml, txt, kind, nick) values (">>, - <<"'">>, ejabberd_odbc:escape(SUser), <<"', ">>, - <<"'">>, TS, <<"', ">>, - <<"'">>, ejabberd_odbc:escape(LPeer), <<"', ">>, - <<"'">>, ejabberd_odbc:escape(BarePeer), <<"', ">>, - <<"'">>, ejabberd_odbc:escape(XML), <<"', ">>, - <<"'">>, ejabberd_odbc:escape(Body), <<"', ">>, - <<"'">>, jlib:atom_to_binary(Type), <<"', ">>, - <<"'">>, ejabberd_odbc:escape(Nick), <<"');">>]) of - {updated, _} -> - {ok, ID}; - Err -> - Err + LServer, + [<<"insert into archive (username, timestamp, " + "peer, bare_peer, xml, txt, kind, nick) values (">>, + <<"'">>, ejabberd_odbc:escape(SUser), <<"', ">>, + <<"'">>, TS, <<"', ">>, + <<"'">>, ejabberd_odbc:escape(LPeer), <<"', ">>, + <<"'">>, ejabberd_odbc:escape(BarePeer), <<"', ">>, + <<"'">>, ejabberd_odbc:escape(XML), <<"', ">>, + <<"'">>, ejabberd_odbc:escape(Body), <<"', ">>, + <<"'">>, jlib:atom_to_binary(Type), <<"', ">>, + <<"'">>, ejabberd_odbc:escape(Nick), <<"');">>]) of + {updated, _} -> + {ok, ID}; + Err -> + Err end. write_prefs(LUser, LServer, Host, Default, Always, Never) -> @@ -486,9 +486,9 @@ write_prefs(LUser, LServer, Host, Default, Always, Never) -> DB -> DB end, Prefs = #archive_prefs{us = {LUser, LServer}, - default = Default, - always = Always, - never = Never}, + default = Default, + always = Always, + never = Never}, cache_tab:dirty_insert( archive_prefs, {LUser, LServer}, Prefs, fun() -> write_prefs(LUser, LServer, Prefs, DBType) end). @@ -496,21 +496,21 @@ write_prefs(LUser, LServer, Host, Default, Always, Never) -> write_prefs(_LUser, _LServer, Prefs, mnesia) -> mnesia:dirty_write(Prefs); write_prefs(LUser, _LServer, #archive_prefs{default = Default, - never = Never, - always = Always}, - {odbc, Host}) -> + never = Never, + always = Always}, + {odbc, Host}) -> SUser = ejabberd_odbc:escape(LUser), SDefault = erlang:atom_to_binary(Default, utf8), SAlways = ejabberd_odbc:encode_term(Always), SNever = ejabberd_odbc:encode_term(Never), case update(Host, <<"archive_prefs">>, - [<<"username">>, <<"def">>, <<"always">>, <<"never">>], - [SUser, SDefault, SAlways, SNever], - [<<"username='">>, SUser, <<"'">>]) of - {updated, _} -> - ok; - Err -> - Err + [<<"username">>, <<"def">>, <<"always">>, <<"never">>], + [SUser, SDefault, SAlways, SNever], + [<<"username='">>, SUser, <<"'">>]) of + {updated, _} -> + ok; + Err -> + Err end. get_prefs(LUser, LServer) -> @@ -520,24 +520,24 @@ get_prefs(LUser, LServer) -> DBType) end), case Res of - {ok, Prefs} -> - Prefs; - error -> - Default = gen_mod:get_module_opt( - LServer, ?MODULE, default, - fun(always) -> always; - (never) -> never; - (roster) -> roster - end, never), - #archive_prefs{us = {LUser, LServer}, default = Default} + {ok, Prefs} -> + Prefs; + error -> + Default = gen_mod:get_module_opt( + LServer, ?MODULE, default, + fun(always) -> always; + (never) -> never; + (roster) -> roster + end, never), + #archive_prefs{us = {LUser, LServer}, default = Default} end. get_prefs(LUser, LServer, mnesia) -> case mnesia:dirty_read(archive_prefs, {LUser, LServer}) of - [Prefs] -> - {ok, Prefs}; - _ -> - error + [Prefs] -> + {ok, Prefs}; + _ -> + error end; get_prefs(LUser, LServer, odbc) -> case ejabberd_odbc:sql_query( @@ -545,16 +545,16 @@ get_prefs(LUser, LServer, odbc) -> [<<"select def, always, never from archive_prefs ">>, <<"where username='">>, ejabberd_odbc:escape(LUser), <<"';">>]) of - {selected, _, [[SDefault, SAlways, SNever]]} -> - Default = erlang:binary_to_existing_atom(SDefault, utf8), - Always = ejabberd_odbc:decode_term(SAlways), - Never = ejabberd_odbc:decode_term(SNever), - {ok, #archive_prefs{us = {LUser, LServer}, - default = Default, - always = Always, - never = Never}}; - _ -> - error + {selected, _, [[SDefault, SAlways, SNever]]} -> + Default = erlang:binary_to_existing_atom(SDefault, utf8), + Always = ejabberd_odbc:decode_term(SAlways), + Never = ejabberd_odbc:decode_term(SNever), + {ok, #archive_prefs{us = {LUser, LServer}, + default = Default, + always = Always, + never = Never}}; + _ -> + error end. select_and_send(LServer, From, To, Start, End, With, RSM, IQ, MsgType) -> @@ -578,7 +578,7 @@ select_and_start(LServer, From, To, Start, End, With, RSM, MsgType, DBType) -> {room, {_, _, <<"">>} = WithJID} -> select(LServer, jlib:make_jid(WithJID), Start, End, WithJID, RSM, MsgType, DBType); - _ -> + _ -> select(LServer, From, Start, End, With, RSM, MsgType, DBType) end; @@ -631,8 +631,8 @@ select(_LServer, #jid{luser = LUser, lserver = LServer} = JidRequestor, Count = length(Msgs), {lists:map( fun(Msg) -> - {Msg#archive_msg.id, - jlib:binary_to_integer(Msg#archive_msg.id), + {Msg#archive_msg.id, + jlib:binary_to_integer(Msg#archive_msg.id), msg_to_el(Msg, MsgType, JidRequestor)} end, FilteredMsgs), IsComplete, Count}; select(LServer, #jid{luser = LUser} = JidRequestor, @@ -650,8 +650,8 @@ select(LServer, #jid{luser = LUser} = JidRequestor, % the client did not specify a limit using RSM then the server % should return a policy-violation error to the client. case {ejabberd_odbc:sql_query(Host, Query), - ejabberd_odbc:sql_query(Host, CountQuery)} of - {{selected, _, Res}, {selected, _, [[Count]]}} -> + ejabberd_odbc:sql_query(Host, CountQuery)} of + {{selected, _, Res}, {selected, _, [[Count]]}} -> {Max, Direction} = case RSM of #rsm_in{max = M, direction = D} -> {M, D}; _ -> {undefined, undefined} @@ -666,24 +666,24 @@ select(LServer, #jid{luser = LUser} = JidRequestor, true -> {Res, true} end, - {lists:map( + {lists:map( fun([TS, XML, PeerBin, Kind, Nick]) -> - #xmlel{} = El = xml_stream:parse_element(XML), - Now = usec_to_now(jlib:binary_to_integer(TS)), - PeerJid = jlib:jid_tolower(jlib:string_to_jid(PeerBin)), + #xmlel{} = El = xml_stream:parse_element(XML), + Now = usec_to_now(jlib:binary_to_integer(TS)), + PeerJid = jlib:jid_tolower(jlib:string_to_jid(PeerBin)), T = if Kind /= <<"">> -> jlib:binary_to_atom(Kind); true -> chat end, - {TS, jlib:binary_to_integer(TS), - msg_to_el(#archive_msg{timestamp = Now, + {TS, jlib:binary_to_integer(TS), + msg_to_el(#archive_msg{timestamp = Now, packet = El, type = T, nick = Nick, peer = PeerJid}, MsgType, JidRequestor)} - end, Res1), IsComplete, jlib:binary_to_integer(Count)}; + end, Res1), IsComplete, jlib:binary_to_integer(Count)}; _ -> {[], false, 0} end. @@ -693,12 +693,12 @@ msg_to_el(#archive_msg{timestamp = TS, packet = Pkt1, nick = Nick, peer = Peer}, Delay = jlib:now_to_utc_string(TS), Pkt = maybe_update_from_to(Pkt1, JidRequestor, Peer, MsgType, Nick), #xmlel{name = <<"forwarded">>, - attrs = [{<<"xmlns">>, ?NS_FORWARD}], - children = [#xmlel{name = <<"delay">>, - attrs = [{<<"xmlns">>, ?NS_DELAY}, - {<<"stamp">>, Delay}]}, - xml:replace_tag_attr( - <<"xmlns">>, <<"jabber:client">>, Pkt)]}. + attrs = [{<<"xmlns">>, ?NS_FORWARD}], + children = [#xmlel{name = <<"delay">>, + attrs = [{<<"xmlns">>, ?NS_DELAY}, + {<<"stamp">>, Delay}]}, + xml:replace_tag_attr( + <<"xmlns">>, <<"jabber:client">>, Pkt)]}. maybe_update_from_to(Pkt, JidRequestor, Peer, chat, _Nick) -> case xml:get_attr_s(<<"type">>, Pkt#xmlel.attrs) of @@ -864,42 +864,42 @@ match_rsm(_Now, _) -> make_matchspec(LUser, LServer, Start, End, {_, _, <<>>} = With) -> ets:fun2ms( fun(#archive_msg{timestamp = TS, - us = US, - bare_peer = BPeer} = Msg) - when Start =< TS, End >= TS, - US == {LUser, LServer}, - BPeer == With -> - Msg + us = US, + bare_peer = BPeer} = Msg) + when Start =< TS, End >= TS, + US == {LUser, LServer}, + BPeer == With -> + Msg end); make_matchspec(LUser, LServer, Start, End, {_, _, _} = With) -> ets:fun2ms( fun(#archive_msg{timestamp = TS, - us = US, - peer = Peer} = Msg) - when Start =< TS, End >= TS, - US == {LUser, LServer}, - Peer == With -> - Msg + us = US, + peer = Peer} = Msg) + when Start =< TS, End >= TS, + US == {LUser, LServer}, + Peer == With -> + Msg end); make_matchspec(LUser, LServer, Start, End, none) -> ets:fun2ms( fun(#archive_msg{timestamp = TS, - us = US, - peer = Peer} = Msg) - when Start =< TS, End >= TS, - US == {LUser, LServer} -> - Msg + us = US, + peer = Peer} = Msg) + when Start =< TS, End >= TS, + US == {LUser, LServer} -> + Msg end). make_sql_query(User, _LServer, Start, End, With, RSM) -> {Max, Direction, ID} = case RSM of - #rsm_in{} -> - {RSM#rsm_in.max, - RSM#rsm_in.direction, - RSM#rsm_in.id}; - none -> - {none, none, <<>>} - end, + #rsm_in{} -> + {RSM#rsm_in.max, + RSM#rsm_in.direction, + RSM#rsm_in.id}; + none -> + {none, none, <<>>} + end, LimitClause = if is_integer(Max), Max >= 0 -> [<<" limit ">>, jlib:integer_to_binary(Max+1)]; true -> @@ -936,19 +936,19 @@ make_sql_query(User, _LServer, Start, End, With, RSM) -> [] end, StartClause = case Start of - {_, _, _} -> - [<<" and timestamp >= ">>, - jlib:integer_to_binary(now_to_usec(Start))]; - _ -> - [] - end, + {_, _, _} -> + [<<" and timestamp >= ">>, + jlib:integer_to_binary(now_to_usec(Start))]; + _ -> + [] + end, EndClause = case End of - {_, _, _} -> - [<<" and timestamp <= ">>, - jlib:integer_to_binary(now_to_usec(End))]; - _ -> - [] - end, + {_, _, _} -> + [<<" and timestamp <= ">>, + jlib:integer_to_binary(now_to_usec(End))]; + _ -> + [] + end, SUser = ejabberd_odbc:escape(User), Query = [<<"SELECT timestamp, xml, peer, kind, nick" @@ -991,11 +991,11 @@ datetime_to_now(DateTime, USecs) -> get_jids(Els) -> lists:flatmap( fun(#xmlel{name = <<"jid">>} = El) -> - J = jlib:string_to_jid(xml:get_tag_cdata(El)), - [jlib:jid_tolower(jlib:jid_remove_resource(J)), - jlib:jid_tolower(J)]; - (_) -> - [] + J = jlib:string_to_jid(xml:get_tag_cdata(El)), + [jlib:jid_tolower(jlib:jid_remove_resource(J)), + jlib:jid_tolower(J)]; + (_) -> + [] end, Els). update(LServer, Table, Fields, Vals, Where) -> diff --git a/src/mod_muc.erl b/src/mod_muc.erl index e68472a29..18b123fa4 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -42,12 +42,12 @@ restore_room/3, forget_room/3, create_room/5, - shutdown_rooms/1, + shutdown_rooms/1, process_iq_disco_items/4, broadcast_service_message/2, - export/1, - import/1, - import/3, + export/1, + import/1, + import/3, can_use_nick/4]). -export([init/1, handle_call/3, handle_cast/2, @@ -85,10 +85,6 @@ %%==================================================================== %% API %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, @@ -295,13 +291,6 @@ can_use_nick(LServer, Host, JID, Nick, odbc) -> %% gen_server callbacks %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Description: Initiates the server -%%-------------------------------------------------------------------- init([Host, Opts]) -> MyHost = gen_mod:get_opt_host(Host, Opts, <<"conference.@HOST@">>), @@ -390,8 +379,7 @@ init([Host, Opts]) -> ejabberd_router:register_route(MyHost), load_permanent_rooms(MyHost, Host, {Access, AccessCreate, AccessAdmin, AccessPersistent}, - HistorySize, - RoomShaper), + HistorySize, RoomShaper), {ok, #state{host = MyHost, server_host = Host, access = {Access, AccessCreate, AccessAdmin, AccessPersistent}, @@ -399,15 +387,6 @@ init([Host, Opts]) -> history_size = HistorySize, room_shaper = RoomShaper}}. -%%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% Description: Handling call messages -%%-------------------------------------------------------------------- handle_call(stop, _From, State) -> {stop, normal, ok, State}; handle_call({create, Room, From, Nick, Opts}, _From, @@ -428,20 +407,8 @@ handle_call({create, Room, From, Nick, Opts}, _From, register_room(Host, Room, Pid), {reply, ok, State}. -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling cast messages -%%-------------------------------------------------------------------- handle_cast(_Msg, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling all non call/cast messages -%%-------------------------------------------------------------------- handle_info({route, From, To, Packet}, #state{host = Host, server_host = ServerHost, access = Access, default_room_opts = DefRoomOpts, @@ -468,21 +435,10 @@ handle_info({mnesia_system_event, {mnesia_down, Node}}, State) -> {noreply, State}; handle_info(_Info, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description: This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%%-------------------------------------------------------------------- terminate(_Reason, State) -> ejabberd_router:unregister_route(State#state.host), ok. -%%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} -%% Description: Convert process state when code is changed -%%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- @@ -508,13 +464,13 @@ do_route(Host, ServerHost, Access, HistorySize, RoomShaper, case acl:match_rule(ServerHost, AccessRoute, From) of allow -> do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, - From, To, Packet, DefRoomOpts); + From, To, Packet, DefRoomOpts); _ -> #xmlel{attrs = Attrs} = Packet, Lang = xml:get_attr_s(<<"xml:lang">>, Attrs), ErrText = <<"Access denied by service policy">>, Err = jlib:make_error_reply(Packet, - ?ERRT_FORBIDDEN(Lang, ErrText)), + ?ERRT_FORBIDDEN(Lang, ErrText)), ejabberd_router:route_error(To, From, Err, Packet) end. @@ -645,26 +601,23 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, <<"error">> -> ok; <<"result">> -> ok; _ -> - Err = jlib:make_error_reply( - Packet, ?ERR_ITEM_NOT_FOUND), - ejabberd_router:route(To, From, Err) - end - end; - _ -> + Err = jlib:make_error_reply(Packet, + ?ERR_ITEM_NOT_FOUND), + ejabberd_router:route(To, From, Err) + end + end; + _ -> case mnesia:dirty_read(muc_online_room, {Room, Host}) of [] -> Type = xml:get_attr_s(<<"type">>, Attrs), case {Name, Type} of {<<"presence">>, <<"">>} -> case check_user_can_create_room(ServerHost, - AccessCreate, From, - Room) of + AccessCreate, From, Room) of true -> - {ok, Pid} = start_new_room( - Host, ServerHost, Access, - Room, HistorySize, - RoomShaper, From, - Nick, DefRoomOpts), + {ok, Pid} = start_new_room(Host, ServerHost, Access, + Room, HistorySize, + RoomShaper, From, Nick, DefRoomOpts), register_room(Host, Room, Pid), mod_muc_room:route(Pid, From, Nick, Packet), ok; @@ -676,19 +629,18 @@ do_route1(Host, ServerHost, Access, HistorySize, RoomShaper, ejabberd_router:route(To, From, Err) end; _ -> - Lang = xml:get_attr_s(<<"xml:lang">>, Attrs), - ErrText = <<"Conference room does not exist">>, - Err = jlib:make_error_reply(Packet, - ?ERRT_ITEM_NOT_FOUND(Lang, - ErrText)), - ejabberd_router:route(To, From, Err) - end; - [R] -> - Pid = R#muc_online_room.pid, - ?DEBUG("MUC: send to process ~p~n", [Pid]), - mod_muc_room:route(Pid, From, Nick, Packet), - ok - end + Lang = xml:get_attr_s(<<"xml:lang">>, Attrs), + ErrText = <<"Conference room does not exist">>, + Err = jlib:make_error_reply(Packet, + ?ERRT_ITEM_NOT_FOUND(Lang, ErrText)), + ejabberd_router:route(To, From, Err) + end; + [R] -> + Pid = R#muc_online_room.pid, + ?DEBUG("MUC: send to process ~p~n", [Pid]), + mod_muc_room:route(Pid, From, Nick, Packet), + ok + end end. check_user_can_create_room(ServerHost, AccessCreate, @@ -743,48 +695,43 @@ get_rooms(LServer, Host, odbc) -> Err -> ?ERROR_MSG("failed to get rooms: ~p", [Err]), [] end. -load_permanent_rooms(Host, ServerHost, Access, HistorySize, RoomShaper) -> +load_permanent_rooms(Host, ServerHost, Access, + HistorySize, RoomShaper) -> lists:foreach( fun(R) -> - {Room, Host} = R#muc_room.name_host, - case mnesia:dirty_read(muc_online_room, {Room, Host}) of - [] -> - {ok, Pid} = mod_muc_room:start( - Host, - ServerHost, - Access, - Room, - HistorySize, - RoomShaper, - R#muc_room.opts), - register_room(Host, Room, Pid); - _ -> - ok - end - end, get_rooms(ServerHost, Host)). + {Room, Host} = R#muc_room.name_host, + case mnesia:dirty_read(muc_online_room, {Room, Host}) of + [] -> + {ok, Pid} = mod_muc_room:start(Host, + ServerHost, Access, Room, + HistorySize, RoomShaper, + R#muc_room.opts), + register_room(Host, Room, Pid); + _ -> ok + end + end, + get_rooms(ServerHost, Host)). start_new_room(Host, ServerHost, Access, Room, - HistorySize, RoomShaper, From, - Nick, DefRoomOpts) -> + HistorySize, RoomShaper, From, + Nick, DefRoomOpts) -> case restore_room(ServerHost, Host, Room) of - error -> + error -> ?DEBUG("MUC: open new room '~s'~n", [Room]), - mod_muc_room:start(Host, ServerHost, Access, - Room, HistorySize, - RoomShaper, From, - Nick, DefRoomOpts); - Opts -> + mod_muc_room:start(Host, ServerHost, Access, Room, + HistorySize, RoomShaper, + From, Nick, DefRoomOpts); + Opts -> ?DEBUG("MUC: restore room '~s'~n", [Room]), - mod_muc_room:start(Host, ServerHost, Access, - Room, HistorySize, - RoomShaper, Opts) + mod_muc_room:start(Host, ServerHost, Access, Room, + HistorySize, RoomShaper, Opts) end. register_room(Host, Room, Pid) -> F = fun() -> - mnesia:write(#muc_online_room{name_host = {Room, Host}, - pid = Pid}) - end, + mnesia:write(#muc_online_room{name_host = {Room, Host}, + pid = Pid}) + end, mnesia:transaction(F). @@ -840,7 +787,6 @@ iq_disco_items(Host, From, Lang, none) -> _ -> false end end, get_vh_rooms(Host)); - iq_disco_items(Host, From, Lang, Rsm) -> {Rooms, RsmO} = get_vh_rooms(Host, Rsm), RsmOut = jlib:rsm_encode(RsmO), @@ -920,13 +866,6 @@ get_room_pos(Desired, [_ | Rooms], HeadPosition) -> flush() -> receive _ -> flush() after 0 -> ok end. -define(XFIELD(Type, Label, Var, Val), -%% @doc Get a pseudo unique Room Name. The Room Name is generated as a hash of -%% the requester JID, the local time and a random salt. -%% -%% "pseudo" because we don't verify that there is not a room -%% with the returned Name already created, nor mark the generated Name -%% as "already used". But in practice, it is unique enough. See -%% http://xmpp.org/extensions/xep-0045.html#createroom-unique #xmlel{name = <<"field">>, attrs = [{<<"type">>, Type}, @@ -1177,13 +1116,12 @@ iq_get_vcard(Lang) -> <<"ejabberd MUC module">>))/binary, "\nCopyright (c) 2003-2015 ProcessOne">>}]}]. - broadcast_service_message(Host, Msg) -> lists:foreach( - fun(#muc_online_room{pid = Pid}) -> - gen_fsm:send_all_state_event( - Pid, {service_message, Msg}) - end, get_vh_rooms(Host)). + fun(#muc_online_room{pid = Pid}) -> + gen_fsm:send_all_state_event( + Pid, {service_message, Msg}) + end, get_vh_rooms(Host)). get_vh_rooms(Host) -> @@ -1349,8 +1287,7 @@ import(_LServer) -> [{<<"select name, host, opts from muc_room;">>, fun([Name, RoomHost, SOpts]) -> Opts = opts_to_binary(ejabberd_odbc:decode_term(SOpts)), - #muc_room{name_host = {Name, RoomHost}, - opts = Opts} + #muc_room{name_host = {Name, RoomHost}, opts = Opts} end}, {<<"select jid, host, nick from muc_registered;">>, fun([J, RoomHost, Nick]) -> diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 923428b3f..b11b5ae2c 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -411,7 +411,6 @@ create_room(Name, Host, ServerHost) -> AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create, fun(X) -> X end, all), AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin, fun(X) -> X end, none), AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent, fun(X) -> X end, all), - _PersistHistory = gen_mod:get_module_opt(ServerHost, mod_muc, persist_history, fun(X) -> X end, false), HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size, fun(X) -> X end, 20), RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper, fun(X) -> X end, none), diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index 65e604ba4..a5242824d 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -76,23 +76,14 @@ %%==================================================================== %% API %%==================================================================== -%%-------------------------------------------------------------------- -%% Function: start_link() -> {ok,Pid} | ignore | {error,Error} -%% Description: Starts the server -%%-------------------------------------------------------------------- start_link(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), gen_server:start_link({local, Proc}, ?MODULE, [Host, Opts], []). start(Host, Opts) -> Proc = gen_mod:get_module_proc(Host, ?PROCNAME), - ChildSpec = - {Proc, - {?MODULE, start_link, [Host, Opts]}, - temporary, - 1000, - worker, - [?MODULE]}, + ChildSpec = {Proc, {?MODULE, start_link, [Host, Opts]}, + temporary, 1000, worker, [?MODULE]}, supervisor:start_child(ejabberd_sup, ChildSpec). stop(Host) -> @@ -123,19 +114,11 @@ transform_module_options(Opts) -> %%==================================================================== %% gen_server callbacks %%==================================================================== - -%%-------------------------------------------------------------------- -%% Function: init(Args) -> {ok, State} | -%% {ok, State, Timeout} | -%% ignore | -%% {stop, Reason} -%% Description: Initiates the server -%%-------------------------------------------------------------------- init([Host, Opts]) -> OutDir = gen_mod:get_opt(outdir, Opts, fun iolist_to_binary/1, <<"www/muc">>), - DirType = gen_mod:get_opt(dirtype, Opts, + DirType = gen_mod:get_opt(dirtype, Opts, fun(subdirs) -> subdirs; (plain) -> plain end, subdirs), @@ -181,31 +164,17 @@ init([Host, Opts]) -> {ok, #logstate{host = Host, out_dir = OutDir, dir_type = DirType, dir_name = DirName, - file_format = FileFormat, file_permissions = FilePermissions, css_file = CSSFile, + file_format = FileFormat, css_file = CSSFile, + file_permissions = FilePermissions, access = AccessLog, lang = Lang, timezone = Timezone, spam_prevention = NoFollow, top_link = Top_link}}. -%%-------------------------------------------------------------------- -%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} | -%% {reply, Reply, State, Timeout} | -%% {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, Reply, State} | -%% {stop, Reason, State} -%% Description: Handling call messages -%%-------------------------------------------------------------------- handle_call({check_access_log, ServerHost, FromJID}, _From, State) -> Reply = acl:match_rule(ServerHost, State#logstate.access, FromJID), {reply, Reply, State}; handle_call(stop, _From, State) -> {stop, normal, ok, State}. -%%-------------------------------------------------------------------- -%% Function: handle_cast(Msg, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling cast messages -%%-------------------------------------------------------------------- handle_cast({add_to_log, Type, Data, Room, Opts}, State) -> case catch add_to_log2(Type, Data, Room, Opts, State) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]); @@ -214,27 +183,10 @@ handle_cast({add_to_log, Type, Data, Room, Opts}, State) -> {noreply, State}; handle_cast(_Msg, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: handle_info(Info, State) -> {noreply, State} | -%% {noreply, State, Timeout} | -%% {stop, Reason, State} -%% Description: Handling all non call/cast messages -%%-------------------------------------------------------------------- handle_info(_Info, State) -> {noreply, State}. -%%-------------------------------------------------------------------- -%% Function: terminate(Reason, State) -> void() -%% Description: This function is called by a gen_server when it is about to -%% terminate. It should be the opposite of Module:init/1 and do any necessary -%% cleaning up. When it returns, the gen_server terminates with Reason. -%% The return value is ignored. -%%-------------------------------------------------------------------- terminate(_Reason, _State) -> ok. -%%-------------------------------------------------------------------- -%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState} -%% Description: Convert process state when code is changed -%%-------------------------------------------------------------------- code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- @@ -242,19 +194,19 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- add_to_log2(text, {Nick, Packet}, Room, Opts, State) -> case has_no_permanent_store_hint(Packet) of - false -> - case {xml:get_subtag(Packet, <<"subject">>), - xml:get_subtag(Packet, <<"body">>)} - of - {false, false} -> ok; - {false, SubEl} -> - Message = {body, xml:get_tag_cdata(SubEl)}, - add_message_to_log(Nick, Message, Room, Opts, State); - {SubEl, _} -> - Message = {subject, xml:get_tag_cdata(SubEl)}, - add_message_to_log(Nick, Message, Room, Opts, State) - end; - true -> ok + false -> + case {xml:get_subtag(Packet, <<"subject">>), + xml:get_subtag(Packet, <<"body">>)} + of + {false, false} -> ok; + {false, SubEl} -> + Message = {body, xml:get_tag_cdata(SubEl)}, + add_message_to_log(Nick, Message, Room, Opts, State); + {SubEl, _} -> + Message = {subject, xml:get_tag_cdata(SubEl)}, + add_message_to_log(Nick, Message, Room, Opts, State) + end; + true -> ok end; add_to_log2(roomconfig_change, _Occupants, Room, Opts, State) -> @@ -349,7 +301,6 @@ close_previous_log(Fn, Images_dir, FileFormat) -> write_last_lines(_, _, plaintext) -> ok; write_last_lines(F, Images_dir, _FileFormat) -> -%% list_to_integer/2 was introduced in OTP R14 fw(F, <<"
">>), fw(F, <<" fw(F, <<"
">>). set_filemode(Fn, {FileMode, FileGroup}) -> - ok = file:change_mode(Fn, list_to_integer(integer_to_list(FileMode), 8)), + ok = file:change_mode(Fn, list_to_integer(integer_to_list(FileMode), 8)), ok = file:change_group(Fn, FileGroup). htmlize_nick(Nick1, html) -> @@ -1163,10 +1114,7 @@ roomoccupants_to_string(Users, _FileFormat) -> Users1 /= []], iolist_to_binary([<<"
">>, Res, <<"
">>]). -%% Users = [{JID, Nick, Role}] group_by_role(Users) -> -%% Role = atom() -%% Users = [{JID, Nick}] {Ms, Ps, Vs, Ns} = lists:foldl(fun ({JID, Nick, moderator}, {Mod, Par, Vis, Non}) -> @@ -1238,7 +1186,8 @@ get_room_state(RoomPid) -> get_state), R. -get_proc_name(Host) -> gen_mod:get_module_proc(Host, ?PROCNAME). +get_proc_name(Host) -> + gen_mod:get_module_proc(Host, ?PROCNAME). calc_hour_offset(TimeHere) -> TimeZero = calendar:now_to_universal_time(now()), diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 39e045d9e..cf26bdea1 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -112,23 +112,17 @@ start_link(Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts) -> %%% Callback functions from gen_fsm %%%---------------------------------------------------------------------- -%%---------------------------------------------------------------------- -%% Func: init/1 -%% Returns: {ok, StateName, StateData} | -%% {ok, StateName, StateData, Timeout} | -%% ignore | -%% {stop, StopReason} -%%---------------------------------------------------------------------- -init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, DefRoomOpts]) -> +init([Host, ServerHost, Access, Room, HistorySize, + RoomShaper, Creator, _Nick, DefRoomOpts]) -> process_flag(trap_exit, true), Shaper = shaper:new(RoomShaper), State = set_affiliation(Creator, owner, - #state{host = Host, server_host = ServerHost, - access = Access, room = Room, - history = lqueue_new(HistorySize), - jid = jlib:make_jid(Room, Host, <<"">>), - just_created = true, - room_shaper = Shaper}), + #state{host = Host, server_host = ServerHost, + access = Access, room = Room, + history = lqueue_new(HistorySize), + jid = jlib:make_jid(Room, Host, <<"">>), + just_created = true, + room_shaper = Shaper}), State1 = set_opts(DefRoomOpts, State), if (State1#state.config)#config.persistent -> mod_muc:store_room(State1#state.server_host, @@ -137,7 +131,7 @@ init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Creator, _Nick, D make_opts(State1)); true -> ok end, - ?INFO_MSG("Created MUC room ~s@~s by ~s", + ?INFO_MSG("Created MUC room ~s@~s by ~s", [Room, Host, jlib:jid_to_string(Creator)]), add_to_log(room_existence, created, State1), add_to_log(room_existence, started, State1), @@ -155,12 +149,6 @@ init([Host, ServerHost, Access, Room, HistorySize, RoomShaper, Opts]) -> add_to_log(room_existence, started, State), {ok, normal_state, State}. -%%---------------------------------------------------------------------- -%% Func: StateName/2 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- normal_state({route, From, <<"">>, #xmlel{name = <<"message">>, attrs = Attrs, children = Els} = @@ -688,12 +676,6 @@ normal_state({route, From, ToNick, normal_state(_Event, StateData) -> {next_state, normal_state, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_event/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_event({service_message, Msg}, _StateName, StateData) -> MessagePkt = #xmlel{name = <<"message">>, @@ -742,15 +724,6 @@ handle_event({set_affiliations, Affiliations}, handle_event(_Event, StateName, StateData) -> {next_state, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_sync_event/4 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {reply, Reply, NextStateName, NextStateData} | -%% {reply, Reply, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} | -%% {stop, Reason, Reply, NewStateData} -%%---------------------------------------------------------------------- handle_sync_event({get_disco_item, JID, Lang}, _From, StateName, StateData) -> Reply = get_roomdesc_reply(JID, StateData, get_roomdesc_tail(StateData, Lang)), @@ -779,12 +752,6 @@ handle_sync_event(_Event, _From, StateName, code_change(_OldVsn, StateName, StateData, _Extra) -> {ok, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: handle_info/3 -%% Returns: {next_state, NextStateName, NextStateData} | -%% {next_state, NextStateName, NextStateData, Timeout} | -%% {stop, Reason, NewStateData} -%%---------------------------------------------------------------------- handle_info({process_user_presence, From}, normal_state = _StateName, StateData) -> RoomQueueEmpty = queue:is_empty(StateData#state.room_queue), RoomQueue = queue:in({presence, From}, StateData#state.room_queue), @@ -864,11 +831,6 @@ handle_info(shutdown, _StateName, StateData) -> handle_info(_Info, StateName, StateData) -> {next_state, StateName, StateData}. -%%---------------------------------------------------------------------- -%% Func: terminate/3 -%% Purpose: Shutdown the fsm -%% Returns: any -%%---------------------------------------------------------------------- terminate(Reason, _StateName, StateData) -> ?INFO_MSG("Stopping MUC room ~s@~s", [StateData#state.room, StateData#state.host]), @@ -979,7 +941,7 @@ process_groupchat_message(From, StateData#state.server_host, StateData#state.users, NewPacket), - NewStateData2 = case has_body_or_subject(Packet) of + NewStateData2 = case has_body_or_subject(NewPacket) of true -> add_message_to_history(FromNick, From, NewPacket, @@ -1808,9 +1770,9 @@ is_nick_change(JID, Nick, StateData) -> nick_collision(User, Nick, StateData) -> UserOfNick = find_jid_by_nick(Nick, StateData), - UserOfNick /= false andalso + (UserOfNick /= false andalso jlib:jid_remove_resource(jlib:jid_tolower(UserOfNick)) - /= jlib:jid_remove_resource(jlib:jid_tolower(User)). + /= jlib:jid_remove_resource(jlib:jid_tolower(User))). add_new_user(From, Nick, #xmlel{attrs = Attrs, children = Els} = Packet, @@ -4412,7 +4374,6 @@ check_invitation(From, Els, Lang, StateData) -> jlib:jid_to_string({StateData#state.room, StateData#state.host, <<"">>})]), - case (StateData#state.config)#config.password_protected of @@ -4561,6 +4522,13 @@ tab_count_user(JID) -> element_size(El) -> byte_size(xml:element_to_binary(El)). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Multicast + +send_multiple(From, Server, Users, Packet) -> + JIDs = [ User#user.jid || {_, User} <- ?DICT:to_list(Users)], + ejabberd_router_multicast:route_multicast(From, Server, JIDs, Packet). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Detect messange stanzas that don't have meaninful content @@ -4571,9 +4539,3 @@ has_body_or_subject(Packet) -> (_) -> true end, Packet#xmlel.children). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Multicast - -send_multiple(From, Server, Users, Packet) -> - JIDs = [ User#user.jid || {_, User} <- ?DICT:to_list(Users)], - ejabberd_router_multicast:route_multicast(From, Server, JIDs, Packet). diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl index 0abf4215c..ad7514c1a 100644 --- a/src/mod_multicast.erl +++ b/src/mod_multicast.erl @@ -3,6 +3,24 @@ %%% Author : Badlop %%% Purpose : Extended Stanza Addressing (XEP-0033) support %%% Created : 29 May 2007 by Badlop +%%% +%%% +%%% 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(mod_multicast). @@ -713,8 +731,7 @@ process_iqreply_error(From, LServiceS, _Packet) -> %%% Check protocol support: Receive response: Disco %%%------------------------- -process_iqreply_result(From, LServiceS, Packet, - State) -> +process_iqreply_result(From, LServiceS, Packet, State) -> #xmlel{name = <<"query">>, attrs = Attrs2, children = Els2} = xml:get_subtag(Packet, <<"query">>), @@ -741,37 +758,35 @@ process_discoinfo_result(From, LServiceS, Els, process_discoinfo_result2(From, FromS, LServiceS, Els, Waiter) -> - Multicast_support = lists:any(fun (XML) -> - case XML of - #xmlel{name = <<"feature">>, - attrs = Attrs} -> - (?NS_ADDRESS) == - xml:get_attr_s(<<"var">>, - Attrs); - _ -> false - end - end, - Els), + Multicast_support = + lists:any( + fun(XML) -> + case XML of + #xmlel{name = <<"feature">>, attrs = Attrs} -> + (?NS_ADDRESS) == xml:get_attr_s(<<"var">>, Attrs); + _ -> false + end + end, + Els), Group = Waiter#waiter.group, RServer = Group#group.server, case Multicast_support of - true -> - SenderT = sender_type(From), - RLimits = get_limits_xml(Els, SenderT), - add_response(RServer, - {multicast_supported, FromS, RLimits}), - FromM = Waiter#waiter.sender, - DestsM = Group#group.dests, - PacketM = Waiter#waiter.packet, - AAttrsM = Waiter#waiter.aattrs, - AddressesM = Waiter#waiter.addresses, - RServiceM = FromS, - route_packet_multicast(FromM, RServiceM, PacketM, - AAttrsM, DestsM, AddressesM, RLimits), - delo_waiter(Waiter); - false -> - case FromS of - RServer -> + true -> + SenderT = sender_type(From), + RLimits = get_limits_xml(Els, SenderT), + add_response(RServer, {multicast_supported, FromS, RLimits}), + FromM = Waiter#waiter.sender, + DestsM = Group#group.dests, + PacketM = Waiter#waiter.packet, + AAttrsM = Waiter#waiter.aattrs, + AddressesM = Waiter#waiter.addresses, + RServiceM = FromS, + route_packet_multicast(FromM, RServiceM, PacketM, + AAttrsM, DestsM, AddressesM, RLimits), + delo_waiter(Waiter); + false -> + case FromS of + RServer -> send_query_items(FromS, LServiceS), delo_waiter(Waiter), add_waiter(Waiter#waiter{awaiting = diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 5165c8e68..bcd65b21b 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -39,7 +39,7 @@ -export([count_offline_messages/2]). -export([start/2, - start_link/2, + start_link/2, stop/1, store_packet/3, resend_offline_messages/2, @@ -48,11 +48,11 @@ remove_expired_messages/1, remove_old_messages/2, remove_user/2, - import/1, - import/3, - export/1, + import/1, + import/3, + export/1, get_queue_length/2, - get_offline_els/2, + get_offline_els/2, webadmin_page/3, webadmin_user/4, webadmin_user_parse_query/5]). @@ -70,17 +70,7 @@ -include("ejabberd_web_admin.hrl"). --record(offline_msg, - {us = {<<"">>, <<"">>} :: {binary(), binary()}, - timestamp = now() :: erlang:timestamp() | '_', - expire = now() :: erlang:timestamp() | never | '_', - from = #jid{} :: jid() | '_', - to = #jid{} :: jid() | '_', - packet = #xmlel{} :: xmlel() | '_'}). - --record(state, - {host = <<"">> :: binary(), - access_max_offline_messages}). +-include("mod_offline.hrl"). -define(PROCNAME, ejabberd_offline). @@ -138,8 +128,11 @@ init([Host, Opts]) -> ejabberd_hooks:add(webadmin_user, Host, ?MODULE, webadmin_user, 50), ejabberd_hooks:add(webadmin_user_parse_query, Host, - ?MODULE, webadmin_user_parse_query, 50), - AccessMaxOfflineMsgs = gen_mod:get_opt(access_max_user_messages, Opts, fun(A) -> A end, max_user_offline_messages), + ?MODULE, webadmin_user_parse_query, 50), + AccessMaxOfflineMsgs = + gen_mod:get_opt(access_max_user_messages, Opts, + fun(A) when is_atom(A) -> A end, + max_user_offline_messages), {ok, #state{host = Host, access_max_offline_messages = AccessMaxOfflineMsgs}}. @@ -253,7 +246,6 @@ store_offline_msg(Host, {User, _}, Msgs, Len, MaxOfflineMsgs, end, Msgs) end. -%% Function copied from ejabberd_sm.erl: get_max_user_messages(AccessRule, {User, Server}, Host) -> case acl:match_rule( Host, AccessRule, jlib:make_jid(User, Server, <<"">>)) of @@ -308,24 +300,24 @@ need_to_store(LServer, Packet) -> store_packet(From, To, Packet) -> case need_to_store(To#jid.lserver, Packet) of true -> - case has_no_store_hint(Packet) of - false -> - case check_event(From, To, Packet) of - true -> - #jid{luser = LUser, lserver = LServer} = To, - TimeStamp = now(), - #xmlel{children = Els} = Packet, - Expire = find_x_expire(TimeStamp, Els), - gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! - #offline_msg{us = {LUser, LServer}, - timestamp = TimeStamp, expire = Expire, - from = From, to = To, packet = Packet}, - stop; - _ -> ok - end; - _ -> ok - end; - false -> ok + case has_no_store_hint(Packet) of + false -> + case check_event(From, To, Packet) of + true -> + #jid{luser = LUser, lserver = LServer} = To, + TimeStamp = now(), + #xmlel{children = Els} = Packet, + Expire = find_x_expire(TimeStamp, Els), + gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) ! + #offline_msg{us = {LUser, LServer}, + timestamp = TimeStamp, expire = Expire, + from = From, to = To, packet = Packet}, + stop; + _ -> ok + end; + _ -> ok + end; + false -> ok end. has_no_store_hint(Packet) -> diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 81ea3dfcf..6ab559c90 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -584,11 +584,10 @@ process_list_set(LUser, LServer, {value, Name}, Els) -> ejabberd_sm:route(jlib:make_jid(LUser, LServer, <<"">>), jlib:make_jid(LUser, LServer, <<"">>), - {broadcast, - {privacy_list, - #userlist{name = Name, - list = []}, - Name}}), + {broadcast, {privacy_list, + #userlist{name = Name, + list = []}, + Name}}), {result, []}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end; @@ -601,12 +600,11 @@ process_list_set(LUser, LServer, {value, Name}, Els) -> ejabberd_sm:route(jlib:make_jid(LUser, LServer, <<"">>), jlib:make_jid(LUser, LServer, <<"">>), - {broadcast, - {privacy_list, - #userlist{name = Name, - list = List, - needdb = NeedDb}, - Name}}), + {broadcast, {privacy_list, + #userlist{name = Name, + list = List, + needdb = NeedDb}, + Name}}), {result, []}; _ -> {error, ?ERR_INTERNAL_SERVER_ERROR} end @@ -1166,7 +1164,7 @@ update_table() -> end. export(Server) -> - case ejabberd_odbc:sql_query(jlib:nameprep(Server), + case catch ejabberd_odbc:sql_query(jlib:nameprep(Server), [<<"select id from privacy_list order by " "id desc limit 1;">>]) of {selected, [<<"id">>], [[I]]} -> diff --git a/src/mod_proxy65_sm.erl b/src/mod_proxy65_sm.erl index ce997154e..f120f828b 100644 --- a/src/mod_proxy65_sm.erl +++ b/src/mod_proxy65_sm.erl @@ -64,8 +64,9 @@ start_link(Host, Opts) -> []). init([Opts]) -> - mnesia:create_table(bytestream, [{ram_copies, [node()]}, - {attributes, record_info(fields, bytestream)}]), + mnesia:create_table(bytestream, + [{ram_copies, [node()]}, + {attributes, record_info(fields, bytestream)}]), mnesia:add_table_copy(bytestream, node(), ram_copies), MaxConnections = gen_mod:get_opt(max_connections, Opts, fun(I) when is_integer(I), I>0 -> diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index b4e936020..6470f0fb5 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -3480,10 +3480,9 @@ subscribed_nodes_by_jid(NotifyType, SubsByDepth) -> NodeOptions = Node#pubsub_node.options, lists:foldl(fun({LJID, SubID, SubOptions}, {JIDs, Recipients}) -> case is_to_deliver(LJID, NotifyType, Depth, NodeOptions, SubOptions) of - true -> - %% If is to deliver : + true -> case state_can_deliver(LJID, SubOptions) of - [] -> {JIDs, Recipients}; + [] -> {JIDs, Recipients}; JIDsToDeliver -> lists:foldl( fun(JIDToDeliver, {JIDsAcc, RecipientsAcc}) -> @@ -3494,11 +3493,14 @@ subscribed_nodes_by_jid(NotifyType, SubsByDepth) -> %% - add the Jid to JIDs list co-accumulator ; %% - create a tuple of the Jid, Nidx, and SubID (as list), %% and add the tuple to the Recipients list co-accumulator - {[JIDToDeliver | JIDsAcc], [{JIDToDeliver, NodeName, [SubID]} | RecipientsAcc]}; + {[JIDToDeliver | JIDsAcc], + [{JIDToDeliver, NodeName, [SubID]} + | RecipientsAcc]}; true -> %% - if the JIDs co-accumulator contains the Jid %% get the tuple containing the Jid from the Recipient list co-accumulator - {_, {JIDToDeliver, NodeName1, SubIDs}} = lists:keysearch(JIDToDeliver, 1, RecipientsAcc), + {_, {JIDToDeliver, NodeName1, SubIDs}} = + lists:keysearch(JIDToDeliver, 1, RecipientsAcc), %% delete the tuple from the Recipients list % v1 : Recipients1 = lists:keydelete(LJID, 1, Recipients), % v2 : Recipients1 = lists:keyreplace(LJID, 1, Recipients, {LJID, Nidx1, [SubID | SubIDs]}), @@ -3507,7 +3509,11 @@ subscribed_nodes_by_jid(NotifyType, SubsByDepth) -> % v1.1 : {JIDs, lists:append(Recipients1, [{LJID, Nidx1, lists:append(SubIDs, [SubID])}])} % v1.2 : {JIDs, [{LJID, Nidx1, [SubID | SubIDs]} | Recipients1]} % v2: {JIDs, Recipients1} - {JIDsAcc, lists:keyreplace(JIDToDeliver, 1, RecipientsAcc, {JIDToDeliver, NodeName1, [SubID | SubIDs]})} + {JIDsAcc, + lists:keyreplace(JIDToDeliver, 1, + RecipientsAcc, + {JIDToDeliver, NodeName1, + [SubID | SubIDs]})} end end, {JIDs, Recipients}, JIDsToDeliver) end; diff --git a/src/mod_register.erl b/src/mod_register.erl index bb2a8fbe9..f9ffa9c50 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -408,6 +408,8 @@ try_register(User, Server, Password, SourceRaw, Lang) -> {error, ?ERR_JID_MALFORMED}; {error, not_allowed} -> {error, ?ERR_NOT_ALLOWED}; + {error, too_many_users} -> + {error, ?ERR_NOT_ALLOWED}; {error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR} end diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 31fbeb1d2..0677605ac 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -1005,7 +1005,6 @@ send_unsubscription_to_rosteritems(LUser, LServer) -> end, RosterItems). -%% @spec (From::jid(), Item::roster()) -> ok send_unsubscribing_presence(From, Item) -> IsTo = case Item#roster.subscription of both -> true; diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 83ecade91..96cda6e3c 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -98,9 +98,6 @@ start(Host, Opts) -> ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50). -%%ejabberd_hooks:add(remove_user, Host, -%% ?MODULE, remove_user, 50), - stop(Host) -> ejabberd_hooks:delete(webadmin_menu_host, Host, ?MODULE, webadmin_menu, 70), @@ -126,12 +123,11 @@ stop(Host) -> register_user, 50), ejabberd_hooks:delete(anonymous_purge_hook, Host, ?MODULE, remove_user, 50), -%%ejabberd_hooks:delete(remove_user, Host, -%% ?MODULE, remove_user, 50), ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, - 50).%%ejabberd_hooks:delete(remove_user, Host, - %% ?MODULE, remove_user, 50), + 50). + %%ejabberd_hooks:delete(remove_user, Host, + %% ?MODULE, remove_user, 50), get_user_roster(Items, US) -> {U, S} = US, @@ -622,7 +618,6 @@ get_group_users(Host1, Group1) -> get_group_users(Host, Group, GroupOpts) -> case proplists:get_value(all_users, GroupOpts, false) of -%% @spec (Host::string(), Group::string()) -> [{User::string(), Server::string()}] true -> ejabberd_auth:get_vh_registered_users(Host); false -> [] end @@ -675,25 +670,22 @@ get_group_name(Host1, Group1) -> %% Get list of names of groups that have @all@/@online@/etc in the memberlist get_special_users_groups(Host) -> -%% Get list of names of groups that have @online@ in the memberlist lists:filter(fun (Group) -> get_group_opt(Host, Group, all_users, false) orelse get_group_opt(Host, Group, online_users, false) end, list_groups(Host)). +%% Get list of names of groups that have @online@ in the memberlist get_special_users_groups_online(Host) -> -%% Given two lists of groupnames and their options, -%% return the list of displayed groups to the second list lists:filter(fun (Group) -> get_group_opt(Host, Group, online_users, false) end, list_groups(Host)). +%% Given two lists of groupnames and their options, +%% return the list of displayed groups to the second list displayed_groups(GroupsOpts, SelectedGroupsOpts) -> -%% Given a list of group names with options, -%% for those that have @all@ in memberlist, -%% get the list of groups displayed DisplayedGroups = lists:usort(lists:flatmap(fun ({_Group, Opts}) -> [G @@ -712,6 +704,9 @@ displayed_groups(GroupsOpts, SelectedGroupsOpts) -> lists:member(disabled, proplists:get_value(G, GroupsOpts, []))]. +%% Given a list of group names with options, +%% for those that have @all@ in memberlist, +%% get the list of groups displayed get_special_displayed_groups(GroupsOpts) -> Groups = lists:filter(fun ({_Group, Opts}) -> proplists:get_value(all_users, Opts, false) @@ -825,7 +820,7 @@ is_user_in_group(US, Group, Host, odbc) -> %% @spec (Host::string(), {User::string(), Server::string()}, Group::string()) -> {atomic, ok} add_user_to_group(Host, US, Group) -> {LUser, LServer} = US, - case ejabberd_regexp:run(LUser, <<"^@.+@$">>) of + case ejabberd_regexp:run(LUser, <<"^@.+@\$">>) of match -> GroupOpts = (?MODULE):get_group_opts(Host, Group), MoreGroupOpts = case LUser of @@ -884,7 +879,7 @@ push_displayed_to_user(LUser, LServer, Host, Subscription, DisplayedGroups) -> remove_user_from_group(Host, US, Group) -> {LUser, LServer} = US, - case ejabberd_regexp:run(LUser, <<"^@.+@$">>) of + case ejabberd_regexp:run(LUser, <<"^@.+@\$">>) of match -> GroupOpts = (?MODULE):get_group_opts(Host, Group), NewGroupOpts = case LUser of diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl index 653c83ee2..2a3d8ee11 100644 --- a/src/mod_shared_roster_ldap.erl +++ b/src/mod_shared_roster_ldap.erl @@ -275,16 +275,9 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- -%% For a given user, map all his shared roster contacts to groups they are -%% members of. Skip the user himself iff SkipUS is true. + get_user_to_groups_map({_, Server} = US, SkipUS) -> DisplayedGroups = get_user_displayed_groups(US), -%% Pass given FilterParseArgs to eldap_filter:parse, and if successful, run and -%% return the resulting filter, retrieving given AttributesList. Return the -%% result entries. On any error silently return an empty list of results. -%% -%% Eldap server ID and base DN for the query are both retrieved from the State -%% record. lists:foldl(fun (Group, Dict1) -> GroupName = get_group_name(Server, Group), lists:foldl(fun (Contact, Dict) -> diff --git a/src/mod_sip.erl b/src/mod_sip.erl index 4827e0c3b..1e4044b15 100644 --- a/src/mod_sip.erl +++ b/src/mod_sip.erl @@ -1,11 +1,11 @@ %%%------------------------------------------------------------------- %%% @author Evgeny Khramtsov -%%% @copyright (C) 2014, Evgeny Khramtsov %%% @doc %%% %%% @end %%% Created : 21 Apr 2014 by Evgeny Khramtsov %%% +%%% %%% ejabberd, Copyright (C) 2014-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl index 1dcf264ed..a0dff1256 100644 --- a/src/mod_sip_proxy.erl +++ b/src/mod_sip_proxy.erl @@ -1,11 +1,11 @@ %%%------------------------------------------------------------------- %%% @author Evgeny Khramtsov -%%% @copyright (C) 2014, Evgeny Khramtsov %%% @doc %%% %%% @end %%% Created : 21 Apr 2014 by Evgeny Khramtsov %%% +%%% %%% ejabberd, Copyright (C) 2014-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index 58ffa5029..f6b3103b7 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -1,11 +1,11 @@ %%%------------------------------------------------------------------- %%% @author Evgeny Khramtsov -%%% @copyright (C) 2014, Evgeny Khramtsov %%% @doc %%% %%% @end %%% Created : 23 Apr 2014 by Evgeny Khramtsov %%% +%%% %%% ejabberd, Copyright (C) 2014-2015 ProcessOne %%% %%% This program is free software; you can redistribute it and/or diff --git a/src/mod_stats.erl b/src/mod_stats.erl index ce97dbdf0..2604f1bb5 100644 --- a/src/mod_stats.erl +++ b/src/mod_stats.erl @@ -175,7 +175,7 @@ get_local_stat(_Server, _, Name) -> get_node_stat(Node, Name) when Name == <<"time/uptime">> -> - case catch rpc:call(Node, erlang, statistics, + case catch ejabberd_cluster:call(Node, erlang, statistics, [wall_clock]) of {badrpc, _Reason} -> @@ -188,7 +188,7 @@ get_node_stat(Node, Name) end; get_node_stat(Node, Name) when Name == <<"time/cputime">> -> - case catch rpc:call(Node, erlang, statistics, [runtime]) + case catch ejabberd_cluster:call(Node, erlang, statistics, [runtime]) of {badrpc, _Reason} -> ?STATERR(<<"500">>, <<"Internal Server Error">>); @@ -200,7 +200,7 @@ get_node_stat(Node, Name) end; get_node_stat(Node, Name) when Name == <<"users/online">> -> - case catch rpc:call(Node, ejabberd_sm, + case catch ejabberd_cluster:call(Node, ejabberd_sm, dirty_get_my_sessions_list, []) of {badrpc, _Reason} -> @@ -211,7 +211,7 @@ get_node_stat(Node, Name) end; get_node_stat(Node, Name) when Name == <<"transactions/committed">> -> - case catch rpc:call(Node, mnesia, system_info, + case catch ejabberd_cluster:call(Node, mnesia, system_info, [transaction_commits]) of {badrpc, _Reason} -> @@ -222,7 +222,7 @@ get_node_stat(Node, Name) end; get_node_stat(Node, Name) when Name == <<"transactions/aborted">> -> - case catch rpc:call(Node, mnesia, system_info, + case catch ejabberd_cluster:call(Node, mnesia, system_info, [transaction_failures]) of {badrpc, _Reason} -> @@ -233,7 +233,7 @@ get_node_stat(Node, Name) end; get_node_stat(Node, Name) when Name == <<"transactions/restarted">> -> - case catch rpc:call(Node, mnesia, system_info, + case catch ejabberd_cluster:call(Node, mnesia, system_info, [transaction_restarts]) of {badrpc, _Reason} -> @@ -244,7 +244,7 @@ get_node_stat(Node, Name) end; get_node_stat(Node, Name) when Name == <<"transactions/logged">> -> - case catch rpc:call(Node, mnesia, system_info, + case catch ejabberd_cluster:call(Node, mnesia, system_info, [transaction_log_writes]) of {badrpc, _Reason} -> diff --git a/src/node_pep.erl b/src/node_pep.erl index b219f6449..15877b073 100644 --- a/src/node_pep.erl +++ b/src/node_pep.erl @@ -54,7 +54,8 @@ init(Host, ServerHost, Opts) -> ok. terminate(Host, ServerHost) -> - node_flat:terminate(Host, ServerHost), ok. + node_flat:terminate(Host, ServerHost), + ok. options() -> [{deliver_payloads, true}, diff --git a/src/node_pep_odbc.erl b/src/node_pep_odbc.erl index 39ea8f0b7..8df25c9b1 100644 --- a/src/node_pep_odbc.erl +++ b/src/node_pep_odbc.erl @@ -55,7 +55,8 @@ init(Host, ServerHost, Opts) -> ok. terminate(Host, ServerHost) -> - node_flat_odbc:terminate(Host, ServerHost), ok. + node_flat_odbc:terminate(Host, ServerHost), + ok. options() -> [{odbc, true}, {rsm, true} | node_pep:options()].