[evolution-data-server] I#402 - IMAPx: Unsubscribed folders in personal namespace hidden in offline



commit 2380982102ef01449f4664006575766900d38f21
Author: Milan Crha <mcrha redhat com>
Date:   Tue Jul 12 14:25:48 2022 +0200

    I#402 - IMAPx: Unsubscribed folders in personal namespace hidden in offline
    
    Closes https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/402

 .../providers/imapx/camel-imapx-store-summary.c    | 77 +++++++++++++---------
 .../providers/imapx/camel-imapx-store-summary.h    |  1 +
 src/camel/providers/imapx/camel-imapx-store.c      | 23 ++++---
 3 files changed, 59 insertions(+), 42 deletions(-)
---
diff --git a/src/camel/providers/imapx/camel-imapx-store-summary.c 
b/src/camel/providers/imapx/camel-imapx-store-summary.c
index 5901bdafa..9f4618957 100644
--- a/src/camel/providers/imapx/camel-imapx-store-summary.c
+++ b/src/camel/providers/imapx/camel-imapx-store-summary.c
@@ -31,17 +31,15 @@
 #define d(...) camel_imapx_debug(debug, '?', __VA_ARGS__)
 
 /* Version 0: Original IMAPX file format. */
-#define CAMEL_IMAPX_STORE_SUMMARY_VERSION_0 (0)
-
 /* Version 1: (3.10) Store the hierarchy separator. */
-#define CAMEL_IMAPX_STORE_SUMMARY_VERSION_1 (1);
+/* Version 2: (3.46) Store the in_personal_namespace. */
+#define CAMEL_IMAPX_STORE_SUMMARY_VERSION (2)
 
-#define CAMEL_IMAPX_STORE_SUMMARY_VERSION (1)
+typedef struct _CamelIMAPXStoreSummaryPrivate {
+       gint32 saved_version;
+} CamelIMAPXStoreSummaryPrivate;
 
-G_DEFINE_TYPE (
-       CamelIMAPXStoreSummary,
-       camel_imapx_store_summary,
-       CAMEL_TYPE_STORE_SUMMARY)
+G_DEFINE_TYPE_WITH_PRIVATE (CamelIMAPXStoreSummary, camel_imapx_store_summary, CAMEL_TYPE_STORE_SUMMARY)
 
 static gboolean
 namespace_load (FILE *in)
