]> granicus.if.org Git - ejabberd/commitdiff
Make modules loading in a dependent order (#1191)
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Wed, 6 Jul 2016 11:58:48 +0000 (14:58 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Wed, 6 Jul 2016 11:58:48 +0000 (14:58 +0300)
47 files changed:
src/gen_mod.erl
src/mod_adhoc.erl
src/mod_admin_extra.erl
src/mod_announce.erl
src/mod_blocking.erl
src/mod_caps.erl
src/mod_configure.erl
src/mod_configure2.erl
src/mod_disco.erl
src/mod_echo.erl
src/mod_fail2ban.erl
src/mod_http_api.erl
src/mod_http_bind.erl
src/mod_http_fileserver.erl
src/mod_http_upload.erl
src/mod_http_upload_quota.erl
src/mod_ip_blacklist.erl
src/mod_irc.erl
src/mod_last.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_multicast.erl
src/mod_offline.erl
src/mod_privacy.erl
src/mod_private.erl
src/mod_proxy65.erl
src/mod_pubsub.erl
src/mod_register.erl
src/mod_register_web.erl
src/mod_roster.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_stats.erl
src/mod_time.erl
src/mod_vcard.erl
src/mod_vcard_ldap.erl
src/mod_vcard_xupdate.erl
src/mod_version.erl
src/node_pep.erl
src/node_pep_sql.erl

index 1cc65ac21a1074d192ce4f59e9acb07480336fea..521ed1b3f6cbbb065769d3b115e901d075158fb4 100644 (file)
@@ -53,6 +53,7 @@
 -callback start(binary(), opts()) -> any().
 -callback stop(binary()) -> any().
 -callback mod_opt_type(atom()) -> fun((term()) -> term()) | [atom()].
+-callback depends(binary(), opts()) -> [{module(), hard | soft}].
 
 -export_type([opts/0]).
 -export_type([db_type/0]).
@@ -77,18 +78,49 @@ start_modules() ->
 
 get_modules_options(Host) ->
     ejabberd_config:get_option(
-       {modules, Host},
-       fun(Mods) ->
-           lists:map(
+      {modules, Host},
+      fun(Mods) ->
+             lists:map(
                fun({M, A}) when is_atom(M), is_list(A) ->
-                   {M, A}
+                       {M, A}
                end, Mods)
-       end, []).
+      end, []).
+
+sort_modules(Host, ModOpts) ->
+    G = digraph:new([acyclic]),
+    lists:foreach(
+      fun({Mod, Opts}) ->
+             digraph:add_vertex(G, Mod, Opts),
+             Deps = try Mod:depends(Host, Opts) catch _:undef -> [] end,
+             lists:foreach(
+               fun({DepMod, Type}) ->
+                       case lists:keyfind(DepMod, 1, ModOpts) of
+                           false when Type == hard ->
+                               ErrTxt = io_lib:format(
+                                          "failed to load module '~s' "
+                                          "because it depends on module '~s' "
+                                          "which is not found in the config",
+                                          [Mod, DepMod]),
+                               ?ERROR_MSG(ErrTxt, []),
+                               digraph:del_vertex(G, Mod),
+                               maybe_halt_ejabberd(ErrTxt);
+                           false when Type == soft ->
+                               ?WARNING_MSG("module '~s' is recommended for "
+                                            "module '~s' but is not found in "
+                                            "the config",
+                                            [DepMod, Mod]);
+                           {DepMod, DepOpts} ->
+                               digraph:add_vertex(G, DepMod, DepOpts),
+                               digraph:add_edge(G, DepMod, Mod)
+                       end
+               end, Deps)
+      end, ModOpts),
+    [digraph:vertex(G, V) || V <- digraph_utils:topsort(G)].
 
 -spec start_modules(binary()) -> any().
 
 start_modules(Host) ->
-    Modules = get_modules_options(Host),
+    Modules = sort_modules(Host, get_modules_options(Host)),
     lists:foreach(
        fun({Module, Opts}) ->
            start_module(Host, Module, Opts)
@@ -121,16 +153,20 @@ start_module(Host, Module, Opts0) ->
                            [Module, Host, Opts, Class, Reason,
                             erlang:get_stacktrace()]),
          ?CRITICAL_MSG(ErrorText, []),
-         case is_app_running(ejabberd) of
-           true ->
-               erlang:raise(Class, Reason, erlang:get_stacktrace());
-           false ->
-               ?CRITICAL_MSG("ejabberd initialization was aborted "
-                             "because a module start failed.",
-                             []),
-               timer:sleep(3000),
-               erlang:halt(string:substr(lists:flatten(ErrorText), 1, 199))
-         end
+          maybe_halt_ejabberd(ErrorText),
+         erlang:raise(Class, Reason, erlang:get_stacktrace())
+    end.
+
+maybe_halt_ejabberd(ErrorText) ->
+    case is_app_running(ejabberd) of
+       false ->
+           ?CRITICAL_MSG("ejabberd initialization was aborted "
+                         "because a module start failed.",
+                         []),
+           timer:sleep(3000),
+           erlang:halt(string:substr(lists:flatten(ErrorText), 1, 199));
+       true ->
+           ok
     end.
 
 is_app_running(AppName) ->
index 9e0682f7d7cb961858212174bdccf08a66a6ed01..e12e0de1e6bd7f3922da9d26d932dbbe159b67eb 100644 (file)
@@ -35,7 +35,7 @@
         process_sm_iq/3, 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]).
