diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 1cc65ac21..521ed1b3f 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -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) -> diff --git a/src/mod_adhoc.erl b/src/mod_adhoc.erl index 9e0682f7d..e12e0de1e 100644 --- a/src/mod_adhoc.erl +++ b/src/mod_adhoc.erl @@ -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; diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl index 562087d96..8f6724281 100644 --- a/src/mod_admin_extra.erl +++ b/src/mod_admin_extra.erl @@ -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 diff --git a/src/mod_announce.erl b/src/mod_announce.erl index fc57d6bd1..52ff2de92 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -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(). diff --git a/src/mod_blocking.erl b/src/mod_blocking.erl index af06e650d..818d53259 100644 --- a/src/mod_blocking.erl +++ b/src/mod_blocking.erl @@ -30,7 +30,7 @@ -protocol({xep, 191, '1.2'}). -export([start/2, stop/1, 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]}. diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 966a9baa6..3ed3149bb 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -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), diff --git a/src/mod_configure.erl b/src/mod_configure.erl index 9d4086559..97c944842 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -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), diff --git a/src/mod_configure2.erl b/src/mod_configure2.erl index a8287b4d4..85b7740d0 100644 --- a/src/mod_configure2.erl +++ b/src/mod_configure2.erl @@ -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]. diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 0d5abcb4b..2e7b80c18 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -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; diff --git a/src/mod_echo.erl b/src/mod_echo.erl index 7d9f81f82..ee904d798 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -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]. diff --git a/src/mod_fail2ban.erl b/src/mod_fail2ban.erl index f0460e704..c57ac21b0 100644 --- a/src/mod_fail2ban.erl +++ b/src/mod_fail2ban.erl @@ -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 %%%=================================================================== diff --git a/src/mod_http_api.erl b/src/mod_http_api.erl index 595c121cd..815ed3ab6 100644 --- a/src/mod_http_api.erl +++ b/src/mod_http_api.erl @@ -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 %% ---------- diff --git a/src/mod_http_bind.erl b/src/mod_http_bind.erl index 1a07867e0..9a3a379f7 100644 --- a/src/mod_http_bind.erl +++ b/src/mod_http_bind.erl @@ -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 diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl index 346dc41c8..37e02edd8 100644 --- a/src/mod_http_fileserver.erl +++ b/src/mod_http_fileserver.erl @@ -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 %%==================================================================== diff --git a/src/mod_http_upload.erl b/src/mod_http_upload.erl index a2aa75465..b166f2b66 100644 --- a/src/mod_http_upload.erl +++ b/src/mod_http_upload.erl @@ -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. %%-------------------------------------------------------------------- diff --git a/src/mod_http_upload_quota.erl b/src/mod_http_upload_quota.erl index e08cd0b91..d2eca8b72 100644 --- a/src/mod_http_upload_quota.erl +++ b/src/mod_http_upload_quota.erl @@ -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. %%-------------------------------------------------------------------- diff --git a/src/mod_ip_blacklist.erl b/src/mod_ip_blacklist.erl index a6f9f619d..4f54ecd79 100644 --- a/src/mod_ip_blacklist.erl +++ b/src/mod_ip_blacklist.erl @@ -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. diff --git a/src/mod_irc.erl b/src/mod_irc.erl index 4bcf69c3b..2206028b7 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -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 %%==================================================================== diff --git a/src/mod_last.erl b/src/mod_last.erl index 92694cf13..ce9148841 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -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]. diff --git a/src/mod_mam.erl b/src/mod_mam.erl index 18bffd909..0e79cd666 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -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), diff --git a/src/mod_metrics.erl b/src/mod_metrics.erl index 40484e488..f1d487e0e 100644 --- a/src/mod_metrics.erl +++ b/src/mod_metrics.erl @@ -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 %%==================================================================== diff --git a/src/mod_mix.erl b/src/mod_mix.erl index c0835b74e..b373ad13d 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -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]. diff --git a/src/mod_muc.erl b/src/mod_muc.erl index b46585066..e5baa37f2 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -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@">>), diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl index 5fbda4f28..0b5e79f60 100644 --- a/src/mod_muc_admin.erl +++ b/src/mod_muc_admin.erl @@ -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 %%% diff --git a/src/mod_muc_log.erl b/src/mod_muc_log.erl index 167a96e37..ec4711b43 100644 --- a/src/mod_muc_log.erl +++ b/src/mod_muc_log.erl @@ -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 %%==================================================================== diff --git a/src/mod_multicast.erl b/src/mod_multicast.erl index cbe2a4e50..df385c28c 100644 --- a/src/mod_multicast.erl +++ b/src/mod_multicast.erl @@ -40,7 +40,7 @@ -export([init/1, handle_info/2, handle_call/3, handle_cast/2, terminate/2, code_change/3]). --export([purge_loop/1, mod_opt_type/1]). +-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; diff --git a/src/mod_offline.erl b/src/mod_offline.erl index a794a0371..7b9c712fa 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -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 diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index ad13c27cd..18ff78371 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -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]. diff --git a/src/mod_private.erl b/src/mod_private.erl index 38e42ca4c..f0e4632f6 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -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]. diff --git a/src/mod_proxy65.erl b/src/mod_proxy65.erl index 2737de7ad..beea35725 100644 --- a/src/mod_proxy65.erl +++ b/src/mod_proxy65.erl @@ -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 diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index 53378c355..f9d1cde21 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -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. %%

