From a8284e999d091cd29210fa75ecdc8076376a7345 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Fri, 16 Oct 2009 17:46:31 -0400 Subject: [PATCH] imap, pop3: Moved imap/pop3_client_workarounds setting parsing to config checking. --HG-- branch : HEAD --- src/imap/cmd-subscribe.c | 3 +- src/imap/imap-client.h | 1 - src/imap/imap-commands-util.c | 3 +- src/imap/imap-common.h | 6 ---- src/imap/imap-fetch-body.c | 2 +- src/imap/imap-settings.c | 58 ++++++++++++++++++++++++++++++++++- src/imap/imap-settings.h | 10 ++++++ src/imap/imap-sync.c | 2 +- src/imap/main.c | 37 ---------------------- src/pop3/pop3-client.c | 34 -------------------- src/pop3/pop3-client.h | 1 - src/pop3/pop3-commands.c | 4 +-- src/pop3/pop3-common.h | 5 --- src/pop3/pop3-settings.c | 55 ++++++++++++++++++++++++++++++++- src/pop3/pop3-settings.h | 9 ++++++ 15 files changed, 138 insertions(+), 92 deletions(-) diff --git a/src/imap/cmd-subscribe.c b/src/imap/cmd-subscribe.c index 53b75a67c6..f5ebaaa34e 100644 --- a/src/imap/cmd-subscribe.c +++ b/src/imap/cmd-subscribe.c @@ -60,7 +60,8 @@ bool cmd_subscribe_full(struct client_command_context *cmd, bool subscribe) mailbox += strlen(ns->prefix); } - if ((cmd->client->workarounds & WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 && + if ((cmd->client->set->parsed_workarounds & + WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 && *mailbox != '\0' && mailbox[strlen(mailbox)-1] == mailbox_list_get_hierarchy_sep(ns->list)) { /* verify the validity without the trailing '/' */ diff --git a/src/imap/imap-client.h b/src/imap/imap-client.h index e40d56f5e4..1c0c100254 100644 --- a/src/imap/imap-client.h +++ b/src/imap/imap-client.h @@ -95,7 +95,6 @@ struct client { struct timeout *to_idle, *to_idle_output; const struct imap_settings *set; - enum client_workarounds workarounds; string_t *capability_string; struct mail_user *user; diff --git a/src/imap/imap-commands-util.c b/src/imap/imap-commands-util.c index 3b890ddd6b..6fdaffb7a6 100644 --- a/src/imap/imap-commands-util.c +++ b/src/imap/imap-commands-util.c @@ -46,7 +46,8 @@ client_find_namespace(struct client_command_context *cmd, const char **mailboxp, } mailbox_len = strlen(mailbox); - if ((cmd->client->workarounds & WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 && + if ((cmd->client->set->parsed_workarounds & + WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 && mailbox[mailbox_len-1] == mailbox_list_get_hierarchy_sep(ns->list)) { /* drop the extra trailing hierarchy separator */ mailbox = t_strndup(mailbox, mailbox_len-1); diff --git a/src/imap/imap-common.h b/src/imap/imap-common.h index c2c0e6b429..7ce6da6864 100644 --- a/src/imap/imap-common.h +++ b/src/imap/imap-common.h @@ -13,12 +13,6 @@ /* Disconnect client when it sends too many bad commands in a row */ #define CLIENT_MAX_BAD_COMMANDS 20 -enum client_workarounds { - WORKAROUND_DELAY_NEWMAIL = 0x01, - WORKAROUND_NETSCAPE_EOH = 0x04, - WORKAROUND_TB_EXTRA_MAILBOX_SEP = 0x08 -}; - #include "lib.h" #include "imap-client.h" #include "imap-settings.h" diff --git a/src/imap/imap-fetch-body.c b/src/imap/imap-fetch-body.c index b0a3900ab3..601da87f9f 100644 --- a/src/imap/imap-fetch-body.c +++ b/src/imap/imap-fetch-body.c @@ -433,7 +433,7 @@ static int fetch_header_partial_from(struct imap_fetch_context *ctx, i_stream_seek(ctx->cur_input, old_offset); if (!ctx->cur_have_eoh && - (ctx->client->workarounds & WORKAROUND_NETSCAPE_EOH) != 0) { + (ctx->client->set->parsed_workarounds & WORKAROUND_NETSCAPE_EOH) != 0) { /* Netscape 4.x doesn't like if end of headers line is missing. */ msg_size.virtual_size += 2; diff --git a/src/imap/imap-settings.c b/src/imap/imap-settings.c index a9c8142ba3..1ac1119643 100644 --- a/src/imap/imap-settings.c +++ b/src/imap/imap-settings.c @@ -9,6 +9,9 @@ #include #include +static bool imap_settings_verify(void *_set, pool_t pool, + const char **error_r); + #undef DEF #undef DEFLIST #define DEF(type, name) \ @@ -62,6 +65,59 @@ struct setting_parser_info imap_setting_parser_info = { MEMBER(parent_offset) (size_t)-1, MEMBER(type_offset) (size_t)-1, MEMBER(struct_size) sizeof(struct imap_settings), - MEMBER(check_func) NULL, + MEMBER(check_func) imap_settings_verify, MEMBER(dependencies) imap_setting_dependencies }; + +/* */ +struct imap_client_workaround_list { + const char *name; + enum imap_client_workarounds num; +}; + +static struct imap_client_workaround_list imap_client_workaround_list[] = { + { "delay-newmail", WORKAROUND_DELAY_NEWMAIL }, + { "outlook-idle", 0 }, /* only for backwards compatibility */ + { "netscape-eoh", WORKAROUND_NETSCAPE_EOH }, + { "tb-extra-mailbox-sep", WORKAROUND_TB_EXTRA_MAILBOX_SEP }, + { NULL, 0 } +}; + +static int +imap_settings_parse_workarounds(struct imap_settings *set, + const char **error_r) +{ + enum imap_client_workarounds client_workarounds = 0; + struct imap_client_workaround_list *list; + const char *const *str; + + str = t_strsplit_spaces(set->imap_client_workarounds, " ,"); + for (; *str != NULL; str++) { + list = imap_client_workaround_list; + for (; list->name != NULL; list++) { + if (strcasecmp(*str, list->name) == 0) { + client_workarounds |= list->num; + break; + } + } + if (list->name == NULL) { + *error_r = t_strdup_printf("imap_client_workarounds: " + "Unknown workaround: %s", *str); + return -1; + } + } + set->parsed_workarounds = client_workarounds; + return 0; +} + + +static bool +imap_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) +{ + struct imap_settings *set = _set; + + if (imap_settings_parse_workarounds(set, error_r) < 0) + return FALSE; + return TRUE; +} +/* */ diff --git a/src/imap/imap-settings.h b/src/imap/imap-settings.h index 7629b6d057..275a969880 100644 --- a/src/imap/imap-settings.h +++ b/src/imap/imap-settings.h @@ -3,6 +3,14 @@ struct mail_user_settings; +/* */ +enum imap_client_workarounds { + WORKAROUND_DELAY_NEWMAIL = 0x01, + WORKAROUND_NETSCAPE_EOH = 0x04, + WORKAROUND_TB_EXTRA_MAILBOX_SEP = 0x08 +}; +/* */ + struct imap_settings { bool mail_debug; bool shutdown_clients; @@ -15,6 +23,8 @@ struct imap_settings { const char *imap_logout_format; const char *imap_id_send; const char *imap_id_log; + + enum imap_client_workarounds parsed_workarounds; }; extern struct setting_parser_info imap_setting_parser_info; diff --git a/src/imap/imap-sync.c b/src/imap/imap-sync.c index 77923490ff..e749a4fc1c 100644 --- a/src/imap/imap-sync.c +++ b/src/imap/imap-sync.c @@ -579,7 +579,7 @@ static bool cmd_sync_client(struct client_command_context *sync_cmd) get_common_sync_flags(client, &flags, &imap_flags); client->sync_counter++; - no_newmail = (client->workarounds & WORKAROUND_DELAY_NEWMAIL) != 0 && + no_newmail = (client->set->parsed_workarounds & WORKAROUND_DELAY_NEWMAIL) != 0 && (imap_flags & IMAP_SYNC_FLAG_SAFE) == 0; if (no_newmail) { /* expunges might break the client just as badly as new mail diff --git a/src/imap/main.c b/src/imap/main.c index 2a6c1cb95e..cf70504fbc 100644 --- a/src/imap/main.c +++ b/src/imap/main.c @@ -23,44 +23,8 @@ #define IS_STANDALONE() \ (getenv("CLIENT_INPUT") == NULL) -struct client_workaround_list { - const char *name; - enum client_workarounds num; -}; - -static struct client_workaround_list client_workaround_list[] = { - { "delay-newmail", WORKAROUND_DELAY_NEWMAIL }, - { "outlook-idle", 0 }, /* only for backwards compatibility */ - { "netscape-eoh", WORKAROUND_NETSCAPE_EOH }, - { "tb-extra-mailbox-sep", WORKAROUND_TB_EXTRA_MAILBOX_SEP }, - { NULL, 0 } -}; - void (*hook_client_created)(struct client **client) = NULL; -static enum client_workarounds -parse_workarounds(const struct imap_settings *set) -{ - enum client_workarounds client_workarounds = 0; - struct client_workaround_list *list; - const char *const *str; - - str = t_strsplit_spaces(set->imap_client_workarounds, " ,"); - for (; *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); - } - - return client_workarounds; -} - static void client_add_input(struct client *client, const char *input) { buffer_t *buf; @@ -122,7 +86,6 @@ static void main_init(const struct imap_settings *set, struct mail_user *user, master_service_set_die_with_master(master_service, TRUE); client = client_create(0, 1, user, set); - client->workarounds = parse_workarounds(set); if (dump_capability) { printf("%s\n", str_c(client->capability_string)); diff --git a/src/pop3/pop3-client.c b/src/pop3/pop3-client.c index 0d096ca336..f00293c73c 100644 --- a/src/pop3/pop3-client.c +++ b/src/pop3/pop3-client.c @@ -35,17 +35,6 @@ transaction. This allows the mailbox to become unlocked. */ #define CLIENT_COMMIT_TIMEOUT_MSECS (10*1000) -struct client_workaround_list { - const char *name; - enum client_workarounds num; -}; - -static struct client_workaround_list client_workaround_list[] = { - { "outlook-no-nuls", WORKAROUND_OUTLOOK_NO_NULS }, - { "oe-ns-eoh", WORKAROUND_OE_NS_EOH }, - { NULL, 0 } -}; - static struct client *pop3_clients; static void client_input(struct client *client); @@ -167,28 +156,6 @@ static bool init_mailbox(struct client *client, const char **error_r) return FALSE; } -static enum client_workarounds -parse_workarounds(const struct pop3_settings *set) -{ - enum client_workarounds client_workarounds = 0; - struct client_workaround_list *list; - const char *const *str; - - str = t_strsplit_spaces(set->pop3_client_workarounds, " ,"); - for (; *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); - } - return client_workarounds; -} - static enum uidl_keys parse_uidl_keymask(const char *format) { enum uidl_keys mask = 0; @@ -281,7 +248,6 @@ struct client *client_create(int fd_in, int fd_out, struct mail_user *user, return NULL; } - client->workarounds = parse_workarounds(set); client->uidl_keymask = parse_uidl_keymask(client->mail_set->pop3_uidl_format); if (client->uidl_keymask == 0) diff --git a/src/pop3/pop3-client.h b/src/pop3/pop3-client.h index 8bc503d99e..a70b1bc278 100644 --- a/src/pop3/pop3-client.h +++ b/src/pop3/pop3-client.h @@ -52,7 +52,6 @@ struct client { /* settings: */ const struct pop3_settings *set; const struct mail_storage_settings *mail_set; - enum client_workarounds workarounds; enum uidl_keys uidl_keymask; unsigned int disconnected:1; diff --git a/src/pop3/pop3-commands.c b/src/pop3/pop3-commands.c index 551fe09962..9681ccef27 100644 --- a/src/pop3/pop3-commands.c +++ b/src/pop3/pop3-commands.c @@ -321,7 +321,7 @@ static void fetch_callback(struct client *client) add = '.'; break; } else if (data[i] == '\0' && - (client->workarounds & + (client->set->parsed_workarounds & WORKAROUND_OUTLOOK_NO_NULS) != 0) { add = 0x80; break; @@ -360,7 +360,7 @@ static void fetch_callback(struct client *client) } if (!ctx->in_body && - (client->workarounds & WORKAROUND_OE_NS_EOH) != 0) { + (client->set->parsed_workarounds & WORKAROUND_OE_NS_EOH) != 0) { /* Add the missing end of headers line. */ (void)o_stream_send(client->output, "\r\n", 2); } diff --git a/src/pop3/pop3-common.h b/src/pop3/pop3-common.h index 8a31acd404..e4b0fd496e 100644 --- a/src/pop3/pop3-common.h +++ b/src/pop3/pop3-common.h @@ -1,11 +1,6 @@ #ifndef POP3_COMMON_H #define POP3_COMMON_H -enum client_workarounds { - WORKAROUND_OUTLOOK_NO_NULS = 0x01, - WORKAROUND_OE_NS_EOH = 0x02 -}; - enum uidl_keys { UIDL_UIDVALIDITY = 0x01, UIDL_UID = 0x02, diff --git a/src/pop3/pop3-settings.c b/src/pop3/pop3-settings.c index 05b6fda834..ba64c6400b 100644 --- a/src/pop3/pop3-settings.c +++ b/src/pop3/pop3-settings.c @@ -9,6 +9,9 @@ #include #include +static bool pop3_settings_verify(void *_set, pool_t pool, + const char **error_r); + #undef DEF #undef DEFLIST #define DEF(type, name) \ @@ -59,6 +62,56 @@ struct setting_parser_info pop3_setting_parser_info = { MEMBER(parent_offset) (size_t)-1, MEMBER(type_offset) (size_t)-1, MEMBER(struct_size) sizeof(struct pop3_settings), - MEMBER(check_func) NULL, + MEMBER(check_func) pop3_settings_verify, MEMBER(dependencies) pop3_setting_dependencies }; + +/* */ +struct pop3_client_workaround_list { + const char *name; + enum pop3_client_workarounds num; +}; + +static struct pop3_client_workaround_list pop3_client_workaround_list[] = { + { "outlook-no-nuls", WORKAROUND_OUTLOOK_NO_NULS }, + { "oe-ns-eoh", WORKAROUND_OE_NS_EOH }, + { NULL, 0 } +}; + +static int +pop3_settings_parse_workarounds(struct pop3_settings *set, + const char **error_r) +{ + enum pop3_client_workarounds client_workarounds = 0; + struct pop3_client_workaround_list *list; + const char *const *str; + + str = t_strsplit_spaces(set->pop3_client_workarounds, " ,"); + for (; *str != NULL; str++) { + list = pop3_client_workaround_list; + for (; list->name != NULL; list++) { + if (strcasecmp(*str, list->name) == 0) { + client_workarounds |= list->num; + break; + } + } + if (list->name == NULL) { + *error_r = t_strdup_printf("pop3_client_workarounds: " + "Unknown workaround: %s", *str); + return -1; + } + } + set->parsed_workarounds = client_workarounds; + return 0; +} + +static bool +pop3_settings_verify(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) +{ + struct pop3_settings *set = _set; + + if (pop3_settings_parse_workarounds(set, error_r) < 0) + return FALSE; + return TRUE; +} +/* */ diff --git a/src/pop3/pop3-settings.h b/src/pop3/pop3-settings.h index 09faeb01a0..02515a5222 100644 --- a/src/pop3/pop3-settings.h +++ b/src/pop3/pop3-settings.h @@ -3,6 +3,13 @@ struct mail_user_settings; +/* */ +enum pop3_client_workarounds { + WORKAROUND_OUTLOOK_NO_NULS = 0x01, + WORKAROUND_OE_NS_EOH = 0x02 +}; +/* */ + struct pop3_settings { bool mail_debug; bool shutdown_clients; @@ -15,6 +22,8 @@ struct pop3_settings { bool pop3_lock_session; const char *pop3_client_workarounds; const char *pop3_logout_format; + + enum pop3_client_workarounds parsed_workarounds; }; extern struct setting_parser_info pop3_setting_parser_info; -- 2.47.3