+        ping_item/4, ping_command/4, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -284,6 +284,9 @@ ping_command(_Acc, _From, _To,
     end;
 ping_command(Acc, _From, _To, _Request) -> Acc.
 
+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;
index 562087d9606c2b62ee565712e4021cb2809d8398..8f6724281030306f1f6ca8a943bce08282ee0aff 100644 (file)
@@ -47,7 +47,7 @@
         srg_delete/2, srg_list/1, srg_get_info/2,
         srg_get_members/2, srg_user_add/4, srg_user_del/4,
         send_message/5, send_stanza/3, send_stanza_c2s/4, privacy_set/3,
-        stats/1, stats/2, mod_opt_type/1, get_commands_spec/0]).
+        stats/1, stats/2, mod_opt_type/1, get_commands_spec/0, depends/2]).
 
 
 -include("ejabberd.hrl").
@@ -66,6 +66,8 @@ start(_Host, _Opts) ->
 stop(_Host) ->
     ejabberd_commands:unregister_commands(get_commands_spec()).
 
+depends(_Host, _Opts) ->
+    [].
 
 %%%
 %%% Register commands
index fc57d6bd13ccdc91bb0c7afe6daa565840c60e48..52ff2de92f6c21e1756c3cbb135121806a17a08e 100644 (file)
@@ -33,7 +33,7 @@
 
 -export([start/2, init/0, stop/1, export/1, import/1,
         import/3, announce/3, send_motd/1, disco_identity/5,
-        disco_features/5, disco_items/5,
+        disco_features/5, disco_items/5, depends/2,
         send_announcement_to_all/3, announce_commands/4,
         announce_items/4, mod_opt_type/1]).
 
@@ -74,6 +74,9 @@ start(Host, Opts) ->
     register(gen_mod:get_module_proc(Host, ?PROCNAME),
             proc_lib:spawn(?MODULE, init, [])).
 
+depends(_Host, _Opts) ->
+    [{mod_adhoc, hard}].
+
 init() ->
     loop().
 
index af06e650d5831897812dd0fb0ea40b1ccf30c7d8..818d5325958f0a2f891f1973546c492473207c89 100644 (file)
@@ -30,7 +30,7 @@
 -protocol({xep, 191, '1.2'}).
 
 -export([start/2, stop/1, process_iq/3,
-        process_iq_set/4, process_iq_get/5, mod_opt_type/1]).
+        process_iq_set/4, process_iq_get/5, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -63,6 +63,9 @@ stop(Host) ->
     gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
                                     ?NS_BLOCKING).
 
+depends(_Host, _Opts) ->
+    [{mod_privacy, hard}].
+
 process_iq(_From, _To, IQ) ->
     SubEl = IQ#iq.sub_el,
     IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}.
index 966a9baa65e989068e2e21bb27a3ee88428c004e..3ed3149bb62222e25b8837105a8b6f6783f0ed03 100644 (file)
@@ -41,7 +41,7 @@
          import_start/2, import_stop/2]).
 
 %% gen_mod callbacks
