-/* Copyright (C) 2005 Timo Sirainen */
+/* Copyright (C) 2005-2009 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "str.h"
#include "network.h"
#include "istream.h"
#include "ostream.h"
+#include "env-util.h"
#include "config-connection.h"
#include <stdlib.h>
config_connection_request(conn, args);
config_connection_destroy(conn);
}
+
+void config_connection_putenv(void)
+{
+ const char *env, *p, *key, *value;
+
+ env = str_c(config_string);
+ for (; *env != '\0'; env = p + 1) {
+ p = strchr(env, '\n');
+ if (env == p || p == NULL)
+ break;
+
+ T_BEGIN {
+ value = strchr(env, '=');
+ i_assert(value != NULL && value < p);
+ key = t_str_ucase(t_strdup_until(env, value));
+ value = t_strdup_until(value, p);
+ env_put(t_strconcat(key, value, NULL));
+ } T_END;
+ }
+}
void config_connection_destroy(struct config_connection *conn);
void config_connection_dump_request(int fd, const char *service);
+void config_connection_putenv(void);
#endif
-/* Copyright (C) 2005 Timo Sirainen */
+/* Copyright (C) 2005-2009 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
-/* Copyright (C) 2005-2008 Timo Sirainen */
+/* Copyright (C) 2005-2009 Dovecot authors, see the included COPYING file */
#include "common.h"
#include "lib-signals.h"
#include "ioloop.h"
+#include "env-util.h"
#include "str.h"
#include "config-connection.h"
#include "config-parser.h"
static void main_init(const char *service)
{
- i_set_failure_internal();
+ if (getenv("LOG_TO_MASTER") != NULL)
+ i_set_failure_internal();
parsers_pool = pool_alloconly_create("parent parsers", 2048);
config_parsers_fix_parents(parsers_pool);
int main(int argc, char *argv[])
{
struct ioloop *ioloop;
- const char *path, *service = "";
+ const char *service = "";
+ char **exec_args = NULL;
bool dump_nondefaults = FALSE, human_readable = FALSE;
- int c;
+ int i;
lib_init();
- path = getenv("CONFIG_FILE_PATH");
- if (path != NULL)
- config_path = path;
-
- while ((c = getopt(argc, argv, "c:s:na")) > 0) {
- switch (c) {
- case 'c':
- config_path = optarg;
- break;
- case 's':
- service = optarg;
- break;
- case 'n':
- dump_nondefaults = TRUE;
- /* fall through */
- case 'a':
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-a") == 0) {
/* FIXME: make it work */
human_readable = TRUE;
+ } else if (strcmp(argv[i], "-c") == 0) {
+ /* config file */
+ i++;
+ if (i == argc) i_fatal("Missing config file argument");
+ config_path = argv[i];
+ } else if (strcmp(argv[i], "-n") == 0) {
+ dump_nondefaults = TRUE;
+ human_readable = TRUE;
+ } else if (strcmp(argv[i], "-s") == 0) {
+ /* service */
+ i++;
+ if (i == argc) i_fatal("Missing service argument");
+ service = argv[i];
+ } else if (strcmp(argv[i], "--exec") == 0) {
+ /* <command> [<args>] */
+ i++;
+ if (i == argc) i_fatal("Missing exec binary argument");
+ exec_args = &argv[i];
break;
- default:
- i_fatal("Unknown parameter: %c", c);
+ } else {
+ i_fatal("Unknown parameter: %s", argv[i]);
}
}
main_init(service);
ioloop = io_loop_create();
- config_connection_dump_request(STDOUT_FILENO, "master");
+ if (exec_args == NULL)
+ config_connection_dump_request(STDOUT_FILENO, "master");
+ else {
+ config_connection_putenv();
+ env_put("DOVECONF_ENV=1");
+ execvp(exec_args[0], exec_args);
+ i_fatal("execvp(%s) failed: %m", exec_args[0]);
+ }
io_loop_destroy(&ioloop);
lib_deinit();
return 0;
#include "deliver-settings.h"
#include <stddef.h>
-
-#define DOVECOT_CONFIG_BIN_PATH BINDIR"/doveconf"
+#include <stdlib.h>
#undef DEF
#undef DEFLIST
}
struct setting_parser_context *
-deliver_settings_read(const char *path,
- struct deliver_settings **set_r,
+deliver_settings_read(struct deliver_settings **set_r,
struct mail_user_settings **user_set_r)
{
static const struct setting_parser_info *roots[] = {
parser = settings_parser_init_list(settings_pool,
roots, N_ELEMENTS(roots),
SETTINGS_PARSER_FLAG_IGNORE_UNKNOWN_KEYS);
- if (settings_parse_exec(parser, DOVECOT_CONFIG_BIN_PATH,
- path, "lda") < 0) {
+
+ if (settings_parse_environ(parser) < 0) {
i_fatal_status(EX_CONFIG, "Error reading configuration: %s",
settings_parser_get_error(parser));
}
};
struct setting_parser_context *
-deliver_settings_read(const char *path,
- struct deliver_settings **set_r,
+deliver_settings_read(struct deliver_settings **set_r,
struct mail_user_settings **user_set_r);
void deliver_settings_add(struct setting_parser_context *parser,
const ARRAY_TYPE(const_string) *extra_fields);
bool stderr_rejection = FALSE;
bool keep_environment = FALSE;
bool user_auth = FALSE;
+ bool doveconf_env;
time_t mtime;
int i, ret;
pool_t userdb_pool = NULL;
}
}
+ doveconf_env = getenv("DOVECONF_ENV") != NULL;
if (user == NULL)
user = getenv("USER");
- if (!keep_environment)
+ if (!keep_environment && !doveconf_env) {
deliver_env_clean(!user_auth);
+ env_put(t_strconcat("USER=", user, NULL));
+ }
+ if (!doveconf_env) {
+ /* currently we need to be executed via doveconf. */
+#define DOVECOT_CONFIG_BIN_PATH BINDIR"/doveconf"
+ const char **conf_argv;
+
+ conf_argv = i_new(const char *, 6 + (argc + 1) + 1);
+ conf_argv[0] = DOVECOT_CONFIG_BIN_PATH;
+ conf_argv[1] = "-s";
+ conf_argv[2] = "lda";
+ conf_argv[3] = "-c";
+ conf_argv[4] = config_path;
+ conf_argv[5] = "--exec";
+ memcpy(conf_argv+6, argv, (argc+1) * sizeof(argv[0]));
+ execv(conf_argv[0], (char **)conf_argv);
+ i_fatal_status(EX_CONFIG, "execv(%s) failed: %m", conf_argv[0]);
+ }
process_euid = geteuid();
if (user_auth)
mail_storage_register_all();
mailbox_list_register_all();
- parser = deliver_settings_read(config_path, &deliver_set, &user_set);
+ parser = deliver_settings_read(&deliver_set, &user_set);
open_logfile(user);
mail_set = mail_user_set_get_driver_settings(user_set, "MAIL");
string_t *all_settings;
int ret;
+ env_put("LOG_TO_MASTER=1");
+
all_settings = str_new(default_pool, 10240);
parser = settings_parser_init(settings_pool,
&master_setting_parser_info,