changeset 21975:b523b154523e

imapc: Make sure client is logged in when checking capabilities Especially with imapc_features=delay-login the capability could have been looked at before the client was even connected.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sun, 23 Apr 2017 19:14:54 +0300
parents b33e28d1e471
children 4430a5cc0a3e
files src/lib-imap-client/imapc-client.c src/lib-imap-client/imapc-client.h src/lib-storage/index/imapc/imapc-list.c src/lib-storage/index/imapc/imapc-storage.c
diffstat 4 files changed, 38 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-imap-client/imapc-client.c	Sun Apr 23 18:51:02 2017 +0300
+++ b/src/lib-imap-client/imapc-client.c	Sun Apr 23 19:14:54 2017 +0300
@@ -506,22 +506,38 @@
 	return TRUE;
 }
 
-enum imapc_capability
-imapc_client_get_capabilities(struct imapc_client *client)
+static bool
+imapc_client_get_any_capabilities(struct imapc_client *client,
+				  enum imapc_capability *capabilities_r)
 {
 	struct imapc_client_connection *const *connp;
 	struct imapc_connection *conn = NULL;
 
-	/* try to find a connection that is already logged in */
 	array_foreach(&client->conns, connp) {
 		conn = (*connp)->conn;
-		if (imapc_connection_get_state(conn) == IMAPC_CONNECTION_STATE_DONE)
-			return imapc_connection_get_capabilities(conn);
+		if (imapc_connection_get_state(conn) == IMAPC_CONNECTION_STATE_DONE) {
+			*capabilities_r = imapc_connection_get_capabilities(conn);
+			return TRUE;
+		}
 	}
+	return FALSE;
+}
 
-	/* fallback to whatever exists (there always exists one) */
-	i_assert(conn != NULL);
-	return imapc_connection_get_capabilities(conn);
+int imapc_client_get_capabilities(struct imapc_client *client,
+				  enum imapc_capability *capabilities_r)
+{
+	/* try to find a connection that is already logged in */
+	if (imapc_client_get_any_capabilities(client, capabilities_r))
+		return 0;
+
+	/* wait for any of the connections to login (there always exists one) */
+	i_assert(array_count(&client->conns) > 0);
+	imapc_client_run(client);
+	if (imapc_client_get_any_capabilities(client, capabilities_r))
+		return 0;
+
+	/* failed */
+	return -1;
 }
 
 int imapc_client_create_temp_fd(struct imapc_client *client,
--- a/src/lib-imap-client/imapc-client.h	Sun Apr 23 18:51:02 2017 +0300
+++ b/src/lib-imap-client/imapc-client.h	Sun Apr 23 19:14:54 2017 +0300
@@ -228,8 +228,8 @@
 void imapc_client_mailbox_idle(struct imapc_client_mailbox *box);
 bool imapc_client_mailbox_is_opened(struct imapc_client_mailbox *box);
 
-enum imapc_capability
-imapc_client_get_capabilities(struct imapc_client *client);
+int imapc_client_get_capabilities(struct imapc_client *client,
+				  enum imapc_capability *capabilities_r);
 
 int imapc_client_create_temp_fd(struct imapc_client *client,
 				const char **path_r);
--- a/src/lib-storage/index/imapc/imapc-list.c	Sun Apr 23 18:51:02 2017 +0300
+++ b/src/lib-storage/index/imapc/imapc-list.c	Sun Apr 23 19:14:54 2017 +0300
@@ -854,7 +854,8 @@
 	struct imapc_command *cmd;
 	struct imapc_simple_context ctx;
 
-	capa = imapc_client_get_capabilities(list->client->client);
+	if (imapc_client_get_capabilities(list->client->client, &capa) < 0)
+		return -1;
 
 	cmd = imapc_list_simple_context_init(&ctx, list);
 	imapc_command_set_flags(cmd, IMAPC_COMMAND_FLAG_RETRIABLE);
--- a/src/lib-storage/index/imapc/imapc-storage.c	Sun Apr 23 18:51:02 2017 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Sun Apr 23 19:14:54 2017 +0300
@@ -603,9 +603,11 @@
 	imapc_client_stop(ctx->mbox->storage->client->client);
 }
 
-static void imapc_mailbox_get_capabilities(struct imapc_mailbox *mbox)
+static int imapc_mailbox_get_capabilities(struct imapc_mailbox *mbox)
 {
-	mbox->capabilities = imapc_client_get_capabilities(mbox->storage->client->client);
+	return imapc_client_get_capabilities(mbox->storage->client->client,
+					     &mbox->capabilities);
+
 }
 
 static void imapc_mailbox_get_extensions(struct imapc_mailbox *mbox)
@@ -630,7 +632,8 @@
 	if (mbox->storage->client->auth_failed) {
 		return -1;
 	}
-	imapc_mailbox_get_capabilities(mbox);
+	if (imapc_mailbox_get_capabilities(mbox) < 0)
+		return -1;
 
 	if (imapc_mailbox_has_modseqs(mbox)) {
 		if (!array_is_created(&mbox->rseq_modseqs))
@@ -898,7 +901,8 @@
 	struct imapc_simple_context sctx;
 	string_t *str;
 
-	imapc_mailbox_get_capabilities(mbox);
+	if (imapc_mailbox_get_capabilities(mbox) < 0)
+		return -1;
 
 	str = t_str_new(256);
 	if ((items & STATUS_MESSAGES) != 0)
@@ -979,7 +983,8 @@
 	if (storage->namespaces_requested)
 		return 0;
 
-	imapc_mailbox_get_capabilities(mbox);
+	if (imapc_mailbox_get_capabilities(mbox) < 0)
+		return -1;
 	if ((mbox->capabilities & IMAPC_CAPABILITY_NAMESPACE) == 0) {
 		/* NAMESPACE capability not supported */
 		return 0;