--export([start/2, start_link/2, stop/1]).
+-export([start/2, start_link/2, stop/1, depends/2]).
 
 %% gen_server callbacks
 -export([init/1, handle_info/2, handle_call/3,
@@ -306,6 +306,9 @@ c2s_broadcast_recipients(InAcc, Host, C2SState,
     end;
 c2s_broadcast_recipients(Acc, _, _, _, _, _) -> Acc.
 
+depends(_Host, _Opts) ->
+    [].
+
 init([Host, Opts]) ->
     Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
     Mod:init(Host, Opts),
index 9d4086559b3fb1e2b1b27dbffe88261f50ecedd3..97c94484276b6a59632d90e0cd8231b85474a72a 100644 (file)
@@ -35,7 +35,8 @@
         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_opt_type/1,
+        depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -95,6 +96,9 @@ stop(Host) ->
     gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
                                     ?NS_COMMANDS).
 
+depends(_Host, _Opts) ->
+    [{mod_adhoc, hard}, {mod_last, soft}].
+
 %%%-----------------------------------------------------------------------
 
 -define(INFO_IDENTITY(Category, Type, Name, Lang),
index a8287b4d47700ae002364215c6540460e628f06b..85b7740d0469c1e18ae8769cb3ddc039064ffe75 100644 (file)
@@ -32,7 +32,7 @@
 -behaviour(gen_mod).
 
 -export([start/2, stop/1, process_local_iq/3,
-        mod_opt_type/1, opt_type/1]).
+        mod_opt_type/1, opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -201,6 +201,9 @@ process_get(#xmlel{name = <<"last">>, attrs = Attrs}, Lang) ->
 %%    {result, };
 process_get(_, _) -> {error, ?ERR_BAD_REQUEST}.
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
 mod_opt_type(_) -> [iqdisc].
 
index 0d5abcb4bba20ceb513edcc5e560e157626e5300..2e7b80c188cda4755e37b1b2617dba76a5236d94 100644 (file)
@@ -39,7 +39,7 @@
         get_sm_identity/5, get_sm_features/5, get_sm_items/5,
         get_info/5, register_feature/2, unregister_feature/2,
         register_extra_domain/2, unregister_extra_domain/2,
-        transform_module_options/1, mod_opt_type/1]).
+        transform_module_options/1, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -534,6 +534,9 @@ values_to_xml(Values) ->
              end,
              Values).
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(extra_domains) ->
     fun (Hs) -> [iolist_to_binary(H) || H <- Hs] end;
 mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
index 7d9f81f823120828efefd162c1d6ffb7cc3701a7..ee904d798f18cf72ae2121f98686cc3fc00c67a1 100644 (file)
@@ -37,7 +37,7 @@
 
 -export([init/1, handle_call/3, handle_cast/2,
         handle_info/2, terminate/2, code_change/3,
-        mod_opt_type/1]).
+        mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -200,5 +200,8 @@ do_client_version(enabled, From, To) ->
     ?INFO_MSG("Information of the client: ~s~s",
              [ToS, Values_string2]).
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(host) -> fun iolist_to_binary/1;
 mod_opt_type(_) -> [host].
index f0460e704864eb6af35c4522ba17acecbdf21dfe..c57ac21b01d9bc4142423389b495857df7f48e9d 100644 (file)
@@ -33,7 +33,7 @@
 
 -export([init/1, handle_call/3, handle_cast/2,
         handle_info/2, terminate/2, code_change/3,
-        mod_opt_type/1]).
+        mod_opt_type/1, depends/2]).
 
 -include_lib("stdlib/include/ms_transform.hrl").
 -include("ejabberd.hrl").
@@ -120,6 +120,9 @@ stop(Host) ->
     supervisor:terminate_child(ejabberd_sup, Proc),
     supervisor:delete_child(ejabberd_sup, Proc).
 
+depends(_Host, _Opts) ->
+    [].
+
 %%%===================================================================
 %%% gen_server callbacks
 %%%===================================================================
