main.c revision b728c54e411fd1964195497572ab7066138206cb
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "common.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "ioloop.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "lib-signals.h"
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen#include "restrict-access.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "fd-close-on-exec.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "process-title.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "randgen.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "module-dir.h"
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen#include "mail-storage.h"
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen#include <stdlib.h>
c000aa8509e03b4f7b0574f910d38a7e5e7e002aTimo Sirainen#include <syslog.h>
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#define IS_STANDALONE() \
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen (getenv("LOGGED_IN") == NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainenstruct ioloop *ioloop;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenvoid (*hook_mail_storage_created)(struct mail_storage **storage) = NULL;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenvoid (*hook_client_created)(struct client **client) = NULL;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic struct module *modules;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstatic char log_prefix[128]; /* syslog() needs this to be permanent */
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstatic void sig_quit(int signo __attr_unused__)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen{
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen io_loop_stop(ioloop);
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen}
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
43a2293a8bddfbeed84b29193c599071c44d17c7Timo Sirainenstatic void open_logfile(void)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen{
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen const char *user;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen user = getenv("USER");
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen if (user == NULL) user = "??";
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen if (strlen(user) >= sizeof(log_prefix)-6) {
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen /* quite a long user name, cut it */
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen user = t_strndup(user, sizeof(log_prefix)-6-2);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen user = t_strconcat(user, "..", NULL);
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen }
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen i_snprintf(log_prefix, sizeof(log_prefix), "pop3(%s)", user);
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen if (getenv("USE_SYSLOG") != NULL)
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen i_set_failure_syslog(log_prefix, LOG_NDELAY, LOG_MAIL);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen else {
f99fab9747beba303a64e7db9026e3185425833dTimo Sirainen /* log to file or stderr */
9439bed2f07d6475febd8a247cd2f0990fb32a13Timo Sirainen i_set_failure_file(getenv("LOGFILE"), log_prefix);
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen if (getenv("INFOLOGFILE") != NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_set_info_file(getenv("INFOLOGFILE"));
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen i_set_failure_timestamp_format(getenv("LOGSTAMP"));
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen}
321221ddc2dedc4ad79839770765adc40d311a0dTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void drop_privileges(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* Log file or syslog opening probably requires roots */
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen open_logfile();
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen /* Most likely needed. Have to open /dev/urandom before possible
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen chrooting. */
f9ef36afc131626754716d6f4874a2ad04da0ac4Timo Sirainen random_init();
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen restrict_access_by_env(!IS_STANDALONE());
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen}
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstatic int main_init(void)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen{
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen struct mail_storage *storage;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen const char *mail;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
8b63896feaef40e8c85fa00acdcc123b508e8d42Timo Sirainen lib_init_signals(sig_quit);
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen if (getenv("USER") == NULL)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen i_fatal("USER environment missing");
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen mail_storage_register_all();
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen clients_init();
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen modules = getenv("MODULE_DIR") == NULL ? NULL :
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen module_dir_load(getenv("MODULE_DIR"));
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen mail = getenv("MAIL");
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen if (mail == NULL) {
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen /* support also maildir-specific environment */
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen mail = getenv("MAILDIR");
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen if (mail != NULL)
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen mail = t_strconcat("maildir:", mail, NULL);
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen }
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen storage = mail_storage_create_with_data(mail, getenv("USER"),
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen NULL, '\0');
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen if (storage == NULL) {
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen /* failed */
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen if (mail != NULL && *mail != '\0')
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen i_fatal("Failed to create storage with data: %s", mail);
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen else {
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen const char *home;
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen home = getenv("HOME");
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen if (home == NULL) home = "not set";
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen
366d6311c9d5bac6613e3cd64619eb878adce9ecTimo Sirainen i_fatal("MAIL environment missing and "
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen "autodetection failed (home %s)", home);
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen }
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen }
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen if (hook_mail_storage_created != NULL)
00f5efa3156ab6a0b4f21e8c703d0eb816cf3091Timo Sirainen hook_mail_storage_created(&storage);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen return client_create(0, 1, storage) != NULL;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainenstatic void main_deinit(void)
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen{
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen /* warn about being killed because of some signal, except SIGINT (^C)
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen which is too common at least while testing :) */
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen if (lib_signal_kill != 0 && lib_signal_kill != 2)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_warning("Killed with signal %d", lib_signal_kill);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen module_dir_unload(modules);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen clients_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail_storage_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen random_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen closelog();
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen}
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainenint main(int argc __attr_unused__, char *argv[], char *envp[])
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen{
38a72d61d3a114816771f3045f374d56e2194232Timo Sirainen#ifdef DEBUG
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (getenv("LOGGED_IN") != NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen fd_debug_verify_leaks(3, 1024);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#endif
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
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (main_init())
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen io_loop_run(ioloop);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen main_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen io_loop_destroy(ioloop);
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen lib_deinit();
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen return 0;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen