main.c revision 2421fd34d51fed6da985c62b5e078d7e96640653
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "common.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "ioloop.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "file-lock.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"
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen#include "base64.h"
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen#include "buffer.h"
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen#include "istream.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "process-title.h"
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen#include "module-dir.h"
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen#include "var-expand.h"
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen#include "dict.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "mail-storage.h"
e8490a52a1bc71bc53034e68f464435684ad810fTimo Sirainen#include "mail-namespace.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
ab0d9eecd85f74acae18fe88529302e0776cc500Timo Sirainenstatic struct 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_client_created)(struct client **client) = NULL;
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainenstatic struct module *modules = NULL;
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;
f99fab9747beba303a64e7db9026e3185425833dTimo Sirainenbool lock_session = FALSE;
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainenconst char *uidl_format, *logout_format;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainenenum uidl_keys uidl_keymask;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
43d32cbe60fdaef2699d99f1ca259053e9350411Timo 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
43d32cbe60fdaef2699d99f1ca259053e9350411Timo Sirainenstatic void log_error_callback(void *context ATTR_UNUSED)
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen{
2421fd34d51fed6da985c62b5e078d7e96640653Timo Sirainen /* the log fd is closed, don't die when trying to log later */
2421fd34d51fed6da985c62b5e078d7e96640653Timo Sirainen i_set_failure_ignore_errors(TRUE);
2421fd34d51fed6da985c62b5e078d7e96640653Timo 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
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen if (getenv("LOG_PREFIX") != NULL)
042a07daa4a5614159532a2a3878e76e3f176965Timo Sirainen i_strocpy(log_prefix, getenv("LOG_PREFIX"), sizeof(log_prefix));
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen else {
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen user = getenv("USER");
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen if (user == NULL) user = "??";
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen if (strlen(user) >= sizeof(log_prefix)-6) {
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen /* quite a long user name, cut it */
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen user = t_strndup(user, sizeof(log_prefix)-6-2);
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen user = t_strconcat(user, "..", NULL);
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen }
174a54c74848b8668acd72ddf36d9b4745e1ad5eTimo Sirainen i_snprintf(log_prefix, sizeof(log_prefix), "pop3(%s): ", user);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
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{
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen const char *version;
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen version = getenv("DOVECOT_VERSION");
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen if (version != NULL && strcmp(version, PACKAGE_VERSION) != 0) {
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen i_fatal("Dovecot version mismatch: "
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen "Master is v%s, pop3 is v"PACKAGE_VERSION" "
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen "(if you don't care, set version_ignore=yes)", version);
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen }
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* Log file or syslog opening probably requires roots */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen open_logfile();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen /* Load the plugins before chrooting. Their init() is called later. */
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen if (getenv("MAIL_PLUGINS") != NULL) {
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen const char *plugin_dir = getenv("MAIL_PLUGIN_DIR");
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen if (plugin_dir == NULL)
d4e141553b783ed96d0709ff52a6a41c0384206eTimo Sirainen plugin_dir = MODULEDIR"/pop3";
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen modules = module_dir_load(plugin_dir, getenv("MAIL_PLUGINS"),
41590df9f518459d66a9f7b9be2126f2e31fb221Timo Sirainen TRUE, version);
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen }
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen
e959e240bb8975cba293a94dbc61712b232904f6Timo Sirainen restrict_access_by_env(!IS_STANDALONE());
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainenstatic bool main_init(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen struct mail_user *user;
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen struct client *client;
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen const char *str;
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen bool ret = TRUE;
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);
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen lib_signals_ignore(SIGPIPE, TRUE);
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen lib_signals_ignore(SIGALRM, FALSE);
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
b725e5503d72a29a3eb18f93c1cbe597c4c31dcdTimo Sirainen if (getenv("STDERR_CLOSE_SHUTDOWN") != 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
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen dict_drivers_register_builtin();
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
c066a8aca1390e9db17214f0119db17eb6fdbe5aTimo Sirainen mail_storage_init();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail_storage_register_all();
84c8de119f2a07785796c0ff6aca20486ea576c5Timo Sirainen mailbox_list_register_all();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen clients_init();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
4449ad85fcbd4f6fedbaa9a5bdfe58a9ae60f8aeTimo Sirainen module_dir_init(modules);
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo 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;
f99fab9747beba303a64e7db9026e3185425833dTimo Sirainen lock_session = getenv("POP3_LOCK_SESSION") != NULL;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen uidl_format = getenv("POP3_UIDL_FORMAT");
9287a73641f0c4d56eb07c2000fc5293cfc8b4f4Timo Sirainen if (uidl_format == NULL || *uidl_format == '\0')
182a8b5b6e495bb590c38303e88b556a90468891Timo Sirainen uidl_format = "%08Xu%08Xv";
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen logout_format = getenv("POP3_LOGOUT_FORMAT");
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen if (logout_format == NULL)
9dd0fae306efb630d9b0dc1e4517cccbc8447164Timo Sirainen logout_format = "top=%t/%p, retr=%r/%b, 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
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen user = mail_user_init(getenv("USER"));
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen mail_user_set_home(user, getenv("HOME"));
092018b35bb1dc5bd61848a38189fe6ac8f791ddTimo Sirainen if (mail_namespaces_init(user) < 0)
da1444b45ce6ffaa0e6c423cf1a6a648e6223147Timo Sirainen i_fatal("Namespace initialization failed");
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen
d23c747de9d33966483fbdd41f08ad7766da7c5cTimo Sirainen client = client_create(0, 1, user);
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen if (client == NULL)
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen return FALSE;
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen
7753eaa6a4275e074b4ce8428b85d9d04fc67f31Timo Sirainen if (!IS_STANDALONE())
7753eaa6a4275e074b4ce8428b85d9d04fc67f31Timo Sirainen client_send_line(client, "+OK Logged in.");
7753eaa6a4275e074b4ce8428b85d9d04fc67f31Timo Sirainen
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen str = getenv("CLIENT_INPUT");
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen if (str != NULL) T_BEGIN {
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen buffer_t *buf = t_base64_decode_str(str);
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen if (buf->used > 0) {
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen if (!i_stream_add_data(client->input, buf->data,
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen buf->used))
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen i_panic("Couldn't add client input to stream");
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen ret = client_handle_input(client);
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen }
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen } T_END;
cd94aeaa294f7cc507206b4b2075852f00e14d61Timo Sirainen return ret;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void main_deinit(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen if (log_io != NULL)
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen io_remove(&log_io);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen clients_deinit();
bba9bf9760690778fcd46b8ce3a1390f60f7d816Timo Sirainen
bba9bf9760690778fcd46b8ce3a1390f60f7d816Timo Sirainen module_dir_unload(&modules);
bba9bf9760690778fcd46b8ce3a1390f60f7d816Timo Sirainen mail_storage_deinit();
67c47dbb3fde79218320fd38a45c33f61bbf3012Timo Sirainen mail_users_deinit();
e3fabe8d0faa9aab7cae2d0eee9653f581a3061dTimo Sirainen dict_drivers_unregister_builtin();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen lib_signals_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen closelog();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
43d32cbe60fdaef2699d99f1ca259053e9350411Timo 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);
b439928e47cb120eacee4ff1eb53156ae31d30dcTimo Sirainen ioloop = io_loop_create();
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}