index 595c121cd275d15f08cc5191304e6e637dee7a46..815ed3ab6103220118860e8e1d0eb7cacbd58cfd 100644 (file)
@@ -74,7 +74,7 @@
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, process/2, mod_opt_type/1]).
+-export([start/2, stop/1, process/2, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("jlib.hrl").
@@ -123,6 +123,9 @@ start(_Host, _Opts) ->
 stop(_Host) ->
     ok.
 
+depends(_Host, _Opts) ->
+    [].
+
 %% ----------
 %% basic auth
 %% ----------
index 1a07867e09a9afbc98a6c2580aa87b64bbe1d68a..9a3a379f7e64135a446242625485ae19e8435090 100644 (file)
@@ -37,7 +37,7 @@
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, process/2, mod_opt_type/1]).
+-export([start/2, stop/1, process/2, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -109,6 +109,8 @@ mod_opt_type(max_pause) ->
     fun (I) when is_integer(I), I > 0 -> I end;
 mod_opt_type(_) -> [max_inactivity, max_pause].
 
+depends(_Host, _Opts) ->
+    [].
 
 %%%----------------------------------------------------------------------
 %%% Help Web Page
index 346dc41c8686bb9b1f55b5012ec6a685425422c8..37e02edd85b55d3208717f683539ffb6355b8e92 100644 (file)
@@ -46,7 +46,7 @@
 %% utility for other http modules
 -export([content_type/3]).
 
--export([reopen_log/1, mod_opt_type/1]).
+-export([reopen_log/1, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -109,6 +109,9 @@ stop(Host) ->
     supervisor:terminate_child(ejabberd_sup, Proc),
     supervisor:delete_child(ejabberd_sup, Proc).
 
+depends(_Host, _Opts) ->
+    [].
+
 %%====================================================================
 %% API
 %%====================================================================
index a2aa7546536f61ccf376735289e031609ab5511a..b166f2b6644af504c86a3b0526c1adee55977c73 100644 (file)
@@ -68,6 +68,7 @@
 -export([start_link/3,
         start/2,
         stop/1,
+        depends/2,
         mod_opt_type/1]).
 
 %% gen_server callbacks.
@@ -222,6 +223,11 @@ mod_opt_type(_) ->
      dir_mode, docroot, put_url, get_url, service_url, custom_headers,
      rm_on_unregister, thumbnail].
 
+-spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}].
+
+depends(_Host, _Opts) ->
+    [].
+
 %%--------------------------------------------------------------------
 %% gen_server callbacks.
 %%--------------------------------------------------------------------
index e08cd0b917cf2a0286fd4d4480571022215bad1a..d2eca8b723f70e6b84c9ce8f41eade3b1238a977 100644 (file)
@@ -39,6 +39,7 @@
 -export([start_link/3,
         start/2,
         stop/1,
+        depends/2,
         mod_opt_type/1]).
 
 %% gen_server callbacks.
@@ -109,6 +110,11 @@ mod_opt_type(max_days) ->
 mod_opt_type(_) ->
     [access_soft_quota, access_hard_quota, max_days].
 
+-spec depends(binary(), gen_mod:opts()) -> [{module(), hard | soft}].
+
+depends(_Host, _Opts) ->
+    [].
+
 %%--------------------------------------------------------------------
 %% gen_server callbacks.
 %%--------------------------------------------------------------------
index a6f9f619d3ebed2b57635723ac3877335b4dd30e..4f54ecd79fdded9073f6d08bc346930fdd2ed75c 100644 (file)
@@ -36,7 +36,7 @@
 
 -export([update_bl_c2s/0]).
 
--export([is_ip_in_c2s_blacklist/3, mod_opt_type/1]).
+-export([is_ip_in_c2s_blacklist/3, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -65,6 +65,9 @@ preinit(Parent, State) ->
       error:_ -> Parent ! {ok, Pid, true}
     end.
 
+depends(_Host, _Opts) ->
+    [].
+
 %% TODO:
 stop(_Host) -> ok.
 
index 4bcf69c3b2f3f8cf978af64b042aaf2c9a4a6c52..2206028b7209c45e728c9aa66d4b072ea7c2f9d9 100644 (file)
@@ -38,7 +38,7 @@
 
 -export([init/1, handle_call/3, handle_cast/2,
         handle_info/2, terminate/2, code_change/3,
-        mod_opt_type/1]).
+        mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -99,6 +99,9 @@ stop(Host) ->
     gen_server:call(Proc, stop),
     supervisor:delete_child(ejabberd_sup, Proc).
 
+depends(_Host, _Opts) ->
+    [].
+
 %%====================================================================
 %% gen_server callbacks
 %%====================================================================
index 92694cf13554c0d05444b12e042e7c4958c246db..ce91488411dc37ffab1b766537c6b8f66bcb080c 100644 (file)
@@ -37,7 +37,7 @@
         process_sm_iq/3, on_presence_update/4, import/1,
         import/3, store_last_info/4, get_last_info/2,
         remove_user/2, transform_options/1, mod_opt_type/1,
-        opt_type/1, register_user/2]).
+        opt_type/1, register_user/2, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -255,6 +255,9 @@ transform_options({node_start, {_, _, _} = Now}, Opts) ->
 transform_options(Opt, Opts) ->
     [Opt|Opts].
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(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(_) -> [db_type, iqdisc].
index 18bffd9097a2daebcf9aff5a0858d1c5663ebd7a..0e79cd6668dbc6be3ca4bda92ffb252a87b62052 100644 (file)
@@ -31,7 +31,7 @@
 -behaviour(gen_mod).
 
 %% API
--export([start/2, stop/1]).
+-export([start/2, stop/1, depends/2]).
 
 -export([user_send_packet/4, user_send_packet_strip_tag/4, user_receive_packet/5,
         process_iq_v0_2/3, process_iq_v0_3/3, disco_sm_features/5,
@@ -165,6 +165,9 @@ stop(Host) ->
     ejabberd_commands:unregister_commands(get_commands_spec()),
     ok.
 
+depends(_Host, _Opts) ->
+    [].
+
 remove_user(User, Server) ->
     LUser = jid:nodeprep(User),
     LServer = jid:nameprep(Server),
index 40484e48817984b5eee379c316e369e147cf77b3..f1d487e0e1148d6878138c6c2f6de08220d1f97a 100644 (file)
@@ -39,7 +39,8 @@
                 s2s_send_packet, s2s_receive_packet,
                 remove_user, register_user]).
 
--export([start/2, stop/1, send_metrics/4, opt_type/1, mod_opt_type/1]).
+-export([start/2, stop/1, send_metrics/4, opt_type/1, mod_opt_type/1,
+        depends/2]).
 
 -export([offline_message_hook/3,
          sm_register_connection_hook/3, sm_remove_connection_hook/3,
@@ -59,6 +60,9 @@ stop(Host) ->
     [ejabberd_hooks:delete(Hook, Host, ?MODULE, Hook, 20)
      || Hook <- ?HOOKS].
 
+depends(_Host, _Opts) ->
+    [].
+
 %%====================================================================
 %% Hooks handlers
 %%====================================================================
index c0835b74e15c0e8425e8762ecda3d9ff7748c499..b373ad13defc26a3cefa7d18923ab2d4ca421e7b 100644 (file)
@@ -14,7 +14,7 @@
 %% API
 -export([start_link/2, start/2, stop/1, process_iq/3,
         disco_items/5, disco_identity/5, disco_info/5,
-        disco_features/5, mod_opt_type/1]).
+        disco_features/5, mod_opt_type/1, depends/2]).
 
 %% gen_server callbacks
 -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -343,6 +343,9 @@ is_not_subscribed({error, ErrEl}) ->
        _ -> false
     end.
 
+depends(_Host, _Opts) ->
+    [{mod_pubsub, hard}].
+
 mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
 mod_opt_type(host) -> fun iolist_to_binary/1;
 mod_opt_type(_) -> [host, iqdisc].
index b46585066f1b395ad16adfb7efb7bec3d4b0d970..e5baa37f20d80b25bc6c80d72d9b2892933c454c 100644 (file)
@@ -53,7 +53,7 @@
 
 -export([init/1, handle_call/3, handle_cast/2,
         handle_info/2, terminate/2, code_change/3,
-        mod_opt_type/1]).
+        mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -105,6 +105,9 @@ stop(Host) ->
     supervisor:delete_child(ejabberd_sup, Proc),
     {wait, Rooms}.
 
+depends(_Host, _Opts) ->
+    [{mod_mam, soft}].
+
 shutdown_rooms(Host) ->
     MyHost = gen_mod:get_module_opt_host(Host, mod_muc,
                                         <<"conference.@HOST@">>),
index 5fbda4f28b767ad3545068f56b89f817beff1a6b..0b5e79f603ce57af9dfc3c4dc1b2db32bee0056a 100644 (file)
@@ -11,7 +11,7 @@
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, muc_online_rooms/1,
+-export([start/2, stop/1, depends/2, muc_online_rooms/1,
         muc_unregister_nick/1, create_room/3, destroy_room/2,
         create_rooms_file/1, destroy_rooms_file/1,
         rooms_unused_list/2, rooms_unused_destroy/2,
@@ -49,6 +49,9 @@ stop(Host) ->
     ejabberd_hooks:delete(webadmin_page_main, ?MODULE, web_page_main, 50),
     ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, web_page_host, 50).
 
+depends(_Host, _Opts) ->
+    [{mod_muc, hard}].
+
 %%%
 %%% Register commands
 %%%
index 167a96e371ac7cd2a24cbf0681354652d9dab7d8..ec4711b4325a8cca5681ccd2f50c895ec33ad56e 100644 (file)
@@ -41,7 +41,7 @@
 
 -export([init/1, handle_call/3, handle_cast/2,
         handle_info/2, terminate/2, code_change/3,
-        mod_opt_type/1, opt_type/1]).
+        mod_opt_type/1, opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -109,6 +109,9 @@ transform_module_options(Opts) ->
               Opt
       end, Opts).
 
+depends(_Host, _Opts) ->
+    [{mod_muc, hard}].
+
 %%====================================================================
 %% gen_server callbacks
 %%====================================================================
index cbe2a4e50984711bcc37d95ad892b227248bbe7e..df385c28caedfb47a00ab39cead84b9bd0aa871e 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]).
+-export([purge_loop/1, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -1219,6 +1219,9 @@ stj(String) -> jid:from_string(String).
 
 jts(String) -> jid:to_string(String).
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(access) ->
     fun acl:access_rules_validator/1;
 mod_opt_type(host) -> fun iolist_to_binary/1;
index a794a0371ab5f367bb2787f8d56d76559d1a3342..7b9c712fae6633fc4f47b07c533e37e4a51e7794 100644 (file)
@@ -66,7 +66,7 @@
 
 -export([init/1, handle_call/3, handle_cast/2,
         handle_info/2, terminate/2, code_change/3,
-        mod_opt_type/1]).
+        mod_opt_type/1, depends/2]).
 
 -deprecated({get_queue_length,2}).
 
