]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Split client_workarounds to imap_ and pop3_ ones. Added outlook-no-nuls POP3
authorTimo Sirainen <tss@iki.fi>
Sat, 10 Jul 2004 17:24:08 +0000 (20:24 +0300)
committerTimo Sirainen <tss@iki.fi>
Sat, 10 Jul 2004 17:24:08 +0000 (20:24 +0300)
workaround.

--HG--
branch : HEAD

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

index a082adaa8978dc6320f40bd7be07b7f0a955c0f3..5a49bd9df12e2914946c57898af0a71901fc835b 100644 (file)
 # 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 @@ protocol imap {
   # 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 @@ protocol pop3 {
   # 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 = 
 }
 
 ##
index 2dc9f4c83bca4625df31928b5d08f3ff1fd66a4a..ce0f43ff3f3abe84158e727a6e9b81206cf37fb9 100644 (file)
 
 #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;
 
index 7aff236e9590f6bbe48a01113d916ecb75bbbbdf..e5da5be62544230a5b154bc8f2d5531915379b59 100644 (file)
 #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 @@ 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("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 @@ static void main_init(void)
        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));
 
index caf96df40c9f9bd5db37baa7417e3ae7b04499a4..11b168ba2308b1f05c4f0f4f6e1fe37eef71cd3c 100644 (file)
@@ -18,44 +18,12 @@ struct mail_storage_list {
        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)
index ed69821e8e5625f2d8750437839ceaeb9b91e6da..1186e308ea64a897aff13056d77d611833869856 100644 (file)
@@ -89,11 +89,6 @@ enum mailbox_sync_flags {
        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 @@ struct mail_storage_callbacks {
 
 };
 
-extern enum client_workarounds client_workarounds;
 extern int full_filesystem_access;
 
 void mail_storage_init(void);
index 72813220e9a39494c71e0279fe0d35034601f384..e017fa0632c82966e639f1b60e634d0c6a75b5e9 100644 (file)
@@ -191,14 +191,16 @@ mail_process_set_environment(struct settings *set, const char *mail,
                                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");
index ea29566adf2965857a2716155f2cbf4d7a282dc6..7e76f5cc25b069d6138843f397438a14ad3cb577 100644 (file)
@@ -88,7 +88,6 @@ static struct setting_def setting_defs[] = {
        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 @@ static struct setting_def setting_defs[] = {
        /* 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 @@ struct settings default_settings = {
        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 @@ struct settings default_settings = {
        /* 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,
index f639cee45a20f02993abcfbee2e642b011b66aa6..80467a0c54c7ad5fb330718b1874207f721c459b 100644 (file)
@@ -59,7 +59,6 @@ struct settings {
        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 @@ struct settings {
        /* 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;
index 8a86d685608efcd268c25cc3515a447f24a3b2cd..0dc1d61215347c23f85abca9c8855ef4be094e48 100644 (file)
@@ -242,6 +242,10 @@ static void stream_send_escaped(struct ostream *output, struct istream *input,
                                add = '.';
                                i++;
                                break;
+                       } else if (data[i] == '\0' &&
+                                  (client_workarounds &
+                                   WORKAROUND_OUTLOOK_NO_NULS) != 0) {
+                               add = '\x80';
                        }
                }
 
@@ -252,6 +256,10 @@ static void stream_send_escaped(struct ostream *output, struct istream *input,
                        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];
                }
index 04f40d14e4304ae37a00e77c8fbfe542e2b8dc64..d464c927f6053212bed5fa99d514765879e4507f 100644 (file)
@@ -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);
index 0e2fb8f06abf0c63ceecf4687c9e708ab97fade4..5ac6fef8115c19518c19acbc60c6a07bef519b8b 100644 (file)
 #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 @@ void (*hook_client_created)(struct client **client) = NULL;
 
 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 @@ static int main_init(void)
                if (mail != NULL)
                        mail = t_strconcat("maildir:", mail, NULL);
        }
+        parse_workarounds();
 
        storage = mail_storage_create_with_data(mail, getenv("USER"),
                                                NULL, '\0');