]> granicus.if.org Git - ejabberd/commitdiff
Introduce new gen_mod callback: mod_options/1
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 23 Jan 2018 07:54:52 +0000 (10:54 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 23 Jan 2018 07:54:52 +0000 (10:54 +0300)
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.

76 files changed:
src/ejabberd_bosh.erl
src/ejabberd_c2s.erl
src/ejabberd_config.erl
src/ejabberd_db_modules.erl [deleted file]
src/ejabberd_listener.erl
src/ejabberd_options.erl [deleted file]
src/ejabberd_web_admin.erl
src/eldap.erl
src/eldap_utils.erl
src/gen_mod.erl
src/mod_adhoc.erl
src/mod_admin_extra.erl
src/mod_admin_update_sql.erl
src/mod_announce.erl
src/mod_avatar.erl
src/mod_block_strangers.erl
src/mod_blocking.erl
src/mod_bosh.erl
src/mod_caps.erl
src/mod_carboncopy.erl
src/mod_client_state.erl
src/mod_configure.erl
src/mod_delegation.erl
src/mod_disco.erl
src/mod_echo.erl
src/mod_fail2ban.erl
src/mod_http_api.erl
src/mod_http_fileserver.erl
src/mod_http_upload.erl
src/mod_http_upload_quota.erl
src/mod_irc.erl
src/mod_last.erl
src/mod_last_mnesia.erl
src/mod_legacy_auth.erl
src/mod_mam.erl
src/mod_metrics.erl
src/mod_mix.erl
src/mod_muc.erl
src/mod_muc_admin.erl
src/mod_muc_log.erl
src/mod_muc_room.erl
src/mod_multicast.erl
src/mod_offline.erl
src/mod_ping.erl
src/mod_pres_counter.erl
src/mod_privacy.erl
src/mod_privacy_mnesia.erl
src/mod_private.erl
src/mod_private_mnesia.erl
src/mod_privilege.erl
src/mod_proxy65.erl
src/mod_proxy65_service.erl
src/mod_proxy65_stream.erl
src/mod_pubsub.erl
src/mod_push.erl
src/mod_push_keepalive.erl
src/mod_register.erl
src/mod_register_web.erl
src/mod_roster.erl
src/mod_roster_mnesia.erl
src/mod_s2s_dialback.erl
src/mod_service_log.erl
src/mod_shared_roster.erl
src/mod_shared_roster_ldap.erl
src/mod_sic.erl
src/mod_sip.erl
src/mod_sip_proxy.erl
src/mod_sip_registrar.erl
src/mod_stats.erl
src/mod_stream_mgmt.erl
src/mod_time.erl
src/mod_vcard.erl
src/mod_vcard_ldap.erl
src/mod_vcard_mnesia.erl
src/mod_vcard_xupdate.erl
src/mod_version.erl

index c3e82c616318ecd4635e9295f7395ec60332c84f..4a552f43c5f1474471543fb781a12be5dee94550 100644 (file)
 -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).
          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) ->
index f7930f725eebd5821d3c91f4572305b57d11adbf..6e7ba1e678bfd8e6c93d31047b94be2febc834a4 100644 (file)
@@ -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.
index 0fa3afe2926194aa995a9baf1e66c5cb0c6901ef..7b275bf6ce43aa67c7ac6216a343230435ca0bc7 100644 (file)
@@ -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,
 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 (file)
index 4e83569..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%% @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 <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% 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
-%%%===================================================================
index 56843e5b5e54f95b66fce1a3b8d19ef4a81119ee..297a9c4865d3ab3f340422391476d3f67f7a5b98 100644 (file)
@@ -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 (file)
index 649c2e4..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
-%%% @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 <ekhramtsov@process-one.net>
-%%%
-%%%
-%%% 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
-%%%===================================================================
index 52e721a91c340e2f2ae30a69aef35f37069cbe6d..da9664a48141da05c734b5bda0623c9975652667 100644 (file)
@@ -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.
index 8e6b710b1d8f35af9c10d9b3a1dfc995e925fde9..03651c5088e913729f3b9058839c7b617499bcc6 100644 (file)
@@ -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.
index 38bc7206966b424bf5d104e100d92dca81536624..0a0d3f96504fb8fdde6e31354732dcc2c817c3dd 100644 (file)
@@ -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}].
index a2befc60ee40944badb3093697554a9b2def1562..98d7d398fb1d0577e28ececbbb6141b9a7eeb7a9 100644 (file)
         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").
 -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 ->