@@ -125,6 +125,8 @@ stop(Host) ->
     supervisor:delete_child(ejabberd_sup, Proc),
     ok.
 
+depends(_Host, _Opts) ->
+    [].
 
 %%====================================================================
 %% gen_server callbacks
index ad13c27cde7743f445d006906898c53f6bf9e2bb..18ff78371a73146d32d62cfa0f1a7c0edec32c52 100644 (file)
@@ -36,7 +36,7 @@
         check_packet/6, remove_user/2,
         is_list_needdb/1, updated_list/3,
          item_to_xml/1, get_user_lists/2, import/3,
-        set_privacy_list/1, mod_opt_type/1]).
+        set_privacy_list/1, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -593,6 +593,9 @@ import(LServer, DBType, Data) ->
     Mod = gen_mod:db_mod(DBType, ?MODULE),
     Mod:import(LServer, Data).
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(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(_) -> [db_type, iqdisc].
index 38e42ca4c540c6f74da3443f160fb40ae02442a5..f0e4632f6af540789bebe19167edc90f8ba80ca2 100644 (file)
@@ -33,7 +33,7 @@
 
 -export([start/2, stop/1, process_sm_iq/3, import/3,
         remove_user/2, get_data/2, export/1, import/1,
-        mod_opt_type/1, set_data/3]).
+        mod_opt_type/1, set_data/3, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -173,6 +173,9 @@ import(LServer, DBType, PD) ->
     Mod = gen_mod:db_mod(DBType, ?MODULE),
     Mod:import(LServer, PD).
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(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(_) -> [db_type, iqdisc].
index 2737de7ad0051d20dfbe9b30b0a239ad75fb032e..beea35725cdd8a3984414be1e8b55c519fd175e5 100644 (file)
@@ -39,7 +39,7 @@
 %% supervisor callbacks.
 -export([init/1]).
 
--export([start_link/2, mod_opt_type/1]).
+-export([start_link/2, mod_opt_type/1, depends/2]).
 
 -define(PROCNAME, ejabberd_mod_proxy65).
 
@@ -84,6 +84,9 @@ init([Host, Opts]) ->
      {{one_for_one, 10, 1},
       [StreamManager, StreamSupervisor, Service]}}.
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(auth_type) ->
     fun (plain) -> plain;
        (anonymous) -> anonymous
index 53378c355174fbd110673babb3f843be31a65b48..f9d1cde21931f4e11a7407b628939d2c2c26f12e 100644 (file)
@@ -77,7 +77,7 @@
 %% API and gen_server callbacks
 -export([start_link/2, start/2, stop/1, init/1,
     handle_call/3, handle_cast/2, handle_info/2,
-    terminate/2, code_change/3]).
+    terminate/2, code_change/3, depends/2]).
 
 -export([send_loop/1, mod_opt_type/1]).
 
