main.c revision f9ef36afc131626754716d6f4874a2ad04da0ac4
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "common.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "ioloop.h"
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen#include "network.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "lib-signals.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "restrict-access.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "fd-close-on-exec.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "process-title.h"
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen#include "randgen.h"
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen#include "module-dir.h"
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen#include "var-expand.h"
c000aa8509e03b4f7b0574f910d38a7e5e7e002aTimo Sirainen#include "dict-client.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "mail-storage.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen#include <stdio.h>
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include <stdlib.h>
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen#include <unistd.h>
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include <syslog.h>
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#define IS_STANDALONE() \
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen (getenv("LOGGED_IN") == NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstruct client_workaround_list {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen const char *name;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen enum client_workarounds num;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen};
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstruct client_workaround_list client_workaround_list[] = {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen { "outlook-no-nuls", WORKAROUND_OUTLOOK_NO_NULS },
43a2293a8bddfbeed84b29193c599071c44d17c7Timo Sirainen { "oe-ns-eoh", WORKAROUND_OE_NS_EOH },
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen { NULL, 0 }
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen};
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstruct ioloop *ioloop;
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainenvoid (*hook_mail_storage_created)(struct mail_storage **storage) = NULL;
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainenvoid (*hook_client_created)(struct client **client) = NULL;
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainenstatic struct module *modules;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic char log_prefix[128]; /* syslog() needs this to be permanent */
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainenstatic struct io *log_io = NULL;
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenenum client_workarounds client_workarounds = 0;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool enable_last_command = FALSE;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool no_flag_updates = FALSE;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenbool reuse_xuidl = FALSE;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenconst char *uidl_format, *logout_format;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainenenum uidl_keys uidl_keymask;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainenstatic void sig_die(int signo, void *context __attr_unused__)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen /* warn about being killed because of some signal, except SIGINT (^C)
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen which is too common at least while testing :) */
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen if (signo != SIGINT)
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen i_warning("Killed with signal %d", signo);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen io_loop_stop(ioloop);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainenstatic void log_error_callback(void *context __attr_unused__)
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen{
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen io_loop_stop(ioloop);
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen}
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstatic void parse_workarounds(void)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen{
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen struct client_workaround_list *list;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen const char *env, *const *str;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen env = getenv("POP3_CLIENT_WORKAROUNDS");
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen if (env == NULL)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen return;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
8b63896feaef40e8c85fa00acdcc123b508e8d42Timo Sirainen for (str = t_strsplit_spaces(env, " ,"); *str != NULL; str++) {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen list = client_workaround_list;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen for (; list->name != NULL; list++) {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen if (strcasecmp(*str, list->name) == 0) {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen client_workarounds |= list->num;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen break;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen }
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen }
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen if (list->name == NULL)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen i_fatal("Unknown client workaround: %s", *str);
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen }
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen}
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainenstatic enum uidl_keys parse_uidl_keymask(const char *format)
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen{
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen enum uidl_keys mask = 0;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen for (; *format != '\0'; format++) {
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen if (format[0] == '%' && format[1] != '\0') {
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen switch (var_get_key(++format)) {
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen case 'v':
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen mask |= UIDL_UIDVALIDITY;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen break;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen case 'u':
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen mask |= UIDL_UID;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen break;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen case 'm':
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen mask |= UIDL_MD5;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen break;
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen case 'f':
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen mask |= UIDL_FILE_NAME;
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen break;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen }
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen }
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen }
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen return mask;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen}
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void open_logfile(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen const char *user;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen if (getenv("LOG_TO_MASTER") != NULL) {
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen i_set_failure_internal();
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen return;
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen }
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen user = getenv("USER");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (user == NULL) user = "??";
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (strlen(user) >= sizeof(log_prefix)-6) {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* quite a long user name, cut it */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen user = t_strndup(user, sizeof(log_prefix)-6-2);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen user = t_strconcat(user, "..", NULL);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_snprintf(log_prefix, sizeof(log_prefix), "pop3(%s)", user);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen if (getenv("USE_SYSLOG") != NULL) {
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen const char *env = getenv("SYSLOG_FACILITY");
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen i_set_failure_syslog(log_prefix, LOG_NDELAY,
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen env == NULL ? LOG_MAIL : atoi(env));
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen } else {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* log to file or stderr */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_set_failure_file(getenv("LOGFILE"), log_prefix);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (getenv("INFOLOGFILE") != NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_set_info_file(getenv("INFOLOGFILE"));
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_set_failure_timestamp_format(getenv("LOGSTAMP"));
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void drop_privileges(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* Log file or syslog opening probably requires roots */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen open_logfile();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen /* Most likely needed. Have to open /dev/urandom before possible
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen chrooting. */
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen random_init();
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen restrict_access_by_env(!IS_STANDALONE());
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
67b785ce2485243c490f0a8b0753ac4a5d347265Timo Sirainenstatic int main_init(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen enum mail_storage_flags flags;
bf661a542d17273066e720b4f75868a1ff975a4cTimo Sirainen enum mail_storage_lock_method lock_method;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen struct mail_storage *storage;
6303fb1055fd85c3e3ca9320bc5754186dbd3a5aTimo Sirainen const char *mail;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen lib_signals_init();
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen lib_signals_set_handler(SIGTERM, TRUE, sig_die, NULL);
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen lib_signals_set_handler(SIGPIPE, FALSE, NULL, NULL);
130191cd9b8dfaf988fd28f9a7d52c1bddc24045Timo Sirainen lib_signals_set_handler(SIGALRM, FALSE, NULL, NULL);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (getenv("USER") == NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_fatal("USER environment missing");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
5ffb4d27772d2ad19d5e1e8136bbac4b7cdc0706Timo Sirainen if (getenv("DEBUG") != NULL) {
5ffb4d27772d2ad19d5e1e8136bbac4b7cdc0706Timo Sirainen i_info("Effective uid=%s, gid=%s",
5ffb4d27772d2ad19d5e1e8136bbac4b7cdc0706Timo Sirainen dec2str(geteuid()), dec2str(getegid()));
5ffb4d27772d2ad19d5e1e8136bbac4b7cdc0706Timo Sirainen }
5ffb4d27772d2ad19d5e1e8136bbac4b7cdc0706Timo Sirainen
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen if (getenv("LOG_TO_MASTER") != NULL) {
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen /* If master dies, the log fd gets closed and we'll quit */
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen log_io = io_add(STDERR_FILENO, IO_ERROR,
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen log_error_callback, NULL);
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen }
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen
c000aa8509e03b4f7b0574f910d38a7e5e7e002aTimo Sirainen dict_client_register();
c066a8aca1390e9db17214f0119db17eb6fdbe5aTimo Sirainen mail_storage_init();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail_storage_register_all();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen clients_init();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
457cafc9e72edb81eacfe88b35f14a75a96cf00aTimo Sirainen if (getenv("MODULE_LIST") == NULL)
457cafc9e72edb81eacfe88b35f14a75a96cf00aTimo Sirainen modules = NULL;
457cafc9e72edb81eacfe88b35f14a75a96cf00aTimo Sirainen else {
457cafc9e72edb81eacfe88b35f14a75a96cf00aTimo Sirainen if (getenv("MODULE_DIR") == NULL)
457cafc9e72edb81eacfe88b35f14a75a96cf00aTimo Sirainen i_fatal("MODULE_LIST given but MODULE_DIR was not");
457cafc9e72edb81eacfe88b35f14a75a96cf00aTimo Sirainen modules = module_dir_load(getenv("MODULE_DIR"),
457cafc9e72edb81eacfe88b35f14a75a96cf00aTimo Sirainen getenv("MODULE_LIST"), TRUE);
457cafc9e72edb81eacfe88b35f14a75a96cf00aTimo Sirainen }
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail = getenv("MAIL");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (mail == NULL) {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* support also maildir-specific environment */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail = getenv("MAILDIR");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (mail != NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail = t_strconcat("maildir:", mail, NULL);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
a1fa538bac7e5f18d507446e84be49a163c6697dTimo Sirainen
a1fa538bac7e5f18d507446e84be49a163c6697dTimo Sirainen parse_workarounds();
a1fa538bac7e5f18d507446e84be49a163c6697dTimo Sirainen enable_last_command = getenv("POP3_ENABLE_LAST") != NULL;
9beca5d6e1f018a7851a57117c036540d823957fTimo Sirainen no_flag_updates = getenv("POP3_NO_FLAG_UPDATES") != NULL;
63d6d0218e5945ad3a7d3fa02e6dc1be2982e257Timo Sirainen reuse_xuidl = getenv("POP3_REUSE_XUIDL") != NULL;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen uidl_format = getenv("POP3_UIDL_FORMAT");
9287a73641f0c4d56eb07c2000fc5293cfc8b4f4Timo Sirainen if (uidl_format == NULL || *uidl_format == '\0')
8aed62c664b031c5bb5965e62ba8530dba37fb80Timo Sirainen i_fatal("pop3_uidl_format setting is missing from config file");
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen logout_format = getenv("POP3_LOGOUT_FORMAT");
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen if (logout_format == NULL)
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen logout_format = "top=%t/%T, retr=%r/%R, del=%d/%m, size=%s";
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen uidl_keymask = parse_uidl_keymask(uidl_format);
afccb70aad7b6609144971e9db9ece96a5ed8dc9Timo Sirainen if (uidl_keymask == 0)
afccb70aad7b6609144971e9db9ece96a5ed8dc9Timo Sirainen i_fatal("pop3_uidl_format setting doesn't contain any "
afccb70aad7b6609144971e9db9ece96a5ed8dc9Timo Sirainen "%% variables.");
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen
6303fb1055fd85c3e3ca9320bc5754186dbd3a5aTimo Sirainen mail_storage_parse_env(&flags, &lock_method);
bf661a542d17273066e720b4f75868a1ff975a4cTimo Sirainen storage = mail_storage_create_with_data(mail, getenv("USER"),
bf661a542d17273066e720b4f75868a1ff975a4cTimo Sirainen flags, lock_method);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (storage == NULL) {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* failed */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (mail != NULL && *mail != '\0')
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_fatal("Failed to create storage with data: %s", mail);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen else {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen const char *home;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen home = getenv("HOME");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (home == NULL) home = "not set";
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_fatal("MAIL environment missing and "
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen "autodetection failed (home %s)", home);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen if (hook_mail_storage_created != NULL)
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen hook_mail_storage_created(&storage);
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen
966e9213f116ae8423634433106b02c833d9376bTimo Sirainen return client_create(0, 1, storage) != NULL;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void main_deinit(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen if (log_io != NULL)
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen io_remove(&log_io);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen module_dir_unload(&modules);
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen clients_deinit();
18d788657cff0fc3905b6a484d33c8c9fc2b9ebaTimo Sirainen mail_storage_deinit();
c000aa8509e03b4f7b0574f910d38a7e5e7e002aTimo Sirainen dict_client_unregister();
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen random_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen lib_signals_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen closelog();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenint main(int argc __attr_unused__, char *argv[], char *envp[])
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#ifdef DEBUG
b565c76999227da8db3670ec2f4b0c39690d8c40Timo Sirainen if (getenv("LOGGED_IN") != NULL && getenv("GDB") == NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen fd_debug_verify_leaks(3, 1024);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#endif
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen if (IS_STANDALONE() && getuid() == 0 &&
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen net_getpeername(1, NULL, NULL) == 0) {
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen printf("-ERR pop3 binary must not be started from "
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen "inetd, use pop3-login instead.\n");
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen return 1;
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen }
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* NOTE: we start rooted, so keep the code minimal until
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen restrict_access_by_env() is called */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen lib_init();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen drop_privileges();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen process_title_init(argv, envp);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen ioloop = io_loop_create(system_pool);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
67b785ce2485243c490f0a8b0753ac4a5d347265Timo Sirainen if (main_init())
67b785ce2485243c490f0a8b0753ac4a5d347265Timo Sirainen io_loop_run(ioloop);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen main_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen io_loop_destroy(&ioloop);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen lib_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen return 0;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}