Handle config_version update separately for accounts.
authorAndrej Kacian <ticho@claws-mail.org>
Sun, 6 Aug 2017 16:43:43 +0000 (18:43 +0200)
committerAndrej Kacian <ticho@claws-mail.org>
Thu, 14 Sep 2017 16:49:41 +0000 (18:49 +0200)
Instead of loading entire configuration from all the
files in rcdir and doing an update at the end, we
now upgrade each "part" right after we load it.

This is to allow greater flexibility during the time
not all of the configuration is loaded yet, e.g. folders
using correct folderclass functions, based on protocol
of account owning a particular folder.

This is currently affecting clawsrc and accountrc, but
it will be trivial to extend it to other rcdir files
as needed.

src/account.c
src/main.c
src/prefs_account.c
src/prefs_account.h
src/prefs_common.c
src/prefs_gtk.c
src/prefs_migration.c
src/prefs_migration.h

index a152ef6..11840ae 100644 (file)
@@ -1052,6 +1052,8 @@ static void account_clone(GtkWidget *widget, gpointer data)
        ac_clon->is_default = FALSE;
        ACP_FASSIGN(folder);
 
+       ACP_FASSIGN(config_version);
+
        account_list = g_list_append(account_list, ac_clon);
        account_list_view_set();
 }
index a35b94a..0c5c907 100644 (file)
@@ -1250,6 +1250,14 @@ int main(int argc, char *argv[])
        folder_system_init();
        prefs_common_read_config();
 
+       if (prefs_update_config_version_common() < 0) {
+               debug_print("Main configuration file version upgrade failed, exiting\n");
+#ifdef G_OS_WIN32
+               win32_close_log();
+#endif
+               exit(200);
+       }
+
        prefs_themes_init();
        prefs_fonts_init();
        prefs_ext_prog_init();
@@ -1326,6 +1334,14 @@ int main(int argc, char *argv[])
        prefs_account_init();
        account_read_config_all();
 
+       if (prefs_update_config_version_accounts() < 0) {
+               debug_print("Accounts configuration file version upgrade failed, exiting\n");
+#ifdef G_OS_WIN32
+               win32_close_log();
+#endif
+               exit(201);
+       }
+
 #ifdef HAVE_LIBETPAN
        imap_main_init(prefs_common.skip_ssl_cert_check);
        imap_main_set_timeout(prefs_common.io_timeout_secs);
@@ -1478,17 +1494,8 @@ int main(int argc, char *argv[])
        }
 
        if (never_ran) {
-               prefs_common_get_prefs()->config_version = CLAWS_CONFIG_VERSION;
                prefs_common_write_config();
                plugin_load_standard_plugins ();
-       } else {
-               if (prefs_update_config_version() < 0) {
-                       exit_claws(mainwin);
-#ifdef G_OS_WIN32
-                       win32_close_log();
-#endif
-                       exit(0);
-               }
        }
 
        /* if not crashed, show window now */
index 3ea0228..3d20cb4 100644 (file)
@@ -435,6 +435,9 @@ static PrefParam basic_param[] = {
        {"password", NULL, &tmp_ac_prefs.passwd, P_PASSWORD,
         NULL, NULL, NULL},
 
+       {"config_version", "-1", &tmp_ac_prefs.config_version, P_INT,
+               NULL, NULL, NULL},
+
        {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL}
 };
 
index fd4dc1a..39aed6f 100644 (file)
@@ -207,6 +207,8 @@ struct _PrefsAccount
        struct _Folder *folder;
        GHashTable *privacy_prefs;
        SMTPSession *session;
+
+       gint config_version;
 };
 
 void prefs_account_init                        (void);
index 8d5dbe0..5a5ee4f 100644 (file)
@@ -41,6 +41,7 @@
 #include "prefs_display_header.h"
 #include "prefs_summary_column.h"
 #include "prefs_folder_column.h"
+#include "prefs_migration.h"
 #include "mainwindow.h"
 #include "summaryview.h"
 #include "folderview.h"
index ca3051e..b5e28f3 100644 (file)
@@ -440,6 +440,8 @@ void prefs_set_default(PrefParam *param)
                        if (param[i].defval != NULL)
                                *((gint *)param[i].data) =
                                        (gint)atoi(param[i].defval);
+                       else if (!strcmp(param[i].name, "config_version"))
+                               *((gint *)param[i].data) = CLAWS_CONFIG_VERSION;
                        else
                                *((gint *)param[i].data) = 0;
                        break;
index cf8a103..6c8041b 100644 (file)
 #include "prefs_common.h"
 #include "alertpanel.h"
 
-static void _update_config(gint version)
+static gint starting_config_version = 0;
+
+gboolean _version_check(gint ver)
 {
-       GList *cur;
-       PrefsAccount *ac_prefs;
+       if (ver > CLAWS_CONFIG_VERSION) {
+               gchar *msg;
+               gchar *markup;
+               AlertValue av;
+
+               markup = g_strdup_printf(
+                       "<a href=\"%s\"><span underline=\"none\">",
+                       CONFIG_VERSIONS_URI);
+               msg = g_strdup_printf(
+                       _("Your Claws Mail configuration is from a newer "
+                         "version than the version which you are currently "
+                         "using.\n\n"
+                         "This is not recommended.\n\n"
+                         "For further information see the %sClaws Mail "
+                         "website%s.\n\n"
+                         "Do you want to exit now?"),
+                         markup, "</span></a>");
+               g_free(markup);
+               av = alertpanel_full(_("Configuration warning"), msg,
+                                       GTK_STOCK_NO, GTK_STOCK_YES, NULL,
+                                       FALSE, NULL,
+                                       ALERT_ERROR, G_ALERTALTERNATE);
+               g_free(msg);
+
+               if (av != G_ALERTDEFAULT)
+                       return FALSE; /* abort startup */
+
+               return TRUE; /* hic sunt dracones */
+       }
+
+       return TRUE;
+}
 