@@ -347,6 +347,18 @@ init_send_loop(ServerHost) ->
     end,
     {Pid, State}.
 
+depends(ServerHost, Opts) ->
+    Host = gen_mod:get_opt_host(ServerHost, Opts, <<"pubsub.@HOST@">>),
+    Plugins = gen_mod:get_opt(plugins, Opts,
+                             fun(A) when is_list(A) -> A end, [?STDNODE]),
+    lists:flatmap(
+      fun(Name) ->
+             Plugin = plugin(ServerHost, Name),
+             try apply(Plugin, depends, [Host, ServerHost, Opts])
+             catch _:undef -> []
+             end
+      end, Plugins).
+
 %% @doc Call the init/1 function for each plugin declared in the config file.
 %% The default plugin module is implicit.
 %% <p>The Erlang code for the plugin is located in a module called
index 43499d2e50d29f839fed9c64b25deb7b2e92ee4a..45cd78fefd4e9a6911b4416952c2babf8ad49d04 100644 (file)
@@ -37,7 +37,7 @@
         unauthenticated_iq_register/4, try_register/5,
         process_iq/3, send_registration_notifications/3,
         transform_options/1, transform_module_options/1,
-        mod_opt_type/1, opt_type/1]).
+        mod_opt_type/1, opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -72,6 +72,9 @@ stop(Host) ->
     gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
                                     ?NS_REGISTER).
 
+depends(_Host, _Opts) ->
+    [].
+
 stream_feature_register(Acc, Host) ->
     AF = gen_mod:get_module_opt(Host, ?MODULE, access_from,
                                           fun(A) -> A end,
index 2b7e5f53251b9b86145d86ecc7e42efc065a39d4..76de1677f78da8d7c31754db6d9e01e6f9d89513 100644 (file)
@@ -55,7 +55,7 @@
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, process/2, mod_opt_type/1]).
+-export([start/2, stop/1, process/2, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -76,6 +76,9 @@ start(_Host, _Opts) ->
 
 stop(_Host) -> ok.
 
+depends(_Host, _Opts) ->
+    [{mod_register, hard}].
+
 %%%----------------------------------------------------------------------
 %%% HTTP handlers
 %%%----------------------------------------------------------------------
index f79061560d70572ba2ea05180283360e2b65df09..a75041bc7335789cb8cc53f3e3b0af662024b3e5 100644 (file)
@@ -49,7 +49,7 @@
         get_jid_info/4, item_to_xml/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]).
+        mod_opt_type/1, set_roster/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -136,6 +136,9 @@ stop(Host) ->
     gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
                                     ?NS_ROSTER).
 
+depends(_Host, _Opts) ->
+    [].
+
 process_iq(From, To, IQ) when ((From#jid.luser == <<"">>) andalso (From#jid.resource == <<"">>)) ->
     process_iq_manager(From, To, IQ);
 
index 3e1da3a4ea1f113d6a3479a3eab58c78ccde3ecb..ae264bbc99b894879712ab641989a1853fead5ca 100644 (file)
@@ -30,7 +30,7 @@
 -behaviour(gen_mod).
 
 -export([start/2, stop/1, log_user_send/4,
-        log_user_receive/5, mod_opt_type/1]).
+        log_user_receive/5, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -51,6 +51,9 @@ stop(Host) ->
                          ?MODULE, log_user_receive, 50),
     ok.
 
+depends(_Host, _Opts) ->
+    [].
+
 log_user_send(Packet, _C2SState, From, To) ->
     log_packet(From, To, Packet, From#jid.lserver),
     Packet.
index 76a619c9bba4bfb6684d2a0d9788fb85a79287e3..b472e1aab24593c8b7454f33037ae9ba3a85c0d0 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]).
+        remove_user_from_group/3, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -132,6 +132,9 @@ stop(Host) ->
     %%ejabberd_hooks:delete(remove_user, Host,
     %%                   ?MODULE, remove_user, 50),
 
