add_global_option/2, add_local_option/2,
get_global_option/1, get_local_option/1]).
-export([get_vh_by_auth_method/1]).
+-export([is_file_readable/1]).
-include("ejabberd.hrl").
-include("ejabberd_config.hrl").
+-include_lib("kernel/include/file.hrl").
%% @type macro() = {macro_key(), macro_value()}
%% @doc Load the ejabberd configuration file.
%% It also includes additional configuration files and replaces macros.
+%% This function will crash if finds some error in the configuration file.
%% @spec (File::string()) -> ok
load_file(File) ->
Terms = get_plain_terms_file(File),
{s2s_use_starttls, Port} ->
add_option(s2s_use_starttls, Port, State);
{s2s_certfile, CertFile} ->
- add_option(s2s_certfile, CertFile, State);
+ case ejabberd_config:is_file_readable(CertFile) of
+ true -> add_option(s2s_certfile, CertFile, State);
+ false ->
+ ErrorText = "There is a problem in the configuration: "
+ "the specified file is not readable: ",
+ throw({error, ErrorText ++ CertFile})
+ end;
{domain_certfile, Domain, CertFile} ->
- add_option({domain_certfile, Domain}, CertFile, State);
+ case ejabberd_config:is_file_readable(CertFile) of
+ true -> add_option({domain_certfile, Domain}, CertFile, State);
+ false ->
+ ErrorText = "There is a problem in the configuration: "
+ "the specified file is not readable: ",
+ throw({error, ErrorText ++ CertFile})
+ end;
{node_type, NodeType} ->
add_option(node_type, NodeType, State);
{cluster_nodes, Nodes} ->
mnesia:dirty_select(local_config,
[{#local_config{key = {auth_method, '$1'},
value=AuthMethod},[],['$1']}]).
+
+%% @spec (Path::string()) -> true | false
+is_file_readable(Path) ->
+ case file:read_file_info(Path) of
+ {ok, FileInfo} ->
+ case {FileInfo#file_info.type, FileInfo#file_info.access} of
+ {regular, read} -> true;
+ {regular, read_write} -> true;
+ _ -> false
+ end;
+ {error, _Reason} ->
+ false
+ end.
_ -> start_dependent(Port, Module, Opts)
end.
-%% -> {ok, Pid} | {error, ErrorMessage}
+%% @spec(Port, Module, Opts) -> {ok, Pid} | {error, ErrorMessage}
start_dependent(Port, Module, Opts) ->
- case includes_deprecated_ssl_option(Opts) of
- false ->
- proc_lib:start_link(?MODULE, init, [Port, Module, Opts]);
- true ->
- SSLErr="There is a problem with your ejabberd configuration file: "
- "the option 'ssl' for listening sockets is no longer available."
- "To get SSL encryption use the option 'tls'.",
- ?ERROR_MSG(SSLErr, []),
- {error, SSLErr}
- end.
-
-%% Parse the options of the socket,
-%% and return if the deprecated option 'ssl' is included
-%% @spec(Opts::[opt()]) -> true | false
-includes_deprecated_ssl_option(Opts) ->
- case lists:keysearch(ssl, 1, Opts) of
- {value, {ssl, _SSLOpts}} ->
- true;
- _ ->
- lists:member(ssl, Opts)
+ try check_listener_options(Opts) of
+ ok ->
+ proc_lib:start_link(?MODULE, init, [Port, Module, Opts])
+ catch
+ throw:{error, Error} ->
+ ?ERROR_MSG(Error, []),
+ {error, Error}
end.
init(PortIP, Module, Opts1) ->
%% where FrontMod = atom() | {frontend, atom()}
strip_frontend({frontend, Module}) -> Module;
strip_frontend(Module) when is_atom(Module) -> Module.
+
+
+%%%
+%%% Check options
+%%%
+
+check_listener_options(Opts) ->
+ case includes_deprecated_ssl_option(Opts) of
+ false -> ok;
+ true ->
+ Error = "There is a problem with your ejabberd configuration file: "
+ "the option 'ssl' for listening sockets is no longer available."
+ " To get SSL encryption use the option 'tls'.",
+ throw({error, Error})
+ end,
+ case certfile_readable(Opts) of
+ true -> ok;
+ {false, Path} ->
+ ErrorText = "There is a problem in the configuration: "
+ "the specified file is not readable: ",
+ throw({error, ErrorText ++ Path})
+ end,
+ ok.
+
+%% Parse the options of the socket,
+%% and return if the deprecated option 'ssl' is included
+%% @spec (Opts) -> true | false
+includes_deprecated_ssl_option(Opts) ->
+ case lists:keysearch(ssl, 1, Opts) of
+ {value, {ssl, _SSLOpts}} ->
+ true;
+ _ ->
+ lists:member(ssl, Opts)
+ end.
+
+%% @spec (Opts) -> true | {false, Path::string()}
+certfile_readable(Opts) ->
+ case proplists:lookup(certfile, Opts) of
+ none -> true;
+ {certfile, Path} ->
+ case ejabberd_config:is_file_readable(Path) of
+ true -> true;
+ false -> {false, Path}
+ end
+ end.