index ebbdb984a58078a6ecc9c1a3c33b46ed80e2b592..4944bd0113251bfc7485ad77562f2c30a67f02ff 100644 (file)
         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}].
index 1727682b8a534f0d1d3469739f8887558b080f52..e64cdb465dcad8ac674a05e21216e4b74665a6ac 100644 (file)
@@ -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(_) -> [].
index 6a45610c8fde950b5e934f364591567c1ef9cb65..0eaab9ff918c479b4e8887ec138c1b20de3804e0 100644 (file)
@@ -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(_) -> [].
index 1c5493a2faecc28b74a2f9987a96c62520f35552..6db1e4529f800658ee5703182e8fb7c97cc5b554 100644 (file)
@@ -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)}].
index 778794e1acdb5d4378e7de2dac65c2f081530b91..48e963ff6a0551015463daa8a16b62890c816e85 100644 (file)
@@ -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()]]}].
index 2d49e2e8e211383b963cba96b1344dca11e00ae0..d427ef9a6ec84dd04309f06c4441cfe476b7b780 100644 (file)
@@ -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}].
index 620586f2c290e3643b42d35093f03d669094de71..c10adf553a9d8037c7435adbd8fadc65188f87e6 100644 (file)
@@ -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)}].
index 913e19644d0b3525dea21ff497b09d098a695fbe..face1692c4328530794a75373387659e01239559 100644 (file)
@@ -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,
index 5e4372e91a16984eb6b579ab93866173f19e2281..61317556d35aad1611b8be60834fb6ece7a89580 100644 (file)
@@ -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)}].
index d56afd7ec01ffb282f6f4d3434c2b277a0129084..8e76ad1d21687addb007235484bf85572ddfccfd 100644 (file)
@@ -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)}].
index bd3bf335980ef4a8fdc80ddd42d396ce290a6f89..4e11ea8c771f29f493b5a5f65f36668eb7510a28 100644 (file)
@@ -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) ->
index c90fd59b7bd1ab67c5c9c794059518f376a9ef86..db0780834c23f07aedfe1d1db0ddfd2f52048ea3 100644 (file)
@@ -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(_) -> [].
index a9874abe724ba8d95b6924d62690ec3190eaeb0b..1d34be12eca95372af12a7dc6fa69dae22291416 100644 (file)
@@ -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
index e2632a0b4cd41a748e8e7eebc3a6d0cdc1984fe7..d6dbd7101e087ac1a4086754b445cff2685f2b74 100644 (file)
@@ -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")}].
index 04b47e08e0d06ad9f57be0b247e6b61fe7d35c3d..7e8c70cb96233539f4ef96d9da5610a919fe0dca 100644 (file)
@@ -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)
index e8ab076fbd463f44978e7712787c400f6d7b7bbc..618e4b6e4158f22cc9fae27b69a7043239d71743 100644 (file)
 
 -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}].
index 2b818840d96856857d1b34ac3fa38c3da1eeda47..d403e3aa982aa6e3656d66797e3047872a38e579 100644 (file)
@@ -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}].
index b804805c201656b970490ae171a17b34d19445ad..4595ac873bdf45d8724f16ea6e14f51e0eaef105 100644 (file)
@@ -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].
index 52036cbe18d1c24addebbb8d2d148f66955f73f8..9f5894499817a4d991deb4508971b71ce6c983d4 100644 (file)
@@ -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,
 -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], <<$/>>),
index cfbd25b7ae65186a1776a85e0d5484a4e0c74c22..6e5b430c527488811b60a2071b48350ff2e8b4be 100644 (file)
@@ -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 -> [];
index ab8b31c2c1b6112299f030dd98d071173969dedc..27d5c0f3b6e8e71e905c7f9249fb62f695fc2044 100644 (file)
@@ -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").
 -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) ->
