From ba2b650464bd3aae2b6b0f3a3177476360cb6d08 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Tue, 23 Jan 2018 10:54:52 +0300 Subject: [PATCH] Introduce new gen_mod callback: mod_options/1 The callback is supposed to provide known options and their default values, as long as the documentation. Passing default values into get_mod functions is now deprecated: all defaults should be provided by the Mod:mod_options/1 callback. --- src/ejabberd_bosh.erl | 20 +- src/ejabberd_c2s.erl | 21 +- src/ejabberd_config.erl | 93 +++----- src/ejabberd_db_modules.erl | 44 ---- src/ejabberd_listener.erl | 9 +- src/ejabberd_options.erl | 44 ---- src/ejabberd_web_admin.erl | 20 +- src/eldap.erl | 21 +- src/eldap_utils.erl | 55 ++++- src/gen_mod.erl | 395 ++++++++++++++++++++++----------- src/mod_adhoc.erl | 20 +- src/mod_admin_extra.erl | 6 +- src/mod_admin_update_sql.erl | 4 +- src/mod_announce.erl | 40 ++-- src/mod_avatar.erl | 14 +- src/mod_block_strangers.erl | 19 +- src/mod_blocking.erl | 12 +- src/mod_bosh.erl | 39 ++-- src/mod_caps.erl | 42 ++-- src/mod_carboncopy.erl | 44 ++-- src/mod_client_state.erl | 28 ++- src/mod_configure.erl | 4 +- src/mod_delegation.erl | 12 +- src/mod_disco.erl | 24 +- src/mod_echo.erl | 17 +- src/mod_fail2ban.erl | 21 +- src/mod_http_api.erl | 9 +- src/mod_http_fileserver.erl | 85 +++---- src/mod_http_upload.erl | 80 ++++--- src/mod_http_upload_quota.erl | 23 +- src/mod_irc.erl | 53 +++-- src/mod_last.erl | 41 ++-- src/mod_last_mnesia.erl | 4 +- src/mod_legacy_auth.erl | 4 +- src/mod_mam.erl | 60 ++--- src/mod_metrics.erl | 13 +- src/mod_mix.erl | 14 +- src/mod_muc.erl | 123 +++++----- src/mod_muc_admin.erl | 23 +- src/mod_muc_log.erl | 47 ++-- src/mod_muc_room.erl | 59 +++-- src/mod_multicast.erl | 31 +-- src/mod_offline.erl | 21 +- src/mod_ping.erl | 41 ++-- src/mod_pres_counter.erl | 12 +- src/mod_privacy.erl | 42 ++-- src/mod_privacy_mnesia.erl | 4 +- src/mod_private.erl | 42 ++-- src/mod_private_mnesia.erl | 4 +- src/mod_privilege.erl | 18 +- src/mod_proxy65.erl | 36 ++- src/mod_proxy65_service.erl | 34 +-- src/mod_proxy65_stream.erl | 21 +- src/mod_pubsub.erl | 69 +++--- src/mod_push.erl | 44 ++-- src/mod_push_keepalive.erl | 28 +-- src/mod_register.erl | 56 ++--- src/mod_register_web.erl | 7 +- src/mod_roster.erl | 52 ++--- src/mod_roster_mnesia.erl | 4 +- src/mod_s2s_dialback.erl | 4 +- src/mod_service_log.erl | 10 +- src/mod_shared_roster.erl | 8 +- src/mod_shared_roster_ldap.erl | 138 +++++------- src/mod_sic.erl | 12 +- src/mod_sip.erl | 20 +- src/mod_sip_proxy.erl | 12 +- src/mod_sip_registrar.erl | 8 +- src/mod_stats.erl | 11 +- src/mod_stream_mgmt.erl | 67 +++--- src/mod_time.erl | 12 +- src/mod_vcard.erl | 59 +++-- src/mod_vcard_ldap.erl | 127 ++++------- src/mod_vcard_mnesia.erl | 10 +- src/mod_vcard_xupdate.erl | 34 ++- src/mod_version.erl | 15 +- 76 files changed, 1455 insertions(+), 1364 deletions(-) delete mode 100644 src/ejabberd_db_modules.erl delete mode 100644 src/ejabberd_options.erl diff --git a/src/ejabberd_bosh.erl b/src/ejabberd_bosh.erl index c3e82c616..4a552f43c 100644 --- a/src/ejabberd_bosh.erl +++ b/src/ejabberd_bosh.erl @@ -71,16 +71,12 @@ -define(NS_HTTP_BIND, <<"http://jabber.org/protocol/httpbind">>). --define(DEFAULT_MAXPAUSE, 120). - -define(DEFAULT_WAIT, 300). -define(DEFAULT_HOLD, 1). -define(DEFAULT_POLLING, 2). --define(DEFAULT_INACTIVITY, 30). - -define(MAX_SHAPED_REQUESTS_QUEUE_LEN, 1000). -define(SEND_TIMEOUT, 15000). @@ -102,7 +98,7 @@ inactivity_timer :: reference() | undefined, wait_timer :: reference() | undefined, wait_timeout = ?DEFAULT_WAIT :: timeout(), - inactivity_timeout = ?DEFAULT_INACTIVITY :: timeout(), + inactivity_timeout :: timeout(), prev_rid = 0 :: non_neg_integer(), prev_key = <<"">> :: binary(), prev_poll :: erlang:timestamp() | undefined, @@ -294,7 +290,7 @@ init([#body{attrs = Attrs}, IP, SID]) -> XMPPVer = get_attr('xmpp:version', Attrs), XMPPDomain = get_attr(to, Attrs), {InBuf, Opts} = case gen_mod:get_module_opt( - XMPPDomain, mod_bosh, prebind, false) of + XMPPDomain, mod_bosh, prebind) of true -> JID = make_random_jid(XMPPDomain), {buf_new(XMPPDomain), [{jid, JID} | Opts2]}; @@ -306,10 +302,8 @@ init([#body{attrs = Attrs}, IP, SID]) -> xmpp_socket:start(ejabberd_c2s, ?MODULE, Socket, [{receiver, self()}|Opts]), Inactivity = gen_mod:get_module_opt(XMPPDomain, - mod_bosh, max_inactivity, - ?DEFAULT_INACTIVITY), - MaxConcat = gen_mod:get_module_opt(XMPPDomain, mod_bosh, max_concat, - unlimited), + mod_bosh, max_inactivity), + MaxConcat = gen_mod:get_module_opt(XMPPDomain, mod_bosh, max_concat), ShapedReceivers = buf_new(XMPPDomain, ?MAX_SHAPED_REQUESTS_QUEUE_LEN), State = #state{host = XMPPDomain, sid = SID, ip = IP, xmpp_ver = XMPPVer, el_ibuf = InBuf, @@ -354,8 +348,7 @@ wait_for_session(#body{attrs = Attrs} = Req, From, true -> {undefined, []} end, MaxPause = gen_mod:get_module_opt(State#state.host, - mod_bosh, max_pause, - ?DEFAULT_MAXPAUSE), + mod_bosh, max_pause), Resp = #body{attrs = [{sid, State#state.sid}, {wait, Wait}, {ver, ?BOSH_VERSION}, {polling, ?DEFAULT_POLLING}, @@ -1028,8 +1021,7 @@ buf_new(Host) -> buf_new(Host, Limit) -> QueueType = gen_mod:get_module_opt( - Host, mod_bosh, queue_type, - ejabberd_config:default_queue_type(Host)), + Host, mod_bosh, queue_type), p1_queue:new(QueueType, Limit). buf_in(Xs, Buf) -> diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index f7930f725..6e7ba1e67 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -648,7 +648,7 @@ process_presence_out(#{user := User, server := Server, lserver := LServer, #presence{from = From, to = To, type = Type} = Pres) -> if Type == subscribe; Type == subscribed; Type == unsubscribe; Type == unsubscribed -> - Access = gen_mod:get_module_opt(LServer, mod_roster, access, all), + Access = gen_mod:get_module_opt(LServer, mod_roster, access), MyBareJID = jid:remove_resource(JID), case acl:match_rule(LServer, Access, MyBareJID) of deny -> @@ -1025,20 +1025,19 @@ listen_opt_type(max_stanza_size) -> end; listen_opt_type(max_fsm_queue) -> fun(I) when is_integer(I), I>0 -> I end; -%% The following hack should be removed in future releases: it is intended -%% for backward compatibility with ejabberd 17.01 or older listen_opt_type(stream_management) -> - ?WARNING_MSG("listening option 'stream_management' is deprecated: " - "use mod_stream_mgmt module", []), + ?ERROR_MSG("listening option 'stream_management' is ignored: " + "use mod_stream_mgmt module", []), fun(B) when is_boolean(B) -> B end; listen_opt_type(O) -> - case mod_stream_mgmt:mod_opt_type(O) of - L when is_list(L) -> + StreamOpts = mod_stream_mgmt:mod_options(?MYNAME), + case lists:keyfind(O, 1, StreamOpts) of + false -> [access, shaper, certfile, ciphers, dhfile, cafile, protocol_options, tls, tls_compression, starttls, starttls_required, tls_verify, zlib, max_fsm_queue]; - VFun -> - ?WARNING_MSG("listening option '~s' is deprecated: use '~s' " - "option from mod_stream_mgmt module", [O, O]), - VFun + _ -> + ?ERROR_MSG("Listening option '~s' is ignored: use '~s' " + "option from mod_stream_mgmt module", [O, O]), + mod_stream_mgmt:mod_opt_type(O) end. diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 0fa3afe29..7b275bf6c 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -28,7 +28,6 @@ -export([start/0, load_file/1, reload_file/0, read_file/1, get_option/1, get_option/2, add_option/2, has_option/1, - get_vh_by_auth_method/1, get_version/0, get_myhosts/0, get_mylang/0, get_lang/1, get_ejabberd_config_path/0, is_using_elixir_config/0, prepare_opt_val/4, transform_options/1, collect_options/1, @@ -71,8 +70,10 @@ start() -> ConfigFile = get_ejabberd_config_path(), ?INFO_MSG("Loading configuration from ~s", [ConfigFile]), - p1_options:start_link(ejabberd_options), - p1_options:start_link(ejabberd_db_modules), + catch ets:new(ejabberd_options, + [named_table, public, {read_concurrency, true}]), + catch ets:new(ejabberd_db_modules, + [named_table, public, {read_concurrency, true}]), State1 = load_file(ConfigFile), UnixTime = p1_time_compat:system_time(seconds), SharedKey = case erlang:get_cookie() of @@ -105,8 +106,10 @@ hosts_to_start(State) -> %% At the moment, these functions are mainly used to setup unit tests. -spec start(Hosts :: [binary()], Opts :: [acl:acl() | local_config()]) -> ok. start(Hosts, Opts) -> - p1_options:start_link(ejabberd_options), - p1_options:start_link(ejabberd_db_modules), + catch ets:new(ejabberd_options, + [named_table, public, {read_concurrency, true}]), + catch ets:new(ejabberd_db_modules, + [named_table, public, {read_concurrency, true}]), set_opts(set_hosts_in_options(Hosts, #state{opts = Opts})), ok. @@ -758,17 +761,12 @@ append_option({Opt, Host}, Val, State) -> set_opts(State) -> Opts = State#state.opts, - ets:select_delete(ejabberd_options, - ets:fun2ms( - fun({{node_start, _}, _}) -> false; - ({{shared_key, _}, _}) -> false; - (_) -> true - end)), - lists:foreach( - fun(#local_config{key = {Opt, Host}, value = Val}) -> - p1_options:insert(ejabberd_options, Opt, Host, Val) - end, Opts), - p1_options:compile(ejabberd_options), + ets:insert( + ejabberd_options, + lists:map( + fun(#local_config{key = Key, value = Val}) -> + {Key, Val} + end, Opts)), set_log_level(). set_log_level() -> @@ -784,8 +782,7 @@ add_local_option(Opt, Val) -> add_option(Opt, Val) when is_atom(Opt) -> add_option({Opt, global}, Val); add_option({Opt, Host}, Val) -> - p1_options:insert(ejabberd_options, Opt, Host, Val), - p1_options:compile(ejabberd_options). + ets:insert(ejabberd_options, {{Opt, Host}, Val}). -spec prepare_opt_val(any(), any(), check_fun(), any()) -> any(). @@ -862,13 +859,12 @@ get_option(Opt, Default) -> "format. This is likely a bug", [Opt]), {undefined, global} end, - case ejabberd_options:is_known(Key) of - true -> - case ejabberd_options:Key(Host) of - {ok, Val} -> Val; - undefined -> Default + try ets:lookup_element(ejabberd_options, {Key, Host}, 2) + catch _:badarg when Host /= global -> + try ets:lookup_element(ejabberd_options, {Key, global}, 2) + catch _:badarg -> Default end; - false -> + _:badarg -> Default end. @@ -878,8 +874,8 @@ has_option(Opt) -> init_module_db_table(Modules) -> %% Dirty hack for mod_pubsub - p1_options:insert(ejabberd_db_modules, mod_pubsub, mnesia, true), - p1_options:insert(ejabberd_db_modules, mod_pubsub, sql, true), + ets:insert(ejabberd_db_modules, {{mod_pubsub, mnesia}, true}), + ets:insert(ejabberd_db_modules, {{mod_pubsub, sql}, true}), lists:foreach( fun(M) -> case re:split(atom_to_list(M), "_", [{return, list}]) of @@ -891,14 +887,13 @@ init_module_db_table(Modules) -> BareMod = list_to_atom(string:join(lists:reverse(T), "_")), case is_behaviour(BareMod, M) of true -> - p1_options:insert(ejabberd_db_modules, - BareMod, Suffix, true); + ets:insert(ejabberd_db_modules, + {{BareMod, Suffix}, true}); false -> ok end end - end, Modules), - p1_options:compile(ejabberd_db_modules). + end, Modules). is_behaviour(Behav, Mod) -> try Mod:module_info(attributes) of @@ -920,20 +915,20 @@ is_behaviour(Behav, Mod) -> v_db(Mod, internal) -> v_db(Mod, mnesia); v_db(Mod, odbc) -> v_db(Mod, sql); v_db(Mod, Type) -> - case ejabberd_db_modules:is_known(Mod) of - true -> - case ejabberd_db_modules:Mod(Type) of - {ok, _} -> Type; - _ -> erlang:error(badarg) - end; - false -> - erlang:error(badarg) + case ets:member(ejabberd_db_modules, {Mod, Type}) of + true -> Type; + false -> erlang:error(badarg) end. -spec v_dbs(module()) -> [atom()]. v_dbs(Mod) -> - ejabberd_db_modules:get_scope(Mod). + ets:select( + ejabberd_db_modules, + ets:fun2ms( + fun({{M, Type}, _}) when M == Mod -> + Type + end)). -spec v_dbs_mods(module()) -> [module()]. @@ -1039,26 +1034,6 @@ validate_opts(#state{opts = Opts} = State, ModOpts) -> end, Opts), State#state{opts = NewOpts}. --spec get_vh_by_auth_method(atom()) -> [binary()]. - -%% Return the list of hosts with a given auth method -get_vh_by_auth_method(AuthMethod) -> - Hosts = ejabberd_options:get_scope(auth_method), - get_vh_by_auth_method(AuthMethod, Hosts, []). - -get_vh_by_auth_method(Method, [Host|Hosts], Result) -> - Methods = get_option({auth_method, Host}, []), - case lists:member(Method, Methods) of - true when Host == global -> - get_myhosts(); - true -> - get_vh_by_auth_method(Method, Hosts, [Host|Result]); - false -> - get_vh_by_auth_method(Method, Hosts, Result) - end; -get_vh_by_auth_method(_, [], Result) -> - Result. - %% @spec (Path::string()) -> true | false is_file_readable(Path) -> case file:read_file_info(Path) of diff --git a/src/ejabberd_db_modules.erl b/src/ejabberd_db_modules.erl deleted file mode 100644 index 4e8356942..000000000 --- a/src/ejabberd_db_modules.erl +++ /dev/null @@ -1,44 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov -%%% @doc -%%% This is a stub module which will be replaced during -%%% configuration load via p1_options:compile/1 -%%% The only purpose of this file is to shut up xref/dialyzer -%%% @end -%%% Created : 27 Apr 2017 by Evgeny Khramtsov -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2018 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_db_modules). - -%% API --export([is_known/1, get_scope/1]). - -%%%=================================================================== -%%% API -%%%=================================================================== -is_known(_) -> - false. - -get_scope(_) -> - []. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl index 56843e5b5..297a9c486 100644 --- a/src/ejabberd_listener.erl +++ b/src/ejabberd_listener.erl @@ -572,9 +572,16 @@ transform_options({listen, LOpts}, Opts) -> transform_options(Opt, Opts) -> [Opt|Opts]. +known_listen_options(Module) -> + try Module:listen_options() of + Opts -> [element(1, Opt) || Opt <- Opts] + catch _:undef -> + Module:listen_opt_type('') + end. + -spec validate_module_options(module(), [{atom(), any()}]) -> [{atom(), any()}]. validate_module_options(Module, Opts) -> - try Module:listen_opt_type('') of + try known_listen_options(Module) of _ -> maybe_start_zlib(Opts), lists:filtermap( diff --git a/src/ejabberd_options.erl b/src/ejabberd_options.erl deleted file mode 100644 index 649c2e4d2..000000000 --- a/src/ejabberd_options.erl +++ /dev/null @@ -1,44 +0,0 @@ -%%%------------------------------------------------------------------- -%%% @author Evgeny Khramtsov -%%% @doc -%%% This is a stub module which will be replaced during -%%% configuration load via p1_options:compile/1 -%%% The only purpose of this file is to shut up xref/dialyzer -%%% @end -%%% Created : 16 Apr 2017 by Evgeny Khramtsov -%%% -%%% -%%% ejabberd, Copyright (C) 2002-2018 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_options). - -%% API --export([is_known/1, get_scope/1]). - -%%%=================================================================== -%%% API -%%%=================================================================== -is_known(_) -> - false. - -get_scope(_) -> - []. - -%%%=================================================================== -%%% Internal functions -%%%=================================================================== diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl index 52e721a91..da9664a48 100644 --- a/src/ejabberd_web_admin.erl +++ b/src/ejabberd_web_admin.erl @@ -74,26 +74,20 @@ get_acl_rule([<<"vhosts">>], _) -> %% The pages of a vhost are only accesible if the user is admin of that vhost: get_acl_rule([<<"server">>, VHost | _RPath], Method) when Method =:= 'GET' orelse Method =:= 'HEAD' -> - AC = gen_mod:get_module_opt(VHost, ejabberd_web_admin, - access, configure), - ACR = gen_mod:get_module_opt(VHost, ejabberd_web_admin, - access_readonly, webadmin_view), + AC = ejabberd_config:get_option({access, VHost}, configure), + ACR = ejabberd_config:get_option({access_readonly, VHost}, webadmin_view), {VHost, [AC, ACR]}; get_acl_rule([<<"server">>, VHost | _RPath], 'POST') -> - AC = gen_mod:get_module_opt(VHost, ejabberd_web_admin, - access, configure), + AC = ejabberd_config:get_option({access, VHost}, configure), {VHost, [AC]}; %% Default rule: only global admins can access any other random page get_acl_rule(_RPath, Method) when Method =:= 'GET' orelse Method =:= 'HEAD' -> - AC = gen_mod:get_module_opt(global, ejabberd_web_admin, - access, configure), - ACR = gen_mod:get_module_opt(global, ejabberd_web_admin, - access_readonly, webadmin_view), + AC = ejabberd_config:get_option(access, configure), + ACR = ejabberd_config:get_option(access_readonly, webadmin_view), {global, [AC, ACR]}; get_acl_rule(_RPath, 'POST') -> - AC = gen_mod:get_module_opt(global, ejabberd_web_admin, - access, configure), + AC = ejabberd_config:get_option(access, configure), {global, [AC]}. %%%================================== @@ -1274,7 +1268,7 @@ get_offlinemsg_module(Server) -> end. get_lastactivity_menuitem_list(Server) -> - case gen_mod:db_type(Server, mod_last) of + case gen_mod:get_module_opt(Server, mod_last, db_type) of mnesia -> [{<<"last-activity">>, <<"Last Activity">>}]; _ -> [] end. diff --git a/src/eldap.erl b/src/eldap.erl index 8e6b710b1..03651c508 100644 --- a/src/eldap.erl +++ b/src/eldap.erl @@ -1046,8 +1046,6 @@ polish([], Res, Ref) -> {Res, Ref}. %%----------------------------------------------------------------------- connect_bind(S) -> Host = next_host(S#eldap.host, S#eldap.hosts), - ?INFO_MSG("LDAP connection on ~s:~p", - [Host, S#eldap.port]), Opts = if S#eldap.tls == tls -> [{packet, asn1}, {active, true}, {keepalive, true}, binary @@ -1056,6 +1054,8 @@ connect_bind(S) -> [{packet, asn1}, {active, true}, {keepalive, true}, {send_timeout, ?SEND_TIMEOUT}, binary] end, + ?DEBUG("Connecting to LDAP server at ~s:~p with options ~p", + [Host, S#eldap.port, Opts]), HostS = binary_to_list(Host), SocketData = case S#eldap.tls of tls -> @@ -1080,9 +1080,8 @@ connect_bind(S) -> {ok, connecting, NewS#eldap{host = Host}} end; {error, Reason} -> - ?ERROR_MSG("LDAP connection failed:~n** Server: " - "~s:~p~n** Reason: ~p~n** Socket options: ~p", - [Host, S#eldap.port, Reason, Opts]), + ?ERROR_MSG("LDAP connection to ~s:~b failed: ~s", + [Host, S#eldap.port, format_error(SockMod, Reason)]), NewS = close_and_retry(S), {ok, connecting, NewS#eldap{host = Host}} end. @@ -1121,3 +1120,15 @@ bump_id(#eldap{id = Id}) when Id > (?MAX_TRANSACTION_ID) -> ?MIN_TRANSACTION_ID; bump_id(#eldap{id = Id}) -> Id + 1. + +format_error(SockMod, Reason) -> + Txt = case SockMod of + ssl -> ssl:format_error(Reason); + gen_tcp -> inet:format_error(Reason) + end, + case Txt of + "unknown POSIX error" -> + lists:flatten(io_lib:format("~p", [Reason])); + _ -> + Txt + end. diff --git a/src/eldap_utils.erl b/src/eldap_utils.erl index 38bc72069..0a0d3f965 100644 --- a/src/eldap_utils.erl +++ b/src/eldap_utils.erl @@ -31,7 +31,8 @@ -export([generate_subfilter/1, find_ldap_attrs/2, check_filter/1, get_ldap_attr/2, get_user_part/2, make_filter/2, get_state/2, case_insensitive_match/2, get_config/2, - decode_octet_string/3, uids_domain_subst/2, opt_type/1]). + decode_octet_string/3, uids_domain_subst/2, opt_type/1, + options/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -180,12 +181,16 @@ get_config(Host, Opts) -> TLSCertFile = get_opt(ldap_tls_certfile, Host, Opts), TLSCAFile = get_opt(ldap_tls_cacertfile, Host, Opts), TLSDepth = get_opt(ldap_tls_depth, Host, Opts), - Port = get_opt(ldap_port, Host, Opts, + Port = case get_opt(ldap_port, Host, Opts) of + undefined -> case Encrypt of tls -> ?LDAPS_PORT; starttls -> ?LDAP_PORT; _ -> ?LDAP_PORT - end), + end; + P -> + P + end, RootDN = get_opt(ldap_rootdn, Host, Opts, <<"">>), Password = get_opt(ldap_password, Host, Opts, <<"">>), Base = get_opt(ldap_base, Host, Opts, <<"">>), @@ -348,7 +353,12 @@ collect_parts_bit([],Acc,Uacc) -> (ldap_uids) -> fun((uids()) -> uids()); (atom()) -> [atom()]. opt_type(deref_aliases) -> - opt_type(ldap_deref_aliases); + fun(unspecified) -> unspecified; + (never) -> never; + (searching) -> searching; + (finding) -> finding; + (always) -> always + end; opt_type(ldap_backups) -> fun (L) -> [iolist_to_binary(H) || H <- L] end; opt_type(ldap_base) -> fun iolist_to_binary/1; @@ -365,25 +375,33 @@ opt_type(ldap_encrypt) -> end; opt_type(ldap_password) -> fun iolist_to_binary/1; opt_type(ldap_port) -> - fun (I) when is_integer(I), I > 0 -> I end; + fun(undefined) -> undefined; + (I) when is_integer(I), I > 0 -> I + end; opt_type(ldap_rootdn) -> fun iolist_to_binary/1; opt_type(ldap_servers) -> fun (L) -> [iolist_to_binary(H) || H <- L] end; opt_type(ldap_tls_certfile) -> - fun(S) -> - binary_to_list(ejabberd_pkix:try_certfile(S)) + fun(undefined) -> undefined; + (S) -> binary_to_list(ejabberd_pkix:try_certfile(S)) end; opt_type(ldap_tls_cacertfile) -> - fun(S) -> binary_to_list(misc:try_read_file(S)) end; + fun(undefined) -> undefined; + (S) -> binary_to_list(misc:try_read_file(S)) + end; opt_type(ldap_tls_depth) -> - fun (I) when is_integer(I), I >= 0 -> I end; + fun(undefined) -> undefined; + (I) when is_integer(I), I >= 0 -> I + end; opt_type(ldap_tls_verify) -> fun (hard) -> hard; (soft) -> soft; (false) -> false end; opt_type(ldap_filter) -> - fun check_filter/1; + fun(<<"">>) -> <<"">>; + (F) -> check_filter(F) + end; opt_type(ldap_uids) -> fun (Us) -> lists:map(fun ({U, P}) -> @@ -399,3 +417,20 @@ opt_type(_) -> ldap_port, ldap_rootdn, ldap_servers, ldap_filter, ldap_tls_certfile, ldap_tls_cacertfile, ldap_tls_depth, ldap_tls_verify]. + +options(_) -> + [{deref_aliases, unspecified}, + {ldap_backups, []}, + {ldap_base, <<"">>}, + {ldap_uids, [{<<"uid">>, <<"%u">>}]}, + {ldap_deref_aliases, never}, + {ldap_encrypt, none}, + {ldap_password, <<"">>}, + {ldap_port, undefined}, + {ldap_rootdn, <<"">>}, + {ldap_servers, [<<"localhost">>]}, + {ldap_filter, <<"">>}, + {ldap_tls_certfile, undefined}, + {ldap_tls_cacertfile, undefined}, + {ldap_tls_depth, undefined}, + {ldap_tls_verify, false}]. diff --git a/src/gen_mod.erl b/src/gen_mod.erl index a2befc60e..98d7d398f 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -34,18 +34,28 @@ stop_child/1, stop_child/2, config_reloaded/0]). -export([start_module/2, start_module/3, stop_module/2, stop_module_keep_config/2, - get_opt/2, get_opt/3, get_opt_host/3, - get_opt_hosts/3, opt_type/1, is_equal_opt/4, - get_module_opt/3, get_module_opt/4, get_module_opt_host/3, + get_opt/2, get_opt_hosts/2, opt_type/1, is_equal_opt/3, + get_module_opt/3, get_module_opt_host/3, loaded_modules/1, loaded_modules_with_opts/1, get_hosts/2, get_module_proc/2, is_loaded/2, is_loaded_elsewhere/2, start_modules/0, start_modules/1, stop_modules/0, stop_modules/1, db_mod/2, db_mod/3, ram_db_mod/2, ram_db_mod/3, - db_type/2, db_type/3, ram_db_type/2, ram_db_type/3]). + is_db_configured/2]). %% Deprecated functions --export([get_opt/4, get_module_opt/5]). --deprecated([{get_opt, 4}, {get_module_opt, 5}]). +-export([get_opt/3, get_opt/4, get_module_opt/4, get_module_opt/5, + get_opt_host/3, get_opt_hosts/3, db_type/2, db_type/3, + ram_db_type/2, ram_db_type/3]). +-deprecated([{get_opt, 3}, + {get_opt, 4}, + {get_opt_host, 3}, + {get_opt_hosts, 3}, + {get_module_opt, 4}, + {get_module_opt, 5}, + {db_type, 2}, + {db_type, 3}, + {ram_db_type, 2}, + {ram_db_type, 3}]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -62,9 +72,10 @@ -callback stop(binary()) -> any(). -callback reload(binary(), opts(), opts()) -> ok | {ok, pid()}. -callback mod_opt_type(atom()) -> fun((term()) -> term()) | [atom()]. +-callback mod_options(binary()) -> opts(). -callback depends(binary(), opts()) -> [{module(), hard | soft}]. --optional_callbacks([reload/3]). +-optional_callbacks([mod_opt_type/1, reload/3]). -export_type([opts/0]). -export_type([db_type/0]). @@ -122,7 +133,7 @@ start_modules() -> end, ?MYHOSTS). get_modules_options(Host) -> - ejabberd_config:get_option({modules, Host}, []). + sort_modules(Host, ejabberd_config:get_option({modules, Host})). sort_modules(Host, ModOpts) -> G = digraph:new([acyclic]), @@ -135,7 +146,7 @@ sort_modules(Host, ModOpts) -> case lists:keyfind(DepMod, 1, ModOpts) of false when Type == hard -> ErrTxt = io_lib:format( - "failed to load module '~s' " + "Failed to load module '~s' " "because it depends on module '~s' " "which is not found in the config", [Mod, DepMod]), @@ -143,7 +154,7 @@ sort_modules(Host, ModOpts) -> digraph:del_vertex(G, Mod), maybe_halt_ejabberd(ErrTxt); false when Type == soft -> - ?WARNING_MSG("module '~s' is recommended for " + ?WARNING_MSG("Module '~s' is recommended for " "module '~s' but is not found in " "the config", [DepMod, Mod]); @@ -151,7 +162,7 @@ sort_modules(Host, ModOpts) -> digraph:add_vertex(G, DepMod, DepOpts), case digraph:add_edge(G, DepMod, Mod) of {error, {bad_edge, Path}} -> - ?WARNING_MSG("cyclic dependency detected " + ?WARNING_MSG("Cyclic dependency detected " "between modules: ~p", [Path]); _ -> @@ -167,7 +178,7 @@ sort_modules(Host, ModOpts) -> -spec start_modules(binary()) -> ok. start_modules(Host) -> - Modules = sort_modules(Host, get_modules_options(Host)), + Modules = get_modules_options(Host), lists:foreach( fun({Module, Opts}) -> start_module(Host, Module, Opts) @@ -190,33 +201,38 @@ start_module(Host, Module, Opts) -> -spec start_module(binary(), atom(), opts(), boolean()) -> ok | {ok, pid()}. start_module(Host, Module, Opts0, NeedValidation) -> - ?DEBUG("loading ~s at ~s", [Module, Host]), - Opts = if NeedValidation -> - validate_opts(Host, Module, Opts0); - true -> - Opts0 - end, - store_options(Host, Module, Opts), - try case Module:start(Host, Opts) of - ok -> ok; - {ok, Pid} when is_pid(Pid) -> {ok, Pid}; - Err -> erlang:error(Err) - end - catch Class:Reason -> - ets:delete(ejabberd_modules, {Module, Host}), - ErrorText = - io_lib:format("Problem starting the module ~s for host " - "~s ~n options: ~p~n ~p: ~p~n~p", - [Module, Host, Opts, Class, Reason, - erlang:get_stacktrace()]), - ?CRITICAL_MSG(ErrorText, []), - maybe_halt_ejabberd(ErrorText), - erlang:raise(Class, Reason, erlang:get_stacktrace()) + ?DEBUG("Loading ~s at ~s", [Module, Host]), + Res = if NeedValidation -> + validate_opts(Host, Module, Opts0); + true -> + {ok, Opts0} + end, + case Res of + {ok, Opts} -> + store_options(Host, Module, Opts), + try case Module:start(Host, Opts) of + ok -> ok; + {ok, Pid} when is_pid(Pid) -> {ok, Pid}; + Err -> erlang:error(Err) + end + catch Class:Reason -> + ets:delete(ejabberd_modules, {Module, Host}), + ErrorText = + io_lib:format("Problem starting the module ~s for host " + "~s ~n options: ~p~n ~p: ~p~n~p", + [Module, Host, Opts, Class, Reason, + erlang:get_stacktrace()]), + ?CRITICAL_MSG(ErrorText, []), + maybe_halt_ejabberd(ErrorText), + erlang:raise(Class, Reason, erlang:get_stacktrace()) + end; + {error, ErrorText} -> + maybe_halt_ejabberd(ErrorText) end. -spec reload_modules(binary()) -> ok. reload_modules(Host) -> - NewMods = ejabberd_config:get_option({modules, Host}, []), + NewMods = ejabberd_config:get_option({modules, Host}), OldMods = ets:select( ejabberd_modules, ets:fun2ms( @@ -246,10 +262,12 @@ reload_modules(Host) -> case lists:keyfind(Mod, 1, NewMods) of {_, NewOpts0} -> case validate_opts(Host, Mod, NewOpts0) of - OldOpts -> + {ok, OldOpts} -> ok; - NewOpts -> - reload_module(Host, Mod, NewOpts, OldOpts) + {ok, NewOpts} -> + reload_module(Host, Mod, NewOpts, OldOpts); + {error, _} -> + ok end; _ -> ok @@ -260,7 +278,7 @@ reload_modules(Host) -> reload_module(Host, Module, NewOpts, OldOpts) -> case erlang:function_exported(Module, reload, 3) of true -> - ?DEBUG("reloading ~s at ~s", [Module, Host]), + ?DEBUG("Reloading ~s at ~s", [Module, Host]), store_options(Host, Module, NewOpts), try case Module:reload(Host, NewOpts, OldOpts) of ok -> ok; @@ -269,14 +287,14 @@ reload_module(Host, Module, NewOpts, OldOpts) -> end catch Class:Reason -> StackTrace = erlang:get_stacktrace(), - ?CRITICAL_MSG("failed to reload module ~s at ~s:~n" + ?CRITICAL_MSG("Failed to reload module ~s at ~s:~n" "** Reason = ~p", [Module, Host, {Class, {Reason, StackTrace}}]), erlang:raise(Class, Reason, StackTrace) end; false -> - ?WARNING_MSG("module ~s doesn't support reloading " + ?WARNING_MSG("Module ~s doesn't support reloading " "and will be restarted", [Module]), stop_module(Host, Module), start_module(Host, Module, NewOpts, false) @@ -316,7 +334,7 @@ stop_modules() -> -spec stop_modules(binary()) -> ok. stop_modules(Host) -> - Modules = get_modules_options(Host), + Modules = lists:reverse(get_modules_options(Host)), lists:foreach( fun({Module, _Args}) -> stop_module_keep_config(Host, Module) @@ -325,7 +343,6 @@ stop_modules(Host) -> -spec stop_module(binary(), atom()) -> error | {aborted, any()} | {atomic, any()}. stop_module(Host, Module) -> - ?DEBUG("stopping ~s at ~s", [Module, Host]), case stop_module_keep_config(Host, Module) of error -> error; ok -> ok @@ -334,6 +351,7 @@ stop_module(Host, Module) -> -spec stop_module_keep_config(binary(), atom()) -> error | ok. stop_module_keep_config(Host, Module) -> + ?DEBUG("Stopping ~s at ~s", [Module, Host]), case catch Module:stop(Host) of {'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]), error; {wait, ProcList} when is_list(ProcList) -> @@ -367,21 +385,19 @@ wait_for_stop1(MonitorReference) -> -type check_fun() :: fun((any()) -> any()) | {module(), atom()}. --spec get_opt(atom() | {atom(), binary() | global}, opts()) -> any(). +-spec get_opt(atom(), opts()) -> any(). get_opt(Opt, Opts) -> - get_opt(Opt, Opts, undefined). + case lists:keyfind(Opt, 1, Opts) of + {_, Val} -> Val; + false -> + ?DEBUG("Attempt to read unspecified option ~s", [Opt]), + undefined + end. --spec get_opt(atom() | {atom(), binary()|global}, opts(), check_fun() | any()) -> any(). +-spec get_opt(atom(), opts(), check_fun() | any()) -> any(). get_opt(Opt, Opts, F) when is_function(F) -> get_opt(Opt, Opts, undefined); -get_opt({Opt, Host}, Opts, Default) -> - case lists:keyfind(Opt, 1, Opts) of - false -> - ejabberd_config:get_option({Opt, Host}, Default); - {_, Val} -> - Val - end; get_opt(Opt, Opts, Default) -> case lists:keyfind(Opt, 1, Opts) of false -> @@ -442,125 +458,228 @@ get_opt_host(Host, Opts, Default) -> Val = get_opt(host, Opts, Default), ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host). --spec get_opt_hosts(binary(), opts(), binary()) -> [binary()]. +-spec get_opt_hosts(binary(), opts()) -> [binary()]. +get_opt_hosts(Host, Opts) -> + get_opt_hosts(Host, Opts, undefined). +-spec get_opt_hosts(binary(), opts(), binary()) -> [binary()]. get_opt_hosts(Host, Opts, Default) -> - Vals = case get_opt(host, Opts, undefined) of - undefined -> - case get_opt(hosts, Opts, []) of - [] -> [Default]; - L -> L - end; - Val -> - [Val] + Vals = case get_opt(hosts, Opts) of + L when L == [] orelse L == undefined -> + case get_opt(host, Opts) of + undefined -> [Default]; + H -> [H] + end; + L -> + L end, [ejabberd_regexp:greplace(V, <<"@HOST@">>, Host) || V <- Vals]. --spec get_validators(binary(), module(), opts()) -> dict:dict() | undef. -get_validators(Host, Module, Opts) -> - try Module:mod_opt_type('') of - L -> - SubMods1 = case lists:member(db_type, L) of - true -> [db_mod(Host, Opts, Module)]; - false -> [] - end, - SubMods2 = case lists:member(ram_db_type, L) of - true -> [ram_db_mod(Host, Opts, Module)]; - false -> [] - end, - lists:foldl( - fun(Mod, D) -> - try Mod:mod_opt_type('') of - Os -> - lists:foldl( - fun({Opt, SubOpt} = O, Acc) -> - SubF = Mod:mod_opt_type(O), - F = case Mod:mod_opt_type(Opt) of - F1 when is_function(F1) -> - F1; - _ -> - fun(X) -> X end - end, - dict:append_list( - Opt, [F, {SubOpt, [SubF]}], Acc); - (O, Acc) -> - F = Mod:mod_opt_type(O), - dict:store(O, [F], Acc) - end, D, Os) - catch _:undef -> - D - end - end, dict:new(), [Module|SubMods1 ++ SubMods2]) - catch _:undef -> - ?WARNING_MSG("module '~s' doesn't export mod_opt_type/1", - [Module]), - undef +-spec get_validators(binary(), {module(), [module()]}) -> list() | undef. +get_validators(Host, {Module, SubMods}) -> + Validators = + dict:to_list( + lists:foldl( + fun(Mod, D) -> + try list_known_opts(Host, Mod) of + Os -> + lists:foldl( + fun({Opt, SubOpt} = O, Acc) -> + SubF = Mod:mod_opt_type(O), + F = try Mod:mod_opt_type(Opt) + catch _:_ -> fun(X) -> X end + end, + dict:append_list( + Opt, [F, {SubOpt, [SubF]}], Acc); + (O, Acc) -> + F = Mod:mod_opt_type(O), + dict:store(O, [F], Acc) + end, D, Os) + catch _:undef -> + D + end + end, dict:new(), [Module|SubMods])), + case Validators of + [] -> + case have_validators(Module) of + false -> + ?WARNING_MSG("Third-party module '~s' doesn't export " + "options validator; consider to upgrade " + "the module", [Module]), + undef; + true -> + [] + end; + _ -> + Validators end. --spec validate_opts(binary(), module(), opts()) -> opts(). -validate_opts(Host, Module, Opts) -> - case get_validators(Host, Module, Opts) of - undef -> - Opts; - Validators -> - validate_opts(Host, Module, Opts, dict:to_list(Validators)) +-spec have_validators(module()) -> boolean(). +have_validators(Module) -> + erlang:function_exported(Module, mod_options, 1) + orelse erlang:function_exported(Module, mod_opt_type, 1). + +-spec validate_opts(binary(), module(), opts()) -> {ok, opts()} | {error, string()}. +validate_opts(Host, Module, Opts0) -> + SubMods = get_submodules(Host, Module, Opts0), + DefaultOpts = lists:flatmap( + fun(M) -> + try M:mod_options(Host) + catch _:undef -> [] + end + end, [Module|SubMods]), + Required = lists:filter(fun is_atom/1, DefaultOpts), + try + Opts = merge_opts(Opts0, DefaultOpts), + {ok, case get_validators(Host, {Module, SubMods}) of + undef -> + Opts; + Validators -> + validate_opts(Host, Module, Opts, Required, Validators) + end} + catch _:{missing_required_option, Opt} -> + ErrTxt = io_lib:format("Module '~s' is missing required option '~s'", + [Module, Opt]), + ?ERROR_MSG(ErrTxt, []), + {error, ErrTxt} end. -validate_opts(Host, Module, Opts, Validators) when is_list(Opts) -> +validate_opts(Host, Module, Opts, Required, Validators) when is_list(Opts) -> lists:flatmap( fun({Opt, Val}) when is_atom(Opt) -> case lists:keyfind(Opt, 1, Validators) of {_, L} -> case lists:partition(fun is_function/1, L) of {[VFun|_], []} -> - validate_opt(Module, Opt, Val, VFun); + validate_opt(Module, Opt, Val, Required, VFun); {[VFun|_], SubValidators} -> - try validate_opts(Host, Module, Val, SubValidators) of + try validate_opts(Host, Module, Val, Required, SubValidators) of SubOpts -> - validate_opt(Module, Opt, SubOpts, VFun) + validate_opt(Module, Opt, SubOpts, Required, VFun) catch _:bad_option -> - ?ERROR_MSG("ignoring invalid value '~p' for " + ?ERROR_MSG("Ignoring invalid value '~p' for " "option '~s' of module '~s'", [Val, Opt, Module]), + fail_if_option_is_required(Opt, Required), [] end end; false -> case Validators of [] -> - ?ERROR_MSG("unknown option '~s' for module '~s' " - "will be likely ignored because the " - "module doesn't have any options", + ?ERROR_MSG("Ignoring unknown option '~s' of '~s':" + " the module doesn't have any options", [Opt, Module]); _ -> - ?ERROR_MSG("unknown option '~s' for module '~s' will be" - " likely ignored, available options are: ~s", + ?ERROR_MSG("Ignoring unknown option '~s' of '~s'," + " available options are: ~s", [Opt, Module, - misc:join_atoms([K || {K, _} <- Validators], - <<", ">>)]) + misc:join_atoms( + [K || {K, _} <- Validators], + <<", ">>)]) end, - [{Opt, Val}] + [] end; (_) -> erlang:error(bad_option) end, Opts); -validate_opts(_, _, _, _) -> +validate_opts(_, _, _, _, _) -> erlang:error(bad_option). --spec validate_opt(module(), atom(), any(), +-spec validate_opt(module(), atom(), any(), [atom()], [{atom(), check_fun(), any()}]) -> [{atom(), any()}]. -validate_opt(Module, Opt, Val, VFun) -> +validate_opt(Module, Opt, Val, Required, VFun) -> try VFun(Val) of NewVal -> [{Opt, NewVal}] catch {invalid_syntax, Error} -> - ?ERROR_MSG("ignoring invalid value '~p' for " + ?ERROR_MSG("Ignoring invalid value '~p' for " "option '~s' of module '~s': ~s", [Val, Opt, Module, Error]), + fail_if_option_is_required(Opt, Required), []; _:_ -> - ?ERROR_MSG("ignoring invalid value '~p' for " + ?ERROR_MSG("Ignoring invalid value '~p' for " "option '~s' of module '~s'", [Val, Opt, Module]), + fail_if_option_is_required(Opt, Required), + [] + end. + +-spec fail_if_option_is_required(atom(), [atom()]) -> ok | no_return(). +fail_if_option_is_required(Opt, Required) -> + case lists:member(Opt, Required) of + true -> erlang:error({missing_required_option, Opt}); + false -> ok + end. + +-spec list_known_opts(binary(), module()) -> [atom() | {atom(), atom()}]. +list_known_opts(Host, Module) -> + try Module:mod_options(Host) of + DefaultOpts -> + lists:flatmap( + fun({Opt, [{A, _}|_] = Vals}) when is_atom(A) -> + [{Opt, Val} || {Val, _} <- Vals]; + ({Opt, _}) -> [Opt]; + (Opt) -> [Opt] + end, DefaultOpts) + catch _:undef -> + Module:mod_opt_type('') + end. + +-spec merge_opts(opts(), opts()) -> opts(). +merge_opts(Opts, DefaultOpts) -> + Result = + lists:foldr( + fun({Opt, Default}, Acc) -> + case lists:keyfind(Opt, 1, Opts) of + {_, Val} -> + case Default of + [{A, _}|_] when is_atom(A) andalso is_list(Val) -> + [{Opt, merge_opts(Val, Default)}|Acc]; + Val -> + [{Opt, Default}|Acc]; + _ -> + [{Opt, Val}, {Opt, Default}|Acc] + end; + _ -> + [{Opt, Default}|Acc] + end; + (Opt, Acc) -> + case lists:keyfind(Opt, 1, Opts) of + {_, Val} -> + [{Opt, Val}|Acc]; + false -> + erlang:error({missing_required_option, Opt}) + end + end, [], DefaultOpts), + lists:foldl( + fun({Opt, Val}, Acc) -> + case lists:keymember(Opt, 1, Result) of + true -> Acc; + false -> [{Opt, Val}|Acc] + end + end, Result, Opts). + +-spec get_submodules(binary(), module(), opts()) -> [module()]. +get_submodules(Host, Module, Opts) -> + try Module:mod_options(Host) of + DefaultOpts -> + Mod1 = case lists:keyfind(db_type, 1, DefaultOpts) of + {_, T1} -> + DBType = proplists:get_value(db_type, Opts, T1), + [db_mod(DBType, Module)]; + false -> + [] + end, + Mod2 = case lists:keyfind(ram_db_type, 1, DefaultOpts) of + {_, T2} -> + RamDBType = proplists:get_value(ram_db_type, Opts, T2), + [ram_db_mod(RamDBType, Module)]; + false -> + [] + end, + Mod1 ++ Mod2 + catch _:undef -> [] end. @@ -630,6 +749,22 @@ ram_db_mod(Host, Module) when is_binary(Host) orelse Host == global -> ram_db_mod(Host, Opts, Module) when is_list(Opts) -> ram_db_mod(ram_db_type(Host, Opts, Module), Module). +is_db_configured(Type, Host) -> + lists:any( + fun(#ejabberd_module{module_host = {_, H}, opts = Opts}) + when H == Host orelse Host == global -> + case lists:keyfind(db_type, 1, Opts) of + {_, Type} -> true; + _ -> + case lists:keyfind(ram_db_type, 1, Opts) of + {_, Type} -> true; + _ -> false + end + end; + (_) -> + false + end, ets:tab2list(ejabberd_modules)). + -spec loaded_modules(binary()) -> [atom()]. loaded_modules(Host) -> @@ -689,11 +824,11 @@ config_reloaded() -> reload_modules(Host) end, ?MYHOSTS). --spec is_equal_opt(atom(), opts(), opts(), any()) -> +-spec is_equal_opt(atom(), opts(), opts()) -> true | {false, any(), any()}. -is_equal_opt(Opt, NewOpts, OldOpts, Default) -> - NewVal = get_opt(Opt, NewOpts, Default), - OldVal = get_opt(Opt, OldOpts, Default), +is_equal_opt(Opt, NewOpts, OldOpts) -> + NewVal = get_opt(Opt, NewOpts), + OldVal = get_opt(Opt, OldOpts), if NewVal /= OldVal -> {false, NewVal, OldVal}; true -> diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index ebbdb984a..4944bd011 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -35,14 +35,15 @@ process_sm_iq/1, get_local_commands/5, get_local_identity/5, get_local_features/5, get_sm_commands/5, get_sm_identity/5, get_sm_features/5, - ping_item/4, ping_command/4, mod_opt_type/1, depends/2]). + ping_item/4, ping_command/4, mod_opt_type/1, depends/2, + mod_options/1]). -include("ejabberd.hrl"). -include("logger.hrl"). -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS, ?MODULE, process_local_iq, IQDisc), @@ -88,7 +89,7 @@ stop(Host) -> ?NS_COMMANDS). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS, ?MODULE, process_local_iq, IQDisc), @@ -104,8 +105,7 @@ get_local_commands(Acc, _From, #jid{server = Server, lserver = LServer} = _To, <<"">>, Lang) -> Display = gen_mod:get_module_opt(LServer, ?MODULE, - report_commands_node, - false), + report_commands_node), case Display of false -> Acc; _ -> @@ -133,8 +133,7 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) -> get_sm_commands(Acc, _From, #jid{lserver = LServer} = To, <<"">>, Lang) -> Display = gen_mod:get_module_opt(LServer, ?MODULE, - report_commands_node, - false), + report_commands_node), case Display of false -> Acc; _ -> @@ -283,5 +282,8 @@ depends(_Host, _Opts) -> mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(report_commands_node) -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> [iqdisc, report_commands_node]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {report_commands_node, false}]. diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 1727682b8..e64cdb465 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -30,7 +30,7 @@ -include("logger.hrl"). --export([start/2, stop/1, reload/3, mod_opt_type/1, +-export([start/2, stop/1, reload/3, mod_options/1, get_commands_spec/0, depends/2]). % Commands API @@ -846,7 +846,7 @@ get_sha(AccountPass) -> || X <- binary_to_list(crypto:hash(sha, AccountPass))]). num_active_users(Host, Days) -> - DB_Type = gen_mod:db_type(Host, mod_last), + DB_Type = gen_mod:get_module_opt(Host, mod_last, db_type), list_last_activity(Host, true, Days, DB_Type). %% Code based on ejabberd/src/web/ejabberd_web_admin.erl @@ -1761,4 +1761,4 @@ is_glob_match(String, <<"!", Glob/binary>>) -> is_glob_match(String, Glob) -> is_regexp_match(String, ejabberd_regexp:sh_to_awk(Glob)). -mod_opt_type(_) -> []. +mod_options(_) -> []. diff --git a/src/mod_admin_update_sql.erl b/src/mod_admin_update_sql.erl index 6a45610c8..0eaab9ff9 100644 --- a/src/mod_admin_update_sql.erl +++ b/src/mod_admin_update_sql.erl @@ -28,7 +28,7 @@ -behaviour(gen_mod). --export([start/2, stop/1, reload/3, mod_opt_type/1, +-export([start/2, stop/1, reload/3, mod_options/1, get_commands_spec/0, depends/2]). % Commands API @@ -362,4 +362,4 @@ sql_query(Host, Query) -> ok end. -mod_opt_type(_) -> []. +mod_options(_) -> []. diff --git a/src/mod_announce.erl b/src/mod_announce.erl index 1c5493a2f..6db1e4529 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -36,7 +36,7 @@ import_start/2, import/5, announce/1, send_motd/1, disco_identity/5, disco_features/5, disco_items/5, depends/2, send_announcement_to_all/3, announce_commands/4, - announce_items/4, mod_opt_type/1, clean_cache/1]). + announce_items/4, mod_opt_type/1, mod_options/1, clean_cache/1]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -export([announce_all/1, @@ -834,7 +834,7 @@ send_announcement_to_all(Host, SubjectS, BodyS) -> -spec get_access(global | binary()) -> atom(). get_access(Host) -> - gen_mod:get_module_opt(Host, ?MODULE, access, none). + gen_mod:get_module_opt(Host, ?MODULE, access). -spec add_store_hint(stanza()) -> stanza(). add_store_hint(El) -> @@ -850,23 +850,17 @@ route_forbidden_error(Packet) -> init_cache(Mod, Host, Opts) -> case use_cache(Mod, Host) of true -> - CacheOpts = cache_opts(Host, Opts), + CacheOpts = cache_opts(Opts), ets_cache:new(?MOTD_CACHE, CacheOpts); false -> ets_cache:delete(?MOTD_CACHE) end. --spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +-spec cache_opts(gen_mod:opts()) -> [proplists:property()]. +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -876,10 +870,7 @@ cache_opts(Host, Opts) -> use_cache(Mod, Host) -> case erlang:function_exported(Mod, use_cache, 1) of true -> Mod:use_cache(Host); - false -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache) end. -spec cache_nodes(module(), binary()) -> [node()]. @@ -918,7 +909,12 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size -> (infinity) -> infinity end; mod_opt_type(O) when O == use_cache; O == cache_missed -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [access, db_type, cache_life_time, cache_size, - use_cache, cache_missed]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{access, none}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_avatar.erl b/src/mod_avatar.erl index 778794e1a..48e963ff6 100644 --- a/src/mod_avatar.erl +++ b/src/mod_avatar.erl @@ -24,7 +24,7 @@ -behaviour(gen_mod). %% gen_mod API --export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1]). +-export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1, mod_options/1]). %% Hooks -export([pubsub_publish_item/6, vcard_iq_convert/1, vcard_iq_publish/1]). @@ -375,7 +375,7 @@ stop_with_error(Lang, Reason) -> -spec get_converting_rules(binary()) -> convert_rules(). get_converting_rules(LServer) -> - gen_mod:get_module_opt(LServer, ?MODULE, convert, []). + gen_mod:get_module_opt(LServer, ?MODULE, convert). -spec get_type(binary()) -> eimp:img_type() | unknown. get_type(Data) -> @@ -429,11 +429,13 @@ mod_opt_type({convert, From}) -> false -> fail(From); true -> - case eimp:is_supported(To) of + case eimp:is_supported(To) orelse To == undefined of false -> fail(To); true -> To end end - end; -mod_opt_type(_) -> - [{convert, T} || T <- [default|eimp:supported_formats()]]. + end. + +mod_options(_) -> + [{convert, + [{T, undefined} || T <- [default|eimp:supported_formats()]]}]. diff --git a/src/mod_block_strangers.erl b/src/mod_block_strangers.erl index 2d49e2e8e..d427ef9a6 100644 --- a/src/mod_block_strangers.erl +++ b/src/mod_block_strangers.erl @@ -30,7 +30,7 @@ %% API -export([start/2, stop/1, reload/3, - depends/2, mod_opt_type/1]). + depends/2, mod_opt_type/1, mod_options/1]). -export([filter_packet/1, filter_offline_msg/1]). @@ -82,7 +82,7 @@ filter_offline_msg({_Action, #message{} = Msg} = Acc) -> check_message(#message{from = From, to = To, lang = Lang} = Msg) -> LServer = To#jid.lserver, AllowLocalUsers = - gen_mod:get_module_opt(LServer, ?MODULE, allow_local_users, true), + gen_mod:get_module_opt(LServer, ?MODULE, allow_local_users), case (Msg#message.body == [] andalso Msg#message.subject == []) orelse ((AllowLocalUsers orelse From#jid.luser == <<"">>) andalso @@ -90,8 +90,8 @@ check_message(#message{from = From, to = To, lang = Lang} = Msg) -> false -> case check_subscription(From, To) of none -> - Drop = gen_mod:get_module_opt(LServer, ?MODULE, drop, true), - Log = gen_mod:get_module_opt(LServer, ?MODULE, log, false), + Drop = gen_mod:get_module_opt(LServer, ?MODULE, drop), + Log = gen_mod:get_module_opt(LServer, ?MODULE, log), if Log -> ?INFO_MSG("~s message from stranger ~s to ~s", @@ -129,7 +129,7 @@ check_subscription(From, To) -> none; {none, _} -> case gen_mod:get_module_opt(LocalServer, ?MODULE, - allow_transports, true) of + allow_transports) of true -> %% Check if the contact's server is in the roster case ejabberd_hooks:run_fold( @@ -182,5 +182,10 @@ mod_opt_type(log) -> mod_opt_type(allow_local_users) -> fun (B) when is_boolean(B) -> B end; mod_opt_type(allow_transports) -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> [drop, log, allow_local_users, allow_transports]. + fun (B) when is_boolean(B) -> B end. + +mod_options(_) -> + [{drop, true}, + {log, false}, + {allow_local_users, true}, + {allow_transports, true}]. diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index 620586f2c..c10adf553 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -30,7 +30,7 @@ -protocol({xep, 191, '1.2'}). -export([start/2, stop/1, reload/3, process_iq/1, mod_opt_type/1, depends/2, - disco_features/5]). + disco_features/5, mod_options/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -40,7 +40,7 @@ -include("mod_privacy.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING, ?MODULE, process_iq, IQDisc). @@ -50,7 +50,7 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING, ?MODULE, process_iq, IQDisc); @@ -267,5 +267,7 @@ err_db_failure(#iq{lang = Lang} = IQ) -> Txt = <<"Database failure">>, xmpp:make_error(IQ, xmpp:err_internal_server_error(Txt, Lang)). -mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; -mod_opt_type(_) -> [iqdisc]. +mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}]. diff --git a/src/mod_bosh.erl b/src/mod_bosh.erl index 913e19644..face1692c 100644 --- a/src/mod_bosh.erl +++ b/src/mod_bosh.erl @@ -36,7 +36,7 @@ -export([start/2, stop/1, reload/3, process/2, open_session/2, close_session/1, find_session/1, clean_cache/1]). --export([depends/2, mod_opt_type/1]). +-export([depends/2, mod_opt_type/1, mod_options/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -144,7 +144,7 @@ reload(_Host, NewOpts, _OldOpts) -> %%% Internal functions %%%=================================================================== start_jiffy(Opts) -> - case gen_mod:get_opt(json, Opts, false) of + case gen_mod:get_opt(json, Opts) of false -> ok; true -> @@ -194,10 +194,20 @@ mod_opt_type(O) when O == cache_size; O == cache_life_time -> fun(I) when is_integer(I), I>0 -> I; (unlimited) -> infinity; (infinity) -> infinity - end; -mod_opt_type(_) -> - [json, max_concat, max_inactivity, max_pause, prebind, ram_db_type, - queue_type, use_cache, cache_size, cache_missed, cache_life_time]. + end. + +mod_options(Host) -> + [{json, false}, + {max_concat, unlimited}, + {max_inactivity, 30}, + {max_pause, 120}, + {prebind, false}, + {ram_db_type, ejabberd_config:default_ram_db(Host, ?MODULE)}, + {queue_type, ejabberd_config:default_queue_type(Host)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. %%%---------------------------------------------------------------------- %%% Cache stuff @@ -215,10 +225,7 @@ init_cache(Mod) -> use_cache(Mod) -> case erlang:function_exported(Mod, use_cache, 0) of true -> Mod:use_cache(); - false -> - gen_mod:get_module_opt( - global, ?MODULE, use_cache, - ejabberd_config:use_cache(global)) + false -> gen_mod:get_module_opt(global, ?MODULE, use_cache) end. -spec cache_nodes(module()) -> [node()]. @@ -239,15 +246,9 @@ delete_cache(Mod, SID) -> -spec cache_opts() -> [proplists:property()]. cache_opts() -> - MaxSize = gen_mod:get_module_opt( - global, ?MODULE, cache_size, - ejabberd_config:cache_size(global)), - CacheMissed = gen_mod:get_module_opt( - global, ?MODULE, cache_missed, - ejabberd_config:cache_missed(global)), - LifeTime = case gen_mod:get_module_opt( - global, ?MODULE, cache_life_time, - ejabberd_config:cache_life_time(global)) of + MaxSize = gen_mod:get_module_opt(global, ?MODULE, cache_size), + CacheMissed = gen_mod:get_module_opt(global, ?MODULE, cache_missed), + LifeTime = case gen_mod:get_module_opt(global, ?MODULE, cache_life_time) of infinity -> infinity; I -> timer:seconds(I) end, diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 5e4372e91..61317556d 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -48,7 +48,7 @@ handle_cast/2, terminate/2, code_change/3]). -export([user_send_packet/1, user_receive_packet/1, - c2s_presence_in/2, mod_opt_type/1]). + c2s_presence_in/2, mod_opt_type/1, mod_options/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -250,16 +250,14 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(cache_size, NewOpts, OldOpts, - ejabberd_config:cache_size(Host)) of + case gen_mod:is_equal_opt(cache_size, NewOpts, OldOpts) of {false, MaxSize, _} -> ets_cache:setopts(caps_features_cache, [{max_size, MaxSize}]), ets_cache:setopts(caps_requests_cache, [{max_size, MaxSize}]); true -> ok end, - case gen_mod:is_equal_opt(cache_life_time, NewOpts, OldOpts, - ejabberd_config:cache_life_time(Host)) of + case gen_mod:is_equal_opt(cache_life_time, NewOpts, OldOpts) of {false, Time, _} -> LifeTime = case Time of infinity -> infinity; @@ -273,7 +271,7 @@ reload(Host, NewOpts, OldOpts) -> init([Host, Opts]) -> process_flag(trap_exit, true), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), - init_cache(Host, Opts), + init_cache(Opts), Mod:init(Host, Opts), ejabberd_hooks:add(c2s_presence_in, Host, ?MODULE, c2s_presence_in, 75), @@ -478,9 +476,9 @@ is_valid_node(Node) -> false end. -init_cache(Host, Opts) -> - CacheOpts = cache_opts(Host, Opts), - case use_cache(Host, Opts) of +init_cache(Opts) -> + CacheOpts = cache_opts(Opts), + case use_cache(Opts) of true -> ets_cache:new(caps_features_cache, CacheOpts); false -> @@ -491,16 +489,13 @@ init_cache(Host, Opts) -> [{max_size, CacheSize}, {life_time, timer:seconds(?BAD_HASH_LIFETIME)}]). -use_cache(Host, Opts) -> - gen_mod:get_opt(use_cache, Opts, ejabberd_config:use_cache(Host)). +use_cache(Opts) -> + gen_mod:get_opt(use_cache, Opts). -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt(cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt(cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt(cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -547,6 +542,11 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size -> end; mod_opt_type(O) when O == use_cache; O == cache_missed -> fun (B) when is_boolean(B) -> B end; -mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; -mod_opt_type(_) -> - [cache_life_time, cache_size, use_cache, cache_missed, db_type]. +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end. + +mod_options(Host) -> + [{db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index d56afd7ec..8e76ad1d2 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -36,7 +36,8 @@ -export([user_send_packet/1, user_receive_packet/1, iq_handler/1, remove_connection/4, disco_features/5, - is_carbon_copy/1, mod_opt_type/1, depends/2, clean_cache/1]). + is_carbon_copy/1, mod_opt_type/1, depends/2, clean_cache/1, + mod_options/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -61,7 +62,7 @@ is_carbon_copy(_) -> false. start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50), Mod = gen_mod:ram_db_mod(Host, ?MODULE), init_cache(Mod, Host, Opts), @@ -91,11 +92,11 @@ reload(Host, NewOpts, OldOpts) -> end, case use_cache(NewMod, Host) of true -> - ets_cache:new(?CARBONCOPY_CACHE, cache_opts(Host, NewOpts)); + ets_cache:new(?CARBONCOPY_CACHE, cache_opts(NewOpts)); false -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_2, ?MODULE, iq_handler, IQDisc); @@ -321,22 +322,16 @@ list(User, Server) -> init_cache(Mod, Host, Opts) -> case use_cache(Mod, Host) of true -> - ets_cache:new(?CARBONCOPY_CACHE, cache_opts(Host, Opts)); + ets_cache:new(?CARBONCOPY_CACHE, cache_opts(Opts)); false -> ets_cache:delete(?CARBONCOPY_CACHE) end. --spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +-spec cache_opts(gen_mod:opts()) -> [proplists:property()]. +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -346,10 +341,7 @@ cache_opts(Host, Opts) -> use_cache(Mod, Host) -> case erlang:function_exported(Mod, use_cache, 1) of true -> Mod:use_cache(Host); - false -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache) end. -spec cache_nodes(module(), binary()) -> [node()]. @@ -394,6 +386,12 @@ mod_opt_type(O) when O == cache_size; O == cache_life_time -> fun(I) when is_integer(I), I>0 -> I; (unlimited) -> infinity; (infinity) -> infinity - end; -mod_opt_type(_) -> - [ram_db_type, iqdisc, use_cache, cache_size, cache_missed, cache_life_time]. + end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {ram_db_type, ejabberd_config:default_ram_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_client_state.erl b/src/mod_client_state.erl index bd3bf3359..4e11ea8c7 100644 --- a/src/mod_client_state.erl +++ b/src/mod_client_state.erl @@ -31,7 +31,7 @@ -behavior(gen_mod). %% gen_mod callbacks. --export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2, mod_options/1]). %% ejabberd_hooks callbacks. -export([filter_presence/1, filter_chat_states/1, @@ -59,9 +59,9 @@ %%-------------------------------------------------------------------- -spec start(binary(), gen_mod:opts()) -> ok. start(Host, Opts) -> - QueuePresence = gen_mod:get_opt(queue_presence, Opts, true), - QueueChatStates = gen_mod:get_opt(queue_chat_states, Opts, true), - QueuePEP = gen_mod:get_opt(queue_pep, Opts, true), + QueuePresence = gen_mod:get_opt(queue_presence, Opts), + QueueChatStates = gen_mod:get_opt(queue_chat_states, Opts), + QueuePEP = gen_mod:get_opt(queue_pep, Opts), if QueuePresence; QueueChatStates; QueuePEP -> register_hooks(Host), if QueuePresence -> @@ -84,9 +84,9 @@ start(Host, Opts) -> -spec stop(binary()) -> ok. stop(Host) -> - QueuePresence = gen_mod:get_module_opt(Host, ?MODULE, queue_presence, true), - QueueChatStates = gen_mod:get_module_opt(Host, ?MODULE, queue_chat_states, true), - QueuePEP = gen_mod:get_module_opt(Host, ?MODULE, queue_pep, true), + QueuePresence = gen_mod:get_module_opt(Host, ?MODULE, queue_presence), + QueueChatStates = gen_mod:get_module_opt(Host, ?MODULE, queue_chat_states), + QueuePEP = gen_mod:get_module_opt(Host, ?MODULE, queue_pep), if QueuePresence; QueueChatStates; QueuePEP -> unregister_hooks(Host), if QueuePresence -> @@ -109,9 +109,9 @@ stop(Host) -> -spec reload(binary(), gen_mod:opts(), gen_mod:opts()) -> ok. reload(Host, NewOpts, _OldOpts) -> - QueuePresence = gen_mod:get_opt(queue_presence, NewOpts, true), - QueueChatStates = gen_mod:get_opt(queue_chat_states, NewOpts, true), - QueuePEP = gen_mod:get_opt(queue_pep, NewOpts, true), + QueuePresence = gen_mod:get_opt(queue_presence, NewOpts), + QueueChatStates = gen_mod:get_opt(queue_chat_states, NewOpts), + QueuePEP = gen_mod:get_opt(queue_pep, NewOpts), if QueuePresence; QueueChatStates; QueuePEP -> register_hooks(Host); true -> @@ -145,8 +145,12 @@ mod_opt_type(queue_presence) -> mod_opt_type(queue_chat_states) -> fun(B) when is_boolean(B) -> B end; mod_opt_type(queue_pep) -> - fun(B) when is_boolean(B) -> B end; -mod_opt_type(_) -> [queue_presence, queue_chat_states, queue_pep]. + fun(B) when is_boolean(B) -> B end. + +mod_options(_) -> + [{queue_presence, true}, + {queue_chat_states, true}, + {queue_pep, true}]. -spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}]. depends(_Host, _Opts) -> diff --git a/src/mod_configure.erl b/src/mod_configure.erl index c90fd59b7..db0780834 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -35,7 +35,7 @@ get_local_features/5, get_local_items/5, adhoc_local_items/4, adhoc_local_commands/4, get_sm_identity/5, get_sm_features/5, get_sm_items/5, - adhoc_sm_items/4, adhoc_sm_commands/4, mod_opt_type/1, + adhoc_sm_items/4, adhoc_sm_commands/4, mod_options/1, depends/2]). -include("ejabberd.hrl"). @@ -1809,4 +1809,4 @@ set_sm_form(User, Server, <<"config">>, set_sm_form(_User, _Server, _Node, _Request) -> {error, xmpp:err_service_unavailable()}. -mod_opt_type(_) -> []. +mod_options(_) -> []. diff --git a/src/mod_delegation.erl b/src/mod_delegation.erl index a9874abe7..1d34be12e 100644 --- a/src/mod_delegation.erl +++ b/src/mod_delegation.erl @@ -31,7 +31,7 @@ -behaviour(gen_mod). %% API --export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2, mod_options/1]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -70,9 +70,11 @@ mod_opt_type(namespaces) -> Access = proplists:get_value(access, Opts, none), {NS, Attrs, Access} end, L) - end; -mod_opt_type(_) -> - [namespaces, iqdisc]. + end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {namespaces, []}]. depends(_, _) -> []. @@ -151,7 +153,7 @@ handle_cast({component_connected, Host}, State) -> ServerHost = State#state.server_host, To = jid:make(Host), NSAttrsAccessList = gen_mod:get_module_opt( - ServerHost, ?MODULE, namespaces, []), + ServerHost, ?MODULE, namespaces), lists:foreach( fun({NS, _Attrs, Access}) -> case acl:match_rule(ServerHost, Access, To) of diff --git a/src/mod_disco.erl b/src/mod_disco.erl index e2632a0b4..d6dbd7101 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -37,7 +37,8 @@ get_local_features/5, get_local_services/5, process_sm_iq_items/1, process_sm_iq_info/1, get_sm_identity/5, get_sm_features/5, get_sm_items/5, - get_info/5, transform_module_options/1, mod_opt_type/1, depends/2]). + get_info/5, transform_module_options/1, mod_opt_type/1, + mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -50,7 +51,7 @@ -type items_acc() :: {error, stanza_error()} | {result, [disco_item()]} | empty. start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS, ?MODULE, process_local_iq_items, IQDisc), @@ -66,7 +67,7 @@ start(Host, Opts) -> catch ets:new(disco_extra_domains, [named_table, ordered_set, public, {heir, erlang:group_leader(), none}]), - ExtraDomains = gen_mod:get_opt(extra_domains, Opts, []), + ExtraDomains = gen_mod:get_opt(extra_domains, Opts), lists:foreach(fun (Domain) -> register_extra_domain(Host, Domain) end, @@ -115,7 +116,7 @@ stop(Host) -> ok. reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(extra_domains, NewOpts, OldOpts, []) of + case gen_mod:is_equal_opt(extra_domains, NewOpts, OldOpts) of {false, NewDomains, OldDomains} -> lists:foreach( fun(Domain) -> @@ -128,7 +129,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS, ?MODULE, @@ -197,7 +198,7 @@ process_local_iq_info(#iq{type = get, lang = Lang, binary(), binary()) -> [identity()]. get_local_identity(Acc, _From, To, <<"">>, _Lang) -> Host = To#jid.lserver, - Name = gen_mod:get_module_opt(Host, ?MODULE, name, ?T("ejabberd")), + Name = gen_mod:get_module_opt(Host, ?MODULE, name), Acc ++ [#identity{category = <<"server">>, type = <<"im">>, name = Name}]; @@ -440,7 +441,7 @@ get_info(Acc, _, _, _Node, _) -> Acc. -spec get_fields(binary(), module()) -> [xdata_field()]. get_fields(Host, Module) -> - Fields = gen_mod:get_module_opt(Host, ?MODULE, server_info, []), + Fields = gen_mod:get_module_opt(Host, ?MODULE, server_info), Fields1 = lists:filter(fun ({Modules, _, _}) -> case Modules of all -> true; @@ -468,5 +469,10 @@ mod_opt_type(server_info) -> {Mods, Name, URLs} end, L) - end; -mod_opt_type(_) -> [extra_domains, iqdisc, server_info, name]. + end. + +mod_options(Host) -> + [{extra_domains, []}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {server_info, []}, + {name, ?T("ejabberd")}]. diff --git a/src/mod_echo.erl b/src/mod_echo.erl index 04b47e08e..7e8c70cb9 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -36,7 +36,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, - mod_opt_type/1, depends/2]). + mod_opt_type/1, depends/2, mod_options/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -63,8 +63,10 @@ depends(_Host, _Opts) -> mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(hosts) -> - fun(L) -> lists:map(fun iolist_to_binary/1, L) end; -mod_opt_type(_) -> [host, hosts]. + fun(L) -> lists:map(fun iolist_to_binary/1, L) end. + +mod_options(_Host) -> + [{host, <<"echo.@HOST@">>}, {hosts, []}]. %%==================================================================== %% gen_server callbacks @@ -79,8 +81,7 @@ mod_opt_type(_) -> [host, hosts]. %%-------------------------------------------------------------------- init([Host, Opts]) -> process_flag(trap_exit, true), - Hosts = gen_mod:get_opt_hosts(Host, Opts, - <<"echo.@HOST@">>), + Hosts = gen_mod:get_opt_hosts(Host, Opts), lists:foreach( fun(H) -> ejabberd_router:register_route(H, Host) @@ -106,10 +107,8 @@ handle_call(stop, _From, State) -> %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast({reload, Host, NewOpts, OldOpts}, State) -> - NewMyHosts = gen_mod:get_opt_hosts(Host, NewOpts, - <<"echo.@HOST@">>), - OldMyHosts = gen_mod:get_opt_hosts(Host, OldOpts, - <<"echo.@HOST@">>), + NewMyHosts = gen_mod:get_opt_hosts(Host, NewOpts), + OldMyHosts = gen_mod:get_opt_hosts(Host, OldOpts), lists:foreach( fun(H) -> ejabberd_router:unregister_route(H) diff --git a/src/mod_fail2ban.erl b/src/mod_fail2ban.erl index e8ab076fb..618e4b6e4 100644 --- a/src/mod_fail2ban.erl +++ b/src/mod_fail2ban.erl @@ -34,15 +34,13 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, - mod_opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, depends/2]). -include_lib("stdlib/include/ms_transform.hrl"). -include("ejabberd.hrl"). -include("logger.hrl"). -include("xmpp.hrl"). --define(C2S_AUTH_BAN_LIFETIME, 3600). %% 1 hour --define(C2S_MAX_AUTH_FAILURES, 20). -define(CLEAN_INTERVAL, timer:minutes(10)). -record(state, {host = <<"">> :: binary()}). @@ -58,11 +56,9 @@ c2s_auth_result(#{ip := {Addr, _}, lserver := LServer} = State, false, _User) -> State; false -> BanLifetime = gen_mod:get_module_opt( - LServer, ?MODULE, c2s_auth_ban_lifetime, - ?C2S_AUTH_BAN_LIFETIME), + LServer, ?MODULE, c2s_auth_ban_lifetime), MaxFailures = gen_mod:get_module_opt( - LServer, ?MODULE, c2s_max_auth_failures, - ?C2S_MAX_AUTH_FAILURES), + LServer, ?MODULE, c2s_max_auth_failures), UnbanTS = p1_time_compat:system_time(seconds) + BanLifetime, Attempts = case ets:lookup(failed_auth, Addr) of [{Addr, N, _, _}] -> @@ -179,7 +175,7 @@ log_and_disconnect(#{ip := {Addr, _}, lang := Lang} = State, Attempts, UnbanTS) {stop, ejabberd_c2s:send(State, Err)}. is_whitelisted(Host, Addr) -> - Access = gen_mod:get_module_opt(Host, ?MODULE, access, none), + Access = gen_mod:get_module_opt(Host, ?MODULE, access), acl:match_rule(Host, Access, Addr) == allow. seconds_to_now(Secs) -> @@ -194,6 +190,9 @@ mod_opt_type(access) -> mod_opt_type(c2s_auth_ban_lifetime) -> fun (T) when is_integer(T), T > 0 -> T end; mod_opt_type(c2s_max_auth_failures) -> - fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(_) -> - [access, c2s_auth_ban_lifetime, c2s_max_auth_failures]. + fun (I) when is_integer(I), I > 0 -> I end. + +mod_options(_Host) -> + [{access, none}, + {c2s_auth_ban_lifetime, 3600}, %% one hour + {c2s_max_auth_failures, 20}]. diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index 2b818840d..d403e3aa9 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -74,7 +74,8 @@ -behaviour(gen_mod). --export([start/2, stop/1, reload/3, process/2, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, process/2, mod_opt_type/1, depends/2, + mod_options/1]). -include("ejabberd.hrl"). -include("xmpp.hrl"). @@ -551,7 +552,7 @@ hide_sensitive_args(NonListArgs) -> NonListArgs. permission_addon() -> - Access = gen_mod:get_module_opt(global, ?MODULE, admin_ip_access, none), + Access = gen_mod:get_module_opt(global, ?MODULE, admin_ip_access), Rules = acl:resolve_access(Access, global), R = case Rules of all -> @@ -576,5 +577,5 @@ permission_addon() -> end, {1, []}, R), Res. -mod_opt_type(admin_ip_access) -> fun acl:access_rules_validator/1; -mod_opt_type(_) -> [admin_ip_access]. +mod_opt_type(admin_ip_access) -> fun acl:access_rules_validator/1. +mod_options(_) -> [{admin_ip_access, none}]. diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl index b804805c2..4595ac873 100644 --- a/src/mod_http_fileserver.erl +++ b/src/mod_http_fileserver.erl @@ -43,7 +43,7 @@ %% utility for other http modules -export([content_type/3]). --export([reopen_log/0, mod_opt_type/1, depends/2]). +-export([reopen_log/0, mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -69,9 +69,6 @@ -define(HTTP_ERR_HOST_UNKNOWN, {-1, 410, [], <<"Host unknown">>}). --define(DEFAULT_CONTENT_TYPE, - <<"application/octet-stream">>). - -define(DEFAULT_CONTENT_TYPES, [{<<".css">>, <<"text/css">>}, {<<".gif">>, <<"image/gif">>}, @@ -126,24 +123,19 @@ init([Host, Opts]) -> initialize(Host, Opts) -> DocRoot = gen_mod:get_opt(docroot, Opts), - check_docroot_defined(DocRoot, Host), - DRInfo = check_docroot_exists(DocRoot), - check_docroot_is_dir(DRInfo, DocRoot), - check_docroot_is_readable(DRInfo, DocRoot), AccessLog = gen_mod:get_opt(accesslog, Opts), AccessLogFD = try_open_log(AccessLog, Host), - DirectoryIndices = gen_mod:get_opt(directory_indices, Opts, []), - CustomHeaders = gen_mod:get_opt(custom_headers, Opts, []), - DefaultContentType = gen_mod:get_opt(default_content_type, Opts, - ?DEFAULT_CONTENT_TYPE), - UserAccess0 = gen_mod:get_opt(must_authenticate_with, Opts, []), + DirectoryIndices = gen_mod:get_opt(directory_indices, Opts), + CustomHeaders = gen_mod:get_opt(custom_headers, Opts), + DefaultContentType = gen_mod:get_opt(default_content_type, Opts), + UserAccess0 = gen_mod:get_opt(must_authenticate_with, Opts), UserAccess = case UserAccess0 of [] -> none; _ -> dict:from_list(UserAccess0) end, ContentTypes = build_list_content_types( - gen_mod:get_opt(content_types, Opts, []), + gen_mod:get_opt(content_types, Opts), ?DEFAULT_CONTENT_TYPES), ?DEBUG("known content types: ~s", [str:join([[$*, K, " -> ", V] || {K, V} <- ContentTypes], @@ -173,37 +165,6 @@ build_list_content_types(AdminCTsUnsorted, DefaultCTsUnsorted) -> || {Extension, Value} <- CTsUnfiltered, Value /= undefined]. -check_docroot_defined(DocRoot, Host) -> - case DocRoot of - undefined -> throw({undefined_docroot_option, Host}); - _ -> ok - end. - -check_docroot_exists(DocRoot) -> - case filelib:ensure_dir(filename:join(DocRoot, "foo")) of - ok -> - case file:read_file_info(DocRoot) of - {error, Reason} -> - throw({error_access_docroot, DocRoot, Reason}); - {ok, FI} -> FI - end; - {error, Reason} -> - throw({error_access_docroot, DocRoot, Reason}) - end. - -check_docroot_is_dir(DRInfo, DocRoot) -> - case DRInfo#file_info.type of - directory -> ok; - _ -> throw({docroot_not_directory, DocRoot}) - end. - -check_docroot_is_readable(DRInfo, DocRoot) -> - case DRInfo#file_info.access of - read -> ok; - read_write -> ok; - _ -> throw({docroot_not_readable, DocRoot}) - end. - try_open_log(undefined, _Host) -> undefined; try_open_log(FN, _Host) -> @@ -504,7 +465,10 @@ ip_to_string(Address) when size(Address) == 8 -> Parts = lists:map(fun (Int) -> io_lib:format("~.16B", [Int]) end, tuple_to_list(Address)), string:to_lower(lists:flatten(join(Parts, ":"))). -mod_opt_type(accesslog) -> fun iolist_to_binary/1; +mod_opt_type(accesslog) -> + fun(undefined) -> undefined; + (File) -> iolist_to_binary(File) + end; mod_opt_type(content_types) -> fun(L) when is_list(L) -> lists:map( @@ -519,15 +483,32 @@ mod_opt_type(default_content_type) -> fun iolist_to_binary/1; mod_opt_type(directory_indices) -> fun (L) when is_list(L) -> L end; -mod_opt_type(docroot) -> fun (A) -> A end; +mod_opt_type(docroot) -> + fun(S) -> + Path = iolist_to_binary(S), + case filelib:ensure_dir(filename:join(Path, "foo")) of + ok -> + Path; + {error, Why} -> + ?ERROR_MSG("Failed to create directory ~s: ~s", + [Path, file:format_error(Why)]), + erlang:error(badarg) + end + end; mod_opt_type(must_authenticate_with) -> fun (L) when is_list(L) -> lists:map(fun(UP) when is_binary(UP) -> [K, V] = binary:split(UP, <<":">>), {K, V} end, L) - end; -mod_opt_type(_) -> - [accesslog, content_types, custom_headers, - default_content_type, directory_indices, docroot, - must_authenticate_with]. + end. + +mod_options(_) -> + [{accesslog, undefined}, + {content_types, []}, + {default_content_type, <<"application/octet-stream">>}, + {custom_headers, []}, + {directory_indices, []}, + {must_authenticate_with, []}, + %% Required option + docroot]. diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index 52036cbe1..9f5894499 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -66,7 +66,8 @@ -export([start/2, stop/1, depends/2, - mod_opt_type/1]). + mod_opt_type/1, + mod_options/1]). %% gen_server callbacks. -export([init/1, @@ -126,7 +127,7 @@ -spec start(binary(), gen_mod:opts()) -> {ok, pid()}. start(ServerHost, Opts) -> - case gen_mod:get_opt(rm_on_unregister, Opts, true) of + case gen_mod:get_opt(rm_on_unregister, Opts) of true -> ejabberd_hooks:add(remove_user, ServerHost, ?MODULE, remove_user, 50); @@ -139,7 +140,7 @@ start(ServerHost, Opts) -> -spec stop(binary()) -> ok | {error, any()}. stop(ServerHost) -> - case gen_mod:get_module_opt(ServerHost, ?MODULE, rm_on_unregister, true) of + case gen_mod:get_module_opt(ServerHost, ?MODULE, rm_on_unregister) of true -> ejabberd_hooks:delete(remove_user, ServerHost, ?MODULE, remove_user, 50); @@ -170,9 +171,13 @@ mod_opt_type(jid_in_url) -> (node) -> node end; mod_opt_type(file_mode) -> - fun(Mode) -> ?STR_TO_INT(Mode, 8) end; + fun(undefined) -> undefined; + (Mode) -> ?STR_TO_INT(Mode, 8) + end; mod_opt_type(dir_mode) -> - fun(Mode) -> ?STR_TO_INT(Mode, 8) end; + fun(undefined) -> undefined; + (Mode) -> ?STR_TO_INT(Mode, 8) + end; mod_opt_type(docroot) -> fun iolist_to_binary/1; mod_opt_type(put_url) -> @@ -181,11 +186,13 @@ mod_opt_type(put_url) -> end; mod_opt_type(get_url) -> fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL + (<<"https://", _/binary>> = URL) -> URL; + (undefined) -> undefined end; mod_opt_type(service_url) -> fun(<<"http://", _/binary>> = URL) -> URL; - (<<"https://", _/binary>> = URL) -> URL + (<<"https://", _/binary>> = URL) -> URL; + (undefined) -> undefined end; mod_opt_type(custom_headers) -> fun(Headers) -> @@ -208,11 +215,25 @@ mod_opt_type(thumbnail) -> end; (false) -> false - end; -mod_opt_type(_) -> - [host, hosts, name, access, max_size, secret_length, jid_in_url, file_mode, - dir_mode, docroot, put_url, get_url, service_url, custom_headers, - rm_on_unregister, thumbnail]. + end. + +mod_options(_Host) -> + [{host, <<"upload.@HOST@">>}, + {hosts, []}, + {name, ?T("HTTP File Upload")}, + {access, local}, + {max_size, 104857600}, + {secret_length, 40}, + {jid_in_url, sha1}, + {file_mode, undefined}, + {dir_mode, undefined}, + {docroot, <<"@HOME@/upload">>}, + {put_url, <<"http://@HOST@:5444">>}, + {get_url, undefined}, + {service_url, undefined}, + {custom_headers, []}, + {rm_on_unregister, true}, + {thumbnail, true}]. -spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}]. @@ -227,20 +248,23 @@ depends(_Host, _Opts) -> init([ServerHost, Opts]) -> process_flag(trap_exit, true), - Hosts = gen_mod:get_opt_hosts(ServerHost, Opts, <<"upload.@HOST@">>), - Name = gen_mod:get_opt(name, Opts, ?T("HTTP File Upload")), - Access = gen_mod:get_opt(access, Opts, local), - MaxSize = gen_mod:get_opt(max_size, Opts, 104857600), - SecretLength = gen_mod:get_opt(secret_length, Opts, 40), - JIDinURL = gen_mod:get_opt(jid_in_url, Opts, sha1), - DocRoot = gen_mod:get_opt(docroot, Opts, <<"@HOME@/upload">>), + Hosts = gen_mod:get_opt_hosts(ServerHost, Opts), + Name = gen_mod:get_opt(name, Opts), + Access = gen_mod:get_opt(access, Opts), + MaxSize = gen_mod:get_opt(max_size, Opts), + SecretLength = gen_mod:get_opt(secret_length, Opts), + JIDinURL = gen_mod:get_opt(jid_in_url, Opts), + DocRoot = gen_mod:get_opt(docroot, Opts), FileMode = gen_mod:get_opt(file_mode, Opts), DirMode = gen_mod:get_opt(dir_mode, Opts), - PutURL = gen_mod:get_opt(put_url, Opts, <<"http://@HOST@:5444">>), - GetURL = gen_mod:get_opt(get_url, Opts, PutURL), + PutURL = gen_mod:get_opt(put_url, Opts), + GetURL = case gen_mod:get_opt(get_url, Opts) of + undefined -> PutURL; + URL -> URL + end, ServiceURL = gen_mod:get_opt(service_url, Opts), - Thumbnail = gen_mod:get_opt(thumbnail, Opts, true), - CustomHeaders = gen_mod:get_opt(custom_headers, Opts, []), + Thumbnail = gen_mod:get_opt(thumbnail, Opts), + CustomHeaders = gen_mod:get_opt(custom_headers, Opts), DocRoot1 = expand_home(str:strip(DocRoot, right, $/)), DocRoot2 = expand_host(DocRoot1, ServerHost), case DirMode of @@ -463,8 +487,7 @@ process(_LocalPath, #request{method = Method, host = Host, ip = IP}) -> -spec get_proc_name(binary(), atom()) -> atom(). get_proc_name(ServerHost, ModuleName) -> - PutURL = gen_mod:get_module_opt(ServerHost, ?MODULE, put_url, - <<"http://@HOST@">>), + PutURL = gen_mod:get_module_opt(ServerHost, ?MODULE, put_url), {ok, {_Scheme, _UserInfo, Host, _Port, Path, _Query}} = http_uri:parse(binary_to_list(expand_host(PutURL, ServerHost))), ProcPrefix = list_to_binary(string:strip(Host ++ Path, right, $/)), @@ -693,7 +716,7 @@ yield_content_type(Type) -> Type. -spec iq_disco_info(binary(), binary(), binary(), [xdata()]) -> disco_info(). iq_disco_info(Host, Lang, Name, AddInfo) -> - Form = case gen_mod:get_module_opt(Host, ?MODULE, max_size, 104857600) of + Form = case gen_mod:get_module_opt(Host, ?MODULE, max_size) of infinity -> AddInfo; MaxSize -> @@ -914,9 +937,8 @@ thumb_el(#media_info{type = T, height = H, width = W}, URI) -> remove_user(User, Server) -> ServerHost = jid:nameprep(Server), - DocRoot = gen_mod:get_module_opt(ServerHost, ?MODULE, docroot, - <<"@HOME@/upload">>), - JIDinURL = gen_mod:get_module_opt(ServerHost, ?MODULE, jid_in_url, sha1), + DocRoot = gen_mod:get_module_opt(ServerHost, ?MODULE, docroot), + JIDinURL = gen_mod:get_module_opt(ServerHost, ?MODULE, jid_in_url), DocRoot1 = expand_host(expand_home(DocRoot), ServerHost), UserStr = make_user_string(jid:make(User, Server), JIDinURL), UserDir = str:join([DocRoot1, UserStr], <<$/>>), diff --git a/src/mod_http_upload_quota.erl b/src/mod_http_upload_quota.erl index cfbd25b7a..6e5b430c5 100644 --- a/src/mod_http_upload_quota.erl +++ b/src/mod_http_upload_quota.erl @@ -37,7 +37,8 @@ -export([start/2, stop/1, depends/2, - mod_opt_type/1]). + mod_opt_type/1, + mod_options/1]). %% gen_server callbacks. -export([init/1, @@ -89,9 +90,12 @@ mod_opt_type(access_hard_quota) -> mod_opt_type(max_days) -> fun(I) when is_integer(I), I > 0 -> I; (infinity) -> infinity - end; -mod_opt_type(_) -> - [access_soft_quota, access_hard_quota, max_days]. + end. + +mod_options(_) -> + [{access_soft_quota, soft_upload_quota}, + {access_hard_quota, hard_upload_quota}, + {max_days, infinity}]. -spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}]. @@ -104,13 +108,10 @@ depends(_Host, _Opts) -> init([ServerHost, Opts]) -> process_flag(trap_exit, true), - AccessSoftQuota = gen_mod:get_opt(access_soft_quota, Opts, - soft_upload_quota), - AccessHardQuota = gen_mod:get_opt(access_hard_quota, Opts, - hard_upload_quota), - MaxDays = gen_mod:get_opt(max_days, Opts, infinity), - DocRoot1 = gen_mod:get_module_opt(ServerHost, mod_http_upload, docroot, - <<"@HOME@/upload">>), + AccessSoftQuota = gen_mod:get_opt(access_soft_quota, Opts), + AccessHardQuota = gen_mod:get_opt(access_hard_quota, Opts), + MaxDays = gen_mod:get_opt(max_days, Opts), + DocRoot1 = gen_mod:get_module_opt(ServerHost, mod_http_upload, docroot), DocRoot2 = mod_http_upload:expand_home(str:strip(DocRoot1, right, $/)), DocRoot3 = mod_http_upload:expand_host(DocRoot2, ServerHost), Timers = if MaxDays == infinity -> []; diff --git a/src/mod_irc.erl b/src/mod_irc.erl index ab8b31c2c..27d5c0f3b 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -39,7 +39,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, - mod_opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -47,14 +47,8 @@ -include("mod_irc.hrl"). -include("translate.hrl"). --define(DEFAULT_IRC_ENCODING, <<"iso8859-15">>). - -define(DEFAULT_IRC_PORT, 6667). --define(DEFAULT_REALNAME, <<"WebIRC-User">>). - --define(DEFAULT_WEBIRC_PASSWORD, <<"">>). - -define(POSSIBLE_ENCODINGS, [<<"koi8-r">>, <<"iso8859-15">>, <<"iso8859-1">>, <<"iso8859-2">>, <<"utf-8">>, <<"utf-8+latin-1">>]). @@ -100,14 +94,14 @@ depends(_Host, _Opts) -> init([Host, Opts]) -> process_flag(trap_exit, true), ejabberd:start_app(iconv), - MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"irc.@HOST@">>), + MyHosts = gen_mod:get_opt_hosts(Host, Opts), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), - Access = gen_mod:get_opt(access, Opts, all), + Access = gen_mod:get_opt(access, Opts), catch ets:new(irc_connection, [named_table, public, {keypos, #irc_connection.jid_server_host}]), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), lists:foreach( fun(MyHost) -> register_hooks(MyHost, IQDisc), @@ -136,13 +130,13 @@ handle_call(stop, _From, State) -> %% Description: Handling cast messages %%-------------------------------------------------------------------- handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> - NewHosts = gen_mod:get_opt_hosts(ServerHost, NewOpts, <<"irc.@HOST@">>), - OldHosts = gen_mod:get_opt_hosts(ServerHost, OldOpts, <<"irc.@HOST@">>), - NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)), - OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)), + NewHosts = gen_mod:get_opt_hosts(ServerHost, NewOpts), + OldHosts = gen_mod:get_opt_hosts(ServerHost, OldOpts), + NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts), + OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts), NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE), OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE), - Access = gen_mod:get_opt(access, NewOpts, all), + Access = gen_mod:get_opt(access, NewOpts), if NewMod /= OldMod -> NewMod:init(ServerHost, NewOpts); true -> @@ -166,7 +160,7 @@ handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> ejabberd_router:unregister_route(OldHost), unregister_hooks(OldHost) end, OldHosts -- NewHosts), - Access = gen_mod:get_opt(access, NewOpts, all), + Access = gen_mod:get_opt(access, NewOpts), {noreply, State#state{hosts = NewHosts, access = Access}}; handle_cast(Msg, State) -> ?WARNING_MSG("unexpected cast: ~p", [Msg]), @@ -434,7 +428,7 @@ closed_connection(Host, From, Server) -> ets:delete(irc_connection, {From, Server, Host}). iq_disco(ServerHost, <<"">>, Lang) -> - Name = gen_mod:get_module_opt(ServerHost, ?MODULE, name, ?T("IRC Transport")), + Name = gen_mod:get_module_opt(ServerHost, ?MODULE, name), #disco_info{ identities = [#identity{category = <<"conference">>, type = <<"irc">>, @@ -595,18 +589,17 @@ get_connection_params(Host, From, IRCServer) -> IRCServer). get_default_encoding(ServerHost) -> - Result = gen_mod:get_module_opt(ServerHost, ?MODULE, default_encoding, - ?DEFAULT_IRC_ENCODING), + Result = gen_mod:get_module_opt(ServerHost, ?MODULE, default_encoding), ?INFO_MSG("The default_encoding configured for " "host ~p is: ~p~n", [ServerHost, Result]), Result. get_realname(ServerHost) -> - gen_mod:get_module_opt(ServerHost, ?MODULE, realname, ?DEFAULT_REALNAME). + gen_mod:get_module_opt(ServerHost, ?MODULE, realname). get_webirc_password(ServerHost) -> - gen_mod:get_module_opt(ServerHost, ?MODULE, webirc_password, ?DEFAULT_WEBIRC_PASSWORD). + gen_mod:get_module_opt(ServerHost, ?MODULE, webirc_password). get_connection_params(Host, ServerHost, From, IRCServer) -> @@ -993,8 +986,22 @@ mod_opt_type(name) -> mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(hosts) -> fun (L) -> lists:map(fun iolist_to_binary/1, L) end; -mod_opt_type(_) -> - [access, db_type, default_encoding, host, hosts, name]. +mod_opt_type(realname) -> + fun iolist_to_binary/1; +mod_opt_type(webirc_password) -> + fun iolist_to_binary/1; +mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1. + +mod_options(Host) -> + [{access, all}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {default_encoding, <<"iso8859-15">>}, + {host, <<"irc.@HOST@">>}, + {hosts, []}, + {realname, <<"WebIRC-User">>}, + {webirc_password, <<"">>}, + {name, ?T("IRC Transport")}]. -spec extract_ident(stanza()) -> binary(). extract_ident(Packet) -> diff --git a/src/mod_last.erl b/src/mod_last.erl index 50303d0b6..f9edb91f4 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -34,7 +34,7 @@ -export([start/2, stop/1, reload/3, process_local_iq/1, export/1, process_sm_iq/1, on_presence_update/4, import_info/0, import/5, import_start/2, store_last_info/4, get_last_info/2, - remove_user/2, mod_opt_type/1, + remove_user/2, mod_opt_type/1, mod_options/1, register_user/2, depends/2, privacy_check_packet/4]). -include("ejabberd.hrl"). @@ -59,7 +59,7 @@ -optional_callbacks([use_cache/1, cache_nodes/1]). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), init_cache(Mod, Host, Opts), @@ -99,7 +99,7 @@ reload(Host, NewOpts, OldOpts) -> ok end, init_cache(NewMod, Host, NewOpts), - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST, ?MODULE, process_local_iq, IQDisc), @@ -275,23 +275,17 @@ remove_user(User, Server) -> init_cache(Mod, Host, Opts) -> case use_cache(Mod, Host) of true -> - CacheOpts = cache_opts(Host, Opts), + CacheOpts = cache_opts(Opts), ets_cache:new(?LAST_CACHE, CacheOpts); false -> ets_cache:delete(?LAST_CACHE) end. --spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +-spec cache_opts(gen_mod:opts()) -> [proplists:property()]. +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -301,10 +295,7 @@ cache_opts(Host, Opts) -> use_cache(Mod, Host) -> case erlang:function_exported(Mod, use_cache, 1) of true -> Mod:use_cache(Host); - false -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache) end. -spec cache_nodes(module(), binary()) -> [node()]. @@ -346,6 +337,12 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size -> (infinity) -> infinity end; mod_opt_type(O) when O == use_cache; O == cache_missed -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [db_type, iqdisc, cache_life_time, cache_size, use_cache, cache_missed]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_last_mnesia.erl b/src/mod_last_mnesia.erl index a926da1b5..de5e448d3 100644 --- a/src/mod_last_mnesia.erl +++ b/src/mod_last_mnesia.erl @@ -45,9 +45,7 @@ init(_Host, _Opts) -> use_cache(Host) -> case mnesia:table_info(last_activity, storage_type) of disc_only_copies -> - gen_mod:get_module_opt( - Host, mod_last, use_cache, - ejabberd_config:use_cache(Host)); + gen_mod:get_module_opt(Host, mod_last, use_cache); _ -> false end. diff --git a/src/mod_legacy_auth.erl b/src/mod_legacy_auth.erl index 8d163818c..19b905ad8 100644 --- a/src/mod_legacy_auth.erl +++ b/src/mod_legacy_auth.erl @@ -25,7 +25,7 @@ -protocol({xep, 78, '2.5'}). %% gen_mod API --export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1]). +-export([start/2, stop/1, reload/3, depends/2, mod_options/1]). %% hooks -export([c2s_unauthenticated_packet/2, c2s_stream_features/2]). @@ -54,7 +54,7 @@ reload(_Host, _NewOpts, _OldOpts) -> depends(_Host, _Opts) -> []. -mod_opt_type(_) -> +mod_options(_) -> []. -spec c2s_unauthenticated_packet(c2s_state(), iq()) -> diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 0f05603a8..8f3704923 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -39,7 +39,8 @@ disco_sm_features/5, remove_user/2, remove_room/3, mod_opt_type/1, muc_process_iq/2, muc_filter_message/3, message_is_archived/3, delete_old_messages/2, get_commands_spec/0, msg_to_el/4, - get_room_config/4, set_room_option/3, offline_message/1, export/1]). + get_room_config/4, set_room_option/3, offline_message/1, export/1, + mod_options/1]). -include("xmpp.hrl"). -include("logger.hrl"). @@ -74,7 +75,7 @@ %%% API %%%=================================================================== start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), init_cache(Host, Opts), @@ -103,7 +104,7 @@ start(Host, Opts) -> get_room_config, 50), ejabberd_hooks:add(set_room_option, Host, ?MODULE, set_room_option, 50), - case gen_mod:get_opt(assume_mam_usage, Opts, false) of + case gen_mod:get_opt(assume_mam_usage, Opts) of true -> ejabberd_hooks:add(message_is_archived, Host, ?MODULE, message_is_archived, 50); @@ -117,26 +118,21 @@ use_cache(Host, Opts) -> Mod = gen_mod:db_mod(Host, Opts, ?MODULE), case erlang:function_exported(Mod, use_cache, 2) of true -> Mod:use_cache(Host, Opts); - false -> - gen_mod:get_opt(use_cache, Opts, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_opt(use_cache, Opts) end. init_cache(Host, Opts) -> case use_cache(Host, Opts) of true -> - ets_cache:new(archive_prefs_cache, cache_opts(Host, Opts)); + ets_cache:new(archive_prefs_cache, cache_opts(Opts)); false -> ok end. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt(cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt(cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt(cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -168,7 +164,7 @@ stop(Host) -> get_room_config, 50), ejabberd_hooks:delete(set_room_option, Host, ?MODULE, set_room_option, 50), - case gen_mod:get_module_opt(Host, ?MODULE, assume_mam_usage, false) of + case gen_mod:get_module_opt(Host, ?MODULE, assume_mam_usage) of true -> ejabberd_hooks:delete(message_is_archived, Host, ?MODULE, message_is_archived, 50); @@ -190,14 +186,14 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - ets_cache:setopts(archive_prefs_cache, cache_opts(Host, NewOpts)), - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + ets_cache:setopts(archive_prefs_cache, cache_opts(NewOpts)), + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> register_iq_handlers(Host, IQDisc); true -> ok end, - case gen_mod:is_equal_opt(assume_mam_usage, NewOpts, OldOpts, false) of + case gen_mod:is_equal_opt(assume_mam_usage, NewOpts, OldOpts) of {false, true, _} -> ejabberd_hooks:add(message_is_archived, Host, ?MODULE, message_is_archived, 50); @@ -463,7 +459,7 @@ disco_sm_features(Acc, _From, _To, _Node, _Lang) -> message_is_archived(true, _C2SState, _Pkt) -> true; message_is_archived(false, #{lserver := LServer}, Pkt) -> - case gen_mod:get_module_opt(LServer, ?MODULE, assume_mam_usage, false) of + case gen_mod:get_module_opt(LServer, ?MODULE, assume_mam_usage) of true -> is_archived(Pkt, LServer); false -> @@ -480,7 +476,7 @@ delete_old_messages(TypeBin, Days) when TypeBin == <<"chat">>; DBTypes = lists:usort( lists:map( fun(Host) -> - case gen_mod:db_type(Host, ?MODULE) of + case gen_mod:get_module_opt(Host, ?MODULE, db_type) of sql -> {sql, Host}; Other -> {Other, global} end @@ -819,13 +815,13 @@ get_prefs(LUser, LServer) -> error -> ActivateOpt = gen_mod:get_module_opt( LServer, ?MODULE, - request_activates_archiving, false), + request_activates_archiving), case ActivateOpt of true -> #archive_prefs{us = {LUser, LServer}, default = never}; false -> Default = gen_mod:get_module_opt( - LServer, ?MODULE, default, never), + LServer, ?MODULE, default), #archive_prefs{us = {LUser, LServer}, default = Default} end end. @@ -838,7 +834,7 @@ prefs_el(Default, Always, Never, NS) -> maybe_activate_mam(LUser, LServer) -> ActivateOpt = gen_mod:get_module_opt( - LServer, ?MODULE, request_activates_archiving, false), + LServer, ?MODULE, request_activates_archiving), case ActivateOpt of true -> Mod = gen_mod:db_mod(LServer, ?MODULE), @@ -851,7 +847,7 @@ maybe_activate_mam(LUser, LServer) -> ok; error -> Default = gen_mod:get_module_opt( - LServer, ?MODULE, default, never), + LServer, ?MODULE, default), write_prefs(LUser, LServer, LServer, Default, [], []) end; false -> @@ -1081,7 +1077,15 @@ mod_opt_type(default) -> end; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(request_activates_archiving) -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [assume_mam_usage, cache_life_time, cache_size, use_cache, cache_missed, - db_type, default, iqdisc, request_activates_archiving]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{assume_mam_usage, false}, + {default, never}, + {request_activates_archiving, false}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_metrics.erl b/src/mod_metrics.erl index 7b2050389..69888eee2 100644 --- a/src/mod_metrics.erl +++ b/src/mod_metrics.erl @@ -32,7 +32,7 @@ -include("logger.hrl"). -include("xmpp.hrl"). --export([start/2, stop/1, mod_opt_type/1, depends/2, reload/3]). +-export([start/2, stop/1, mod_opt_type/1, mod_options/1, depends/2, reload/3]). -export([offline_message_hook/1, sm_register_connection_hook/3, sm_remove_connection_hook/3, @@ -127,8 +127,8 @@ register_user(_User, Server) -> %%==================================================================== push(Host, Probe) -> - IP = gen_mod:get_module_opt(Host, ?MODULE, ip, {127,0,0,1}), - Port = gen_mod:get_module_opt(Host, ?MODULE, port, 11111), + IP = gen_mod:get_module_opt(Host, ?MODULE, ip), + Port = gen_mod:get_module_opt(Host, ?MODULE, port), send_metrics(Host, Probe, IP, Port). send_metrics(Host, Probe, Peer, Port) -> @@ -184,6 +184,7 @@ mod_opt_type(ip) -> IP end; mod_opt_type(port) -> - fun(I) when is_integer(I), I>0, I<65536 -> I end; -mod_opt_type(_) -> - [ip, port]. + fun(I) when is_integer(I), I>0, I<65536 -> I end. + +mod_options(_) -> + [{ip, <<"127.0.0.1">>}, {port, 11111}]. diff --git a/src/mod_mix.erl b/src/mod_mix.erl index b91dd77f1..fc51a5a02 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -30,7 +30,7 @@ %% API -export([start/2, stop/1, process_iq/1, disco_items/5, disco_identity/5, disco_info/5, - disco_features/5, mod_opt_type/1, depends/2]). + disco_features/5, mod_opt_type/1, mod_options/1, depends/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -124,8 +124,8 @@ process_iq(#iq{lang = Lang} = IQ) -> %%%=================================================================== init([ServerHost, Opts]) -> process_flag(trap_exit, true), - Hosts = gen_mod:get_opt_hosts(ServerHost, Opts, <<"mix.@HOST@">>), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(ServerHost)), + Hosts = gen_mod:get_opt_hosts(ServerHost, Opts), + IQDisc = gen_mod:get_opt(iqdisc, Opts), lists:foreach( fun(Host) -> ConfigTab = gen_mod:get_module_proc(Host, config), @@ -319,5 +319,9 @@ depends(_Host, _Opts) -> mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(hosts) -> - fun (L) -> lists:map(fun iolist_to_binary/1, L) end; -mod_opt_type(_) -> [host, hosts, iqdisc]. + fun (L) -> lists:map(fun iolist_to_binary/1, L) end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {host, <<"mix.@HOST@">>}, + {hosts, []}]. diff --git a/src/mod_muc.erl b/src/mod_muc.erl index d3ad90cb4..0cf03fa81 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -69,7 +69,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, - mod_opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -233,7 +233,7 @@ get_online_rooms_by_user(ServerHost, LUser, LServer) -> init([Host, Opts]) -> process_flag(trap_exit, true), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), #state{access = Access, hosts = MyHosts, history_size = HistorySize, queue_type = QueueType, room_shaper = RoomShaper} = State = init_state(Host, Opts), @@ -273,8 +273,8 @@ handle_call({create, Room, Host, From, Nick, Opts}, _From, {reply, ok, State}. handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{hosts = OldHosts}) -> - NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)), - OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)), + NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts), + OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts), NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE), NewRMod = gen_mod:ram_db_mod(ServerHost, NewOpts, ?MODULE), OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE), @@ -353,18 +353,16 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%% Internal functions %%-------------------------------------------------------------------- init_state(Host, Opts) -> - MyHosts = gen_mod:get_opt_hosts(Host, Opts, - <<"conference.@HOST@">>), - Access = gen_mod:get_opt(access, Opts, all), - AccessCreate = gen_mod:get_opt(access_create, Opts, all), - AccessAdmin = gen_mod:get_opt(access_admin, Opts, none), - AccessPersistent = gen_mod:get_opt(access_persistent, Opts, all), - HistorySize = gen_mod:get_opt(history_size, Opts, 20), - MaxRoomsDiscoItems = gen_mod:get_opt(max_rooms_discoitems, Opts, 100), - DefRoomOpts = gen_mod:get_opt(default_room_options, Opts, []), - QueueType = gen_mod:get_opt(queue_type, Opts, - ejabberd_config:default_queue_type(Host)), - RoomShaper = gen_mod:get_opt(room_shaper, Opts, none), + MyHosts = gen_mod:get_opt_hosts(Host, Opts), + Access = gen_mod:get_opt(access, Opts), + AccessCreate = gen_mod:get_opt(access_create, Opts), + AccessAdmin = gen_mod:get_opt(access_admin, Opts), + AccessPersistent = gen_mod:get_opt(access_persistent, Opts), + HistorySize = gen_mod:get_opt(history_size, Opts), + MaxRoomsDiscoItems = gen_mod:get_opt(max_rooms_discoitems, Opts), + DefRoomOpts = gen_mod:get_opt(default_room_options, Opts), + QueueType = gen_mod:get_opt(queue_type, Opts), + RoomShaper = gen_mod:get_opt(room_shaper, Opts), #state{hosts = MyHosts, server_host = Host, access = {Access, AccessCreate, AccessAdmin, AccessPersistent}, @@ -527,7 +525,7 @@ process_disco_info(#iq{type = get, to = To, lang = Lang, Features = [?NS_DISCO_INFO, ?NS_DISCO_ITEMS, ?NS_REGISTER, ?NS_MUC, ?NS_VCARD, ?NS_MUCSUB, ?NS_MUC_UNIQUE | RSMFeatures ++ MAMFeatures], - Name = gen_mod:get_module_opt(ServerHost, ?MODULE, name, ?T("Chatrooms")), + Name = gen_mod:get_module_opt(ServerHost, ?MODULE, name), Identity = #identity{category = <<"conference">>, type = <<"text">>, name = translate:translate(Lang, Name)}, @@ -551,8 +549,7 @@ process_disco_items(#iq{type = get, from = From, to = To, lang = Lang, Host = To#jid.lserver, ServerHost = ejabberd_router:host_of_route(Host), MaxRoomsDiscoItems = gen_mod:get_module_opt( - ServerHost, ?MODULE, max_rooms_discoitems, - 100), + ServerHost, ?MODULE, max_rooms_discoitems), case iq_disco_items(ServerHost, Host, From, Lang, MaxRoomsDiscoItems, Node, RSM) of {error, Err} -> @@ -605,8 +602,8 @@ check_user_can_create_room(ServerHost, AccessCreate, end. check_create_roomid(ServerHost, RoomID) -> - Max = gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id, infinity), - Regexp = gen_mod:get_module_opt(ServerHost, ?MODULE, regexp_room_id, ""), + Max = gen_mod:get_module_opt(ServerHost, ?MODULE, max_room_id), + Regexp = gen_mod:get_module_opt(ServerHost, ?MODULE, regexp_room_id), (byte_size(RoomID) =< Max) and (re:run(RoomID, Regexp, [unicode, {capture, none}]) == match). @@ -976,34 +973,56 @@ mod_opt_type({default_room_options, presence_broadcast}) -> (visitor) -> visitor end, L) end; -mod_opt_type(_) -> - [access, access_admin, access_create, access_persistent, - db_type, ram_db_type, history_size, host, hosts, name, - max_room_desc, max_room_id, max_room_name, - max_rooms_discoitems, max_user_conferences, max_users, - max_users_admin_threshold, max_users_presence, - min_message_interval, min_presence_interval, queue_type, - regexp_room_id, room_shaper, user_message_shaper, user_presence_shaper, - {default_room_options, allow_change_subj}, - {default_room_options, allow_private_messages}, - {default_room_options, allow_query_users}, - {default_room_options, allow_user_invites}, - {default_room_options, allow_visitor_nickchange}, - {default_room_options, allow_visitor_status}, - {default_room_options, anonymous}, - {default_room_options, captcha_protected}, - {default_room_options, logging}, - {default_room_options, members_by_default}, - {default_room_options, members_only}, - {default_room_options, moderated}, - {default_room_options, password_protected}, - {default_room_options, persistent}, - {default_room_options, public}, - {default_room_options, public_list}, - {default_room_options, mam}, - {default_room_options, allow_subscription}, - {default_room_options, password}, - {default_room_options, title}, - {default_room_options, allow_private_messages_from_visitors}, - {default_room_options, max_users}, - {default_room_options, presence_broadcast}]. +mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1. + +mod_options(Host) -> + [{access, all}, + {access_admin, none}, + {access_create, all}, + {access_persistent, all}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {ram_db_type, ejabberd_config:default_ram_db(Host, ?MODULE)}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {history_size, 20}, + {host, <<"conference.@HOST@">>}, + {hosts, []}, + {name, ?T("Chatrooms")}, + {max_room_desc, infinity}, + {max_room_id, infinity}, + {max_room_name, infinity}, + {max_rooms_discoitems, 100}, + {max_user_conferences, 10}, + {max_users, 200}, + {max_users_admin_threshold, 5}, + {max_users_presence, 1000}, + {min_message_interval, 0}, + {min_presence_interval, 0}, + {queue_type, ejabberd_config:default_queue_type(Host)}, + {regexp_room_id, <<"">>}, + {room_shaper, none}, + {user_message_shaper, none}, + {user_presence_shaper, none}, + {default_room_options, + [{allow_change_subj,true}, + {allow_private_messages,true}, + {allow_query_users,true}, + {allow_user_invites,false}, + {allow_visitor_nickchange,true}, + {allow_visitor_status,true}, + {anonymous,true}, + {captcha_protected,false}, + {logging,false}, + {members_by_default,true}, + {members_only,false}, + {moderated,true}, + {password_protected,false}, + {persistent,false}, + {public,true}, + {public_list,true}, + {mam,false}, + {allow_subscription,false}, + {password,<<>>}, + {title,<<>>}, + {allow_private_messages_from_visitors,anyone}, + {max_users,200}, + {presence_broadcast,[moderator,participant,visitor]}]}]. diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 5fb01132b..0bd47dcaa 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -40,7 +40,7 @@ set_room_affiliation/4, get_room_affiliations/2, web_menu_main/2, web_page_main/2, web_menu_host/3, subscribe_room/4, unsubscribe_room/2, get_subscribers/2, - web_page_host/3, mod_opt_type/1, get_commands_spec/0]). + web_page_host/3, mod_options/1, get_commands_spec/0]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -578,7 +578,7 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) -> %% Get the default room options from the muc configuration DefRoomOpts = gen_mod:get_module_opt(ServerHost, mod_muc, - default_room_options, []), + default_room_options), %% Change default room options as required FormattedRoomOpts = [format_room_option(Opt, Val) || {Opt, Val}<-CustomRoomOpts], RoomOpts = lists:ukeymerge(1, @@ -589,14 +589,13 @@ create_room_with_opts(Name1, Host1, ServerHost, CustomRoomOpts) -> mod_muc:store_room(ServerHost, Host, Name, RoomOpts), %% Get all remaining mod_muc parameters that might be utilized - Access = gen_mod:get_module_opt(ServerHost, mod_muc, access, all), - AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create, all), - AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin, none), - AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent, all), - HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size, 20), - RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper, none), - QueueType = gen_mod:get_module_opt(ServerHost, mod_muc, queue_type, - ejabberd_config:default_queue_type(ServerHost)), + Access = gen_mod:get_module_opt(ServerHost, mod_muc, access), + AcCreate = gen_mod:get_module_opt(ServerHost, mod_muc, access_create), + AcAdmin = gen_mod:get_module_opt(ServerHost, mod_muc, access_admin), + AcPer = gen_mod:get_module_opt(ServerHost, mod_muc, access_persistent), + HistorySize = gen_mod:get_module_opt(ServerHost, mod_muc, history_size), + RoomShaper = gen_mod:get_module_opt(ServerHost, mod_muc, room_shaper), + QueueType = gen_mod:get_module_opt(ServerHost, mod_muc, queue_type), %% If the room does not exist yet in the muc_online_room case mod_muc:find_online_room(Name, Host) of @@ -698,7 +697,7 @@ create_rooms_file(Filename) -> file:close(F), %% Read the default room options defined for the first virtual host DefRoomOpts = gen_mod:get_module_opt(?MYNAME, mod_muc, - default_room_options, []), + default_room_options), [muc_create_room(?MYNAME, A, DefRoomOpts) || A <- Rooms], ok. @@ -1215,4 +1214,4 @@ find_hosts(ServerHost) -> [] end. -mod_opt_type(_) -> []. +mod_options(_) -> []. diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index f8957a23e..bf88b2d8b 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -39,7 +39,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, - mod_opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -138,16 +138,16 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}. %%% Internal functions %%-------------------------------------------------------------------- init_state(Host, Opts) -> - OutDir = gen_mod:get_opt(outdir, Opts, <<"www/muc">>), - DirType = gen_mod:get_opt(dirtype, Opts, subdirs), - DirName = gen_mod:get_opt(dirname, Opts, room_jid), - FileFormat = gen_mod:get_opt(file_format, Opts, html), - FilePermissions = gen_mod:get_opt(file_permissions, Opts, {644, 33}), - CSSFile = gen_mod:get_opt(cssfile, Opts, false), - AccessLog = gen_mod:get_opt(access_log, Opts, muc_admin), - Timezone = gen_mod:get_opt(timezone, Opts, local), - Top_link = gen_mod:get_opt(top_link, Opts, {<<"/">>, <<"Home">>}), - NoFollow = gen_mod:get_opt(spam_prevention, Opts, true), + OutDir = gen_mod:get_opt(outdir, Opts), + DirType = gen_mod:get_opt(dirtype, Opts), + DirName = gen_mod:get_opt(dirname, Opts), + FileFormat = gen_mod:get_opt(file_format, Opts), + FilePermissions = gen_mod:get_opt(file_permissions, Opts), + CSSFile = gen_mod:get_opt(cssfile, Opts), + AccessLog = gen_mod:get_opt(access_log, Opts), + Timezone = gen_mod:get_opt(timezone, Opts), + Top_link = gen_mod:get_opt(top_link, Opts), + NoFollow = gen_mod:get_opt(spam_prevention, Opts), Lang = ejabberd_config:get_lang(Host), #logstate{host = Host, out_dir = OutDir, dir_type = DirType, dir_name = DirName, @@ -931,7 +931,10 @@ has_no_permanent_store_hint(Packet) -> mod_opt_type(access_log) -> fun acl:access_rules_validator/1; -mod_opt_type(cssfile) -> fun misc:try_read_file/1; +mod_opt_type(cssfile) -> + fun(false) -> false; + (File) -> misc:try_read_file(File) + end; mod_opt_type(dirname) -> fun (room_jid) -> room_jid; (room_name) -> room_name @@ -963,8 +966,18 @@ mod_opt_type(timezone) -> mod_opt_type(top_link) -> fun ([{S1, S2}]) -> {iolist_to_binary(S1), iolist_to_binary(S2)} - end; -mod_opt_type(_) -> - [access_log, cssfile, dirname, dirtype, file_format, - {file_permissions, mode}, {file_permissions, group}, - outdir, spam_prevention, timezone, top_link]. + end. + +mod_options(_) -> + [{access_log, muc_admin}, + {cssfile, false}, + {dirname, room_jid}, + {dirtype, subdirs}, + {file_format, html}, + {file_permissions, + [{mode, 644}, + {group, 33}]}, + {outdir, <<"www/muc">>}, + {spam_prevention, true}, + {timezone, local}, + {top_link, [{<<"/">>, <<"Home">>}]}]. diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index 9a12e97fb..a82689406 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -164,8 +164,8 @@ normal_state({route, <<"">>, Now = p1_time_compat:system_time(micro_seconds), MinMessageInterval = trunc(gen_mod:get_module_opt( StateData#state.server_host, - mod_muc, min_message_interval, - 0) * 1000000), + mod_muc, min_message_interval) + * 1000000), Size = element_size(Packet), {MessageShaper, MessageShaperInterval} = shaper:update(Activity#activity.message_shaper, Size), @@ -346,8 +346,8 @@ normal_state({route, Nick, #presence{from = From} = Packet}, StateData) -> Now = p1_time_compat:system_time(micro_seconds), MinPresenceInterval = trunc(gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, min_presence_interval, - 0) * 1000000), + mod_muc, min_presence_interval) + * 1000000), if (Now >= Activity#activity.presence_time + MinPresenceInterval) and (Activity#activity.presence == undefined) -> NewActivity = Activity#activity{presence_time = Now}, @@ -1421,30 +1421,28 @@ get_max_users(StateData) -> -spec get_service_max_users(state()) -> pos_integer(). get_service_max_users(StateData) -> gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, max_users, - ?MAX_USERS_DEFAULT). + mod_muc, max_users). -spec get_max_users_admin_threshold(state()) -> pos_integer(). get_max_users_admin_threshold(StateData) -> gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, max_users_admin_threshold, - 5). + mod_muc, max_users_admin_threshold). -spec room_queue_new(binary(), shaper:shaper(), _) -> p1_queue:queue(). room_queue_new(ServerHost, Shaper, QueueType) -> HaveRoomShaper = Shaper /= none, HaveMessageShaper = gen_mod:get_module_opt( - ServerHost, mod_muc, user_message_shaper, - none) /= none, + ServerHost, mod_muc, + user_message_shaper) /= none, HavePresenceShaper = gen_mod:get_module_opt( - ServerHost, mod_muc, user_presence_shaper, - none) /= none, + ServerHost, mod_muc, + user_presence_shaper) /= none, HaveMinMessageInterval = gen_mod:get_module_opt( - ServerHost, mod_muc, min_message_interval, - 0) /= 0, + ServerHost, mod_muc, + min_message_interval) /= 0, HaveMinPresenceInterval = gen_mod:get_module_opt( - ServerHost, mod_muc, min_presence_interval, - 0) /= 0, + ServerHost, mod_muc, + min_presence_interval) /= 0, if HaveRoomShaper or HaveMessageShaper or HavePresenceShaper or HaveMinMessageInterval or HaveMinPresenceInterval -> p1_queue:new(QueueType); @@ -1461,12 +1459,10 @@ get_user_activity(JID, StateData) -> error -> MessageShaper = shaper:new(gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, user_message_shaper, - none)), + mod_muc, user_message_shaper)), PresenceShaper = shaper:new(gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, user_presence_shaper, - none)), + mod_muc, user_presence_shaper)), #activity{message_shaper = MessageShaper, presence_shaper = PresenceShaper} end. @@ -1475,12 +1471,12 @@ get_user_activity(JID, StateData) -> store_user_activity(JID, UserActivity, StateData) -> MinMessageInterval = trunc(gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, min_message_interval, - 0) * 1000), + mod_muc, min_message_interval) + * 1000), MinPresenceInterval = trunc(gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, min_presence_interval, - 0) * 1000), + mod_muc, min_presence_interval) + * 1000), Key = jid:tolower(JID), Now = p1_time_compat:system_time(micro_seconds), Activity1 = clean_treap(StateData#state.activity, @@ -1788,8 +1784,7 @@ add_new_user(From, Nick, Packet, StateData) -> NConferences = tab_count_user(From, StateData), MaxConferences = gen_mod:get_module_opt(StateData#state.server_host, - mod_muc, max_user_conferences, - 10), + mod_muc, max_user_conferences), Collision = nick_collision(From, Nick, StateData), IsSubscribeRequest = not is_record(Packet, presence), case {(ServiceAffiliation == owner orelse @@ -2060,8 +2055,7 @@ filter_history(Queue, Now, Nick, is_room_overcrowded(StateData) -> MaxUsersPresence = gen_mod:get_module_opt( StateData#state.server_host, - mod_muc, max_users_presence, - ?DEFAULT_MAX_USERS_PRESENCE), + mod_muc, max_users_presence), (?DICT):size(StateData#state.users) > MaxUsersPresence. -spec presence_broadcast_allowed(jid(), state()) -> boolean(). @@ -3126,12 +3120,10 @@ is_allowed_room_name_desc_limits(Options, StateData) -> RoomDesc = proplists:get_value(roomdesc, Options, <<"">>), MaxRoomName = gen_mod:get_module_opt( StateData#state.server_host, - mod_muc, max_room_name, - infinity), + mod_muc, max_room_name), MaxRoomDesc = gen_mod:get_module_opt( StateData#state.server_host, - mod_muc, max_room_desc, - infinity), + mod_muc, max_room_desc), (byte_size(RoomName) =< MaxRoomName) andalso (byte_size(RoomDesc) =< MaxRoomDesc). @@ -3156,8 +3148,7 @@ is_password_settings_correct(Options, StateData) -> get_default_room_maxusers(RoomState) -> DefRoomOpts = gen_mod:get_module_opt(RoomState#state.server_host, - mod_muc, default_room_options, - []), + mod_muc, default_room_options), RoomState2 = set_opts(DefRoomOpts, RoomState), (RoomState2#state.config)#config.max_users. diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl index f2a48ecaf..e6b2a93d2 100644 --- a/src/mod_multicast.erl +++ b/src/mod_multicast.erl @@ -40,7 +40,7 @@ -export([init/1, handle_info/2, handle_call/3, handle_cast/2, terminate/2, code_change/3]). --export([purge_loop/1, mod_opt_type/1, depends/2]). +-export([purge_loop/1, mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -132,10 +132,9 @@ reload(LServerS, NewOpts, OldOpts) -> init([LServerS, Opts]) -> process_flag(trap_exit, true), - LServiceS = gen_mod:get_opt_host(LServerS, Opts, - <<"multicast.@HOST@">>), - Access = gen_mod:get_opt(access, Opts, all), - SLimits = build_service_limit_record(gen_mod:get_opt(limits, Opts, [])), + [LServiceS|_] = gen_mod:get_opt_hosts(LServerS, Opts), + Access = gen_mod:get_opt(access, Opts), + SLimits = build_service_limit_record(gen_mod:get_opt(limits, Opts)), create_cache(), try_start_loop(), create_pool(), @@ -150,10 +149,9 @@ handle_call(stop, _From, State) -> handle_cast({reload, NewOpts, NewOpts}, #state{lserver = LServerS, lservice = OldLServiceS} = State) -> - Access = gen_mod:get_opt(access, NewOpts, all), - SLimits = build_service_limit_record(gen_mod:get_opt(limits, NewOpts, [])), - NewLServiceS = gen_mod:get_opt_host(LServerS, NewOpts, - <<"multicast.@HOST@">>), + Access = gen_mod:get_opt(access, NewOpts), + SLimits = build_service_limit_record(gen_mod:get_opt(limits, NewOpts)), + [NewLServiceS|_] = gen_mod:get_opt_hosts(LServerS, NewOpts), if NewLServiceS /= OldLServiceS -> ejabberd_router:register_route(NewLServiceS, LServerS), ejabberd_router:unregister_route(OldLServiceS); @@ -261,8 +259,7 @@ process_iq(_, _) -> -define(FEATURE(Feat), Feat). iq_disco_info(From, Lang, State) -> - Name = gen_mod:get_module_opt(State#state.lserver, ?MODULE, - name, ?T("Multicast")), + Name = gen_mod:get_module_opt(State#state.lserver, ?MODULE, name), #disco_info{ identities = [#identity{category = <<"service">>, type = <<"multicast">>, @@ -1121,6 +1118,8 @@ depends(_Host, _Opts) -> mod_opt_type(access) -> fun acl:access_rules_validator/1; mod_opt_type(host) -> fun iolist_to_binary/1; +mod_opt_type(hosts) -> + fun(L) -> lists:map(fun iolist_to_binary/1, L) end; mod_opt_type(name) -> fun iolist_to_binary/1; mod_opt_type({limits, Type}) when (Type == local) or (Type == remote) -> fun(L) -> @@ -1130,5 +1129,11 @@ mod_opt_type({limits, Type}) when (Type == local) or (Type == remote) -> ({message, I} = O) when is_integer(I) -> O; ({presence, I} = O) when is_integer(I) -> O end, L) - end; -mod_opt_type(_) -> [access, host, {limits, local}, {limits, remote}, name]. + end. + +mod_options(_Host) -> + [{access, all}, + {host, <<"multicast.@HOST@">>}, + {hosts, []}, + {limits, [{local, []}, {remote, []}]}, + {name, ?T("Multicast")}]. diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 5c509acca..d9f66843e 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -63,7 +63,7 @@ webadmin_user/4, webadmin_user_parse_query/5]). --export([mod_opt_type/1, depends/2]). +-export([mod_opt_type/1, mod_options/1, depends/2]). -deprecated({get_queue_length,2}). @@ -108,7 +108,7 @@ depends(_Host, _Opts) -> start(Host, Opts) -> Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), ejabberd_hooks:add(offline_message_hook, Host, ?MODULE, store_packet, 50), ejabberd_hooks:add(c2s_self_presence, Host, ?MODULE, c2s_self_presence, 50), @@ -163,7 +163,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_FLEX_OFFLINE, ?MODULE, handle_offline_query, IQDisc); @@ -187,8 +187,7 @@ store_offline_msg(#offline_msg{us = {User, Server}} = Msg) -> end. get_max_user_messages(User, Server) -> - Access = gen_mod:get_module_opt(Server, ?MODULE, access_max_user_messages, - max_user_offline_messages), + Access = gen_mod:get_module_opt(Server, ?MODULE, access_max_user_messages), case acl:match_rule(Server, Access, jid:make(User, Server)) of Max when is_integer(Max) -> Max; infinity -> infinity; @@ -388,8 +387,7 @@ need_to_store(LServer, #message{type = Type} = Packet) -> false; none -> case gen_mod:get_module_opt( - LServer, ?MODULE, store_empty_body, - unless_chat_state) of + LServer, ?MODULE, store_empty_body) of true -> true; false -> @@ -850,5 +848,10 @@ mod_opt_type(store_empty_body) -> fun (V) when is_boolean(V) -> V; (unless_chat_state) -> unless_chat_state end; -mod_opt_type(_) -> - [access_max_user_messages, db_type, store_empty_body]. +mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1. + +mod_options(Host) -> + [{db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {access_max_user_messages, max_user_offline_messages}, + {store_empty_body, unless_chat_state}]. diff --git a/src/mod_ping.erl b/src/mod_ping.erl index a51d4e8a2..5c349a75d 100644 --- a/src/mod_ping.erl +++ b/src/mod_ping.erl @@ -38,10 +38,6 @@ -include("xmpp.hrl"). --define(DEFAULT_SEND_PINGS, false). - --define(DEFAULT_PING_INTERVAL, 60). - %% API -export([start_ping/2, stop_ping/2]). @@ -53,14 +49,14 @@ handle_cast/2, handle_info/2, code_change/3]). -export([iq_ping/1, user_online/3, user_offline/3, - user_send/1, mod_opt_type/1, depends/2]). + user_send/1, mod_opt_type/1, mod_options/1, depends/2]). -record(state, - {host = <<"">>, - send_pings = ?DEFAULT_SEND_PINGS :: boolean(), - ping_interval = ?DEFAULT_PING_INTERVAL :: non_neg_integer(), - ping_ack_timeout = undefined :: non_neg_integer(), - timeout_action = none :: none | kill, + {host = <<"">> :: binary(), + send_pings :: boolean(), + ping_interval :: non_neg_integer(), + ping_ack_timeout :: undefined | non_neg_integer(), + timeout_action ::none | kill, timers = maps:new() :: map()}). %%==================================================================== @@ -95,7 +91,7 @@ reload(Host, NewOpts, OldOpts) -> init([Host, Opts]) -> process_flag(trap_exit, true), State = init_state(Host, Opts), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), register_iq_handlers(Host, IQDisc), case State#state.send_pings of true -> register_hooks(Host); @@ -114,7 +110,7 @@ handle_call(_Req, _From, State) -> handle_cast({reload, Host, NewOpts, OldOpts}, #state{timers = Timers} = OldState) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> register_iq_handlers(Host, IQDisc); true -> ok end, @@ -196,10 +192,10 @@ user_send({Packet, #{jid := JID} = C2SState}) -> %% Internal functions %%==================================================================== init_state(Host, Opts) -> - SendPings = gen_mod:get_opt(send_pings, Opts, ?DEFAULT_SEND_PINGS), - PingInterval = gen_mod:get_opt(ping_interval, Opts, ?DEFAULT_PING_INTERVAL), + SendPings = gen_mod:get_opt(send_pings, Opts), + PingInterval = gen_mod:get_opt(ping_interval, Opts), PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts), - TimeoutAction = gen_mod:get_opt(timeout_action, Opts, none), + TimeoutAction = gen_mod:get_opt(timeout_action, Opts), #state{host = Host, send_pings = SendPings, ping_interval = PingInterval, @@ -271,12 +267,19 @@ mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(ping_interval) -> fun (I) when is_integer(I), I > 0 -> I end; mod_opt_type(ping_ack_timeout) -> - fun(I) when is_integer(I), I>0 -> timer:seconds(I) end; + fun(undefined) -> undefined; + (I) when is_integer(I), I>0 -> timer:seconds(I) + end; mod_opt_type(send_pings) -> fun (B) when is_boolean(B) -> B end; mod_opt_type(timeout_action) -> fun (none) -> none; (kill) -> kill - end; -mod_opt_type(_) -> - [iqdisc, ping_interval, ping_ack_timeout, send_pings, timeout_action]. + end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {ping_interval, 60}, + {ping_ack_timeout, undefined}, + {send_pings, false}, + {timeout_action, none}]. diff --git a/src/mod_pres_counter.erl b/src/mod_pres_counter.erl index c747eb361..62e4fc08f 100644 --- a/src/mod_pres_counter.erl +++ b/src/mod_pres_counter.erl @@ -28,7 +28,7 @@ -behavior(gen_mod). -export([start/2, stop/1, reload/3, check_packet/4, - mod_opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -79,8 +79,8 @@ check_packet(Acc, _, _, _) -> Acc. update(Server, JID, Dir) -> - StormCount = gen_mod:get_module_opt(Server, ?MODULE, count, 5), - TimeInterval = gen_mod:get_module_opt(Server, ?MODULE, interval, 60), + StormCount = gen_mod:get_module_opt(Server, ?MODULE, count), + TimeInterval = gen_mod:get_module_opt(Server, ?MODULE, interval), TimeStamp = p1_time_compat:system_time(seconds), case read(Dir) of undefined -> @@ -126,5 +126,7 @@ write(K, V) -> put({pres_counter, K}, V). mod_opt_type(count) -> fun (I) when is_integer(I), I > 0 -> I end; mod_opt_type(interval) -> - fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(_) -> [count, interval]. + fun (I) when is_integer(I), I > 0 -> I end. + +mod_options(_) -> + [{count, 5}, {interval, 60}]. diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 7f0d8e216..888a231ed 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -38,7 +38,7 @@ set_list/1, set_list/4, set_default_list/3, user_send_packet/1, user_receive_packet/1, import_start/2, import_stop/2, import/5, import_info/0, - mod_opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -70,7 +70,7 @@ -optional_callbacks([use_cache/1, cache_nodes/1]). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), init_cache(Mod, Host, Opts), @@ -114,7 +114,7 @@ reload(Host, NewOpts, OldOpts) -> ok end, init_cache(NewMod, Host, NewOpts), - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY, ?MODULE, process_iq, IQDisc); @@ -681,7 +681,7 @@ remove_user(User, Server) -> init_cache(Mod, Host, Opts) -> case use_cache(Mod, Host) of true -> - CacheOpts = cache_opts(Host, Opts), + CacheOpts = cache_opts(Opts), ets_cache:new(?PRIVACY_CACHE, CacheOpts), ets_cache:new(?PRIVACY_LIST_CACHE, CacheOpts); false -> @@ -689,17 +689,11 @@ init_cache(Mod, Host, Opts) -> ets_cache:delete(?PRIVACY_LIST_CACHE) end. --spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +-spec cache_opts(gen_mod:opts()) -> [proplists:property()]. +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -709,10 +703,7 @@ cache_opts(Host, Opts) -> use_cache(Mod, Host) -> case erlang:function_exported(Mod, use_cache, 1) of true -> Mod:use_cache(Host); - false -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache) end. -spec cache_nodes(module(), binary()) -> [node()]. @@ -851,7 +842,12 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size -> (infinity) -> infinity end; mod_opt_type(O) when O == use_cache; O == cache_missed -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [db_type, iqdisc, cache_life_time, cache_size, - use_cache, cache_missed]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_privacy_mnesia.erl b/src/mod_privacy_mnesia.erl index b0acf40da..a28910c0f 100644 --- a/src/mod_privacy_mnesia.erl +++ b/src/mod_privacy_mnesia.erl @@ -47,9 +47,7 @@ init(_Host, _Opts) -> use_cache(Host) -> case mnesia:table_info(privacy, storage_type) of disc_only_copies -> - gen_mod:get_module_opt( - Host, mod_privacy, use_cache, - ejabberd_config:use_cache(Host)); + gen_mod:get_module_opt(Host, mod_privacy, use_cache); _ -> false end. diff --git a/src/mod_private.erl b/src/mod_private.erl index f04d9c739..f819f2b60 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -33,7 +33,8 @@ -export([start/2, stop/1, reload/3, process_sm_iq/1, import_info/0, remove_user/2, get_data/2, get_data/3, export/1, - import/5, import_start/2, mod_opt_type/1, set_data/3, depends/2]). + import/5, import_start/2, mod_opt_type/1, set_data/3, + mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -54,7 +55,7 @@ -optional_callbacks([use_cache/1, cache_nodes/1]). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), init_cache(Mod, Host, Opts), @@ -78,7 +79,7 @@ reload(Host, NewOpts, OldOpts) -> ok end, init_cache(NewMod, Host, NewOpts), - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE, ?MODULE, process_sm_iq, IQDisc); @@ -208,23 +209,17 @@ delete_cache(Mod, LUser, LServer, Data) -> init_cache(Mod, Host, Opts) -> case use_cache(Mod, Host) of true -> - CacheOpts = cache_opts(Host, Opts), + CacheOpts = cache_opts(Opts), ets_cache:new(?PRIVATE_CACHE, CacheOpts); false -> ets_cache:delete(?PRIVATE_CACHE) end. --spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +-spec cache_opts(gen_mod:opts()) -> [proplists:property()]. +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -234,10 +229,7 @@ cache_opts(Host, Opts) -> use_cache(Mod, Host) -> case erlang:function_exported(Mod, use_cache, 1) of true -> Mod:use_cache(Host); - false -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache) end. -spec cache_nodes(module(), binary()) -> [node()]. @@ -272,6 +264,12 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size -> (infinity) -> infinity end; mod_opt_type(O) when O == use_cache; O == cache_missed -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [db_type, iqdisc, cache_life_time, cache_size, use_cache, cache_missed]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_private_mnesia.erl b/src/mod_private_mnesia.erl index f51c1a395..b981a803a 100644 --- a/src/mod_private_mnesia.erl +++ b/src/mod_private_mnesia.erl @@ -46,9 +46,7 @@ init(_Host, _Opts) -> use_cache(Host) -> case mnesia:table_info(private_storage, storage_type) of disc_only_copies -> - gen_mod:get_module_opt( - Host, mod_private, use_cache, - ejabberd_config:use_cache(Host)); + gen_mod:get_module_opt(Host, mod_private, use_cache); _ -> false end. diff --git a/src/mod_privilege.erl b/src/mod_privilege.erl index a8cf8a096..e201338f3 100644 --- a/src/mod_privilege.erl +++ b/src/mod_privilege.erl @@ -31,7 +31,7 @@ -behaviour(gen_mod). %% API --export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, mod_opt_type/1, mod_options/1, depends/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). @@ -60,10 +60,12 @@ reload(_Host, _NewOpts, _OldOpts) -> mod_opt_type({roster, _}) -> fun acl:access_rules_validator/1; mod_opt_type({message, _}) -> fun acl:access_rules_validator/1; -mod_opt_type({presence, _}) -> fun acl:access_rules_validator/1; -mod_opt_type(_) -> - [{roster, both}, {roster, get}, {roster, set}, - {message, outgoing}, {presence, managed_entity}, {presence, roster}]. +mod_opt_type({presence, _}) -> fun acl:access_rules_validator/1. + +mod_options(_) -> + [{roster, [{both, none}, {get, none}, {set, none}]}, + {presence, [{managed_entity, none}, {roster, none}]}, + {message, [{outgoing,none}]}]. depends(_, _) -> []. @@ -307,7 +309,7 @@ forward_message(#message{to = To} = Msg) -> end. get_roster_permission(ServerHost, Host) -> - Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, roster, []), + Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, roster), case match_rule(ServerHost, Host, Perms, both) of allow -> both; @@ -322,14 +324,14 @@ get_roster_permission(ServerHost, Host) -> end. get_message_permission(ServerHost, Host) -> - Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, message, []), + Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, message), case match_rule(ServerHost, Host, Perms, outgoing) of allow -> outgoing; deny -> none end. get_presence_permission(ServerHost, Host) -> - Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, presence, []), + Perms = gen_mod:get_module_opt(ServerHost, ?MODULE, presence), case match_rule(ServerHost, Host, Perms, roster) of allow -> roster; diff --git a/src/mod_proxy65.erl b/src/mod_proxy65.erl index d49b95b92..eb6950c60 100644 --- a/src/mod_proxy65.erl +++ b/src/mod_proxy65.erl @@ -39,10 +39,12 @@ %% supervisor callbacks. -export([init/1]). --export([start_link/2, mod_opt_type/1, depends/2]). +-export([start_link/2, mod_opt_type/1, mod_options/1, depends/2]). -define(PROCNAME, ejabberd_mod_proxy65). +-include("translate.hrl"). + -callback init() -> any(). -callback register_stream(binary(), pid()) -> ok | {error, any()}. -callback unregister_stream(binary()) -> ok | {error, any()}. @@ -114,9 +116,14 @@ mod_opt_type(access) -> fun acl:access_rules_validator/1; mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(hosts) -> fun(L) -> lists:map(fun iolist_to_binary/1, L) end; -mod_opt_type(hostname) -> fun iolist_to_binary/1; +mod_opt_type(hostname) -> + fun(undefined) -> undefined; + (H) -> iolist_to_binary(H) + end; mod_opt_type(ip) -> - fun (S) -> + fun(undefined) -> + undefined; + (S) -> {ok, Addr} = inet_parse:address(binary_to_list(iolist_to_binary(S))), Addr @@ -130,11 +137,20 @@ mod_opt_type(max_connections) -> end; mod_opt_type(ram_db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; +mod_opt_type(iqdisc) -> + fun gen_iq_handler:check_type/1; mod_opt_type(Opt) -> - case mod_proxy65_stream:listen_opt_type(Opt) of - Opts when is_list(Opts) -> - [access, host, hosts, hostname, ip, name, port, - max_connections, ram_db_type] ++ Opts; - Fun -> - Fun - end. + mod_proxy65_stream:listen_opt_type(Opt). + +mod_options(Host) -> + [{ram_db_type, ejabberd_config:default_ram_db(Host, ?MODULE)}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {access, all}, + {host, <<"proxy.@HOST@">>}, + {hosts, []}, + {hostname, undefined}, + {ip, undefined}, + {port, 7777}, + {name, ?T("SOCKS5 Bytestreams")}, + {max_connections, infinity}] ++ + mod_proxy65_stream:listen_options(). diff --git a/src/mod_proxy65_service.erl b/src/mod_proxy65_service.erl index 718f97ee8..f81874694 100644 --- a/src/mod_proxy65_service.erl +++ b/src/mod_proxy65_service.erl @@ -61,8 +61,8 @@ reload(Host, NewOpts, OldOpts) -> init([Host, Opts]) -> process_flag(trap_exit, true), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), - MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"proxy.@HOST@">>), + IQDisc = gen_mod:get_opt(iqdisc, Opts), + MyHosts = gen_mod:get_opt_hosts(Host, Opts), lists:foreach( fun(MyHost) -> gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO, @@ -93,10 +93,10 @@ handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) -> - NewHosts = gen_mod:get_opt_hosts(ServerHost, NewOpts, <<"proxy.@HOST@">>), - OldHosts = gen_mod:get_opt_hosts(ServerHost, OldOpts, <<"proxy.@HOST@">>), - NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts, gen_iq_handler:iqdisc(ServerHost)), - OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts, gen_iq_handler:iqdisc(ServerHost)), + NewHosts = gen_mod:get_opt_hosts(ServerHost, NewOpts), + OldHosts = gen_mod:get_opt_hosts(ServerHost, OldOpts), + NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts), + OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts), if (NewIQDisc /= OldIQDisc) -> lists:foreach( fun(NewHost) -> @@ -144,8 +144,7 @@ process_disco_info(#iq{type = set, lang = Lang} = IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); process_disco_info(#iq{type = get, to = To, lang = Lang} = IQ) -> Host = ejabberd_router:host_of_route(To#jid.lserver), - Name = gen_mod:get_module_opt(Host, mod_proxy65, name, - ?T("SOCKS5 Bytestreams")), + Name = gen_mod:get_module_opt(Host, mod_proxy65, name), Info = ejabberd_hooks:run_fold(disco_info, Host, [], [Host, ?MODULE, <<"">>, <<"">>]), xmpp:make_iq_result( @@ -178,7 +177,7 @@ process_vcard(#iq{type = get, lang = Lang} = IQ) -> process_bytestreams(#iq{type = get, from = JID, to = To, lang = Lang} = IQ) -> Host = To#jid.lserver, ServerHost = ejabberd_router:host_of_route(Host), - ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, all), + ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access), case acl:match_rule(ServerHost, ACL, JID) of allow -> StreamHost = get_streamhost(Host, ServerHost), @@ -201,7 +200,7 @@ process_bytestreams(#iq{type = set, lang = Lang, from = InitiatorJID, to = To, sub_els = [#bytestreams{activate = TargetJID, sid = SID}]} = IQ) -> ServerHost = ejabberd_router:host_of_route(To#jid.lserver), - ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access, all), + ACL = gen_mod:get_module_opt(ServerHost, mod_proxy65, access), case acl:match_rule(ServerHost, ACL, InitiatorJID) of allow -> Node = ejabberd_cluster:get_node_by_id(To#jid.lresource), @@ -253,8 +252,10 @@ transform_module_options(Opts) -> -spec get_streamhost(binary(), binary()) -> streamhost(). get_streamhost(Host, ServerHost) -> {Port, IP} = get_port_ip(ServerHost), - HostName0 = gen_mod:get_module_opt(ServerHost, mod_proxy65, hostname, - misc:ip_to_list(IP)), + HostName0 = case gen_mod:get_module_opt(ServerHost, mod_proxy65, hostname) of + undefined -> misc:ip_to_list(IP); + Val -> Val + end, HostName = misc:expand_keyword(<<"@HOST@">>, HostName0, ServerHost), Resource = ejabberd_cluster:node_id(), #streamhost{jid = jid:make(<<"">>, Host, Resource), @@ -263,8 +264,11 @@ get_streamhost(Host, ServerHost) -> -spec get_port_ip(binary()) -> {pos_integer(), inet:ip_address()}. get_port_ip(Host) -> - Port = gen_mod:get_module_opt(Host, mod_proxy65, port, 7777), - IP = gen_mod:get_module_opt(Host, mod_proxy65, ip, get_my_ip()), + Port = gen_mod:get_module_opt(Host, mod_proxy65, port), + IP = case gen_mod:get_module_opt(Host, mod_proxy65, ip) of + undefined -> get_my_ip(); + Addr -> Addr + end, {Port, IP}. -spec get_my_ip() -> inet:ip_address(). @@ -276,7 +280,7 @@ get_my_ip() -> end. max_connections(ServerHost) -> - gen_mod:get_module_opt(ServerHost, mod_proxy65, max_connections, infinity). + gen_mod:get_module_opt(ServerHost, mod_proxy65, max_connections). register_handlers(Host, IQDisc) -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO, diff --git a/src/mod_proxy65_stream.erl b/src/mod_proxy65_stream.erl index 558b681a7..ad1844e0c 100644 --- a/src/mod_proxy65_stream.erl +++ b/src/mod_proxy65_stream.erl @@ -38,7 +38,8 @@ stream_established/2]). -export([start/2, stop/1, start_link/3, activate/2, - relay/3, socket_type/0, listen_opt_type/1]). + relay/3, socket_type/0, listen_opt_type/1, + listen_options/0]). -include("mod_proxy65.hrl"). @@ -79,10 +80,10 @@ start_link(Socket, Host, Opts) -> init([Socket, Host, Opts]) -> process_flag(trap_exit, true), - AuthType = gen_mod:get_opt(auth_type, Opts, anonymous), - Shaper = gen_mod:get_opt(shaper, Opts, none), - RecvBuf = gen_mod:get_opt(recbuf, Opts, 8192), - SendBuf = gen_mod:get_opt(sndbuf, Opts, 8192), + AuthType = gen_mod:get_opt(auth_type, Opts), + Shaper = gen_mod:get_opt(shaper, Opts), + RecvBuf = gen_mod:get_opt(recbuf, Opts), + SendBuf = gen_mod:get_opt(sndbuf, Opts), TRef = erlang:send_after(?WAIT_TIMEOUT, self(), stop), inet:setopts(Socket, [{active, true}, {recbuf, RecvBuf}, {sndbuf, SendBuf}]), @@ -293,6 +294,10 @@ listen_opt_type(recbuf) -> fun (I) when is_integer(I), I > 0 -> I end; listen_opt_type(shaper) -> fun acl:shaper_rules_validator/1; listen_opt_type(sndbuf) -> - fun (I) when is_integer(I), I > 0 -> I end; -listen_opt_type(_) -> - [auth_type, recbuf, sndbuf, shaper]. + fun (I) when is_integer(I), I > 0 -> I end. + +listen_options() -> + [{auth_type, anonymous}, + {recbuf, 8192}, + {sndbuf, 8192}, + {shaper, none}]. diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index 47ee8fa3e..40a326357 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -91,7 +91,7 @@ %% API and gen_server callbacks -export([start/2, stop/1, init/1, handle_call/3, handle_cast/2, handle_info/2, - terminate/2, code_change/3, depends/2, mod_opt_type/1]). + terminate/2, code_change/3, depends/2, mod_opt_type/1, mod_options/1]). %%==================================================================== %% API @@ -241,12 +241,12 @@ stop(Host) -> init([ServerHost, Opts]) -> process_flag(trap_exit, true), ?DEBUG("pubsub init ~p ~p", [ServerHost, Opts]), - Hosts = gen_mod:get_opt_hosts(ServerHost, Opts, <<"pubsub.@HOST@">>), - Access = gen_mod:get_opt(access_createnode, Opts, all), - PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, true), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(ServerHost)), - LastItemCache = gen_mod:get_opt(last_item_cache, Opts, false), - MaxItemsNode = gen_mod:get_opt(max_items_node, Opts, ?MAXITEMS), + Hosts = gen_mod:get_opt_hosts(ServerHost, Opts), + Access = gen_mod:get_opt(access_createnode, Opts), + PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts), + IQDisc = gen_mod:get_opt(iqdisc, Opts), + LastItemCache = gen_mod:get_opt(last_item_cache, Opts), + MaxItemsNode = gen_mod:get_opt(max_items_node, Opts), MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts), ejabberd_mnesia:create(?MODULE, pubsub_last_item, [{ram_copies, [node()]}, @@ -255,14 +255,14 @@ init([ServerHost, Opts]) -> lists:flatmap( fun(Host) -> ejabberd_router:register_route(Host, ServerHost), - case gen_mod:db_type(ServerHost, ?MODULE) of + case gen_mod:get_module_opt(ServerHost, ?MODULE, db_type) of mnesia -> pubsub_index:init(Host, ServerHost, Opts); _ -> ok end, {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts), DefaultModule = plugin(Host, hd(Plugins)), DefaultNodeCfg = merge_config( - gen_mod:get_opt(default_node_config, Opts, []), + gen_mod:get_opt(default_node_config, Opts), DefaultModule:options()), lists:foreach( fun(H) -> @@ -339,7 +339,7 @@ init([ServerHost, Opts]) -> NodeTree = config(ServerHost, nodetree), Plugins = config(ServerHost, plugins), PepMapping = config(ServerHost, pep_mapping), - DBType = gen_mod:db_type(ServerHost, ?MODULE), + DBType = gen_mod:get_module_opt(ServerHost, ?MODULE, db_type), {ok, #state{hosts = Hosts, server_host = ServerHost, access = Access, pep_mapping = PepMapping, ignore_pep_from_offline = PepOffline, @@ -347,9 +347,10 @@ init([ServerHost, Opts]) -> max_items_node = MaxItemsNode, nodetree = NodeTree, plugins = Plugins, db_type = DBType}}. -depends(ServerHost, Opts) -> - Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>), - Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]), +depends(ServerHost, Opts0) -> + Opts = Opts0 ++ mod_options(ServerHost), + [Host|_] = gen_mod:get_opt_hosts(ServerHost, Opts), + Plugins = gen_mod:get_opt(plugins, Opts), lists:flatmap( fun(Name) -> Plugin = plugin(ServerHost, Name), @@ -364,11 +365,11 @@ depends(ServerHost, Opts) -> %% node_plugin. The 'node_' prefix is mandatory.

%%

See {@link node_hometree:init/1} for an example implementation.

init_plugins(Host, ServerHost, Opts) -> - TreePlugin = tree(Host, gen_mod:get_opt(nodetree, Opts, ?STDTREE)), + TreePlugin = tree(Host, gen_mod:get_opt(nodetree, Opts)), ?DEBUG("** tree plugin is ~p", [TreePlugin]), TreePlugin:init(Host, ServerHost, Opts), - Plugins = gen_mod:get_opt(plugins, Opts, [?STDNODE]), - PepMapping = gen_mod:get_opt(pep_mapping, Opts, []), + Plugins = gen_mod:get_opt(plugins, Opts), + PepMapping = gen_mod:get_opt(pep_mapping, Opts), ?DEBUG("** PEP Mapping : ~p~n", [PepMapping]), PluginsOK = lists:foldl( fun (Name, Acc) -> @@ -980,8 +981,7 @@ iq_disco_info(ServerHost, Host, SNode, From, Lang) -> end, case Node of <<>> -> - Name = gen_mod:get_module_opt(ServerHost, ?MODULE, name, - ?T("Publish-Subscribe")), + Name = gen_mod:get_module_opt(ServerHost, ?MODULE, name), {result, #disco_info{ identities = [#identity{ @@ -3421,7 +3421,7 @@ subscription_plugin(Host) -> -spec submodule(host(), binary(), binary()) -> atom(). submodule(Host, Type, Name) -> - case gen_mod:db_type(serverhost(Host), ?MODULE) of + case gen_mod:get_module_opt(serverhost(Host), ?MODULE, db_type) of mnesia -> ejabberd:module_name([<<"pubsub">>, Type, Name]); Db -> ejabberd:module_name([<<"pubsub">>, Type, Name, misc:atom_to_binary(Db)]) end. @@ -3524,7 +3524,7 @@ tree_action(Host, Function, Args) -> ?DEBUG("tree_action ~p ~p ~p", [Host, Function, Args]), ServerHost = serverhost(Host), Fun = fun () -> tree_call(Host, Function, Args) end, - case gen_mod:db_type(ServerHost, ?MODULE) of + case gen_mod:get_module_opt(ServerHost, ?MODULE, db_type) of mnesia -> catch mnesia:sync_dirty(Fun); sql -> @@ -3592,7 +3592,7 @@ transaction(Host, Node, Action, Trans) -> transaction(Host, Fun, Trans) -> ServerHost = serverhost(Host), - DBType = gen_mod:db_type(ServerHost, ?MODULE), + DBType = gen_mod:get_module_opt(ServerHost, ?MODULE, db_type), Retry = case DBType of sql -> 2; _ -> 1 @@ -3867,7 +3867,9 @@ mod_opt_type(last_item_cache) -> mod_opt_type(max_items_node) -> fun (A) when is_integer(A) andalso A >= 0 -> A end; mod_opt_type(max_subscriptions_node) -> - fun (A) when is_integer(A) andalso A >= 0 -> A end; + fun(A) when is_integer(A) andalso A >= 0 -> A; + (undefined) -> undefined + end; mod_opt_type(default_node_config) -> fun (A) when is_list(A) -> A end; mod_opt_type(nodetree) -> @@ -3875,9 +3877,20 @@ mod_opt_type(nodetree) -> mod_opt_type(pep_mapping) -> fun (A) when is_list(A) -> A end; mod_opt_type(plugins) -> - fun (A) when is_list(A) -> A end; -mod_opt_type(_) -> - [access_createnode, db_type, host, hosts, name, - ignore_pep_from_offline, iqdisc, last_item_cache, - max_items_node, nodetree, pep_mapping, plugins, - max_subscriptions_node, default_node_config]. + fun (A) when is_list(A) -> A end. + +mod_options(Host) -> + [{access_createnode, all}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {host, <<"pubsub.@HOST@">>}, + {hosts, []}, + {name, ?T("Publish-Subscribe")}, + {ignore_pep_from_offline, true}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {last_item_cache, false}, + {max_items_node, ?MAXITEMS}, + {nodetree, ?STDTREE}, + {pep_mapping, []}, + {plugins, [?STDNODE]}, + {max_subscriptions_node, undefined}, + {default_node_config, []}]. diff --git a/src/mod_push.erl b/src/mod_push.erl index 11aa848de..df63ee6f1 100644 --- a/src/mod_push.erl +++ b/src/mod_push.erl @@ -30,7 +30,7 @@ -behavior(gen_mod). %% gen_mod callbacks. --export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, mod_opt_type/1, mod_options/1, depends/2]). %% ejabberd_hooks callbacks. -export([disco_sm_features/5, c2s_session_pending/1, c2s_copy_session/2, @@ -92,7 +92,7 @@ %%-------------------------------------------------------------------- -spec start(binary(), gen_mod:opts()) -> ok. start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), init_cache(Mod, Host, Opts), @@ -120,8 +120,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, - gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> register_iq_handlers(Host, IQDisc); true -> @@ -142,9 +141,15 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size -> mod_opt_type(O) when O == use_cache; O == cache_missed -> fun (B) when is_boolean(B) -> B end; mod_opt_type(iqdisc) -> - fun gen_iq_handler:check_type/1; -mod_opt_type(_) -> - [db_type, cache_life_time, cache_size, use_cache, cache_missed, iqdisc]. + fun gen_iq_handler:check_type/1. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. %%-------------------------------------------------------------------- %% ejabberd command callback. @@ -165,7 +170,7 @@ delete_old_sessions(Days) -> DBTypes = lists:usort( lists:map( fun(Host) -> - case gen_mod:db_type(Host, ?MODULE) of + case gen_mod:get_module_opt(Host, ?MODULE, db_type) of sql -> {sql, Host}; Other -> {Other, global} end @@ -579,23 +584,17 @@ drop_online_sessions(LUser, LServer, Clients) -> init_cache(Mod, Host, Opts) -> case use_cache(Mod, Host) of true -> - CacheOpts = cache_opts(Host, Opts), + CacheOpts = cache_opts(Opts), ets_cache:new(?PUSH_CACHE, CacheOpts); false -> ets_cache:delete(?PUSH_CACHE) end. --spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +-spec cache_opts(gen_mod:opts()) -> [proplists:property()]. +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -605,10 +604,7 @@ cache_opts(Host, Opts) -> use_cache(Mod, Host) -> case erlang:function_exported(Mod, use_cache, 1) of true -> Mod:use_cache(Host); - false -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache) end. -spec cache_nodes(module(), binary()) -> [node()]. diff --git a/src/mod_push_keepalive.erl b/src/mod_push_keepalive.erl index 50b526c3b..1e0942ebf 100644 --- a/src/mod_push_keepalive.erl +++ b/src/mod_push_keepalive.erl @@ -29,7 +29,7 @@ -behavior(gen_mod). %% gen_mod callbacks. --export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, mod_opt_type/1, mod_options/1, depends/2]). %% ejabberd_hooks callbacks. -export([c2s_session_pending/1, c2s_session_resumed/1, c2s_copy_session/2, @@ -47,7 +47,7 @@ %%-------------------------------------------------------------------- -spec start(binary(), gen_mod:opts()) -> ok. start(Host, Opts) -> - case gen_mod:get_opt(wake_on_start, Opts, false) of + case gen_mod:get_opt(wake_on_start, Opts) of true -> wake_all(Host); false -> @@ -61,7 +61,7 @@ stop(Host) -> -spec reload(binary(), gen_mod:opts(), gen_mod:opts()) -> ok. reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(wake_on_start, NewOpts, OldOpts, false) of + case gen_mod:is_equal_opt(wake_on_start, NewOpts, OldOpts) of {false, true, _} -> wake_all(Host); _ -> @@ -83,16 +83,12 @@ mod_opt_type(resume_timeout) -> mod_opt_type(wake_on_start) -> fun (B) when is_boolean(B) -> B end; mod_opt_type(wake_on_timeout) -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(O) when O == cache_life_time; O == cache_size -> - fun(I) when is_integer(I), I > 0 -> I; - (infinity) -> infinity - end; -mod_opt_type(O) when O == use_cache; O == cache_missed -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [resume_timeout, wake_on_start, wake_on_timeout, cache_life_time, - cache_size, use_cache, cache_missed, iqdisc]. + fun (B) when is_boolean(B) -> B end. + +mod_options(_Host) -> + [{resume_timeout, 86400}, + {wake_on_start, false}, + {wake_on_timeout, true}]. %%-------------------------------------------------------------------- %% Register/unregister hooks. @@ -168,10 +164,8 @@ c2s_copy_session(State, _) -> -spec c2s_handle_cast(c2s_state(), any()) -> c2s_state(). c2s_handle_cast(#{lserver := LServer} = State, push_enable) -> - ResumeTimeout = gen_mod:get_module_opt(LServer, ?MODULE, - resume_timeout, 86400), - WakeOnTimeout = gen_mod:get_module_opt(LServer, ?MODULE, - wake_on_timeout, true), + ResumeTimeout = gen_mod:get_module_opt(LServer, ?MODULE, resume_timeout), + WakeOnTimeout = gen_mod:get_module_opt(LServer, ?MODULE, wake_on_timeout), State#{push_resume_timeout => ResumeTimeout, push_wake_on_timeout => WakeOnTimeout}; c2s_handle_cast(State, push_disable) -> diff --git a/src/mod_register.erl b/src/mod_register.erl index 0204b32e2..b9dabe16d 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -37,14 +37,14 @@ c2s_unauthenticated_packet/2, try_register/5, process_iq/1, send_registration_notifications/3, transform_options/1, transform_module_options/1, - mod_opt_type/1, opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, opt_type/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER, ?MODULE, process_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, @@ -69,7 +69,7 @@ stop(Host) -> ?NS_REGISTER). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER, ?MODULE, process_iq, IQDisc), @@ -83,14 +83,8 @@ depends(_Host, _Opts) -> []. -spec stream_feature_register([xmpp_element()], binary()) -> [xmpp_element()]. -stream_feature_register(Acc, Host) -> - AF = gen_mod:get_module_opt(Host, ?MODULE, access_from, all), - case (AF /= none) of - true -> - [#feature_register{}|Acc]; - false -> - Acc - end. +stream_feature_register(Acc, _Host) -> + [#feature_register{}|Acc]. c2s_unauthenticated_packet(#{ip := IP, server := Server} = State, #iq{type = T, sub_els = [_]} = IQ) @@ -119,13 +113,12 @@ process_iq(#iq{from = From} = IQ) -> process_iq(#iq{from = From, to = To} = IQ, Source) -> IsCaptchaEnabled = - case gen_mod:get_module_opt(To#jid.lserver, ?MODULE, - captcha_protected, false) of + case gen_mod:get_module_opt(To#jid.lserver, ?MODULE, captcha_protected) of true -> true; false -> false end, Server = To#jid.lserver, - Access = gen_mod:get_module_opt(Server, ?MODULE, access_remove, all), + Access = gen_mod:get_module_opt(Server, ?MODULE, access_remove), AllowRemove = allow == acl:match_rule(Server, Access, From), process_iq(IQ, Source, IsCaptchaEnabled, AllowRemove). @@ -215,7 +208,7 @@ process_iq(#iq{type = get, from = From, to = To, id = ID, lang = Lang} = IQ, Instr = translate:translate( Lang, <<"Choose a username and password to register " "with this server">>), - URL = gen_mod:get_module_opt(Server, ?MODULE, redirect_url, <<"">>), + URL = gen_mod:get_module_opt(Server, ?MODULE, redirect_url), if (URL /= <<"">>) and not IsRegistered -> Txt = translate:translate(Lang, <<"To register, visit ~s">>), Desc = str:format(Txt, [URL]), @@ -322,7 +315,7 @@ try_register(User, Server, Password, SourceRaw, Lang) -> false -> {error, xmpp:err_bad_request(<<"Malformed username">>, Lang)}; _ -> JID = jid:make(User, Server), - Access = gen_mod:get_module_opt(Server, ?MODULE, access, all), + Access = gen_mod:get_module_opt(Server, ?MODULE, access), IPAccess = get_ip_access(Server), case {acl:match_rule(Server, Access, JID), check_ip_access(SourceRaw, IPAccess)} @@ -390,8 +383,7 @@ try_register(User, Server, Password, SourceRaw, Lang) -> send_welcome_message(JID) -> Host = JID#jid.lserver, - case gen_mod:get_module_opt(Host, ?MODULE, welcome_message, - {<<"">>, <<"">>}) of + case gen_mod:get_module_opt(Host, ?MODULE, welcome_message) of {<<"">>, <<"">>} -> ok; {Subj, Body} -> ejabberd_router:route( @@ -404,7 +396,7 @@ send_welcome_message(JID) -> send_registration_notifications(Mod, UJID, Source) -> Host = UJID#jid.lserver, - case gen_mod:get_module_opt(Host, Mod, registration_watchers, []) of + case gen_mod:get_module_opt(Host, Mod, registration_watchers) of [] -> ok; JIDs when is_list(JIDs) -> Body = @@ -428,7 +420,7 @@ check_from(#jid{user = <<"">>, server = <<"">>}, _Server) -> allow; check_from(JID, Server) -> - Access = gen_mod:get_module_opt(Server, ?MODULE, access_from, none), + Access = gen_mod:get_module_opt(Server, ?MODULE, access_from), acl:match_rule(Server, Access, JID). check_timeout(undefined) -> true; @@ -532,7 +524,7 @@ is_strong_password(Server, Password) -> is_strong_password2(Server, Password) -> LServer = jid:nameprep(Server), - case gen_mod:get_module_opt(LServer, ?MODULE, password_strength, 0) of + case gen_mod:get_module_opt(LServer, ?MODULE, password_strength) of 0 -> true; Entropy -> @@ -596,7 +588,7 @@ may_remove_resource({_, _, _} = From) -> may_remove_resource(From) -> From. get_ip_access(Host) -> - gen_mod:get_module_opt(Host, ?MODULE, ip_access, all). + gen_mod:get_module_opt(Host, ?MODULE, ip_access). check_ip_access({User, Server, Resource}, IPAccess) -> case ejabberd_sm:get_user_ip(User, Server, Resource) of @@ -633,11 +625,21 @@ mod_opt_type({welcome_message, subject}) -> mod_opt_type({welcome_message, body}) -> fun iolist_to_binary/1; mod_opt_type(redirect_url) -> - fun iolist_to_binary/1; -mod_opt_type(_) -> - [access, access_from, access_remove, captcha_protected, ip_access, - iqdisc, password_strength, registration_watchers, redirect_url, - {welcome_message, subject}, {welcome_message, body}]. + fun iolist_to_binary/1. + +mod_options(Host) -> + [{access, all}, + {access_from, none}, + {access_remove, all}, + {captcha_protected, false}, + {ip_access, all}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {password_strength, 0}, + {registration_watchers, []}, + {redirect_url, <<"">>}, + {welcome_message, + [{subject, <<"">>}, + {body, <<"">>}]}]. -spec opt_type(registration_timeout) -> fun((timeout()) -> timeout()); (atom()) -> [atom()]. diff --git a/src/mod_register_web.erl b/src/mod_register_web.erl index 646b6d7ac..c857887ee 100644 --- a/src/mod_register_web.erl +++ b/src/mod_register_web.erl @@ -55,7 +55,7 @@ -behaviour(gen_mod). --export([start/2, stop/1, reload/3, process/2, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, process/2, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -517,7 +517,7 @@ form_del_get(Host, Lang) -> %% {error, not_allowed} | %% {error, invalid_jid} register_account(Username, Host, Password) -> - Access = gen_mod:get_module_opt(Host, mod_register, access, all), + Access = gen_mod:get_module_opt(Host, mod_register, access), case jid:make(Username, Host) of error -> {error, invalid_jid}; JID -> @@ -602,4 +602,5 @@ get_error_text({error, passwords_not_identical}) -> get_error_text({error, wrong_parameters}) -> <<"Wrong parameters in the web formulary">>. -mod_opt_type(_) -> []. +mod_options(_) -> + []. diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 276603737..f9779c47f 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -49,7 +49,8 @@ get_jid_info/4, encode_item/1, webadmin_page/3, webadmin_user/4, get_versioning_feature/2, roster_versioning_enabled/1, roster_version/2, - mod_opt_type/1, set_roster/1, del_roster/3, depends/2]). + mod_opt_type/1, mod_options/1, set_roster/1, del_roster/3, + depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -87,7 +88,7 @@ -optional_callbacks([use_cache/2, cache_nodes/1]). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), Mod = gen_mod:db_mod(Host, Opts, ?MODULE), Mod:init(Host, Opts), init_cache(Mod, Host, Opts), @@ -142,7 +143,7 @@ reload(Host, NewOpts, OldOpts) -> true -> ok end, - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER, ?MODULE, process_iq, IQDisc); @@ -181,7 +182,7 @@ process_local_iq(#iq{type = set, from = From, lang = Lang, xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)); false -> #jid{server = Server} = From, - Access = gen_mod:get_module_opt(Server, ?MODULE, access, all), + Access = gen_mod:get_module_opt(Server, ?MODULE, access), case acl:match_rule(Server, Access, From) of deny -> Txt = <<"Access denied by service policy">>, @@ -214,10 +215,10 @@ roster_hash(Items) -> <- Items]))). roster_versioning_enabled(Host) -> - gen_mod:get_module_opt(Host, ?MODULE, versioning, false). + gen_mod:get_module_opt(Host, ?MODULE, versioning). roster_version_on_db(Host) -> - gen_mod:get_module_opt(Host, ?MODULE, store_current_id, false). + gen_mod:get_module_opt(Host, ?MODULE, store_current_id). %% Returns a list that may contain an xmlelement with the XEP-237 feature if it's enabled. -spec get_versioning_feature([xmpp_element()], binary()) -> [xmpp_element()]. @@ -1088,7 +1089,7 @@ has_duplicated_groups(Groups) -> -spec init_cache(module(), binary(), gen_mod:opts()) -> ok. init_cache(Mod, Host, Opts) -> - CacheOpts = cache_opts(Host, Opts), + CacheOpts = cache_opts(Opts), case use_cache(Mod, Host, roster_version) of true -> ets_cache:new(?ROSTER_VERSION_CACHE, CacheOpts); @@ -1104,17 +1105,11 @@ init_cache(Mod, Host, Opts) -> ets_cache:delete(?ROSTER_ITEM_CACHE) end. --spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +-spec cache_opts(gen_mod:opts()) -> [proplists:property()]. +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -1124,10 +1119,7 @@ cache_opts(Host, Opts) -> use_cache(Mod, Host, Table) -> case erlang:function_exported(Mod, use_cache, 2) of true -> Mod:use_cache(Host, Table); - false -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache) end. -spec cache_nodes(module(), binary()) -> [node()]. @@ -1213,7 +1205,15 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size -> (infinity) -> infinity end; mod_opt_type(O) when O == use_cache; O == cache_missed -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [access, db_type, iqdisc, store_current_id, - versioning, cache_life_time, cache_size, use_cache, cache_missed]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{access, all}, + {store_current_id, false}, + {versioning, false}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl index e7d75e025..67d302f8a 100644 --- a/src/mod_roster_mnesia.erl +++ b/src/mod_roster_mnesia.erl @@ -53,9 +53,7 @@ init(_Host, _Opts) -> use_cache(Host, Table) -> case mnesia:table_info(Table, storage_type) of disc_only_copies -> - gen_mod:get_module_opt( - Host, mod_roster, use_cache, - ejabberd_config:use_cache(Host)); + gen_mod:get_module_opt(Host, mod_roster, use_cache); _ -> false end. diff --git a/src/mod_s2s_dialback.erl b/src/mod_s2s_dialback.erl index 1eedd71c3..6f088b349 100644 --- a/src/mod_s2s_dialback.erl +++ b/src/mod_s2s_dialback.erl @@ -26,7 +26,7 @@ -protocol({xep, 185, '1.0'}). %% gen_mod API --export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1]). +-export([start/2, stop/1, reload/3, depends/2, mod_options/1]). %% Hooks -export([s2s_out_auth_result/2, s2s_out_downgraded/2, s2s_in_packet/2, s2s_out_packet/2, s2s_in_recv/3, @@ -97,7 +97,7 @@ reload(Host, NewOpts, _OldOpts) -> depends(_Host, _Opts) -> []. -mod_opt_type(_) -> +mod_options(_Host) -> []. s2s_in_features(Acc, _) -> diff --git a/src/mod_service_log.erl b/src/mod_service_log.erl index b6f6f7f1d..783c29188 100644 --- a/src/mod_service_log.erl +++ b/src/mod_service_log.erl @@ -29,7 +29,7 @@ -behaviour(gen_mod). --export([start/2, stop/1, log_user_send/1, +-export([start/2, stop/1, log_user_send/1, mod_options/1, log_user_receive/1, mod_opt_type/1, depends/2]). -include("ejabberd.hrl"). @@ -68,7 +68,7 @@ log_user_receive({Packet, C2SState}) -> -spec log_packet(stanza(), binary()) -> ok. log_packet(Packet, Host) -> - Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, []), + Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers), ForwardedMsg = #message{from = jid:make(Host), id = randoms:get_string(), sub_els = [#forwarded{ @@ -86,5 +86,7 @@ mod_opt_type(loggers) -> if N /= error -> N end end, L) - end; -mod_opt_type(_) -> [loggers]. + end. + +mod_options(_) -> + [{loggers, []}]. diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 4a0cb07cd..fffd68d60 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -39,7 +39,7 @@ delete_group/2, get_group_opts/2, set_group_opts/3, get_group_users/2, get_group_explicit_users/2, is_user_in_group/3, add_user_to_group/3, opts_to_binary/1, - remove_user_from_group/3, mod_opt_type/1, depends/2]). + remove_user_from_group/3, mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -1071,5 +1071,7 @@ import(LServer, {sql, _}, DBType, Tab, L) -> Mod = gen_mod:db_mod(DBType, ?MODULE), Mod:import(LServer, Tab, L). -mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; -mod_opt_type(_) -> [db_type]. +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end. + +mod_options(Host) -> + [{db_type, ejabberd_config:default_db(Host, ?MODULE)}]. diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl index 909a3fbc5..82db781e6 100644 --- a/src/mod_shared_roster_ldap.erl +++ b/src/mod_shared_roster_ldap.erl @@ -41,8 +41,8 @@ -export([get_user_roster/2, get_jid_info/4, process_item/2, in_subscription/6, - out_subscription/4, mod_opt_type/1, opt_type/1, depends/2, - transform_module_options/1]). + out_subscription/4, mod_opt_type/1, mod_options/1, + opt_type/1, depends/2, transform_module_options/1]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -446,18 +446,21 @@ get_user_part_re(String, Pattern) -> parse_options(Host, Opts) -> Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?MODULE)), Cfg = eldap_utils:get_config(Host, Opts), - GroupAttr = gen_mod:get_opt(ldap_groupattr, Opts, <<"cn">>), - GroupDesc = gen_mod:get_opt(ldap_groupdesc, Opts, GroupAttr), - UserDesc = gen_mod:get_opt(ldap_userdesc, Opts, <<"cn">>), - UserUID = gen_mod:get_opt(ldap_useruid, Opts, <<"cn">>), - UIDAttr = gen_mod:get_opt(ldap_memberattr, Opts, <<"memberUid">>), - UIDAttrFormat = gen_mod:get_opt(ldap_memberattr_format, Opts, <<"%u">>), - UIDAttrFormatRe = gen_mod:get_opt(ldap_memberattr_format_re, Opts, <<"">>), - AuthCheck = gen_mod:get_opt(ldap_auth_check, Opts, true), - ConfigFilter = gen_mod:get_opt({ldap_filter, Host}, Opts, <<"">>), - ConfigUserFilter = gen_mod:get_opt({ldap_ufilter, Host}, Opts, <<"">>), - ConfigGroupFilter = gen_mod:get_opt({ldap_gfilter, Host}, Opts, <<"">>), - RosterFilter = gen_mod:get_opt({ldap_rfilter, Host}, Opts, <<"">>), + GroupAttr = gen_mod:get_opt(ldap_groupattr, Opts), + GroupDesc = case gen_mod:get_opt(ldap_groupdesc, Opts) of + undefined -> GroupAttr; + GD -> GD + end, + UserDesc = gen_mod:get_opt(ldap_userdesc, Opts), + UserUID = gen_mod:get_opt(ldap_useruid, Opts), + UIDAttr = gen_mod:get_opt(ldap_memberattr, Opts), + UIDAttrFormat = gen_mod:get_opt(ldap_memberattr_format, Opts), + UIDAttrFormatRe = gen_mod:get_opt(ldap_memberattr_format_re, Opts), + AuthCheck = gen_mod:get_opt(ldap_auth_check, Opts), + ConfigFilter = gen_mod:get_opt(ldap_filter, Opts), + ConfigUserFilter = gen_mod:get_opt(ldap_ufilter, Opts), + ConfigGroupFilter = gen_mod:get_opt(ldap_gfilter, Opts), + RosterFilter = gen_mod:get_opt(ldap_rfilter, Opts), SubFilter = <<"(&(", UIDAttr/binary, "=", UIDAttrFormat/binary, ")(", GroupAttr/binary, "=%g))">>, UserSubFilter = case ConfigUserFilter of @@ -517,16 +520,13 @@ init_cache(Host, Opts) -> end, UseCache. -use_cache(Host, Opts) -> - gen_mod:get_opt(use_cache, Opts, ejabberd_config:use_cache(Host)). +use_cache(_Host, Opts) -> + gen_mod:get_opt(use_cache, Opts). -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt(cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt(cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt(cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +cache_opts(_Host, Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -554,51 +554,14 @@ transform_module_options(Opts) -> Opt end, Opts). -mod_opt_type(deref_aliases) -> - fun (never) -> never; - (searching) -> searching; - (finding) -> finding; - (always) -> always - end; -mod_opt_type(ldap_backups) -> - fun (L) -> [iolist_to_binary(H) || H <- L] end; -mod_opt_type(ldap_base) -> fun iolist_to_binary/1; -mod_opt_type(ldap_deref_aliases) -> - fun (never) -> never; - (searching) -> searching; - (finding) -> finding; - (always) -> always - end; -mod_opt_type(ldap_encrypt) -> - fun (tls) -> tls; - (starttls) -> starttls; - (none) -> none - end; -mod_opt_type(ldap_password) -> fun iolist_to_binary/1; -mod_opt_type(ldap_port) -> - fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(ldap_rootdn) -> fun iolist_to_binary/1; -mod_opt_type(ldap_servers) -> - fun (L) -> [iolist_to_binary(H) || H <- L] end; -mod_opt_type(ldap_tls_cacertfile) -> - fun misc:try_read_file/1; -mod_opt_type(ldap_tls_certfile) -> - fun ejabberd_pkix:try_certfile/1; -mod_opt_type(ldap_tls_depth) -> - fun (I) when is_integer(I), I >= 0 -> I end; -mod_opt_type(ldap_tls_verify) -> - fun (hard) -> hard; - (soft) -> soft; - (false) -> false - end; mod_opt_type(ldap_auth_check) -> fun (on) -> true; (off) -> false; (false) -> false; (true) -> true end; -mod_opt_type(ldap_filter) -> fun eldap_utils:check_filter/1; -mod_opt_type(ldap_gfilter) -> fun eldap_utils:check_filter/1; +mod_opt_type(ldap_gfilter) -> + opt_type(ldap_gfilter); mod_opt_type(O) when O == cache_size; O == cache_life_time -> fun (I) when is_integer(I), I > 0 -> I; @@ -607,7 +570,10 @@ mod_opt_type(O) when O == cache_size; mod_opt_type(O) when O == use_cache; O == cache_missed -> fun (B) when is_boolean(B) -> B end; mod_opt_type(ldap_groupattr) -> fun iolist_to_binary/1; -mod_opt_type(ldap_groupdesc) -> fun iolist_to_binary/1; +mod_opt_type(ldap_groupdesc) -> + fun(undefined) -> undefined; + (G) -> iolist_to_binary(G) + end; mod_opt_type(ldap_memberattr) -> fun iolist_to_binary/1; mod_opt_type(ldap_memberattr_format) -> fun iolist_to_binary/1; @@ -615,23 +581,39 @@ mod_opt_type(ldap_memberattr_format_re) -> fun (S) -> Re = iolist_to_binary(S), {ok, MP} = re:compile(Re), MP end; -mod_opt_type(ldap_rfilter) -> fun eldap_utils:check_filter/1; -mod_opt_type(ldap_ufilter) -> fun eldap_utils:check_filter/1; +mod_opt_type(ldap_rfilter) -> + opt_type(ldap_rfilter); +mod_opt_type(ldap_ufilter) -> + opt_type(ldap_ufilter); mod_opt_type(ldap_userdesc) -> fun iolist_to_binary/1; mod_opt_type(ldap_useruid) -> fun iolist_to_binary/1; -mod_opt_type(_) -> - [ldap_auth_check, ldap_filter, ldap_gfilter, - ldap_groupattr, ldap_groupdesc, ldap_memberattr, - ldap_memberattr_format, ldap_memberattr_format_re, - ldap_rfilter, ldap_ufilter, ldap_userdesc, ldap_useruid, - deref_aliases, ldap_backups, ldap_base, - ldap_deref_aliases, ldap_encrypt, ldap_password, - ldap_port, ldap_rootdn, ldap_servers, - ldap_tls_cacertfile, ldap_tls_certfile, ldap_tls_depth, - ldap_tls_verify, use_cache, cache_missed, cache_size, cache_life_time]. +mod_opt_type(Opt) -> + eldap_utils:opt_type(Opt). -opt_type(ldap_gfilter) -> fun eldap_utils:check_filter/1; -opt_type(ldap_rfilter) -> fun eldap_utils:check_filter/1; -opt_type(ldap_ufilter) -> fun eldap_utils:check_filter/1; +mod_options(Host) -> + [{ldap_auth_check, true}, + {ldap_gfilter, ejabberd_config:get_option({ldap_gfilter, Host}, <<"">>)}, + {ldap_groupattr, <<"cn">>}, + {ldap_groupdesc, undefined}, + {ldap_memberattr, <<"memberUid">>}, + {ldap_memberattr_format, <<"%u">>}, + {ldap_memberattr_format_re, <<"">>}, + {ldap_rfilter, ejabberd_config:get_option({ldap_rfilter, Host}, <<"">>)}, + {ldap_ufilter, ejabberd_config:get_option({ldap_ufilter, Host}, <<"">>)}, + {ldap_userdesc, <<"cn">>}, + {ldap_useruid, <<"cn">>}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)} + | lists:map( + fun({Opt, Default}) -> + {Opt, ejabberd_config:get_option({Opt, Host}, Default)} + end, eldap_utils:options(Host))]. + +opt_type(O) when O == ldap_rfilter; O == ldap_gfilter; O == ldap_ufilter -> + fun(<<>>) -> <<>>; + (F) -> eldap_utils:check_filter(F) + end; opt_type(_) -> [ldap_gfilter, ldap_rfilter, ldap_ufilter]. diff --git a/src/mod_sic.erl b/src/mod_sic.erl index 8e1dcca7e..6a417b9b0 100644 --- a/src/mod_sic.erl +++ b/src/mod_sic.erl @@ -32,14 +32,14 @@ -behaviour(gen_mod). -export([start/2, stop/1, reload/3, process_local_iq/1, - process_sm_iq/1, mod_opt_type/1, depends/2]). + process_sm_iq/1, mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_0, @@ -56,7 +56,7 @@ stop(Host) -> gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_SIC_1). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_0, ?MODULE, process_local_iq, IQDisc), @@ -107,5 +107,7 @@ get_ip({User, Server, Resource}, xmpp:make_error(IQ, xmpp:err_item_not_found(Txt, Lang)) end. -mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; -mod_opt_type(_) -> [iqdisc]. +mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}]. diff --git a/src/mod_sip.erl b/src/mod_sip.erl index bd11d1a85..c40e4eb7c 100644 --- a/src/mod_sip.erl +++ b/src/mod_sip.erl @@ -29,7 +29,7 @@ -include("logger.hrl"). -ifndef(SIP). --export([start/2, stop/1, depends/2, mod_opt_type/1]). +-export([start/2, stop/1, depends/2, mod_options/1]). start(_, _) -> ?CRITICAL_MSG("ejabberd is not compiled with SIP support", []), {error, sip_not_compiled}. @@ -37,7 +37,7 @@ stop(_) -> ok. depends(_, _) -> []. -mod_opt_type(_) -> +mod_options(_) -> []. -else. -behaviour(gen_mod). @@ -49,7 +49,7 @@ mod_opt_type(_) -> -export([data_in/2, data_out/2, message_in/2, message_out/2, request/2, request/3, response/2, - locate/1, mod_opt_type/1, depends/2]). + locate/1, mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include_lib("esip/include/esip.hrl"). @@ -360,9 +360,15 @@ mod_opt_type(via) -> {Type, {Host, Port}} end, L) - end; -mod_opt_type(_) -> - [always_record_route, flow_timeout_tcp, - flow_timeout_udp, record_route, routes, via]. + end. + +mod_options(Host) -> + Route = <<"sip:", Host/binary, ";lr">>, + [{always_record_route, true}, + {flow_timeout_tcp, 120}, + {flow_timeout_udp, 29}, + {record_route, Route}, + {routes, [Route]}, + {via, []}]. -endif. diff --git a/src/mod_sip_proxy.erl b/src/mod_sip_proxy.erl index ae020f8ce..0e7f367df 100644 --- a/src/mod_sip_proxy.erl +++ b/src/mod_sip_proxy.erl @@ -321,7 +321,7 @@ is_request_within_dialog(#sip{hdrs = Hdrs}) -> esip:has_param(<<"tag">>, Params). need_record_route(LServer) -> - gen_mod:get_module_opt(LServer, mod_sip, always_record_route, true). + gen_mod:get_module_opt(LServer, mod_sip, always_record_route). make_sign(TS, Hdrs) -> {_, #uri{user = FUser, host = FServer}, FParams} = esip:get_hdr('from', Hdrs), @@ -348,17 +348,13 @@ is_signed_by_me(TS_Sign, Hdrs) -> end. get_configured_vias(LServer) -> - gen_mod:get_module_opt(LServer, mod_sip, via, []). + gen_mod:get_module_opt(LServer, mod_sip, via). get_configured_record_route(LServer) -> - gen_mod:get_module_opt( - LServer, mod_sip, record_route, - #uri{host = LServer, params = [{<<"lr">>, <<"">>}]}). + gen_mod:get_module_opt(LServer, mod_sip, record_route). get_configured_routes(LServer) -> - gen_mod:get_module_opt( - LServer, mod_sip, routes, - [#uri{host = LServer, params = [{<<"lr">>, <<"">>}]}]). + gen_mod:get_module_opt(LServer, mod_sip, routes). mark_transaction_as_complete(TrID, State) -> NewTrIDs = lists:delete(TrID, State#state.tr_ids), diff --git a/src/mod_sip_registrar.erl b/src/mod_sip_registrar.erl index 34e024ba5..346b3be19 100644 --- a/src/mod_sip_registrar.erl +++ b/src/mod_sip_registrar.erl @@ -46,8 +46,6 @@ -define(CALL_TIMEOUT, timer:seconds(30)). -define(DEFAULT_EXPIRES, 3600). --define(FLOW_TIMEOUT_UDP, 29). --define(FLOW_TIMEOUT_TCP, 120). -record(sip_session, {us = {<<"">>, <<"">>} :: {binary(), binary()}, socket = #sip_socket{} :: #sip_socket{}, @@ -497,12 +495,10 @@ get_flow_timeout(LServer, #sip_socket{type = Type}) -> case Type of udp -> gen_mod:get_module_opt( - LServer, mod_sip, flow_timeout_udp, - ?FLOW_TIMEOUT_UDP); + LServer, mod_sip, flow_timeout_udp); _ -> gen_mod:get_module_opt( - LServer, mod_sip, flow_timeout_tcp, - ?FLOW_TIMEOUT_TCP) + LServer, mod_sip, flow_timeout_tcp) end. update_table() -> diff --git a/src/mod_stats.erl b/src/mod_stats.erl index f9ea9373f..af7ad7195 100644 --- a/src/mod_stats.erl +++ b/src/mod_stats.erl @@ -31,14 +31,15 @@ -behaviour(gen_mod). --export([start/2, stop/1, reload/3, process_iq/1, mod_opt_type/1, depends/2]). +-export([start/2, stop/1, reload/3, process_iq/1, mod_opt_type/1, + mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS, ?MODULE, process_iq, IQDisc). @@ -233,5 +234,7 @@ search_running_node(SNode, [Node | Nodes]) -> _ -> search_running_node(SNode, Nodes) end. -mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; -mod_opt_type(_) -> [iqdisc]. +mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}]. diff --git a/src/mod_stream_mgmt.erl b/src/mod_stream_mgmt.erl index e295a8612..baf72b329 100644 --- a/src/mod_stream_mgmt.erl +++ b/src/mod_stream_mgmt.erl @@ -26,7 +26,7 @@ -protocol({xep, 198, '1.5.2'}). %% gen_mod API --export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1]). +-export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1, mod_options/1]). %% hooks -export([c2s_stream_init/2, c2s_stream_started/2, c2s_stream_features/2, c2s_authenticated_packet/2, c2s_unauthenticated_packet/2, @@ -117,18 +117,17 @@ c2s_stream_init({ok, State}, Opts) -> c2s_stream_init(Acc, _Opts) -> Acc. -c2s_stream_started(#{lserver := LServer, mgmt_options := Opts} = State, - _StreamStart) -> +c2s_stream_started(#{lserver := LServer} = State, _StreamStart) -> State1 = maps:remove(mgmt_options, State), - ResumeTimeout = get_resume_timeout(LServer, Opts), - MaxResumeTimeout = get_max_resume_timeout(LServer, Opts, ResumeTimeout), + ResumeTimeout = get_configured_resume_timeout(LServer), + MaxResumeTimeout = get_max_resume_timeout(LServer, ResumeTimeout), State1#{mgmt_state => inactive, - mgmt_queue_type => get_queue_type(LServer, Opts), - mgmt_max_queue => get_max_ack_queue(LServer, Opts), + mgmt_queue_type => get_queue_type(LServer), + mgmt_max_queue => get_max_ack_queue(LServer), mgmt_timeout => ResumeTimeout, mgmt_max_timeout => MaxResumeTimeout, - mgmt_ack_timeout => get_ack_timeout(LServer, Opts), - mgmt_resend => get_resend_on_timeout(LServer, Opts), + mgmt_ack_timeout => get_ack_timeout(LServer), + mgmt_resend => get_resend_on_timeout(LServer), mgmt_stanzas_in => 0, mgmt_stanzas_out => 0, mgmt_stanzas_req => 0}; @@ -711,39 +710,30 @@ bounce_message_queue() -> %%%=================================================================== %%% Configuration processing %%%=================================================================== -get_max_ack_queue(Host, Opts) -> - gen_mod:get_module_opt(Host, ?MODULE, max_ack_queue, - gen_mod:get_opt(max_ack_queue, Opts, 5000)). +get_max_ack_queue(Host) -> + gen_mod:get_module_opt(Host, ?MODULE, max_ack_queue). -get_resume_timeout(Host, Opts) -> - gen_mod:get_module_opt(Host, ?MODULE, resume_timeout, - gen_mod:get_opt(resume_timeout, Opts, 300)). +get_configured_resume_timeout(Host) -> + gen_mod:get_module_opt(Host, ?MODULE, resume_timeout). -get_max_resume_timeout(Host, Opts, ResumeTimeout) -> - case gen_mod:get_module_opt(Host, ?MODULE, max_resume_timeout, - gen_mod:get_opt(max_resume_timeout, Opts)) of +get_max_resume_timeout(Host, ResumeTimeout) -> + case gen_mod:get_module_opt(Host, ?MODULE, max_resume_timeout) of undefined -> ResumeTimeout; Max when Max >= ResumeTimeout -> Max; _ -> ResumeTimeout end. -get_ack_timeout(Host, Opts) -> - case gen_mod:get_module_opt(Host, ?MODULE, ack_timeout, - gen_mod:get_opt(ack_timeout, Opts, 60)) of +get_ack_timeout(Host) -> + case gen_mod:get_module_opt(Host, ?MODULE, ack_timeout) of infinity -> infinity; T -> timer:seconds(T) end. -get_resend_on_timeout(Host, Opts) -> - gen_mod:get_module_opt(Host, ?MODULE, resend_on_timeout, - gen_mod:get_opt(resend_on_timeout, Opts, false)). +get_resend_on_timeout(Host) -> + gen_mod:get_module_opt(Host, ?MODULE, resend_on_timeout). -get_queue_type(Host, Opts) -> - case gen_mod:get_module_opt(Host, ?MODULE, queue_type, - gen_mod:get_opt(queue_type, Opts)) of - undefined -> ejabberd_config:default_queue_type(Host); - Type -> Type - end. +get_queue_type(Host) -> + gen_mod:get_module_opt(Host, ?MODULE, queue_type). mod_opt_type(max_ack_queue) -> fun(I) when is_integer(I), I > 0 -> I; @@ -752,7 +742,9 @@ mod_opt_type(max_ack_queue) -> mod_opt_type(resume_timeout) -> fun(I) when is_integer(I), I >= 0 -> I end; mod_opt_type(max_resume_timeout) -> - fun(I) when is_integer(I), I >= 0 -> I end; + fun(I) when is_integer(I), I >= 0 -> I; + (undefined) -> undefined + end; mod_opt_type(ack_timeout) -> fun(I) when is_integer(I), I > 0 -> I; (infinity) -> infinity @@ -762,7 +754,12 @@ mod_opt_type(resend_on_timeout) -> (if_offline) -> if_offline end; mod_opt_type(queue_type) -> - fun(ram) -> ram; (file) -> file end; -mod_opt_type(_) -> - [max_ack_queue, resume_timeout, max_resume_timeout, ack_timeout, - resend_on_timeout, queue_type]. + fun(ram) -> ram; (file) -> file end. + +mod_options(Host) -> + [{max_ack_queue, 5000}, + {resume_timeout, 300}, + {max_resume_timeout, undefined}, + {ack_timeout, 60}, + {resend_on_timeout, false}, + {queue_type, ejabberd_config:default_queue_type(Host)}]. diff --git a/src/mod_time.erl b/src/mod_time.erl index 4b3b67c94..d4dffbf10 100644 --- a/src/mod_time.erl +++ b/src/mod_time.erl @@ -33,7 +33,7 @@ -behaviour(gen_mod). -export([start/2, stop/1, reload/3, process_local_iq/1, - mod_opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -41,7 +41,7 @@ -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME, ?MODULE, process_local_iq, IQDisc). @@ -50,7 +50,7 @@ stop(Host) -> ?NS_TIME). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME, ?MODULE, process_local_iq, IQDisc); @@ -74,5 +74,7 @@ process_local_iq(#iq{type = get} = IQ) -> depends(_Host, _Opts) -> []. -mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; -mod_opt_type(_) -> [iqdisc]. +mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}]. diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 352c80324..fbbf59b84 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -33,7 +33,7 @@ -behaviour(gen_server). -behaviour(gen_mod). --export([start/2, stop/1, get_sm_features/5, +-export([start/2, stop/1, get_sm_features/5, mod_options/1, process_local_iq/1, process_sm_iq/1, string2lower/1, remove_user/2, export/1, import_info/0, import/5, import_start/2, depends/2, process_search/1, process_vcard/1, get_vcard/2, @@ -48,7 +48,6 @@ -include("mod_vcard.hrl"). -include("translate.hrl"). --define(JUD_MATCHES, 30). -define(VCARD_CACHE, vcard_cache). -callback init(binary(), gen_mod:opts()) -> any(). @@ -89,7 +88,7 @@ init([Host, Opts]) -> init_cache(Mod, Host, Opts), ejabberd_hooks:add(remove_user, Host, ?MODULE, remove_user, 50), - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD, ?MODULE, process_local_iq, IQDisc), gen_iq_handler:add_iq_handler(ejabberd_sm, Host, @@ -97,8 +96,8 @@ init([Host, Opts]) -> ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50), ejabberd_hooks:add(vcard_iq_set, Host, ?MODULE, vcard_iq_set, 50), - MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"vjud.@HOST@">>), - Search = gen_mod:get_opt(search, Opts, false), + MyHosts = gen_mod:get_opt_hosts(Host, Opts), + Search = gen_mod:get_opt(search, Opts), if Search -> lists:foreach( fun(MyHost) -> @@ -122,7 +121,7 @@ init([Host, Opts]) -> false -> ?WARNING_MSG("vcard search functionality is " "not implemented for ~s backend", - [gen_mod:db_type(Host, Opts, ?MODULE)]); + [gen_mod:get_opt(db_type, Opts)]); true -> ejabberd_router:register_route(MyHost, Host) end @@ -289,7 +288,7 @@ disco_features(Acc, _From, _To, _Node, _Lang) -> binary(), binary()) -> [identity()]. disco_identity(Acc, _From, To, <<"">>, Lang) -> Host = ejabberd_router:host_of_route(To#jid.lserver), - Name = gen_mod:get_module_opt(Host, ?MODULE, name, ?T("vCard User Search")), + Name = gen_mod:get_module_opt(Host, ?MODULE, name), [#identity{category = <<"directory">>, type = <<"user">>, name = translate:translate(Lang, Name)}|Acc]; @@ -467,9 +466,8 @@ item_to_field(Items) -> search(LServer, XFields) -> Data = [{Var, Vals} || #xdata_field{var = Var, values = Vals} <- XFields], Mod = gen_mod:db_mod(LServer, ?MODULE), - AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all, - false), - MaxMatch = gen_mod:get_module_opt(LServer, ?MODULE, matches, ?JUD_MATCHES), + AllowReturnAll = gen_mod:get_module_opt(LServer, ?MODULE, allow_return_all), + MaxMatch = gen_mod:get_module_opt(LServer, ?MODULE, matches), Mod:search(LServer, Data, AllowReturnAll, MaxMatch). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -492,16 +490,10 @@ init_cache(Mod, Host, Opts) -> end. -spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +cache_opts(_Host, Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -511,10 +503,7 @@ cache_opts(Host, Opts) -> use_cache(Mod, Host) -> case erlang:function_exported(Mod, use_cache, 1) of true -> Mod:use_cache(Host); - false -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)) + false -> gen_mod:get_module_opt(Host, ?MODULE, use_cache) end. -spec cache_nodes(module(), binary()) -> [node()]. @@ -556,15 +545,23 @@ mod_opt_type(matches) -> end; mod_opt_type(search) -> fun (B) when is_boolean(B) -> B end; -mod_opt_type(search_all_hosts) -> - fun (B) when is_boolean(B) -> B end; mod_opt_type(O) when O == cache_life_time; O == cache_size -> fun (I) when is_integer(I), I > 0 -> I; (infinity) -> infinity end; mod_opt_type(O) when O == use_cache; O == cache_missed -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [allow_return_all, db_type, host, hosts, iqdisc, matches, - search, search_all_hosts, cache_life_time, cache_size, - use_cache, cache_missed, name]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{allow_return_all, false}, + {host, <<"vjud.@HOST@">>}, + {hosts, []}, + {matches, 30}, + {search, false}, + {name, ?T("vCard User Search")}, + {iqdisc, gen_iq_handler:iqdisc(Host)}, + {db_type, ejabberd_config:default_db(Host, ?MODULE)}, + {use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index edb99972b..ce4fcd702 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -31,7 +31,7 @@ -export([start_link/2]). -export([init/2, stop/1, get_vcard/2, set_vcard/4, search/4, remove_user/2, import/3, search_fields/1, search_reported/1, - mod_opt_type/1]). + mod_opt_type/1, mod_options/1]). -export([is_search_supported/1]). %% gen_server callbacks @@ -303,26 +303,26 @@ process_pattern(Str, {User, Domain}, AttrValues) -> [{<<"%s">>, V, 1} || V <- AttrValues]). default_vcard_map() -> - [{<<"NICKNAME">>, <<"%u">>, []}, - {<<"FN">>, <<"%s">>, [<<"displayName">>]}, - {<<"FAMILY">>, <<"%s">>, [<<"sn">>]}, - {<<"GIVEN">>, <<"%s">>, [<<"givenName">>]}, - {<<"MIDDLE">>, <<"%s">>, [<<"initials">>]}, - {<<"ORGNAME">>, <<"%s">>, [<<"o">>]}, - {<<"ORGUNIT">>, <<"%s">>, [<<"ou">>]}, - {<<"CTRY">>, <<"%s">>, [<<"c">>]}, - {<<"LOCALITY">>, <<"%s">>, [<<"l">>]}, - {<<"STREET">>, <<"%s">>, [<<"street">>]}, - {<<"REGION">>, <<"%s">>, [<<"st">>]}, - {<<"PCODE">>, <<"%s">>, [<<"postalCode">>]}, - {<<"TITLE">>, <<"%s">>, [<<"title">>]}, - {<<"URL">>, <<"%s">>, [<<"labeleduri">>]}, - {<<"DESC">>, <<"%s">>, [<<"description">>]}, - {<<"TEL">>, <<"%s">>, [<<"telephoneNumber">>]}, - {<<"EMAIL">>, <<"%s">>, [<<"mail">>]}, - {<<"BDAY">>, <<"%s">>, [<<"birthDay">>]}, - {<<"ROLE">>, <<"%s">>, [<<"employeeType">>]}, - {<<"PHOTO">>, <<"%s">>, [<<"jpegPhoto">>]}]. + [{<<"NICKNAME">>, [{<<"%u">>, []}]}, + {<<"FN">>, [{<<"%s">>, [<<"displayName">>]}]}, + {<<"FAMILY">>, [{<<"%s">>, [<<"sn">>]}]}, + {<<"GIVEN">>, [{<<"%s">>, [<<"givenName">>]}]}, + {<<"MIDDLE">>, [{<<"%s">>, [<<"initials">>]}]}, + {<<"ORGNAME">>, [{<<"%s">>, [<<"o">>]}]}, + {<<"ORGUNIT">>, [{<<"%s">>, [<<"ou">>]}]}, + {<<"CTRY">>, [{<<"%s">>, [<<"c">>]}]}, + {<<"LOCALITY">>, [{<<"%s">>, [<<"l">>]}]}, + {<<"STREET">>, [{<<"%s">>, [<<"street">>]}]}, + {<<"REGION">>, [{<<"%s">>, [<<"st">>]}]}, + {<<"PCODE">>, [{<<"%s">>, [<<"postalCode">>]}]}, + {<<"TITLE">>, [{<<"%s">>, [<<"title">>]}]}, + {<<"URL">>, [{<<"%s">>, [<<"labeleduri">>]}]}, + {<<"DESC">>, [{<<"%s">>, [<<"description">>]}]}, + {<<"TEL">>, [{<<"%s">>, [<<"telephoneNumber">>]}]}, + {<<"EMAIL">>, [{<<"%s">>, [<<"mail">>]}]}, + {<<"BDAY">>, [{<<"%s">>, [<<"birthDay">>]}]}, + {<<"ROLE">>, [{<<"%s">>, [<<"employeeType">>]}]}, + {<<"PHOTO">>, [{<<"%s">>, [<<"jpegPhoto">>]}]}]. default_search_fields() -> [{?T("User"), <<"%u">>}, @@ -352,16 +352,15 @@ default_search_reported() -> {?T("Organization Unit"), <<"ORGUNIT">>}]. parse_options(Host, Opts) -> - MyHosts = gen_mod:get_opt_hosts(Host, Opts, <<"vjud.@HOST@">>), - Search = gen_mod:get_opt(search, Opts, false), - Matches = gen_mod:get_opt(matches, Opts, 30), + MyHosts = gen_mod:get_opt_hosts(Host, Opts), + Search = gen_mod:get_opt(search, Opts), + Matches = gen_mod:get_opt(matches, Opts), Eldap_ID = misc:atom_to_binary(gen_mod:get_module_proc(Host, ?PROCNAME)), Cfg = eldap_utils:get_config(Host, Opts), - UIDsTemp = gen_mod:get_opt({ldap_uids, Host}, Opts, - [{<<"uid">>, <<"%u">>}]), + UIDsTemp = gen_mod:get_opt(ldap_uids, Opts), UIDs = eldap_utils:uids_domain_subst(Host, UIDsTemp), SubFilter = eldap_utils:generate_subfilter(UIDs), - UserFilter = case gen_mod:get_opt({ldap_filter, Host}, Opts, <<"">>) of + UserFilter = case gen_mod:get_opt(ldap_filter, Opts) of <<"">> -> SubFilter; F -> @@ -370,11 +369,9 @@ parse_options(Host, Opts) -> {ok, SearchFilter} = eldap_filter:parse(eldap_filter:do_sub(UserFilter, [{<<"%u">>, <<"*">>}])), - VCardMap = gen_mod:get_opt(ldap_vcard_map, Opts, default_vcard_map()), - SearchFields = gen_mod:get_opt(ldap_search_fields, Opts, - default_search_fields()), - SearchReported = gen_mod:get_opt(ldap_search_reported, Opts, - default_search_reported()), + VCardMap = gen_mod:get_opt(ldap_vcard_map, Opts), + SearchFields = gen_mod:get_opt(ldap_search_fields, Opts), + SearchReported = gen_mod:get_opt(ldap_search_reported, Opts), UIDAttrs = [UAttr || {UAttr, _} <- UIDs], VCardMapAttrs = lists:usort(lists:append([A || {_, _, A} <- VCardMap]) @@ -412,7 +409,6 @@ parse_options(Host, Opts) -> search_reported_attrs = SearchReportedAttrs, matches = Matches}. -mod_opt_type(ldap_filter) -> fun eldap_utils:check_filter/1; mod_opt_type(ldap_search_fields) -> fun (Ls) -> [{iolist_to_binary(S), iolist_to_binary(P)} @@ -423,15 +419,6 @@ mod_opt_type(ldap_search_reported) -> [{iolist_to_binary(S), iolist_to_binary(P)} || {S, P} <- Ls] end; -mod_opt_type(ldap_uids) -> - fun (Us) -> - lists:map(fun ({U, P}) -> - {iolist_to_binary(U), iolist_to_binary(P)}; - ({U}) -> {iolist_to_binary(U)}; - (U) -> {iolist_to_binary(U)} - end, - lists:flatten(Us)) - end; mod_opt_type(ldap_vcard_map) -> fun (Ls) -> lists:map(fun ({S, [{P, L}]}) -> @@ -440,48 +427,14 @@ mod_opt_type(ldap_vcard_map) -> end, Ls) end; -mod_opt_type(deref_aliases) -> - fun (never) -> never; - (searching) -> searching; - (finding) -> finding; - (always) -> always - end; -mod_opt_type(ldap_backups) -> - fun (L) -> [iolist_to_binary(H) || H <- L] end; -mod_opt_type(ldap_base) -> fun iolist_to_binary/1; -mod_opt_type(ldap_deref_aliases) -> - fun (never) -> never; - (searching) -> searching; - (finding) -> finding; - (always) -> always - end; -mod_opt_type(ldap_encrypt) -> - fun (tls) -> tls; - (starttls) -> starttls; - (none) -> none - end; -mod_opt_type(ldap_password) -> fun iolist_to_binary/1; -mod_opt_type(ldap_port) -> - fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(ldap_rootdn) -> fun iolist_to_binary/1; -mod_opt_type(ldap_servers) -> - fun (L) -> [iolist_to_binary(H) || H <- L] end; -mod_opt_type(ldap_tls_cacertfile) -> - fun misc:try_read_file/1; -mod_opt_type(ldap_tls_certfile) -> - fun ejabberd_pkix:try_certfile/1; -mod_opt_type(ldap_tls_depth) -> - fun (I) when is_integer(I), I >= 0 -> I end; -mod_opt_type(ldap_tls_verify) -> - fun (hard) -> hard; - (soft) -> soft; - (false) -> false - end; -mod_opt_type(_) -> - [ldap_filter, ldap_search_fields, - ldap_search_reported, ldap_uids, ldap_vcard_map, - deref_aliases, ldap_backups, ldap_base, - ldap_deref_aliases, ldap_encrypt, ldap_password, - ldap_port, ldap_rootdn, ldap_servers, - ldap_tls_cacertfile, ldap_tls_certfile, ldap_tls_depth, - ldap_tls_verify]. +mod_opt_type(Opt) -> + eldap_utils:opt_type(Opt). + +mod_options(Host) -> + [{ldap_search_fields, default_search_fields()}, + {ldap_search_reported, default_search_reported()}, + {ldap_vcard_map, default_vcard_map()} + | lists:map( + fun({Opt, Default}) -> + {Opt, ejabberd_config:get_option({Opt, Host}, Default)} + end, eldap_utils:options(Host))]. diff --git a/src/mod_vcard_mnesia.erl b/src/mod_vcard_mnesia.erl index f7231ee21..e759627ec 100644 --- a/src/mod_vcard_mnesia.erl +++ b/src/mod_vcard_mnesia.erl @@ -31,6 +31,7 @@ search_fields/1, search_reported/1, remove_user/2]). -export([is_search_supported/1]). -export([need_transform/1, transform/1]). +-export([mod_opt_type/1, mod_options/1]). -include("ejabberd.hrl"). -include("xmpp.hrl"). @@ -193,8 +194,7 @@ filter_fields([{SVar, [Val]} | Ds], Match, LServer) NewMatch = case SVar of <<"user">> -> case gen_mod:get_module_opt(LServer, ?MODULE, - search_all_hosts, - true) of + search_all_hosts) of true -> Match#vcard_search{luser = make_val(LVal)}; false -> Host = find_my_host(LServer), @@ -265,3 +265,9 @@ record_to_item(R) -> {<<"email">>, (R#vcard_search.email)}, {<<"orgname">>, (R#vcard_search.orgname)}, {<<"orgunit">>, (R#vcard_search.orgunit)}]. + +mod_opt_type(search_all_hosts) -> + fun (B) when is_boolean(B) -> B end. + +mod_options(_) -> + [{search_all_hosts, true}]. diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl index 1578e655c..597ff41a8 100644 --- a/src/mod_vcard_xupdate.erl +++ b/src/mod_vcard_xupdate.erl @@ -31,7 +31,7 @@ -export([start/2, stop/1, reload/3]). -export([update_presence/1, vcard_set/1, remove_user/2, - user_send_packet/1, mod_opt_type/1, depends/2]). + user_send_packet/1, mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -141,23 +141,17 @@ db_get_xupdate(LUser, LServer) -> init_cache(Host, Opts) -> case use_cache(Host) of true -> - CacheOpts = cache_opts(Host, Opts), + CacheOpts = cache_opts(Opts), ets_cache:new(?VCARD_XUPDATE_CACHE, CacheOpts); false -> ets_cache:delete(?VCARD_XUPDATE_CACHE) end. --spec cache_opts(binary(), gen_mod:opts()) -> [proplists:property()]. -cache_opts(Host, Opts) -> - MaxSize = gen_mod:get_opt( - cache_size, Opts, - ejabberd_config:cache_size(Host)), - CacheMissed = gen_mod:get_opt( - cache_missed, Opts, - ejabberd_config:cache_missed(Host)), - LifeTime = case gen_mod:get_opt( - cache_life_time, Opts, - ejabberd_config:cache_life_time(Host)) of +-spec cache_opts(gen_mod:opts()) -> [proplists:property()]. +cache_opts(Opts) -> + MaxSize = gen_mod:get_opt(cache_size, Opts), + CacheMissed = gen_mod:get_opt(cache_missed, Opts), + LifeTime = case gen_mod:get_opt(cache_life_time, Opts) of infinity -> infinity; I -> timer:seconds(I) end, @@ -165,9 +159,7 @@ cache_opts(Host, Opts) -> -spec use_cache(binary()) -> boolean(). use_cache(Host) -> - gen_mod:get_module_opt( - Host, ?MODULE, use_cache, - ejabberd_config:use_cache(Host)). + gen_mod:get_module_opt(Host, ?MODULE, use_cache). -spec compute_hash(xmlel()) -> binary() | external. compute_hash(VCard) -> @@ -195,6 +187,10 @@ mod_opt_type(O) when O == cache_life_time; O == cache_size -> (infinity) -> infinity end; mod_opt_type(O) when O == use_cache; O == cache_missed -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> - [cache_life_time, cache_size, use_cache, cache_missed]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{use_cache, ejabberd_config:use_cache(Host)}, + {cache_size, ejabberd_config:cache_size(Host)}, + {cache_missed, ejabberd_config:cache_missed(Host)}, + {cache_life_time, ejabberd_config:cache_life_time(Host)}]. diff --git a/src/mod_version.erl b/src/mod_version.erl index 6765d1e86..12051332b 100644 --- a/src/mod_version.erl +++ b/src/mod_version.erl @@ -32,7 +32,7 @@ -behaviour(gen_mod). -export([start/2, stop/1, reload/3, process_local_iq/1, - mod_opt_type/1, depends/2]). + mod_opt_type/1, mod_options/1, depends/2]). -include("ejabberd.hrl"). -include("logger.hrl"). @@ -40,7 +40,7 @@ -include("xmpp.hrl"). start(Host, Opts) -> - IQDisc = gen_mod:get_opt(iqdisc, Opts, gen_iq_handler:iqdisc(Host)), + IQDisc = gen_mod:get_opt(iqdisc, Opts), gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION, ?MODULE, process_local_iq, IQDisc). @@ -50,7 +50,7 @@ stop(Host) -> ?NS_VERSION). reload(Host, NewOpts, OldOpts) -> - case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts, gen_iq_handler:iqdisc(Host)) of + case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts) of {false, IQDisc, _} -> gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION, ?MODULE, process_local_iq, IQDisc); @@ -63,7 +63,7 @@ process_local_iq(#iq{type = set, lang = Lang} = IQ) -> xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang)); process_local_iq(#iq{type = get, to = To} = IQ) -> Host = To#jid.lserver, - OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, true) of + OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os) of true -> get_os(); false -> undefined end, @@ -87,5 +87,8 @@ depends(_Host, _Opts) -> mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(show_os) -> - fun (B) when is_boolean(B) -> B end; -mod_opt_type(_) -> [iqdisc, show_os]. + fun (B) when is_boolean(B) -> B end. + +mod_options(Host) -> + [{iqdisc, gen_iq_handler:iqdisc(Host)}, + {show_os, true}].