master-service-settings.c revision 8bf9eec2783abd32643578460cc6ba4ab0a647f9
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define DOVECOT_CONFIG_BIN_PATH BINDIR"/doveconf"
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen#define CONFIG_REQUEST_SERVICE "REQ\tservice=%s\n"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen { type, #name, offsetof(struct master_service_settings, name), NULL }
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic struct setting_define master_service_setting_defines[] = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic struct master_service_settings master_service_default_settings = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MEMBER(log_timestamp) DEFAULT_FAILURE_STAMP_FORMAT,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstruct setting_parser_info master_service_setting_parser_info = {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MEMBER(defines) master_service_setting_defines,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MEMBER(defaults) &master_service_default_settings,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen MEMBER(struct_size) sizeof(struct master_service_settings)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmaster_service_exec_config(struct master_service *service, bool preserve_home)
d41ebbd7ae8cfe36a570c644dd7c9c55073fbb20Timo Sirainen const char **conf_argv, *path, *const *paths, *binary_path;
8bf9eec2783abd32643578460cc6ba4ab0a647f9Timo Sirainen /* already have the path */
8bf9eec2783abd32643578460cc6ba4ab0a647f9Timo Sirainen } else if (strchr(service->argv[0], '/') != NULL) {
8bf9eec2783abd32643578460cc6ba4ab0a647f9Timo Sirainen /* relative to current directory */
8bf9eec2783abd32643578460cc6ba4ab0a647f9Timo Sirainen if (realpath(service->argv[0], full_path) == NULL)
8bf9eec2783abd32643578460cc6ba4ab0a647f9Timo Sirainen i_fatal("realpath(%s) failed: %m", service->argv[0]);
d41ebbd7ae8cfe36a570c644dd7c9c55073fbb20Timo Sirainen /* we have to find our executable from path */
d41ebbd7ae8cfe36a570c644dd7c9c55073fbb20Timo Sirainen path = t_strconcat(*paths, "/", binary_path, NULL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* @UNSAFE */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen conf_argv = t_new(const char *, 6 + (service->argc + 1) + 1);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_fatal("execv(%s) failed: %m", conf_argv[0]);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainenmaster_service_read_config(struct master_service *service, bool preserve_home,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen const char **error_r)
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen path = master_service_get_config_path(service);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *error_r = t_strdup_printf("net_connect_unix(%s) failed: %m",
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen if (stat(path, &st) == 0 && !S_ISFIFO(st.st_mode)) {
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen /* it's a file, not a socket */
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen master_service_exec_config(service, preserve_home);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen str = t_strdup_printf(CONFIG_HANDSHAKE CONFIG_REQUEST_SERVICE,
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen *error_r = t_strdup_printf("write_full(%s) failed: %m", path);
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainenmaster_service_apply_config_overrides(struct master_service *service,
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen const char **error_r)
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen const char *const *overrides;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen unsigned int i, count;
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen overrides = array_get(&service->config_overrides, &count);
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen for (i = 0; i < count; i++) {
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen if (settings_parse_line(parser, overrides[i]) < 0) {
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen settings_parse_set_key_expandeded(parser, service->set_pool,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint master_service_settings_read(struct master_service *service,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen const struct dynamic_settings_parser *dyn_parsers,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ARRAY_DEFINE(all_roots, const struct setting_parser_info *);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen unsigned int i;
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen fd = master_service_read_config(service, preserve_home,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen pool_alloconly_create("master service settings", 4096);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen settings_parser_info_update(service->set_pool, dyn_parsers);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen p_array_init(&all_roots, service->set_pool, 8);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen tmp_root = &master_service_setting_parser_info;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen parser = settings_parser_init_list(service->set_pool,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen array_idx(&all_roots, 0), array_count(&all_roots),
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen input = i_stream_create_fd(fd, (size_t)-1, FALSE);
d176f84ce5ca2073f4dfbafb457b9c74f6bf0d76Timo Sirainen ret = settings_parse_stream_read(parser, input);
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen /* let environment override settings. especially useful for the
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen settings from userdb. */
e3ae2ac7a93b418cf46e829c94973b6e962a7830Timo Sirainen settings_parse_set_keys_expandeded(parser, service->set_pool,
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen if (array_is_created(&service->config_overrides)) {
d39a04db2f4d0599cb9b5f03a9aa10a3c234453cTimo Sirainen if (master_service_apply_config_overrides(service, parser,
8c4b2e0734326ef8e534f25e8ee78ace1fc22d15Timo Sirainen if (!settings_parser_check(parser, service->set_pool, &error)) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen *error_r = t_strdup_printf("Invalid settings: %s", error);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (service->flags & MASTER_SERVICE_FLAG_STANDALONE) != 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* running standalone. we want to ignore plugin versions. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* if we change any settings afterwards, they're in expanded form.
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen especially all settings from userdb are already expanded. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen settings_parse_set_expanded(service->set_parser, TRUE);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenmaster_service_settings_get(struct master_service *service)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen sets = settings_parser_get_list(service->set_parser);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenvoid **master_service_settings_get_others(struct master_service *service)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen return settings_parser_get_list(service->set_parser) + 1;
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainenint master_service_set(struct master_service *service, const char *line)