Mercurial > dovecot > core-2.2
changeset 1212:9ced30dda6c3 HEAD
workaround: outlook-idle
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 20 Feb 2003 02:46:17 +0200 |
parents | 6fd1f2e82c9a |
children | fee90d8ad273 |
files | dovecot-example.conf src/imap/client.c src/imap/client.h src/imap/cmd-close.c src/imap/cmd-idle.c src/imap/cmd-select.c src/imap/cmd-unselect.c src/imap/commands-util.c src/imap/commands-util.h src/imap/common.h src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h |
diffstat | 12 files changed, 78 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Thu Feb 20 02:01:57 2003 +0200 +++ b/dovecot-example.conf Thu Feb 20 02:46:17 2003 +0200 @@ -220,6 +220,11 @@ # mailboxes are sent before any of their children. This is mostly # maildir-specific, mbox list replies are always sorted. MacOS X's Mail.app # at least wants this. +# outlook-idle: +# Outlook and Outlook Express never abort IDLE command, so if no mail +# arrives in half a hour, Dovecot closes the connection. This is still +# fine, except Outlook doesn't connect back so you don't see if new mail +# arrives. #client_workarounds = # Dovecot can notify client of new mail in selected mailbox soon after it's
--- a/src/imap/client.c Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/client.c Thu Feb 20 02:46:17 2003 +0200 @@ -22,9 +22,6 @@ /* Disconnect client when it sends too many bad commands in a row */ #define CLIENT_MAX_BAD_COMMANDS 20 -/* Disconnect client after idling this many seconds */ -#define CLIENT_IDLE_TIMEOUT (60*30) - extern struct mail_storage_callbacks mail_storage_callbacks; static struct client *my_client; /* we don't need more than one currently */ @@ -92,6 +89,9 @@ imap_parser_destroy(client->parser); io_remove(client->io); + if (client->idle_to != NULL) + timeout_remove(client->idle_to); + i_stream_unref(client->input); o_stream_unref(client->output);
--- a/src/imap/client.h Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/client.h Thu Feb 20 02:46:17 2003 +0200 @@ -34,6 +34,9 @@ const char *cmd_name; /* command name (allocated from parser pool) */ client_command_func_t *cmd_func; + struct timeout *idle_to; + unsigned int idle_expunge; + unsigned int cmd_error:1; unsigned int cmd_uid:1; /* used UID command */ unsigned int sync_flags_send_uid:1;
--- a/src/imap/cmd-close.c Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/cmd-close.c Thu Feb 20 02:46:17 2003 +0200 @@ -5,16 +5,18 @@ int cmd_close(struct client *client) { + struct mailbox *mailbox = client->mailbox; + if (!client_verify_open_mailbox(client)) return TRUE; - if (!client->mailbox->expunge(client->mailbox, FALSE)) - client_send_closing_mailbox_error(client); + client->mailbox = NULL; - if (!client->mailbox->close(client->mailbox)) - client_send_closing_mailbox_error(client); + if (!mailbox->expunge(mailbox, FALSE)) + client_send_untagged_storage_error(client); - client->mailbox = NULL; + if (!mailbox->close(mailbox)) + client_send_untagged_storage_error(client); client_send_tagline(client, "OK Close completed."); return TRUE;
--- a/src/imap/cmd-idle.c Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/cmd-idle.c Thu Feb 20 02:46:17 2003 +0200 @@ -11,6 +11,16 @@ static void idle_finish(struct client *client) { + if (client->idle_to != NULL) { + timeout_remove(client->idle_to); + client->idle_to = NULL; + } + + if (client->idle_expunge) { + client_send_line(client, + t_strdup_printf("* %u EXPUNGE", client->idle_expunge)); + } + io_remove(client->io); client->io = io_add(i_stream_get_fd(client->input), IO_READ, _client_input, client); @@ -60,6 +70,25 @@ } } +static void idle_timeout(void *context) +{ + struct client *client = context; + struct mailbox_status status; + + timeout_remove(client->idle_to); + client->idle_to = NULL; + + if (!client->mailbox->get_status(client->mailbox, STATUS_MESSAGES, + &status)) { + client_send_untagged_storage_error(client); + idle_finish(client); + } else { + client->idle_expunge = status.messages+1; + client_send_line(client, + t_strdup_printf("* %u EXISTS", client->idle_expunge)); + } +} + int cmd_idle(struct client *client) { const char *str; @@ -68,6 +97,12 @@ if (!client_verify_open_mailbox(client)) return TRUE; + client->idle_expunge = 0; + if ((client_workarounds & WORKAROUND_OUTLOOK_IDLE) != 0) { + client->idle_to = timeout_add((CLIENT_IDLE_TIMEOUT - 60) * 1000, + idle_timeout, client); + } + str = getenv("MAILBOX_IDLE_CHECK_INTERVAL"); interval = str == NULL ? 0 : (unsigned int)strtoul(str, NULL, 10); if (interval == 0)
--- a/src/imap/cmd-select.c Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/cmd-select.c Thu Feb 20 02:46:17 2003 +0200 @@ -14,9 +14,10 @@ return FALSE; if (client->mailbox != NULL) { - if (!client->mailbox->close(client->mailbox)) - client_send_closing_mailbox_error(client); + box = client->mailbox; client->mailbox = NULL; + if (!box->close(box)) + client_send_untagged_storage_error(client); } box = client->storage->open_mailbox(client->storage, mailbox,
--- a/src/imap/cmd-unselect.c Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/cmd-unselect.c Thu Feb 20 02:46:17 2003 +0200 @@ -5,13 +5,15 @@ int cmd_unselect(struct client *client) { + struct mailbox *mailbox = client->mailbox; + if (!client_verify_open_mailbox(client)) return TRUE; - if (!client->mailbox->close(client->mailbox)) - client_send_closing_mailbox_error(client); + client->mailbox = NULL; - client->mailbox = NULL; + if (!mailbox->close(mailbox)) + client_send_untagged_storage_error(client); client_send_tagline(client, "OK Unselect completed."); return TRUE;
--- a/src/imap/commands-util.c Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/commands-util.c Thu Feb 20 02:46:17 2003 +0200 @@ -121,11 +121,19 @@ error, NULL)); } -void client_send_closing_mailbox_error(struct client *client) +void client_send_untagged_storage_error(struct client *client) { const char *error; int syntax; + if (client->mailbox != NULL && + client->mailbox->is_inconsistency_error(client->mailbox)) { + /* we can't do forced CLOSE, so have to disconnect */ + client_disconnect_with_error(client, + "Mailbox is in inconsistent state, please relogin."); + return; + } + error = client->storage->get_last_error(client->storage, &syntax); client_send_line(client, t_strconcat(syntax ? "* BAD " : "* NO ", error, NULL));
--- a/src/imap/commands-util.h Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/commands-util.h Thu Feb 20 02:46:17 2003 +0200 @@ -26,9 +26,8 @@ /* Send last mail storage error message to client. */ void client_send_storage_error(struct client *client); -/* Send untagged error message to client. Doesn't check for inconsistency, - so should be called only by CLOSE, SELECT and UNSELECT. */ -void client_send_closing_mailbox_error(struct client *client); +/* Send untagged error message to client. */ +void client_send_untagged_storage_error(struct client *client); /* Parse flags. Returns TRUE if successful, if not sends an error message to client. */
--- a/src/imap/common.h Thu Feb 20 02:01:57 2003 +0200 +++ b/src/imap/common.h Thu Feb 20 02:46:17 2003 +0200 @@ -8,6 +8,9 @@ for command from user is around MAX_INBUF_SIZE * MAX_IMAP_ARG_ELEMENTS */ #define MAX_IMAP_ARG_ELEMENTS 128 +/* Disconnect client after idling this many seconds */ +#define CLIENT_IDLE_TIMEOUT (60*30) + #define DEFAULT_MAX_CUSTOM_FLAG_LENGTH 50 extern struct ioloop *ioloop;
--- a/src/lib-storage/mail-storage.c Thu Feb 20 02:01:57 2003 +0200 +++ b/src/lib-storage/mail-storage.c Thu Feb 20 02:46:17 2003 +0200 @@ -24,6 +24,7 @@ struct client_workaround_list client_workaround_list[] = { { "oe6-fetch-no-newmail", WORKAROUND_OE6_FETCH_NO_NEWMAIL }, { "list-sort", WORKAROUND_LIST_SORT }, + { "outlook-idle", WORKAROUND_OUTLOOK_IDLE }, { NULL, 0 } };
--- a/src/lib-storage/mail-storage.h Thu Feb 20 02:01:57 2003 +0200 +++ b/src/lib-storage/mail-storage.h Thu Feb 20 02:46:17 2003 +0200 @@ -92,7 +92,8 @@ enum client_workarounds { WORKAROUND_OE6_FETCH_NO_NEWMAIL = 0x01, - WORKAROUND_LIST_SORT = 0x02 + WORKAROUND_LIST_SORT = 0x02, + WORKAROUND_OUTLOOK_IDLE = 0x04 }; struct mail_full_flags {