mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-22 16:20:52 +01:00
Reload modules when reloading configuration file
This commit is contained in:
parent
ff67860cdb
commit
3c4057ff55
@ -138,7 +138,7 @@ get_ejabberd_config_path() ->
|
|||||||
-spec get_env_config() -> {ok, string()} | undefined.
|
-spec get_env_config() -> {ok, string()} | undefined.
|
||||||
get_env_config() ->
|
get_env_config() ->
|
||||||
%% First case: the filename can be specified with: erl -config "/path/to/ejabberd.yml".
|
%% First case: the filename can be specified with: erl -config "/path/to/ejabberd.yml".
|
||||||
case application:get_env(config) of
|
case application:get_env(ejabberd, config) of
|
||||||
R = {ok, _Path} -> R;
|
R = {ok, _Path} -> R;
|
||||||
undefined ->
|
undefined ->
|
||||||
%% Second case for embbeding ejabberd in another app, for example for Elixir:
|
%% Second case for embbeding ejabberd in another app, for example for Elixir:
|
||||||
@ -194,7 +194,8 @@ load_file(File) ->
|
|||||||
|
|
||||||
reload_file() ->
|
reload_file() ->
|
||||||
Config = get_ejabberd_config_path(),
|
Config = get_ejabberd_config_path(),
|
||||||
load_file(Config).
|
load_file(Config),
|
||||||
|
ejabberd_hooks:run(config_reloaded, []).
|
||||||
|
|
||||||
-spec convert_to_yaml(file:filename()) -> ok | {error, any()}.
|
-spec convert_to_yaml(file:filename()) -> ok | {error, any()}.
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
-type component() :: ejabberd_sm | ejabberd_local.
|
-type component() :: ejabberd_sm | ejabberd_local.
|
||||||
-type type() :: no_queue | one_queue | pos_integer() | parallel.
|
-type type() :: no_queue | one_queue | pos_integer() | parallel.
|
||||||
-type opts() :: no_queue | {one_queue, pid()} | {queues, [pid()]} | parallel.
|
-type opts() :: no_queue | {one_queue, pid()} | {queues, [pid()]} | parallel.
|
||||||
-export_type([opts/0]).
|
-export_type([opts/0, type/0]).
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% API
|
%% API
|
||||||
|
111
src/gen_mod.erl
111
src/gen_mod.erl
@ -31,10 +31,10 @@
|
|||||||
-author('alexey@process-one.net').
|
-author('alexey@process-one.net').
|
||||||
|
|
||||||
-export([init/1, start_link/0, start_child/3, start_child/4,
|
-export([init/1, start_link/0, start_child/3, start_child/4,
|
||||||
stop_child/1, stop_child/2]).
|
stop_child/1, stop_child/2, config_reloaded/0]).
|
||||||
-export([start/0, start_module/2, start_module/3,
|
-export([start/0, start_module/2, start_module/3,
|
||||||
stop_module/2, stop_module_keep_config/2, get_opt/3,
|
stop_module/2, stop_module_keep_config/2, get_opt/3,
|
||||||
get_opt/4, get_opt_host/3, opt_type/1,
|
get_opt/4, get_opt_host/3, opt_type/1, is_equal_opt/5,
|
||||||
get_module_opt/4, get_module_opt/5, get_module_opt_host/3,
|
get_module_opt/4, get_module_opt/5, get_module_opt_host/3,
|
||||||
loaded_modules/1, loaded_modules_with_opts/1,
|
loaded_modules/1, loaded_modules_with_opts/1,
|
||||||
get_hosts/2, get_module_proc/2, is_loaded/2,
|
get_hosts/2, get_module_proc/2, is_loaded/2,
|
||||||
@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
-include_lib("stdlib/include/ms_transform.hrl").
|
||||||
|
|
||||||
-record(ejabberd_module,
|
-record(ejabberd_module,
|
||||||
{module_host = {undefined, <<"">>} :: {atom(), binary()},
|
{module_host = {undefined, <<"">>} :: {atom(), binary()},
|
||||||
@ -56,9 +57,12 @@
|
|||||||
|
|
||||||
-callback start(binary(), opts()) -> ok | {ok, pid()}.
|
-callback start(binary(), opts()) -> ok | {ok, pid()}.
|
||||||
-callback stop(binary()) -> any().
|
-callback stop(binary()) -> any().
|
||||||
|
-callback reload(binary(), opts(), opts()) -> ok | {ok, pid()}.
|
||||||
-callback mod_opt_type(atom()) -> fun((term()) -> term()) | [atom()].
|
-callback mod_opt_type(atom()) -> fun((term()) -> term()) | [atom()].
|
||||||
-callback depends(binary(), opts()) -> [{module(), hard | soft}].
|
-callback depends(binary(), opts()) -> [{module(), hard | soft}].
|
||||||
|
|
||||||
|
-optional_callbacks([reload/3]).
|
||||||
|
|
||||||
-export_type([opts/0]).
|
-export_type([opts/0]).
|
||||||
-export_type([db_type/0]).
|
-export_type([db_type/0]).
|
||||||
|
|
||||||
@ -75,6 +79,7 @@ start_link() ->
|
|||||||
supervisor:start_link({local, ejabberd_gen_mod_sup}, ?MODULE, []).
|
supervisor:start_link({local, ejabberd_gen_mod_sup}, ?MODULE, []).
|
||||||
|
|
||||||
init([]) ->
|
init([]) ->
|
||||||
|
ejabberd_hooks:add(config_reloaded, ?MODULE, config_reloaded, 50),
|
||||||
ets:new(ejabberd_modules,
|
ets:new(ejabberd_modules,
|
||||||
[named_table, public,
|
[named_table, public,
|
||||||
{keypos, #ejabberd_module.module_host}]),
|
{keypos, #ejabberd_module.module_host}]),
|
||||||
@ -182,9 +187,7 @@ start_module(Host, Module) ->
|
|||||||
start_module(Host, Module, Opts0) ->
|
start_module(Host, Module, Opts0) ->
|
||||||
?DEBUG("loading ~s at ~s", [Module, Host]),
|
?DEBUG("loading ~s at ~s", [Module, Host]),
|
||||||
Opts = validate_opts(Module, Opts0),
|
Opts = validate_opts(Module, Opts0),
|
||||||
ets:insert(ejabberd_modules,
|
store_options(Host, Module, Opts),
|
||||||
#ejabberd_module{module_host = {Module, Host},
|
|
||||||
opts = Opts}),
|
|
||||||
try case Module:start(Host, Opts) of
|
try case Module:start(Host, Opts) of
|
||||||
ok -> ok;
|
ok -> ok;
|
||||||
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
|
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
|
||||||
@ -202,6 +205,77 @@ start_module(Host, Module, Opts0) ->
|
|||||||
erlang:raise(Class, Reason, erlang:get_stacktrace())
|
erlang:raise(Class, Reason, erlang:get_stacktrace())
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec reload_modules(binary()) -> ok.
|
||||||
|
reload_modules(Host) ->
|
||||||
|
NewMods = ejabberd_config:get_option(
|
||||||
|
{modules, Host}, opt_type(modules), []),
|
||||||
|
OldMods = ets:select(
|
||||||
|
ejabberd_modules,
|
||||||
|
ets:fun2ms(
|
||||||
|
fun(#ejabberd_module{module_host = {M, H}, opts = O})
|
||||||
|
when H == Host -> {M, O}
|
||||||
|
end)),
|
||||||
|
lists:foreach(
|
||||||
|
fun({Mod, _Opts}) ->
|
||||||
|
case lists:keymember(Mod, 1, NewMods) of
|
||||||
|
false ->
|
||||||
|
stop_module(Host, Mod);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end
|
||||||
|
end, OldMods),
|
||||||
|
lists:foreach(
|
||||||
|
fun({Mod, Opts}) ->
|
||||||
|
case lists:keymember(Mod, 1, OldMods) of
|
||||||
|
false ->
|
||||||
|
start_module(Host, Mod, Opts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end
|
||||||
|
end, NewMods),
|
||||||
|
lists:foreach(
|
||||||
|
fun({Mod, OldOpts}) ->
|
||||||
|
case lists:keyfind(Mod, 1, NewMods) of
|
||||||
|
{_, NewOpts} when NewOpts /= OldOpts ->
|
||||||
|
reload_module(Host, Mod, NewOpts, OldOpts);
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end
|
||||||
|
end, OldMods).
|
||||||
|
|
||||||
|
-spec reload_module(binary(), module(), opts(), opts()) -> ok | {ok, pid()}.
|
||||||
|
reload_module(Host, Module, NewOpts0, OldOpts) ->
|
||||||
|
case erlang:function_exported(Module, reload, 3) of
|
||||||
|
true ->
|
||||||
|
?DEBUG("reloading ~s at ~s", [Module, Host]),
|
||||||
|
NewOpts = validate_opts(Module, NewOpts0),
|
||||||
|
store_options(Host, Module, NewOpts),
|
||||||
|
try case Module:reload(Host, NewOpts, OldOpts) of
|
||||||
|
ok -> ok;
|
||||||
|
{ok, Pid} when is_pid(Pid) -> {ok, Pid};
|
||||||
|
Err -> erlang:error(Err)
|
||||||
|
end
|
||||||
|
catch Class:Reason ->
|
||||||
|
StackTrace = erlang:get_stacktrace(),
|
||||||
|
?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 "
|
||||||
|
"and will be restarted", [Module]),
|
||||||
|
stop_module(Host, Module),
|
||||||
|
start_module(Host, Module, NewOpts0)
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec store_options(binary(), module(), opts()) -> true.
|
||||||
|
store_options(Host, Module, Opts) ->
|
||||||
|
ets:insert(ejabberd_modules,
|
||||||
|
#ejabberd_module{module_host = {Module, Host},
|
||||||
|
opts = Opts}).
|
||||||
|
|
||||||
maybe_halt_ejabberd(ErrorText) ->
|
maybe_halt_ejabberd(ErrorText) ->
|
||||||
case is_app_running(ejabberd) of
|
case is_app_running(ejabberd) of
|
||||||
false ->
|
false ->
|
||||||
@ -239,6 +313,7 @@ stop_modules(Host) ->
|
|||||||
-spec stop_module(binary(), atom()) -> error | {aborted, any()} | {atomic, any()}.
|
-spec stop_module(binary(), atom()) -> error | {aborted, any()} | {atomic, any()}.
|
||||||
|
|
||||||
stop_module(Host, Module) ->
|
stop_module(Host, Module) ->
|
||||||
|
?DEBUG("stopping ~s at ~s", [Module, Host]),
|
||||||
case stop_module_keep_config(Host, Module) of
|
case stop_module_keep_config(Host, Module) of
|
||||||
error -> error;
|
error -> error;
|
||||||
ok -> ok
|
ok -> ok
|
||||||
@ -544,5 +619,29 @@ get_module_proc(Host, Base) ->
|
|||||||
is_loaded(Host, Module) ->
|
is_loaded(Host, Module) ->
|
||||||
ets:member(ejabberd_modules, {Module, Host}).
|
ets:member(ejabberd_modules, {Module, Host}).
|
||||||
|
|
||||||
opt_type(modules) -> fun (L) when is_list(L) -> L end;
|
-spec config_reloaded() -> ok.
|
||||||
|
config_reloaded() ->
|
||||||
|
lists:foreach(
|
||||||
|
fun(Host) ->
|
||||||
|
reload_modules(Host)
|
||||||
|
end, ?MYHOSTS).
|
||||||
|
|
||||||
|
-spec is_equal_opt(atom(), opts(), opts(), check_fun(), any()) ->
|
||||||
|
true | {false, any(), any()}.
|
||||||
|
is_equal_opt(Opt, NewOpts, OldOpts, VFun, Default) ->
|
||||||
|
NewVal = get_opt(Opt, NewOpts, VFun, Default),
|
||||||
|
OldVal = get_opt(Opt, OldOpts, VFun, Default),
|
||||||
|
if NewVal /= OldVal ->
|
||||||
|
{false, NewVal, OldVal};
|
||||||
|
true ->
|
||||||
|
true
|
||||||
|
end.
|
||||||
|
|
||||||
|
opt_type(modules) ->
|
||||||
|
fun(Mods) ->
|
||||||
|
lists:map(
|
||||||
|
fun({M, A}) when is_atom(M), is_list(A) ->
|
||||||
|
{M, A}
|
||||||
|
end, Mods)
|
||||||
|
end;
|
||||||
opt_type(_) -> [modules].
|
opt_type(_) -> [modules].
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_local_iq/1,
|
-export([start/2, stop/1, reload/3, process_local_iq/1,
|
||||||
process_sm_iq/1, get_local_commands/5,
|
process_sm_iq/1, get_local_commands/5,
|
||||||
get_local_identity/5, get_local_features/5,
|
get_local_identity/5, get_local_features/5,
|
||||||
get_sm_commands/5, get_sm_identity/5, get_sm_features/5,
|
get_sm_commands/5, get_sm_identity/5, get_sm_features/5,
|
||||||
@ -88,6 +88,19 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
||||||
?NS_COMMANDS).
|
?NS_COMMANDS).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
|
||||||
|
?MODULE, process_local_iq, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_COMMANDS,
|
||||||
|
?MODULE, process_sm_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
%-------------------------------------------------------------------------
|
%-------------------------------------------------------------------------
|
||||||
|
|
||||||
get_local_commands(Acc, _From,
|
get_local_commands(Acc, _From,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
|
|
||||||
-export([start/2, stop/1, mod_opt_type/1,
|
-export([start/2, stop/1, reload/3, mod_opt_type/1,
|
||||||
get_commands_spec/0, depends/2]).
|
get_commands_spec/0, depends/2]).
|
||||||
|
|
||||||
% Commands API
|
% Commands API
|
||||||
@ -96,6 +96,9 @@ start(_Host, _Opts) ->
|
|||||||
stop(_Host) ->
|
stop(_Host) ->
|
||||||
ejabberd_commands:unregister_commands(get_commands_spec()).
|
ejabberd_commands:unregister_commands(get_commands_spec()).
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, export/1, import_info/0,
|
-export([start/2, stop/1, reload/3, export/1, import_info/0,
|
||||||
import_start/2, import/5, announce/1, send_motd/1, disco_identity/5,
|
import_start/2, import/5, announce/1, send_motd/1, disco_identity/5,
|
||||||
disco_features/5, disco_items/5, depends/2,
|
disco_features/5, disco_items/5, depends/2,
|
||||||
send_announcement_to_all/3, announce_commands/4,
|
send_announcement_to_all/3, announce_commands/4,
|
||||||
@ -80,6 +80,16 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[{mod_adhoc, hard}].
|
[{mod_adhoc, hard}].
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1,
|
-export([start/2, stop/1, reload/3,
|
||||||
depends/2, mod_opt_type/1]).
|
depends/2, mod_opt_type/1]).
|
||||||
|
|
||||||
-export([filter_packet/1]).
|
-export([filter_packet/1]).
|
||||||
@ -50,6 +50,9 @@ stop(Host) ->
|
|||||||
?MODULE, filter_packet, 25),
|
?MODULE, filter_packet, 25),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
filter_packet({#message{} = Msg, State} = Acc) ->
|
filter_packet({#message{} = Msg, State} = Acc) ->
|
||||||
From = xmpp:get_from(Msg),
|
From = xmpp:get_from(Msg),
|
||||||
LFrom = jid:tolower(From),
|
LFrom = jid:tolower(From),
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
-protocol({xep, 191, '1.2'}).
|
-protocol({xep, 191, '1.2'}).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_iq/1, mod_opt_type/1, depends/2,
|
-export([start/2, stop/1, reload/3, process_iq/1, mod_opt_type/1, depends/2,
|
||||||
disco_features/5]).
|
disco_features/5]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -56,6 +56,17 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50),
|
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING).
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_BLOCKING,
|
||||||
|
?MODULE, process_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[{mod_privacy, hard}].
|
[{mod_privacy, hard}].
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start_link/0]).
|
-export([start_link/0]).
|
||||||
-export([start/2, stop/1, process/2, open_session/2,
|
-export([start/2, stop/1, reload/3, process/2, open_session/2,
|
||||||
close_session/1, find_session/1]).
|
close_session/1, find_session/1]).
|
||||||
|
|
||||||
-export([depends/2, mod_opt_type/1]).
|
-export([depends/2, mod_opt_type/1]).
|
||||||
@ -103,6 +103,12 @@ stop(Host) ->
|
|||||||
supervisor:terminate_child(ejabberd_sup, TmpSup),
|
supervisor:terminate_child(ejabberd_sup, TmpSup),
|
||||||
supervisor:delete_child(ejabberd_sup, TmpSup).
|
supervisor:delete_child(ejabberd_sup, TmpSup).
|
||||||
|
|
||||||
|
reload(_Host, NewOpts, _OldOpts) ->
|
||||||
|
start_jiffy(NewOpts),
|
||||||
|
Mod = gen_mod:ram_db_mod(global, ?MODULE),
|
||||||
|
Mod:init(),
|
||||||
|
ok.
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
get_user_caps/2, import_start/2, import_stop/2]).
|
get_user_caps/2, import_start/2, import_stop/2]).
|
||||||
|
|
||||||
%% gen_mod callbacks
|
%% gen_mod callbacks
|
||||||
-export([start/2, stop/1, depends/2]).
|
-export([start/2, stop/1, reload/3, depends/2]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, handle_info/2, handle_call/3,
|
-export([init/1, handle_info/2, handle_call/3,
|
||||||
@ -238,6 +238,31 @@ c2s_presence_in(C2SState,
|
|||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if OldMod /= NewMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(cache_size, NewOpts, OldOpts,
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end,
|
||||||
|
1000) of
|
||||||
|
{false, MaxSize, _} ->
|
||||||
|
cache_tab:setopts(caps_features, [{max_size, MaxSize}]);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(cache_life_time, NewOpts, OldOpts,
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end,
|
||||||
|
timer:hours(24) div 1000) of
|
||||||
|
{false, LifeTime, _} ->
|
||||||
|
cache_tab:setopts(caps_features, [{life_time, LifeTime}]);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
|
@ -32,8 +32,7 @@
|
|||||||
-behavior(gen_mod).
|
-behavior(gen_mod).
|
||||||
|
|
||||||
%% API:
|
%% API:
|
||||||
-export([start/2,
|
-export([start/2, stop/1, reload/3]).
|
||||||
stop/1]).
|
|
||||||
|
|
||||||
-export([user_send_packet/1, user_receive_packet/1,
|
-export([user_send_packet/1, user_receive_packet/1,
|
||||||
iq_handler/1, remove_connection/4, disco_features/5,
|
iq_handler/1, remove_connection/4, disco_features/5,
|
||||||
@ -75,6 +74,24 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(user_receive_packet,Host, ?MODULE, user_receive_packet, 89),
|
ejabberd_hooks:delete(user_receive_packet,Host, ?MODULE, user_receive_packet, 89),
|
||||||
ejabberd_hooks:delete(unset_presence_hook,Host, ?MODULE, remove_connection, 10).
|
ejabberd_hooks:delete(unset_presence_hook,Host, ?MODULE, remove_connection, 10).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_CARBONS_2,
|
||||||
|
?MODULE, iq_handler, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
-spec disco_features({error, stanza_error()} | {result, [binary()]} | empty,
|
-spec disco_features({error, stanza_error()} | {result, [binary()]} | empty,
|
||||||
jid(), jid(), binary(), binary()) ->
|
jid(), jid(), binary(), binary()) ->
|
||||||
{error, stanza_error()} | {result, [binary()]}.
|
{error, stanza_error()} | {result, [binary()]}.
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
-behavior(gen_mod).
|
-behavior(gen_mod).
|
||||||
|
|
||||||
%% gen_mod callbacks.
|
%% gen_mod callbacks.
|
||||||
-export([start/2, stop/1, mod_opt_type/1, depends/2]).
|
-export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
%% ejabberd_hooks callbacks.
|
%% ejabberd_hooks callbacks.
|
||||||
-export([filter_presence/1, filter_chat_states/1,
|
-export([filter_presence/1, filter_chat_states/1,
|
||||||
@ -72,16 +72,7 @@ start(Host, Opts) ->
|
|||||||
fun(B) when is_boolean(B) -> B end,
|
fun(B) when is_boolean(B) -> B end,
|
||||||
true),
|
true),
|
||||||
if QueuePresence; QueueChatStates; QueuePEP ->
|
if QueuePresence; QueueChatStates; QueuePEP ->
|
||||||
ejabberd_hooks:add(c2s_stream_started, Host, ?MODULE,
|
register_hooks(Host),
|
||||||
c2s_stream_started, 50),
|
|
||||||
ejabberd_hooks:add(c2s_post_auth_features, Host, ?MODULE,
|
|
||||||
add_stream_feature, 50),
|
|
||||||
ejabberd_hooks:add(c2s_authenticated_packet, Host, ?MODULE,
|
|
||||||
c2s_authenticated_packet, 50),
|
|
||||||
ejabberd_hooks:add(c2s_copy_session, Host, ?MODULE,
|
|
||||||
c2s_copy_session, 50),
|
|
||||||
ejabberd_hooks:add(c2s_session_resumed, Host, ?MODULE,
|
|
||||||
c2s_session_resumed, 50),
|
|
||||||
if QueuePresence ->
|
if QueuePresence ->
|
||||||
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
||||||
filter_presence, 50);
|
filter_presence, 50);
|
||||||
@ -96,9 +87,7 @@ start(Host, Opts) ->
|
|||||||
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
||||||
filter_pep, 50);
|
filter_pep, 50);
|
||||||
true -> ok
|
true -> ok
|
||||||
end,
|
end;
|
||||||
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
|
||||||
filter_other, 75);
|
|
||||||
true -> ok
|
true -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -118,16 +107,7 @@ stop(Host) ->
|
|||||||
fun(B) when is_boolean(B) -> B end,
|
fun(B) when is_boolean(B) -> B end,
|
||||||
true),
|
true),
|
||||||
if QueuePresence; QueueChatStates; QueuePEP ->
|
if QueuePresence; QueueChatStates; QueuePEP ->
|
||||||
ejabberd_hooks:delete(c2s_stream_started, Host, ?MODULE,
|
unregister_hooks(Host),
|
||||||
c2s_stream_started, 50),
|
|
||||||
ejabberd_hooks:delete(c2s_post_auth_features, Host, ?MODULE,
|
|
||||||
add_stream_feature, 50),
|
|
||||||
ejabberd_hooks:delete(c2s_authenticated_packet, Host, ?MODULE,
|
|
||||||
c2s_authenticated_packet, 50),
|
|
||||||
ejabberd_hooks:delete(c2s_copy_session, Host, ?MODULE,
|
|
||||||
c2s_copy_session, 50),
|
|
||||||
ejabberd_hooks:delete(c2s_session_resumed, Host, ?MODULE,
|
|
||||||
c2s_session_resumed, 50),
|
|
||||||
if QueuePresence ->
|
if QueuePresence ->
|
||||||
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
||||||
filter_presence, 50);
|
filter_presence, 50);
|
||||||
@ -142,12 +122,48 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
||||||
filter_pep, 50);
|
filter_pep, 50);
|
||||||
true -> ok
|
true -> ok
|
||||||
end,
|
end;
|
||||||
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
|
||||||
filter_other, 75);
|
|
||||||
true -> ok
|
true -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec reload(binary(), gen_mod:opts(), gen_mod:opts()) -> ok.
|
||||||
|
reload(Host, NewOpts, _OldOpts) ->
|
||||||
|
QueuePresence = gen_mod:get_opt(queue_presence, NewOpts,
|
||||||
|
fun(B) when is_boolean(B) -> B end,
|
||||||
|
true),
|
||||||
|
QueueChatStates = gen_mod:get_opt(queue_chat_states, NewOpts,
|
||||||
|
fun(B) when is_boolean(B) -> B end,
|
||||||
|
true),
|
||||||
|
QueuePEP = gen_mod:get_opt(queue_pep, NewOpts,
|
||||||
|
fun(B) when is_boolean(B) -> B end,
|
||||||
|
true),
|
||||||
|
if QueuePresence; QueueChatStates; QueuePEP ->
|
||||||
|
register_hooks(Host);
|
||||||
|
true ->
|
||||||
|
unregister_hooks(Host)
|
||||||
|
end,
|
||||||
|
if QueuePresence ->
|
||||||
|
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
||||||
|
filter_presence, 50);
|
||||||
|
true ->
|
||||||
|
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
||||||
|
filter_presence, 50)
|
||||||
|
end,
|
||||||
|
if QueueChatStates ->
|
||||||
|
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
||||||
|
filter_chat_states, 50);
|
||||||
|
true ->
|
||||||
|
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
||||||
|
filter_chat_states, 50)
|
||||||
|
end,
|
||||||
|
if QueuePEP ->
|
||||||
|
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
||||||
|
filter_pep, 50);
|
||||||
|
true ->
|
||||||
|
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
||||||
|
filter_pep, 50)
|
||||||
|
end.
|
||||||
|
|
||||||
-spec mod_opt_type(atom()) -> fun((term()) -> term()) | [atom()].
|
-spec mod_opt_type(atom()) -> fun((term()) -> term()) | [atom()].
|
||||||
|
|
||||||
mod_opt_type(queue_presence) ->
|
mod_opt_type(queue_presence) ->
|
||||||
@ -163,6 +179,36 @@ mod_opt_type(_) -> [queue_presence, queue_chat_states, queue_pep].
|
|||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
-spec register_hooks(binary()) -> ok.
|
||||||
|
register_hooks(Host) ->
|
||||||
|
ejabberd_hooks:add(c2s_stream_started, Host, ?MODULE,
|
||||||
|
c2s_stream_started, 50),
|
||||||
|
ejabberd_hooks:add(c2s_post_auth_features, Host, ?MODULE,
|
||||||
|
add_stream_feature, 50),
|
||||||
|
ejabberd_hooks:add(c2s_authenticated_packet, Host, ?MODULE,
|
||||||
|
c2s_authenticated_packet, 50),
|
||||||
|
ejabberd_hooks:add(c2s_copy_session, Host, ?MODULE,
|
||||||
|
c2s_copy_session, 50),
|
||||||
|
ejabberd_hooks:add(c2s_session_resumed, Host, ?MODULE,
|
||||||
|
c2s_session_resumed, 50),
|
||||||
|
ejabberd_hooks:add(c2s_filter_send, Host, ?MODULE,
|
||||||
|
filter_other, 75).
|
||||||
|
|
||||||
|
-spec unregister_hooks(binary()) -> ok.
|
||||||
|
unregister_hooks(Host) ->
|
||||||
|
ejabberd_hooks:delete(c2s_stream_started, Host, ?MODULE,
|
||||||
|
c2s_stream_started, 50),
|
||||||
|
ejabberd_hooks:delete(c2s_post_auth_features, Host, ?MODULE,
|
||||||
|
add_stream_feature, 50),
|
||||||
|
ejabberd_hooks:delete(c2s_authenticated_packet, Host, ?MODULE,
|
||||||
|
c2s_authenticated_packet, 50),
|
||||||
|
ejabberd_hooks:delete(c2s_copy_session, Host, ?MODULE,
|
||||||
|
c2s_copy_session, 50),
|
||||||
|
ejabberd_hooks:delete(c2s_session_resumed, Host, ?MODULE,
|
||||||
|
c2s_session_resumed, 50),
|
||||||
|
ejabberd_hooks:delete(c2s_filter_send, Host, ?MODULE,
|
||||||
|
filter_other, 75).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% ejabberd_hooks callbacks.
|
%% ejabberd_hooks callbacks.
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, get_local_identity/5,
|
-export([start/2, stop/1, reload/3, get_local_identity/5,
|
||||||
get_local_features/5, get_local_items/5,
|
get_local_features/5, get_local_items/5,
|
||||||
adhoc_local_items/4, adhoc_local_commands/4,
|
adhoc_local_items/4, adhoc_local_commands/4,
|
||||||
get_sm_identity/5, get_sm_features/5, get_sm_items/5,
|
get_sm_identity/5, get_sm_features/5, get_sm_items/5,
|
||||||
@ -89,11 +89,10 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(disco_local_features, Host,
|
ejabberd_hooks:delete(disco_local_features, Host,
|
||||||
?MODULE, get_local_features, 50),
|
?MODULE, get_local_features, 50),
|
||||||
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE,
|
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE,
|
||||||
get_local_items, 50),
|
get_local_items, 50).
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
|
||||||
?NS_COMMANDS),
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
ok.
|
||||||
?NS_COMMANDS).
|
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[{mod_adhoc, hard}, {mod_last, soft}].
|
[{mod_adhoc, hard}, {mod_last, soft}].
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, mod_opt_type/1, depends/2]).
|
-export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2]).
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
terminate/2, code_change/3]).
|
terminate/2, code_change/3]).
|
||||||
@ -57,6 +57,9 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
|
mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1;
|
||||||
mod_opt_type(namespaces) -> validate_fun();
|
mod_opt_type(namespaces) -> validate_fun();
|
||||||
mod_opt_type(_) ->
|
mod_opt_type(_) ->
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_local_iq_items/1,
|
-export([start/2, stop/1, reload/3, process_local_iq_items/1,
|
||||||
process_local_iq_info/1, get_local_identity/5,
|
process_local_iq_info/1, get_local_identity/5,
|
||||||
get_local_features/5, get_local_services/5,
|
get_local_features/5, get_local_services/5,
|
||||||
process_sm_iq_items/1, process_sm_iq_info/1,
|
process_sm_iq_items/1, process_sm_iq_info/1,
|
||||||
@ -118,10 +118,51 @@ stop(Host) ->
|
|||||||
{{'_', Host}}),
|
{{'_', Host}}),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
case gen_mod:is_equal_opt(extra_domains, NewOpts, OldOpts,
|
||||||
|
fun(Hs) ->
|
||||||
|
[iolist_to_binary(H) || H <- Hs]
|
||||||
|
end, []) of
|
||||||
|
{false, NewDomains, OldDomains} ->
|
||||||
|
lists:foreach(
|
||||||
|
fun(Domain) ->
|
||||||
|
register_extra_domain(Host, Domain)
|
||||||
|
end, NewDomains -- OldDomains),
|
||||||
|
lists:foreach(
|
||||||
|
fun(Domain) ->
|
||||||
|
unregister_extra_domain(Host, Domain)
|
||||||
|
end, OldDomains -- NewDomains);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
|
?NS_DISCO_ITEMS, ?MODULE,
|
||||||
|
process_local_iq_items, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
||||||
|
?NS_DISCO_INFO, ?MODULE,
|
||||||
|
process_local_iq_info, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
||||||
|
?NS_DISCO_ITEMS, ?MODULE, process_sm_iq_items,
|
||||||
|
IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
||||||
|
?NS_DISCO_INFO, ?MODULE, process_sm_iq_info,
|
||||||
|
IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
-spec register_extra_domain(binary(), binary()) -> true.
|
-spec register_extra_domain(binary(), binary()) -> true.
|
||||||
register_extra_domain(Host, Domain) ->
|
register_extra_domain(Host, Domain) ->
|
||||||
ets:insert(disco_extra_domains, {{Domain, Host}}).
|
ets:insert(disco_extra_domains, {{Domain, Host}}).
|
||||||
|
|
||||||
|
-spec unregister_extra_domain(binary(), binary()) -> true.
|
||||||
|
unregister_extra_domain(Host, Domain) ->
|
||||||
|
ets:delete_object(disco_extra_domains, {{Domain, Host}}).
|
||||||
|
|
||||||
-spec process_local_iq_items(iq()) -> iq().
|
-spec process_local_iq_items(iq()) -> iq().
|
||||||
process_local_iq_items(#iq{type = set, lang = Lang} = IQ) ->
|
process_local_iq_items(#iq{type = set, lang = Lang} = IQ) ->
|
||||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, do_client_version/3]).
|
-export([start/2, stop/1, reload/3, do_client_version/3]).
|
||||||
|
|
||||||
-export([init/1, handle_call/3, handle_cast/2,
|
-export([init/1, handle_call/3, handle_cast/2,
|
||||||
handle_info/2, terminate/2, code_change/3,
|
handle_info/2, terminate/2, code_change/3,
|
||||||
@ -54,6 +54,10 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||||
|
gen_server:cast(Proc, {reload, Host, NewOpts, OldOpts}).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
@ -96,7 +100,21 @@ handle_call(stop, _From, State) ->
|
|||||||
%% {stop, Reason, State}
|
%% {stop, Reason, State}
|
||||||
%% Description: Handling cast messages
|
%% Description: Handling cast messages
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
handle_cast(_Msg, State) -> {noreply, State}.
|
handle_cast({reload, Host, NewOpts, OldOpts}, State) ->
|
||||||
|
NewMyHost = gen_mod:get_opt_host(Host, NewOpts,
|
||||||
|
<<"echo.@HOST@">>),
|
||||||
|
OldMyHost = gen_mod:get_opt_host(Host, OldOpts,
|
||||||
|
<<"echo.@HOST@">>),
|
||||||
|
if NewMyHost /= OldMyHost ->
|
||||||
|
ejabberd_router:register_route(NewMyHost, Host),
|
||||||
|
ejabberd_router:unregister_route(OldMyHost);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
{noreply, State#state{host = NewMyHost}};
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Function: handle_info(Info, State) -> {noreply, State} |
|
%% Function: handle_info(Info, State) -> {noreply, State} |
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, c2s_auth_result/3,
|
-export([start/2, stop/1, reload/3, c2s_auth_result/3,
|
||||||
c2s_stream_started/2]).
|
c2s_stream_started/2]).
|
||||||
|
|
||||||
-export([init/1, handle_call/3, handle_cast/2,
|
-export([init/1, handle_call/3, handle_cast/2,
|
||||||
@ -111,6 +111,9 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process/2, mod_opt_type/1, depends/2]).
|
-export([start/2, stop/1, reload/3, process/2, mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
@ -125,6 +125,10 @@ stop(_Host) ->
|
|||||||
ejabberd_access_permissions:unregister_permission_addon(?MODULE),
|
ejabberd_access_permissions:unregister_permission_addon(?MODULE),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
reload(Host, NewOpts, _OldOpts) ->
|
||||||
|
stop(Host),
|
||||||
|
start(Host, NewOpts).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
|
|
||||||
%% gen_mod callbacks
|
%% gen_mod callbacks
|
||||||
-export([start/2, stop/1]).
|
-export([start/2, stop/1, reload/3]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
@ -90,6 +90,10 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
Proc = get_proc_name(Host),
|
||||||
|
gen_server:cast(Proc, {reload, Host, NewOpts, OldOpts}).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
@ -105,19 +109,9 @@ depends(_Host, _Opts) ->
|
|||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
try initialize(Host, Opts) of
|
try initialize(Host, Opts) of
|
||||||
{DocRoot, AccessLog, AccessLogFD, DirectoryIndices,
|
State ->
|
||||||
CustomHeaders, DefaultContentType, ContentTypes,
|
|
||||||
UserAccess} ->
|
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
{ok, #state{host = Host,
|
{ok, State}
|
||||||
accesslog = AccessLog,
|
|
||||||
accesslogfd = AccessLogFD,
|
|
||||||
docroot = DocRoot,
|
|
||||||
directory_indices = DirectoryIndices,
|
|
||||||
custom_headers = CustomHeaders,
|
|
||||||
default_content_type = DefaultContentType,
|
|
||||||
content_types = ContentTypes,
|
|
||||||
user_access = UserAccess}}
|
|
||||||
catch
|
catch
|
||||||
throw:Reason ->
|
throw:Reason ->
|
||||||
{stop, Reason}
|
{stop, Reason}
|
||||||
@ -163,9 +157,15 @@ initialize(Host, Opts) ->
|
|||||||
?INFO_MSG("known content types: ~s",
|
?INFO_MSG("known content types: ~s",
|
||||||
[str:join([[$*, K, " -> ", V] || {K, V} <- ContentTypes],
|
[str:join([[$*, K, " -> ", V] || {K, V} <- ContentTypes],
|
||||||
<<", ">>)]),
|
<<", ">>)]),
|
||||||
{DocRoot, AccessLog, AccessLogFD, DirectoryIndices,
|
#state{host = Host,
|
||||||
CustomHeaders, DefaultContentType, ContentTypes, UserAccess}.
|
accesslog = AccessLog,
|
||||||
|
accesslogfd = AccessLogFD,
|
||||||
|
docroot = DocRoot,
|
||||||
|
directory_indices = DirectoryIndices,
|
||||||
|
custom_headers = CustomHeaders,
|
||||||
|
default_content_type = DefaultContentType,
|
||||||
|
content_types = ContentTypes,
|
||||||
|
user_access = UserAccess}.
|
||||||
|
|
||||||
%% @spec (AdminCTs::[CT], Default::[CT]) -> [CT]
|
%% @spec (AdminCTs::[CT], Default::[CT]) -> [CT]
|
||||||
%% where CT = {Extension::string(), Value}
|
%% where CT = {Extension::string(), Value}
|
||||||
@ -251,7 +251,16 @@ handle_cast({add_to_log, FileSize, Code, Request}, State) ->
|
|||||||
handle_cast(reopen_log, State) ->
|
handle_cast(reopen_log, State) ->
|
||||||
FD2 = reopen_log(State#state.accesslog, State#state.accesslogfd),
|
FD2 = reopen_log(State#state.accesslog, State#state.accesslogfd),
|
||||||
{noreply, State#state{accesslogfd = FD2}};
|
{noreply, State#state{accesslogfd = FD2}};
|
||||||
handle_cast(_Msg, State) ->
|
handle_cast({reload, Host, NewOpts, _OldOpts}, OldState) ->
|
||||||
|
try initialize(Host, NewOpts) of
|
||||||
|
NewState ->
|
||||||
|
FD = reopen_log(NewState#state.accesslog, OldState#state.accesslogfd),
|
||||||
|
{noreply, NewState#state{accesslogfd = FD}}
|
||||||
|
catch throw:_ ->
|
||||||
|
{noreply, OldState}
|
||||||
|
end;
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, export/1, import/1,
|
-export([start/2, stop/1, reload/3, export/1, import/1,
|
||||||
import/3, closed_connection/3, get_connection_params/3,
|
import/3, closed_connection/3, get_connection_params/3,
|
||||||
data_to_binary/2, process_disco_info/1, process_disco_items/1,
|
data_to_binary/2, process_disco_info/1, process_disco_items/1,
|
||||||
process_register/1, process_vcard/1, process_command/1]).
|
process_register/1, process_vcard/1, process_command/1]).
|
||||||
@ -78,6 +78,10 @@ stop(Host) ->
|
|||||||
stop_supervisor(Host),
|
stop_supervisor(Host),
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||||
|
gen_server:cast(Proc, {reload, Host, NewOpts, OldOpts}).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
@ -107,16 +111,7 @@ init([Host, Opts]) ->
|
|||||||
{keypos, #irc_connection.jid_server_host}]),
|
{keypos, #irc_connection.jid_server_host}]),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
||||||
one_queue),
|
one_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO,
|
register_hooks(MyHost, IQDisc),
|
||||||
?MODULE, process_disco_info, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS,
|
|
||||||
?MODULE, process_disco_items, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_REGISTER,
|
|
||||||
?MODULE, process_register, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD,
|
|
||||||
?MODULE, process_vcard, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_COMMANDS,
|
|
||||||
?MODULE, process_command, IQDisc),
|
|
||||||
ejabberd_router:register_route(MyHost, Host),
|
ejabberd_router:register_route(MyHost, Host),
|
||||||
{ok,
|
{ok,
|
||||||
#state{host = MyHost, server_host = Host,
|
#state{host = MyHost, server_host = Host,
|
||||||
@ -140,7 +135,44 @@ handle_call(stop, _From, State) ->
|
|||||||
%% {stop, Reason, State}
|
%% {stop, Reason, State}
|
||||||
%% Description: Handling cast messages
|
%% Description: Handling cast messages
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
handle_cast(_Msg, State) -> {noreply, State}.
|
handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
|
||||||
|
NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"irc.@HOST@">>),
|
||||||
|
OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"irc.@HOST@">>),
|
||||||
|
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue),
|
||||||
|
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue),
|
||||||
|
NewMod = gen_mod:db_mod(ServerHost, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(ServerHost, OldOpts, ?MODULE),
|
||||||
|
Access = gen_mod:get_opt(access, NewOpts,
|
||||||
|
fun acl:access_rules_validator/1,
|
||||||
|
all),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(ServerHost, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) ->
|
||||||
|
register_hooks(NewHost, NewIQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
if NewHost /= OldHost ->
|
||||||
|
ejabberd_router:register_route(NewHost, ServerHost),
|
||||||
|
ejabberd_router:unregister_route(OldHost),
|
||||||
|
unregister_hooks(OldHost);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
Access = gen_mod:get_opt(access, NewOpts,
|
||||||
|
fun acl:access_rules_validator/1,
|
||||||
|
all),
|
||||||
|
{noreply, State#state{host = NewHost, access = Access}};
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Function: handle_info(Info, State) -> {noreply, State} |
|
%% Function: handle_info(Info, State) -> {noreply, State} |
|
||||||
@ -168,11 +200,7 @@ handle_info(_Info, State) -> {noreply, State}.
|
|||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
terminate(_Reason, #state{host = MyHost}) ->
|
terminate(_Reason, #state{host = MyHost}) ->
|
||||||
ejabberd_router:unregister_route(MyHost),
|
ejabberd_router:unregister_route(MyHost),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO),
|
unregister_hooks(MyHost).
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_REGISTER),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_COMMANDS).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
|
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
|
||||||
@ -183,6 +211,25 @@ code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
|||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
register_hooks(Host, IQDisc) ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
|
||||||
|
?MODULE, process_disco_info, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
|
||||||
|
?MODULE, process_disco_items, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER,
|
||||||
|
?MODULE, process_register, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
|
||||||
|
?MODULE, process_vcard, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_COMMANDS,
|
||||||
|
?MODULE, process_command, IQDisc).
|
||||||
|
|
||||||
|
unregister_hooks(Host) ->
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_REGISTER),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_COMMANDS).
|
||||||
|
|
||||||
start_supervisor(Host) ->
|
start_supervisor(Host) ->
|
||||||
Proc = gen_mod:get_module_proc(Host,
|
Proc = gen_mod:get_module_proc(Host,
|
||||||
ejabberd_mod_irc_sup),
|
ejabberd_mod_irc_sup),
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_local_iq/1, export/1,
|
-export([start/2, stop/1, reload/3, process_local_iq/1, export/1,
|
||||||
process_sm_iq/1, on_presence_update/4, import_info/0,
|
process_sm_iq/1, on_presence_update/4, import_info/0,
|
||||||
import/5, import_start/2, store_last_info/4, get_last_info/2,
|
import/5, import_start/2, store_last_info/4, get_last_info/2,
|
||||||
remove_user/2, transform_options/1, mod_opt_type/1,
|
remove_user/2, transform_options/1, mod_opt_type/1,
|
||||||
@ -86,6 +86,26 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
||||||
?NS_LAST).
|
?NS_LAST).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST,
|
||||||
|
?MODULE, process_local_iq, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST,
|
||||||
|
?MODULE, process_sm_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
%%%
|
%%%
|
||||||
%%% Uptime of ejabberd node
|
%%% Uptime of ejabberd node
|
||||||
%%%
|
%%%
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
-protocol({xep, 78, '2.5'}).
|
-protocol({xep, 78, '2.5'}).
|
||||||
|
|
||||||
%% gen_mod API
|
%% gen_mod API
|
||||||
-export([start/2, stop/1, depends/2, mod_opt_type/1]).
|
-export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1]).
|
||||||
%% hooks
|
%% hooks
|
||||||
-export([c2s_unauthenticated_packet/2, c2s_stream_features/2]).
|
-export([c2s_unauthenticated_packet/2, c2s_stream_features/2]).
|
||||||
|
|
||||||
@ -48,6 +48,9 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(c2s_pre_auth_features, Host, ?MODULE,
|
ejabberd_hooks:delete(c2s_pre_auth_features, Host, ?MODULE,
|
||||||
c2s_stream_features, 50).
|
c2s_stream_features, 50).
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, depends/2]).
|
-export([start/2, stop/1, reload/3, depends/2]).
|
||||||
|
|
||||||
-export([user_send_packet/1, user_send_packet_strip_tag/1, user_receive_packet/1,
|
-export([user_send_packet/1, user_send_packet_strip_tag/1, user_receive_packet/1,
|
||||||
process_iq_v0_2/1, process_iq_v0_3/1, disco_sm_features/5,
|
process_iq_v0_2/1, process_iq_v0_3/1, disco_sm_features/5,
|
||||||
@ -74,18 +74,7 @@ start(Host, Opts) ->
|
|||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, Opts),
|
Mod:init(Host, Opts),
|
||||||
init_cache(Opts),
|
init_cache(Opts),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
register_iq_handlers(Host, IQDisc),
|
||||||
?NS_MAM_TMP, ?MODULE, process_iq_v0_2, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
|
||||||
?NS_MAM_TMP, ?MODULE, process_iq_v0_2, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
|
||||||
?NS_MAM_0, ?MODULE, process_iq_v0_3, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
|
||||||
?NS_MAM_0, ?MODULE, process_iq_v0_3, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
|
||||||
?NS_MAM_1, ?MODULE, process_iq_v0_3, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
|
||||||
?NS_MAM_1, ?MODULE, process_iq_v0_3, IQDisc),
|
|
||||||
ejabberd_hooks:add(user_receive_packet, Host, ?MODULE,
|
ejabberd_hooks:add(user_receive_packet, Host, ?MODULE,
|
||||||
user_receive_packet, 88),
|
user_receive_packet, 88),
|
||||||
ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
|
ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
|
||||||
@ -130,6 +119,7 @@ init_cache(Opts) ->
|
|||||||
{life_time, LifeTime}]).
|
{life_time, LifeTime}]).
|
||||||
|
|
||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
|
unregister_iq_handlers(Host),
|
||||||
ejabberd_hooks:delete(user_send_packet, Host, ?MODULE,
|
ejabberd_hooks:delete(user_send_packet, Host, ?MODULE,
|
||||||
user_send_packet, 88),
|
user_send_packet, 88),
|
||||||
ejabberd_hooks:delete(user_receive_packet, Host, ?MODULE,
|
ejabberd_hooks:delete(user_receive_packet, Host, ?MODULE,
|
||||||
@ -142,12 +132,6 @@ stop(Host) ->
|
|||||||
muc_filter_message, 50),
|
muc_filter_message, 50),
|
||||||
ejabberd_hooks:delete(muc_process_iq, Host, ?MODULE,
|
ejabberd_hooks:delete(muc_process_iq, Host, ?MODULE,
|
||||||
muc_process_iq, 50),
|
muc_process_iq, 50),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_MAM_TMP),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_MAM_TMP),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_MAM_0),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_MAM_0),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_MAM_1),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_MAM_1),
|
|
||||||
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE,
|
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE,
|
||||||
disco_sm_features, 50),
|
disco_sm_features, 50),
|
||||||
ejabberd_hooks:delete(remove_user, Host, ?MODULE,
|
ejabberd_hooks:delete(remove_user, Host, ?MODULE,
|
||||||
@ -169,9 +153,77 @@ stop(Host) ->
|
|||||||
ejabberd_commands:unregister_commands(get_commands_spec()),
|
ejabberd_commands:unregister_commands(get_commands_spec()),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(cache_size, NewOpts, OldOpts,
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end,
|
||||||
|
1000) of
|
||||||
|
{false, MaxSize, _} ->
|
||||||
|
cache_tab:setopts(archive_prefs, [{max_size, MaxSize}]);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(cache_life_time, NewOpts, OldOpts,
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end,
|
||||||
|
timer:hours(1) div 1000) of
|
||||||
|
{false, LifeTime, _} ->
|
||||||
|
cache_tab:setopts(archive_prefs, [{life_time, LifeTime}]);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
register_iq_handlers(Host, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(assume_mam_usage, NewOpts, OldOpts,
|
||||||
|
fun(B) when is_boolean(B) -> B end, false) of
|
||||||
|
{false, true, _} ->
|
||||||
|
ejabberd_hooks:add(message_is_archived, Host, ?MODULE,
|
||||||
|
message_is_archived, 50);
|
||||||
|
{false, false, _} ->
|
||||||
|
ejabberd_hooks:delete(message_is_archived, Host, ?MODULE,
|
||||||
|
message_is_archived, 50);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
-spec register_iq_handlers(binary(), gen_iq_handler:type()) -> ok.
|
||||||
|
register_iq_handlers(Host, IQDisc) ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_MAM_TMP,
|
||||||
|
?MODULE, process_iq_v0_2, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_MAM_TMP,
|
||||||
|
?MODULE, process_iq_v0_2, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_MAM_0,
|
||||||
|
?MODULE, process_iq_v0_3, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_MAM_0, ?MODULE,
|
||||||
|
process_iq_v0_3, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_MAM_1,
|
||||||
|
?MODULE, process_iq_v0_3, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_MAM_1,
|
||||||
|
?MODULE, process_iq_v0_3, IQDisc).
|
||||||
|
|
||||||
|
-spec unregister_iq_handlers(binary()) -> ok.
|
||||||
|
unregister_iq_handlers(Host) ->
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_MAM_TMP),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_MAM_TMP),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_MAM_0),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_MAM_0),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_MAM_1),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_MAM_1).
|
||||||
|
|
||||||
-spec remove_user(binary(), binary()) -> ok.
|
-spec remove_user(binary(), binary()) -> ok.
|
||||||
remove_user(User, Server) ->
|
remove_user(User, Server) ->
|
||||||
LUser = jid:nodeprep(User),
|
LUser = jid:nodeprep(User),
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
-include("xmpp.hrl").
|
-include("xmpp.hrl").
|
||||||
|
|
||||||
-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]).
|
depends/2, reload/3]).
|
||||||
|
|
||||||
-export([offline_message_hook/2,
|
-export([offline_message_hook/2,
|
||||||
sm_register_connection_hook/3, sm_remove_connection_hook/3,
|
sm_register_connection_hook/3, sm_remove_connection_hook/3,
|
||||||
@ -68,6 +68,9 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 20),
|
ejabberd_hooks:delete(remove_user, Host, ?MODULE, remove_user, 20),
|
||||||
ejabberd_hooks:delete(register_user, Host, ?MODULE, register_user, 20).
|
ejabberd_hooks:delete(register_user, Host, ?MODULE, register_user, 20).
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
214
src/mod_muc.erl
214
src/mod_muc.erl
@ -36,6 +36,7 @@
|
|||||||
%% API
|
%% API
|
||||||
-export([start/2,
|
-export([start/2,
|
||||||
stop/1,
|
stop/1,
|
||||||
|
reload/3,
|
||||||
room_destroyed/4,
|
room_destroyed/4,
|
||||||
store_room/4,
|
store_room/4,
|
||||||
restore_room/3,
|
restore_room/3,
|
||||||
@ -114,6 +115,10 @@ stop(Host) ->
|
|||||||
gen_mod:stop_child(?MODULE, Host),
|
gen_mod:stop_child(?MODULE, Host),
|
||||||
{wait, Rooms}.
|
{wait, Rooms}.
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||||
|
gen_server:cast(Proc, {reload, Host, NewOpts, OldOpts}).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[{mod_mam, soft}].
|
[{mod_mam, soft}].
|
||||||
|
|
||||||
@ -220,12 +225,115 @@ init([Host, Opts]) ->
|
|||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
||||||
one_queue),
|
one_queue),
|
||||||
MyHost = gen_mod:get_opt_host(Host, Opts,
|
#state{access = Access, host = MyHost,
|
||||||
<<"conference.@HOST@">>),
|
history_size = HistorySize,
|
||||||
|
room_shaper = RoomShaper} = State = init_state(Host, Opts),
|
||||||
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
Mod = gen_mod:db_mod(Host, Opts, ?MODULE),
|
||||||
RMod = gen_mod:ram_db_mod(Host, Opts, ?MODULE),
|
RMod = gen_mod:ram_db_mod(Host, Opts, ?MODULE),
|
||||||
Mod:init(Host, [{host, MyHost}|Opts]),
|
Mod:init(Host, [{host, MyHost}|Opts]),
|
||||||
RMod:init(Host, [{host, MyHost}|Opts]),
|
RMod:init(Host, [{host, MyHost}|Opts]),
|
||||||
|
register_iq_handlers(MyHost, IQDisc),
|
||||||
|
ejabberd_router:register_route(MyHost, Host),
|
||||||
|
load_permanent_rooms(MyHost, Host, Access, HistorySize, RoomShaper),
|
||||||
|
{ok, State}.
|
||||||
|
|
||||||
|
handle_call(stop, _From, State) ->
|
||||||
|
{stop, normal, ok, State};
|
||||||
|
handle_call({create, Room, From, Nick, Opts}, _From,
|
||||||
|
#state{host = Host, server_host = ServerHost,
|
||||||
|
access = Access, default_room_opts = DefOpts,
|
||||||
|
history_size = HistorySize,
|
||||||
|
room_shaper = RoomShaper} = State) ->
|
||||||
|
?DEBUG("MUC: create new room '~s'~n", [Room]),
|
||||||
|
NewOpts = case Opts of
|
||||||
|
default -> DefOpts;
|
||||||
|
_ -> Opts
|
||||||
|
end,
|
||||||
|
{ok, Pid} = mod_muc_room:start(
|
||||||
|
Host, ServerHost, Access,
|
||||||
|
Room, HistorySize,
|
||||||
|
RoomShaper, From,
|
||||||
|
Nick, NewOpts),
|
||||||
|
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
||||||
|
RMod:register_online_room(Room, Host, Pid),
|
||||||
|
{reply, ok, State}.
|
||||||
|
|
||||||
|
handle_cast({reload, ServerHost, NewOpts, OldOpts}, #state{host = OldHost}) ->
|
||||||
|
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue),
|
||||||
|
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue),
|
||||||
|
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),
|
||||||
|
OldRMod = gen_mod:ram_db_mod(ServerHost, OldOpts, ?MODULE),
|
||||||
|
#state{host = NewHost} = NewState = init_state(ServerHost, NewOpts),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(ServerHost, [{host, NewHost}|NewOpts]);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
if NewRMod /= OldRMod ->
|
||||||
|
NewRMod:init(ServerHost, [{host, NewHost}|NewOpts]);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) ->
|
||||||
|
register_iq_handlers(NewHost, NewIQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
if NewHost /= OldHost ->
|
||||||
|
ejabberd_router:register_route(NewHost, ServerHost),
|
||||||
|
ejabberd_router:unregister_route(OldHost),
|
||||||
|
unregister_iq_handlers(OldHost);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
{noreply, NewState};
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_info({route, Packet},
|
||||||
|
#state{host = Host, server_host = ServerHost,
|
||||||
|
access = Access, default_room_opts = DefRoomOpts,
|
||||||
|
history_size = HistorySize,
|
||||||
|
max_rooms_discoitems = MaxRoomsDiscoItems,
|
||||||
|
room_shaper = RoomShaper} = State) ->
|
||||||
|
From = xmpp:get_from(Packet),
|
||||||
|
To = xmpp:get_to(Packet),
|
||||||
|
case catch do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
|
||||||
|
From, To, Packet, DefRoomOpts, MaxRoomsDiscoItems) of
|
||||||
|
{'EXIT', Reason} ->
|
||||||
|
?ERROR_MSG("~p", [Reason]);
|
||||||
|
_ ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
{noreply, State};
|
||||||
|
handle_info({room_destroyed, {Room, Host}, Pid}, State) ->
|
||||||
|
ServerHost = State#state.server_host,
|
||||||
|
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
||||||
|
RMod:unregister_online_room(Room, Host, Pid),
|
||||||
|
{noreply, State};
|
||||||
|
handle_info(Info, State) ->
|
||||||
|
?ERROR_MSG("unexpected info: ~p", [Info]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
terminate(_Reason, #state{host = MyHost}) ->
|
||||||
|
ejabberd_router:unregister_route(MyHost),
|
||||||
|
unregister_iq_handlers(MyHost).
|
||||||
|
|
||||||
|
code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%%% Internal functions
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
init_state(Host, Opts) ->
|
||||||
|
MyHost = gen_mod:get_opt_host(Host, Opts,
|
||||||
|
<<"conference.@HOST@">>),
|
||||||
Access = gen_mod:get_opt(access, Opts,
|
Access = gen_mod:get_opt(access, Opts,
|
||||||
fun acl:access_rules_validator/1, all),
|
fun acl:access_rules_validator/1, all),
|
||||||
AccessCreate = gen_mod:get_opt(access_create, Opts,
|
AccessCreate = gen_mod:get_opt(access_create, Opts,
|
||||||
@ -298,93 +406,35 @@ init([Host, Opts]) ->
|
|||||||
RoomShaper = gen_mod:get_opt(room_shaper, Opts,
|
RoomShaper = gen_mod:get_opt(room_shaper, Opts,
|
||||||
fun(A) when is_atom(A) -> A end,
|
fun(A) when is_atom(A) -> A end,
|
||||||
none),
|
none),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_REGISTER,
|
#state{host = MyHost,
|
||||||
?MODULE, process_register, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_VCARD,
|
|
||||||
?MODULE, process_vcard, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_MUCSUB,
|
|
||||||
?MODULE, process_mucsub, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_MUC_UNIQUE,
|
|
||||||
?MODULE, process_muc_unique, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO,
|
|
||||||
?MODULE, process_disco_info, IQDisc),
|
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS,
|
|
||||||
?MODULE, process_disco_items, IQDisc),
|
|
||||||
ejabberd_router:register_route(MyHost, Host),
|
|
||||||
load_permanent_rooms(MyHost, Host,
|
|
||||||
{Access, AccessCreate, AccessAdmin, AccessPersistent},
|
|
||||||
HistorySize, RoomShaper),
|
|
||||||
{ok, #state{host = MyHost,
|
|
||||||
server_host = Host,
|
server_host = Host,
|
||||||
access = {Access, AccessCreate, AccessAdmin, AccessPersistent},
|
access = {Access, AccessCreate, AccessAdmin, AccessPersistent},
|
||||||
default_room_opts = DefRoomOpts,
|
default_room_opts = DefRoomOpts,
|
||||||
history_size = HistorySize,
|
history_size = HistorySize,
|
||||||
max_rooms_discoitems = MaxRoomsDiscoItems,
|
max_rooms_discoitems = MaxRoomsDiscoItems,
|
||||||
room_shaper = RoomShaper}}.
|
room_shaper = RoomShaper}.
|
||||||
|
|
||||||
handle_call(stop, _From, State) ->
|
register_iq_handlers(Host, IQDisc) ->
|
||||||
{stop, normal, ok, State};
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER,
|
||||||
handle_call({create, Room, From, Nick, Opts}, _From,
|
?MODULE, process_register, IQDisc),
|
||||||
#state{host = Host, server_host = ServerHost,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
|
||||||
access = Access, default_room_opts = DefOpts,
|
?MODULE, process_vcard, IQDisc),
|
||||||
history_size = HistorySize,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_MUCSUB,
|
||||||
room_shaper = RoomShaper} = State) ->
|
?MODULE, process_mucsub, IQDisc),
|
||||||
?DEBUG("MUC: create new room '~s'~n", [Room]),
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_MUC_UNIQUE,
|
||||||
NewOpts = case Opts of
|
?MODULE, process_muc_unique, IQDisc),
|
||||||
default -> DefOpts;
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO,
|
||||||
_ -> Opts
|
?MODULE, process_disco_info, IQDisc),
|
||||||
end,
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS,
|
||||||
{ok, Pid} = mod_muc_room:start(
|
?MODULE, process_disco_items, IQDisc).
|
||||||
Host, ServerHost, Access,
|
|
||||||
Room, HistorySize,
|
|
||||||
RoomShaper, From,
|
|
||||||
Nick, NewOpts),
|
|
||||||
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
|
||||||
RMod:register_online_room(Room, Host, Pid),
|
|
||||||
{reply, ok, State}.
|
|
||||||
|
|
||||||
handle_cast(_Msg, State) -> {noreply, State}.
|
unregister_iq_handlers(Host) ->
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_REGISTER),
|
||||||
handle_info({route, Packet},
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
|
||||||
#state{host = Host, server_host = ServerHost,
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_MUCSUB),
|
||||||
access = Access, default_room_opts = DefRoomOpts,
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_MUC_UNIQUE),
|
||||||
history_size = HistorySize,
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
|
||||||
max_rooms_discoitems = MaxRoomsDiscoItems,
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS).
|
||||||
room_shaper = RoomShaper} = State) ->
|
|
||||||
From = xmpp:get_from(Packet),
|
|
||||||
To = xmpp:get_to(Packet),
|
|
||||||
case catch do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
|
|
||||||
From, To, Packet, DefRoomOpts, MaxRoomsDiscoItems) of
|
|
||||||
{'EXIT', Reason} ->
|
|
||||||
?ERROR_MSG("~p", [Reason]);
|
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
{noreply, State};
|
|
||||||
handle_info({room_destroyed, {Room, Host}, Pid}, State) ->
|
|
||||||
ServerHost = State#state.server_host,
|
|
||||||
RMod = gen_mod:ram_db_mod(ServerHost, ?MODULE),
|
|
||||||
RMod:unregister_online_room(Room, Host, Pid),
|
|
||||||
{noreply, State};
|
|
||||||
handle_info(Info, State) ->
|
|
||||||
?ERROR_MSG("unexpected info: ~p", [Info]),
|
|
||||||
{noreply, State}.
|
|
||||||
|
|
||||||
terminate(_Reason, #state{host = MyHost}) ->
|
|
||||||
ejabberd_router:unregister_route(MyHost),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_REGISTER),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_VCARD),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_MUCSUB),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_MUC_UNIQUE),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_INFO),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, MyHost, ?NS_DISCO_ITEMS),
|
|
||||||
ok.
|
|
||||||
|
|
||||||
code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%%% Internal functions
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
|
|
||||||
do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
|
do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
|
||||||
From, To, Packet, DefRoomOpts, _MaxRoomsDiscoItems) ->
|
From, To, Packet, DefRoomOpts, _MaxRoomsDiscoItems) ->
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, depends/2, muc_online_rooms/1,
|
-export([start/2, stop/1, reload/3, depends/2, muc_online_rooms/1,
|
||||||
muc_unregister_nick/1, create_room/3, destroy_room/2,
|
muc_unregister_nick/1, create_room/3, destroy_room/2,
|
||||||
create_room_with_opts/4,
|
create_room_with_opts/4,
|
||||||
create_rooms_file/1, destroy_rooms_file/1,
|
create_rooms_file/1, destroy_rooms_file/1,
|
||||||
@ -67,6 +67,9 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(webadmin_page_main, ?MODULE, web_page_main, 50),
|
ejabberd_hooks:delete(webadmin_page_main, ?MODULE, web_page_main, 50),
|
||||||
ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, web_page_host, 50).
|
ejabberd_hooks:delete(webadmin_page_host, Host, ?MODULE, web_page_host, 50).
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[{mod_muc, hard}].
|
[{mod_muc, hard}].
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, transform_module_options/1,
|
-export([start/2, stop/1, reload/3, transform_module_options/1,
|
||||||
check_access_log/2, add_to_log/5]).
|
check_access_log/2, add_to_log/5]).
|
||||||
|
|
||||||
-export([init/1, handle_call/3, handle_cast/2,
|
-export([init/1, handle_call/3, handle_cast/2,
|
||||||
@ -78,6 +78,10 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, _OldOpts) ->
|
||||||
|
Proc = get_proc_name(Host),
|
||||||
|
gen_server:cast(Proc, {reload, NewOpts}).
|
||||||
|
|
||||||
add_to_log(Host, Type, Data, Room, Opts) ->
|
add_to_log(Host, Type, Data, Room, Opts) ->
|
||||||
gen_server:cast(get_proc_name(Host),
|
gen_server:cast(get_proc_name(Host),
|
||||||
{add_to_log, Type, Data, Room, Opts}).
|
{add_to_log, Type, Data, Room, Opts}).
|
||||||
@ -106,6 +110,36 @@ depends(_Host, _Opts) ->
|
|||||||
%%====================================================================
|
%%====================================================================
|
||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
|
{ok, init_state(Host, Opts)}.
|
||||||
|
|
||||||
|
handle_call({check_access_log, ServerHost, FromJID}, _From, State) ->
|
||||||
|
Reply = acl:match_rule(ServerHost, State#logstate.access, FromJID),
|
||||||
|
{reply, Reply, State};
|
||||||
|
handle_call(stop, _From, State) ->
|
||||||
|
{stop, normal, ok, State}.
|
||||||
|
|
||||||
|
handle_cast({reload, Opts}, #logstate{host = Host}) ->
|
||||||
|
{noreply, init_state(Host, Opts)};
|
||||||
|
handle_cast({add_to_log, Type, Data, Room, Opts}, State) ->
|
||||||
|
case catch add_to_log2(Type, Data, Room, Opts, State) of
|
||||||
|
{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
|
||||||
|
_ -> ok
|
||||||
|
end,
|
||||||
|
{noreply, State};
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
handle_info(_Info, State) -> {noreply, State}.
|
||||||
|
|
||||||
|
terminate(_Reason, _State) -> ok.
|
||||||
|
|
||||||
|
code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%%% Internal functions
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
init_state(Host, Opts) ->
|
||||||
OutDir = gen_mod:get_opt(outdir, Opts,
|
OutDir = gen_mod:get_opt(outdir, Opts,
|
||||||
fun iolist_to_binary/1,
|
fun iolist_to_binary/1,
|
||||||
<<"www/muc">>),
|
<<"www/muc">>),
|
||||||
@ -152,37 +186,13 @@ init([Host, Opts]) ->
|
|||||||
{language, Host},
|
{language, Host},
|
||||||
fun iolist_to_binary/1,
|
fun iolist_to_binary/1,
|
||||||
?MYLANG),
|
?MYLANG),
|
||||||
{ok,
|
|
||||||
#logstate{host = Host, out_dir = OutDir,
|
#logstate{host = Host, out_dir = OutDir,
|
||||||
dir_type = DirType, dir_name = DirName,
|
dir_type = DirType, dir_name = DirName,
|
||||||
file_format = FileFormat, css_file = CSSFile,
|
file_format = FileFormat, css_file = CSSFile,
|
||||||
file_permissions = FilePermissions,
|
file_permissions = FilePermissions,
|
||||||
access = AccessLog, lang = Lang, timezone = Timezone,
|
access = AccessLog, lang = Lang, timezone = Timezone,
|
||||||
spam_prevention = NoFollow, top_link = Top_link}}.
|
spam_prevention = NoFollow, top_link = Top_link}.
|
||||||
|
|
||||||
handle_call({check_access_log, ServerHost, FromJID}, _From, State) ->
|
|
||||||
Reply = acl:match_rule(ServerHost, State#logstate.access, FromJID),
|
|
||||||
{reply, Reply, State};
|
|
||||||
handle_call(stop, _From, State) ->
|
|
||||||
{stop, normal, ok, State}.
|
|
||||||
|
|
||||||
handle_cast({add_to_log, Type, Data, Room, Opts}, State) ->
|
|
||||||
case catch add_to_log2(Type, Data, Room, Opts, State) of
|
|
||||||
{'EXIT', Reason} -> ?ERROR_MSG("~p", [Reason]);
|
|
||||||
_ -> ok
|
|
||||||
end,
|
|
||||||
{noreply, State};
|
|
||||||
handle_cast(_Msg, State) -> {noreply, State}.
|
|
||||||
|
|
||||||
handle_info(_Info, State) -> {noreply, State}.
|
|
||||||
|
|
||||||
terminate(_Reason, _State) -> ok.
|
|
||||||
|
|
||||||
code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
%%% Internal functions
|
|
||||||
%%--------------------------------------------------------------------
|
|
||||||
add_to_log2(text, {Nick, Packet}, Room, Opts, State) ->
|
add_to_log2(text, {Nick, Packet}, Room, Opts, State) ->
|
||||||
case has_no_permanent_store_hint(Packet) of
|
case has_no_permanent_store_hint(Packet) of
|
||||||
false ->
|
false ->
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1]).
|
-export([start/2, stop/1, reload/3]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, handle_info/2, handle_call/3,
|
-export([init/1, handle_info/2, handle_call/3,
|
||||||
@ -122,6 +122,10 @@ start(LServerS, Opts) ->
|
|||||||
stop(LServerS) ->
|
stop(LServerS) ->
|
||||||
gen_mod:stop_child(?MODULE, LServerS).
|
gen_mod:stop_child(?MODULE, LServerS).
|
||||||
|
|
||||||
|
reload(LServerS, NewOpts, OldOpts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(LServerS, ?MODULE),
|
||||||
|
gen_server:cast(Proc, {reload, NewOpts, OldOpts}).
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
@ -150,7 +154,29 @@ init([LServerS, Opts]) ->
|
|||||||
handle_call(stop, _From, State) ->
|
handle_call(stop, _From, State) ->
|
||||||
try_stop_loop(), {stop, normal, ok, State}.
|
try_stop_loop(), {stop, normal, ok, State}.
|
||||||
|
|
||||||
handle_cast(_Msg, State) -> {noreply, State}.
|
handle_cast({reload, NewOpts, NewOpts},
|
||||||
|
#state{lserver = LServerS, lservice = OldLServiceS} = State) ->
|
||||||
|
Access = gen_mod:get_opt(access, NewOpts,
|
||||||
|
fun acl:access_rules_validator/1, all),
|
||||||
|
SLimits =
|
||||||
|
build_service_limit_record(gen_mod:get_opt(limits, NewOpts,
|
||||||
|
fun (A) when is_list(A) ->
|
||||||
|
A
|
||||||
|
end,
|
||||||
|
[])),
|
||||||
|
NewLServiceS = gen_mod:get_opt_host(LServerS, NewOpts,
|
||||||
|
<<"multicast.@HOST@">>),
|
||||||
|
if NewLServiceS /= OldLServiceS ->
|
||||||
|
ejabberd_router:register_route(NewLServiceS, LServerS),
|
||||||
|
ejabberd_router:unregister_route(OldLServiceS);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
{noreply, State#state{lservice = NewLServiceS,
|
||||||
|
access = Access, service_limits = SLimits}};
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Function: handle_info(Info, State) -> {noreply, State} |
|
%% Function: handle_info(Info, State) -> {noreply, State} |
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
-export([start/2,
|
-export([start/2,
|
||||||
stop/1,
|
stop/1,
|
||||||
|
reload/3,
|
||||||
store_packet/2,
|
store_packet/2,
|
||||||
store_offline_msg/5,
|
store_offline_msg/5,
|
||||||
c2s_self_presence/1,
|
c2s_self_presence/1,
|
||||||
@ -113,6 +114,10 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||||
|
gen_server:cast(Proc, {reload, NewOpts, OldOpts}).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
@ -162,8 +167,35 @@ init([Host, Opts]) ->
|
|||||||
handle_call(stop, _From, State) ->
|
handle_call(stop, _From, State) ->
|
||||||
{stop, normal, ok, State}.
|
{stop, normal, ok, State}.
|
||||||
|
|
||||||
|
handle_cast({reload, NewOpts, OldOpts}, #state{host = Host} = State) ->
|
||||||
handle_cast(_Msg, State) -> {noreply, State}.
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_FLEX_OFFLINE,
|
||||||
|
?MODULE, handle_offline_query, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(access_max_user_messages, NewOpts, OldOpts,
|
||||||
|
fun acl:shaper_rules_validator/1,
|
||||||
|
max_user_offline_messages) of
|
||||||
|
{false, AccessMaxOfflineMsgs, _} ->
|
||||||
|
{noreply,
|
||||||
|
State#state{access_max_offline_messages = AccessMaxOfflineMsgs}};
|
||||||
|
true ->
|
||||||
|
{noreply, State}
|
||||||
|
end;
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
|
|
||||||
handle_info(#offline_msg{us = UserServer} = Msg, State) ->
|
handle_info(#offline_msg{us = UserServer} = Msg, State) ->
|
||||||
|
122
src/mod_ping.erl
122
src/mod_ping.erl
@ -48,7 +48,7 @@
|
|||||||
-export([start_ping/2, stop_ping/2]).
|
-export([start_ping/2, stop_ping/2]).
|
||||||
|
|
||||||
%% gen_mod callbacks
|
%% gen_mod callbacks
|
||||||
-export([start/2, stop/1]).
|
-export([start/2, stop/1, reload/3]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, terminate/2, handle_call/3,
|
-export([init/1, terminate/2, handle_call/3,
|
||||||
@ -87,64 +87,49 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||||
|
gen_server:cast(Proc, {reload, Host, NewOpts, OldOpts}).
|
||||||
|
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
SendPings = gen_mod:get_opt(send_pings, Opts,
|
State = init_state(Host, Opts),
|
||||||
fun(B) when is_boolean(B) -> B end,
|
|
||||||
?DEFAULT_SEND_PINGS),
|
|
||||||
PingInterval = gen_mod:get_opt(ping_interval, Opts,
|
|
||||||
fun(I) when is_integer(I), I>0 -> I end,
|
|
||||||
?DEFAULT_PING_INTERVAL),
|
|
||||||
PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts,
|
|
||||||
fun(I) when is_integer(I), I>0 -> I * 1000 end,
|
|
||||||
undefined),
|
|
||||||
TimeoutAction = gen_mod:get_opt(timeout_action, Opts,
|
|
||||||
fun(none) -> none;
|
|
||||||
(kill) -> kill
|
|
||||||
end, none),
|
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
||||||
no_queue),
|
no_queue),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, Host,
|
register_iq_handlers(Host, IQDisc),
|
||||||
?NS_PING, ?MODULE, iq_ping, IQDisc),
|
case State#state.send_pings of
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, Host,
|
true -> register_hooks(Host);
|
||||||
?NS_PING, ?MODULE, iq_ping, IQDisc),
|
false -> ok
|
||||||
case SendPings of
|
|
||||||
true ->
|
|
||||||
ejabberd_hooks:add(sm_register_connection_hook, Host,
|
|
||||||
?MODULE, user_online, 100),
|
|
||||||
ejabberd_hooks:add(sm_remove_connection_hook, Host,
|
|
||||||
?MODULE, user_offline, 100),
|
|
||||||
ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
|
|
||||||
user_send, 100);
|
|
||||||
_ -> ok
|
|
||||||
end,
|
end,
|
||||||
{ok,
|
{ok, State}.
|
||||||
#state{host = Host, send_pings = SendPings,
|
|
||||||
ping_interval = PingInterval,
|
|
||||||
timeout_action = TimeoutAction,
|
|
||||||
ping_ack_timeout = PingAckTimeout,
|
|
||||||
timers = maps:new()}}.
|
|
||||||
|
|
||||||
terminate(_Reason, #state{host = Host}) ->
|
terminate(_Reason, #state{host = Host}) ->
|
||||||
ejabberd_hooks:delete(sm_remove_connection_hook, Host,
|
unregister_hooks(Host),
|
||||||
?MODULE, user_offline, 100),
|
unregister_iq_handlers(Host).
|
||||||
ejabberd_hooks:delete(sm_register_connection_hook, Host,
|
|
||||||
?MODULE, user_online, 100),
|
|
||||||
ejabberd_hooks:delete(user_send_packet, Host, ?MODULE,
|
|
||||||
user_send, 100),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
|
||||||
?NS_PING),
|
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
|
||||||
?NS_PING).
|
|
||||||
|
|
||||||
handle_call(stop, _From, State) ->
|
handle_call(stop, _From, State) ->
|
||||||
{stop, normal, ok, State};
|
{stop, normal, ok, State};
|
||||||
handle_call(_Req, _From, State) ->
|
handle_call(_Req, _From, State) ->
|
||||||
{reply, {error, badarg}, State}.
|
{reply, {error, badarg}, State}.
|
||||||
|
|
||||||
|
handle_cast({reload, Host, NewOpts, OldOpts},
|
||||||
|
#state{timers = Timers} = OldState) ->
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} -> register_iq_handlers(Host, IQDisc);
|
||||||
|
true -> ok
|
||||||
|
end,
|
||||||
|
NewState = init_state(Host, NewOpts),
|
||||||
|
case {NewState#state.send_pings, OldState#state.send_pings} of
|
||||||
|
{true, false} -> register_hooks(Host);
|
||||||
|
{false, true} -> unregister_hooks(Host);
|
||||||
|
_ -> ok
|
||||||
|
end,
|
||||||
|
{noreply, NewState#state{timers = Timers}};
|
||||||
handle_cast({start_ping, JID}, State) ->
|
handle_cast({start_ping, JID}, State) ->
|
||||||
Timers = add_timer(JID, State#state.ping_interval,
|
Timers = add_timer(JID, State#state.ping_interval,
|
||||||
State#state.timers),
|
State#state.timers),
|
||||||
@ -169,7 +154,9 @@ handle_cast({iq_pong, JID, timeout}, State) ->
|
|||||||
_ -> ok
|
_ -> ok
|
||||||
end,
|
end,
|
||||||
{noreply, State#state{timers = Timers}};
|
{noreply, State#state{timers = Timers}};
|
||||||
handle_cast(_Msg, State) -> {noreply, State}.
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
handle_info({timeout, _TRef, {ping, JID}}, State) ->
|
handle_info({timeout, _TRef, {ping, JID}}, State) ->
|
||||||
From = jid:make(State#state.host),
|
From = jid:make(State#state.host),
|
||||||
@ -212,6 +199,53 @@ user_send({Packet, #{jid := JID} = C2SState}) ->
|
|||||||
%%====================================================================
|
%%====================================================================
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
%%====================================================================
|
%%====================================================================
|
||||||
|
init_state(Host, Opts) ->
|
||||||
|
SendPings = gen_mod:get_opt(send_pings, Opts,
|
||||||
|
fun(B) when is_boolean(B) -> B end,
|
||||||
|
?DEFAULT_SEND_PINGS),
|
||||||
|
PingInterval = gen_mod:get_opt(ping_interval, Opts,
|
||||||
|
fun(I) when is_integer(I), I>0 -> I end,
|
||||||
|
?DEFAULT_PING_INTERVAL),
|
||||||
|
PingAckTimeout = gen_mod:get_opt(ping_ack_timeout, Opts,
|
||||||
|
fun(I) when is_integer(I), I>0 -> I * 1000 end,
|
||||||
|
undefined),
|
||||||
|
TimeoutAction = gen_mod:get_opt(timeout_action, Opts,
|
||||||
|
fun(none) -> none;
|
||||||
|
(kill) -> kill
|
||||||
|
end, none),
|
||||||
|
#state{host = Host,
|
||||||
|
send_pings = SendPings,
|
||||||
|
ping_interval = PingInterval,
|
||||||
|
timeout_action = TimeoutAction,
|
||||||
|
ping_ack_timeout = PingAckTimeout,
|
||||||
|
timers = maps:new()}.
|
||||||
|
|
||||||
|
register_hooks(Host) ->
|
||||||
|
ejabberd_hooks:add(sm_register_connection_hook, Host,
|
||||||
|
?MODULE, user_online, 100),
|
||||||
|
ejabberd_hooks:add(sm_remove_connection_hook, Host,
|
||||||
|
?MODULE, user_offline, 100),
|
||||||
|
ejabberd_hooks:add(user_send_packet, Host, ?MODULE,
|
||||||
|
user_send, 100).
|
||||||
|
|
||||||
|
unregister_hooks(Host) ->
|
||||||
|
ejabberd_hooks:delete(sm_remove_connection_hook, Host,
|
||||||
|
?MODULE, user_offline, 100),
|
||||||
|
ejabberd_hooks:delete(sm_register_connection_hook, Host,
|
||||||
|
?MODULE, user_online, 100),
|
||||||
|
ejabberd_hooks:delete(user_send_packet, Host, ?MODULE,
|
||||||
|
user_send, 100).
|
||||||
|
|
||||||
|
register_iq_handlers(Host, IQDisc) ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PING,
|
||||||
|
?MODULE, iq_ping, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_PING,
|
||||||
|
?MODULE, iq_ping, IQDisc).
|
||||||
|
|
||||||
|
unregister_iq_handlers(Host) ->
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_PING),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PING).
|
||||||
|
|
||||||
-spec add_timer(jid(), non_neg_integer(), map()) -> map().
|
-spec add_timer(jid(), non_neg_integer(), map()) -> map().
|
||||||
add_timer(JID, Interval, Timers) ->
|
add_timer(JID, Interval, Timers) ->
|
||||||
LJID = jid:tolower(JID),
|
LJID = jid:tolower(JID),
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
-behavior(gen_mod).
|
-behavior(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, check_packet/4,
|
-export([start/2, stop/1, reload/3, check_packet/4,
|
||||||
mod_opt_type/1, depends/2]).
|
mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -48,6 +48,9 @@ stop(Host) ->
|
|||||||
?MODULE, check_packet, 25),
|
?MODULE, check_packet, 25),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_iq/1, export/1, import_info/0,
|
-export([start/2, stop/1, reload/3, process_iq/1, export/1, import_info/0,
|
||||||
c2s_session_opened/1, c2s_copy_session/2, push_list_update/3,
|
c2s_session_opened/1, c2s_copy_session/2, push_list_update/3,
|
||||||
user_send_packet/1, user_receive_packet/1, disco_features/5,
|
user_send_packet/1, user_receive_packet/1, disco_features/5,
|
||||||
check_packet/4, remove_user/2, encode_list_item/1,
|
check_packet/4, remove_user/2, encode_list_item/1,
|
||||||
@ -99,6 +99,24 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
||||||
?NS_PRIVACY).
|
?NS_PRIVACY).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
|
||||||
|
?MODULE, process_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
-spec disco_features({error, stanza_error()} | {result, [binary()]} | empty,
|
-spec disco_features({error, stanza_error()} | {result, [binary()]} | empty,
|
||||||
jid(), jid(), binary(), binary()) ->
|
jid(), jid(), binary(), binary()) ->
|
||||||
{error, stanza_error()} | {result, [binary()]}.
|
{error, stanza_error()} | {result, [binary()]}.
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_sm_iq/1, import_info/0,
|
-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,
|
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, depends/2]).
|
||||||
|
|
||||||
@ -64,6 +64,24 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
||||||
?NS_PRIVATE).
|
?NS_PRIVATE).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
|
||||||
|
?MODULE, process_sm_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
-spec process_sm_iq(iq()) -> iq().
|
-spec process_sm_iq(iq()) -> iq().
|
||||||
process_sm_iq(#iq{type = Type, lang = Lang,
|
process_sm_iq(#iq{type = Type, lang = Lang,
|
||||||
from = #jid{luser = LUser, lserver = LServer},
|
from = #jid{luser = LUser, lserver = LServer},
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, mod_opt_type/1, depends/2]).
|
-export([start/2, stop/1, reload/3, mod_opt_type/1, depends/2]).
|
||||||
%% gen_server callbacks
|
%% gen_server callbacks
|
||||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||||
terminate/2, code_change/3]).
|
terminate/2, code_change/3]).
|
||||||
@ -55,6 +55,9 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_mod:stop_child(?MODULE, Host).
|
gen_mod:stop_child(?MODULE, Host).
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
mod_opt_type(roster) -> v_roster();
|
mod_opt_type(roster) -> v_roster();
|
||||||
mod_opt_type(message) -> v_message();
|
mod_opt_type(message) -> v_message();
|
||||||
mod_opt_type(presence) -> v_presence();
|
mod_opt_type(presence) -> v_presence();
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
-behaviour(supervisor).
|
-behaviour(supervisor).
|
||||||
|
|
||||||
%% gen_mod callbacks.
|
%% gen_mod callbacks.
|
||||||
-export([start/2, stop/1, transform_module_options/1]).
|
-export([start/2, stop/1, reload/3, transform_module_options/1]).
|
||||||
|
|
||||||
%% supervisor callbacks.
|
%% supervisor callbacks.
|
||||||
-export([init/1]).
|
-export([init/1]).
|
||||||
@ -68,6 +68,11 @@ stop(Host) ->
|
|||||||
supervisor:terminate_child(ejabberd_sup, Proc),
|
supervisor:terminate_child(ejabberd_sup, Proc),
|
||||||
supervisor:delete_child(ejabberd_sup, Proc).
|
supervisor:delete_child(ejabberd_sup, Proc).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
Mod = gen_mod:ram_db_mod(global, ?MODULE),
|
||||||
|
Mod:init(),
|
||||||
|
mod_proxy65_service:reload(Host, NewOpts, OldOpts).
|
||||||
|
|
||||||
start_link(Host, Opts) ->
|
start_link(Host, Opts) ->
|
||||||
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
supervisor:start_link({local, Proc}, ?MODULE,
|
supervisor:start_link({local, Proc}, ?MODULE,
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
-export([init/1, handle_info/2, handle_call/3,
|
-export([init/1, handle_info/2, handle_call/3,
|
||||||
handle_cast/2, terminate/2, code_change/3]).
|
handle_cast/2, terminate/2, code_change/3]).
|
||||||
|
|
||||||
-export([start_link/2, add_listener/2, process_disco_info/1,
|
-export([start_link/2, reload/3, add_listener/2, process_disco_info/1,
|
||||||
process_disco_items/1, process_vcard/1, process_bytestreams/1,
|
process_disco_items/1, process_vcard/1, process_bytestreams/1,
|
||||||
transform_module_options/1, delete_listener/1]).
|
transform_module_options/1, delete_listener/1]).
|
||||||
|
|
||||||
@ -54,6 +54,10 @@ start_link(Host, Opts) ->
|
|||||||
gen_server:start_link({local, Proc}, ?MODULE,
|
gen_server:start_link({local, Proc}, ?MODULE,
|
||||||
[Host, Opts], []).
|
[Host, Opts], []).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
|
||||||
|
gen_server:cast(Proc, {reload, Host, NewOpts, OldOpts}).
|
||||||
|
|
||||||
init([Host, Opts]) ->
|
init([Host, Opts]) ->
|
||||||
process_flag(trap_exit, true),
|
process_flag(trap_exit, true),
|
||||||
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
|
||||||
@ -85,7 +89,41 @@ handle_info(_Info, State) -> {noreply, State}.
|
|||||||
handle_call(_Request, _From, State) ->
|
handle_call(_Request, _From, State) ->
|
||||||
{reply, ok, State}.
|
{reply, ok, State}.
|
||||||
|
|
||||||
handle_cast(_Request, State) -> {noreply, State}.
|
handle_cast({reload, ServerHost, NewOpts, OldOpts}, State) ->
|
||||||
|
NewHost = gen_mod:get_opt_host(ServerHost, NewOpts, <<"proxy.@HOST@">>),
|
||||||
|
OldHost = gen_mod:get_opt_host(ServerHost, OldOpts, <<"proxy.@HOST@">>),
|
||||||
|
NewIQDisc = gen_mod:get_opt(iqdisc, NewOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue),
|
||||||
|
OldIQDisc = gen_mod:get_opt(iqdisc, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue),
|
||||||
|
if (NewIQDisc /= OldIQDisc) or (NewHost /= OldHost) ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_INFO,
|
||||||
|
?MODULE, process_disco_info, NewIQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_DISCO_ITEMS,
|
||||||
|
?MODULE, process_disco_items, NewIQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_VCARD,
|
||||||
|
?MODULE, process_vcard, NewIQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, NewHost, ?NS_BYTESTREAMS,
|
||||||
|
?MODULE, process_bytestreams, NewIQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
if NewHost /= OldHost ->
|
||||||
|
ejabberd_router:register_route(NewHost, ServerHost),
|
||||||
|
ejabberd_router:unregister_route(OldHost),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_DISCO_INFO),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_DISCO_ITEMS),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_VCARD),
|
||||||
|
gen_iq_handler:remove_iq_handler(ejabberd_local, OldHost, ?NS_BYTESTREAMS);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
{noreply, State#state{myhost = NewHost}};
|
||||||
|
handle_cast(Msg, State) ->
|
||||||
|
?WARNING_MSG("unexpected cast: ~p", [Msg]),
|
||||||
|
{noreply, State}.
|
||||||
|
|
||||||
code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
code_change(_OldVsn, State, _Extra) -> {ok, State}.
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, stream_feature_register/2,
|
-export([start/2, stop/1, reload/3, stream_feature_register/2,
|
||||||
c2s_unauthenticated_packet/2, try_register/5,
|
c2s_unauthenticated_packet/2, try_register/5,
|
||||||
process_iq/1, send_registration_notifications/3,
|
process_iq/1, send_registration_notifications/3,
|
||||||
transform_options/1, transform_module_options/1,
|
transform_options/1, transform_module_options/1,
|
||||||
@ -71,6 +71,19 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
||||||
?NS_REGISTER).
|
?NS_REGISTER).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_REGISTER,
|
||||||
|
?MODULE, process_iq, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_REGISTER,
|
||||||
|
?MODULE, process_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process/2, mod_opt_type/1, depends/2]).
|
-export([start/2, stop/1, reload/3, process/2, mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -76,6 +76,9 @@ start(_Host, _Opts) ->
|
|||||||
|
|
||||||
stop(_Host) -> ok.
|
stop(_Host) -> ok.
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[{mod_register, hard}].
|
[{mod_register, hard}].
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_iq/1, export/1,
|
-export([start/2, stop/1, reload/3, process_iq/1, export/1,
|
||||||
import_info/0, process_local_iq/1, get_user_roster/2,
|
import_info/0, process_local_iq/1, get_user_roster/2,
|
||||||
import/5, c2s_session_opened/1, get_roster/2,
|
import/5, c2s_session_opened/1, get_roster/2,
|
||||||
import_start/2, import_stop/2, user_receive_packet/1,
|
import_start/2, import_stop/2, user_receive_packet/1,
|
||||||
@ -139,6 +139,24 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
|
||||||
?NS_ROSTER).
|
?NS_ROSTER).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
|
||||||
|
?MODULE, process_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
-protocol({xep, 185, '1.0'}).
|
-protocol({xep, 185, '1.0'}).
|
||||||
|
|
||||||
%% gen_mod API
|
%% gen_mod API
|
||||||
-export([start/2, stop/1, depends/2, mod_opt_type/1]).
|
-export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1]).
|
||||||
%% Hooks
|
%% Hooks
|
||||||
-export([s2s_out_auth_result/2, s2s_out_downgraded/2,
|
-export([s2s_out_auth_result/2, s2s_out_downgraded/2,
|
||||||
s2s_in_packet/2, s2s_out_packet/2, s2s_in_recv/3,
|
s2s_in_packet/2, s2s_out_packet/2, s2s_in_recv/3,
|
||||||
@ -86,6 +86,14 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(s2s_out_auth_result, Host, ?MODULE,
|
ejabberd_hooks:delete(s2s_out_auth_result, Host, ?MODULE,
|
||||||
s2s_out_auth_result, 50).
|
s2s_out_auth_result, 50).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, _OldOpts) ->
|
||||||
|
case ejabberd_s2s:tls_verify(Host) of
|
||||||
|
false ->
|
||||||
|
start(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
stop(Host)
|
||||||
|
end.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, export/1,
|
-export([start/2, stop/1, reload/3, export/1,
|
||||||
import_info/0, webadmin_menu/3, webadmin_page/3,
|
import_info/0, webadmin_menu/3, webadmin_page/3,
|
||||||
get_user_roster/2, c2s_session_opened/1,
|
get_user_roster/2, c2s_session_opened/1,
|
||||||
get_jid_info/4, import/5, process_item/2, import_start/2,
|
get_jid_info/4, import/5, process_item/2, import_start/2,
|
||||||
@ -127,8 +127,16 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(remove_user, Host, ?MODULE,
|
ejabberd_hooks:delete(remove_user, Host, ?MODULE,
|
||||||
remove_user,
|
remove_user,
|
||||||
50).
|
50).
|
||||||
%%ejabberd_hooks:delete(remove_user, Host,
|
|
||||||
%% ?MODULE, remove_user, 50),
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_local_iq/1,
|
-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, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -56,6 +56,23 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_SIC_1),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_SIC_1),
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_SIC_1).
|
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,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
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,
|
||||||
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_SIC_1,
|
||||||
|
?MODULE, process_local_iq, IQDisc),
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_SIC_1,
|
||||||
|
?MODULE, process_sm_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
-behaviour(esip).
|
-behaviour(esip).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start/2, stop/1, make_response/2, is_my_host/1, at_my_host/1]).
|
-export([start/2, stop/1, reload/3,
|
||||||
|
make_response/2, is_my_host/1, at_my_host/1]).
|
||||||
|
|
||||||
-export([data_in/2, data_out/2, message_in/2,
|
-export([data_in/2, data_out/2, message_in/2,
|
||||||
message_out/2, request/2, request/3, response/2,
|
message_out/2, request/2, request/3, response/2,
|
||||||
@ -61,6 +62,9 @@ start(_Host, _Opts) ->
|
|||||||
stop(_Host) ->
|
stop(_Host) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_iq/1, mod_opt_type/1, depends/2]).
|
-export([start/2, stop/1, reload/3, process_iq/1, mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
@ -46,6 +46,9 @@ start(Host, Opts) ->
|
|||||||
stop(Host) ->
|
stop(Host) ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS).
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, _OldOpts) ->
|
||||||
|
start(Host, NewOpts).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
-protocol({xep, 198, '1.5.2'}).
|
-protocol({xep, 198, '1.5.2'}).
|
||||||
|
|
||||||
%% gen_mod API
|
%% gen_mod API
|
||||||
-export([start/2, stop/1, depends/2, mod_opt_type/1]).
|
-export([start/2, stop/1, reload/3, depends/2, mod_opt_type/1]).
|
||||||
%% hooks
|
%% hooks
|
||||||
-export([c2s_stream_init/2, c2s_stream_started/2, c2s_stream_features/2,
|
-export([c2s_stream_init/2, c2s_stream_started/2, c2s_stream_features/2,
|
||||||
c2s_authenticated_packet/2, c2s_unauthenticated_packet/2,
|
c2s_authenticated_packet/2, c2s_unauthenticated_packet/2,
|
||||||
@ -87,6 +87,10 @@ stop(Host) ->
|
|||||||
ejabberd_hooks:delete(c2s_closed, Host, ?MODULE, c2s_closed, 50),
|
ejabberd_hooks:delete(c2s_closed, Host, ?MODULE, c2s_closed, 50),
|
||||||
ejabberd_hooks:delete(c2s_terminated, Host, ?MODULE, c2s_terminated, 50).
|
ejabberd_hooks:delete(c2s_terminated, Host, ?MODULE, c2s_terminated, 50).
|
||||||
|
|
||||||
|
reload(_Host, _NewOpts, _OldOpts) ->
|
||||||
|
?WARNING_MSG("module ~s is reloaded, but new configuration will take "
|
||||||
|
"effect for newly created client connections only", []).
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_local_iq/1,
|
-export([start/2, stop/1, reload/3, process_local_iq/1,
|
||||||
mod_opt_type/1, depends/2]).
|
mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -50,6 +50,17 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
||||||
?NS_TIME).
|
?NS_TIME).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_TIME,
|
||||||
|
?MODULE, process_local_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
|
process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
|
||||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||||
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
%% gen_mod callbacks
|
%% gen_mod callbacks
|
||||||
-export([start/2, stop/1]).
|
-export([start/2, stop/1, reload/3]).
|
||||||
|
|
||||||
-export([update_presence/1, vcard_set/3, export/1,
|
-export([update_presence/1, vcard_set/3, export/1,
|
||||||
import_info/0, import/5, import_start/2,
|
import_info/0, import/5, import_start/2,
|
||||||
@ -64,6 +64,16 @@ stop(Host) ->
|
|||||||
vcard_set, 100),
|
vcard_set, 100),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
NewMod = gen_mod:db_mod(Host, NewOpts, ?MODULE),
|
||||||
|
OldMod = gen_mod:db_mod(Host, OldOpts, ?MODULE),
|
||||||
|
if NewMod /= OldMod ->
|
||||||
|
NewMod:init(Host, NewOpts);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
ok.
|
||||||
|
|
||||||
depends(_Host, _Opts) ->
|
depends(_Host, _Opts) ->
|
||||||
[].
|
[].
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
-behaviour(gen_mod).
|
-behaviour(gen_mod).
|
||||||
|
|
||||||
-export([start/2, stop/1, process_local_iq/1,
|
-export([start/2, stop/1, reload/3, process_local_iq/1,
|
||||||
mod_opt_type/1, depends/2]).
|
mod_opt_type/1, depends/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
@ -50,6 +50,17 @@ stop(Host) ->
|
|||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
|
||||||
?NS_VERSION).
|
?NS_VERSION).
|
||||||
|
|
||||||
|
reload(Host, NewOpts, OldOpts) ->
|
||||||
|
case gen_mod:is_equal_opt(iqdisc, NewOpts, OldOpts,
|
||||||
|
fun gen_iq_handler:check_type/1,
|
||||||
|
one_queue) of
|
||||||
|
{false, IQDisc, _} ->
|
||||||
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VERSION,
|
||||||
|
?MODULE, process_local_iq, IQDisc);
|
||||||
|
true ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
|
process_local_iq(#iq{type = set, lang = Lang} = IQ) ->
|
||||||
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
|
||||||
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
|
||||||
|
Loading…
Reference in New Issue
Block a user