+depends(_Host, _Opts) ->
+    [].
+
 get_user_roster(Items, US) ->
     {U, S} = US,
     DisplayedGroups = get_user_displayed_groups(US),
index 34588b90c48a85f5cc23ed228e746df5f8457a76..22f50d302e67b843ccbbe5eb3968841d1f652567 100644 (file)
@@ -41,7 +41,7 @@
 
 -export([get_user_roster/2, get_subscription_lists/3,
         get_jid_info/4, process_item/2, in_subscription/6,
-        out_subscription/4, mod_opt_type/1, opt_type/1]).
+        out_subscription/4, mod_opt_type/1, opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -105,6 +105,9 @@ stop(Host) ->
     supervisor:terminate_child(ejabberd_sup, Proc),
     supervisor:delete_child(ejabberd_sup, Proc).
 
+depends(_Host, _Opts) ->
+    [{mod_roster, hard}].
+
 %%--------------------------------------------------------------------
 %% Hooks
 %%--------------------------------------------------------------------
index b4eae0dafcf3dff66c01bfcdac4ef6d3297170f6..49b65a0eef58a2719b01619434223652097b7e88 100644 (file)
@@ -32,7 +32,7 @@
 -behaviour(gen_mod).
 
 -export([start/2, stop/1, process_local_iq/3,
-        process_sm_iq/3, mod_opt_type/1]).
+        process_sm_iq/3, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -55,6 +55,9 @@ stop(Host) ->
     gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
                                     ?NS_SIC).
 
+depends(_Host, _Opts) ->
+    [].
+
 process_local_iq(#jid{user = User, server = Server,
                      resource = Resource},
                 _To, #iq{type = get, sub_el = _SubEl} = IQ) ->
index 6ffe563315e48ebfdf5194db14f659a87150938d..816100f472891562c6eff481cf823fe38f2a8c1d 100644 (file)
@@ -34,7 +34,7 @@
 
 -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]).
+        locate/1, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -62,6 +62,9 @@ start(_Host, _Opts) ->
 stop(_Host) ->
     ok.
 
+depends(_Host, _Opts) ->
+    [].
+
 data_in(Data, #sip_socket{type = Transport,
                           addr = {MyIP, MyPort},
                           peer = {PeerIP, PeerPort}}) ->
index c14cf8d15c2334147c57c76da2c8e8d270334831..99059839a085ae7cfd850de326f6388fb4f8b8f6 100644 (file)
@@ -32,7 +32,7 @@
 -behaviour(gen_mod).
 
 -export([start/2, stop/1, process_local_iq/3,
-        mod_opt_type/1]).
+        mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -48,6 +48,9 @@ stop(Host) ->
     gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
                                     ?NS_STATS).
 
+depends(_Host, _Opts) ->
+    [].
+
 process_local_iq(_From, To,
                 #iq{id = _ID, type = Type, xmlns = XMLNS,
                     sub_el = SubEl, lang = Lang} =
index 740b654a7b51d22d5aee0707b045bf135fba0e6c..90296f3d809f9de3f81fbb9c5485cb0f6882b617 100644 (file)
@@ -33,7 +33,7 @@
 -behaviour(gen_mod).
 
 -export([start/2, stop/1, process_local_iq/3,
-        mod_opt_type/1]).
+        mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -86,5 +86,8 @@ process_local_iq(_From, _To,
 sign(N) when N < 0 -> <<"-">>;
 sign(_) -> <<"+">>.
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
 mod_opt_type(_) -> [iqdisc].
index 5e042528b34f8c96d7524b6a4422380219d1e291..aca9d7462ba79e40672424b2b748ed1e9d3142db 100644 (file)
@@ -34,7 +34,7 @@
 
 -export([start/2, init/3, stop/1, get_sm_features/5,
         process_local_iq/3, process_sm_iq/3, string2lower/1,
-        remove_user/2, export/1, import/1, import/3,
+        remove_user/2, export/1, import/1, import/3, depends/2,
         mod_opt_type/1, set_vcard/3, make_vcard_search/4]).
 
 -include("ejabberd.hrl").
@@ -594,6 +594,9 @@ import(LServer, DBType, VCard) ->
     Mod = gen_mod:db_mod(DBType, ?MODULE),
     Mod:import(LServer, VCard).
 
+depends(_Host, _Opts) ->
+    [].
+
 mod_opt_type(allow_return_all) ->
     fun (B) when is_boolean(B) -> B end;
 mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end;
index 46f81af096afa34394c776251ed74fb3b452c115..a0ad305a962b4b1df28628376c12e81231aa17b6 100644 (file)
@@ -40,7 +40,7 @@
 -export([start/2, start_link/2, stop/1,
         get_sm_features/5, process_local_iq/3, process_sm_iq/3,
         remove_user/1, route/4, transform_module_options/1,
-        mod_opt_type/1, opt_type/1]).
+        mod_opt_type/1, opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -138,6 +138,9 @@ stop(Host) ->
     supervisor:terminate_child(ejabberd_sup, Proc),
     supervisor:delete_child(ejabberd_sup, Proc).
 
+depends(_Host, _Opts) ->
+    [].
+
 terminate(_Reason, State) ->
     Host = State#state.serverhost,
     gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
index 041b0b64c6a36ce72332ba5296d0d373727d6e7c..f2101df912e2508dedad1966bc7b6e327cbbca6f 100644 (file)
@@ -13,7 +13,7 @@
 -export([start/2, stop/1]).
 
 -export([update_presence/3, vcard_set/3, export/1,
-        import/1, import/3, mod_opt_type/1]).
+        import/1, import/3, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -46,6 +46,9 @@ stop(Host) ->
                          vcard_set, 100),
     ok.
 
