changeset 21642:720e5963f3ca

pop3c: Add no pipelining pop3c feature This should help with certain broken pop3c servers that advertise that they support pipelining but they really don't.
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Mon, 20 Feb 2017 09:18:45 +0200
parents e9a0ccfe9b67
children 19ec1861e84f
files 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
diffstat 6 files changed, 70 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/pop3c/pop3c-client.c	Wed May 25 01:57:08 2016 +0200
+++ b/src/lib-storage/index/pop3c/pop3c-client.c	Mon Feb 20 09:18:45 2017 +0200
@@ -490,7 +490,8 @@
 			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;
--- a/src/lib-storage/index/pop3c/pop3c-client.h	Wed May 25 01:57:08 2016 +0200
+++ b/src/lib-storage/index/pop3c/pop3c-client.h	Mon Feb 20 09:18:45 2017 +0200
@@ -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 @@
 	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;
 
--- a/src/lib-storage/index/pop3c/pop3c-mail.c	Wed May 25 01:57:08 2016 +0200
+++ b/src/lib-storage/index/pop3c/pop3c-mail.c	Mon Feb 20 09:18:45 2017 +0200
@@ -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"
--- a/src/lib-storage/index/pop3c/pop3c-settings.c	Wed May 25 01:57:08 2016 +0200
+++ b/src/lib-storage/index/pop3c/pop3c-settings.c	Mon Feb 20 09:18:45 2017 +0200
@@ -25,6 +25,8 @@
 	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 @@
 	.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 @@
 
 	.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)
--- a/src/lib-storage/index/pop3c/pop3c-settings.h	Wed May 25 01:57:08 2016 +0200
+++ b/src/lib-storage/index/pop3c/pop3c-settings.h	Mon Feb 20 09:18:45 2017 +0200
@@ -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 @@
 
 	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);
--- a/src/lib-storage/index/pop3c/pop3c-storage.c	Wed May 25 01:57:08 2016 +0200
+++ b/src/lib-storage/index/pop3c/pop3c-storage.c	Mon Feb 20 09:18:45 2017 +0200
@@ -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"