+static void _update_config_common(gint version)
+{
        debug_print("Updating config version %d to %d.\n", version, version + 1);
 
+       switch (version) {
+               case 1:
+
+                       /* The autochk_interval preference is now
+                        * interpreted as seconds instead of minutes */
+                       prefs_common.autochk_itv *= 60;
+
+                       break;
+
+               default:
+
+                       /* NOOP */
+
+                       break;
+       }
+}
+
+static void _update_config_account(PrefsAccount *ac_prefs, gint version)
+{
+       debug_print("Account '%s': Updating config version from %d to %d.\n",
+                       ac_prefs->account_name, version, version + 1);
+
        switch (version) {
                case 0:
 
@@ -54,64 +110,35 @@ static void _update_config(gint version)
                         * A_IMAP and the rest are from 3 up.
                         * We can't use the macros, since they may change in the
                         * future. Numbers do not change. :) */
-                       for (cur = account_get_list(); cur != NULL; cur = cur->next) {
-                               ac_prefs = (PrefsAccount *)cur->data;
-                               if (ac_prefs->protocol == 1) {
-                                       ac_prefs->protocol = 0;
-                               } else if (ac_prefs->protocol > 2) {
-                                       /* A_IMAP and above gets bumped down by 2. */
-                                       ac_prefs->protocol -= 2;
-                               }
+                       if (ac_prefs->protocol == 1) {
+                               ac_prefs->protocol = 0;
+                       } else if (ac_prefs->protocol > 2) {
+                               /* A_IMAP and above gets bumped down by 2. */
+                               ac_prefs->protocol -= 2;
                        }
 
                        break;
 
-               case 1:
+               default:
 
-                       /* The autochk_interval preference is now
-                        * interpreted as seconds instead of minutes */
-                       prefs_common.autochk_itv *= 60;
+                       /* NOOP */
 
                        break;
-
-               default:
-                       break;
        }
+
+       ac_prefs->config_version = version + 1;
 }
 
-int prefs_update_config_version()
+int prefs_update_config_version_common()
 {
        gint ver = prefs_common_get_prefs()->config_version;
 
-       if (ver > CLAWS_CONFIG_VERSION) {
-               gchar *msg;
-               gchar *markup;
-               AlertValue av;
-
-               markup = g_strdup_printf(
-                       "<a href=\"%s\"><span underline=\"none\">",
-                       CONFIG_VERSIONS_URI);
-               msg = g_strdup_printf(
-                       _("Your Claws Mail configuration is from a newer "
-                         "version than the version which you are currently "
-                         "using.\n\n"
-                         "This is not recommended.\n\n"
-                         "For further information see the %sClaws Mail "
-                         "website%s.\n\n"
-                         "Do you want to exit now?"),
-                         markup, "</span></a>");
-               g_free(markup);
-               av = alertpanel_full(_("Configuration warning"), msg,
-                                       GTK_STOCK_NO, GTK_STOCK_YES, NULL,
-                                       FALSE, NULL,
-                                       ALERT_ERROR, G_ALERTALTERNATE);
-               g_free(msg);
-
-               if (av != G_ALERTDEFAULT)
-                       return -1; /* abort startup */
+       /* Store the starting version number for other components'
+        * migration functions. */
+       starting_config_version = ver;
 
-               return 0; /* hic sunt dracones */
-       }
+       if (!_version_check(ver))
+               return -1;
 
        debug_print("Starting config update at config_version %d.\n", ver);
        if (ver == CLAWS_CONFIG_VERSION) {
@@ -120,10 +147,46 @@ int prefs_update_config_version()
        }
 
        while (ver < CLAWS_CONFIG_VERSION) {
-               _update_config(ver++);
+               _update_config_common(ver++);
                prefs_common_get_prefs()->config_version = ver;
        }
 
        debug_print("Config update done.\n");
        return 1; /* update done */
 }
+
+int prefs_update_config_version_accounts()
+{
+       GList *cur;
+       PrefsAccount *ac_prefs;
+
+       for (cur = account_get_list(); cur != NULL; cur = cur->next) {
+               ac_prefs = (PrefsAccount *)cur->data;
+
+               if (ac_prefs->config_version == -1) {
+                       /* There was no config_version stored in accountrc, let's assume
+                        * config_version same as clawsrc started at, to avoid breaking
+                        * this account by "upgrading" it unnecessarily. */
+                       debug_print("Account '%s': config_version not saved, using one from clawsrc: %d\n", ac_prefs->account_name, starting_config_version);
+                       ac_prefs->config_version = starting_config_version;
+               }
+
+               gint ver = ac_prefs->config_version;
+
+               debug_print("Account '%s': Starting config update at config_version %d.\n", ac_prefs->account_name, ver);
+
+               if (!_version_check(ver))
+                       return -1;
+
+               if (ver == CLAWS_CONFIG_VERSION) {
+                       debug_print("Account '%s': No update necessary, already at latest config_version.\n", ac_prefs->account_name);
+                       continue;
+               }
+
+               while (ver < CLAWS_CONFIG_VERSION) {
+                       _update_config_account(ac_prefs, ver++);
+               }
+       }
+
+       return 1;
+}
index e984096..31dc892 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef __PREFS_MIGRATION_H__
 #define __PREFS_MIGRATION_H__
 
-int prefs_update_config_version();
+int prefs_update_config_version_common();
+int prefs_update_config_version_accounts();
 
 #endif /* __PREFS_MIGRATION_H__ */