index 50303d0b6af7e70692cf354801f2c74e9a25c8e0..f9edb91f41883f6b1a040e27178b2908d9de7f2c 100644 (file)
@@ -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)}].
index a926da1b52d0cd2d9a6f2cf18a6b86549764e231..de5e448d3fadfc258e7fe363b7ffc29497ca2e06 100644 (file)
@@ -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.
index 8d163818c33e013e5540967ad377a1cfe412ba34..19b905ad8c8c7d39e4add7d053c6d9d9d501ecb2 100644 (file)
@@ -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()) ->
index 0f05603a8318ee89593de78513600dceaf5a073b..8f37049239730e8c8c56d4e9a7dd4818d5f3fa5e 100644 (file)
@@ -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)}].
index 7b2050389b02380d18af04823488a8b78659aa52..69888eee2bf27e66ff2ef7f0adb21a801e3bfe05 100644 (file)
@@ -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}].
index b91dd77f196ffe69c821b9203cc1fa0e65f022e5..fc51a5a024562c25917d769741b9d0fd00e81486 100644 (file)
@@ -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, []}].
index d3ad90cb4f5e6d3c07ddb320f4a0fb49cbc54e0b..0cf03fa812b9b0c96acb65cd05a0bec922c33f1a 100644 (file)
@@ -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]}]}].
index 5fb01132b9063495696cbc41b7d377ec43297402..0bd47dcaa46d6748e757354d2092fc788fe24385 100644 (file)
@@ -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(_) -> [].
index f8957a23eb7f5884c018543b8f26b9b8687d1225..bf88b2d8bdefe17aecdea20a2536c6483bf0e461 100644 (file)
@@ -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">>}]}].
index 9a12e97fb33a2bd3ae2545f4dadb00972928a2a5..a82689406d53327873c5b7eb3335762debb889fd 100644 (file)
@@ -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.
 
index f2a48ecaf6d9303e8f457111686fbb655997183d..e6b2a93d23d5d8bf1e13bb0c7e48e5637c987876 100644 (file)
@@ -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")}].
index 5c509acca1c3760e41a844c41ae30fe57a693fdf..d9f66843e5f3b6ae013aa4f0885a312431105d4b 100644 (file)
@@ -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}].
index a51d4e8a25d59258cb578f3ca963709186e76e20..5c349a75d59133abfcbea797b759818e85229ef9 100644 (file)
 
 -include("xmpp.hrl").
 
--define(DEFAULT_SEND_PINGS, false).
-
--define(DEFAULT_PING_INTERVAL, 60).
-
 %% API
 -export([start_ping/2, stop_ping/2]).
 
         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}].
index c747eb3612de68952830d86ea61cc8a39fbc5e80..62e4fc08febeb2d2611662626907979a05cfa149 100644 (file)
@@ -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}].
index 7f0d8e2169d43eb37fef457ffdf4bdb976bc0e26..888a231ed971b384075529aa0bcc611e3616e4fc 100644 (file)
@@ -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)}].
index b0acf40da5d33715fd2916ac01e8f97f7abb5f7d..a28910c0f7070bf14826f25a7bbad73e3460b425 100644 (file)
@@ -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.
index f04d9c739748b00c00d77f50afad3f4c043d37b4..f819f2b60a6bfa738746dc7fb47aa923a9d37290 100644 (file)
@@ -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)}].
index f51c1a3955982af3cbd7c79c58f060364efc84db..b981a803aed8b60c6749b5ffbfae13a077211a84 100644 (file)
@@ -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.
index a8cf8a0965c2222c2588421d8bad2bf22c896231..e201338f3dfd60ca551129d4375d79fe43b62ed7 100644 (file)
@@ -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;
index d49b95b92ce25879f5f3426aebe77265c7a4da7b..eb6950c60a4b0f1a371fbf532df4c2e7a4e939d6 100644 (file)
 %% 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().
index 718f97ee8df651aec14e4a547cce9501c70c17e0..f81874694d8221c9b7e7c2479f4e5684d5b5efa5 100644 (file)
@@ -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,
index 558b681a7701e7a4587db0be12930869070cb951..ad1844e0c9bf805c925f681546947732dd8b55c7 100644 (file)
@@ -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}].
index 47ee8fa3eb5ffded3481dfba5938dd6f0036b110..40a326357294b904adee7095771baa189821b05c 100644 (file)
@@ -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) ->
 %% <em>node_plugin</em>. The 'node_' prefix is mandatory.</p>
 %% <p>See {@link node_hometree:init/1} for an example implementation.</p>
 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, []}].
