]> granicus.if.org Git - ejabberd/commitdiff
Allow multiple definitions of host_config and append_host_config
authorEvgeny Khramtsov <ekhramtsov@process-one.net>
Fri, 21 Jun 2019 12:37:51 +0000 (15:37 +0300)
committerEvgeny Khramtsov <ekhramtsov@process-one.net>
Fri, 21 Jun 2019 12:37:51 +0000 (15:37 +0300)
src/ejabberd_config.erl
src/ejabberd_options.erl

index 3bfcf65d2a6661ba2e524ae89ca569272ee41279..1a6026fbf9d55a71e974e6b876705e2058ca63f8 100644 (file)
@@ -492,15 +492,9 @@ read_erlang_file(File, _) ->
            Err
     end.
 
--spec validate(term()) -> {ok, term()} | error_return().
+-spec validate(term()) -> {ok, [{atom(), term()}]} | error_return().
 validate(Y1) ->
-    case econf:validate(
-          econf:options(
-            #{hosts => ejabberd_options:opt_type(hosts),
-              loglevel => ejabberd_options:opt_type(loglevel),
-              '_' => econf:any()},
-            [{required, [hosts]}, unique]),
-          Y1) of
+    case pre_validate(Y1) of
        {ok, Y2} ->
            set_loglevel(proplists:get_value(loglevel, Y2, 4)),
            case ejabberd_config_transformer:map_reduce(Y2) of
@@ -522,6 +516,23 @@ validate(Y1) ->
            Err
     end.
 
+-spec pre_validate(term()) -> {ok, [{atom(), term()}]} | error_return().
+pre_validate(Y1) ->
+    case econf:validate(
+          econf:options(
+            #{hosts => ejabberd_options:opt_type(hosts),
+              loglevel => ejabberd_options:opt_type(loglevel),
+              host_config => econf:map(econf:binary(), econf:any()),
+              append_host_config => econf:map(econf:binary(), econf:any()),
+              '_' => econf:any()},
+            [{required, [hosts]}]),
+          Y1) of
+       {ok, Y2} ->
+           {ok, group_duplicated_options(Y2, [append_host_config, host_config])};
+       Err ->
+           Err
+    end.
+
 -spec load_file(file:filename_all()) -> ok | error_return().
 load_file(File) ->
     try
@@ -725,3 +736,17 @@ set_node_start(UnixTime) ->
 -spec set_loglevel(0..5) -> ok.
 set_loglevel(Level) ->
     ejabberd_logger:set(Level).
+
+-spec group_duplicated_options([{atom(), term()}], [atom()]) -> [{atom(), term()}].
+group_duplicated_options(Y1, Options) ->
+    {Y2, Y3} = lists:partition(
+                fun({Option, _}) ->
+                        lists:member(Option, Options)
+                end, Y1),
+    lists:foldl(
+      fun(Option, Y4) ->
+             case lists:flatten(proplists:get_all_values(Option, Y2)) of
+                 [] -> Y4;
+                 Values -> [{Option, Values}|Y4]
+             end
+      end, Y3, Options).
index e47ca6711de496db224bd74f8027fe88326e6e8b..c76d89ae18fd793ebc342dc06054bd833059eed5 100644 (file)
@@ -55,7 +55,8 @@ opt_type(append_host_config) ->
       econf:and_then(
        econf:domain(),
        econf:enum(ejabberd_option:hosts())),
-      validator());
+      validator(),
+      [unique]);
 opt_type(auth_cache_life_time) ->
     econf:timeout(second, infinity);
 opt_type(auth_cache_missed) ->
@@ -145,7 +146,8 @@ opt_type(host_config) ->
       econf:and_then(
        econf:domain(),
        econf:enum(ejabberd_option:hosts())),
-      validator());
+      validator(),
+      [unique]);
 opt_type(hosts) ->
     econf:non_empty(econf:list(econf:domain(), [unique]));
 opt_type(include_config_file) ->