aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers/imap
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2000-10-03 03:08:20 +0800
committerDan Winship <danw@src.gnome.org>2000-10-03 03:08:20 +0800
commite9dc30dbf0c018bbc845f253bfe0b26baddbeaf2 (patch)
treee70ca64851c0167f959a9e6c0c38179cd0de102b /camel/providers/imap
parent46d07e9e465e336a5c39d8c27c846cb380fbc6fb (diff)
downloadgsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar
gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.gz
gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.bz2
gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.lz
gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.xz
gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.tar.zst
gsoc2013-evolution-e9dc30dbf0c018bbc845f253bfe0b26baddbeaf2.zip
Remove camel_folder_{get,free}_subfolder_info, as we want to be able to
* camel-folder.[ch]: Remove camel_folder_{get,free}_subfolder_info, as we want to be able to scan the whole subfolder tree without having to open any folders, so this needs to be in CamelStore. Remove can_hold_folders and can_hold_messages flags; things that don't hold messages are no longer considered CamelFolders. * camel-folder-summary.[ch]: Remove CamelFolderInfo stuff. * camel-store.[ch]: Add camel_store_{get,free}_folder_info, as well as camel_store_free_folder_info_full and ..._nop for default implementations, and camel_folder_info_free and camel_folder_info_build as convenience functions. Turn CamelFolderInfo into a tree structure and also add an "url" member. * providers/*/camel-*-folder.c: Remove subfolder_info and can_hold stuff. * providers/*/camel-*-store.c: Add folder_info stuff. * providers/imap/camel-imap-folder.c (imap_summary_free): Free the summary elements with camel_message_info_free, not camel_folder_info_free. Oops. * providers/imap/camel-imap-utils.c: const poison svn path=/trunk/; revision=5663
Diffstat (limited to 'camel/providers/imap')
-rw-r--r--camel/providers/imap/camel-imap-folder.c117
-rw-r--r--camel/providers/imap/camel-imap-folder.h2
-rw-r--r--camel/providers/imap/camel-imap-store.c194
-rw-r--r--camel/providers/imap/camel-imap-utils.c10
-rw-r--r--camel/providers/imap/camel-imap-utils.h4
5 files changed, 168 insertions, 159 deletions
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index 63ef5b31d1..ab2d7f88b9 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -79,10 +79,6 @@ static void imap_copy_message_to (CamelFolder *source, const char *uid,
static void imap_move_message_to (CamelFolder *source, const char *uid,
CamelFolder *destination, CamelException *ex);
-/* subfolder listing */
-static GPtrArray *imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex);
-static GPtrArray *imap_get_subfolder_info (CamelFolder *folder);
-
/* summary info */
static GPtrArray *imap_get_uids (CamelFolder *folder);
static GPtrArray *imap_get_summary_internal (CamelFolder *folder, CamelException *ex);
@@ -116,8 +112,6 @@ camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class)
camel_folder_class->get_uids = imap_get_uids;
camel_folder_class->free_uids = camel_folder_free_nop;
- camel_folder_class->get_subfolder_info = imap_get_subfolder_info;
- camel_folder_class->free_subfolder_info = camel_folder_free_nop;
camel_folder_class->get_message_count = imap_get_message_count;
camel_folder_class->get_unread_message_count = imap_get_unread_message_count;
@@ -144,14 +138,11 @@ camel_imap_folder_init (gpointer object, gpointer klass)
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
CamelFolder *folder = CAMEL_FOLDER (object);
- folder->can_hold_messages = TRUE;
- folder->can_hold_folders = TRUE;
folder->has_summary_capability = TRUE;
folder->has_search_capability = TRUE;
imap_folder->summary = NULL;
imap_folder->summary_hash = NULL;
- imap_folder->lsub = NULL;
/* some IMAP daemons support user-flags *
* I would not, however, rely on this feature as *
@@ -197,9 +188,6 @@ camel_imap_folder_new (CamelStore *parent, const char *folder_name)
short_name = folder_name;
camel_folder_construct (folder, parent, folder_name, short_name);
- if (!*folder_name)
- folder->can_hold_messages = FALSE;
-
return folder;
}
@@ -211,7 +199,7 @@ imap_summary_free (GPtrArray **summary)
if (array) {
for (i = 0; i < array->len; i++)
- camel_folder_info_free (array->pdata[i]);
+ camel_message_info_free (array->pdata[i]);
g_ptr_array_free (array, TRUE);
*summary = NULL;
@@ -233,25 +221,14 @@ static void
imap_finalize (CamelObject *object)
{
CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (object);
- gint i;
-
+
imap_folder_summary_free (imap_folder);
-
- if (imap_folder->lsub) {
- for (i = 0; i < imap_folder->lsub->len; i++)
- camel_folder_info_free (imap_folder->lsub->pdata[i]);
-
- g_ptr_array_free (imap_folder->lsub, TRUE);
- }
}
static void
imap_refresh_info (CamelFolder *folder, CamelException *ex)
{
- imap_get_subfolder_info_internal (folder, ex);
-
- if (folder->can_hold_messages)
- imap_get_summary_internal (folder, ex);
+ imap_get_summary_internal (folder, ex);
}
static void
@@ -308,8 +285,6 @@ imap_get_message_count_internal (CamelFolder *folder, CamelException *ex)
GPtrArray *response;
gint status, count = 0;
- g_return_val_if_fail (folder->can_hold_messages, 0);
-
folder_path = camel_imap_store_folder_path (store, folder->full_name);
if (store->has_status_capability)
@@ -501,92 +476,6 @@ imap_get_uids (CamelFolder *folder)
return array;
}
-static GPtrArray *
-imap_get_subfolder_info_internal (CamelFolder *folder, CamelException *ex)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
- CamelImapStore *store = CAMEL_IMAP_STORE (folder->parent_store);
- GPtrArray *response, *listing;
- gboolean found_inbox = FALSE;
- gint status, i;
- gchar *namespace;
- CamelFolderInfo *fi;
-
- g_return_val_if_fail (folder != NULL, g_ptr_array_new ());
-
- namespace = camel_imap_store_folder_path (store, folder->full_name);
- status = camel_imap_command_extended (store, NULL, &response, ex,
- "LIST \"\" \"%s%s*\"", namespace,
- *namespace ? store->dir_sep : "");
-
- if (status != CAMEL_IMAP_OK) {
- g_free (namespace);
-
- imap_folder->lsub = g_ptr_array_new ();
- return imap_folder->lsub;
- }
-
- /* parse out the subfolders */
- listing = g_ptr_array_new ();
- if (response) {
- for (i = 0; i < response->len; i++) {
- gchar *resp, *flags, *sep, *dir;
-
- resp = response->pdata[i];
- if (!imap_parse_list_response (resp, namespace, &flags, &sep, &dir)) {
- g_free (flags);
- g_free (sep);
- g_free (dir);
- continue;
- }
-
- g_free (flags);
-
- if (*dir) {
- d(fprintf (stderr, "adding folder: %s\n", dir));
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = dir;
- fi->name = strrchr (dir, *sep);
- if (fi->name)
- fi->name = g_strdup (fi->name + 1);
- else
- fi->name = g_strdup (dir);
- /* FIXME: read/unread msg count */
-
- if (!g_strcasecmp (dir, "INBOX"))
- found_inbox = TRUE;
- g_ptr_array_add (listing, fi);
- }
-
- g_free (sep);
- }
- camel_imap_response_free (response);
- }
-
- if (!*folder->name && !found_inbox) {
- fi = g_new0 (CamelFolderInfo, 1);
- fi->full_name = g_strdup ("INBOX");
- fi->name = g_strdup ("INBOX");
- /* FIXME: read/unread msg count */
-
- g_ptr_array_add (listing, fi);
- }
-
- g_free (namespace);
-
- imap_folder->lsub = listing;
-
- return listing;
-}
-
-static GPtrArray *
-imap_get_subfolder_info (CamelFolder *folder)
-{
- CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
-
- return imap_folder->lsub;
-}
-
static CamelMimeMessage *
imap_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex)
{
diff --git a/camel/providers/imap/camel-imap-folder.h b/camel/providers/imap/camel-imap-folder.h
index d4d960b2a8..41170ce698 100644
--- a/camel/providers/imap/camel-imap-folder.h
+++ b/camel/providers/imap/camel-imap-folder.h
@@ -48,8 +48,6 @@ typedef struct {
GPtrArray *summary;
GHashTable *summary_hash;
-
- GPtrArray *lsub;
} CamelImapFolder;
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index d5fc59b33e..eab33b308f 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -60,6 +60,9 @@ static CamelFolder *get_folder (CamelStore *store, const char *folder_name, gboo
static char *get_folder_name (CamelStore *store, const char *folder_name,
CamelException *ex);
static char *get_root_folder_name (CamelStore *store, CamelException *ex);
+static CamelFolderInfo *get_folder_info (CamelStore *store, const char *top,
+ gboolean fast, gboolean recursive,
+ CamelException *ex);
static void imap_keepalive (CamelRemoteStore *store);
/*static gboolean stream_is_alive (CamelStream *istream);*/
static int camel_imap_status (char *cmdid, char *respbuf);
@@ -87,6 +90,8 @@ camel_imap_store_class_init (CamelImapStoreClass *camel_imap_store_class)
camel_store_class->get_folder = get_folder;
camel_store_class->get_folder_name = get_folder_name;
camel_store_class->get_root_folder_name = get_root_folder_name;
+ camel_store_class->get_folder_info = get_folder_info;
+ camel_store_class->free_folder_info = camel_store_free_folder_info_full;
camel_remote_store_class->keepalive = imap_keepalive;
}
@@ -393,33 +398,35 @@ get_folder (CamelStore *store, const char *folder_name, gboolean create, CamelEx
CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
CamelFolder *new_folder;
char *folder_path;
- gboolean exists = FALSE;
gboolean selectable;
- new_folder = camel_imap_folder_new (store, folder_name);
-
- /* this is the top-level dir, we already know it exists - it has to! */
- if (!*folder_name) {
- camel_folder_refresh_info (new_folder, ex);
- return new_folder;
- }
-
folder_path = camel_imap_store_folder_path (imap_store, folder_name);
- if (imap_folder_exists (imap_store, folder_path, &selectable, ex)) {
- exists = TRUE;
- if (!selectable)
- new_folder->can_hold_messages = FALSE;
- }
+ if (!imap_folder_exists (imap_store, folder_path, &selectable, ex)) {
+ if (!create) {
+ g_free (folder_path);
+ return NULL;
+ }
- if (!exists && create && !imap_create (imap_store, folder_path, ex)) {
+ if (!imap_create (imap_store, folder_path, ex)) {
+ g_free (folder_path);
+ return NULL;
+ }
+ } else if (!selectable) {
+ camel_exception_setv (ex, CAMEL_EXCEPTION_STORE_NO_FOLDER,
+ "%s is not a selectable folder",
+ folder_name);
g_free (folder_path);
- camel_object_unref (CAMEL_OBJECT (new_folder));
return NULL;
}
+ g_free (folder_path);
- /* this is where we *should refresh_info, not in imap_folder_new() */
+ new_folder = camel_imap_folder_new (store, folder_name);
camel_folder_refresh_info (new_folder, ex);
-
+ if (camel_exception_is_set (ex)) {
+ camel_object_unref (CAMEL_OBJECT (new_folder));
+ return NULL;
+ }
+
return new_folder;
}
@@ -440,32 +447,145 @@ get_root_folder_name (CamelStore *store, CamelException *ex)
return g_strdup ("");
}
-static void
-imap_keepalive (CamelRemoteStore *store)
+static CamelFolderInfo *
+parse_list_response_as_folder_info (const char *response,
+ const char *namespace,
+ const char *base_url)
+{
+ CamelFolderInfo *fi;
+ char *flags, *sep, *dir;
+
+ if (!imap_parse_list_response (response, namespace,
+ &flags, &sep, &dir))
+ return NULL;
+
+ fi = g_new0 (CamelFolderInfo, 1);
+ fi->full_name = dir;
+ fi->name = strrchr (dir, *sep);
+ if (fi->name)
+ fi->name = g_strdup (fi->name + 1);
+ else
+ fi->name = g_strdup (dir);
+ g_free (sep);
+ if (!e_strstrcase (flags, "\\NoSelect"))
+ fi->url = g_strdup_printf ("%s%s", base_url, dir);
+ g_free (flags);
+ /* FIXME: read/unread msg count */
+
+ return fi;
+}
+
+static CamelFolderInfo *
+get_folder_info (CamelStore *store, const char *top, gboolean fast,
+ gboolean recursive, CamelException *ex)
{
CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
-
- camel_imap_command_extended (imap_store, NULL, NULL, NULL, "NOOP");
+ CamelURL *url = CAMEL_SERVICE (store)->url;
+ gboolean found_inbox = FALSE;
+ int status, len, i;
+ GPtrArray *response;
+ char *dir_sep, *namespace, *base_url, *list;
+ CamelFolderInfo *topfi, *fi;
+
+ if (!top)
+ top = "";
+ dir_sep = imap_store->dir_sep;
+ namespace = camel_imap_store_folder_path (imap_store, top);
+
+ /* Yah! I am complicated! */
+ base_url = camel_url_to_string (url, FALSE);
+ len = strlen (base_url);
+ if (url->path && base_url[len - 1] != *dir_sep) {
+ base_url = g_realloc (base_url, len + 2);
+ base_url[len] = *dir_sep;
+ base_url[len + 1] = '\0';
+ } else if (!url->path) {
+ base_url = g_realloc (base_url, len + 2);
+ base_url[len] = '/';
+ base_url[len + 1] = '\0';
+ }
+
+ status = camel_imap_command_extended (imap_store, NULL, &response, ex,
+ "LIST \"\" \"%s\"", namespace);
+ if (status != CAMEL_IMAP_OK) {
+ g_free (namespace);
+ g_free (base_url);
+ return NULL;
+ }
+ list = camel_imap_response_extract (response, "LIST", ex);
+ if (!list) {
+ g_free (namespace);
+ g_free (base_url);
+ return NULL;
+ }
+ topfi = parse_list_response_as_folder_info (list, namespace, base_url);
+ g_free (list);
+
+ status = camel_imap_command_extended (imap_store, NULL, &response, ex,
+ "LIST \"\" \"%s%s%c\"",
+ namespace,
+ *namespace ? dir_sep : "",
+ recursive ? '*' : '%');
+ if (status != CAMEL_IMAP_OK) {
+ g_free (namespace);
+ g_free (base_url);
+ return NULL;
+ }
+
+ /* Turn responses into CamelFolderInfo and remove any
+ * extraneous responses.
+ */
+ for (i = 0; i < response->len; i++) {
+ list = response->pdata[i];
+ response->pdata[i] = fi =
+ parse_list_response_as_folder_info (list, namespace,
+ base_url);
+ g_free (list);
+
+ if (!response->pdata[i]) {
+ g_ptr_array_remove_index_fast (response, i--);
+ continue;
+ }
+
+ if (!g_strcasecmp (fi->full_name, "INBOX"))
+ found_inbox = TRUE;
+ }
+
+ /* Add INBOX, if necessary */
+ if (!*top && !found_inbox) {
+ fi = g_new0 (CamelFolderInfo, 1);
+ fi->full_name = g_strdup ("INBOX");
+ fi->name = g_strdup ("INBOX");
+ fi->url = g_strdup_printf ("%sINBOX", base_url);
+ /* FIXME: read/unread msg count */
+
+ g_ptr_array_add (response, fi);
+ }
+
+ /* And assemble */
+ camel_folder_info_build (response, topfi, *dir_sep, TRUE);
+ g_ptr_array_free (response, FALSE);
+
+ /* Remove the top if it's the root of the store. */
+ if (!*top && !topfi->sibling) {
+ fi = topfi;
+ topfi = topfi->child;
+ fi->child = NULL;
+ camel_folder_info_free (fi);
+ }
+
+ g_free (namespace);
+ g_free (base_url);
+ return topfi;
}
-#if 0
-static gboolean
-stream_is_alive (CamelStream *istream)
+static void
+imap_keepalive (CamelRemoteStore *store)
{
- CamelStreamFs *fs_stream;
- char buf;
-
- g_return_val_if_fail (istream != NULL, FALSE);
-
- fs_stream = CAMEL_STREAM_FS (CAMEL_STREAM_BUFFER (istream)->stream);
- g_return_val_if_fail (fs_stream->fd != -1, FALSE);
-
- if (read (fs_stream->fd, (void *) &buf, 0) == 0)
- return TRUE;
+ CamelImapStore *imap_store = CAMEL_IMAP_STORE (store);
- return FALSE;
+ camel_imap_command_extended (imap_store, NULL, NULL, NULL, "NOOP");
}
-#endif
static int
camel_imap_status (char *cmdid, char *respbuf)
diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c
index bb110f1f90..4658341e6a 100644
--- a/camel/providers/imap/camel-imap-utils.c
+++ b/camel/providers/imap/camel-imap-utils.c
@@ -33,12 +33,12 @@
#define d(x) x
char *
-imap_next_word (char *buf)
+imap_next_word (const char *buf)
{
char *word;
/* skip over current word */
- for (word = buf; *word && *word != ' '; word++);
+ for (word = (char *)buf; *word && *word != ' '; word++);
/* skip over white space */
for ( ; *word && *word == ' '; word++);
@@ -47,7 +47,7 @@ imap_next_word (char *buf)
}
gboolean
-imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, char **folder)
+imap_parse_list_response (const char *buf, const char *namespace, char **flags, char **sep, char **folder)
{
char *word, *ep, *f;
@@ -96,7 +96,9 @@ imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep,
/* chop out the folder prefix */
if (*namespace && !strncmp (*folder, namespace, strlen (namespace))) {
- f = *folder + strlen (namespace) + strlen (*sep);
+ f = *folder + strlen (namespace);
+ if (!strncmp (f, *sep, strlen (*sep)))
+ f += strlen (*sep);
memmove (*folder, f, strlen (f) + 1);
}
diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h
index 6f450fc8e8..b08c179926 100644
--- a/camel/providers/imap/camel-imap-utils.h
+++ b/camel/providers/imap/camel-imap-utils.h
@@ -30,9 +30,9 @@ extern "C" {
#include <glib.h>
-char *imap_next_word (char *buf);
+char *imap_next_word (const char *buf);
-gboolean imap_parse_list_response (char *buf, char *namespace, char **flags, char **sep, char **folder);
+gboolean imap_parse_list_response (const char *buf, const char *namespace, char **flags, char **sep, char **folder);
char *imap_translate_sexp (const char *expression);