+depends(_Host, _Opts) ->
+    [].
+
 %%====================================================================
 %% Hooks
 %%====================================================================
index 7f7759f2d1e32502f0e53a6b103b203e4ae5cc33..8a035763f4f193fb9732cc027e49a542c0ec3e87 100644 (file)
@@ -32,7 +32,7 @@
 -behaviour(gen_mod).
 
 -export([start/2, stop/1, process_local_iq/3,
-        mod_opt_type/1]).
+        mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
@@ -93,6 +93,9 @@ get_os() ->
     #xmlel{name = <<"os">>, attrs = [],
           children = [{xmlcdata, OS}]}.
 
+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;
index 504e39fa3d9df6066a2359494abace1df7a2c4de..1677ed4bd681548fb427ce391aa853ca1c74294f 100644 (file)
     get_pending_nodes/2, get_states/1, get_state/2,
     set_state/1, get_items/7, get_items/3, get_item/7,
     get_item/2, set_item/1, get_item_name/3, node_to_path/1,
-    path_to_node/1]).
+    path_to_node/1, depends/3]).
+
+depends(_Host, _ServerHost, _Opts) ->
+    [{mod_caps, hard}].
 
 init(Host, ServerHost, Opts) ->
     node_flat:init(Host, ServerHost, Opts),
-    complain_if_modcaps_disabled(ServerHost),
     ok.
 
 terminate(Host, ServerHost) ->
@@ -245,21 +247,3 @@ node_to_path(Node) ->
 
 path_to_node(Path) ->
     node_flat:path_to_node(Path).
-
-%%%
-%%% Internal
-%%%
-
-%% @doc Check mod_caps is enabled, otherwise show warning.
-%% The PEP plugin for mod_pubsub requires mod_caps to be enabled in the host.
-%% Check that the mod_caps module is enabled in that Jabber Host
-%% If not, show a warning message in the ejabberd log file.
-complain_if_modcaps_disabled(ServerHost) ->
-    case gen_mod:is_loaded(ServerHost, mod_caps) of
-       false ->
-           ?WARNING_MSG("The PEP plugin is enabled in mod_pubsub "
-               "of host ~p. This plugin requires mod_caps "
-               "but it does not seems enabled, please check config.",
-               [ServerHost]);
-       true -> ok
-    end.
index 1df173fd7e7fee3d575a053ce5012d5b19b4e27e..ec77954751af766ea2fda0b6d34dc2392e46732b 100644 (file)
     get_pending_nodes/2, get_states/1, get_state/2,
     set_state/1, get_items/7, get_items/3, get_item/7,
     get_item/2, set_item/1, get_item_name/3, node_to_path/1,
-    path_to_node/1,
+    path_to_node/1, depends/3,
     get_entity_subscriptions_for_send_last/2, get_last_items/3]).
 
+depends(_Host, _ServerHost, _Opts) ->
+    [{mod_caps, hard}].
+
 init(Host, ServerHost, Opts) ->
     node_flat_sql:init(Host, ServerHost, Opts),
-    complain_if_modcaps_disabled(ServerHost),
     ok.
 
 terminate(Host, ServerHost) ->
@@ -237,21 +239,3 @@ node_to_path(Node) ->
 
 path_to_node(Path) ->
     node_flat_sql:path_to_node(Path).
-
-%%%
-%%% Internal
-%%%
-
-%% @doc Check mod_caps is enabled, otherwise show warning.
-%% The PEP plugin for mod_pubsub requires mod_caps to be enabled in the host.
-%% Check that the mod_caps module is enabled in that Jabber Host
-%% If not, show a warning message in the ejabberd log file.
-complain_if_modcaps_disabled(ServerHost) ->
-    case gen_mod:is_loaded(ServerHost, mod_caps) of
-       false ->
-           ?WARNING_MSG("The PEP plugin is enabled in mod_pubsub "
-               "of host ~p. This plugin requires mod_caps "
-               "to be enabled, but it isn't.",
-               [ServerHost]);
-       true -> ok
-    end.