[evolution-data-server] Fetches the folderinfo from multiple namespaces - imapx.
- From: Chenthill Palanisamy <pchen src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Fetches the folderinfo from multiple namespaces - imapx.
- Date: Tue, 24 Nov 2009 15:15:25 +0000 (UTC)
commit 02f2bbd4e6caed34f439e53ba9558c5103ea4968
Author: Chenthill Palanisamy <pchenthill novell com>
Date: Tue Nov 24 20:37:30 2009 +0530
Fetches the folderinfo from multiple namespaces - imapx.
camel/camel-msgport.h | 2 +
camel/camel-tcp-stream-ssl.c | 6 +
camel/camel-tcp-stream-ssl.h | 3 +
camel/providers/imapx/camel-imapx-server.c | 75 +++++--
camel/providers/imapx/camel-imapx-server.h | 2 +-
camel/providers/imapx/camel-imapx-store.c | 308 ++++++++++++++++++++++++----
camel/providers/imapx/camel-imapx-store.h | 5 +-
camel/providers/imapx/camel-imapx-utils.c | 14 +-
8 files changed, 348 insertions(+), 67 deletions(-)
---
diff --git a/camel/camel-msgport.h b/camel/camel-msgport.h
index da89c73..30f1891 100644
--- a/camel/camel-msgport.h
+++ b/camel/camel-msgport.h
@@ -22,6 +22,7 @@
#define CAMEL_MSGPORT_H
#include <glib.h>
+#include "camel-list-utils.h"
G_BEGIN_DECLS
@@ -29,6 +30,7 @@ typedef struct _CamelMsg CamelMsg;
typedef struct _CamelMsgPort CamelMsgPort;
struct _CamelMsg {
+ CamelDListNode ln;
CamelMsgPort *reply_port;
gint flags;
};
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index e2af703..dfe126d 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -1312,4 +1312,10 @@ stream_get_remote_address (CamelTcpStream *stream, socklen_t *len)
return sockaddr_from_praddr(&addr, len);
}
+PRFileDesc *
+camel_tcp_stream_ssl_sockfd (CamelTcpStreamSSL *stream)
+{
+ return stream->priv->sockfd;
+}
+
#endif /* HAVE_NSS */
diff --git a/camel/camel-tcp-stream-ssl.h b/camel/camel-tcp-stream-ssl.h
index d8f5861..f4060a3 100644
--- a/camel/camel-tcp-stream-ssl.h
+++ b/camel/camel-tcp-stream-ssl.h
@@ -24,6 +24,7 @@
#define CAMEL_TCP_STREAM_SSL_H
#include <camel/camel-tcp-stream.h>
+#include <prio.h>
#define CAMEL_TCP_STREAM_SSL_TYPE (camel_tcp_stream_ssl_get_type ())
#define CAMEL_TCP_STREAM_SSL(obj) (CAMEL_CHECK_CAST((obj), CAMEL_TCP_STREAM_SSL_TYPE, CamelTcpStreamSSL))
@@ -61,6 +62,8 @@ CamelStream *camel_tcp_stream_ssl_new_raw (struct _CamelSession *session, const
gint camel_tcp_stream_ssl_enable_ssl (CamelTcpStreamSSL *ssl);
+PRFileDesc * camel_tcp_stream_ssl_sockfd (CamelTcpStreamSSL *stream);
+
G_END_DECLS
#endif /* CAMEL_TCP_STREAM_SSL_H */
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index 1f29807..77ab12f 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -17,6 +17,8 @@
#include <prerr.h>
#endif
+#include <poll.h>
+
#include <camel/camel-list-utils.h>
#include <camel/camel-msgport.h>
#include <camel/camel-object.h>
@@ -870,7 +872,7 @@ imapx_find_job(CamelIMAPXServer *imap, gint type, const gchar *uid)
QUEUE_LOCK(imap);
- for (node = imap->jobs.head;node->next;node = node->next) {
+ for (node = imap->jobs.head;node->next;node = job->msg.ln.next) {
job = (CamelIMAPXJob *) node;
if (job->type != type)
continue;
@@ -942,6 +944,7 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
guint id, len;
guchar *token, *p, c;
gint tok;
+ gboolean lsub = FALSE;
struct _status_info *sinfo;
e(printf("got untagged response\n"));
@@ -1091,7 +1094,9 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
imap_free_fetch(finfo);
break;
}
- case IMAP_LIST: case IMAP_LSUB: {
+ case IMAP_LSUB:
+ lsub = TRUE;
+ case IMAP_LIST: {
struct _list_info *linfo = imap_parse_list(imap->stream, ex);
CamelIMAPXJob *job = imapx_find_job(imap, IMAPX_JOB_LIST, linfo->name);
@@ -1099,6 +1104,8 @@ imapx_untagged(CamelIMAPXServer *imap, CamelException *ex)
printf("list: '%s' (%c)\n", linfo->name, linfo->separator);
if (job && g_hash_table_lookup(job->u.list.folders, linfo->name) == NULL) {
+ if (lsub)
+ linfo->flags |= CAMEL_FOLDER_SUBSCRIBED;
g_hash_table_insert(job->u.list.folders, linfo->name, linfo);
} else {
g_warning("got list response but no current listing job happening?\n");
@@ -1613,6 +1620,21 @@ retry:
ic = camel_imapx_command_new ("NAMESPACE", NULL, "NAMESPACE");
imapx_command_run (is, ic, ex);
camel_imapx_command_free (ic);
+ } else {
+ CamelIMAPXNamespaceList *nsl = NULL;
+ CamelIMAPXStoreNamespace *ns = NULL;
+ CamelIMAPXStore *imapx_store = (CamelIMAPXStore *) is->store;
+
+ /* set a default namespace */
+ nsl = g_malloc0(sizeof(CamelIMAPXNamespaceList));
+ ns = g_new0 (CamelIMAPXStoreNamespace, 1);
+ ns->next = NULL;
+ ns->path = g_strdup ("");
+ ns->full_name = g_strdup ("");
+ /* FIXME needs to be identified from list response */
+ ns->sep = '/';
+ nsl->personal = ns;
+ imapx_store->summary->namespaces = nsl;
}
}
@@ -1628,7 +1650,7 @@ imapx_job_done(CamelIMAPXServer *is, CamelIMAPXCommand *ic)
camel_exception_clear(job->ex);
g_free(job);
} else
- camel_msgport_reply(job->msg.reply_port);
+ camel_msgport_reply((CamelMsg *) job);
}
/* ********************************************************************** */
@@ -2204,18 +2226,18 @@ imapx_server_loop(gpointer d)
break;
}
- job = (CamelIMAPXJob *)camel_msgport_try_pop (is->port);
+/* job = (CamelIMAPXJob *)camel_msgport_try_pop (is->port);
if (job) {
camel_dlist_addtail(&is->jobs, (CamelDListNode *)job);
job->start(is, job);
- }
+ } */
- if (!camel_dlist_empty(&is->active)
+/* if (!camel_dlist_empty(&is->active)
|| camel_imapx_stream_buffered(is->stream))
imapx_step(is, &ex);
else
- camel_msgport_pop (is->port);
-#if 0
+ camel_msgport_pop (is->port); */
+#if 1
/* TODO:
This poll stuff wont work - we might block
waiting for results inside loops etc.
@@ -2232,6 +2254,7 @@ imapx_server_loop(gpointer d)
/* if ssl stream ... */
#ifdef HAVE_SSL
+ if (CAMEL_IS_TCP_STREAM_SSL (is->stream->source))
{
PRPollDesc pollfds[2] = { };
gint res;
@@ -2242,6 +2265,7 @@ imapx_server_loop(gpointer d)
pollfds[0].in_flags = PR_POLL_READ;
pollfds[1].fd = camel_msgport_prfd(is->port);
pollfds[1].in_flags = PR_POLL_READ;
+#include <prio.h>
res = PR_Poll(pollfds, 2, PR_TicksPerSecond() / 10);
if (res == -1)
@@ -2252,36 +2276,36 @@ imapx_server_loop(gpointer d)
/* This is quite shitty, it will often block on each
part of the decode, causing significant
processing delays. */
- imapx_step(is);
+ imapx_step(is, &ex);
} while (camel_imapx_stream_buffered(is->stream));
} else if (pollfds[1].out_flags & PR_POLL_READ) {
printf(" * woken * have new job\n");
/* job is handled in main loop */
}
}
-#else
+#endif
+ if (CAMEL_IS_TCP_STREAM (is->stream->source))
{
- struct pollfd[2] = { 0 };
+ struct pollfd fds[2] = { 0 };
gint res;
- pollfd[0].fd = ((CamelTcpStreamRaw *)is->stream->source)->sockfd;
- pollfd[0].events = POLLIN;
- pollfd[1].fd = camel_msgport_fd(is->port);
- pollfd[1].events = POLLIN;
+ fds[0].fd = ((CamelTcpStreamRaw *)is->stream->source)->sockfd;
+ fds[0].events = POLLIN;
+ fds[1].fd = camel_msgport_fd(is->port);
+ fds[1].events = POLLIN;
- res = poll(pollfd, 2, 1000*30);
+ res = poll(fds, 2, 1000*30);
if (res == -1)
sleep(1) /* ?? */ ;
else if (res == 0)
/* timed out */;
- else if (pollfds[0].revents & POLLIN) {
+ else if (fds[0].revents & POLLIN) {
do {
- imapx_step(is);
+ imapx_step(is, &ex);
} while (camel_imapx_stream_buffered(is->stream));
}
}
#endif
-#endif
if (camel_exception_is_set (&ex)) {
printf("######### Got main loop exception: %s\n", ex.desc);
sleep(1);
@@ -2368,15 +2392,24 @@ camel_imapx_server_new(CamelStore *store, CamelURL *url)
/* Client commands */
-void
+gboolean
camel_imapx_server_connect(CamelIMAPXServer *is, gint state)
{
if (state) {
pthread_t id;
+ CamelException ex = {0, NULL};
+
+ imapx_reconnect (is, &ex);
+ if (camel_exception_is_set (&ex))
+ return FALSE;
pthread_create(&id, NULL, imapx_server_loop, is);
+
+ return TRUE;
} else {
/* tell processing thread to die, and wait till it does? */
+
+ return TRUE;
}
}
@@ -2392,7 +2425,7 @@ imapx_run_job(CamelIMAPXServer *is, CamelIMAPXJob *job)
/* Umm, so all these jobs 'select' first, which means reading(!)
we can't read from this thread ... hrm ... */
- if (FALSE /*is->state >= IMAPX_AUTHENTICATED*/) {
+ if (is->state >= IMAPX_AUTHENTICATED) {
/* NB: Must catch exceptions, cleanup/etc if we fail here? */
QUEUE_LOCK(is);
camel_dlist_addhead(&is->jobs, (CamelDListNode *)job);
diff --git a/camel/providers/imapx/camel-imapx-server.h b/camel/providers/imapx/camel-imapx-server.h
index a8e5f24..daafb98 100644
--- a/camel/providers/imapx/camel-imapx-server.h
+++ b/camel/providers/imapx/camel-imapx-server.h
@@ -94,7 +94,7 @@ struct _CamelIMAPXServerClass {
CamelType camel_imapx_server_get_type (void);
CamelIMAPXServer *camel_imapx_server_new(struct _CamelStore *store, struct _CamelURL *url);
-void camel_imapx_server_connect(CamelIMAPXServer *is, gint state);
+gboolean camel_imapx_server_connect(CamelIMAPXServer *is, gint state);
GPtrArray *camel_imapx_server_list(CamelIMAPXServer *is, const gchar *top, guint32 flags, CamelException *ex);
diff --git a/camel/providers/imapx/camel-imapx-store.c b/camel/providers/imapx/camel-imapx-store.c
index c2a3304..d5a4cd1 100644
--- a/camel/providers/imapx/camel-imapx-store.c
+++ b/camel/providers/imapx/camel-imapx-store.c
@@ -86,7 +86,7 @@ imapx_name_equal(gconstpointer a, gconstpointer b)
static void imap_construct(CamelService *service, CamelSession *session, CamelProvider *provider, CamelURL *url, CamelException *ex)
{
- gchar *base, *summary;
+ gchar *summary;
CamelIMAPXStore *store = (CamelIMAPXStore *)service;
CAMEL_SERVICE_CLASS (parent_class)->construct (service, session, provider, url, ex);
@@ -102,6 +102,10 @@ static void imap_construct(CamelService *service, CamelSession *session, CamelPr
camel_store_summary_set_uri_base((CamelStoreSummary *)store->summary, service->url);
camel_store_summary_load((CamelStoreSummary *)store->summary);
}
+
+ store->base_url = camel_url_to_string (service->url, (CAMEL_URL_HIDE_PASSWORD |
+ CAMEL_URL_HIDE_PARAMS |
+ CAMEL_URL_HIDE_AUTH));
}
extern CamelServiceAuthType camel_imapx_password_authtype;
@@ -249,7 +253,6 @@ get_folder_offline (CamelStore *store, const gchar *folder_name,
static CamelFolder *
imap_get_folder (CamelStore *store, const gchar *folder_name, guint32 flags, CamelException *ex)
{
- CamelIMAPXStore *istore = (CamelIMAPXStore *)store;
CamelFolder *folder;
folder = get_folder_offline(store, folder_name, flags, ex);
@@ -480,11 +483,40 @@ fill_fi(CamelStore *store, CamelFolderInfo *fi, guint32 flags)
}
}
-static gint
-imap_match_pattern(gchar dir_sep, const gchar *pattern, const gchar *name)
+/* imap needs to treat inbox case insensitive */
+/* we'll assume the names are normalised already */
+static guint folder_hash(gconstpointer ap)
+{
+ const gchar *a = ap;
+
+ if (g_ascii_strcasecmp(a, "INBOX") == 0)
+ a = "INBOX";
+
+ return g_str_hash(a);
+}
+
+static gint folder_eq(gconstpointer ap, gconstpointer bp)
{
- gchar p, n;
+ const gchar *a = ap;
+ const gchar *b = bp;
+
+ if (g_ascii_strcasecmp(a, "INBOX") == 0)
+ a = "INBOX";
+ if (g_ascii_strcasecmp(b, "INBOX") == 0)
+ b = "INBOX";
+ return g_str_equal(a, b);
+}
+
+static gboolean
+imap_match_pattern(CamelIMAPXStoreNamespace *ns, const gchar *pattern, const gchar *name)
+{
+ gchar p, n, dir_sep;
+
+ if (!ns)
+ return TRUE;
+
+ dir_sep = ns->sep;
p = *pattern++;
n = *name++;
while (n && p) {
@@ -517,7 +549,6 @@ get_folder_info_offline (CamelStore *store, const gchar *top,
gchar *pattern, *name;
gint i;
-// if (camel_debug("imap:folder_info"))
printf("get folder info offline\n");
/* FIXME: obey other flags */
@@ -552,6 +583,8 @@ get_folder_info_offline (CamelStore *store, const gchar *top,
for (i=0;i<camel_store_summary_count((CamelStoreSummary *)imapx_store->summary);i++) {
CamelStoreInfo *si = camel_store_summary_index((CamelStoreSummary *)imapx_store->summary, i);
const gchar *full_name;
+ CamelIMAPXStoreNamespace *ns;
+
if (si == NULL)
continue;
@@ -562,13 +595,16 @@ get_folder_info_offline (CamelStore *store, const gchar *top,
continue;
}
- if ((!strcmp(name, full_name)
- || imap_match_pattern(imapx_store->dir_sep, pattern, full_name)
- || (include_inbox && !g_ascii_strcasecmp (full_name, "INBOX")))
-// && ((imapx_store->parameters & IMAP_PARAM_SUBSCRIPTIONS) == 0
- &&((flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) == 0
- || (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))) {
+ ns = camel_imapx_store_summary_namespace_find_full (imapx_store->summary, full_name);
+ /* Modify the checks to see match the namespaces from preferences */
+ if ((g_str_equal (name, full_name)
+ || imap_match_pattern (ns, pattern, full_name)
+ || (include_inbox && !g_ascii_strcasecmp (full_name, "INBOX")))
+ && ( TRUE
+ || (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)
+ || (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0)) {
+
fi = imapx_build_folder_info(imapx_store, camel_store_info_path((CamelStoreSummary *)imapx_store->summary, si));
fi->unread = si->unread;
fi->total = si->total;
@@ -608,8 +644,210 @@ get_folder_info_offline (CamelStore *store, const gchar *top,
return fi;
}
+static void
+add_folders_to_summary (CamelIMAPXStore *istore, GPtrArray *folders, GHashTable **table)
+{
+ gint i = 0;
+
+ for (i = 0; i < folders->len; i++) {
+ struct _list_info *li = folders->pdata[i];
+ CamelIMAPXStoreInfo *si;
+ guint32 new_flags;
+ CamelFolderInfo *fi, *hfi;
+ gchar *path;
+ CamelURL *url;
+
+ si = camel_imapx_store_summary_add_from_full (istore->summary, li->name, li->separator);
+ if (!si)
+ continue;
+
+ new_flags = (si->info.flags & (CAMEL_STORE_INFO_FOLDER_SUBSCRIBED | CAMEL_STORE_INFO_FOLDER_CHECK_FOR_NEW)) |
+ (li->flags & ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED);
+
+ if (si->info.flags != new_flags) {
+ si->info.flags = new_flags;
+ camel_store_summary_touch ((CamelStoreSummary *) istore->summary);
+ }
+
+ if (!table)
+ continue;
+
+ fi = camel_folder_info_new ();
+ fi->full_name = g_strdup(camel_store_info_path(istore->summary, si));
+ if (!g_ascii_strcasecmp(fi->full_name, "inbox")) {
+ li->flags |= CAMEL_FOLDER_SYSTEM|CAMEL_FOLDER_TYPE_INBOX;
+ fi->name = g_strdup (_("Inbox"));
+ } else
+ fi->name = g_strdup(camel_store_info_name(istore->summary, si));
+
+ /* HACK: some servers report noinferiors for all folders (uw-imapd)
+ We just translate this into nochildren, and let the imap layer enforce
+ it. See create folder */
+ if (li->flags & CAMEL_FOLDER_NOINFERIORS)
+ li->flags = (li->flags & ~CAMEL_FOLDER_NOINFERIORS) | CAMEL_FOLDER_NOCHILDREN;
+ fi->flags = li->flags;
+
+ url = camel_url_new (istore->base_url, NULL);
+ path = alloca(strlen(fi->full_name)+2);
+ sprintf(path, "/%s", fi->full_name);
+ camel_url_set_path(url, path);
+
+ if (li->flags & CAMEL_FOLDER_NOSELECT || fi->name[0] == 0)
+ camel_url_set_param (url, "noselect", "yes");
+ fi->uri = camel_url_to_string (url, 0);
+ camel_url_free (url);
+
+ fi->total = -1;
+ fi->unread = -1;
+
+ hfi = g_hash_table_lookup (*table, fi->name);
+ if (hfi == NULL)
+ g_hash_table_insert (*table, fi->name, fi);
+ else if ((hfi->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) ^ (fi->flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED))
+ hfi->flags |= CAMEL_STORE_INFO_FOLDER_SUBSCRIBED;
+ }
+}
+
+static void
+free_list (gpointer data, gpointer user_data)
+{
+ struct _list_info *li = data;
+ imap_free_list (li);
+}
+
+static void
+fetch_folders_for_pattern (CamelIMAPXStore *istore, const gchar *pattern, guint32 flags, GHashTable **table, CamelException *ex)
+{
+ GPtrArray *folders = NULL;
+
+ folders = camel_imapx_server_list (istore->server, pattern, flags, ex);
+ add_folders_to_summary (istore, folders, table);
+
+ g_ptr_array_foreach (folders, free_list, folders);
+ g_ptr_array_free (folders, TRUE);
+}
+
+static GSList *
+get_namespaces (CamelIMAPXStore *istore)
+{
+ GSList *namespaces = NULL;
+ CamelIMAPXNamespaceList *nsl = NULL;
+
+ /* Add code to return the namespaces from preference else all of them */
+ nsl = istore->summary->namespaces;
+ if (nsl->personal)
+ namespaces = g_slist_append (namespaces, nsl->personal);
+ if (nsl->other)
+ namespaces = g_slist_append (namespaces, nsl->other);
+ if (nsl->shared)
+ namespaces = g_slist_append (namespaces, nsl->shared);
+
+ return namespaces;
+}
+
+static GHashTable *
+fetch_folders_for_namespaces (CamelIMAPXStore *istore, const gchar *pattern, CamelException *ex)
+{
+ GHashTable *folders = NULL;
+ GSList *namespaces = NULL, *l;
+
+ folders = g_hash_table_new (folder_hash, folder_eq);
+ namespaces = get_namespaces (istore);
+
+ for (l = namespaces; l != NULL; l = g_slist_next (l))
+ {
+ CamelIMAPXStoreNamespace *ns = l->data;
+
+ while (ns) {
+ guint32 flags = 0;
+ gchar *pat = NULL;
+
+ if (!pattern) {
+ if (!*ns->path)
+ pat = g_strdup ("");
+ else
+ pat = g_strdup_printf ("%s%c", ns->path, ns->sep);
+ } else
+ pat = g_strdup (pattern);
+
+ flags |= CAMEL_STORE_FOLDER_INFO_RECURSIVE;
+ fetch_folders_for_pattern (istore, pat, flags, &folders, ex);
+ flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED;
+ fetch_folders_for_pattern (istore, pat, flags, &folders, ex);
+
+ g_free (pat);
+
+ if (pattern)
+ return folders;
+
+ ns = ns->next;
+ }
+ }
+
+ return folders;
+}
+
+static void
+sync_folders (CamelIMAPXStore *istore, const gchar *pattern, CamelException *ex)
+{
+ struct _list_info *li = NULL;
+ guint32 flags = 0;
+ GHashTable *folders_from_server;
+ gint i, total;
+
+ folders_from_server = fetch_folders_for_namespaces (istore, pattern, ex);
+
+ total = camel_store_summary_count ((CamelStoreSummary *) istore->summary);
+ for (i = 0; i < total; i++) {
+ CamelStoreInfo *si;
+ const gchar *full_name;
+ CamelFolderInfo *fi;
+
+ si = camel_store_summary_index ((CamelStoreSummary *) istore->summary, i);
+ if (!si)
+ continue;
+
+ full_name = camel_imapx_store_info_full_name (istore->summary, si);
+ if (!full_name || !*full_name) {
+ camel_store_summary_info_free ((CamelStoreSummary *)istore->summary, si);
+ continue;
+ }
+
+ if (!pattern || imap_match_pattern (camel_imapx_store_summary_namespace_find_full (istore->summary, full_name), pattern, full_name)) {
+ if ((fi = g_hash_table_lookup(folders_from_server, camel_store_info_path(istore->summary, si))) != NULL) {
+ if (((fi->flags ^ si->flags) & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)) {
+ si->flags = (si->flags & ~CAMEL_FOLDER_SUBSCRIBED) | (fi->flags & CAMEL_FOLDER_SUBSCRIBED);
+ camel_store_summary_touch((CamelStoreSummary *)istore->summary);
+
+ camel_object_trigger_event (CAMEL_OBJECT (istore), "folder_created", fi);
+ camel_object_trigger_event (CAMEL_OBJECT (istore), "folder_subscribed", fi);
+ }
+ } else {
+ gchar *dup_folder_name = g_strdup (camel_store_info_path (istore->summary, si));
+
+ if (dup_folder_name) {
+ CamelException eex;
+
+ camel_exception_init (&eex);
+
+ /* Delete the folder from cache */
+
+ g_free (dup_folder_name);
+ camel_exception_clear (&eex);
+ } else {
+ camel_store_summary_remove ((CamelStoreSummary *)istore->summary, si);
+ }
+
+ total--;
+ i--;
+ }
+ }
+ camel_store_summary_info_free((CamelStoreSummary *)istore->summary, si);
+ }
+}
+
static CamelFolderInfo *
-imap_get_folder_info(CamelStore *store, const gchar *top, guint32 flags, CamelException *ex)
+imapx_get_folder_info(CamelStore *store, const gchar *top, guint32 flags, CamelException *ex)
{
CamelIMAPXStore *istore = (CamelIMAPXStore *)store;
CamelFolderInfo * fi= NULL;
@@ -618,35 +856,26 @@ imap_get_folder_info(CamelStore *store, const gchar *top, guint32 flags, CamelEx
CamelIterator *iter;
gint i;
+ if (top == NULL)
+ top = "";
+
+ if (CAMEL_OFFLINE_STORE(store)->state == CAMEL_OFFLINE_STORE_NETWORK_UNAVAIL) {
+ fi = get_folder_info_offline (store, top, flags, ex);
+ return fi;
+ }
+
if (istore->server == NULL) {
camel_service_connect((CamelService *)store, ex);
if (camel_exception_is_set(ex))
return NULL;
}
-
- if (top == NULL)
- top = "";
-
- if (folders == NULL) {
- folders = camel_imapx_server_list(istore->server, "", flags, ex);
- for (i=0;!camel_exception_is_set(ex) && i<folders->len;i++) {
- struct _list_info *li = folders->pdata[i];
- gchar *name;
-
- name = imapx_list_get_path(li);
- g_free(name);
- }
+
+ if (camel_store_summary_count (istore->summary) == 0) {
+ sync_folders (istore, top, ex);
+ camel_store_summary_save((CamelStoreSummary *)istore->summary);
}
-
- i = 0;
- base = camel_url_copy(((CamelService *)store)->url);
- fi = folders_build_rec(base, folders, &i, NULL, NULL);
- camel_url_free(base);
-
- g_ptr_array_free(folders, TRUE);
-
- // FIXME: temporary
- folder_info_fill(store, fi);
+
+ fi = get_folder_info_offline (store, top, flags, ex);
return fi;
}
@@ -916,7 +1145,7 @@ camel_imapx_store_class_init(CamelIMAPXStoreClass *klass)
camel_store_class->create_folder = imap_create_folder;
camel_store_class->rename_folder = imap_rename_folder;
camel_store_class->delete_folder = imap_delete_folder;
- camel_store_class->get_folder_info = imap_get_folder_info;
+ camel_store_class->get_folder_info = imapx_get_folder_info;
((CamelStoreClass *)klass)->hash_folder_name = imapx_name_hash;
((CamelStoreClass *)klass)->compare_folder_name = imapx_name_equal;
@@ -937,6 +1166,9 @@ imapx_store_finalise(CamelObject *object)
/* SIGH */
camel_service_disconnect((CamelService *)imap_store, TRUE, NULL);
+
+ if (imap_store->base_url)
+ g_free (imap_store->base_url);
}
CamelType
@@ -945,7 +1177,7 @@ camel_imapx_store_get_type (void)
static CamelType camel_imapx_store_type = CAMEL_INVALID_TYPE;
if (!camel_imapx_store_type) {
- camel_imapx_store_type = camel_type_register(CAMEL_STORE_TYPE,
+ camel_imapx_store_type = camel_type_register(camel_offline_store_get_type (),
"CamelIMAPXStore",
sizeof (CamelIMAPXStore),
sizeof (CamelIMAPXStoreClass),
diff --git a/camel/providers/imapx/camel-imapx-store.h b/camel/providers/imapx/camel-imapx-store.h
index 03d117f..773e5a0 100644
--- a/camel/providers/imapx/camel-imapx-store.h
+++ b/camel/providers/imapx/camel-imapx-store.h
@@ -32,6 +32,7 @@ extern "C" {
#include <camel/camel-types.h>
#include <camel/camel-store.h>
#include "camel-imapx-store-summary.h"
+#include <camel/camel-offline-store.h>
#define CAMEL_IMAPX_STORE_TYPE (camel_imapx_store_get_type ())
#define CAMEL_IMAPX_STORE(obj) (CAMEL_CHECK_CAST((obj), CAMEL_IMAPX_STORE_TYPE, CamelIMAPXStore))
@@ -46,7 +47,7 @@ struct _pending_fetch {
};
typedef struct {
- CamelStore parent_object;
+ CamelOfflineStore parent_object;
struct _CamelIMAPXServer *server;
@@ -60,7 +61,7 @@ typedef struct {
} CamelIMAPXStore;
typedef struct {
- CamelStoreClass parent_class;
+ CamelOfflineStoreClass parent_class;
} CamelIMAPXStoreClass;
diff --git a/camel/providers/imapx/camel-imapx-utils.c b/camel/providers/imapx/camel-imapx-utils.c
index 7273a15..0868530 100644
--- a/camel/providers/imapx/camel-imapx-utils.c
+++ b/camel/providers/imapx/camel-imapx-utils.c
@@ -157,7 +157,7 @@ imap_parse_capability(CamelIMAPXStream *stream, CamelException *ex)
gint tok, len, i;
guchar *token, *p, c, *temp;
gboolean free_token = FALSE;
- struct _capability_info * volatile cinfo;
+ struct _capability_info * cinfo;
cinfo = g_malloc0(sizeof(*cinfo));
@@ -175,7 +175,7 @@ imap_parse_capability(CamelIMAPXStream *stream, CamelException *ex)
case IMAP_TOK_INT:
printf(" cap: '%s'\n", token);
for (i = 0; i < G_N_ELEMENTS (capa_table); i++)
- if (strcmp(token, capa_table[i].name))
+ if (!strcmp(token, capa_table[i].name))
cinfo->capa |= capa_table[i].flag;
if (free_token) {
g_free (token);
@@ -233,6 +233,7 @@ imap_parse_namespace_list (CamelIMAPXStream *stream, CamelException *ex)
node = g_new0 (CamelIMAPXStoreNamespace, 1);
node->next = NULL;
+ node->full_name = g_strdup (token);
node->path = g_strdup (token);
g_message ("namespace: Node path is %s \n", node->path);
@@ -1335,8 +1336,8 @@ static struct {
} list_flag_table[] = {
{ "\\NOINFERIORS", CAMEL_FOLDER_NOINFERIORS },
{ "\\NOSELECT", CAMEL_FOLDER_NOSELECT },
- { "\\MARKED", 1<<8 },
- { "\\UNMARKED", 1<<9 },
+ { "\\MARKED", 1<< 16},
+ { "\\UNMARKED", 1<< 17},
};
struct _list_info *
@@ -1345,7 +1346,7 @@ imap_parse_list(CamelIMAPXStream *is, CamelException *ex)
{
gint tok, len, i;
guchar *token, *p, c;
- struct _list_info * volatile linfo;
+ struct _list_info * linfo;
linfo = g_malloc0(sizeof(*linfo));
@@ -1582,6 +1583,9 @@ imapx_namespace_clear (CamelIMAPXStoreNamespace **ns)
void
camel_imapx_namespace_list_clear (struct _CamelIMAPXNamespaceList *nsl)
{
+ if (!nsl)
+ return;
+
imapx_namespace_clear (&nsl->personal);
imapx_namespace_clear (&nsl->shared);
imapx_namespace_clear (&nsl->other);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]