diff options
Diffstat (limited to 'camel/providers')
-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 |
3 files changed, 145 insertions, 123 deletions
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); |