changeset 2316:1c1ed4494aa4 HEAD

Split client_workarounds to imap_ and pop3_ ones. Added outlook-no-nuls POP3 workaround.
author Timo Sirainen <tss@iki.fi>
date Sat, 10 Jul 2004 20:24:08 +0300
parents 22210d6cf238
children 0cf316c77b1b
files dovecot-example.conf src/imap/common.h src/imap/main.c src/lib-storage/mail-storage.c src/lib-storage/mail-storage.h src/master/mail-process.c src/master/master-settings.c src/master/master-settings.h src/pop3/commands.c src/pop3/common.h src/pop3/main.c
diffstat 11 files changed, 117 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/dovecot-example.conf	Sat Jul 10 14:16:05 2004 +0300
+++ b/dovecot-example.conf	Sat Jul 10 20:24:08 2004 +0300
@@ -218,19 +218,6 @@
 # needed.
 #mail_never_cache_fields = 
 
-# Workarounds for various client bugs:
-#   oe6-fetch-no-newmail:
-#     Never send EXISTS/RECENT when replying to FETCH command. Outlook Express
-#     seems to think they are FETCH replies and gives user "Message no longer
-#     in server" error. Note that OE6 still breaks even with this workaround
-#     if synchronization is set to "Headers Only".
-#   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
 # received. This setting specifies the minimum interval in seconds between
 # new mail notifications to client - internally they may be checked more or
@@ -354,6 +341,19 @@
   # Support for dynamically loadable modules.
   #mail_use_modules = no
   #mail_modules = /usr/lib/dovecot/imap
+
+  # Workarounds for various client bugs:
+  #   oe6-fetch-no-newmail:
+  #     Never send EXISTS/RECENT when replying to FETCH command. Outlook Express
+  #     seems to think they are FETCH replies and gives user "Message no longer
+  #     in server" error. Note that OE6 still breaks even with this workaround
+  #     if synchronization is set to "Headers Only".
+  #   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.
+  #imap_client_workarounds = 
 }
   
 ##
@@ -375,6 +375,12 @@
   # Support for dynamically loadable modules.
   #mail_use_modules = no
   #mail_modules = /usr/lib/dovecot/pop3
+
+  # Workarounds for various client bugs:
+  #   outlook-no-nuls:
+  #     Outlook and Outlook Express hang if mails contain NUL characters.
+  #     This setting replaces them with 0x80 character.
+  #pop3_client_workarounds = 
 }
 
 ##
--- a/src/imap/common.h	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/imap/common.h	Sat Jul 10 20:24:08 2004 +0300
@@ -14,9 +14,15 @@
 
 #define DEFAULT_MAX_KEYWORD_LENGTH 50
 
+enum client_workarounds {
+	WORKAROUND_OE6_FETCH_NO_NEWMAIL		= 0x01,
+	WORKAROUND_OUTLOOK_IDLE			= 0x02
+};
+
 extern struct ioloop *ioloop;
 extern unsigned int max_keyword_length, mailbox_check_interval;
 extern unsigned int imap_max_line_length;
+extern enum client_workarounds client_workarounds;
 
 extern string_t *capability_string;
 
--- a/src/imap/main.c	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/imap/main.c	Sat Jul 10 20:24:08 2004 +0300
@@ -21,9 +21,21 @@
 #define IS_STANDALONE() \
         (getenv("LOGGED_IN") == NULL && getenv("IMAPLOGINTAG") == NULL)
 
+struct client_workaround_list {
+	const char *name;
+	enum client_workarounds num;
+};
+
+struct client_workaround_list client_workaround_list[] = {
+	{ "oe6-fetch-no-newmail", WORKAROUND_OE6_FETCH_NO_NEWMAIL },
+	{ "outlook-idle", WORKAROUND_OUTLOOK_IDLE },
+	{ NULL, 0 }
+};
+
 struct ioloop *ioloop;
 unsigned int max_keyword_length, mailbox_check_interval;
 unsigned int imap_max_line_length;
+enum client_workarounds client_workarounds = 0;
 
 static struct module *modules;
 static char log_prefix[128]; /* syslog() needs this to be permanent */
@@ -39,6 +51,28 @@
 	io_loop_stop(ioloop);
 }
 
+static void parse_workarounds(void)
+{
+        struct client_workaround_list *list;
+	const char *env, *const *str;
+
+	env = getenv("IMAP_CLIENT_WORKAROUNDS");
+	if (env == NULL)
+		return;
+
+	for (str = t_strsplit_spaces(env, " "); *str != NULL; str++) {
+		list = client_workaround_list;
+		for (; list->name != NULL; list++) {
+			if (strcasecmp(*str, list->name) == 0) {
+				client_workarounds |= list->num;
+				break;
+			}
+		}
+		if (list->name == NULL)
+			i_fatal("Unknown client workaround: %s", *str);
+	}
+}
+
 static void open_logfile(void)
 {
 	const char *user;
@@ -127,6 +161,8 @@
 	mailbox_check_interval = str == NULL ? 0 :
 		(unsigned int)strtoul(str, NULL, 10);
 
+        parse_workarounds();
+
 	namespace_pool = pool_alloconly_create("namespaces", 1024);
 	client = client_create(0, 1, namespace_init(namespace_pool, user));
 
--- a/src/lib-storage/mail-storage.c	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/lib-storage/mail-storage.c	Sat Jul 10 20:24:08 2004 +0300
@@ -18,44 +18,12 @@
 	struct mail_storage *storage;
 };
 
