main.c revision 39802a0699533868bf6054d73265b1ac99c225f5
b5ab29780f74cf88212a547ebbe3b6bc0cb867c5Stephan Bosch/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "imap-common.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "ioloop.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "istream.h"
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi#include "ostream.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "str.h"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include "base64.h"
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen#include "restrict-access.h"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include "fd-close-on-exec.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "process-title.h"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include "master-interface.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "master-service.h"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include "master-login.h"
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen#include "mail-user.h"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include "mail-storage-service.h"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include "imap-commands.h"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include "imap-fetch.h"
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen#include <stdio.h>
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#include <stdlib.h>
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi#include <unistd.h>
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi#define IS_STANDALONE() \
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi (getenv(MASTER_UID_ENV) == NULL)
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvistatic const struct setting_parser_info *set_roots[] = {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi &imap_setting_parser_info,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi NULL
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi};
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic struct master_login *master_login = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvistatic enum mail_storage_service_flags storage_service_flags = 0;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvistatic bool user_initialized = FALSE;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvivoid (*hook_client_created)(struct client **client) = NULL;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvistatic void client_add_input(struct client *client, const buffer_t *buf)
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi struct ostream *output;
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi const char *tag;
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi unsigned int data_pos;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi bool send_untagged_capability = FALSE;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if (buf != NULL && buf->used > 0) {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi tag = t_strndup(buf->data, buf->used);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi switch (*tag) {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi case '0':
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi tag++;
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi break;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi case '1':
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi send_untagged_capability = TRUE;
9b5576a265cbadb1f0b3c3d5e40e928e1fed1ec9Timo Sirainen tag++;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi break;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi }
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi data_pos = strlen(tag) + 1;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if (data_pos > buf->used &&
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi !i_stream_add_data(client->input,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi CONST_PTR_OFFSET(buf->data, data_pos),
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi buf->used - data_pos))
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi i_panic("Couldn't add client input to stream");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi } else {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* IMAPLOGINTAG environment is compatible with mailfront */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi tag = getenv("IMAPLOGINTAG");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi }
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi output = client->output;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi o_stream_ref(output);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi o_stream_cork(output);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if (tag == NULL) {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi client_send_line(client, t_strconcat(
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi "* PREAUTH [CAPABILITY ",
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi str_c(client->capability_string), "] "
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi "Logged in as ", client->user->username, NULL));
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi } else if (send_untagged_capability) {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* client doesn't seem to understand tagged capabilities. send
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi untagged instead and hope that it works. */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi client_send_line(client, t_strconcat("* CAPABILITY ",
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi str_c(client->capability_string), NULL));
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi client_send_line(client, t_strconcat(tag, " OK Logged in", NULL));
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi } else {
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi client_send_line(client, t_strconcat(
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi tag, " OK [CAPABILITY ",
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi str_c(client->capability_string), "] Logged in", NULL));
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen }
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi (void)client_handle_input(client);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi o_stream_uncork(output);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi o_stream_unref(&output);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainenstatic void
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvimain_stdio_init_user(const struct imap_settings *set, struct mail_user *user)
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi{
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen struct client *client;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi buffer_t *input_buf;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *input_base64;
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi input_base64 = getenv("CLIENT_INPUT");
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi input_buf = input_base64 == NULL ? NULL :
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi t_base64_decode_str(input_base64);
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen client = client_create(STDIN_FILENO, STDOUT_FILENO, user, set);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi client_add_input(client, input_buf);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainenstatic void main_stdio_run(void)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen{
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen struct mail_storage_service_input input;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen struct mail_user *mail_user;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen const struct imap_settings *set;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen const char *value;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen memset(&input, 0, sizeof(input));
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen input.module = input.service = "imap";
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen input.username = getenv("USER");
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if (input.username == NULL && IS_STANDALONE())
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen input.username = getlogin();
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if (input.username == NULL)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen i_fatal("USER environment missing");
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if ((value = getenv("IP")) != NULL)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen net_addr2ip(value, &input.remote_ip);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if ((value = getenv("LOCAL_IP")) != NULL)
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen net_addr2ip(value, &input.local_ip);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen user_initialized = TRUE;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen mail_user = mail_storage_service_init_user(master_service,
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen &input, set_roots,
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen storage_service_flags);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi set = mail_storage_service_get_settings(master_service);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi restrict_access_allow_coredumps(TRUE);
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi if (set->shutdown_clients)
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi master_service_set_die_with_master(master_service, TRUE);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi /* fake that we're running, so we know if client was destroyed
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi while handling its initial input */
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi io_loop_set_running(current_ioloop);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi main_stdio_init_user(set, mail_user);
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomistatic void
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomilogin_client_connected(const struct master_login_client *client,
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const char *username, const char *const *extra_fields)
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi{
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi struct mail_storage_service_input input;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi struct mail_user *mail_user;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi struct client *imap_client;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi const struct imap_settings *set;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi buffer_t input_buf;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen if (imap_clients != NULL) {
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen i_error("Can't handle more than one connection currently");
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen (void)close(client->fd);
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek return;
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek }
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek i_assert(!user_initialized);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen memset(&input, 0, sizeof(input));
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen input.module = input.service = "imap";
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen input.local_ip = client->auth_req.local_ip;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen input.remote_ip = client->auth_req.remote_ip;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen input.username = username;
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek input.userdb_fields = extra_fields;
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek if (input.username == NULL) {
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek i_error("login client: Username missing from auth reply");
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek (void)close(client->fd);
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek return;
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek }
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen user_initialized = TRUE;
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen master_login_deinit(&master_login);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek mail_user = mail_storage_service_init_user(master_service,
4ee65ee399f701f94adfe40489a87bdf5edca316Josef 'Jeff' Sipek &input, set_roots,
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen storage_service_flags);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen set = mail_storage_service_get_settings(master_service);
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi restrict_access_allow_coredumps(TRUE);
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi if (set->shutdown_clients)
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi master_service_set_die_with_master(master_service, TRUE);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi /* fake that we're running, so we know if client was destroyed
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi while handling its initial input */
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi io_loop_set_running(current_ioloop);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi buffer_create_const_data(&input_buf, client->data,
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi client->auth_req.data_size);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi imap_client = client_create(client->fd, client->fd, mail_user, set);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi T_BEGIN {
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi client_add_input(imap_client, &input_buf);
dead275d577c87b8f8ba476a7709db758dfffb9bTimo Sirainen } T_END;
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi}
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomistatic void client_connected(const struct master_service_connection *conn)
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi{
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi if (master_login == NULL) {
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi /* running standalone, we shouldn't even get here */
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi (void)close(conn->fd);
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi } else {
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi master_login_add(master_login, conn->fd);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen }
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi}
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomiint main(int argc, char *argv[], char *envp[])
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi{
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi enum master_service_flags service_flags = 0;
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi int c;
dfe2b5d36666dfc941821dadf59267d28ff58ff5Aki Tuomi
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen if (IS_STANDALONE() && getuid() == 0 &&
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen net_getpeername(1, NULL, NULL) == 0) {
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen printf("* BAD [ALERT] imap binary must not be started from "
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen "inetd, use imap-login instead.\n");
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen return 1;
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen }
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen if (IS_STANDALONE()) {
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen service_flags |= MASTER_SERVICE_FLAG_STANDALONE |
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen MASTER_SERVICE_FLAG_STD_CLIENT;
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen } else {
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen storage_service_flags |=
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT;
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen }
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen master_service = master_service_init("imap", service_flags, argc, argv);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen while ((c = getopt(argc, argv, master_service_getopt_string())) > 0) {
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen if (!master_service_parse_option(master_service, c, optarg))
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen exit(FATAL_DEFAULT);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen }
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen process_title_init(argv, envp);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen master_service_init_finish(master_service);
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen /* plugins may want to add commands, so this needs to be called early */
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen commands_init();
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen imap_fetch_handlers_init();
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen if (IS_STANDALONE()) {
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen T_BEGIN {
71acd1d082704ebabd034d3e73110b39fa5b7ef2Timo Sirainen main_stdio_run();
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen } T_END;
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen } else {
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen master_login = master_login_init("auth-master",
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen login_client_connected);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen io_loop_set_running(current_ioloop);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen }
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen if (io_loop_is_running(current_ioloop))
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi master_service_run(master_service, client_connected);
7ebda61d3fd228451530ca8faa33380105230ebeAki Tuomi clients_destroy_all();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi if (master_login != NULL)
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen master_login_deinit(&master_login);
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen if (user_initialized)
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen mail_storage_service_deinit_user();
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen imap_fetch_handlers_deinit();
796beea86bcdc92e4ba2f4865414a951b1717e5cTimo Sirainen commands_deinit();
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi master_service_deinit(&master_service);
d7a2f56cd0e550a92cb160b346f33a84b0daa75eTimo Sirainen return 0;
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi}
b28403dc4da6ee942ff18315596b43d4c4e9b7bdMartti Rannanjärvi