aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2002-10-24 22:01:53 +0800
committerMichael Zucci <zucchi@src.gnome.org>2002-10-24 22:01:53 +0800
commitd91b5bb03431dc5477cacfd2b922a68a1ec623c5 (patch)
treea8f5b77e2df75140c78e1bf811f50ed9ec9a888b /camel/providers
parent5f737e09fe3132cee4322b52332fc83add921d99 (diff)
downloadgsoc2013-evolution-d91b5bb03431dc5477cacfd2b922a68a1ec623c5.tar.gz
gsoc2013-evolution-d91b5bb03431dc5477cacfd2b922a68a1ec623c5.tar.zst
gsoc2013-evolution-d91b5bb03431dc5477cacfd2b922a68a1ec623c5.zip
** For bug #31647 and bug #31456.
2002-10-24 Not Zed <NotZed@Ximian.com> ** For bug #31647 and bug #31456. * camel-store-summary.c (store_info_string): for STORE_INFO_NAME, skip the leading /. * providers/imap/camel-imap-store.c (parse_list_response_as_folder_info): Remove jeff's last patch, and use the store summary to create the name and path of the folderinfo so it manages namespace issues. (get_folder_info_online): Just pass @top directly to build_folder_info always, since namespace is mapped to 1 tree level. (imap_build_folder_info): Remove jeff's last patch, dont strip leading /'s, they shouldn't exist. (imap_connect_online): Remove adding the INBOX here, we add it later. (get_subscribed_folders): Make sure INBOX is always in the list. some imap servers dont seem to let you subscribe to it(?), so always have it act as subscribed. * camel-store.c (camel_folder_info_build): back out the last 2 patches from Jeff (for #31456) to get the original behaviour. (camel_folder_info_build): When creating a fake parent, dont strip the namespace from the full_name. malloc keys in hash since we dont have them anymore. (free_name): Helper to free names. * providers/imap/camel-imap-store-summary.c (camel_imap_store_summary_namespace_new): Canonicalise the namespace (strip trailing dir_sep), and change the path to remove any /'s. (camel_imap_store_summary_namespace_find_path): (camel_imap_store_summary_namespace_find_full): new, find namespace by path/full name. (camel_imap_store_summary_full_from_path): Changed to a simple wrapper around path_to_full, after checking namespace. (camel_imap_store_summary_add_from_full): map the namespace if present. (camel_imap_store_summary_path_to_full): If namespace exists, unmap it. svn path=/trunk/; revision=18424
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/imap/camel-imap-store-summary.c114
-rw-r--r--camel/providers/imap/camel-imap-store-summary.h4
-rw-r--r--camel/providers/imap/camel-imap-store.c100
-rw-r--r--camel/providers/imap/camel-imap-store.h1
4 files changed, 142 insertions, 77 deletions
diff --git a/camel/providers/imap/camel-imap-store-summary.c b/camel/providers/imap/camel-imap-store-summary.c
index 4ba5bb9b68..9cdebba3e9 100644
--- a/camel/providers/imap/camel-imap-store-summary.c
+++ b/camel/providers/imap/camel-imap-store-summary.c
@@ -214,6 +214,7 @@ camel_imap_store_summary_path_to_full(CamelImapStoreSummary *s, const char *path
int state=0;
char *subpath, *last = NULL;
CamelStoreInfo *si;
+ CamelImapStoreNamespace *ns;
/* check to see if we have a subpath of path already defined */
subpath = alloca(strlen(path)+1);
@@ -234,11 +235,16 @@ camel_imap_store_summary_path_to_full(CamelImapStoreSummary *s, const char *path
return f;
}
+ ns = camel_imap_store_summary_namespace_find_path(s, path);
+
f = full = alloca(strlen(path)*2+1);
if (si)
p = path + strlen(subpath);
+ else if (ns)
+ p = path + strlen(ns->path);
else
p = path;
+
while ( (c = camel_utf8_getc((const unsigned char **)&p)) ) {
switch(state) {
case 0:
@@ -270,18 +276,31 @@ camel_imap_store_summary_path_to_full(CamelImapStoreSummary *s, const char *path
g_free(f);
camel_store_summary_info_free((CamelStoreSummary *)s, si);
f = full;
+ } else if (ns) {
+ full = g_strdup_printf("%s%s", ns->full_name, f);
+ g_free(f);
+ f = full;
}
return f;
}
CamelImapStoreInfo *
-camel_imap_store_summary_add_from_full(CamelImapStoreSummary *s, const char *full_name, char dir_sep)
+camel_imap_store_summary_add_from_full(CamelImapStoreSummary *s, const char *full, char dir_sep)
{
CamelImapStoreInfo *info;
- char *pathu8;
+ char *pathu8, *prefix;
+ int len;
+ char *full_name;
+ CamelImapStoreNamespace *ns;
+
+ d(printf("adding full name '%s' '%c'\n", full, dir_sep));
- d(printf("adding full name '%s' '%c'\n", full_name, dir_sep));
+ len = strlen(full);
+ full_name = alloca(len+1);
+ strcpy(full_name, full);
+ if (full_name[len-1] == dir_sep)
+ full_name[len-1] = 0;
info = camel_imap_store_summary_full_name(s, full_name);
if (info) {
@@ -290,7 +309,24 @@ camel_imap_store_summary_add_from_full(CamelImapStoreSummary *s, const char *ful
return info;
}
- pathu8 = camel_imap_store_summary_full_to_path(s, full_name, dir_sep);
+ ns = camel_imap_store_summary_namespace_find_full(s, full_name);
+ if (ns) {
+ d(printf("(found namespace for '%s' ns '%s') ", full_name, ns->path));
+ len = strlen(ns->full_name);
+ if (len >= strlen(full_name)) {
+ pathu8 = g_strdup(ns->path);
+ } else {
+ if (full_name[len] == ns->sep)
+ len++;
+ prefix = camel_imap_store_summary_full_to_path(s, full_name+len, ns->sep);
+ pathu8 = g_strdup_printf("%s/%s", ns->path, prefix);
+ g_free(prefix);
+ }
+ d(printf(" (pathu8 = '%s')", pathu8));
+ } else {
+ d(printf("(Cannot find namespace for '%s')\n", full_name));
+ pathu8 = camel_imap_store_summary_full_to_path(s, full_name, dir_sep);
+ }
info = (CamelImapStoreInfo *)camel_store_summary_add_from_path((CamelStoreSummary *)s, pathu8);
if (info) {
@@ -303,30 +339,44 @@ camel_imap_store_summary_add_from_full(CamelImapStoreSummary *s, const char *ful
}
/* should this be const? */
+/* TODO: deprecate/merge this function with path_to_full */
char *
camel_imap_store_summary_full_from_path(CamelImapStoreSummary *s, const char *path)
{
CamelImapStoreInfo *si;
+ CamelImapStoreNamespace *ns;
+ char *name = NULL;
- si = (CamelImapStoreInfo *)camel_store_summary_path((CamelStoreSummary *)s, path);
+ ns = camel_imap_store_summary_namespace_find_path(s, path);
+ if (ns)
+ name = camel_imap_store_summary_path_to_full(s, path, ns->sep);
- d(printf("looking up path %s -> %s\n", path, si?si->full_name:"not found"));
+ d(printf("looking up path %s -> %s\n", path, name?name:"not found"));
- if (si)
- return g_strdup(si->full_name);
-
- return NULL;
+ return name;
}
/* TODO: this api needs some more work */
CamelImapStoreNamespace *camel_imap_store_summary_namespace_new(CamelImapStoreSummary *s, const char *full_name, char dir_sep)
{
CamelImapStoreNamespace *ns;
+ char *p;
+ int len;
+ GString *tmp;
ns = g_malloc0(sizeof(*ns));
ns->full_name = g_strdup(full_name);
+ len = strlen(ns->full_name)-1;
+ if (len >= 0 && ns->full_name[len] == dir_sep)
+ ns->full_name[len] = 0;
ns->sep = dir_sep;
- ns->path = camel_imap_store_summary_full_to_path(s, full_name, dir_sep);
+
+ p = ns->path = camel_imap_store_summary_full_to_path(s, ns->full_name, dir_sep);
+ while (*p) {
+ if (*p == '/')
+ *p = '.';
+ p++;
+ }
return ns;
}
@@ -335,11 +385,53 @@ void camel_imap_store_summary_namespace_set(CamelImapStoreSummary *s, CamelImapS
{
static void namespace_clear(CamelStoreSummary *s);
+ d(printf("Setting namesapce to '%s' '%c' -> '%s'\n", ns->full_name, ns->sep, ns->path));
namespace_clear((CamelStoreSummary *)s);
s->namespace = ns;
camel_store_summary_touch((CamelStoreSummary *)s);
}
+CamelImapStoreNamespace *
+camel_imap_store_summary_namespace_find_path(CamelImapStoreSummary *s, const char *path)
+{
+ int len;
+ CamelImapStoreNamespace *ns;
+
+ /* NB: this currently only compares against 1 namespace, in future compare against others */
+ ns = s->namespace;
+ while (ns) {
+ len = strlen(ns->path);
+ if (strncmp(ns->path, path, len) == 0
+ && (path[len] == '/' || path[len] == 0))
+ break;
+ ns = NULL;
+ }
+
+ /* have a default? */
+ return ns;
+}
+
+CamelImapStoreNamespace *
+camel_imap_store_summary_namespace_find_full(CamelImapStoreSummary *s, const char *full)
+{
+ int len;
+ CamelImapStoreNamespace *ns;
+
+ /* NB: this currently only compares against 1 namespace, in future compare against others */
+ ns = s->namespace;
+ while (ns) {
+ len = strlen(ns->full_name);
+ d(printf("find_full: comparing namespace '%s' to name '%s'\n", ns->full_name, full));
+ if (strncmp(ns->full_name, full, len) == 0
+ && (full[len] == ns->sep || full[len] == 0))
+ break;
+ ns = NULL;
+ }
+
+ /* have a default? */
+ return ns;
+}
+
static void
namespace_free(CamelStoreSummary *s, CamelImapStoreNamespace *ns)
{
diff --git a/camel/providers/imap/camel-imap-store-summary.h b/camel/providers/imap/camel-imap-store-summary.h
index 013283b5c1..0fa6be0df3 100644
--- a/camel/providers/imap/camel-imap-store-summary.h
+++ b/camel/providers/imap/camel-imap-store-summary.h
@@ -76,9 +76,11 @@ struct _CamelImapStoreSummaryClass {
CamelType camel_imap_store_summary_get_type (void);
CamelImapStoreSummary *camel_imap_store_summary_new (void);
-/* TODO: this api needs some more work */
+/* TODO: this api needs some more work, needs to support lists */
CamelImapStoreNamespace *camel_imap_store_summary_namespace_new(CamelImapStoreSummary *s, const char *full_name, char dir_sep);
void camel_imap_store_summary_namespace_set(CamelImapStoreSummary *s, CamelImapStoreNamespace *ns);
+CamelImapStoreNamespace *camel_imap_store_summary_namespace_find_path(CamelImapStoreSummary *s, const char *path);
+CamelImapStoreNamespace *camel_imap_store_summary_namespace_find_full(CamelImapStoreSummary *s, const char *full_name);
/* converts to/from utf8 canonical nasmes */
char *camel_imap_store_summary_full_to_path(CamelImapStoreSummary *s, const char *full_name, char dir_sep);
diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c
index 1da03ffdef..ac8d3e93ab 100644
--- a/camel/providers/imap/camel-imap-store.c
+++ b/camel/providers/imap/camel-imap-store.c
@@ -816,31 +816,26 @@ imap_build_folder_info(CamelImapStore *imap_store, const char *folder_name)
CamelURL *url;
const char *name;
CamelFolderInfo *fi;
-
+
fi = g_malloc0(sizeof(*fi));
-
+
fi->full_name = g_strdup(folder_name);
fi->unread_message_count = 0;
-
+
url = camel_url_new (imap_store->base_url, NULL);
g_free (url->path);
url->path = g_strdup_printf ("/%s", folder_name);
fi->url = camel_url_to_string (url, CAMEL_URL_HIDE_ALL);
camel_url_free(url);
-
- /* strip extranious leading /'s */
- while (*folder_name == '/')
- folder_name++;
-
fi->path = g_strdup_printf("/%s", folder_name);
name = strrchr (fi->path, '/');
if (name)
name++;
else
name = fi->path;
-
+
fi->name = g_strdup (name);
-
+
return fi;
}
@@ -1271,33 +1266,29 @@ imap_connect_online (CamelService *service, CamelException *ex)
/* canonicalize the namespace to end with dir_sep */
len = strlen (store->namespace);
if (len && store->namespace[len - 1] != store->dir_sep) {
- char *tmp;
+ gchar *tmp;
tmp = g_strdup_printf ("%s%c", store->namespace, store->dir_sep);
g_free (store->namespace);
store->namespace = tmp;
}
-
+
ns = camel_imap_store_summary_namespace_new(store->summary, store->namespace, store->dir_sep);
camel_imap_store_summary_namespace_set(store->summary, ns);
if (CAMEL_STORE (store)->flags & CAMEL_STORE_SUBSCRIPTIONS) {
GPtrArray *folders;
char *pattern;
-
+
/* this pre-fills the summary, and checks that lsub is useful */
- folders = g_ptr_array_new ();
- pattern = g_strdup_printf ("%s*", store->namespace);
- get_folders_online (store, pattern, folders, TRUE, ex);
- g_free (pattern);
-
- /* if we have a namespace, then our LSUB won't include INBOX so LSUB for the INBOX too */
- if (*store->namespace && !camel_exception_is_set (ex))
- get_folders_online (store, "INBOX", folders, TRUE, ex);
-
+ folders = g_ptr_array_new();
+ pattern = g_strdup_printf("%s*", store->namespace);
+ get_folders_online(store, pattern, folders, TRUE, ex);
+ g_free(pattern);
+
for (i=0;i<folders->len;i++) {
CamelFolderInfo *fi = folders->pdata[i];
-
+
if (fi->flags & (CAMEL_IMAP_FOLDER_MARKED | CAMEL_IMAP_FOLDER_UNMARKED))
store->capabilities |= IMAP_CAPABILITY_useful_lsub;
camel_folder_info_free(fi);
@@ -1312,7 +1303,7 @@ imap_connect_online (CamelService *service, CamelException *ex)
done:
/* save any changes we had */
camel_store_summary_save((CamelStoreSummary *)store->summary);
-
+
CAMEL_SERVICE_UNLOCK (store, connect_lock);
if (camel_exception_is_set (ex))
@@ -1926,19 +1917,17 @@ parse_list_response_as_folder_info (CamelImapStore *imap_store,
const char *response)
{
CamelFolderInfo *fi;
- int flags;
- char sep, *dir, *name = NULL, *path, *p;
+ int flags, i;
+ char sep, *dir, *name = NULL, *path;
CamelURL *url;
CamelImapStoreInfo *si;
guint32 newflags;
-
+
if (!imap_parse_list_response (imap_store, response, &flags, &sep, &dir))
return NULL;
-
+
/* FIXME: should use imap_build_folder_info, note the differences with param setting tho */
- path = camel_utf7_utf8(dir);
-
- /* hack: pokes in value from any list response */
+
si = camel_imap_store_summary_add_from_full(imap_store->summary, dir, sep?sep:'/');
newflags = (si->info.flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) | (flags & ~CAMEL_STORE_INFO_FOLDER_SUBSCRIBED);
if (si->info.flags != newflags) {
@@ -1946,45 +1935,24 @@ parse_list_response_as_folder_info (CamelImapStore *imap_store,
camel_store_summary_touch((CamelStoreSummary *)imap_store->summary);
}
- if (sep && sep != '/') {
- for (p = path; *p; p++) {
- if (*p == sep)
- *p = '/';
- }
- }
-
- if ((name = strrchr (path, '/'))) {
- name++;
- if (!*name) {
- g_free(dir);
- g_free(path);
- return NULL;
- }
- } else
- name = path;
-
fi = g_new0 (CamelFolderInfo, 1);
fi->flags = flags;
- fi->name = g_strdup (name);
- fi->full_name = path;
-
- while (*path == '/')
- path++;
- fi->path = g_strdup_printf ("/%s", path);
+ fi->name = g_strdup(camel_store_info_name(imap_store->summary, si));
+ fi->path = g_strdup_printf("/%s", camel_store_info_path(imap_store->summary, si));
+ fi->full_name = g_strdup(fi->path+1);
url = camel_url_new (imap_store->base_url, NULL);
- g_free (url->path);
- url->path = g_strdup_printf ("/%s", fi->full_name);
-
+ camel_url_set_path(url, fi->path);
+
if (flags & CAMEL_FOLDER_NOSELECT || fi->name[0] == 0)
camel_url_set_param (url, "noselect", "yes");
fi->url = camel_url_to_string (url, 0);
camel_url_free (url);
-
+
/* FIXME: redundant */
if (flags & CAMEL_IMAP_FOLDER_UNMARKED)
fi->unread_message_count = -1;
-
+
return fi;
}
@@ -1998,16 +1966,19 @@ get_subscribed_folders (CamelImapStore *imap_store, const char *top, CamelExcept
CamelImapResponse *response;
CamelFolderInfo *fi;
char *result;
+ int haveinbox = FALSE;
folders = g_ptr_array_new ();
names = g_ptr_array_new ();
for (i=0;(si = camel_store_summary_index((CamelStoreSummary *)imap_store->summary, i));i++) {
- if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)
+ if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
g_ptr_array_add(names, (char *)camel_imap_store_info_full_name(imap_store->summary, si));
+ haveinbox = haveinbox || strcasecmp(camel_imap_store_info_full_name(imap_store->summary, si), "INBOX") == 0;
+ }
camel_store_summary_info_free((CamelStoreSummary *)imap_store->summary, si);
}
-
- if (names->len == 0)
+
+ if (!haveinbox)
g_ptr_array_add (names, "INBOX");
for (i = 0; i < names->len; i++) {
@@ -2399,14 +2370,13 @@ get_folder_info_online (CamelStore *store, const char *top, guint32 flags, Camel
if (folders == NULL)
return NULL;
- /* note the weird top stuff, it is so a namespace based list "" is properly tree-ised */
- tree = camel_folder_info_build(folders, top[0] == 0 && imap_store->namespace?"":top, '/', TRUE);
+ tree = camel_folder_info_build(folders, top, '/', TRUE);
g_ptr_array_free(folders, TRUE);
if (!(flags & CAMEL_STORE_FOLDER_INFO_FAST))
get_folder_counts(imap_store, tree, ex);
- dumpfi(tree);
+ d(dumpfi(tree));
camel_store_summary_save((CamelStoreSummary *)imap_store->summary);
return tree;
diff --git a/camel/providers/imap/camel-imap-store.h b/camel/providers/imap/camel-imap-store.h
index 38df1880a0..d461b51440 100644
--- a/camel/providers/imap/camel-imap-store.h
+++ b/camel/providers/imap/camel-imap-store.h
@@ -114,6 +114,7 @@ struct _CamelImapStore {
/* Information about the server */
CamelImapServerLevel server_level;
guint32 capabilities, parameters;
+ /* NB: namespace should be handled by summary->namespace */
char *namespace, dir_sep, *base_url, *storage_path;
GHashTable *authtypes;