-struct client_workaround_list {
-	const char *name;
-	enum client_workarounds num;
-};
-
-struct client_workaround_list client_workaround_list[] = {
-	{ "oe6-fetch-no-newmail", WORKAROUND_OE6_FETCH_NO_NEWMAIL },
-	{ "outlook-idle", WORKAROUND_OUTLOOK_IDLE },
-	{ NULL, 0 }
-};
-
 static struct mail_storage_list *storages = NULL;
-enum client_workarounds client_workarounds = 0;
 int full_filesystem_access = FALSE;
 
 void mail_storage_init(void)
 {
-        struct client_workaround_list *list;
-	const char *env;
-	const char *const *str;
-
         full_filesystem_access = getenv("FULL_FILESYSTEM_ACCESS") != NULL;
-
-	env = getenv("CLIENT_WORKAROUNDS");
-	if (env == NULL)
-		return;
-
-	for (str = t_strsplit_spaces(env, " "); *str != NULL; str++) {
-		list = client_workaround_list;
-		for (; list->name != NULL; list++) {
-			if (strcasecmp(*str, list->name) == 0) {
-				client_workarounds |= list->num;
-				break;
-			}
-		}
-		if (list->name == NULL)
-			i_fatal("Unknown client workaround: %s", *str);
-	}
 }
 
 void mail_storage_deinit(void)
--- a/src/lib-storage/mail-storage.h	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/lib-storage/mail-storage.h	Sat Jul 10 20:24:08 2004 +0300
@@ -89,11 +89,6 @@
 	MAILBOX_SYNC_AUTO_STOP		= 0x04
 };
 
-enum client_workarounds {
-	WORKAROUND_OE6_FETCH_NO_NEWMAIL		= 0x01,
-	WORKAROUND_OUTLOOK_IDLE			= 0x02
-};
-
 struct mail_storage;
 struct mail_storage_callbacks;
 struct mailbox_list;
@@ -159,7 +154,6 @@
 
 };
 
-extern enum client_workarounds client_workarounds;
 extern int full_filesystem_access;
 
 void mail_storage_init(void);
--- a/src/master/mail-process.c	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/master/mail-process.c	Sat Jul 10 20:24:08 2004 +0300
@@ -191,14 +191,16 @@
 				set->mailbox_check_interval));
 	env_put(t_strdup_printf("MAILBOX_IDLE_CHECK_INTERVAL=%u",
 				set->mailbox_idle_check_interval));
-	env_put(t_strconcat("CLIENT_WORKAROUNDS=",
-			    set->client_workarounds, NULL));
 	env_put(t_strdup_printf("MAIL_MAX_KEYWORD_LENGTH=%u",
 				set->mail_max_keyword_length));
 	env_put(t_strdup_printf("IMAP_MAX_LINE_LENGTH=%u",
 				set->imap_max_line_length));
 	env_put(t_strconcat("IMAP_CAPABILITY=",
 			    set->imap_capability, NULL));
+	env_put(t_strconcat("IMAP_CLIENT_WORKAROUNDS=",
+			    set->imap_client_workarounds, NULL));
+	env_put(t_strconcat("POP3_CLIENT_WORKAROUNDS=",
+			    set->pop3_client_workarounds, NULL));
 
 	if (set->mail_save_crlf)
 		env_put("MAIL_SAVE_CRLF=1");
--- a/src/master/master-settings.c	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/master/master-settings.c	Sat Jul 10 20:24:08 2004 +0300
@@ -88,7 +88,6 @@
 	DEF(SET_STR, default_mail_env),
 	DEF(SET_STR, mail_cache_fields),
 	DEF(SET_STR, mail_never_cache_fields),
-	DEF(SET_STR, client_workarounds),
 	DEF(SET_INT, mailbox_check_interval),
 	DEF(SET_INT, mailbox_idle_check_interval),
 	DEF(SET_BOOL, mail_full_filesystem_access),
@@ -117,9 +116,11 @@
 	/* imap */
 	DEF(SET_INT, imap_max_line_length),
 	DEF(SET_STR, imap_capability),
+	DEF(SET_STR, imap_client_workarounds),
 
 	/* pop3 */
 	DEF(SET_BOOL, pop3_mails_keep_recent),
+	DEF(SET_STR, pop3_client_workarounds),
 
 	{ 0, NULL, 0 }
 };
@@ -242,7 +243,6 @@
 	MEMBER(default_mail_env) NULL,
 	MEMBER(mail_cache_fields) "MessagePart",
 	MEMBER(mail_never_cache_fields) NULL,
