main.c revision 8d3278a82b964217d95c340ec6f82037cdc59d19
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic struct client_workaround_list client_workaround_list[] = {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore { "outlook-no-nuls", WORKAROUND_OUTLOOK_NO_NULS },
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid (*hook_client_created)(struct client **client) = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic char log_prefix[128]; /* syslog() needs this to be permanent */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* warn about being killed because of some signal, except SIGINT (^C)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore which is too common at least while testing :) */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore lib_signal_code_to_str(si->si_signo, si->si_code));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic void log_error_callback(void *context ATTR_UNUSED)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* the log fd is closed, don't die when trying to log later */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreparse_workarounds(const struct pop3_settings *set)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore enum client_workarounds client_workarounds = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore const char *const *str;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore str = t_strsplit_spaces(set->pop3_client_workarounds, " ,");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_fatal("Unknown client workaround: %s", *str);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic enum uidl_keys parse_uidl_keymask(const char *format)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (format[0] == '%' && format[1] != '\0') {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic void open_logfile(void)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_strocpy(log_prefix, getenv("LOG_PREFIX"), sizeof(log_prefix));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* quite a long user name, cut it */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore user = t_strndup(user, sizeof(log_prefix)-6-2);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_snprintf(log_prefix, sizeof(log_prefix), "pop3(%s): ", user);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore const char *env = getenv("SYSLOG_FACILITY");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_set_failure_syslog(log_prefix, LOG_NDELAY,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* log to file or stderr */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_set_failure_file(getenv("LOGFILE"), log_prefix);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_set_failure_timestamp_format(getenv("LOGSTAMP"));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic void main_preinit(const struct pop3_settings **set_r,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore const struct mail_user_settings **user_set_r)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (version != NULL && strcmp(version, PACKAGE_VERSION) != 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "Master is v%s, pop3 is v"PACKAGE_VERSION" "
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "(if you don't care, set version_ignore=yes)", version);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Log file or syslog opening probably requires roots */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* read settings after registering storages so they can have their
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore own setting definitions too */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* Load the plugins before chrooting. Their init() is called later. */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore modules = *(*user_set_r)->mail_plugins == '\0' ? NULL :
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore module_dir_load((*user_set_r)->mail_plugin_dir,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (*user_set_r)->mail_plugins, TRUE, version);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore restrict_access_by_env(getenv("HOME"), !IS_STANDALONE());
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic bool main_init(const struct pop3_settings *set,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* If master dies, the log fd gets closed and we'll quit */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore mail_users_init(user_set->auth_socket_path, set->mail_debug);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore user = mail_user_alloc(getenv("USER"), user_set);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_fatal("Mail user initialization failed: %s", error);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_fatal("Namespace initialization failed: %s", error);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore client->workarounds = parse_workarounds(set);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore client->uidl_keymask = parse_uidl_keymask(set->pop3_uidl_format);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_fatal("pop3_uidl_format setting doesn't contain any "
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "%% variables.");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (!i_stream_add_data(client->input, buf->data,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore i_panic("Couldn't add client input to stream");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic void main_deinit(void)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint main(int argc ATTR_UNUSED, char *argv[], char *envp[])
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (!IS_STANDALONE() && getenv("GDB") == NULL)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore printf("-ERR pop3 binary must not be started from "
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "inetd, use pop3-login instead.\n");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* NOTE: we start rooted, so keep the code minimal until
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore restrict_access_by_env() is called */