]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-settings, config: Add setting_parser_info.plugin_dependency
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 3 Mar 2025 12:30:46 +0000 (14:30 +0200)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Sat, 8 Mar 2025 06:56:18 +0000 (06:56 +0000)
If set, the referred plugin must actually exist on filesystem before its
settings are used. This allows spltting core plugins to separate packages
so that the settings are hidden unless the packages are installed.

src/config/config-parser.c
src/lib-settings/settings-parser.h

index 751ffb0fc2f362e7a6de17693e95269a65b42dd5..84b87ea90e2f1c5f7ac0529db99059807a93e9c0 100644 (file)
@@ -3223,6 +3223,16 @@ static int config_service_cmp(const struct config_service *s1,
        return strcmp(s1->set->name, s2->set->name);
 }
 
+static bool config_have_info_dependency(const struct setting_parser_info *info)
+{
+       if (info->plugin_dependency == NULL)
+               return TRUE;
+       const char *path = t_strconcat(MODULEDIR"/", info->plugin_dependency,
+                                      MODULE_SUFFIX, NULL);
+       struct stat st;
+       return stat(path, &st) == 0;
+}
+
 void config_parse_load_modules(bool dump_config_import)
 {
        struct module_dir_load_settings mod_set;
@@ -3241,6 +3251,12 @@ void config_parse_load_modules(bool dump_config_import)
        config_import = str_new(default_pool, 10240);
        str_append(config_import, stats_metric_defaults);
        i_array_init(&new_infos, 64);
+       /* drop any default infos which depend on plugins that don't exist */
+       for (i = 0; all_infos[i] != NULL; i++) {
+               if (config_have_info_dependency(all_infos[i]))
+                       array_push_back(&new_infos, &all_infos[i]);
+       }
+
        i_array_init(&new_services, 64);
        for (m = modules; m != NULL; m = m->next) {
                infos = module_get_symbol_quiet(m,
@@ -3272,17 +3288,10 @@ void config_parse_load_modules(bool dump_config_import)
                        }
                }
        }
-       if (array_count(&new_infos) > 0) {
-               /* modules added new settings. add the defaults and start
-                  using the new list. */
-               for (i = 0; all_infos[i] != NULL; i++)
-                       array_push_back(&new_infos, &all_infos[i]);
-               array_append_zero(&new_infos);
-               all_infos = array_front(&new_infos);
-               infos_free_at_deinit = new_infos;
-       } else {
-               array_free(&new_infos);
-       }
+       array_append_zero(&new_infos);
+       all_infos = array_front(&new_infos);
+       infos_free_at_deinit = new_infos;
+
        if (array_count(&new_services) > 0) {
                /* module added new services. update the defaults. */
                for (i = 0; config_all_services[i].set != NULL; i++)
index ee0f49c3607733caf44f48170a95a2723ae2bcc0..38bf623413a228e0469bc03407f89d4cb77488c2 100644 (file)
@@ -156,6 +156,12 @@ struct setting_keyvalue {
 struct setting_parser_info {
        /* Unique name for the settings struct */
        const char *name;
+       /* If non-NULL, config process verifies whether this plugin actually
+          exists on filesystem before exposing these settings. This allows
+          for example the plugins in Dovecot core to be extracted into
+          separate optional packages, even though they don't have individual
+          settings plugins. */
+       const char *plugin_dependency;
 
        const struct setting_define *defines;
        const void *defaults;