main.c revision ab8e7c30442b7f625d074336430ea44bbf2b2978
5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "common.h"
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen#include "ioloop.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "network.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "ostream.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "str.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "lib-signals.h"
abf015c9682f0f723db87a7c97bc284ef814818fTimo Sirainen#include "restrict-access.h"
70afae43cc78ea6ecca83f6c587072c442a15ec1Timo Sirainen#include "fd-close-on-exec.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "process-title.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "randgen.h"
fa2a11210f20fb8998ed656f75e163191c8047e6Timo Sirainen#include "module-dir.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "mail-storage.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "commands.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include "namespace.h"
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen#include <stdio.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <stdlib.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <unistd.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#include <syslog.h>
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#define IS_STANDALONE() \
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen (getenv("LOGGED_IN") == NULL && getenv("IMAPLOGINTAG") == NULL)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstruct client_workaround_list {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen const char *name;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen enum client_workarounds num;
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen};
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainenstruct client_workaround_list client_workaround_list[] = {
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen { "delay-newmail", WORKAROUND_DELAY_NEWMAIL },
542e28b384a6b26695f3e8de38fd5727d06f3333Timo Sirainen { "outlook-idle", WORKAROUND_OUTLOOK_IDLE },
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen { "netscape-eoh", WORKAROUND_NETSCAPE_EOH },
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen { NULL, 0 }
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen};
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainenstruct ioloop *ioloop;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainenunsigned int max_keyword_length;
3b22894b8805b186c73d8b754001e8d7e944be85Timo Sirainenunsigned int imap_max_line_length;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenenum client_workarounds client_workarounds = 0;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic struct module *modules;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic char log_prefix[128]; /* syslog() needs this to be permanent */
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenstatic pool_t namespace_pool;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenvoid (*hook_mail_storage_created)(struct mail_storage *storage) = NULL;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainenvoid (*hook_client_created)(struct client **client) = NULL;
13b063ba3ea51256fd97d7fa883f14cb08842b0dTimo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstring_t *capability_string;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void sig_quit(int signo __attr_unused__)
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen{
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen io_loop_stop(ioloop);
49621bf0ef1d55aaaa2dc7d76011cbfeabdcfbe1Timo Sirainen}
fa2433aebcf3fccfa30ca9eed9b1a9166cf92ee2Timo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainenstatic void parse_workarounds(void)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct client_workaround_list *list;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen const char *env, *const *str;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen env = getenv("IMAP_CLIENT_WORKAROUNDS");
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen if (env == NULL)
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen return;
3482fee0e3733456512ba110780824e6daa7ff9fTimo Sirainen
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen for (str = t_strsplit_spaces(env, " "); *str != NULL; str++) {
12797080b552a3c1727b73b61cc7427bec0c7472Timo Sirainen list = client_workaround_list;
49fd8c950e3da2ed32506e617a4b1480a07f874fTimo Sirainen for (; list->name != NULL; list++) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (strcasecmp(*str, list->name) == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen client_workarounds |= list->num;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen break;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen }
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen }
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen if (list->name == NULL)
b9b841558c5f91db7f5fc71c0ac62aad1bbf6418Timo Sirainen i_fatal("Unknown client workaround: %s", *str);
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainen }
1388b590dbd85245b591346f860bc1319953318aTimo Sirainen}
ab90f702ceedb7ba445a9a592be0b213b27cbafaStephan Bosch
1388b590dbd85245b591346f860bc1319953318aTimo Sirainenstatic void open_logfile(void)
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen{
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen const char *user;
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen if (getenv("LOG_TO_MASTER") != NULL) {
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch i_set_failure_internal();
e438c85a6b0f77889e25913bbbba808d6078282dStephan Bosch return;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen }
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
38f227941bcf673e0e523c1ac7267bca9cbcd2c4Timo Sirainen user = getenv("USER");
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (user == NULL) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (IS_STANDALONE())
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen user = getlogin();
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (user == NULL)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen user = "??";
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (strlen(user) >= sizeof(log_prefix)-6) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* quite a long user name, cut it */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen user = t_strndup(user, sizeof(log_prefix)-6-2);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen user = t_strconcat(user, "..", NULL);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_snprintf(log_prefix, sizeof(log_prefix), "imap(%s)", user);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (getenv("USE_SYSLOG") != NULL)
2eb2cf8eeb763bd5ca9b6848dce32f0303e88ec1Timo Sirainen i_set_failure_syslog(log_prefix, LOG_NDELAY, LOG_MAIL);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen else {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* log to file or stderr */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_set_failure_file(getenv("LOGFILE"), log_prefix);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (getenv("INFOLOGFILE") != NULL)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_set_info_file(getenv("INFOLOGFILE"));
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_set_failure_timestamp_format(getenv("LOGSTAMP"));
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic void drop_privileges(void)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* Log file or syslog opening probably requires roots */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen open_logfile();
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* Most likely needed. Have to open /dev/urandom before possible
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen chrooting. */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen random_init();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen restrict_access_by_env(!IS_STANDALONE());
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic void main_init(void)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen struct client *client;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen const char *user, *str;
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen lib_init_signals(sig_quit);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen user = getenv("USER");
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (user == NULL) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (IS_STANDALONE())
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen user = getlogin();
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (user == NULL)
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen i_fatal("USER environment missing");
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen }
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen if (getenv("DEBUG") != NULL) {
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen i_info("Effective uid=%s, gid=%s",
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen dec2str(geteuid()), dec2str(getegid()));
7af5f78e9fee296e42430d94ef252ff0333d8024Timo Sirainen }
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen capability_string = str_new(default_pool, sizeof(CAPABILITY_STRING)+32);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen str_append(capability_string, CAPABILITY_STRING);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen mail_storage_init();
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen mail_storage_register_all();
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen clients_init();
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen commands_init();
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen modules = getenv("MODULE_DIR") == NULL ? NULL :
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen module_dir_load(getenv("MODULE_DIR"), TRUE);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen str = getenv("IMAP_MAX_LINE_LENGTH");
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen imap_max_line_length = str != NULL ?
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen (unsigned int)strtoul(str, NULL, 10) :
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen DEFAULT_IMAP_MAX_LINE_LENGTH;
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen str = getenv("MAIL_MAX_KEYWORD_LENGTH");
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen max_keyword_length = str != NULL ?
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen (unsigned int)strtoul(str, NULL, 10) :
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen DEFAULT_MAX_KEYWORD_LENGTH;
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen parse_workarounds();
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen namespace_pool = pool_alloconly_create("namespaces", 1024);
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen client = client_create(0, 1, namespace_init(namespace_pool, user));
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen
1f5597beba229acd914e30a6da3c0e62d83b6e8fTimo Sirainen o_stream_cork(client->output);
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen if (IS_STANDALONE()) {
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen client_send_line(client, t_strconcat(
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen "* PREAUTH [CAPABILITY "CAPABILITY_STRING"] "
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen "Logged in as ", user, NULL));
47569a4b2b4d3cc55e786177798c922c3c44233dTimo Sirainen } else if (getenv("IMAPLOGINTAG") != NULL) {
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* Support for mailfront */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen client_send_line(client, t_strconcat(getenv("IMAPLOGINTAG"),
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen " OK Logged in.", NULL));
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen }
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen o_stream_uncork(client->output);
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen}
417642ddac19708bea6dd2c2bbeaf6a9578d521bTimo Sirainen
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainenstatic void main_deinit(void)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen{
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen /* warn about being killed because of some signal, except SIGINT (^C)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen which is too common at least while testing :) */
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen if (lib_signal_kill != 0 && lib_signal_kill != 2)
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen i_warning("Killed with signal %d", lib_signal_kill);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen module_dir_unload(modules);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen commands_deinit();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen clients_deinit();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen mail_storage_deinit();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen random_deinit();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen pool_unref(namespace_pool);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen str_free(capability_string);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen closelog();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen}
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenint main(int argc __attr_unused__, char *argv[], char *envp[])
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen{
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#ifdef DEBUG
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (getenv("LOGGED_IN") != NULL && getenv("GDB") == NULL)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen fd_debug_verify_leaks(3, 1024);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen#endif
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (IS_STANDALONE() && getuid() == 0 &&
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen net_getpeername(1, NULL, NULL) == 0) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen printf("* BAD [ALERT] imap binary must not be started from "
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen "inetd, use imap-login instead.\n");
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen return 1;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen }
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* NOTE: we start rooted, so keep the code minimal until
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen restrict_access_by_env() is called */
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen lib_init();
002179a890bf4f1942cad6463787719eaa9fd6c0Timo Sirainen drop_privileges();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen process_title_init(argv, envp);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen ioloop = io_loop_create(system_pool);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen main_init();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen io_loop_run(ioloop);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen main_deinit();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen io_loop_destroy(ioloop);
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen lib_deinit();
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen return 0;
f3e17726502b6cf1912f30aae7e283b5d31ea69cTimo Sirainen}
c07d7eb3ca9754367697c98f5e66a3982a45d142Timo Sirainen