diff options
author | Jeffrey Stedfast <fejj@novell.com> | 2008-05-12 14:04:02 +0000 |
---|---|---|
committer | Jeffrey Stedfast <fejj@src.gnome.org> | 2008-05-12 14:04:02 +0000 |
commit | 19b882def5d95e0b1164df449de139c57b2c9e2e (patch) | |
tree | d8bb5d2ddc5cf19e81331350d20a1b7753cc41e7 | |
parent | 17c80f764ed29fd924e6c91b678542602c88f745 (diff) | |
download | evolution-data-server-19b882def5d95e0b1164df449de139c57b2c9e2e.tar.gz |
Properly handle empty folders.
2008-05-12 Jeffrey Stedfast <fejj@novell.com>
* camel-imap4-summary.c (camel_imap4_summary_flush_updates):
Properly handle empty folders.
* camel-imap4-store.c (connect_to_server): Disconnect the engine
if SSL negotiations fail (there's no other way for the engine to
know that failed).
* camel-imap4-engine.c (camel_imap4_engine_disconnect): New
convenience function.
2008-05-11 Jeffrey Stedfast <fejj@novell.com>
* camel-imap4-utils.c (camel_imap4_build_folder_info_tree): New
utility function.
* camel-imap4-store-summary.c (camel_imap4_store_summary_get_folder_info):
Use a custom imap4 routine to create a folderinfo tree.
* camel-imap4-summary.c (imap4_fetch_all_add): Need to ref the
CamelMessageInfo after adding to the summary because
camel_folder_summary_add() does not ref.
* camel-imap4-store.c: Define some symbols that might not exist in
the version of camel we are linking against.
(imap4_build_folder_info_tree): New function to build a tree
structure of CamelFolderInfo's from an array.
svn path=/trunk/; revision=8783
-rw-r--r-- | camel/providers/imap4/ChangeLog | 18 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-engine.c | 33 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-engine.h | 2 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-store-summary.c | 7 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-store.c | 80 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-summary.c | 4 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-utils.c | 67 | ||||
-rw-r--r-- | camel/providers/imap4/camel-imap4-utils.h | 3 |
8 files changed, 130 insertions, 84 deletions
diff --git a/camel/providers/imap4/ChangeLog b/camel/providers/imap4/ChangeLog index b4b8289ee..fb9a1a1d7 100644 --- a/camel/providers/imap4/ChangeLog +++ b/camel/providers/imap4/ChangeLog @@ -1,5 +1,23 @@ +2008-05-12 Jeffrey Stedfast <fejj@novell.com> + + * camel-imap4-summary.c (camel_imap4_summary_flush_updates): + Properly handle empty folders. + + * camel-imap4-store.c (connect_to_server): Disconnect the engine + if SSL negotiations fail (there's no other way for the engine to + know that failed). + + * camel-imap4-engine.c (camel_imap4_engine_disconnect): New + convenience function. + 2008-05-11 Jeffrey Stedfast <fejj@novell.com> + * camel-imap4-utils.c (camel_imap4_build_folder_info_tree): New + utility function. + + * camel-imap4-store-summary.c (camel_imap4_store_summary_get_folder_info): + Use a custom imap4 routine to create a folderinfo tree. + * camel-imap4-summary.c (imap4_fetch_all_add): Need to ref the CamelMessageInfo after adding to the summary because camel_folder_summary_add() does not ref. diff --git a/camel/providers/imap4/camel-imap4-engine.c b/camel/providers/imap4/camel-imap4-engine.c index 78ce87722..b15374eff 100644 --- a/camel/providers/imap4/camel-imap4-engine.c +++ b/camel/providers/imap4/camel-imap4-engine.c @@ -227,14 +227,33 @@ camel_imap4_engine_take_stream (CamelIMAP4Engine *engine, CamelStream *stream, C exception: + camel_imap4_engine_disconnect (engine); + + return -1; +} + + +/** + * camel_imap4_engine_disconnect: + * @engine: IMAP4 engine + * + * Closes the engine's connection to the IMAP4 server and sets state + * to #CAMEL_IMAP4_ENGINE_DISCONNECTED. + **/ +void +camel_imap4_engine_disconnect (CamelIMAP4Engine *engine) +{ engine->state = CAMEL_IMAP4_ENGINE_DISCONNECTED; - camel_object_unref (engine->istream); - engine->istream = NULL; - camel_object_unref (engine->ostream); - engine->ostream = NULL; + if (engine->istream) { + camel_object_unref (engine->istream); + engine->istream = NULL; + } - return -1; + if (engine->ostream) { + camel_object_unref (engine->ostream); + engine->ostream = NULL; + } } @@ -245,7 +264,7 @@ camel_imap4_engine_take_stream (CamelIMAP4Engine *engine, CamelStream *stream, C * * Forces the IMAP4 engine to query the IMAP4 server for a list of capabilities. * - * Returns 0 on success or -1 on fail. + * Returns %0 on success or %-1 on fail. **/ int camel_imap4_engine_capability (CamelIMAP4Engine *engine, CamelException *ex) @@ -1540,7 +1559,7 @@ camel_imap4_engine_dequeue (CamelIMAP4Engine *engine, CamelIMAP4Command *ic) * failure and updates the engine state to DISCONNECTED if the stream * gets disconencted. * - * Returns 0 on success or -1 on fail. + * Returns %0 on success or %-1 on fail. **/ int camel_imap4_engine_next_token (CamelIMAP4Engine *engine, camel_imap4_token_t *token, CamelException *ex) diff --git a/camel/providers/imap4/camel-imap4-engine.h b/camel/providers/imap4/camel-imap4-engine.h index de0a811cd..bd8aafa87 100644 --- a/camel/providers/imap4/camel-imap4-engine.h +++ b/camel/providers/imap4/camel-imap4-engine.h @@ -200,6 +200,8 @@ CamelIMAP4Engine *camel_imap4_engine_new (CamelService *service, CamelIMAP4Recon /* returns 0 on success or -1 on error */ int camel_imap4_engine_take_stream (CamelIMAP4Engine *engine, CamelStream *stream, CamelException *ex); +void camel_imap4_engine_disconnect (CamelIMAP4Engine *engine); + int camel_imap4_engine_capability (CamelIMAP4Engine *engine, CamelException *ex); int camel_imap4_engine_namespace (CamelIMAP4Engine *engine, CamelException *ex); diff --git a/camel/providers/imap4/camel-imap4-store-summary.c b/camel/providers/imap4/camel-imap4-store-summary.c index 96f10700a..92df4b694 100644 --- a/camel/providers/imap4/camel-imap4-store-summary.c +++ b/camel/providers/imap4/camel-imap4-store-summary.c @@ -353,14 +353,14 @@ store_info_to_folder_info (CamelStoreSummary *s, CamelStoreInfo *si) { CamelFolderInfo *fi; const char *name; - + fi = camel_folder_info_new (); fi->full_name = g_strdup (camel_store_info_path (s, si)); fi->uri = g_strdup (camel_store_info_uri (s, si)); fi->flags = si->flags; fi->unread = si->unread; fi->total = si->total; - + name = camel_store_info_name (s, si); if (!g_ascii_strcasecmp (fi->full_name, "INBOX")) { fi->flags |= CAMEL_FOLDER_SYSTEM | CAMEL_FOLDER_TYPE_INBOX; @@ -372,6 +372,7 @@ store_info_to_folder_info (CamelStoreSummary *s, CamelStoreInfo *si) return fi; } + CamelFolderInfo * camel_imap4_store_summary_get_folder_info (CamelIMAP4StoreSummary *s, const char *top, guint32 flags) { @@ -404,7 +405,7 @@ camel_imap4_store_summary_get_folder_info (CamelIMAP4StoreSummary *s, const char g_ptr_array_add (folders, store_info_to_folder_info (ss, si)); } - fi = camel_folder_info_build (folders, top, '/', TRUE); + fi = camel_imap4_build_folder_info_tree (folders, top); g_ptr_array_free (folders, TRUE); return fi; diff --git a/camel/providers/imap4/camel-imap4-store.c b/camel/providers/imap4/camel-imap4-store.c index 04b86037d..5ed81cc80 100644 --- a/camel/providers/imap4/camel-imap4-store.c +++ b/camel/providers/imap4/camel-imap4-store.c @@ -328,6 +328,7 @@ connect_to_server (CamelIMAP4Engine *engine, struct addrinfo *ai, int ssl_mode, camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, _("Failed to connect to IMAP server %s in secure mode: %s"), service->url->host, _("TLS negotiations failed")); + camel_imap4_engine_disconnect (engine); return FALSE; } @@ -859,22 +860,22 @@ imap4_folder_create (CamelStore *store, const char *folder_name, const char *sub CamelURL *url; const char *c; int id; - + CAMEL_SERVICE_REC_LOCK (store, connect_lock); - + utf7_name = imap4_folder_utf7_name (store, folder_name, '\0'); ic = camel_imap4_engine_queue (engine, NULL, "CREATE %S%s\r\n", utf7_name, subfolder_hint); g_free (utf7_name); - + 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); goto done; } - + switch (ic->result) { case CAMEL_IMAP4_RESULT_OK: url = camel_url_copy (engine->url); @@ -1336,73 +1337,6 @@ imap4_subscription_info (CamelStore *store, CamelFolderInfo *fi) } static CamelFolderInfo * -imap4_build_folder_info_tree (GPtrArray *array, const char *top) -{ - CamelFolderInfo *cur, *fi, *root = NULL; - const char *p; - size_t n = 0; - char *pname; - int i; - - if (array->len == 0) - return NULL; - - if (array->len == 1) - return array->pdata[0]; - - if (top) - n = strlen (top); - - cur = root = array->pdata[0]; - - for (i = 1; i < array->len; i++) { - fi = (CamelFolderInfo *) array->pdata[i]; - if (top && strncmp (fi->full_name, top, n) != 0) { - /* this folder info was not requested */ - camel_folder_info_free (fi); - continue; - } - - if ((p = strrchr (fi->full_name, '/'))) { - pname = g_strndup (fi->full_name, p - fi->full_name); - if (!strcmp (cur->full_name, pname)) { - /* cur is our parent */ - fi->parent = cur; - cur->child = fi; - cur = fi; - } else if (cur->parent && !strcmp (cur->parent->full_name, pname)) { - /* cur is our sibling */ - fi->parent = cur->parent; - cur->next = fi; - cur = fi; - } else { - /* search back for our parent */ - while (cur->parent) { - if (!strcmp (cur->parent->full_name, pname)) - break; - cur = cur->parent; - } - - /* cur should now be our sibling */ - fi->parent = cur->parent; - cur->next = fi; - cur = fi; - } - g_free (pname); - } else { - /* traverse back to most recent top-level fi */ - while (cur->parent) - cur = cur->parent; - - cur->next = fi; - cur = fi; - } - } - - return root; -} - -static CamelFolderInfo * imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtrArray *array) { CamelIMAP4Engine *engine = ((CamelIMAP4Store *) store)->engine; @@ -1478,7 +1412,7 @@ imap4_build_folder_info (CamelStore *store, const char *top, guint32 flags, GPtr g_free (list); } - fi = imap4_build_folder_info_tree (array, top); + fi = camel_imap4_build_folder_info_tree (array, top); camel_url_free (url); diff --git a/camel/providers/imap4/camel-imap4-summary.c b/camel/providers/imap4/camel-imap4-summary.c index cf052a571..e3bd0d89f 100644 --- a/camel/providers/imap4/camel-imap4-summary.c +++ b/camel/providers/imap4/camel-imap4-summary.c @@ -1304,6 +1304,7 @@ imap4_summary_fetch_flags (CamelFolderSummary *summary) engine = ((CamelIMAP4Store *) folder->parent_store)->engine; scount = camel_folder_summary_count (summary); + g_assert (scount > 0); info[0] = camel_folder_summary_index (summary, 0); if (scount > 1) @@ -1581,7 +1582,8 @@ camel_imap4_summary_flush_updates (CamelFolderSummary *summary, CamelException * summary->flags ^= CAMEL_IMAP4_SUMMARY_HAVE_MLIST; engine = ((CamelIMAP4Store *) summary->folder->parent_store)->engine; - scount = camel_folder_summary_count (summary); + if ((scount = camel_folder_summary_count (summary)) == 0) + imap4_summary->update_flags = FALSE; if (imap4_summary->uidvalidity_changed) { /* need to refetch everything */ diff --git a/camel/providers/imap4/camel-imap4-utils.c b/camel/providers/imap4/camel-imap4-utils.c index 2f81d0904..a479b3e60 100644 --- a/camel/providers/imap4/camel-imap4-utils.c +++ b/camel/providers/imap4/camel-imap4-utils.c @@ -44,6 +44,73 @@ #define d(x) +CamelFolderInfo * +camel_imap4_build_folder_info_tree (GPtrArray *array, const char *top) +{ + CamelFolderInfo *cur, *fi, *root = NULL; + const char *p; + size_t n = 0; + char *pname; + int i; + + if (array->len == 0) + return NULL; + + if (array->len == 1) + return array->pdata[0]; + + if (top) + n = strlen (top); + + cur = root = array->pdata[0]; + + for (i = 1; i < array->len; i++) { + fi = (CamelFolderInfo *) array->pdata[i]; + if (top && strncmp (fi->full_name, top, n) != 0) { + /* this folder info was not requested */ + camel_folder_info_free (fi); + continue; + } + + if ((p = strrchr (fi->full_name, '/'))) { + pname = g_strndup (fi->full_name, p - fi->full_name); + if (!strcmp (cur->full_name, pname)) { + /* cur is our parent */ + fi->parent = cur; + cur->child = fi; + cur = fi; + } else if (cur->parent && !strcmp (cur->parent->full_name, pname)) { + /* cur is our sibling */ + fi->parent = cur->parent; + cur->next = fi; + cur = fi; + } else { + /* search back for our parent */ + while (cur->parent) { + if (!strcmp (cur->parent->full_name, pname)) + break; + cur = cur->parent; + } + + /* cur should now be our sibling */ + fi->parent = cur->parent; + cur->next = fi; + cur = fi; + } + g_free (pname); + } else { + /* traverse back to most recent top-level fi */ + while (cur->parent) + cur = cur->parent; + + cur->next = fi; + cur = fi; + } + } + + return root; +} + void camel_imap4_flags_diff (flags_diff_t *diff, guint32 old, guint32 new) { diff --git a/camel/providers/imap4/camel-imap4-utils.h b/camel/providers/imap4/camel-imap4-utils.h index 00eb88b10..d67698809 100644 --- a/camel/providers/imap4/camel-imap4-utils.h +++ b/camel/providers/imap4/camel-imap4-utils.h @@ -40,6 +40,7 @@ guint32 camel_imap4_flags_merge (flags_diff_t *diff, guint32 flags); guint32 camel_imap4_merge_flags (guint32 original, guint32 local, guint32 server); +struct _CamelFolderInfo; struct _CamelIMAP4Engine; struct _CamelIMAP4Command; struct _CamelFolderSummary; @@ -48,6 +49,8 @@ struct _CamelIMAP4StoreSummary; struct _CamelIMAP4NamespaceList; struct _CamelIMAP4Namespace; +struct _CamelFolderInfo *camel_imap4_build_folder_info_tree (GPtrArray *array, const char *top); + void camel_imap4_namespace_clear (struct _CamelIMAP4Namespace **ns); struct _CamelIMAP4NamespaceList *camel_imap4_namespace_list_copy (const struct _CamelIMAP4NamespaceList *nsl); void camel_imap4_namespace_list_free (struct _CamelIMAP4NamespaceList *nsl); |