@@ -92,9 +90,12 @@ static gint
 imapx_store_summary_summary_header_load (CamelStoreSummary *summary,
                                          FILE *in)
 {
+       CamelIMAPXStoreSummaryPrivate *priv = camel_imapx_store_summary_get_instance_private 
(CAMEL_IMAPX_STORE_SUMMARY (summary));
        CamelStoreSummaryClass *store_summary_class;
        gint32 version, unused;
 
+       priv->saved_version = -1;
+
        store_summary_class =
                CAMEL_STORE_SUMMARY_CLASS (
                camel_imapx_store_summary_parent_class);
@@ -106,18 +107,22 @@ imapx_store_summary_summary_header_load (CamelStoreSummary *summary,
        if (camel_file_util_decode_fixed_int32 (in, &version) == -1)
                return -1;
 
-       if (version < CAMEL_IMAPX_STORE_SUMMARY_VERSION) {
+       if (version != CAMEL_IMAPX_STORE_SUMMARY_VERSION && version != 1) {
                g_warning ("IMAPx: Unable to load store summary: Expected version (%d), got (%d)",
                        CAMEL_IMAPX_STORE_SUMMARY_VERSION, version);
                return -1;
        }
 
-       if (camel_file_util_decode_fixed_int32 (in, &unused) == -1)
-               return -1;
+       if (version <= 1) {
+               if (camel_file_util_decode_fixed_int32 (in, &unused) == -1)
+                       return -1;
 
-       /* XXX This just eats old data that we no longer use. */
-       if (!namespace_load (in))
-               return -1;
+               /* XXX This just eats old data that we no longer use. */
+               if (!namespace_load (in))
+                       return -1;
+       }
+
+       priv->saved_version = version;
 
        return 0;
 }
@@ -126,6 +131,7 @@ static gint
 imapx_store_summary_summary_header_save (CamelStoreSummary *summary,
                                          FILE *out)
 {
+       CamelIMAPXStoreSummaryPrivate *priv = camel_imapx_store_summary_get_instance_private 
(CAMEL_IMAPX_STORE_SUMMARY (summary));
        CamelStoreSummaryClass *store_summary_class;
 
        store_summary_class =
@@ -141,21 +147,7 @@ imapx_store_summary_summary_header_save (CamelStoreSummary *summary,
                out, CAMEL_IMAPX_STORE_SUMMARY_VERSION) == -1)
                return -1;
 
-       if (camel_file_util_encode_fixed_int32 (out, 0) == -1)
-               return -1;
-
-       /* XXX This just saves zero-count namespace placeholders for
-        *     backward compatibility.  Next time we bump the summary
-        *     version, delete all this cruft. */
-
-       if (camel_file_util_encode_fixed_int32 (out, 0) == -1)
-               return -1;
-
-       if (camel_file_util_encode_fixed_int32 (out, 0) == -1)
-               return -1;
-
-       if (camel_file_util_encode_fixed_int32 (out, 0) == -1)
-               return -1;
+       priv->saved_version = CAMEL_IMAPX_STORE_SUMMARY_VERSION;
 
        return 0;
 }
@@ -164,10 +156,12 @@ static CamelStoreInfo *
 imapx_store_summary_store_info_load (CamelStoreSummary *summary,
                                      FILE *in)
 {
+       CamelIMAPXStoreSummaryPrivate *priv = camel_imapx_store_summary_get_instance_private 
(CAMEL_IMAPX_STORE_SUMMARY (summary));
        CamelStoreSummaryClass *store_summary_class;
        CamelStoreInfo *si;
        gchar *mailbox_name = NULL;
        gchar *separator = NULL;
+       gint32 in_personal_namespace = 0;
 
        store_summary_class =
                CAMEL_STORE_SUMMARY_CLASS (
@@ -189,6 +183,14 @@ imapx_store_summary_store_info_load (CamelStoreSummary *summary,
                return NULL;
        }
 
+       if (priv->saved_version >= 2 &&
+           camel_file_util_decode_fixed_int32 (in, &in_personal_namespace) == -1) {
+               camel_store_summary_info_unref (summary, si);
+               g_free (mailbox_name);
+               g_free (separator);
+               return NULL;
+       }
+
        camel_imapx_normalize_mailbox (mailbox_name, *separator);
 
        /* NB: this is done again for compatability */
@@ -199,6 +201,7 @@ imapx_store_summary_store_info_load (CamelStoreSummary *summary,
 
        ((CamelIMAPXStoreInfo *) si)->mailbox_name = mailbox_name;
        ((CamelIMAPXStoreInfo *) si)->separator = *separator;
+       ((CamelIMAPXStoreInfo *) si)->in_personal_namespace = in_personal_namespace != 0;
 
        g_free (separator);
 
@@ -213,6 +216,7 @@ imapx_store_summary_store_info_save (CamelStoreSummary *summary,
        CamelStoreSummaryClass *store_summary_class;
        gchar separator[] = { '\0', '\0' };
        const gchar *mailbox_name;
+       gint32 in_personal_namespace;
 
        store_summary_class =
                CAMEL_STORE_SUMMARY_CLASS (
@@ -220,6 +224,7 @@ imapx_store_summary_store_info_save (CamelStoreSummary *summary,
 
        mailbox_name = ((CamelIMAPXStoreInfo *) si)->mailbox_name;
        separator[0] = ((CamelIMAPXStoreInfo *) si)->separator;
+       in_personal_namespace = ((CamelIMAPXStoreInfo *) si)->in_personal_namespace ? 1 : 0;
 
        /* Chain up to parent's store_info_save() method. */
        if (store_summary_class->store_info_save (summary, out, si) == -1)
@@ -231,6 +236,9 @@ imapx_store_summary_store_info_save (CamelStoreSummary *summary,
        if (camel_file_util_encode_string (out, mailbox_name) == -1)
                return -1;
 
+       if (camel_file_util_encode_fixed_int32 (out, in_personal_namespace) == -1)
+               return -1;
+
        return 0;
 }
 
@@ -333,16 +341,24 @@ camel_imapx_store_summary_add_from_mailbox (CamelStoreSummary *summary,
        const gchar *mailbox_name;
        gchar *folder_path;
        gchar separator;
+       gboolean in_personal_namespace;
 
        g_return_val_if_fail (CAMEL_IS_IMAPX_STORE_SUMMARY (summary), NULL);
        g_return_val_if_fail (CAMEL_IS_IMAPX_MAILBOX (mailbox), NULL);
 
        mailbox_name = camel_imapx_mailbox_get_name (mailbox);
        separator = camel_imapx_mailbox_get_separator (mailbox);
+       in_personal_namespace = camel_imapx_namespace_get_category (camel_imapx_mailbox_get_namespace 
(mailbox)) == CAMEL_IMAPX_NAMESPACE_PERSONAL;
 
        info = camel_imapx_store_summary_mailbox (summary, mailbox_name);
-       if (info != NULL)
+       if (info != NULL) {
+               if ((!in_personal_namespace) != (!info->in_personal_namespace)) {
+                       info->in_personal_namespace = in_personal_namespace;
+
+                       camel_store_summary_touch (summary);
+               }
                return info;
+       }
 
        folder_path = camel_imapx_mailbox_to_folder_path (
                mailbox_name, separator);
@@ -358,6 +374,7 @@ camel_imapx_store_summary_add_from_mailbox (CamelStoreSummary *summary,
 
        info->mailbox_name = g_strdup (mailbox_name);
        info->separator = separator;
+       info->in_personal_namespace = in_personal_namespace;
 
        if (camel_imapx_mailbox_is_inbox (mailbox_name))
                info->info.flags |=
diff --git a/src/camel/providers/imapx/camel-imapx-store-summary.h 
b/src/camel/providers/imapx/camel-imapx-store-summary.h
index 390bb7484..632ac5a36 100644
--- a/src/camel/providers/imapx/camel-imapx-store-summary.h
+++ b/src/camel/providers/imapx/camel-imapx-store-summary.h
@@ -52,6 +52,7 @@ struct _CamelIMAPXStoreInfo {
        CamelStoreInfo info;
        gchar *mailbox_name;
        gchar separator;
+       gboolean in_personal_namespace;
 };
 
 struct _CamelIMAPXStoreSummary {
diff --git a/src/camel/providers/imapx/camel-imapx-store.c b/src/camel/providers/imapx/camel-imapx-store.c
index c1c7dce6f..09669afb2 100644
--- a/src/camel/providers/imapx/camel-imapx-store.c
+++ b/src/camel/providers/imapx/camel-imapx-store.c
@@ -595,6 +595,7 @@ imapx_store_process_mailbox_attributes (CamelIMAPXStore *store,
        CamelIMAPXStoreInfo *si;
        CamelStoreInfoFlags flags;
        CamelSettings *settings;
+       gboolean in_personal_namespace;
        gboolean use_subscriptions;
        gboolean mailbox_is_subscribed;
        gboolean mailbox_is_nonexistent;
@@ -624,6 +625,9 @@ imapx_store_process_mailbox_attributes (CamelIMAPXStore *store,
                camel_imapx_mailbox_has_attribute (
                mailbox, CAMEL_IMAPX_LIST_ATTR_NONEXISTENT);
 
+       in_personal_namespace = camel_imapx_namespace_get_category (
+               camel_imapx_mailbox_get_namespace (mailbox)) == CAMEL_IMAPX_NAMESPACE_PERSONAL;
+
        /* XXX The flags type transforms from CamelStoreInfoFlags
         *     to CamelFolderInfoFlags about half-way through this.
         *     We should really eliminate the confusing redundancy. */
@@ -649,8 +653,10 @@ imapx_store_process_mailbox_attributes (CamelIMAPXStore *store,
        }
 
        /* Check whether the flags disagree. */
-       if (si->info.flags != flags) {
+       if (si->info.flags != flags ||
+           (!si->in_personal_namespace) != (!in_personal_namespace)) {
                si->info.flags = flags;
+               si->in_personal_namespace = in_personal_namespace;
                camel_store_summary_touch (store->summary);
        }
 
@@ -1352,17 +1358,10 @@ get_folder_info_offline (CamelStore *store,
                        continue;
 
                if (!si_is_inbox && !use_subscriptions && !(si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) &&
-                   !(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST)) {
-                       CamelIMAPXMailbox *mailbox;
-
-                       mailbox = camel_imapx_store_ref_mailbox (imapx_store, ((CamelIMAPXStoreInfo *) 
si)->mailbox_name);
-                       if (!mailbox || camel_imapx_namespace_get_category (camel_imapx_mailbox_get_namespace 
(mailbox)) != CAMEL_IMAPX_NAMESPACE_PERSONAL) {
-                               /* Skip unsubscribed mailboxes which are not in the Personal namespace */
-                               g_clear_object (&mailbox);
-                               continue;
-                       }
-
-                       g_clear_object (&mailbox);
+                   !(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) &&
+                   !((CamelIMAPXStoreInfo *) si)->in_personal_namespace) {
+                       /* Skip unsubscribed mailboxes which are not in the Personal namespace */
+                       continue;
                }
 
                fi = imapx_store_build_folder_info (imapx_store, folder_path, 0);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]