summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2001-08-07 02:03:22 +0000
committerJeffrey Stedfast <fejj@src.gnome.org>2001-08-07 02:03:22 +0000
commit0e1f7c05eb61aa3fdc92e79ca0d7af795c4a2d67 (patch)
treee722fb0ef04aca7af482545301f92195c404848f
parent5fc7ef31b4234ae3b157b787af9e205138c627e4 (diff)
downloadevolution-data-server-0e1f7c05eb61aa3fdc92e79ca0d7af795c4a2d67.tar.gz
New internal function to get a message stream by message sequence id (so
2001-08-06 Jeffrey Stedfast <fejj@ximian.com> * providers/pop3/camel-pop3-folder.c (pop3_get_message_stream): New internal function to get a message stream by message sequence id (so that we can share code between pop3_get_message and pop3_generate_uids). (pop3_get_message): Use pop3_get_message_stream. (pop3_generate_uids): New function to generate UIDs based on the message - this fixes bug #1256. (pop3_refresh_info): If the server doesn't support UIDL, call pop3_generate_uids to get our list of UIDs. * providers/imap/camel-imap-store.c (get_folder_info_online): Don't strstr for noselect=yes, that's just plain broken.
-rw-r--r--camel/ChangeLog10
-rw-r--r--camel/providers/pop3/camel-pop3-folder.c187
2 files changed, 129 insertions, 68 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index fd46fc93c..219209bd8 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,5 +1,15 @@
2001-08-06 Jeffrey Stedfast <fejj@ximian.com>
+ * providers/pop3/camel-pop3-folder.c (pop3_get_message_stream):
+ New internal function to get a message stream by message sequence
+ id (so that we can share code between pop3_get_message and
+ pop3_generate_uids).
+ (pop3_get_message): Use pop3_get_message_stream.
+ (pop3_generate_uids): New function to generate UIDs based on the
+ message - this fixes bug #1256.
+ (pop3_refresh_info): If the server doesn't support UIDL, call
+ pop3_generate_uids to get our list of UIDs.
+
* providers/imap/camel-imap-store.c (get_folder_info_online):
Don't strstr for noselect=yes, that's just plain broken.
diff --git a/camel/providers/pop3/camel-pop3-folder.c b/camel/providers/pop3/camel-pop3-folder.c
index 0032077fd..2648a48a5 100644
--- a/camel/providers/pop3/camel-pop3-folder.c
+++ b/camel/providers/pop3/camel-pop3-folder.c
@@ -35,6 +35,8 @@
#include "camel-mime-message.h"
#include "camel-operation.h"
+#include <e-util/md5-utils.h>
+
#include <stdlib.h>
#include <string.h>
@@ -49,6 +51,8 @@ static void pop3_sync (CamelFolder *folder, gboolean expunge,
static gint pop3_get_message_count (CamelFolder *folder);
static GPtrArray *pop3_get_uids (CamelFolder *folder);
+static CamelStreamMem *pop3_get_message_stream (CamelFolder *folder, int id,
+ CamelException *ex);
static CamelMimeMessage *pop3_get_message (CamelFolder *folder,
const char *uid,
CamelException *ex);
@@ -62,17 +66,17 @@ camel_pop3_folder_class_init (CamelPop3FolderClass *camel_pop3_folder_class)
{
CamelFolderClass *camel_folder_class =
CAMEL_FOLDER_CLASS (camel_pop3_folder_class);
-
+
parent_class = CAMEL_FOLDER_CLASS(camel_type_get_global_classfuncs (camel_folder_get_type ()));
-
+
/* virtual method overload */
camel_folder_class->refresh_info = pop3_refresh_info;
camel_folder_class->sync = pop3_sync;
-
+
camel_folder_class->get_message_count = pop3_get_message_count;
camel_folder_class->get_uids = pop3_get_uids;
camel_folder_class->free_uids = camel_folder_free_nop;
-
+
camel_folder_class->get_message = pop3_get_message;
camel_folder_class->set_message_flags = pop3_set_message_flags;
}
@@ -82,10 +86,10 @@ camel_pop3_folder_init (gpointer object)
{
CamelFolder *folder = CAMEL_FOLDER (object);
CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (object);
-
+
folder->has_summary_capability = FALSE;
folder->has_search_capability = FALSE;
-
+
pop3_folder->uids = NULL;
pop3_folder->flags = NULL;
}
@@ -94,7 +98,7 @@ CamelType
camel_pop3_folder_get_type (void)
{
static CamelType camel_pop3_folder_type = CAMEL_INVALID_TYPE;
-
+
if (!camel_pop3_folder_type) {
camel_pop3_folder_type = camel_type_register (CAMEL_FOLDER_TYPE, "CamelPop3Folder",
sizeof (CamelPop3Folder),
@@ -104,7 +108,7 @@ camel_pop3_folder_get_type (void)
(CamelObjectInitFunc) camel_pop3_folder_init,
(CamelObjectFinalizeFunc) pop3_finalize);
}
-
+
return camel_pop3_folder_type;
}
@@ -112,7 +116,7 @@ void
pop3_finalize (CamelObject *object)
{
CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (object);
-
+
if (pop3_folder->uids)
camel_folder_free_deep (NULL, pop3_folder->uids);
if (pop3_folder->flags)
@@ -123,31 +127,71 @@ CamelFolder *
camel_pop3_folder_new (CamelStore *parent, CamelException *ex)
{
CamelFolder *folder;
-
+
folder = CAMEL_FOLDER (camel_object_new (CAMEL_POP3_FOLDER_TYPE));
camel_folder_construct (folder, parent, "inbox", "inbox");
-
+
/* mt-ok, since we dont have the folder-lock for new() */
camel_folder_refresh_info (folder, ex);/* mt-ok */
if (camel_exception_is_set (ex)) {
camel_object_unref (CAMEL_OBJECT (folder));
folder = NULL;
}
-
+
return folder;
}
+static GPtrArray *
+pop3_generate_uids (CamelFolder *folder, int count, CamelException *ex)
+{
+ /* FIXME: This is extremely inefficient but there's no way
+ around it. Because of that, perhaps we should have some way
+ of caching these messages so we don't have to download them
+ a second time for this session? */
+ GPtrArray *uids;
+ int i;
+
+ uids = g_ptr_array_new ();
+ g_ptr_array_set_size (uids, count);
+
+ for (i = 0; i < count; i++) {
+ CamelStreamMem *stream;
+ guchar digest[16];
+ char *uid;
+
+ stream = pop3_get_message_stream (folder, i, ex);
+ if (stream == NULL)
+ goto exception;
+
+ md5_get_digest (stream->buffer->data, stream->buffer->len, digest);
+ camel_object_unref (CAMEL_OBJECT (stream));
+
+ uid = base64_encode_simple (digest, 16);
+ g_ptr_array_add (uids, uid);
+ }
+
+ return uids;
+
+ exception:
+
+ for (i = 0; i < count; i++)
+ g_free (uids->pdata[i]);
+ g_ptr_array_free (uids, TRUE);
+
+ return NULL;
+}
+
static void
pop3_refresh_info (CamelFolder *folder, CamelException *ex)
{
+ CamelPop3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store);
+ CamelPop3Folder *pop3_folder = (CamelPop3Folder *) folder;
GPtrArray *uids;
int status, count;
char *data;
- CamelPop3Folder *pop3_folder = (CamelPop3Folder *) folder;
- CamelPop3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store);
-
- camel_operation_start(NULL, _("Retrieving POP summary"));
-
+
+ camel_operation_start (NULL, _("Retrieving POP summary"));
+
status = camel_pop3_command (pop3_store, &data, ex, "STAT");
switch (status) {
case CAMEL_POP3_ERR:
@@ -157,13 +201,13 @@ pop3_refresh_info (CamelFolder *folder, CamelException *ex)
g_free (data);
/* fall through */
case CAMEL_POP3_FAIL:
- camel_operation_end(NULL);
+ camel_operation_end (NULL);
return;
}
-
+
count = atoi (data);
g_free (data);
-
+
if (pop3_store->supports_uidl != FALSE) {
status = camel_pop3_command (pop3_store, NULL, ex, "UIDL");
switch (status) {
@@ -171,29 +215,24 @@ pop3_refresh_info (CamelFolder *folder, CamelException *ex)
pop3_store->supports_uidl = FALSE;
break;
case CAMEL_POP3_FAIL:
- camel_operation_end(NULL);
+ camel_operation_end (NULL);
return;
}
}
-
+
if (pop3_store->supports_uidl == FALSE) {
- int i;
-
- uids = g_ptr_array_new ();
- g_ptr_array_set_size (uids, count);
-
- for (i = 0; i < count; i++)
- uids->pdata[i] = g_strdup_printf ("%d", i + 1);
- camel_operation_end(NULL);
+ uids = pop3_generate_uids (folder, count, ex);
+
+ camel_operation_end (NULL);
} else {
data = camel_pop3_command_get_additional_data (pop3_store, 0, ex);
camel_operation_end(NULL);
if (camel_exception_is_set (ex))
return;
-
+
uids = parse_listing (count, data);
g_free (data);
-
+
if (!uids) {
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
_("Could not open folder: "
@@ -202,7 +241,7 @@ pop3_refresh_info (CamelFolder *folder, CamelException *ex)
return;
}
}
-
+
pop3_folder->uids = uids;
pop3_folder->flags = g_new0 (guint32, uids->len);
}
@@ -216,10 +255,10 @@ pop3_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
if (!expunge)
return;
-
+
pop3_folder = CAMEL_POP3_FOLDER (folder);
pop3_store = CAMEL_POP3_STORE (folder->parent_store);
-
+
for (i = 0; i < pop3_folder->uids->len; i++) {
if (pop3_folder->flags[i] & CAMEL_MESSAGE_DELETED) {
status = camel_pop3_command (pop3_store, NULL, ex,
@@ -228,7 +267,7 @@ pop3_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
return;
}
}
-
+
camel_pop3_store_expunge (pop3_store, ex);
}
@@ -239,10 +278,10 @@ parse_listing (int count, char *data)
GPtrArray *ans;
char *p;
int index, len;
-
+
ans = g_ptr_array_new ();
g_ptr_array_set_size (ans, count);
-
+
p = data;
while (*p) {
index = strtoul (p, &p, 10);
@@ -253,14 +292,14 @@ parse_listing (int count, char *data)
if (*p == '\n')
p++;
}
-
+
for (index = 0; index < count; index++) {
if (ans->pdata[index] == NULL) {
g_ptr_array_free (ans, TRUE);
return NULL;
}
}
-
+
return ans;
}
@@ -268,35 +307,26 @@ static int
uid_to_number (CamelPop3Folder *pop3_folder, const char *uid)
{
int i;
-
+
for (i = 0; i < pop3_folder->uids->len; i++) {
if (!strcmp (uid, pop3_folder->uids->pdata[i]))
return i + 1;
}
-
+
return -1;
}
-
-static CamelMimeMessage *
-pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
+static CamelStreamMem *
+pop3_get_message_stream (CamelFolder *folder, int id, CamelException *ex)
{
- int status, num, total;
+ CamelStream *stream;
char *result, *body;
- CamelStream *msgstream;
- CamelMimeMessage *msg;
+ int status, total;
- num = uid_to_number (CAMEL_POP3_FOLDER (folder), uid);
- if (num == -1) {
- camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
- _("No message with uid %s"), uid);
- return NULL;
- }
-
- camel_operation_start_transient (NULL, _("Retrieving POP message %d"), num);
+ camel_operation_start_transient (NULL, _("Retrieving POP message %d"), id);
status = camel_pop3_command (CAMEL_POP3_STORE (folder->parent_store),
- &result, ex, "RETR %d", num);
+ &result, ex, "RETR %d", id);
switch (status) {
case CAMEL_POP3_ERR:
camel_exception_setv (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
@@ -323,18 +353,39 @@ pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
return NULL;
}
- msgstream = camel_stream_mem_new_with_buffer (body, strlen (body));
+ stream = camel_stream_mem_new_with_buffer (body, strlen (body));
g_free (body);
- msg = camel_mime_message_new ();
- camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (msg),
- CAMEL_STREAM (msgstream));
+ camel_operation_end (NULL);
- camel_object_unref (CAMEL_OBJECT (msgstream));
+ return CAMEL_STREAM_MEM (stream);
+}
+
+static CamelMimeMessage *
+pop3_get_message (CamelFolder *folder, const char *uid, CamelException *ex)
+{
+ CamelMimeMessage *message;
+ CamelStreamMem *stream;
+ int id;
- camel_operation_end (NULL);
+ id = uid_to_number (CAMEL_POP3_FOLDER (folder), uid);
+ if (id == -1) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID,
+ _("No message with uid %s"), uid);
+ return NULL;
+ }
+
+ stream = pop3_get_message_stream (folder, id, ex);
+ if (stream == NULL)
+ return NULL;
+
+ message = camel_mime_message_new ();
+ camel_data_wrapper_construct_from_stream (CAMEL_DATA_WRAPPER (message),
+ CAMEL_STREAM (stream));
- return msg;
+ camel_object_unref (CAMEL_OBJECT (stream));
+
+ return message;
}
static void
@@ -343,11 +394,11 @@ pop3_set_message_flags (CamelFolder *folder, const char *uid,
{
CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
int num;
-
+
num = uid_to_number (pop3_folder, uid);
if (num == -1)
return;
-
+
pop3_folder->flags[num - 1] =
(pop3_folder->flags[num] & ~flags) | (set & flags);
}
@@ -356,7 +407,7 @@ static gint
pop3_get_message_count (CamelFolder *folder)
{
CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
-
+
return pop3_folder->uids->len;
}
@@ -364,6 +415,6 @@ static GPtrArray *
pop3_get_uids (CamelFolder *folder)
{
CamelPop3Folder *pop3_folder = CAMEL_POP3_FOLDER (folder);
-
+
return pop3_folder->uids;
}