Mercurial > dovecot > core-2.2
view src/imap/main.c @ 12782:447bce266022
Updated copyright notices to include year 2011.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 04 Mar 2011 20:54:29 +0200 |
parents | 0d455d1a9ea6 |
children | 9015f0b8fa4d |
line wrap: on
line source
/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */ #include "imap-common.h" #include "ioloop.h" #include "istream.h" #include "ostream.h" #include "abspath.h" #include "str.h" #include "base64.h" #include "process-title.h" #include "restrict-access.h" #include "fd-close-on-exec.h" #include "master-interface.h" #include "master-service.h" #include "master-login.h" #include "mail-user.h" #include "mail-storage-service.h" #include "imap-resp-code.h" #include "imap-commands.h" #include "imap-fetch.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define IS_STANDALONE() \ (getenv(MASTER_IS_PARENT_ENV) == NULL) #define IMAP_DIE_IDLE_SECS 10 static bool verbose_proctitle = FALSE; static struct mail_storage_service_ctx *storage_service; static struct master_login *master_login = NULL; imap_client_created_func_t *hook_client_created = NULL; imap_client_created_func_t * imap_client_created_hook_set(imap_client_created_func_t *new_hook) { imap_client_created_func_t *old_hook = hook_client_created; hook_client_created = new_hook; return old_hook; } void imap_refresh_proctitle(void) { #define IMAP_PROCTITLE_PREFERRED_LEN 80 struct client *client; struct client_command_context *cmd; string_t *title = t_str_new(128); if (!verbose_proctitle) return; str_append_c(title, '['); switch (imap_client_count) { case 0: str_append(title, "idling"); break; case 1: client = imap_clients; str_append(title, client->user->username); if (client->user->remote_ip != NULL) { str_append_c(title, ' '); str_append(title, net_ip2addr(client->user->remote_ip)); } for (cmd = client->command_queue; cmd != NULL; cmd = cmd->next) { if (cmd->name == NULL) continue; if (str_len(title) > IMAP_PROCTITLE_PREFERRED_LEN) break; str_append_c(title, ' '); str_append(title, cmd->name); } break; default: str_printfa(title, "%u connections", imap_client_count); break; } str_append_c(title, ']'); process_title_set(str_c(title)); } static void client_kill_idle(struct client *client) { if (client->output_lock != NULL) return; client_send_line(client, "* BYE Server shutting down."); client_destroy(client, "Server shutting down."); } static void imap_die(void) { struct client *client, *next; time_t last_io, now = time(NULL); time_t stop_timestamp = now - IMAP_DIE_IDLE_SECS; unsigned int stop_msecs; for (client = imap_clients; client != NULL; client = next) { next = client->next; last_io = I_MAX(client->last_input, client->last_output); if (last_io <= stop_timestamp) client_kill_idle(client); else { timeout_remove(&client->to_idle); stop_msecs = (last_io - stop_timestamp) * 1000; client->to_idle = timeout_add(stop_msecs, client_kill_idle, client); } } } struct client_input { const char *tag; const unsigned char *input; unsigned int input_size; bool send_untagged_capability; }; static void client_parse_input(const unsigned char *data, unsigned int len, struct client_input *input_r) { unsigned int taglen; i_assert(len > 0); memset(input_r, 0, sizeof(*input_r)); if (data[0] == '1') input_r->send_untagged_capability = TRUE; data++; len--; input_r->tag = t_strndup(data, len); taglen = strlen(input_r->tag) + 1; if (len > taglen) { input_r->input = data + taglen; input_r->input_size = len - taglen; } } static void client_add_input(struct client *client, const buffer_t *buf) { struct ostream *output; struct client_input input; if (buf != NULL && buf->used > 0) { client_parse_input(buf->data, buf->used, &input); if (input.input_size > 0 && !i_stream_add_data(client->input, input.input, input.input_size)) i_panic("Couldn't add client input to stream"); } else { /* IMAPLOGINTAG environment is compatible with mailfront */ memset(&input, 0, sizeof(input)); input.tag = getenv("IMAPLOGINTAG"); } output = client->output; o_stream_ref(output); o_stream_cork(output); if (input.tag == NULL) { client_send_line(client, t_strconcat( "* PREAUTH [CAPABILITY ", str_c(client->capability_string), "] " "Logged in as ", client->user->username, NULL)); } else if (input.send_untagged_capability) { /* client doesn't seem to understand tagged capabilities. send untagged instead and hope that it works. */ client_send_line(client, t_strconcat("* CAPABILITY ",