index 11aa848de99e96b3ec73e277b22e4097704ea293..df63ee6f1eaa6a6a42191c351bf4100a71b6ff83 100644 (file)
@@ -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()].
index 50b526c3b810966088f33334c13f37826cb3141d..1e0942ebfa1ea56b6adc700bbac33da63da5f4d3 100644 (file)
@@ -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) ->
index 0204b32e28fa204e4d63ebba7e7c5edd09730917..b9dabe16d8ca172f6b3ccf288dc8695a374914e9 100644 (file)
         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()].
index 646b6d7ac03aa12e13e7a85ff2738b07d7accc3a..c857887ee5eabb2be8508d49316648d40b72a357 100644 (file)
@@ -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(_) ->
+    [].
index 276603737c27305a34e165f4908bb495ca47012c..f9779c47f3598cf99d2bdba0e59f1184a03075b2 100644 (file)
@@ -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)}].
index e7d75e025bc2561f4caef24208ce631b94d91f33..67d302f8ae9b330d103dc33453b1d9eeccddef24 100644 (file)
@@ -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.
index 1eedd71c32213974eaca008d08bafa4d2b15f37e..6f088b3495ca3b560e0f11493228d458af3a4910 100644 (file)
@@ -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, _) ->
index b6f6f7f1d7a3732b73aeb1e95d61704513315dc2..783c29188b8025844459119b672bf441cffd1a2b 100644 (file)
@@ -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, []}].
index 4a0cb07cddf965144510f6c8f7ba393f0acac7e4..fffd68d60c3b6c045cd93ffd9cb6ded170ddaa86 100644 (file)
@@ -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)}].
index 909a3fbc53bce0f4967b04cb8319f22b247bcd28..82db781e63728d53f0445cfd9029ee7b164c2fc1 100644 (file)
@@ -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].
-
-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_opt_type(Opt) ->
+    eldap_utils:opt_type(Opt).
+
+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].
index 8e1dcca7ef8576bb6d242ea9f3d13cdb0b11bfbf..6a417b9b00321fd543740e9750de9bd0ead81f7d 100644 (file)
 -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)}].
index bd11d1a85b7cc86f22ac503069b8f7e483f4903e..c40e4eb7c07d2ccaf989bb83777ec5d5b22ea540 100644 (file)
@@ -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.
index ae020f8ce27a1077864823926612aebb0fb36363..0e7f367df70c11c8188fff8cafe817661d9ffb8d 100644 (file)
@@ -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),
index 34e024ba515db0c23bb871f3a3e3145d5e53581c..346b3be19069f563455690e0881b87b78aac8332 100644 (file)
@@ -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() ->
index f9ea9373f5730396bcb2249602c8a7c7eb9d6bc5..af7ad7195bd25d08563d33774b4c03f62e17ec5b 100644 (file)
 
 -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)}].
index e295a8612dfc508c6ac5b8b02822d9b4bf5c6865..baf72b329de3d4f26306dad8e97b5edf6b44c10e 100644 (file)
@@ -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)}].
index 4b3b67c94c09a42878bbb5e8e6c942545b68925a..d4dffbf10719d866ed5a987c2e0f7e90b7c0d85d 100644 (file)
@@ -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)}].
index 352c80324e1218f771993d03cddd6221dc9e1868..fbbf59b84534a1bf49e2f458bb0a7cf052f4f136 100644 (file)
@@ -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)}].
index edb99972b4dfeb9131570c2b03162dedfa94ccd2..ce4fcd702cb378c7897d2f0e814f6da1fa7c57ec 100644 (file)
@@ -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))].
index f7231ee21b1e872b9194e625e6bf4d38933c83e2..e759627ec2bf6a657e1facdc0141b49a180344b0 100644 (file)
@@ -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}].
index 1578e655cc35be1a7f283cf17f485bde56db1fc7..597ff41a84c5ecda8395fa42768be4ef3e9ac019 100644 (file)
@@ -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)}].
index 6765d1e86bd09a315fb3891fa7df5272fe02c2a8..12051332b7ce768fdef27f059dca323facccd0dc 100644 (file)
@@ -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}].