aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap/camel-imap-folder.c
diff options
context:
space:
mode:
Diffstat (limited to 'camel/providers/imap/camel-imap-folder.c')
-rw-r--r--camel/providers/imap/camel-imap-folder.c198
1 files changed, 122 insertions, 76 deletions
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index ef4df4b4ce..443e1b8fbf 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -37,7 +37,10 @@
#include "camel-imap-folder.h"
#include "camel-imap-store.h"
#include "string-utils.h"
+#include "camel-stream.h"
#include "camel-stream-fs.h"
+#include "camel-stream-mem.h"
+#include "camel-stream-buffer.h"
#include "camel-data-wrapper.h"
#include "camel-mime-message.h"
#include "camel-stream-filter.h"
@@ -49,8 +52,8 @@
static CamelFolderClass *parent_class = NULL;
static void imap_init (CamelFolder *folder, CamelStore *parent_store,
- CamelFolder *parent_folder, const gchar *name,
- gchar separator, CamelException *ex);
+ CamelFolder *parent_folder, const gchar *name,
+ gchar separator, CamelException *ex);
static void imap_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex);
static void imap_close (CamelFolder *folder, gboolean expunge, CamelException *ex);
@@ -164,10 +167,10 @@ camel_imap_folder_get_type (void)
CamelFolder *
camel_imap_folder_new (CamelStore *parent, CamelException *ex)
{
- /* TODO: code this */
+ /* TODO: code this - do we need this? */
CamelFolder *folder = CAMEL_FOLDER (gtk_object_new (camel_imap_folder_get_type (), NULL));
- CF_CLASS (folder)->init (folder, parent, NULL, "inbox", '/', ex);
+ CAMEL_FOLDER_CLASS (folder)->init (folder, parent, NULL, "inbox", '/', ex);
return folder;
}
@@ -224,8 +227,10 @@ imap_init (CamelFolder *folder, CamelStore *parent_store, CamelFolder *parent_fo
root_dir_path = camel_imap_store_get_toplevel_dir (CAMEL_IMAP_STORE(folder->parent_store));
imap_folder->folder_file_path = g_strdup_printf ("%s/%s", root_dir_path, folder->full_name);
+#if 0
imap_folder->folder_dir_path = g_strdup_printf ("%s/%s.sdb", root_dir_path, folder->full_name);
imap_folder->index_file_path = g_strdup_printf ("%s/%s.ibex", root_dir_path, folder->full_name);
+#endif
}
static void
@@ -242,7 +247,7 @@ imap_open (CamelFolder *folder, CamelFolderOpenMode mode, CamelException *ex)
/* SELECT the IMAP mail spool */
status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), &result,
- "SELECT %s", imap_folder->folder_file_path);
+ "SELECT %s", imap_folder->folder_file_path);
if (status != CAMEL_IMAP_OK) {
CamelService *service = CAMEL_SERVICE (folder->parent_store);
@@ -267,12 +272,14 @@ imap_close (CamelFolder *folder, gboolean expunge, CamelException *ex)
camel_imap_store_close (CAMEL_IMAP_STORE (folder->parent_store), expunge, ex);
if (camel_exception_get_id (ex) == CAMEL_EXCEPTION_NONE)
parent_class->close (folder, expunge, ex);
+
+
}
static void
imap_expunge (CamelFolder *folder, CamelException *ex)
{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+ /*CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);*/
gchar *result;
gint status;
@@ -298,9 +305,11 @@ imap_expunge (CamelFolder *folder, CamelException *ex)
static gboolean
imap_exists (CamelFolder *folder, CamelException *ex)
{
- /* TODO: look at Mbox code and figure out exactly what needs to be done here */
- CamelImapFolder *imap_folder;
- gboolean exists;
+ /* make sure the folder exists */
+ CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+ GPtrArray *lsub;
+ gboolean exists = FALSE;
+ int i, max;
g_return_val_if_fail (folder != NULL, FALSE);
@@ -320,7 +329,21 @@ imap_exists (CamelFolder *folder, CamelException *ex)
return FALSE;
}
- /* TODO: Finish coding this. */
+ /* Get a listing of the folders that exist */
+ lsub = imap_get_subfolder_names (folder, ex);
+
+ /* look to see if any of those subfolders match... */
+ max = lsub->len;
+ for (i = 0; i < max; i++)
+ if (!strcmp(g_ptr_array_index(lsub, i), imap_folder->folder_file_path))
+ {
+ exists = TRUE;
+ break;
+ }
+
+ g_ptr_array_free (lsub, TRUE);
+
+ return exists;
}
static gboolean
@@ -348,7 +371,6 @@ imap_create (CamelFolder *folder, CamelException *ex)
"invalid folder path. Use set_name ?");
return FALSE;
}
-
/* if the folder already exists, simply return */
folder_already_exists = camel_folder_exists (folder, ex);
@@ -358,7 +380,6 @@ imap_create (CamelFolder *folder, CamelException *ex)
if (folder_already_exists)
return TRUE;
-
/* create the directory for the subfolder */
status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), &result,
"CREATE %s", imap_folder->folder_file_path);
@@ -427,18 +448,19 @@ imap_delete (CamelFolder *folder, gboolean recurse, CamelException *ex)
return TRUE;
}
-/* TODO: remove this */
+/* TODO: remove this - don't bother coding, it'll be moved/removed */
gboolean
imap_delete_messages (CamelFolder *folder, CamelException *ex)
{
/* TODO: delete the messages (mark as deleted/whatever) */
+#if 0
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
gchar *result;
gint status;
+#endif
g_return_val_if_fail (folder != NULL, FALSE);
-
return TRUE;
}
@@ -453,10 +475,10 @@ imap_get_message_count (CamelFolder *folder, CamelException *ex)
/* If we already have a count, return */
if (imap_folder->count != -1)
- imap_folder->count;
+ return imap_folder->count;
status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), &result,
- "STATUS %s (MESSAGES)", imap_folder->folder_file_path);
+ "STATUS %s (MESSAGES)", imap_folder->folder_file_path);
if (status != CAMEL_IMAP_OK) {
CamelService *service = CAMEL_SERVICE (folder->parent_store);
@@ -471,10 +493,11 @@ imap_get_message_count (CamelFolder *folder, CamelException *ex)
/* parse out the message count - should come in the form: "* STATUS <folder> (MESSAGES <count>)\r\n" */
if (result && *result == '*') {
- /* FIXME: This should really be rewritten to not depend on absolute spacing */
- if (msg_count = strstr(result, "MESSAGES")) {
+ if ((msg_count = strstr(result, "MESSAGES")) != NULL) {
msg_count += strlen("MESSAGES") + 1;
+ for ( ; *msg_count == ' '; msg_count++);
+
/* we should now be pointing to the message count */
imap_folder->count = atoi(msg_count);
}
@@ -490,17 +513,17 @@ static void
imap_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelException *ex)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- CamelStreamBuffer *stream = CAMEL_STREAM_BUFFER (store->istream);
CamelStreamMem *mem;
- gchar *cmdid, *respbuf;
+ gchar *result;
+ gint status;
g_return_if_fail (folder != NULL);
g_return_if_fail (message != NULL);
/* write the message to a CamelStreamMem so we can get it's size */
- mem = CAMEL_STREAM_MEM (camel_stream_mem_new());
+ mem = camel_stream_mem_new();
if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), CAMEL_STREAM (mem)) == -1) {
+ CamelService *service = CAMEL_SERVICE (folder->parent_store);
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
"Could not APPEND message to IMAP server %s: %s.",
service->url->host,
@@ -509,8 +532,9 @@ imap_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept
return;
}
- mem->buffer = g_byte_array_append(mem->buffer, g_strdup("\n"));
+ mem->buffer = g_byte_array_append(mem->buffer, g_strdup("\n"), 2);
status = camel_imap_command(CAMEL_IMAP_STORE (folder->parent_store),
+ &result,
"APPEND %s (\\Seen) {%d}\r\n%s",
imap_folder->folder_file_path,
mem->buffer->len,
@@ -534,43 +558,38 @@ imap_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept
static GPtrArray *
imap_get_uids (CamelFolder *folder, CamelException *ex)
{
- return g_ptr_array_new();
-#if 0
- /* TODO: Find out what this is actually supposed to do */
- GPtrArray *array;
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+ CamelImapMessageInfo *info;
+ GPtrArray *array;
gint i, count;
- count = camel_folder_summary_count((CamelFolderSummary *)imap_folder->summary);
+ count = camel_folder_summary_count(CAMEL_FOLDER_SUMMARY (imap_folder->summary));
array = g_ptr_array_new ();
g_ptr_array_set_size (array, count);
for (i = 0; i < count; i++) {
- CamelImapMessageInfo *info =
- (CamelImapMessageInfo *)camel_folder_summary_index((CamelFolderSummary *)imap_folder->summary, i);
+ info = CAMEL_IMAP_MESSAGE_INFO (camel_folder_summary_index(CAMEL_FOLDER_SUMMARY (imap_folder->summary), i));
array->pdata[i] = g_strdup(info->info.uid);
}
return array;
-#endif
}
static GPtrArray *
imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
{
- /* NOTE: use LSUB or LIST - preferably LSUB but I managed with LIST in Spruce */
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
GPtrArray *listing;
gint status;
gchar *result;
-
+
g_return_val_if_fail (folder != NULL, g_ptr_array_new());
-
+
if (imap_folder->count != -1)
- imap_folder->count;
-
+ return g_ptr_array_new ();
+
status = camel_imap_command_extended (CAMEL_IMAP_STORE (folder->parent_store), &result,
- "LSUB \"\" \"%s\"", imap_folder->folder_file_path);
-
+ "LSUB \"\" \"%s\"", imap_folder->folder_file_path);
+
if (status != CAMEL_IMAP_OK) {
CamelService *service = CAMEL_SERVICE (folder->parent_store);
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
@@ -581,18 +600,20 @@ imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
g_free (result);
return g_ptr_array_new ();
}
-
+
/* parse out the subfolders */
listing = g_ptr_array_new ();
+ g_ptr_array_add(listing, g_strdup("INBOX"));
if (result) {
- ptr = result;
+ char *ptr = result;
+
while (*ptr == '*') {
- gchar *flags, *param, *end, *dir_sep;
-
+ gchar *flags, *end, *dir_sep, *param = NULL;
+
ptr = flags = strchr(ptr, '(') + 1; /* jump to the flags section */
end = strchr(flags, ')'); /* locate end of flags */
- flags = strndup(flags, (gint)(end - flags));
-
+ flags = g_strndup(flags, (gint)(end - flags));
+
if (strstr(flags, "\\NoSelect")) {
g_free(flags);
continue;
@@ -608,7 +629,7 @@ imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
for (end = ptr; *end && *end != '\n'; end++);
param = g_strndup(ptr, (gint)(end - ptr));
- g_ptr_array_add (listing, param);
+ g_ptr_array_add(listing, param);
g_free(dir_sep); /* TODO: decide if we really need dir_sep */
@@ -624,19 +645,20 @@ imap_get_subfolder_names (CamelFolder *folder, CamelException *ex)
}
static void
-imap_delete_message_by_uid(CamelFolder *folder, const gchar *uid, CamelException *ex)
+imap_delete_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *ex)
{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
+ /*CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);*/
gchar *result;
gint status;
status = camel_imap_command_extended(CAMEL_IMAP_STORE (folder->parent_store),
- "STORE %s +FLAGS.SILENT (\\Deleted)", uid);
+ &result, "UID STORE %s +FLAGS.SILENT (\\Deleted)", uid);
if (status != CAMEL_IMAP_OK) {
CamelService *service = CAMEL_SERVICE (folder->parent_store);
+
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
- "Could not mark message %s as 'Deleted' on IMAP server %s: %s"
+ "Could not mark message %s as 'Deleted' on IMAP server %s: %s",
uid, service->url->host,
status == CAMEL_IMAP_ERR ? result :
"Unknown error");
@@ -650,19 +672,15 @@ imap_delete_message_by_uid(CamelFolder *folder, const gchar *uid, CamelException
/* track flag changes in the summary */
static void
-message_changed(CamelMimeMessage *m, int type, CamelImapFolder *mf)
+message_changed (CamelMimeMessage *m, int type, CamelImapFolder *mf)
{
- return;
-
-#if 0
- /* TODO: find a way to do this in IMAP - will probably not be easy */
CamelMessageInfo *info;
CamelFlag *flag;
printf("Message changed: %s: %d\n", m->message_uid, type);
switch (type) {
case MESSAGE_FLAGS_CHANGED:
- info = camel_folder_summary_uid((CamelFolderSummary *)mf->summary, m->message_uid);
+ info = camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY (mf->summary), m->message_uid);
if (info) {
info->flags = m->flags | CAMEL_MESSAGE_FOLDER_FLAGGED;
camel_flag_list_free(&info->user_flags);
@@ -671,7 +689,7 @@ message_changed(CamelMimeMessage *m, int type, CamelImapFolder *mf)
camel_flag_set(&info->user_flags, flag->name, TRUE);
flag = flag->next;
}
- camel_folder_summary_touch((CamelFolderSummary *)mf->summary);
+ camel_folder_summary_touch(CAMEL_FOLDER_SUMMARY (mf->summary));
} else
g_warning("Message changed event on message not in summary: %s", m->message_uid);
break;
@@ -679,7 +697,6 @@ message_changed(CamelMimeMessage *m, int type, CamelImapFolder *mf)
printf("Unhandled message change event: %d\n", type);
break;
}
-#endif
}
static CamelMimeMessage *
@@ -687,15 +704,15 @@ imap_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *
{
/* NOTE: extremely easy to do in IMAP - just needa code it ;-) */
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelStream *message_stream = NULL;
+ CamelStreamMem *message_stream = NULL;
CamelMimeMessage *message = NULL;
CamelImapMessageInfo *info;
CamelMimeParser *parser = NULL;
- gchar *buffer;
- gint len;
+ gchar *buffer, *result;
+ gint len, status;
/* get the message summary info */
- info = (CamelImapMessageInfo *)camel_folder_summary_uid((CamelFolderSummary *)imap_folder->summary, uid);
+ info = (CamelImapMessageInfo *)camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY (imap_folder->summary), uid);
if (info == NULL) {
errno = ENOENT;
@@ -706,8 +723,24 @@ imap_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *
g_assert(info->info.content);
g_assert(info->frompos != -1);
+ /* get our message buffer */
+ status = camel_imap_command_extended(CAMEL_IMAP_STORE (folder->parent_store),
+ &result, "UID FETCH %s (FLAGS BODY[])", uid);
+
+ if (status != CAMEL_IMAP_OK) {
+ CamelService *service = CAMEL_SERVICE (folder->parent_store);
+
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
+ "Could not mark message %s as 'Deleted' on IMAP server %s: %s",
+ uid, service->url->host,
+ status == CAMEL_IMAP_ERR ? result :
+ "Unknown error");
+ g_free (result);
+ return;
+ }
+
/* where we read from */
- message_stream = camel_stream_fs_new_with_name (imap_folder->folder_file_path, O_RDONLY, 0);
+ message_stream = camel_stream_mem_new_with_buffer (result, strlen(result));
if (message_stream == NULL)
goto fail;
@@ -724,13 +757,15 @@ imap_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *
}
if (camel_mime_parser_tell_start_from(parser) != info->frompos) {
- g_warning("Summary doesn't match the folder contents! eek!");
+ g_warning("Summary doesn't match the folder contents! eek!"
+ " expecting offset %ld got %ld", (long int)info->frompos,
+ (long int)camel_mime_parser_tell_start_from(parser));
errno = EINVAL;
goto fail;
}
message = camel_mime_message_new();
- if (camel_mime_part_construct_from_parser((CamelMimePart *)message, parser) == -1) {
+ if (camel_mime_part_construct_from_parser(CAMEL_MIME_PART (message), parser) == -1) {
g_warning("Construction failed");
goto fail;
}
@@ -746,15 +781,15 @@ imap_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException *
return message;
-fail:
+ fail:
camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
"Cannot get message: %s",
g_strerror(errno));
if (parser)
- gtk_object_unref((GtkObject *)parser);
+ gtk_object_unref(GTK_OBJECT (parser));
if (message)
- gtk_object_unref((GtkObject *)message);
+ gtk_object_unref(GTK_OBJECT (message));
return NULL;
}
@@ -763,33 +798,33 @@ GPtrArray *
imap_get_summary (CamelFolder *folder, CamelException *ex)
{
/* TODO: what should we do here?? */
- CamelImapFolder *imap_folder = (CamelImapFolder *)folder;
+ CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- return ((CamelFolderSummary *)imap_folder->summary)->messages;
+ return CAMEL_FOLDER_SUMMARY (imap_folder->summary)->messages;
}
void
imap_free_summary (CamelFolder *folder, GPtrArray *array)
{
- /* This is IMAP dude, no need to free a summary */
+ /* no-op */
return;
}
/* get a single message info, by uid */
static const CamelMessageInfo *
-imap_summary_get_by_uid(CamelFolder *f, const char *uid)
+imap_summary_get_by_uid (CamelFolder *f, const char *uid)
{
/* TODO: what do we do here? */
- CamelImapFolder *imap_folder = (CamelImapFolder *)f;
+ CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (f);
- return camel_folder_summary_uid((CamelFolderSummary *)imap_folder->summary, uid);
+ return camel_folder_summary_uid(CAMEL_FOLDER_SUMMARY (imap_folder->summary), uid);
}
static GList *
-imap_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex)
+imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex)
{
/* TODO: find a good way of doing this */
- CamelImapFolder *imap_folder = (CamelImapFolder *)folder;
+ CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
if (imap_folder->search == NULL) {
imap_folder->search = camel_folder_search_new();
@@ -798,7 +833,8 @@ imap_search_by_expression(CamelFolder *folder, const char *expression, CamelExce
camel_folder_search_set_folder(imap_folder->search, folder);
if (imap_folder->summary)
/* FIXME: dont access summary array directly? */
- camel_folder_search_set_summary(imap_folder->search, ((CamelFolderSummary *)imap_folder->summary)->messages);
+ camel_folder_search_set_summary(imap_folder->search,
+ CAMEL_FOLDER_SUMMARY (imap_folder->summary)->messages);
camel_folder_search_set_body_index(imap_folder->search, imap_folder->index);
return camel_folder_search_execute_expression(imap_folder->search, expression, ex);
@@ -808,3 +844,13 @@ imap_search_by_expression(CamelFolder *folder, const char *expression, CamelExce
+
+
+
+
+
+
+
+
+
+