-	MEMBER(client_workarounds) NULL,
 	MEMBER(mailbox_check_interval) 0,
 	MEMBER(mailbox_idle_check_interval) 30,
 	MEMBER(mail_full_filesystem_access) FALSE,
@@ -275,9 +275,11 @@
 	/* imap */
 	MEMBER(imap_max_line_length) 65536,
 	MEMBER(imap_capability) NULL,
+	MEMBER(imap_client_workarounds) NULL,
 
 	/* pop3 */
 	MEMBER(pop3_mails_keep_recent) FALSE,
+	MEMBER(pop3_client_workarounds) NULL,
 
 	/* .. */
 	MEMBER(login_uid) 0,
--- a/src/master/master-settings.h	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/master/master-settings.h	Sat Jul 10 20:24:08 2004 +0300
@@ -59,7 +59,6 @@
 	const char *default_mail_env;
 	const char *mail_cache_fields;
 	const char *mail_never_cache_fields;
-	const char *client_workarounds;
 	unsigned int mailbox_check_interval;
 	unsigned int mailbox_idle_check_interval;
 	int mail_full_filesystem_access;
@@ -88,9 +87,11 @@
 	/* imap */
 	unsigned int imap_max_line_length;
 	const char *imap_capability;
+	const char *imap_client_workarounds;
 
 	/* pop3 */
         int pop3_mails_keep_recent;
+	const char *pop3_client_workarounds;
 
 	/* .. */
 	uid_t login_uid;
--- a/src/pop3/commands.c	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/pop3/commands.c	Sat Jul 10 20:24:08 2004 +0300
@@ -242,6 +242,10 @@
 				add = '.';
 				i++;
 				break;
+			} else if (data[i] == '\0' &&
+				   (client_workarounds &
+				    WORKAROUND_OUTLOOK_NO_NULS) != 0) {
+				add = '\x80';
 			}
 		}
 
@@ -252,6 +256,10 @@
 			if (o_stream_send(output, &add, 1) < 0)
 				return;
 			last = add;
+			if (client_workarounds & WORKAROUND_OUTLOOK_NO_NULS) {
+				if (i < size && data[i] == '\0')
+					i++;
+			}
 		} else {
 			last = data[i-1];
 		}
--- a/src/pop3/common.h	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/pop3/common.h	Sat Jul 10 20:24:08 2004 +0300
@@ -4,11 +4,12 @@
 #include "lib.h"
 #include "client.h"
 
-/* max. number of IMAP argument elements to accept. The maximum memory usage
-   for command from user is around MAX_INBUF_SIZE * MAX_IMAP_ARG_ELEMENTS */
-#define MAX_IMAP_ARG_ELEMENTS 128
+enum client_workarounds {
+	WORKAROUND_OUTLOOK_NO_NULS		= 0x01
+};
 
 extern struct ioloop *ioloop;
+extern enum client_workarounds client_workarounds;
 
 extern void (*hook_mail_storage_created)(struct mail_storage **storage);
 extern void (*hook_client_created)(struct client **client);
--- a/src/pop3/main.c	Sat Jul 10 14:16:05 2004 +0300
+++ b/src/pop3/main.c	Sat Jul 10 20:24:08 2004 +0300
@@ -16,6 +16,16 @@
 #define IS_STANDALONE() \
         (getenv("LOGGED_IN") == NULL)
 
+struct client_workaround_list {
+	const char *name;
+	enum client_workarounds num;
+};
+
+struct client_workaround_list client_workaround_list[] = {
+	{ "outlook-no-nuls", WORKAROUND_OUTLOOK_NO_NULS },
+	{ NULL, 0 }
+};
+
 struct ioloop *ioloop;
 
 void (*hook_mail_storage_created)(struct mail_storage **storage) = NULL;
@@ -23,12 +33,35 @@
 
 static struct module *modules;
 static char log_prefix[128]; /* syslog() needs this to be permanent */
+enum client_workarounds client_workarounds = 0;
 
 static void sig_quit(int signo __attr_unused__)
 {
 	io_loop_stop(ioloop);
 }
 
+static void parse_workarounds(void)
+{
+        struct client_workaround_list *list;
+	const char *env, *const *str;
+
+	env = getenv("POP3_CLIENT_WORKAROUNDS");
+	if (env == NULL)
+		return;
+
+	for (str = t_strsplit_spaces(env, " "); *str != NULL; str++) {
+		list = client_workaround_list;
+		for (; list->name != NULL; list++) {
+			if (strcasecmp(*str, list->name) == 0) {
+				client_workarounds |= list->num;
+				break;
+			}
+		}
+		if (list->name == NULL)
+			i_fatal("Unknown client workaround: %s", *str);
+	}
+}
+
 static void open_logfile(void)
 {
 	const char *user;
@@ -95,6 +128,7 @@
 		if (mail != NULL)
 			mail = t_strconcat("maildir:", mail, NULL);
 	}
+        parse_workarounds();
 
 	storage = mail_storage_create_with_data(mail, getenv("USER"),
 						NULL, '\0');