diff options
author | Jeffrey Stedfast <fejj@helixcode.com> | 2000-08-30 12:03:07 +0800 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2000-08-30 12:03:07 +0800 |
commit | 149838c6df1ec4579b2cea7e95014f80151637f1 (patch) | |
tree | f7ead9801942f576ce9487be6f745a19969dc60b /camel | |
parent | 3242c4685bc4a021efb58bbefe1603c1f5f8d2ea (diff) | |
download | gsoc2013-evolution-149838c6df1ec4579b2cea7e95014f80151637f1.tar.gz gsoc2013-evolution-149838c6df1ec4579b2cea7e95014f80151637f1.tar.zst gsoc2013-evolution-149838c6df1ec4579b2cea7e95014f80151637f1.zip |
Prevent exceptions from being overwritten
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
svn path=/trunk/; revision=5107
Diffstat (limited to 'camel')
-rw-r--r-- | camel/ChangeLog | 8 | ||||
-rw-r--r-- | camel/camel-remote-store.c | 152 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-folder.c | 149 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.c | 93 | ||||
-rw-r--r-- | camel/providers/imap/camel-imap-store.h | 26 |
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); |