workaround.
--HG--
branch : HEAD
# 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
# 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 =
}
##
# 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 =
}
##
#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;
#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 */
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;
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));
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)
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;
};
-extern enum client_workarounds client_workarounds;
extern int full_filesystem_access;
void mail_storage_init(void);
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");
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),
/* 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 }
};
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,
/* 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,
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;
/* 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;
add = '.';
i++;
break;
+ } else if (data[i] == '\0' &&
+ (client_workarounds &
+ WORKAROUND_OUTLOOK_NO_NULS) != 0) {
+ add = '\x80';
}
}
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];
}
#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);
#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;
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;
if (mail != NULL)
mail = t_strconcat("maildir:", mail, NULL);
}
+ parse_workarounds();
storage = mail_storage_create_with_data(mail, getenv("USER"),
NULL, '\0');