aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2004-03-31 07:39:51 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2004-03-31 07:39:51 +0800
commitbcb74f26bfdef06ef9904c797fc5f6e32c1a1e35 (patch)
treead6ad025b0956c2cf8304ba5604fb3eee5bedcd5
parent3c310a60ee2720d520f1da2a7a911ad4f8c0d2d2 (diff)
downloadgsoc2013-evolution-bcb74f26bfdef06ef9904c797fc5f6e32c1a1e35.tar.gz
gsoc2013-evolution-bcb74f26bfdef06ef9904c797fc5f6e32c1a1e35.tar.zst
gsoc2013-evolution-bcb74f26bfdef06ef9904c797fc5f6e32c1a1e35.zip
Partially implemented. (imap4_get_folder): Implemented.
2004-03-30 Jeffrey Stedfast <fejj@ximian.com> * providers/imap4/camel-imap4-store.c (imap4_get_folder_info): Partially implemented. (imap4_get_folder): Implemented. svn path=/trunk/; revision=25254
-rw-r--r--camel/ChangeLog7
-rw-r--r--camel/providers/imap4/camel-imap4-engine.c4
-rw-r--r--camel/providers/imap4/camel-imap4-store.c313
3 files changed, 305 insertions, 19 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 6882c8d58a..ce8cbdbc63 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,5 +1,11 @@
2004-03-30 Jeffrey Stedfast <fejj@ximian.com>
+ * providers/imap4/camel-imap4-store.c (imap4_get_folder_info):
+ Partially implemented.
+ (imap4_get_folder): Implemented.
+
+2004-03-30 Jeffrey Stedfast <fejj@ximian.com>
+
* camel-mime-utils.c (header_decode_param): Use
header_decode_text() rather than rfc2047_decode_word() to decode
the brokenly rfc2047 encoded param value string in case it is
@@ -30,6 +36,7 @@
* camel-debug.c (camel_debug_start, camel_debug_end): some helpers
to wrap debug output for atomicicity.
+>>>>>>> 1.2077
2004-03-29 Jeffrey Stedfast <fejj@ximian.com>
* providers/imap4/camel-imap4-folder.c (camel_imap4_folder_new):
diff --git a/camel/providers/imap4/camel-imap4-engine.c b/camel/providers/imap4/camel-imap4-engine.c
index 5e3d93ddaf..75831fa0b3 100644
--- a/camel/providers/imap4/camel-imap4-engine.c
+++ b/camel/providers/imap4/camel-imap4-engine.c
@@ -310,6 +310,10 @@ camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex)
if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
camel_exception_xfer (ex, &ic->ex);
camel_imap4_command_unref (ic);
+
+ if (array != NULL)
+ g_ptr_array_free (array, TRUE);
+
return -1;
}
diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c
index ffc8c91408..3dd1120f5d 100644
--- a/camel/providers/imap4/camel-imap4-store.c
+++ b/camel/providers/imap4/camel-imap4-store.c
@@ -39,6 +39,7 @@
#include "camel-imap4-folder.h"
#include "camel-imap4-stream.h"
#include "camel-imap4-command.h"
+#include "camel-imap4-utils.h"
static void camel_imap4_store_class_init (CamelIMAP4StoreClass *klass);
@@ -59,7 +60,6 @@ static CamelFolder *imap4_get_folder (CamelStore *store, const char *folder_name
static CamelFolderInfo *imap4_create_folder (CamelStore *store, const char *parent_name, const char *folder_name, CamelException *ex);
static void imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException *ex);
static void imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_name, CamelException *ex);
-static void imap4_sync (CamelStore *store, gboolean expunge, CamelException *ex);
static CamelFolderInfo *imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex);
static void imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
static void imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelException *ex);
@@ -130,7 +130,6 @@ camel_imap4_store_class_init (CamelIMAP4StoreClass *klass)
store_class->create_folder = imap4_create_folder;
store_class->delete_folder = imap4_delete_folder;
store_class->rename_folder = imap4_rename_folder;
- store_class->sync = imap4_sync;
store_class->get_folder_info = imap4_get_folder_info;
store_class->subscribe_folder = imap4_subscribe_folder;
store_class->unsubscribe_folder = imap4_unsubscribe_folder;
@@ -585,32 +584,172 @@ imap4_query_auth_types (CamelService *service, CamelException *ex)
}
+static char
+imap4_get_path_delim (CamelIMAP4Engine *engine, const char *full_name)
+{
+ /* FIXME: move this to utils so imap4-folder.c can share */
+ CamelIMAP4Namespace *namespace;
+ const char *slash;
+ size_t len;
+ char *top;
+
+ if ((slash = strchr (full_name, '/')))
+ len = (slash - full_name);
+ else
+ len = strlen (full_name);
+
+ top = g_alloca (len + 1);
+ memcpy (top, full_name, len);
+ top[len] = '\0';
+
+ if (!g_ascii_strcasecmp (top, "INBOX"))
+ top = "INBOX";
+
+ retry:
+ namespace = engine->namespaces.personal;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ namespace = engine->namespaces.other;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ namespace = engine->namespaces.shared;
+ while (namespace != NULL) {
+ if (!strcmp (namespace->path, top))
+ return namespace->sep;
+ namespace = namespace->next;
+ }
+
+ if (top[0] != '\0') {
+ /* look for a default namespace? */
+ top[0] = '\0';
+ goto retry;
+ }
+
+ return '/';
+}
+
static char *
-imap4_folder_utf7_name (CamelStore *store, const char *folder_name)
+imap4_folder_utf7_name (CamelStore *store, const char *folder_name, char wildcard)
{
char *real_name, *p;
+ char sep;
+ int len;
+
+ sep = imap4_get_path_delim (((CamelIMAP4Store *) store)->engine, folder_name);
- if (store->dir_sep != '/') {
+ if (sep != '/') {
p = real_name = g_alloca (strlen (folder_name) + 1);
strcpy (real_name, folder_name);
while (*p != '\0') {
if (*p == '/')
- *p = store->dir_sep;
+ *p = sep;
p++;
}
folder_name = real_name;
}
- return camel_utf8_utf7 (folder_name);
+ if (*folder_name)
+ real_name = camel_utf8_utf7 (folder_name);
+ else
+ real_name = g_strdup ("");
+
+ if (wildcard) {
+ len = strlen (real_name);
+ real_name = g_realloc (real_name, len + 3);
+
+ if (len > 0)
+ real_name[len++] = sep;
+
+ real_name[len++] = wildcard;
+ real_name[len] = '\0';
+ }
+
+ return real_name;
}
static CamelFolder *
imap4_get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex)
{
- /* FIXME: implement me */
+ CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
+ camel_imap4_list_t *list;
+ CamelIMAP4Command *ic;
+ CamelFolderInfo *fi;
+ GPtrArray *array;
+ char *utf7_name;
+ int create;
+ int id, i;
+
+ /* make sure the folder exists - try LISTing it? */
+ utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
+ ic = camel_imap4_engine_queue (engine, NULL, "LIST "" %S\r\n", utf7_name);
+ camel_imap4_command_register_untagged (ic, "LIST", camel_imap4_untagged_list);
+ ic->user_data = array = g_ptr_array_new ();
+ g_free (utf7_name);
+
+ while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
+ ;
- return NULL;
+ if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
+ camel_exception_xfer (ex, &ic->ex);
+ camel_imap4_command_unref (ic);
+ g_ptr_array_free (array, TRUE);
+ return NULL;
+ }
+
+ create = array->len == 0;
+
+ for (i = 0; i < array->len; i++) {
+ list = array->pdata[i];
+ g_free (list->name);
+ g_free (list);
+ }
+
+ g_ptr_array_free (array, TRUE);
+
+ if (ic->result != CAMEL_IMAP4_RESULT_OK) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Cannot get folder `%s' on IMAP server %s: Unknown"),
+ folder_name, ((CamelService *) store)->url->host);
+ camel_imap4_command_unref (ic);
+ return NULL;
+ }
+
+ camel_imap4_command_unref (ic);
+
+ if (create) {
+ const char *basename;
+ char *parent;
+ int len;
+
+ if (!(flags & CAMEL_STORE_FOLDER_CREATE))
+ return NULL;
+
+ if (!(basename = strrchr (folder_name, '/')))
+ basename = folder_name;
+ else
+ basename++;
+
+ len = basename > folder_name ? (basename - folder_name) - 1 : 0;
+ parent = g_alloca (len + 1);
+ memcpy (parent, folder_name, len);
+ parent[len] = '\0';
+
+ if (!(fi = imap4_create_folder (store, parent, basename, ex)))
+ return NULL;
+
+ camel_store_free_folder_info (store, fi);
+ }
+
+ return camel_imap4_folder_new (store, folder_name, ex);
}
static CamelFolderInfo *
@@ -645,9 +784,7 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
else
name = g_strdup (folder_name);
- utf7_name = imap4_folder_utf7_name (store, name);
- g_free (name);
-
+ utf7_name = imap4_folder_utf7_name (store, name, '\0');
ic = camel_imap4_engine_queue (engine, NULL, "CREATE %S\r\n", utf7_name);
g_free (utf7_name);
@@ -657,23 +794,31 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
camel_exception_xfer (ex, &ic->ex);
camel_imap4_command_unref (ic);
+ g_free (name);
return NULL;
}
switch (ic->result) {
case CAMEL_IMAP4_RESULT_OK:
- /* FIXME: allocate fi */
+ if (!(fi = imap4_get_folder_info (store, name, CAMEL_STORE_FOLDER_INFO_FAST, ex))) {
+ camel_imap4_command_unref (ic);
+ g_free (name);
+
+ return NULL;
+ }
+
+ camel_object_trigger_event (store, "folder_created", fi);
break;
case CAMEL_IMAP4_RESULT_NO:
/* FIXME: would be good to save the NO reason into the err message */
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
_("Cannot create folder `%s': Invalid mailbox name"),
- folder_name);
+ name);
break;
case CAMEL_IMAP4_RESULT_BAD:
camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
_("Cannot create folder `%s': Bad command"),
- folder_name);
+ name);
break;
default:
g_assert_not_reached ();
@@ -681,6 +826,8 @@ imap4_create_folder (CamelStore *store, const char *parent_name, const char *fol
camel_imap4_command_unref (ic);
+ g_free (name);
+
return fi;
}
@@ -700,7 +847,7 @@ imap4_delete_folder (CamelStore *store, const char *folder_name, CamelException
return;
}
- utf7_name = imap4_folder_utf7_name (store, folder_name);
+ utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
ic = camel_imap4_engine_queue (engine, NULL, "DELETE %S\r\n", utf7_name);
g_free (utf7_name);
@@ -742,16 +889,144 @@ imap4_rename_folder (CamelStore *store, const char *old_name, const char *new_na
}
+static int
+list_sort (const camel_imap4_list_t **list0, const camel_imap4_list_t **list1)
+{
+ return strcmp ((*list0)->name, (*list1)->name);
+}
+
static void
-imap4_sync (CamelStore *store, gboolean expunge, CamelException *ex)
+list_remove_duplicates (GPtrArray *array)
{
+ camel_imap4_list_t *list, *last;
+ int i;
+
+ last = array->pdata[0];
+ for (i = 1; i < array->len; i++) {
+ list = array->pdata[i];
+ if (!strcmp (list->name, last->name)) {
+ g_ptr_array_remove_index (array, i--);
+ last->flags |= list->flags;
+ g_free (list->name);
+ g_free (list);
+ }
+ }
+}
+static CamelFolderInfo *
+imap4_build_folder_info (CamelIMAP4Engine *engine, guint32 flags, GPtrArray *array, const char *top)
+{
+ camel_imap4_list_t *list;
+ CamelFolderInfo *fi;
+ char *name, *p;
+ CamelURL *url;
+ int i;
+
+ g_ptr_array_sort (array, (GCompareFunc) list_sort);
+
+ list_remove_duplicates (array);
+
+ url = camel_url_copy (engine->url);
+
+ for (i = 0; i < array->len; i++) {
+ list = array->pdata[i];
+ fi = g_malloc0 (sizeof (CamelFolderInfo));
+
+ p = name = camel_utf7_utf8 (list->name);
+ while (*p != '\0') {
+ if (*p == list->delim)
+ *p = '/';
+ p++;
+ }
+
+ camel_url_set_fragment (url, name);
+
+ fi->full_name = name;
+ p = strrchr (name, '/');
+ fi->name = g_strdup (p ? p + 1: name);
+ fi->path = g_strdup_printf ("/%s", name);
+ fi->uri = camel_url_to_string (url, 0);
+ fi->flags = list->flags;
+
+ /* FIXME: use STATUS to get these values if requested */
+ fi->unread = -1;
+ fi->total = -1;
+
+ g_free (list->name);
+ g_free (list);
+
+ array->pdata[i] = fi;
+ }
+
+ /* FIXME: build the fi tree */
+ fi = array->pdata[0];
+
+ camel_url_free (url);
+
+ g_ptr_array_free (array, TRUE);
+
+ return fi;
}
static CamelFolderInfo *
imap4_get_folder_info (CamelStore *store, const char *top, guint32 flags, CamelException *ex)
{
- return NULL;
+ CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine;
+ camel_imap4_list_t *list;
+ CamelIMAP4Command *ic;
+ GPtrArray *array;
+ const char *cmd;
+ char *pattern;
+ int id, i;
+
+ if (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED)
+ cmd = "LSUB";
+ else
+ cmd = "LIST";
+
+ if (top == NULL)
+ top = "";
+
+ pattern = imap4_folder_utf7_name (store, top, (flags & CAMEL_STORE_FOLDER_INFO_RECURSIVE) ? '*' : '%');
+ ic = camel_imap4_engine_queue (engine, NULL, "%s "" %S\r\n", cmd, pattern);
+ camel_imap4_command_register_untagged (ic, cmd, camel_imap4_untagged_list);
+ ic->user_data = array = g_ptr_array_new ();
+
+ while ((id = camel_imap4_engine_iterate (engine)) < ic->id && id != -1)
+ ;
+
+ if (id == -1 || ic->status != CAMEL_IMAP4_COMMAND_COMPLETE) {
+ camel_exception_xfer (ex, &ic->ex);
+ camel_imap4_command_unref (ic);
+ g_ptr_array_free (array, TRUE);
+ g_free (pattern);
+ return NULL;
+ }
+
+ if (ic->result != CAMEL_IMAP4_RESULT_OK) {
+ camel_imap4_command_unref (ic);
+
+ camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM,
+ _("Cannot get %s information for pattern `%s' on IMAP server %s: %s"),
+ cmd, pattern, engine->url->host, ic->result == CAMEL_IMAP4_RESULT_BAD ?
+ _("Bad command") : _("Unknown"));
+
+ for (i = 0; i < array->len; i++) {
+ list = array->pdata[i];
+ g_free (list->name);
+ g_free (list);
+ }
+
+ g_ptr_array_free (array, TRUE);
+
+ g_free (pattern);
+
+ return NULL;
+ }
+
+ g_free (pattern);
+
+ return imap4_build_folder_info (engine, flags, array, top);
}
static void
@@ -762,7 +1037,7 @@ imap4_subscribe_folder (CamelStore *store, const char *folder_name, CamelExcepti
char *utf7_name;
int id;
- utf7_name = imap4_folder_utf7_name (store, folder_name);
+ utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
ic = camel_imap4_engine_queue (engine, NULL, "SUBSCRIBE %S\r\n", utf7_name);
g_free (utf7_name);
@@ -807,7 +1082,7 @@ imap4_unsubscribe_folder (CamelStore *store, const char *folder_name, CamelExcep
char *utf7_name;
int id;
- utf7_name = imap4_folder_utf7_name (store, folder_name);
+ utf7_name = imap4_folder_utf7_name (store, folder_name, '\0');
ic = camel_imap4_engine_queue (engine, NULL, "UNSUBSCRIBE %S\r\n", utf7_name);
g_free (utf7_name);