aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog8
-rw-r--r--camel/camel-remote-store.c152
-rw-r--r--camel/providers/imap/camel-imap-folder.c149
-rw-r--r--camel/providers/imap/camel-imap-store.c93
-rw-r--r--camel/providers/imap/camel-imap-store.h26
5 files changed, 235 insertions, 193 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index b1d93bac81..a7c662a67b 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,11 @@
+2000-08-30 Jeffrey Stedfast <fejj@helixcode.com>
+
+ * camel-remote-store.c: Prevent exceptions from being overwritten
+
+ * providers/imap/camel-imap-folder.c (imap_expunge): Beautified
+ (imap_get_subfolder_names_internal): Removed old code as the
+ replacement code has now been tested and proven to work
+
2000-08-29 Jeffrey Stedfast <fejj@helixcode.com>
* providers/imap/camel-imap-utils.c: Removed old code that will
diff --git a/camel/camel-remote-store.c b/camel/camel-remote-store.c
index e86c05e909..4534c85544 100644
--- a/camel/camel-remote-store.c
+++ b/camel/camel-remote-store.c
@@ -81,9 +81,9 @@ camel_remote_store_class_init (CamelRemoteStoreClass *camel_remote_store_class)
CAMEL_SERVICE_CLASS (camel_remote_store_class);
CamelStoreClass *camel_store_class =
CAMEL_STORE_CLASS (camel_remote_store_class);
-
- store_class = CAMEL_STORE_CLASS(camel_type_get_global_classfuncs (camel_store_get_type ()));
-
+
+ store_class = CAMEL_STORE_CLASS (camel_type_get_global_classfuncs (camel_store_get_type ()));
+
/* virtual method overload */
camel_service_class->connect = remote_connect;
camel_service_class->disconnect = remote_disconnect;
@@ -91,9 +91,9 @@ camel_remote_store_class_init (CamelRemoteStoreClass *camel_remote_store_class)
camel_service_class->query_auth_types_connected = remote_query_auth_types_connected;
camel_service_class->free_auth_types = remote_free_auth_types;
camel_service_class->get_name = remote_get_name;
-
+
camel_store_class->get_folder_name = remote_get_folder_name;
-
+
camel_remote_store_class->post_connect = remote_post_connect;
camel_remote_store_class->pre_disconnect = remote_pre_disconnect;
camel_remote_store_class->send_string = remote_send_string;
@@ -108,11 +108,11 @@ camel_remote_store_init (CamelObject *object)
CamelService *service = CAMEL_SERVICE (object);
CamelStore *store = CAMEL_STORE (object);
CamelRemoteStore *remote_store = CAMEL_REMOTE_STORE (object);
-
+
service->url_flags |= CAMEL_SERVICE_URL_NEED_HOST;
-
+
store->folders = g_hash_table_new (g_str_hash, g_str_equal);
-
+
remote_store->istream = NULL;
remote_store->ostream = NULL;
remote_store->timeout_id = 0;
@@ -134,13 +134,14 @@ camel_remote_store_get_type (void)
static CamelType camel_remote_store_type = CAMEL_INVALID_TYPE;
if (camel_remote_store_type == CAMEL_INVALID_TYPE) {
- camel_remote_store_type = camel_type_register (CAMEL_STORE_TYPE, "CamelRemoteStore",
- sizeof (CamelRemoteStore),
- sizeof (CamelRemoteStoreClass),
- (CamelObjectClassInitFunc) camel_remote_store_class_init,
- NULL,
- (CamelObjectInitFunc) camel_remote_store_init,
- (CamelObjectFinalizeFunc) NULL);
+ camel_remote_store_type =
+ camel_type_register (CAMEL_STORE_TYPE, "CamelRemoteStore",
+ sizeof (CamelRemoteStore),
+ sizeof (CamelRemoteStoreClass),
+ (CamelObjectClassInitFunc) camel_remote_store_class_init,
+ NULL,
+ (CamelObjectInitFunc) camel_remote_store_init,
+ (CamelObjectFinalizeFunc) NULL);
}
return camel_remote_store_type;
@@ -199,7 +200,7 @@ static void
refresh_folder_info (gpointer key, gpointer value, gpointer data)
{
CamelFolder *folder = CAMEL_FOLDER (value);
-
+
camel_folder_refresh_info (folder, (CamelException *) data);
}
@@ -211,61 +212,64 @@ remote_connect (CamelService *service, CamelException *ex)
struct sockaddr_in sin;
gint fd;
gint port;
-
+
h = camel_service_gethost (service, ex);
if (!h)
return FALSE;
-
+
/* connect to the server */
sin.sin_family = h->h_addrtype;
-
+
if (service->url->port)
port = service->url->port;
else {
CamelProvider *prov = camel_service_get_provider (service);
-
+
port = prov->default_ports[CAMEL_PROVIDER_STORE];
g_assert (port); /* a remote service MUST define a valid default port */
}
-
- sin.sin_port = htons(port);
-
+
+ sin.sin_port = htons (port);
+
memcpy (&sin.sin_addr, h->h_addr, sizeof (sin.sin_addr));
fd = socket (h->h_addrtype, SOCK_STREAM, 0);
- if (fd == -1 || connect (fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
+ if (fd == -1 || connect (fd, (struct sockaddr *)&sin, sizeof (sin)) == -1) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
"Could not connect to %s (port %d): %s",
service->url->host ? service->url->host : "(unknown host)",
- port, strerror(errno));
+ port, g_strerror (errno));
if (fd > -1)
close (fd);
return FALSE;
}
-
+
/* parent class connect initialization */
CAMEL_SERVICE_CLASS (store_class)->connect (service, ex);
store->ostream = camel_stream_fs_new_with_fd (fd);
store->istream = camel_stream_buffer_new (store->ostream, CAMEL_STREAM_BUFFER_READ);
-
+
/* Okay, good enough for us */
CAMEL_SERVICE (store)->connected = TRUE;
-
+
/* implementation of postconnect */
CRSC (store)->post_connect (store, ex);
-
+
if (camel_exception_is_set (ex)) {
- /* FIXME: the real exception may get overridden? */
- camel_service_disconnect (CAMEL_SERVICE (store), ex);
+ CamelException dex;
+
+ camel_exception_init (&dex);
+ camel_service_disconnect (CAMEL_SERVICE (store), &dex);
return FALSE;
}
-
+
return TRUE;
}
-static gboolean timeout_cb (gpointer data)
+static gboolean
+timeout_cb (gpointer data)
{
CRSC (data)->keepalive (CAMEL_REMOTE_STORE (data));
return TRUE;
@@ -278,12 +282,12 @@ remote_post_connect (CamelRemoteStore *store, CamelException *ex)
/* (Only if the implementation supports it) */
if (CRSC (store)->keepalive) {
CamelSession *session = camel_service_get_session (CAMEL_SERVICE (store));
-
+
store->timeout_id = camel_session_register_timeout (session, 10 * 60 * 1000,
timeout_cb,
store);
}
-
+
/* Let's make sure that any of our folders are brought up to speed */
g_hash_table_foreach (CAMEL_STORE (store)->folders, refresh_folder_info, ex);
}
@@ -302,23 +306,23 @@ static gboolean
remote_disconnect (CamelService *service, CamelException *ex)
{
CamelRemoteStore *store = CAMEL_REMOTE_STORE (service);
-
+
CRSC (service)->pre_disconnect (store, ex);
/* if the exception is set, screw it and dconn anyway */
-
+
if (!CAMEL_SERVICE_CLASS (store_class)->disconnect (service, ex))
return FALSE;
-
+
if (store->istream) {
camel_object_unref (CAMEL_OBJECT (store->istream));
store->istream = NULL;
}
-
+
if (store->ostream) {
camel_object_unref (CAMEL_OBJECT (store->ostream));
store->ostream = NULL;
}
-
+
return TRUE;
}
@@ -332,13 +336,13 @@ static gint
remote_send_string (CamelRemoteStore *store, CamelException *ex, char *fmt, va_list ap)
{
gchar *cmdbuf;
-
+
/* Check for connectedness. Failed (or cancelled) operations will
* close the connection. */
-
+
if (store->ostream == NULL) {
d(g_message ("remote: (send) disconnected, reconnecting."));
-
+
if (!camel_service_connect (CAMEL_SERVICE (store), ex))
return -1;
}
@@ -349,11 +353,14 @@ remote_send_string (CamelRemoteStore *store, CamelException *ex, char *fmt, va_l
d(fprintf (stderr, "sending : \"%s\"\n", cmdbuf));
if (camel_stream_printf (store->ostream, "%s", cmdbuf) == -1) {
+ CamelException dex;
+
g_free (cmdbuf);
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
g_strerror (errno));
- /* FIXME: exception may be overridden */
- camel_service_disconnect (CAMEL_SERVICE (store), ex);
+
+ camel_exception_init (&dex);
+ camel_service_disconnect (CAMEL_SERVICE (store), &dex);
return -1;
}
g_free (cmdbuf);
@@ -378,14 +385,14 @@ camel_remote_store_send_string (CamelRemoteStore *store, CamelException *ex,
{
va_list ap;
gint ret;
-
+
g_return_val_if_fail (CAMEL_IS_REMOTE_STORE (store), -1);
g_return_val_if_fail (fmt, -1);
-
+
va_start (ap, fmt);
ret = CRSC (store)->send_string (store, ex, fmt, ap);
va_end (ap);
-
+
return ret;
}
@@ -394,10 +401,10 @@ remote_send_stream (CamelRemoteStore *store, CamelStream *stream, CamelException
{
/* Check for connectedness. Failed (or cancelled) operations will
* close the connection. */
-
+
if (store->ostream == NULL) {
d(g_message ("remote: (sendstream) disconnected, reconnecting."));
-
+
if (!camel_service_connect (CAMEL_SERVICE (store), ex))
return -1;
}
@@ -405,10 +412,13 @@ remote_send_stream (CamelRemoteStore *store, CamelStream *stream, CamelException
d(fprintf (stderr, "(sending stream)\n"));
if (camel_stream_write_to_stream (stream, store->ostream) < 0) {
+ CamelException dex;
+
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
g_strerror (errno));
- /* FIXME: exception may be overridden */
- camel_service_disconnect (CAMEL_SERVICE (store), ex);
+
+ camel_exception_init (&dex);
+ camel_service_disconnect (CAMEL_SERVICE (store), &dex);
return -1;
}
@@ -430,7 +440,7 @@ camel_remote_store_send_stream (CamelRemoteStore *store, CamelStream *stream, Ca
{
g_return_val_if_fail (CAMEL_IS_REMOTE_STORE (store), -1);
g_return_val_if_fail (CAMEL_IS_STREAM (stream), -1);
-
+
return CRSC (store)->send_stream (store, stream, ex);
}
@@ -438,38 +448,41 @@ static gint
remote_recv_line (CamelRemoteStore *store, char **dest, CamelException *ex)
{
CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream);
-
- (*dest) = NULL;
-
+
+ *dest = NULL;
+
/* Check for connectedness. Failed (or cancelled) operations will
* close the connection. We can't expect a read to have any
* meaning if we reconnect, so always set an exception.
*/
-
+
if (store->istream == NULL) {
g_message ("remote: (recv) disconnected, reconnecting.");
-
+
camel_service_connect (CAMEL_SERVICE (store), ex);
-
+
if (!camel_exception_is_set (ex))
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_NOT_CONNECTED,
g_strerror (errno));
-
+
return -1;
}
+
+ *dest = camel_stream_buffer_read_line (stream);
+
+ if (!*dest) {
+ CamelException dex;
- (*dest) = camel_stream_buffer_read_line (stream);
-
- if (!(*dest)) {
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
g_strerror (errno));
- /* FIXME: exception may be overridden */
- camel_service_disconnect (CAMEL_SERVICE (store), ex);
+
+ camel_exception_init (&dex);
+ camel_service_disconnect (CAMEL_SERVICE (store), &dex);
return -1;
}
-
- d(fprintf (stderr, "received: %s\n", (*dest)));
-
+
+ d(fprintf (stderr, "received: %s\n", *dest));
+
return 0;
}
@@ -490,7 +503,6 @@ camel_remote_store_recv_line (CamelRemoteStore *store, char **dest,
{
g_return_val_if_fail (CAMEL_IS_REMOTE_STORE (store), -1);
g_return_val_if_fail (dest, -1);
-
+
return CRSC (store)->recv_line (store, dest, ex);
}
-
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index b0dbad53a4..ce15fd7e97 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -63,31 +63,39 @@ static void imap_init (CamelFolder *folder, CamelStore *parent_store,
CamelFolder *parent_folder, const gchar *name,
gchar *separator, gboolean path_begns_with_sep,
CamelException *ex);
+static void imap_finalize (CamelObject *object);
static void imap_refresh_info (CamelFolder *folder, CamelException *ex);
static void imap_sync (CamelFolder *folder, gboolean expunge, CamelException *ex);
static void imap_expunge (CamelFolder *folder, CamelException *ex);
+/* message counts */
static gint imap_get_message_count_internal (CamelFolder *folder, CamelException *ex);
static gint imap_get_message_count (CamelFolder *folder);
static gint imap_get_unread_message_count (CamelFolder *folder);
-static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex);
-static void imap_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex);
-static void imap_copy_message_to (CamelFolder *source, const char *uid, CamelFolder *destination, CamelException *ex);
-static void imap_move_message_to (CamelFolder *source, const char *uid, CamelFolder *destination, CamelException *ex);
+/* message manipulation */
+static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid,
+ CamelException *ex);
+static void imap_append_message (CamelFolder *folder, CamelMimeMessage *message,
+ const CamelMessageInfo *info, CamelException *ex);
+static void imap_copy_message_to (CamelFolder *source, const char *uid,
+ CamelFolder *destination, CamelException *ex);
+static void imap_move_message_to (CamelFolder *source, const char *uid,
+ CamelFolder *destination, CamelException *ex);
+/* subfolder listing */
static GPtrArray *imap_get_subfolder_names_internal (CamelFolder *folder, CamelException *ex);
static GPtrArray *imap_get_subfolder_names (CamelFolder *folder);
+/* summary info */
static GPtrArray *imap_get_uids (CamelFolder *folder);
static GPtrArray *imap_get_summary_internal (CamelFolder *folder, CamelException *ex);
static GPtrArray *imap_get_summary (CamelFolder *folder);
static const CamelMessageInfo *imap_get_message_info (CamelFolder *folder, const char *uid);
+/* searching */
static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex);
-static void imap_finalize (CamelObject *object);
-
/* flag methods */
/*static guint32 imap_get_permanent_flags (CamelFolder *folder, CamelException *ex);*/
static guint32 imap_get_message_flags (CamelFolder *folder, const char *uid);
@@ -359,67 +367,66 @@ imap_expunge (CamelFolder *folder, CamelException *ex)
/* determine which messages were successfully expunged */
node = result;
for (i = 0; node; i++) {
- if (*node == '*') {
- char *word;
+ char *word;
+
+ if (*node != '*')
+ break;
+
+ word = imap_next_word (node);
+
+ if (!strncmp (word, "NO", 2)) {
+ /* Something failed, probably a Read-Only mailbox? */
+ CamelService *service = CAMEL_SERVICE (folder->parent_store);
+ char *reason, *ep;
- word = imap_next_word (node);
+ word = imap_next_word (word);
+ for (ep = word; *ep && *ep != '\n'; ep++);
+ reason = g_strndup (word, (gint)(ep - word));
- if (!strncmp (word, "NO", 2)) {
- /* Something failed, probably a Read-Only mailbox? */
- CamelService *service = CAMEL_SERVICE (folder->parent_store);
- char *reason, *ep;
-
- word = imap_next_word (word);
- for (ep = word; *ep && *ep != '\n'; ep++);
- reason = g_strndup (word, (gint)(ep - word));
-
- camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- "Could not EXPUNGE from IMAP server %s: %s.",
- service->url->host, reason ? reason :
- "Unknown error");
-
- g_free (reason);
- break;
- }
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ "Could not EXPUNGE from IMAP server %s: %s.",
+ service->url->host, reason ? reason :
+ "Unknown error");
- /* else we have a message id? */
- if (*word >= '0' && *word <= '9' && !strncmp ("EXPUNGE", imap_next_word (word), 7)) {
- int id;
+ g_free (reason);
+ break;
+ }
+
+ /* else we have a message id? */
+ if (*word >= '0' && *word <= '9' && !strncmp ("EXPUNGE", imap_next_word (word), 7)) {
+ int id;
+
+ id = atoi (word);
+
+ d(fprintf (stderr, "Expunging message %d from the summary (i = %d)\n", id + i, i));
+
+ if (id <= imap_folder->summary->len) {
+ CamelMessageInfo *info;
- id = atoi (word);
+ info = (CamelMessageInfo *) imap_folder->summary->pdata[id - 1];
- d(fprintf (stderr, "Expunging message %d from the summary (i = %d)\n", id + i, i));
+ /* remove from the lookup table and summary */
+ g_hash_table_remove (imap_folder->summary_hash, info->uid);
+ g_ptr_array_remove_index (imap_folder->summary, id - 1);
- if (id <= imap_folder->summary->len) {
- CamelMessageInfo *info;
-
- info = (CamelMessageInfo *) imap_folder->summary->pdata[id - 1];
-
- /* remove from the lookup table and summary */
- g_hash_table_remove (imap_folder->summary_hash, info->uid);
- g_ptr_array_remove_index (imap_folder->summary, id - 1);
-
- /* free the info data */
- g_free (info->subject);
- g_free (info->from);
- g_free (info->to);
- g_free (info->cc);
- g_free (info->uid);
- g_free (info->message_id);
- header_references_list_clear (&info->references);
- g_free (info);
- info = NULL;
- } else {
- /* Hopefully this should never happen */
- d(fprintf (stderr, "imap expunge-error: message %d is out of range\n", id));
- }
- } else if (*word >= '0' && *word <= '9' && !strncmp ("RECENT", imap_next_word (word), 6)) {
- recent = atoi (word);
- if (!recent)
- recent = -1;
+ /* free the info data */
+ g_free (info->subject);
+ g_free (info->from);
+ g_free (info->to);
+ g_free (info->cc);
+ g_free (info->uid);
+ g_free (info->message_id);
+ header_references_list_clear (&info->references);
+ g_free (info);
+ info = NULL;
+ } else {
+ /* Hopefully this should never happen */
+ d(fprintf (stderr, "imap expunge-error: message %d is out of range\n", id));
}
- } else {
- break;
+ } else if (*word >= '0' && *word <= '9' && !strncmp ("RECENT", imap_next_word (word), 6)) {
+ recent = atoi (word);
+ if (!recent)
+ recent = -1;
}
for ( ; *node && *node != '\n'; node++);
@@ -456,7 +463,7 @@ imap_get_message_count_internal (CamelFolder *folder, CamelException *ex)
else
status = camel_imap_command_extended (CAMEL_IMAP_STORE (store), folder,
&result, ex, "EXAMINE %s", folder_path);
-
+
g_free (folder_path);
if (status != CAMEL_IMAP_OK)
@@ -580,7 +587,7 @@ imap_append_message (CamelFolder *folder, CamelMimeMessage *message, const Camel
if (status != CAMEL_IMAP_OK)
return;
-
+
g_free (result);
camel_object_unref (CAMEL_OBJECT (memstream));
@@ -637,7 +644,7 @@ imap_move_message_to (CamelFolder *source, const char *uid, CamelFolder *destina
if (status != CAMEL_IMAP_OK)
return;
-
+
g_free (result);
if (!(info = (CamelMessageInfo *)imap_get_message_info (source, uid))) {
@@ -690,20 +697,6 @@ imap_get_subfolder_names_internal (CamelFolder *folder, CamelException *ex)
dir_sep = CAMEL_IMAP_STORE (folder->parent_store)->dir_sep;
-#if 0
- /* this is the old code, the new code hasn't been tested */
- if (url && url->path) {
- if (!strcmp (folder->full_name, url->path + 1))
- namespace = g_strdup (url->path + 1);
- else if (!g_strcasecmp (folder->full_name, "INBOX"))
- namespace = g_strdup (url->path + 1); /* FIXME: erm...not sure */
- else
- namespace = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name);
- } else {
- namespace = g_strdup (folder->full_name);
- }
-#endif
-
if (url && url->path) {
char *path = url->path + 1;
@@ -937,7 +930,7 @@ imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
#endif
camel_object_unref (CAMEL_OBJECT (msgstream));
/*camel_object_unref (CAMEL_OBJECT (f_stream));*/
-
+
d(fprintf (stderr, "*** We're returning... ***\n"));
g_free (mesg);
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 45f3794627..fc11631209 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -75,13 +75,13 @@ camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class)
remote_store_class = CAMEL_REMOTE_STORE_CLASS(camel_type_get_global_classfuncs
(camel_remote_store_get_type ()));
-
+
/* virtual method overload */
camel_service_class->query_auth_types_generic = query_auth_types_generic;
camel_service_class->query_auth_types_connected = query_auth_types_connected;
-
+
camel_store_class->get_folder = get_folder;
-
+
camel_remote_store_class->post_connect = imap_post_connect;
camel_remote_store_class->pre_disconnect = imap_pre_disconnect;
camel_remote_store_class->keepalive = imap_keepalive;
@@ -92,11 +92,11 @@ camel_imap_store_init (gpointer object, gpointer klass)
{
CamelService *service = CAMEL_SERVICE (object);
CamelImapStore *imap_store = CAMEL_IMAP_STORE (object);
-
+
service->url_flags |= (CAMEL_SERVICE_URL_NEED_USER |
CAMEL_SERVICE_URL_NEED_HOST |
CAMEL_SERVICE_URL_ALLOW_PATH);
-
+
imap_store->dir_sep = g_strdup ("/"); /*default*/
imap_store->current_folder = NULL;
}
@@ -107,13 +107,14 @@ camel_imap_store_get_type (void)
static CamelType camel_imap_store_type = CAMEL_INVALID_TYPE;
if (camel_imap_store_type == CAMEL_INVALID_TYPE) {
- camel_imap_store_type = camel_type_register (CAMEL_REMOTE_STORE_TYPE, "CamelImapStore",
- sizeof (CamelImapStore),
- sizeof (CamelImapStoreClass),
- (CamelObjectClassInitFunc) camel_imap_store_class_init,
- NULL,
- (CamelObjectInitFunc) camel_imap_store_init,
- (CamelObjectFinalizeFunc) NULL);
+ camel_imap_store_type =
+ camel_type_register (CAMEL_REMOTE_STORE_TYPE, "CamelImapStore",
+ sizeof (CamelImapStore),
+ sizeof (CamelImapStoreClass),
+ (CamelObjectClassInitFunc) camel_imap_store_class_init,
+ NULL,
+ (CamelObjectInitFunc) camel_imap_store_init,
+ (CamelObjectFinalizeFunc) NULL);
}
return camel_imap_store_type;
@@ -175,9 +176,9 @@ imap_post_connect (CamelRemoteStore *remote_store, CamelException *ex)
CamelService *service = CAMEL_SERVICE (remote_store);
CamelImapStore *store = CAMEL_IMAP_STORE (remote_store);
CamelSession *session = camel_service_get_session (CAMEL_SERVICE (store));
- gint status;
gchar *buf, *result, *errbuf = NULL;
gboolean authenticated = FALSE;
+ gint status;
store->command = 0;
g_free (store->dir_sep);
@@ -513,14 +514,14 @@ static gint
check_current_folder (CamelImapStore *store, CamelFolder *folder, char *fmt, CamelException *ex)
{
CamelURL *url = CAMEL_SERVICE (store)->url;
- char *r, *folder_path, *dir_sep;
- int s;
+ char *result, *folder_path, *dir_sep;
+ int status;
- if (!folder)
- return CAMEL_IMAP_OK;
- if (store->current_folder == folder)
- return CAMEL_IMAP_OK;
- if (strncmp (fmt, "CREATE", 5) == 0)
+ /* return OK if we meet one of the following criteria:
+ * 1. the command doesn't care about which folder we're in (folder == NULL)
+ * 2. if we're already in the right folder (store->current_folder == folder)
+ * 3. we're going to create a new folder */
+ if (!folder || store->current_folder == folder || !strncmp (fmt, "CREATE", 5))
return CAMEL_IMAP_OK;
dir_sep = store->dir_sep;
@@ -529,21 +530,23 @@ check_current_folder (CamelImapStore *store, CamelFolder *folder, char *fmt, Cam
folder_path = g_strdup_printf ("%s%s%s", url->path + 1, dir_sep, folder->full_name);
else
folder_path = g_strdup (folder->full_name);
-
- s = camel_imap_command_extended (store, NULL, &r, ex, "SELECT %s", folder_path);
+
+ status = camel_imap_command_extended (store, NULL, &result, ex, "SELECT %s", folder_path);
g_free (folder_path);
- if (!r || s != CAMEL_IMAP_OK) {
+ if (!result || status != CAMEL_IMAP_OK) {
store->current_folder = NULL;
- return s;
+ return status;
}
+ g_free (result);
- g_free (r);
+ /* remember our currently selected folder */
store->current_folder = folder;
+
return CAMEL_IMAP_OK;
}
-static gint
+static gboolean
send_command (CamelImapStore *store, char **cmdid, char *fmt, va_list ap, CamelException *ex)
{
gchar *cmdbuf;
@@ -556,11 +559,11 @@ send_command (CamelImapStore *store, char **cmdid, char *fmt, va_list ap, CamelE
g_free (cmdbuf);
g_free (*cmdid);
*cmdid = NULL;
- return CAMEL_IMAP_FAIL;
+ return FALSE;
}
g_free (cmdbuf);
- return CAMEL_IMAP_OK;
+ return TRUE;
}
static gint
@@ -578,8 +581,14 @@ slurp_response (CamelImapStore *store, CamelFolder *folder, char *cmdid, char **
expunged = g_ptr_array_new ();
while (1) {
- if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0)
+ if (camel_remote_store_recv_line (CAMEL_REMOTE_STORE (store), &respbuf, ex) < 0) {
+ for (i = 0; i < data->len; i++)
+ g_free (data->pdata[i]);
+ g_ptr_array_free (data, TRUE);
+ g_ptr_array_free (expunged, TRUE);
+
return CAMEL_IMAP_FAIL;
+ }
g_ptr_array_add (data, respbuf);
len += strlen (respbuf) + 1;
@@ -762,10 +771,11 @@ camel_imap_command (CamelImapStore *store, CamelFolder *folder, CamelException *
/* send the command */
va_start (ap, fmt);
- status = send_command (store, &cmdid, fmt, ap, ex);
+ if (!send_command (store, &cmdid, fmt, ap, ex)) {
+ va_end (ap);
+ return CAMEL_IMAP_FAIL;
+ }
va_end (ap);
- if (status != CAMEL_IMAP_OK)
- return status;
return parse_single_line (store, cmdid, ex);
}
@@ -809,13 +819,14 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
status = check_current_folder (store, folder, fmt, ex);
if (status != CAMEL_IMAP_OK)
return status;
-
+
/* send the command */
va_start (ap, fmt);
- status = send_command (store, &cmdid, fmt, ap, ex);
+ if (!send_command (store, &cmdid, fmt, ap, ex)) {
+ va_end (ap);
+ return CAMEL_IMAP_FAIL;
+ }
va_end (ap);
- if (status != CAMEL_IMAP_OK)
- return status;
return slurp_response (store, folder, cmdid, ret, FALSE, ex);
}
@@ -838,7 +849,8 @@ camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **
* containing the rest of the response from the IMAP server. The
* caller function is responsible for freeing @ret.
*
- * Return value: one of CAMEL_IMAP_PLUS, CAMEL_IMAP_OK, or CAMEL_IMAP_FAIL
+ * Return value: one of CAMEL_IMAP_PLUS, CAMEL_IMAP_NO, CAMEL_IMAP_BAD
+ * or CAMEL_IMAP_FAIL
*
* Note: on success (CAMEL_IMAP_PLUS), you will need to follow up with
* a camel_imap_command_continuation call.
@@ -851,10 +863,11 @@ camel_imap_command_preliminary (CamelImapStore *store, char **cmdid, CamelExcept
/* send the command */
va_start (ap, fmt);
- status = send_command (store, cmdid, fmt, ap, ex);
+ if (!send_command (store, cmdid, fmt, ap, ex)) {
+ va_end (ap);
+ return CAMEL_IMAP_FAIL;
+ }
va_end (ap);
- if (status != CAMEL_IMAP_OK)
- return status;
/* Read the response */
return parse_single_line (store, g_strdup (*cmdid), ex);
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
index c153b11aa4..eecc42a1e0 100644
--- a/camel/providers/imap/camel-imap-store.h
+++ b/camel/providers/imap/camel-imap-store.h
@@ -83,13 +83,29 @@ enum {
CAMEL_IMAP_FAIL
};
-gint camel_imap_command (CamelImapStore *store, CamelFolder *folder, CamelException *ex, char *fmt, ...);
-gint camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder, char **ret, CamelException *ex, char *fmt, ...);
+gint camel_imap_command (CamelImapStore *store, CamelFolder *folder,
+ CamelException *ex, char *fmt, ...);
+
+gint camel_imap_command_extended (CamelImapStore *store, CamelFolder *folder,
+ char **ret, CamelException *ex, char *fmt, ...);
/* multi-transactional commands... */
-gint camel_imap_command_preliminary (CamelImapStore *store, char **cmdid, CamelException *ex, char *fmt, ...);
-gint camel_imap_command_continuation (CamelImapStore *store, char **ret, char *cmdid, char *cmdbuf, CamelException *ex);
-gint camel_imap_command_continuation_with_stream (CamelImapStore *store, char **ret, char *cmdid, CamelStream *cstream, CamelException *ex);
+gint camel_imap_command_preliminary (CamelImapStore *store,
+ char **cmdid,
+ CamelException *ex,
+ char *fmt, ...);
+
+gint camel_imap_command_continuation (CamelImapStore *store,
+ char **ret,
+ char *cmdid,
+ char *cmdbuf,
+ CamelException *ex);
+
+gint camel_imap_command_continuation_with_stream (CamelImapStore *store,
+ char **ret,
+ char *cmdid,
+ CamelStream *cstream,
+ CamelException *ex);
/* Standard Camel function */
CamelType camel_imap_store_get_type (void);