aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers')
-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
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);