mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-28 16:34:13 +01:00
Store options using p1_options module
This commit is contained in:
parent
b51e2aa213
commit
0b93cb7ece
@ -19,7 +19,7 @@
|
|||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
{deps, [{lager, ".*", {git, "https://github.com/basho/lager", {tag, "3.2.1"}}},
|
{deps, [{lager, ".*", {git, "https://github.com/basho/lager", {tag, "3.2.1"}}},
|
||||||
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", {tag, "1.0.8"}}},
|
{p1_utils, ".*", {git, "https://github.com/processone/p1_utils", "470539a"}},
|
||||||
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", "b0c787a"}},
|
{cache_tab, ".*", {git, "https://github.com/processone/cache_tab", "b0c787a"}},
|
||||||
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.11"}}},
|
{fast_tls, ".*", {git, "https://github.com/processone/fast_tls", {tag, "1.0.11"}}},
|
||||||
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.8"}}},
|
{stringprep, ".*", {git, "https://github.com/processone/stringprep", {tag, "1.0.8"}}},
|
||||||
|
@ -616,7 +616,7 @@ restore(Path) ->
|
|||||||
%% Obsolete tables or tables created by module who are no longer used are not
|
%% Obsolete tables or tables created by module who are no longer used are not
|
||||||
%% restored and are ignored.
|
%% restored and are ignored.
|
||||||
keep_tables() ->
|
keep_tables() ->
|
||||||
lists:flatten([acl, passwd, config, local_config,
|
lists:flatten([acl, passwd, config,
|
||||||
keep_modules_tables()]).
|
keep_modules_tables()]).
|
||||||
|
|
||||||
%% Returns the list of modules tables in use, according to the list of actually
|
%% Returns the list of modules tables in use, according to the list of actually
|
||||||
|
@ -46,9 +46,9 @@ start(normal, _Args) ->
|
|||||||
start_apps(),
|
start_apps(),
|
||||||
start_elixir_application(),
|
start_elixir_application(),
|
||||||
ejabberd:check_app(ejabberd),
|
ejabberd:check_app(ejabberd),
|
||||||
ejabberd_mnesia:start(),
|
|
||||||
setup_if_elixir_conf_used(),
|
setup_if_elixir_conf_used(),
|
||||||
ejabberd_config:start(),
|
ejabberd_config:start(),
|
||||||
|
ejabberd_mnesia:start(),
|
||||||
set_settings_from_config(),
|
set_settings_from_config(),
|
||||||
file_queue_init(),
|
file_queue_init(),
|
||||||
maybe_add_nameservers(),
|
maybe_add_nameservers(),
|
||||||
@ -59,6 +59,7 @@ start(normal, _Args) ->
|
|||||||
{T2, _} = statistics(wall_clock),
|
{T2, _} = statistics(wall_clock),
|
||||||
?INFO_MSG("ejabberd ~s is started in the node ~p in ~.2fs",
|
?INFO_MSG("ejabberd ~s is started in the node ~p in ~.2fs",
|
||||||
[?VERSION, node(), (T2-T1)/1000]),
|
[?VERSION, node(), (T2-T1)/1000]),
|
||||||
|
lists:foreach(fun erlang:garbage_collect/1, processes()),
|
||||||
{ok, SupPid};
|
{ok, SupPid};
|
||||||
Err ->
|
Err ->
|
||||||
Err
|
Err
|
||||||
@ -161,6 +162,7 @@ start_apps() ->
|
|||||||
crypto:start(),
|
crypto:start(),
|
||||||
ejabberd:start_app(sasl),
|
ejabberd:start_app(sasl),
|
||||||
ejabberd:start_app(ssl),
|
ejabberd:start_app(ssl),
|
||||||
|
ejabberd:start_app(p1_utils),
|
||||||
ejabberd:start_app(fast_yaml),
|
ejabberd:start_app(fast_yaml),
|
||||||
ejabberd:start_app(fast_tls),
|
ejabberd:start_app(fast_tls),
|
||||||
ejabberd:start_app(xmpp),
|
ejabberd:start_app(xmpp),
|
||||||
|
@ -37,8 +37,7 @@
|
|||||||
is_elixir_enabled/0, v_dbs/1, v_dbs_mods/1,
|
is_elixir_enabled/0, v_dbs/1, v_dbs_mods/1,
|
||||||
default_db/1, default_db/2, default_ram_db/1, default_ram_db/2,
|
default_db/1, default_db/2, default_ram_db/1, default_ram_db/2,
|
||||||
default_queue_type/1, queue_dir/0, fsm_limit_opts/1,
|
default_queue_type/1, queue_dir/0, fsm_limit_opts/1,
|
||||||
use_cache/1, cache_size/1, cache_missed/1, cache_life_time/1,
|
use_cache/1, cache_size/1, cache_missed/1, cache_life_time/1]).
|
||||||
dump/0]).
|
|
||||||
|
|
||||||
-export([start/2]).
|
-export([start/2]).
|
||||||
|
|
||||||
@ -55,6 +54,7 @@
|
|||||||
-include("logger.hrl").
|
-include("logger.hrl").
|
||||||
-include("ejabberd_config.hrl").
|
-include("ejabberd_config.hrl").
|
||||||
-include_lib("kernel/include/file.hrl").
|
-include_lib("kernel/include/file.hrl").
|
||||||
|
-include_lib("stdlib/include/ms_transform.hrl").
|
||||||
|
|
||||||
-callback opt_type(atom()) -> function() | [atom()].
|
-callback opt_type(atom()) -> function() | [atom()].
|
||||||
|
|
||||||
@ -68,7 +68,8 @@
|
|||||||
start() ->
|
start() ->
|
||||||
ConfigFile = get_ejabberd_config_path(),
|
ConfigFile = get_ejabberd_config_path(),
|
||||||
?INFO_MSG("Loading configuration from ~s", [ConfigFile]),
|
?INFO_MSG("Loading configuration from ~s", [ConfigFile]),
|
||||||
mnesia_init(),
|
p1_options:start_link(ejabberd_options),
|
||||||
|
p1_options:start_link(ejabberd_db_modules),
|
||||||
State1 = load_file(ConfigFile),
|
State1 = load_file(ConfigFile),
|
||||||
UnixTime = p1_time_compat:system_time(seconds),
|
UnixTime = p1_time_compat:system_time(seconds),
|
||||||
SharedKey = case erlang:get_cookie() of
|
SharedKey = case erlang:get_cookie() of
|
||||||
@ -101,22 +102,9 @@ hosts_to_start(State) ->
|
|||||||
%% At the moment, these functions are mainly used to setup unit tests.
|
%% At the moment, these functions are mainly used to setup unit tests.
|
||||||
-spec start(Hosts :: [binary()], Opts :: [acl:acl() | local_config()]) -> ok.
|
-spec start(Hosts :: [binary()], Opts :: [acl:acl() | local_config()]) -> ok.
|
||||||
start(Hosts, Opts) ->
|
start(Hosts, Opts) ->
|
||||||
mnesia_init(),
|
|
||||||
set_opts(set_hosts_in_options(Hosts, #state{opts = Opts})),
|
set_opts(set_hosts_in_options(Hosts, #state{opts = Opts})),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
mnesia_init() ->
|
|
||||||
case catch mnesia:table_info(local_config, storage_type) of
|
|
||||||
disc_copies ->
|
|
||||||
mnesia:delete_table(local_config);
|
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
ejabberd_mnesia:create(?MODULE, local_config,
|
|
||||||
[{ram_copies, [node()]},
|
|
||||||
{local_content, true},
|
|
||||||
{attributes, record_info(fields, local_config)}]).
|
|
||||||
|
|
||||||
%% @doc Get the filename of the ejabberd configuration file.
|
%% @doc Get the filename of the ejabberd configuration file.
|
||||||
%% The filename can be specified with: erl -config "/path/to/ejabberd.yml".
|
%% The filename can be specified with: erl -config "/path/to/ejabberd.yml".
|
||||||
%% It can also be specified with the environtment variable EJABBERD_CONFIG_PATH.
|
%% It can also be specified with the environtment variable EJABBERD_CONFIG_PATH.
|
||||||
@ -762,30 +750,18 @@ append_option({Opt, Host}, Val, State) ->
|
|||||||
|
|
||||||
set_opts(State) ->
|
set_opts(State) ->
|
||||||
Opts = State#state.opts,
|
Opts = State#state.opts,
|
||||||
F = fun() ->
|
ets:select_delete(ejabberd_options,
|
||||||
|
ets:fun2ms(
|
||||||
|
fun({{node_start, _}, _}) -> false;
|
||||||
|
({{shared_key, _}, _}) -> false;
|
||||||
|
(_) -> true
|
||||||
|
end)),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({node_start, _}) -> ok;
|
fun(#local_config{key = {Opt, Host}, value = Val}) ->
|
||||||
({shared_key, _}) -> ok;
|
p1_options:insert(ejabberd_options, Opt, Host, Val)
|
||||||
(Key) -> mnesia:delete({local_config, Key})
|
end, Opts),
|
||||||
end, mnesia:all_keys(local_config)),
|
p1_options:compile(ejabberd_options),
|
||||||
lists:foreach(fun mnesia:write/1, Opts)
|
set_log_level().
|
||||||
end,
|
|
||||||
case mnesia:transaction(F) of
|
|
||||||
{atomic, _} ->
|
|
||||||
recompile_options(),
|
|
||||||
set_log_level();
|
|
||||||
{aborted,{no_exists,Table}} ->
|
|
||||||
MnesiaDirectory = mnesia:system_info(directory),
|
|
||||||
?CRITICAL_MSG("Error reading Mnesia database spool files:~n"
|
|
||||||
"The Mnesia database couldn't read the spool file for the table '~p'.~n"
|
|
||||||
"ejabberd needs read and write access in the directory:~n ~s~n"
|
|
||||||
"Maybe the problem is a change in the computer hostname,~n"
|
|
||||||
"or a change in the Erlang node name, which is currently:~n ~p~n"
|
|
||||||
"Check the ejabberd guide for details about changing the~n"
|
|
||||||
"computer hostname or Erlang node name.~n",
|
|
||||||
[Table, MnesiaDirectory, node()]),
|
|
||||||
exit("Error reading Mnesia database")
|
|
||||||
end.
|
|
||||||
|
|
||||||
set_log_level() ->
|
set_log_level() ->
|
||||||
Level = get_option(
|
Level = get_option(
|
||||||
@ -802,12 +778,9 @@ add_local_option(Opt, Val) ->
|
|||||||
|
|
||||||
add_option(Opt, Val) when is_atom(Opt) ->
|
add_option(Opt, Val) when is_atom(Opt) ->
|
||||||
add_option({Opt, global}, Val);
|
add_option({Opt, global}, Val);
|
||||||
add_option(Opt, Val) ->
|
add_option({Opt, Host}, Val) ->
|
||||||
mnesia:transaction(fun() ->
|
p1_options:insert(ejabberd_options, Opt, Host, Val),
|
||||||
mnesia:write(#local_config{key = Opt,
|
p1_options:compile(ejabberd_options).
|
||||||
value = Val})
|
|
||||||
end),
|
|
||||||
recompile_options().
|
|
||||||
|
|
||||||
-spec prepare_opt_val(any(), any(), check_fun(), any()) -> any().
|
-spec prepare_opt_val(any(), any(), check_fun(), any()) -> any().
|
||||||
|
|
||||||
@ -882,10 +855,9 @@ get_option(Opt, F, Default) ->
|
|||||||
end,
|
end,
|
||||||
case ejabberd_options:is_known(Key) of
|
case ejabberd_options:is_known(Key) of
|
||||||
true ->
|
true ->
|
||||||
try ejabberd_options:Key(Host) of
|
case ejabberd_options:Key(Host) of
|
||||||
Val -> prepare_opt_val(Opt, Val, F, Default)
|
{ok, Val} -> prepare_opt_val(Opt, Val, F, Default);
|
||||||
catch _:function_clause ->
|
undefined -> Default
|
||||||
Default
|
|
||||||
end;
|
end;
|
||||||
false ->
|
false ->
|
||||||
Default
|
Default
|
||||||
@ -896,46 +868,71 @@ has_option(Opt) ->
|
|||||||
get_option(Opt, fun(_) -> true end, false).
|
get_option(Opt, fun(_) -> true end, false).
|
||||||
|
|
||||||
init_module_db_table(Modules) ->
|
init_module_db_table(Modules) ->
|
||||||
catch ets:new(module_db, [named_table, public, bag,
|
|
||||||
{read_concurrency, true}]),
|
|
||||||
%% Dirty hack for mod_pubsub
|
%% Dirty hack for mod_pubsub
|
||||||
ets:insert(module_db, {mod_pubsub, mnesia}),
|
p1_options:insert(ejabberd_db_modules, mod_pubsub, mnesia, true),
|
||||||
ets:insert(module_db, {mod_pubsub, sql}),
|
p1_options:insert(ejabberd_db_modules, mod_pubsub, sql, true),
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun(M) ->
|
fun(M) ->
|
||||||
case re:split(atom_to_list(M), "_", [{return, list}]) of
|
case re:split(atom_to_list(M), "_", [{return, list}]) of
|
||||||
[_] ->
|
[_] ->
|
||||||
ok;
|
ok;
|
||||||
Parts ->
|
Parts ->
|
||||||
[Suffix|T] = lists:reverse(Parts),
|
[H|T] = lists:reverse(Parts),
|
||||||
BareMod = string:join(lists:reverse(T), "_"),
|
Suffix = list_to_atom(H),
|
||||||
ets:insert(module_db, {list_to_atom(BareMod),
|
BareMod = list_to_atom(string:join(lists:reverse(T), "_")),
|
||||||
list_to_atom(Suffix)})
|
case is_behaviour(BareMod, M) of
|
||||||
|
true ->
|
||||||
|
p1_options:insert(ejabberd_db_modules,
|
||||||
|
BareMod, Suffix, true);
|
||||||
|
false ->
|
||||||
|
ok
|
||||||
end
|
end
|
||||||
end, Modules).
|
end
|
||||||
|
end, Modules),
|
||||||
|
p1_options:compile(ejabberd_db_modules).
|
||||||
|
|
||||||
|
is_behaviour(Behav, Mod) ->
|
||||||
|
try Mod:module_info(attributes) of
|
||||||
|
[] ->
|
||||||
|
%% Stripped module?
|
||||||
|
true;
|
||||||
|
Attrs ->
|
||||||
|
lists:any(
|
||||||
|
fun({behaviour, L}) -> lists:member(Behav, L);
|
||||||
|
({behavior, L}) -> lists:member(Behav, L);
|
||||||
|
(_) -> false
|
||||||
|
end, Attrs)
|
||||||
|
catch _:_ ->
|
||||||
|
true
|
||||||
|
end.
|
||||||
|
|
||||||
-spec v_db(module(), atom()) -> atom().
|
-spec v_db(module(), atom()) -> atom().
|
||||||
|
|
||||||
v_db(Mod, internal) -> v_db(Mod, mnesia);
|
v_db(Mod, internal) -> v_db(Mod, mnesia);
|
||||||
v_db(Mod, odbc) -> v_db(Mod, sql);
|
v_db(Mod, odbc) -> v_db(Mod, sql);
|
||||||
v_db(Mod, Type) ->
|
v_db(Mod, Type) ->
|
||||||
case ets:match_object(module_db, {Mod, Type}) of
|
case ejabberd_db_modules:is_known(Mod) of
|
||||||
[_|_] -> Type;
|
true ->
|
||||||
[] -> erlang:error(badarg)
|
case ejabberd_db_modules:Mod(Type) of
|
||||||
|
{ok, _} -> Type;
|
||||||
|
_ -> erlang:error(badarg)
|
||||||
|
end;
|
||||||
|
false ->
|
||||||
|
erlang:error(badarg)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec v_dbs(module()) -> [atom()].
|
-spec v_dbs(module()) -> [atom()].
|
||||||
|
|
||||||
v_dbs(Mod) ->
|
v_dbs(Mod) ->
|
||||||
lists:flatten(ets:match(module_db, {Mod, '$1'})).
|
ejabberd_db_modules:get_scope(Mod).
|
||||||
|
|
||||||
-spec v_dbs_mods(module()) -> [module()].
|
-spec v_dbs_mods(module()) -> [module()].
|
||||||
|
|
||||||
v_dbs_mods(Mod) ->
|
v_dbs_mods(Mod) ->
|
||||||
lists:map(fun([M]) ->
|
lists:map(fun(M) ->
|
||||||
binary_to_atom(<<(atom_to_binary(Mod, utf8))/binary, "_",
|
binary_to_atom(<<(atom_to_binary(Mod, utf8))/binary, "_",
|
||||||
(atom_to_binary(M, utf8))/binary>>, utf8)
|
(atom_to_binary(M, utf8))/binary>>, utf8)
|
||||||
end, ets:match(module_db, {Mod, '$1'})).
|
end, v_dbs(Mod)).
|
||||||
|
|
||||||
-spec default_db(module()) -> atom().
|
-spec default_db(module()) -> atom().
|
||||||
default_db(Module) ->
|
default_db(Module) ->
|
||||||
@ -976,13 +973,18 @@ get_modules_with_options() ->
|
|||||||
init_module_db_table(AllMods),
|
init_module_db_table(AllMods),
|
||||||
lists:foldl(
|
lists:foldl(
|
||||||
fun(Mod, D) ->
|
fun(Mod, D) ->
|
||||||
case catch Mod:opt_type('') of
|
case is_behaviour(?MODULE, Mod) orelse Mod == ?MODULE of
|
||||||
|
true ->
|
||||||
|
try Mod:opt_type('') of
|
||||||
Opts when is_list(Opts) ->
|
Opts when is_list(Opts) ->
|
||||||
lists:foldl(
|
lists:foldl(
|
||||||
fun(Opt, Acc) ->
|
fun(Opt, Acc) ->
|
||||||
dict:append(Opt, Mod, Acc)
|
dict:append(Opt, Mod, Acc)
|
||||||
end, D, Opts);
|
end, D, Opts)
|
||||||
{'EXIT', {undef, _}} ->
|
catch _:undef ->
|
||||||
|
D
|
||||||
|
end;
|
||||||
|
false ->
|
||||||
D
|
D
|
||||||
end
|
end
|
||||||
end, dict:new(), AllMods).
|
end, dict:new(), AllMods).
|
||||||
@ -1022,23 +1024,21 @@ validate_opts(#state{opts = Opts} = State) ->
|
|||||||
|
|
||||||
%% Return the list of hosts with a given auth method
|
%% Return the list of hosts with a given auth method
|
||||||
get_vh_by_auth_method(AuthMethod) ->
|
get_vh_by_auth_method(AuthMethod) ->
|
||||||
Cfgs = mnesia:dirty_match_object(local_config,
|
Hosts = ejabberd_options:get_scope(auth_method),
|
||||||
#local_config{key = {auth_method, '_'},
|
get_vh_by_auth_method(AuthMethod, Hosts, []).
|
||||||
_ = '_'}),
|
|
||||||
lists:flatmap(
|
get_vh_by_auth_method(Method, [Host|Hosts], Result) ->
|
||||||
fun(#local_config{key = {auth_method, Host}, value = M}) ->
|
Methods = get_option({auth_method, Host}, fun(Ms) -> Ms end, []),
|
||||||
Methods = if not is_list(M) -> [M];
|
case lists:member(Method, Methods) of
|
||||||
true -> M
|
|
||||||
end,
|
|
||||||
case lists:member(AuthMethod, Methods) of
|
|
||||||
true when Host == global ->
|
true when Host == global ->
|
||||||
get_myhosts();
|
get_myhosts();
|
||||||
true ->
|
true ->
|
||||||
[Host];
|
get_vh_by_auth_method(Method, Hosts, [Host|Result]);
|
||||||
false ->
|
false ->
|
||||||
[]
|
get_vh_by_auth_method(Method, Hosts, Result)
|
||||||
end
|
end;
|
||||||
end, Cfgs).
|
get_vh_by_auth_method(_, [], Result) ->
|
||||||
|
Result.
|
||||||
|
|
||||||
%% @spec (Path::string()) -> true | false
|
%% @spec (Path::string()) -> true | false
|
||||||
is_file_readable(Path) ->
|
is_file_readable(Path) ->
|
||||||
@ -1445,64 +1445,3 @@ cache_missed(Host) ->
|
|||||||
%% NOTE: the integer value returned is in *seconds*
|
%% NOTE: the integer value returned is in *seconds*
|
||||||
cache_life_time(Host) ->
|
cache_life_time(Host) ->
|
||||||
get_option({cache_life_time, Host}, opt_type(cache_life_time), 3600).
|
get_option({cache_life_time, Host}, opt_type(cache_life_time), 3600).
|
||||||
|
|
||||||
%%%===================================================================
|
|
||||||
%%% Dynamic config compilation
|
|
||||||
%%%===================================================================
|
|
||||||
-spec recompile_options() -> ok.
|
|
||||||
recompile_options() ->
|
|
||||||
Exprs = get_exprs(),
|
|
||||||
case misc:compile_exprs(ejabberd_options, Exprs) of
|
|
||||||
ok -> ok;
|
|
||||||
{error, _} = Err ->
|
|
||||||
?CRITICAL_MSG("Failed to compile ejabberd_options:~n~s",
|
|
||||||
[string:join(Exprs, io_lib:nl())]),
|
|
||||||
erlang:error(Err)
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec get_exprs() -> [string()].
|
|
||||||
get_exprs() ->
|
|
||||||
Opts = lists:foldl(
|
|
||||||
fun(#local_config{key = {Opt, Host}, value = Val}, D) ->
|
|
||||||
Hosts = maps:get(Opt, D, #{}),
|
|
||||||
maps:put(Opt, maps:put(Host, Val, Hosts), D)
|
|
||||||
end, #{}, ets:tab2list(local_config)),
|
|
||||||
Funs = maps:fold(
|
|
||||||
fun(Opt, Vals, Acc) ->
|
|
||||||
HostVals = lists:reverse(lists:keysort(1, maps:to_list(Vals))),
|
|
||||||
[string:join(
|
|
||||||
lists:map(
|
|
||||||
fun({global, Val}) ->
|
|
||||||
io_lib:format("'~s'(_) -> ~p", [Opt, Val]);
|
|
||||||
({Host, Val}) ->
|
|
||||||
io_lib:format("'~s'(~p) -> ~p", [Opt, Host, Val])
|
|
||||||
end, HostVals),
|
|
||||||
";" ++ io_lib:nl()) ++ "."|Acc]
|
|
||||||
end, [], Opts),
|
|
||||||
Module = "-module(ejabberd_options).",
|
|
||||||
Export = "-compile(export_all).",
|
|
||||||
Knowns = maps:fold(
|
|
||||||
fun(Opt, _, Acc) ->
|
|
||||||
io_lib:format("is_known('~s') -> true;~n", [Opt]) ++ Acc
|
|
||||||
end, "", Opts) ++ "is_known(_) -> false.",
|
|
||||||
[Module, Export, Knowns|Funs].
|
|
||||||
|
|
||||||
%% @doc This is only for debugging purposes, likely to report a bug
|
|
||||||
-spec dump() -> ok.
|
|
||||||
dump() ->
|
|
||||||
ETSFile = filename:join("/tmp", "ejabberd_options.ets"),
|
|
||||||
ErlFile = filename:join("/tmp", "ejabberd_options.erl"),
|
|
||||||
ETSData = io_lib:format("~p~n", [ets:tab2list(local_config)]),
|
|
||||||
ErlData = io_lib:format("~s~n", [str:join(get_exprs(), io_lib:nl())]),
|
|
||||||
case file:write_file(ETSFile, ETSData) of
|
|
||||||
ok -> io:format("ETS data written to ~s~n", [ETSFile]);
|
|
||||||
{error, Reason1} ->
|
|
||||||
io:format("Failed to write to ~s: ~s",
|
|
||||||
[ETSFile, file:format_error(Reason1)])
|
|
||||||
end,
|
|
||||||
case file:write_file(ErlFile, ErlData) of
|
|
||||||
ok -> io:format("Dynamic module written to ~s~n", [ErlFile]);
|
|
||||||
{error, Reason2} ->
|
|
||||||
io:format("Failed to write to ~s: ~s",
|
|
||||||
[ErlFile, file:format_error(Reason2)])
|
|
||||||
end.
|
|
||||||
|
44
src/ejabberd_db_modules.erl
Normal file
44
src/ejabberd_db_modules.erl
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%% @doc
|
||||||
|
%%% This is a stub module which will be replaced during
|
||||||
|
%%% configuration load via p1_options:compile/1
|
||||||
|
%%% The only purpose of this file is to shut up xref/dialyzer
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 27 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
|
%%%
|
||||||
|
%%%
|
||||||
|
%%% ejabberd, Copyright (C) 2002-2017 ProcessOne
|
||||||
|
%%%
|
||||||
|
%%% This program is free software; you can redistribute it and/or
|
||||||
|
%%% modify it under the terms of the GNU General Public License as
|
||||||
|
%%% published by the Free Software Foundation; either version 2 of the
|
||||||
|
%%% License, or (at your option) any later version.
|
||||||
|
%%%
|
||||||
|
%%% This program is distributed in the hope that it will be useful,
|
||||||
|
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
%%% General Public License for more details.
|
||||||
|
%%%
|
||||||
|
%%% You should have received a copy of the GNU General Public License along
|
||||||
|
%%% with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
%%%
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(ejabberd_db_modules).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([is_known/1, get_scope/1]).
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% API
|
||||||
|
%%%===================================================================
|
||||||
|
is_known(_) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
get_scope(_) ->
|
||||||
|
[].
|
||||||
|
|
||||||
|
%%%===================================================================
|
||||||
|
%%% Internal functions
|
||||||
|
%%%===================================================================
|
@ -2,7 +2,7 @@
|
|||||||
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
%%% @author Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
%%% @doc
|
%%% @doc
|
||||||
%%% This is a stub module which will be replaced during
|
%%% This is a stub module which will be replaced during
|
||||||
%%% configuration load, see ejabberd_config:recompile_options/0.
|
%%% configuration load via p1_options:compile/1
|
||||||
%%% The only purpose of this file is to shut up xref/dialyzer
|
%%% The only purpose of this file is to shut up xref/dialyzer
|
||||||
%%% @end
|
%%% @end
|
||||||
%%% Created : 16 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
%%% Created : 16 Apr 2017 by Evgeny Khramtsov <ekhramtsov@process-one.net>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
-module(ejabberd_options).
|
-module(ejabberd_options).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([is_known/1]).
|
-export([is_known/1, get_scope/1]).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% API
|
%%% API
|
||||||
@ -36,6 +36,9 @@
|
|||||||
is_known(_) ->
|
is_known(_) ->
|
||||||
false.
|
false.
|
||||||
|
|
||||||
|
get_scope(_) ->
|
||||||
|
[].
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
|
Loading…
Reference in New Issue
Block a user