]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
pop3c: Add no pipelining pop3c feature
authorAki Tuomi <aki.tuomi@dovecot.fi>
Mon, 20 Feb 2017 07:18:45 +0000 (09:18 +0200)
committerGitLab <gitlab@git.dovecot.net>
Mon, 20 Feb 2017 09:35:56 +0000 (11:35 +0200)
This should help with certain broken pop3c
servers that advertise that they support pipelining
but they really don't.

src/lib-storage/index/pop3c/pop3c-client.c
src/lib-storage/index/pop3c/pop3c-client.h
src/lib-storage/index/pop3c/pop3c-mail.c
src/lib-storage/index/pop3c/pop3c-settings.c
src/lib-storage/index/pop3c/pop3c-settings.h
src/lib-storage/index/pop3c/pop3c-storage.c

index 9cbee3325aa31f9e625147173f1c90031fce8da9..9651b2ffd298620f8523f353376862fbfb237804 100644 (file)
@@ -490,7 +490,8 @@ pop3c_client_prelogin_input_line(struct pop3c_client *client, const char *line)
                        pop3c_client_login_finished(client);
                        break;
                }
-               if (strcasecmp(line, "PIPELINING") == 0)
+               if ((client->set.parsed_features & POP3C_FEATURE_NO_PIPELINING) == 0 &&
+                   strcasecmp(line, "PIPELINING") == 0)
                        client->capabilities |= POP3C_CAPABILITY_PIPELINING;
                else if (strcasecmp(line, "TOP") == 0)
                        client->capabilities |= POP3C_CAPABILITY_TOP;
index 84365c2621414b14d7d9ed58f9f8cf7631ab7893..57a4cb0d4f5dc951a96a1f258e13256099639d4e 100644 (file)
@@ -2,6 +2,7 @@
 #define POP3C_CLIENT_H
 
 #include "net.h"
+#include "pop3c-settings.h"
 
 enum pop3c_capability {
        POP3C_CAPABILITY_PIPELINING     = 0x01,
@@ -33,6 +34,7 @@ struct pop3c_client_settings {
        const char *temp_path_prefix;
 
        enum pop3c_client_ssl_mode ssl_mode;
+       enum pop3c_features parsed_features;
        const char *ssl_ca_dir, *ssl_ca_file;
        bool ssl_verify;
 
index 9073d5f9be5e71af858c0d3d693905e69e3fd407..e2b61860d513c965fc2a7a2688bf20dfa5c55f17 100644 (file)
@@ -4,7 +4,6 @@
 #include "ioloop.h"
 #include "istream.h"
 #include "index-mail.h"
-#include "pop3c-settings.h"
 #include "pop3c-client.h"
 #include "pop3c-sync.h"
 #include "pop3c-storage.h"
index ddf7f091604ed0bf6fefc775ebd4194c593fddd2..93cb43e14c251251c169ca14113b4c129afd14c2 100644 (file)
@@ -25,6 +25,8 @@ static const struct setting_define pop3c_setting_defines[] = {
        DEF(SET_STR, pop3c_rawlog_dir),
        DEF(SET_BOOL, pop3c_quick_received_date),
 
+       DEF(SET_STR, pop3c_features),
+
        SETTING_DEFINE_LIST_END
 };
 
@@ -40,9 +42,60 @@ static const struct pop3c_settings pop3c_default_settings = {
        .pop3c_ssl_verify = TRUE,
 
        .pop3c_rawlog_dir = "",
-       .pop3c_quick_received_date = FALSE
+       .pop3c_quick_received_date = FALSE,
+
+       .pop3c_features = ""
+};
+
+/* <settings checks> */
+struct pop3c_feature_list {
+       const char *name;
+       enum pop3c_features num;
 };
 
+static const struct pop3c_feature_list pop3c_feature_list[] = {
+       { "no-pipelining", POP3C_FEATURE_NO_PIPELINING },
+       { NULL, 0 }
+};
+
+static int
+pop3c_settings_parse_features(struct pop3c_settings *set,
+                             const char **error_r)
+{
+       enum pop3c_features features = 0;
+       const struct pop3c_feature_list *list;
+       const char *const *str;
+
+       str = t_strsplit_spaces(set->pop3c_features, " ,");
+       for (; *str != NULL; str++) {
+               list = pop3c_feature_list;
+               for (; list->name != NULL; list++) {
+                       if (strcasecmp(*str, list->name) == 0) {
+                               features |= list->num;
+                               break;
+                       }
+               }
+               if (list->name == NULL) {
+                       *error_r = t_strdup_printf("pop3c_features: "
+                               "Unknown feature: %s", *str);
+                       return -1;
+               }
+       }
+       set->parsed_features = features;
+       return 0;
+}
+
+static bool pop3c_settings_check(void *_set, pool_t pool ATTR_UNUSED,
+                                const char **error_r)
+{
+       struct pop3c_settings *set = _set;
+
+       if (pop3c_settings_parse_features(set, error_r) < 0)
+               return FALSE;
+       return TRUE;
+}
+/* </settings checks> */
+
 static const struct setting_parser_info pop3c_setting_parser_info = {
        .module_name = "pop3c",
        .defines = pop3c_setting_defines,
@@ -53,6 +106,8 @@ static const struct setting_parser_info pop3c_setting_parser_info = {
 
        .parent_offset = (size_t)-1,
        .parent = &mail_user_setting_parser_info,
+
+        .check_func = pop3c_settings_check
 };
 
 const struct setting_parser_info *pop3c_get_setting_parser_info(void)
index 844026afe70ffb3b7c6d52d67bf14ca80bc56a5a..bf44e24477d422a0d755d92e8b88d5ac3a167dc6 100644 (file)
@@ -3,6 +3,13 @@
 
 #include "net.h"
 
+/* <settings checks> */
+enum pop3c_features {
+        POP3C_FEATURE_NO_PIPELINING = 0x1,
+};
+/* </settings checks> */
+
+
 struct pop3c_settings {
        const char *pop3c_host;
        in_port_t pop3c_port;
@@ -16,6 +23,9 @@ struct pop3c_settings {
 
        const char *pop3c_rawlog_dir;
        bool pop3c_quick_received_date;
+
+       const char *pop3c_features;
+       enum pop3c_features parsed_features;
 };
 
 const struct setting_parser_info *pop3c_get_setting_parser_info(void);
index 5c2f57e8476223f706fc919ce62c84ab393c8703..87be0818600c8bfb5b1e809e09f3b0ee4522ca61 100644 (file)
@@ -8,7 +8,6 @@
 #include "mailbox-list-private.h"
 #include "index-mail.h"
 #include "pop3c-client.h"
-#include "pop3c-settings.h"
 #include "pop3c-sync.h"
 #include "pop3c-storage.h"