The Erlang code for the plugin is located in a module called diff --git a/src/mod_register.erl b/src/mod_register.erl index 43499d2e5..45cd78fef 100644 --- a/src/mod_register.erl +++ b/src/mod_register.erl @@ -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, diff --git a/src/mod_register_web.erl b/src/mod_register_web.erl index 2b7e5f532..76de1677f 100644 --- a/src/mod_register_web.erl +++ b/src/mod_register_web.erl @@ -55,7 +55,7 @@ -behaviour(gen_mod). --export([start/2, stop/1, 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 %%%---------------------------------------------------------------------- diff --git a/src/mod_roster.erl b/src/mod_roster.erl index f79061560..a75041bc7 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -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); diff --git a/src/mod_service_log.erl b/src/mod_service_log.erl index 3e1da3a4e..ae264bbc9 100644 --- a/src/mod_service_log.erl +++ b/src/mod_service_log.erl @@ -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. diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 76a619c9b..b472e1aab 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -39,7 +39,7 @@ delete_group/2, get_group_opts/2, set_group_opts/3, get_group_users/2, get_group_explicit_users/2, is_user_in_group/3, add_user_to_group/3, opts_to_binary/1, - remove_user_from_group/3, mod_opt_type/1]). + 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), diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl index 34588b90c..22f50d302 100644 --- a/src/mod_shared_roster_ldap.erl +++ b/src/mod_shared_roster_ldap.erl @@ -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 %%-------------------------------------------------------------------- diff --git a/src/mod_sic.erl b/src/mod_sic.erl index b4eae0daf..49b65a0ee 100644 --- a/src/mod_sic.erl +++ b/src/mod_sic.erl @@ -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) -> diff --git a/src/mod_sip.erl b/src/mod_sip.erl index 6ffe56331..816100f47 100644 --- a/src/mod_sip.erl +++ b/src/mod_sip.erl @@ -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}}) -> diff --git a/src/mod_stats.erl b/src/mod_stats.erl index c14cf8d15..99059839a 100644 --- a/src/mod_stats.erl +++ b/src/mod_stats.erl @@ -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} = diff --git a/src/mod_time.erl b/src/mod_time.erl index 740b654a7..90296f3d8 100644 --- a/src/mod_time.erl +++ b/src/mod_time.erl @@ -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]. diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index 5e042528b..aca9d7462 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -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; diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index 46f81af09..a0ad305a9 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -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, diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl index 041b0b64c..f2101df91 100644 --- a/src/mod_vcard_xupdate.erl +++ b/src/mod_vcard_xupdate.erl @@ -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 %%==================================================================== diff --git a/src/mod_version.erl b/src/mod_version.erl index 7f7759f2d..8a035763f 100644 --- a/src/mod_version.erl +++ b/src/mod_version.erl @@ -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; diff --git a/src/node_pep.erl b/src/node_pep.erl index 504e39fa3..1677ed4bd 100644 --- a/src/node_pep.erl +++ b/src/node_pep.erl @@ -45,11 +45,13 @@ 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. diff --git a/src/node_pep_sql.erl b/src/node_pep_sql.erl index 1df173fd7..ec7795475 100644 --- a/src/node_pep_sql.erl +++ b/src/node_pep_sql.erl @@ -45,12 +45,14 @@ 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.