[evolution-data-server] Bug #644367 - Check NNTP server capabilities before using OVER command



commit bc684193faf20d20bde20dcd0af92898b17d16ec
Author: Milan Crha <mcrha redhat com>
Date:   Fri Mar 11 16:58:40 2011 +0100

    Bug #644367 - Check NNTP server capabilities before using OVER command

 camel/providers/nntp/camel-nntp-store.c   |   59 +++++++++++++++++++++++++++++
 camel/providers/nntp/camel-nntp-store.h   |    6 +++
 camel/providers/nntp/camel-nntp-summary.c |    9 +++-
 3 files changed, 72 insertions(+), 2 deletions(-)
---
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index 8b5c10e..e15a960 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -196,6 +196,39 @@ nntp_can_work_offline (CamelDiscoStore *store)
 	return TRUE;
 }
 
+static gint
+check_capabilities (CamelNNTPStore *store,
+             GCancellable *cancellable,
+             GError **error)
+{
+	gint ret;
+	gchar *line;
+	guint len;
+
+	store->capabilities = 0;
+
+	ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "CAPABILITIES");
+	if (ret != 101)
+		return -1;
+
+	while ((ret = camel_nntp_stream_line (store->stream, (guchar **) &line, &len, cancellable, error)) > 0) {
+		while (len > 0 && g_ascii_isspace (*line)) {
+			line++;
+			len--;
+		}
+
+		if (len == 4 && g_ascii_strncasecmp (line, "OVER", len) == 0)
+			store->capabilities |= NNTP_CAPABILITY_OVER;
+
+		if (len == 1 && g_ascii_strncasecmp (line, ".", len) == 0) {
+			ret = 0;
+			break;
+		}
+	}
+
+	return ret;
+}
+
 static struct {
 	const gchar *name;
 	gint type;
@@ -409,10 +442,12 @@ nntp_connect_online (CamelService *service,
                      GCancellable *cancellable,
                      GError **error)
 {
+	CamelNNTPStore *store = CAMEL_NNTP_STORE (service);
 	const gchar *ssl_mode;
 	gint mode, i;
 	gchar *serv;
 	gint fallback_port;
+	GError *local_error = NULL;
 
 	if ((ssl_mode = camel_url_get_param (service->url, "use_ssl"))) {
 		for (i = 0; ssl_options[i].value; i++)
@@ -433,6 +468,30 @@ nntp_connect_online (CamelService *service,
 		fallback_port = 0;
 	}
 
+	if (!connect_to_server (
+		service, service->url->host, serv,
+		fallback_port, mode, cancellable, error))
+		return FALSE;
+
+	if (check_capabilities (store, cancellable, &local_error) != -1)
+		return TRUE;
+
+	if (local_error)
+		g_error_free (local_error);
+
+	store->capabilities = 0;
+
+	/* disconnect and reconnect without capability check */
+	camel_service_lock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
+	if (store->stream)
+		g_object_unref (store->stream);
+	store->stream = NULL;
+	g_free (store->current_folder);
+	store->current_folder = NULL;
+
+	camel_service_unlock (CAMEL_SERVICE (store), CAMEL_SERVICE_REC_CONNECT_LOCK);
+
 	return connect_to_server (
 		service, service->url->host, serv,
 		fallback_port, mode, cancellable, error);
diff --git a/camel/providers/nntp/camel-nntp-store.h b/camel/providers/nntp/camel-nntp-store.h
index 92e3c69..cc6a36b 100644
--- a/camel/providers/nntp/camel-nntp-store.h
+++ b/camel/providers/nntp/camel-nntp-store.h
@@ -78,6 +78,11 @@ struct _xover_header {
 	xover_t type:8;
 };
 
+/* names of supported capabilities on the server */
+enum nntp_capabilities {
+	NNTP_CAPABILITY_OVER = (1 << 0)  /* supports OVER command */
+};
+
 struct _CamelNNTPStore {
 	CamelDiscoStore parent;
 
@@ -100,6 +105,7 @@ struct _CamelNNTPStore {
 	gchar *current_folder, *storage_path, *base_url;
 
 	struct _xover_header *xover;
+	guint32 capabilities; /* bit-or of nntp_capabilities */
 };
 
 struct _CamelNNTPStoreClass {
diff --git a/camel/providers/nntp/camel-nntp-summary.c b/camel/providers/nntp/camel-nntp-summary.c
index 0497743..081b237 100644
--- a/camel/providers/nntp/camel-nntp-summary.c
+++ b/camel/providers/nntp/camel-nntp-summary.c
@@ -232,9 +232,14 @@ add_range_xover (CamelNNTPSummary *cns,
 		cancellable, _("%s: Scanning new messages"),
 		((CamelService *)store)->url->host);
 
-	ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "over %r", low, high);
-	if (ret != 224)
+	if ((store->capabilities & NNTP_CAPABILITY_OVER) != 0)
+		ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "over %r", low, high);
+	else
+		ret = -1;
+	if (ret != 224) {
+		store->capabilities = store->capabilities & (~NNTP_CAPABILITY_OVER);
 		ret = camel_nntp_raw_command_auth (store, cancellable, error, &line, "xover %r", low, high);
+	}
 
 	if (ret != 224) {
 		camel_operation_pop_message (cancellable);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]