diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2010-03-03 04:00:01 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2010-03-30 07:04:00 +0800 |
commit | 797acc24457e34c29332d9f1be5bd19e84aab111 (patch) | |
tree | 6a7ffd65d824ffab78c50794bfc9b20bdfdd35af | |
parent | 3c1c071f490c2b090326b53c29540fff713af380 (diff) | |
download | gsoc2013-evolution-797acc24457e34c29332d9f1be5bd19e84aab111.tar gsoc2013-evolution-797acc24457e34c29332d9f1be5bd19e84aab111.tar.gz gsoc2013-evolution-797acc24457e34c29332d9f1be5bd19e84aab111.tar.bz2 gsoc2013-evolution-797acc24457e34c29332d9f1be5bd19e84aab111.tar.lz gsoc2013-evolution-797acc24457e34c29332d9f1be5bd19e84aab111.tar.xz gsoc2013-evolution-797acc24457e34c29332d9f1be5bd19e84aab111.tar.zst gsoc2013-evolution-797acc24457e34c29332d9f1be5bd19e84aab111.zip |
Drop support for migrating from Evolution < 2.0.
There's too much ancient, crufty code there that we can't realistically
support anymore. A workaround for those poor users still on 1.x is to
upgrade to some 2.x release first, then upgrade again to 3.x. An error
dialog explaining this will be shown at startup.
-rw-r--r-- | doc/reference/shell/tmpl/e-util.sgml | 28 | ||||
-rw-r--r-- | e-util/Makefile.am | 4 | ||||
-rw-r--r-- | e-util/e-bconf-map.c | 537 | ||||
-rw-r--r-- | e-util/e-bconf-map.h | 95 | ||||
-rw-r--r-- | e-util/e-file-utils.c | 105 | ||||
-rw-r--r-- | e-util/e-file-utils.h | 3 | ||||
-rw-r--r-- | e-util/e-folder-map.c | 187 | ||||
-rw-r--r-- | e-util/e-folder-map.h | 36 | ||||
-rw-r--r-- | mail/e-mail-migrate.c | 2331 | ||||
-rw-r--r-- | mail/mail-vfolder.c | 14 | ||||
-rw-r--r-- | modules/addressbook/e-book-shell-migrate.c | 1011 | ||||
-rw-r--r-- | modules/calendar/e-cal-shell-migrate.c | 555 | ||||
-rw-r--r-- | modules/calendar/e-task-shell-migrate.c | 495 | ||||
-rw-r--r-- | shell/Makefile.am | 4 | ||||
-rw-r--r-- | shell/e-config-upgrade.c | 162 | ||||
-rw-r--r-- | shell/e-config-upgrade.h | 29 | ||||
-rw-r--r-- | shell/e-shell-migrate.c | 194 | ||||
-rw-r--r-- | shell/main.c | 29 | ||||
-rw-r--r-- | shell/shell.error.xml | 40 |
19 files changed, 46 insertions, 5813 deletions
diff --git a/doc/reference/shell/tmpl/e-util.sgml b/doc/reference/shell/tmpl/e-util.sgml index 82be9d041b..beae9b9258 100644 --- a/doc/reference/shell/tmpl/e-util.sgml +++ b/doc/reference/shell/tmpl/e-util.sgml @@ -346,16 +346,6 @@ Miscellaneous Utilities @Returns: -<!-- ##### FUNCTION e_folder_map_local_folders ##### --> -<para> - -</para> - -@local_dir: -@type: -@Returns: - - <!-- ##### FUNCTION e_file_replace_contents_async ##### --> <para> @@ -384,24 +374,6 @@ Miscellaneous Utilities @Returns: -<!-- ##### FUNCTION e_fsutils_usage ##### --> -<para> - -</para> - -@path: -@Returns: - - -<!-- ##### FUNCTION e_fsutils_avail ##### --> -<para> - -</para> - -@path: -@Returns: - - <!-- ##### FUNCTION e_mktemp ##### --> <para> diff --git a/e-util/Makefile.am b/e-util/Makefile.am index 99f873cbd8..3a9c723ec1 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -15,7 +15,6 @@ eutilinclude_HEADERS = \ e-alert.h \ e-alert-activity.h \ e-alert-dialog.h \ - e-bconf-map.h \ e-binding.h \ e-bit-array.h \ e-categories-config.h \ @@ -28,7 +27,6 @@ eutilinclude_HEADERS = \ e-extensible.h \ e-extension.h \ e-file-utils.h \ - e-folder-map.h \ e-html-utils.h \ e-icon-factory.h \ e-import.h \ @@ -95,7 +93,6 @@ libeutil_la_SOURCES = \ e-alert.c \ e-alert-activity.c \ e-alert-dialog.c \ - e-bconf-map.c \ e-binding.c \ e-bit-array.c \ e-categories-config.c \ @@ -108,7 +105,6 @@ libeutil_la_SOURCES = \ e-extensible.c \ e-extension.c \ e-file-utils.c \ - e-folder-map.c \ e-html-utils.c \ e-icon-factory.c \ e-import.c \ diff --git a/e-util/e-bconf-map.c b/e-util/e-bconf-map.c deleted file mode 100644 index d0bd526715..0000000000 --- a/e-util/e-bconf-map.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <glib.h> - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include "e-bconf-map.h" - -#define d(x) - -static gchar hexnib[256] = { - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1, - -1,10,11,12,13,14,15,16,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,10,11,12,13,14,15,16,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -}; - -gchar * -e_bconf_hex_decode (const gchar *val) -{ - const guchar *p; - gchar *o, *res; - - o = res = g_malloc (strlen (val) / 2 + 1); - for (p = (const guchar *)val; (p[0] && p[1]); p += 2) - *o++ = (hexnib[p[0]] << 4) | hexnib[p[1]]; - *o = 0; - - return res; -} - -gchar * -e_bconf_url_decode (const gchar *val) -{ - const guchar *p = (const guchar *) val; - gchar *o, *res, c; - - o = res = g_malloc (strlen (val) + 1); - while (*p) { - c = *p++; - if (c == '%' - && hexnib[p[0]] != -1 && hexnib[p[1]] != -1) { - *o++ = (hexnib[p[0]] << 4) | hexnib[p[1]]; - p+=2; - } else - *o++ = c; - } - *o = 0; - - return res; -} - -xmlNodePtr -e_bconf_get_path (xmlDocPtr doc, const gchar *path) -{ - xmlNodePtr root; - gchar *val; - gint found; - - root = doc->children; - if (strcmp ((gchar *)root->name, "bonobo-config") != 0) { - g_warning ("not bonobo-config xml file"); - return NULL; - } - - root = root->children; - while (root) { - if (!strcmp ((gchar *)root->name, "section")) { - val = (gchar *)xmlGetProp (root, (const guchar *)"path"); - found = val && strcmp (val, path) == 0; - xmlFree (val); - if (found) - break; - } - root = root->next; - } - - return root; -} - -xmlNodePtr -e_bconf_get_entry (xmlNodePtr root, const gchar *name) -{ - xmlNodePtr node = root->children; - gint found; - gchar *val; - - while (node) { - if (!strcmp ((gchar *)node->name, "entry")) { - val = (gchar *)xmlGetProp (node, (const guchar *)"name"); - found = val && strcmp (val, name) == 0; - xmlFree (val); - if (found) - break; - } - node = node->next; - } - - return node; -} - -gchar * -e_bconf_get_value (xmlNodePtr root, const gchar *name) -{ - xmlNodePtr node = e_bconf_get_entry (root, name); - gchar *prop, *val = NULL; - - if (node && (prop = (gchar *)xmlGetProp (node, (const guchar *)"value"))) { - val = g_strdup (prop); - xmlFree (prop); - } - - return val; -} - -gchar * -e_bconf_get_bool (xmlNodePtr root, const gchar *name) -{ - gchar *val, *res; - - if ((val = e_bconf_get_value (root, name))) { - res = g_strdup (val[0] == '1' ? "true" : "false"); - g_free (val); - } else - res = NULL; - - return res; -} - -gchar * -e_bconf_get_long (xmlNodePtr root, const gchar *name) -{ - gchar *val, *res; - - if ((val = e_bconf_get_value (root, name))) { - res = g_strdup (val); - g_free (val); - } else - res = NULL; - - return res; -} - -gchar * -e_bconf_get_string (xmlNodePtr root, const gchar *name) -{ - gchar *val, *res; - - if ((val = e_bconf_get_value (root, name))) { - res = e_bconf_hex_decode (val); - g_free (val); - } else - res = NULL; - - return res; -} - -/* lookup functions */ -typedef gchar * (* bconf_lookup_func) (xmlNodePtr root, const gchar *name, e_bconf_map_t *nap); - -static gchar * -bconf_lookup_bool (xmlNodePtr root, const gchar *name, e_bconf_map_t *map) -{ - return e_bconf_get_bool (root, name); -} - -static gchar * -bconf_lookup_long (xmlNodePtr root, const gchar *name, e_bconf_map_t *map) -{ - return e_bconf_get_long (root, name); -} - -static gchar * -bconf_lookup_string (xmlNodePtr root, const gchar *name, e_bconf_map_t *map) -{ - return e_bconf_get_string (root, name); -} - -static gchar * -bconf_lookup_enum (xmlNodePtr root, const gchar *name, e_bconf_map_t *map) -{ - gint index = 0, i; - gchar *val; - - if ((val = e_bconf_get_value (root, name))) { - index = atoi (val); - g_free (val); - } - - for (i = 0; map->child[i].from; i++) { - if (i == index) - return g_strdup (map->child[i].from); - } - - return NULL; -} - -static bconf_lookup_func lookup_table[] = { - bconf_lookup_bool, bconf_lookup_long, bconf_lookup_string, bconf_lookup_enum -}; - -static gchar * -get_name (const gchar *in, gint index) -{ - GString *out = g_string_new (""); - gchar c, *res; - - while ((c = *in++)) { - if (c == '%') { - c = *in++; - switch (c) { - case '%': - g_string_append_c (out, '%'); - break; - case 'i': - g_string_append_printf (out, "%d", index); - break; - } - } else { - g_string_append_c (out, c); - } - } - - res = out->str; - g_string_free (out, FALSE); - - return res; -} - -static void -build_xml (xmlNodePtr root, e_bconf_map_t *map, gint index, xmlNodePtr source) -{ - gchar *name, *value; - xmlNodePtr node; - - while (map->type != E_BCONF_MAP_END) { - if ((map->type & E_BCONF_MAP_MASK) == E_BCONF_MAP_CHILD) { - node = xmlNewChild (root, NULL, (guchar *)map->to, NULL); - build_xml (node, map->child, index, source); - } else { - name = get_name (map->from, index); - value = lookup_table[(map->type & E_BCONF_MAP_MASK) - 1] (source, name, map); - - d(printf ("key '%s=%s' -> ", name, value)); - - if (map->type & E_BCONF_MAP_CONTENT) { - if (value && value[0]) - xmlNewTextChild (root, NULL, (guchar *)map->to, (guchar *)value); - } else { - xmlSetProp (root, (guchar *)map->to, (guchar *)value); - } - - g_free (value); - g_free (name); - } - map++; - } -} - -gint -e_bconf_import_xml_blob (GConfClient *gconf, xmlDocPtr config_xmldb, e_bconf_map_t *map, - const gchar *bconf_path, const gchar *gconf_path, - const gchar *name, const gchar *idparam) -{ - xmlNodePtr source; - gint count = 0, i; - GSList *list, *l; - gchar *val; - - source = e_bconf_get_path (config_xmldb, bconf_path); - if (source) { - list = NULL; - if ((val = e_bconf_get_value (source, "num"))) { - count = atoi (val); - g_free (val); - } - - d(printf("Found %d blobs at %s\n", count, bconf_path)); - - for (i = 0; i < count; i++) { - xmlDocPtr doc; - xmlNodePtr root; - xmlChar *xmlbuf; - gint n; - - doc = xmlNewDoc ((const guchar *)"1.0"); - root = xmlNewDocNode (doc, NULL, (guchar *)name, NULL); - xmlDocSetRootElement (doc, root); - - /* This could be set with a MAP_UID type ... */ - if (idparam) { - gchar buf[16]; - - sprintf (buf, "%d", i); - xmlSetProp (root, (guchar *)idparam, (guchar *)buf); - } - - build_xml (root, map, i, source); - - xmlDocDumpMemory (doc, &xmlbuf, &n); - xmlFreeDoc (doc); - - list = g_slist_append (list, xmlbuf); - } - - gconf_client_set_list (gconf, gconf_path, GCONF_VALUE_STRING, list, NULL); - - while (list) { - l = list->next; - xmlFree (list->data); - g_slist_free_1 (list); - list = l; - } - } else { - g_warning ("could not find '%s' in old config database, skipping", bconf_path); - } - - return 0; -} - -static gint gconf_type[] = { GCONF_VALUE_BOOL, GCONF_VALUE_BOOL, GCONF_VALUE_INT, GCONF_VALUE_STRING, GCONF_VALUE_STRING }; - -gint -e_bconf_import (GConfClient *gconf, xmlDocPtr config_xmldb, e_gconf_map_list_t *remap_list) -{ - gchar *path, *val, *tmp; - e_gconf_map_t *map; - xmlNodePtr source; - GSList *list, *l; - gchar buf[32]; - gint i, j, k; - - /* process all flat config */ - for (i = 0; remap_list[i].root; i++) { - d(printf ("Path: %s\n", remap_list[i].root)); - if (!(source = e_bconf_get_path (config_xmldb, remap_list[i].root))) - continue; - - map = remap_list[i].map; - for (j = 0; map[j].from; j++) { - if (map[j].type & E_GCONF_MAP_LIST) { - /* collapse a multi-entry indexed field into a list */ - list = NULL; - k = 0; - do { - path = get_name (map[j].from, k); - val = e_bconf_get_value (source, path); - d(printf ("finding path '%s' = '%s'\n", path, val)); - g_free (path); - if (val) { - switch (map[j].type & E_GCONF_MAP_MASK) { - case E_GCONF_MAP_BOOL: - case E_GCONF_MAP_INT: - list = g_slist_append (list, GINT_TO_POINTER (atoi (val))); - break; - case E_GCONF_MAP_STRING: - d(printf (" -> '%s'\n", e_bconf_hex_decode (val))); - list = g_slist_append (list, e_bconf_hex_decode (val)); - break; - } - - g_free (val); - k++; - } - } while (val); - - if (list) { - path = g_strdup_printf ("/apps/evolution/%s", map[j].to); - gconf_client_set_list (gconf, path, gconf_type[map[j].type & E_GCONF_MAP_MASK], list, NULL); - g_free (path); - if ((map[j].type & E_GCONF_MAP_MASK) == E_GCONF_MAP_STRING) - g_slist_foreach (list, (GFunc) g_free, NULL); - g_slist_free (list); - } - - continue; - } else if (map[j].type == E_GCONF_MAP_ANYLIST) { - val = NULL; - } else { - if (!(val = e_bconf_get_value (source, map[j].from))) - continue; - } - - d(printf (" %s = '%s' -> %s [%d]\n", - map[j].from, - val == NULL ? "(null)" : val, - map[j].to, - map[j].type)); - - path = g_strdup_printf ("/apps/evolution/%s", map[j].to); - switch (map[j].type) { - case E_GCONF_MAP_BOOL: - gconf_client_set_bool (gconf, path, atoi (val), NULL); - break; - case E_GCONF_MAP_BOOLNOT: - gconf_client_set_bool (gconf, path, !atoi (val), NULL); - break; - case E_GCONF_MAP_INT: - gconf_client_set_int (gconf, path, atoi (val), NULL); - break; - case E_GCONF_MAP_STRING: - tmp = e_bconf_hex_decode (val); - gconf_client_set_string (gconf, path, tmp, NULL); - g_free (tmp); - break; - case E_GCONF_MAP_SIMPLESTRING: - gconf_client_set_string (gconf, path, val, NULL); - break; - case E_GCONF_MAP_FLOAT: - gconf_client_set_float (gconf, path, strtod (val, NULL), NULL); - break; - case E_GCONF_MAP_STRLIST: { - gchar *v = e_bconf_hex_decode (val); - gchar **t = g_strsplit (v, " !<-->!", 8196); - - list = NULL; - for (k = 0; t[k]; k++) { - list = g_slist_append (list, t[k]); - d(printf (" [%d] = '%s'\n", k, t[k])); - } - - gconf_client_set_list (gconf, path, GCONF_VALUE_STRING, list, NULL); - g_slist_free (list); - g_strfreev (t); - g_free (v); - break; } - case E_GCONF_MAP_ANYLIST: { - xmlNodePtr node = source->children; - list = NULL; - - /* find the entry node */ - while (node) { - if (!strcmp ((gchar *)node->name, "entry")) { - gint found; - - if ((tmp = (gchar *)xmlGetProp (node, (const guchar *)"name"))) { - found = strcmp ((gchar *)tmp, map[j].from) == 0; - xmlFree (tmp); - if (found) - break; - } - } - - node = node->next; - } - - /* find the the any block */ - if (node) { - node = node->children; - while (node) { - if (strcmp ((gchar *)node->name, "any") == 0) - break; - node = node->next; - } - } - - /* skip to the value inside it */ - if (node) { - node = node->children; - while (node) { - if (strcmp ((gchar *)node->name, "value") == 0) - break; - node = node->next; - } - } - - if (node) { - node = node->children; - while (node) { - if (strcmp ((gchar *)node->name, "value") == 0) - list = g_slist_append (list, xmlNodeGetContent (node)); - node = node->next; - } - } - - /* & store */ - if (list) { - gconf_client_set_list (gconf, path, GCONF_VALUE_STRING, list, NULL); - while (list) { - l = list->next; - xmlFree (list->data); - g_slist_free_1 (list); - list = l; - } - } - - break; } - case E_GCONF_MAP_COLOUR: - sprintf (buf, "#%06x", atoi (val) & 0xffffff); - gconf_client_set_string (gconf, path, buf, NULL); - break; - } - - /* FIXME: handle errors */ - g_free (path); - g_free (val); - } - } - - return 0; -} diff --git a/e-util/e-bconf-map.h b/e-util/e-bconf-map.h deleted file mode 100644 index 181533dde4..0000000000 --- a/e-util/e-bconf-map.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_BCONF_MAP_H__ -#define __E_BCONF_MAP_H__ - -#include <gconf/gconf-client.h> - -#include <libxml/tree.h> - -G_BEGIN_DECLS - -enum { - E_BCONF_MAP_END = 0, /* end of table */ - E_BCONF_MAP_BOOL, /* bool -> prop of name 'to' value true or false */ - E_BCONF_MAP_LONG, /* long -> prop of name 'to' value a long */ - E_BCONF_MAP_STRING, /* string -> prop of name 'to' */ - E_BCONF_MAP_ENUM, /* long/bool -> prop of name 'to', with the value indexed into the child map table's from field */ - E_BCONF_MAP_CHILD, /* a new child of name 'to' */ - E_BCONF_MAP_MASK = 0x3f, - E_BCONF_MAP_CONTENT = 0x80 /* if set, create a new node of name 'to' instead of a property */ -}; - -typedef struct _e_bconf_map { - const gchar *from; - const gchar *to; - gint type; - struct _e_bconf_map *child; -} e_bconf_map_t; - -gchar *e_bconf_hex_decode (const gchar *val); -gchar *e_bconf_url_decode (const gchar *val); - -xmlNodePtr e_bconf_get_path (xmlDocPtr doc, const gchar *path); -xmlNodePtr e_bconf_get_entry (xmlNodePtr root, const gchar *name); - -gchar *e_bconf_get_value (xmlNodePtr root, const gchar *name); -gchar *e_bconf_get_bool (xmlNodePtr root, const gchar *name); -gchar *e_bconf_get_long (xmlNodePtr root, const gchar *name); -gchar *e_bconf_get_string (xmlNodePtr root, const gchar *name); - -gint e_bconf_import_xml_blob (GConfClient *gconf, xmlDocPtr config_xmldb, e_bconf_map_t *map, - const gchar *bconf_path, const gchar *gconf_path, - const gchar *name, const gchar *idparam); - -enum { - E_GCONF_MAP_BOOL, - E_GCONF_MAP_BOOLNOT, - E_GCONF_MAP_INT, - E_GCONF_MAP_STRING, - E_GCONF_MAP_SIMPLESTRING, /* a non-encoded string */ - E_GCONF_MAP_COLOUR, - E_GCONF_MAP_FLOAT, /* bloody floats, who uses floats ... idiots */ - E_GCONF_MAP_STRLIST, /* strings separated to !<-->! -> gconf list */ - E_GCONF_MAP_ANYLIST, /* corba sequence corba string -> gconf list */ - E_GCONF_MAP_MASK = 0x7f, - E_GCONF_MAP_LIST = 0x80 /* from includes a %i field for the index of the key, to be converted to a list of type MAP_* */ -}; - -typedef struct { - const gchar *from; - const gchar *to; - gint type; -} e_gconf_map_t; - -typedef struct { - const gchar *root; - e_gconf_map_t *map; -} e_gconf_map_list_t; - -gint e_bconf_import (GConfClient *gconf, xmlDocPtr config_xmldb, e_gconf_map_list_t *remap_list); - -G_END_DECLS - -#endif /* __E_BCONF_MAP_H__ */ diff --git a/e-util/e-file-utils.c b/e-util/e-file-utils.c index 571154733b..e647b8deb1 100644 --- a/e-util/e-file-utils.c +++ b/e-util/e-file-utils.c @@ -210,108 +210,3 @@ e_file_replace_contents_finish (GFile *file, return TRUE; } -/** - * e_fsutils_usage: - * @path: a file path - * - * Calculate the amount of disk space used by a given path. - * - * Return value: The number of 1024 byte blocks used by the - * filesystem. - **/ -glong e_fsutils_usage(const gchar *inpath) -{ - GDir *dir; - const gchar *d; - long size = 0; - GSList *paths; - - /* iterative, depth-first scan, because i can ... */ - paths = g_slist_prepend(NULL, g_strdup(inpath)); - - while (paths) { - gchar *path = paths->data; - - paths = g_slist_remove_link(paths, paths); - - dir = g_dir_open(path, 0, NULL); - if (dir == NULL) { - g_free(path); - goto fail; - } - - while ((d = g_dir_read_name(dir))) { - gchar *full_path; - struct stat st; - - full_path = g_build_filename(path, d, NULL); - if (g_stat(full_path, &st) == -1) { - g_free(full_path); - g_dir_close(dir); - g_free(path); - goto fail; - } else if (S_ISDIR(st.st_mode)) { - paths = g_slist_prepend(paths, full_path); - full_path = NULL; - } else if (S_ISREG(st.st_mode)) { - /* This is in 512 byte blocks. st_blksize is page size on linux, - on *BSD it might be significant. */ -#ifndef G_OS_WIN32 - size += st.st_blocks/2; -#endif - } - - g_free(full_path); - } - - g_dir_close(dir); - g_free(path); - } - - return size; - -fail: - g_slist_foreach(paths, (GFunc)g_free, NULL); - g_slist_free(paths); - - return -1; -} - -/** - * e_fsutils_avail: - * @path: a file path - * - * Find the available disk space at the given path. - * - * Return value: -1 if it could not be determined, otherwise the - * number of disk blocks, expressed as system-independent, 1024 byte - * blocks. - **/ -glong -e_fsutils_avail(const gchar *path) -{ -#if defined(HAVE_STATVFS) - struct statvfs stfs; - - if (statvfs(path, &stfs) == -1) - return -1; - - /* Assumes that frsize === power of 2 */ - if (stfs.f_frsize >= 1024) - return stfs.f_bavail * (stfs.f_frsize / 1024); - else - return stfs.f_bavail / (1024 / stfs.f_frsize); -#elif defined(HAVE_STATFS) - struct statfs stfs; - - if (statfs(path, &stfs) == -1) - return -1; - - /* For BSD this isn't clear, it may be dependent on f_bsize */ - return stfs.f_bavail / 2; -#else - errno = ENOSYS; - return -1; -#endif -} - diff --git a/e-util/e-file-utils.h b/e-util/e-file-utils.h index 147b9b5b79..e1e8b29872 100644 --- a/e-util/e-file-utils.h +++ b/e-util/e-file-utils.h @@ -41,9 +41,6 @@ gboolean e_file_replace_contents_finish (GFile *file, gchar **new_etag, GError **error); -glong e_fsutils_usage (const gchar *path); -glong e_fsutils_avail (const gchar *path); - G_END_DECLS #endif /* E_FILE_UTILS_H */ diff --git a/e-util/e-folder-map.c b/e-util/e-folder-map.c deleted file mode 100644 index 7d775bed8a..0000000000 --- a/e-util/e-folder-map.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> - -#include <libedataserver/e-xml-utils.h> - -#include "e-folder-map.h" - -#define d(x) - -static gboolean -is_type_folder (const gchar *metadata, const gchar *search_type) -{ - xmlNodePtr node; - xmlDocPtr doc; - gchar *type; - - doc = e_xml_parse_file (metadata); - if (!doc) { - g_warning ("Cannot parse '%s'", metadata); - return FALSE; - } - - if (!(node = xmlDocGetRootElement (doc))) { - g_warning ("'%s' corrupt: document contains no root node", metadata); - xmlFreeDoc (doc); - return FALSE; - } - - if (!node->name || strcmp ((gchar *)node->name, "efolder") != 0) { - g_warning ("'%s' corrupt: root node is not 'efolder'", metadata); - xmlFreeDoc (doc); - return FALSE; - } - - node = node->children; - while (node != NULL) { - if (node->name && !strcmp ((gchar *)node->name, "type")) { - type = (gchar *)xmlNodeGetContent (node); - if (!strcmp (type, search_type)) { - xmlFreeDoc (doc); - xmlFree (type); - - return TRUE; - } - - xmlFree (type); - - break; - } - - node = node->next; - } - - xmlFreeDoc (doc); - - return FALSE; -} - -static void -e_folder_map_dir (const gchar *dirname, const gchar *type, GSList **dir_list) -{ - gchar *path; - const gchar *name; - GDir *dir; - GError *error = NULL; - - path = g_build_filename (dirname, "folder-metadata.xml", NULL); - if (!g_file_test (path, G_FILE_TEST_IS_REGULAR)) { - g_free (path); - return; - } - - if (!is_type_folder (path, type)) { - g_free (path); - goto try_subdirs; - } - - d(g_message ("Found '%s'", dirname)); - *dir_list = g_slist_prepend (*dir_list, g_strdup (dirname)); - - g_free (path); - - try_subdirs: - - path = g_build_filename (dirname, "subfolders", NULL); - if (!g_file_test (path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { - g_free (path); - return; - } - - if (!(dir = g_dir_open (path, 0, &error))) { - g_warning ("cannot open '%s': %s", path, error->message); - g_error_free (error); - g_free (path); - return; - } - - while ((name = g_dir_read_name (dir))) { - gchar *full_path; - - if (*name == '.') - continue; - - full_path = g_build_filename (path, name, NULL); - if (!g_file_test (full_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { - g_free (full_path); - continue; - } - - e_folder_map_dir (full_path, type, dir_list); - g_free (full_path); - } - - g_dir_close (dir); - - g_free (path); -} - -GSList * -e_folder_map_local_folders (const gchar *local_dir, const gchar *type) -{ - const gchar *name; - GDir *dir; - GSList *dir_list = NULL; - GError *error = NULL; - - if (!(dir = g_dir_open (local_dir, 0, &error))) { - g_warning ("cannot open '%s': %s", local_dir, error->message); - g_error_free (error); - return NULL; - } - - while ((name = g_dir_read_name (dir))) { - gchar *full_path; - - if (*name == '.') - continue; - - full_path = g_build_filename (local_dir, name, NULL); - d(g_message ("Looking in %s", full_path)); - if (!g_file_test (full_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { - g_free (full_path); - continue; - } - - e_folder_map_dir (full_path, type, &dir_list); - - g_free (full_path); - } - - g_dir_close (dir); - - return dir_list; -} diff --git a/e-util/e-folder-map.h b/e-util/e-folder-map.h deleted file mode 100644 index 3f41838882..0000000000 --- a/e-util/e-folder-map.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Jeffrey Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef __E_FOLDER_MAP_H__ -#define __E_FOLDER_MAP_H__ - -#include <glib.h> - -G_BEGIN_DECLS - -GSList * e_folder_map_local_folders (const gchar *local_dir, - const gchar *type); - -G_END_DECLS - -#endif /* __E_FOLDER_MAP_H__ */ diff --git a/mail/e-mail-migrate.c b/mail/e-mail-migrate.c index 98eef5a927..3659c73466 100644 --- a/mail/e-mail-migrate.c +++ b/mail/e-mail-migrate.c @@ -57,7 +57,6 @@ #include <e-util/e-xml-utils.h> #include "e-util/e-account-utils.h" -#include "e-util/e-bconf-map.h" #include "e-util/e-alert-dialog.h" #include "e-util/e-util-private.h" #include "e-util/e-plugin.h" @@ -72,969 +71,13 @@ #define d(x) x -#ifndef G_OS_WIN32 -/* No versions previous to 2.8 or thereabouts have been available on - * Windows, so don't bother with upgrade support from earlier versions - * on Win32. Do try to support upgrades from 2.12 and later to the - * current version. - */ - -/* upgrade helper functions */ -static xmlDocPtr -emm_load_xml (const gchar *dirname, const gchar *filename) -{ - xmlDocPtr doc; - struct stat st; - gchar *path; - - path = g_strdup_printf ("%s/%s", dirname, filename); - if (stat (path, &st) == -1 || !(doc = xmlParseFile (path))) { - g_free (path); - return NULL; - } - - g_free (path); - - return doc; -} - -static gint -emm_save_xml (xmlDocPtr doc, const gchar *dirname, const gchar *filename) -{ - gchar *path; - gint retval; - - path = g_strdup_printf ("%s/%s", dirname, filename); - retval = e_xml_save_file (path, doc); - g_free (path); - - return retval; -} - -static xmlNodePtr -xml_find_node (xmlNodePtr parent, const gchar *name) -{ - xmlNodePtr node; - - node = parent->children; - while (node != NULL) { - if (node->name && !strcmp ((gchar *)node->name, name)) - return node; - - node = node->next; - } - - return NULL; -} - -static void -upgrade_xml_uris (xmlDocPtr doc, gchar * (* upgrade_uri) (const gchar *uri)) -{ - xmlNodePtr root, node; - gchar *uri, *new; - - if (!doc || !(root = xmlDocGetRootElement (doc))) - return; - - if (!root->name || strcmp ((gchar *)root->name, "filteroptions") != 0) { - /* root node is not <filteroptions>, nothing to upgrade */ - return; - } - - if (!(node = xml_find_node (root, "ruleset"))) { - /* no ruleset node, nothing to upgrade */ - return; - } - - node = node->children; - while (node != NULL) { - if (node->name && !strcmp ((gchar *)node->name, "rule")) { - xmlNodePtr actionset, part, val, n; - - if ((actionset = xml_find_node (node, "actionset"))) { - /* filters.xml */ - part = actionset->children; - while (part != NULL) { - if (part->name && !strcmp ((gchar *)part->name, "part")) { - val = part->children; - while (val != NULL) { - if (val->name && !strcmp ((gchar *)val->name, "value")) { - gchar *type; - - type = (gchar *)xmlGetProp (val, (const guchar *)"type"); - if (type && !strcmp ((gchar *)type, "folder")) { - if ((n = xml_find_node (val, "folder"))) { - uri = (gchar *)xmlGetProp (n, (const guchar *)"uri"); - new = upgrade_uri (uri); - xmlFree (uri); - - xmlSetProp (n, (const guchar *)"uri", (guchar *)new); - g_free (new); - } - } - - xmlFree (type); - } - - val = val->next; - } - } - - part = part->next; - } - } else if ((actionset = xml_find_node (node, "sources"))) { - /* vfolders.xml */ - n = actionset->children; - while (n != NULL) { - if (n->name && !strcmp ((gchar *)n->name, "folder")) { - uri = (gchar *)xmlGetProp (n, (const guchar *)"uri"); - new = upgrade_uri (uri); - xmlFree (uri); - - xmlSetProp (n, (const guchar *)"uri", (guchar *)new); - g_free (new); - } - - n = n->next; - } - } - } - - node = node->next; - } -} - -/* 1.0 upgrade functions & data */ - -/* as much info as we have on a given account */ -struct _account_info_1_0 { - gchar *name; - gchar *uri; - gchar *base_uri; - union { - struct { - /* for imap */ - gchar *namespace; - gchar *namespace_full; - guint32 capabilities; - GHashTable *folders; - gchar dir_sep; - } imap; - } u; -}; - -struct _imap_folder_info_1_0 { - gchar *folder; - /* encoded? decoded? canonicalised? */ - gchar dir_sep; -}; - struct _migrate_state_info { gchar *label_name; gdouble progress; }; -static gboolean update_states_in_main_thread (const struct - _migrate_state_info *info); - -static GHashTable *accounts_1_0 = NULL; -static GHashTable *accounts_name_1_0 = NULL; - -static void -imap_folder_info_1_0_free (struct _imap_folder_info_1_0 *fi) -{ - g_free(fi->folder); - g_free(fi); -} - -static void -account_info_1_0_free (struct _account_info_1_0 *ai) -{ - g_free(ai->name); - g_free(ai->uri); - g_free(ai->base_uri); - g_free(ai->u.imap.namespace); - g_free(ai->u.imap.namespace_full); - g_hash_table_destroy(ai->u.imap.folders); - g_free(ai); -} - -static gchar * -get_base_uri(const gchar *val) -{ - const gchar *tmp; - - tmp = strchr(val, ':'); - if (tmp) { - tmp++; - if (strncmp(tmp, "//", 2) == 0) - tmp += 2; - tmp = strchr(tmp, '/'); - } - - if (tmp) - return g_strndup(val, tmp-val); - else - return g_strdup(val); -} - -static gchar * -upgrade_xml_uris_1_0 (const gchar *uri) -{ - gchar *out = NULL; - - /* upgrades camel uri's */ - if (strncmp (uri, "imap:", 5) == 0) { - gchar *base_uri, dir_sep, *folder, *p; - struct _account_info_1_0 *ai; - - /* add namespace, canonicalise dir_sep to / */ - base_uri = get_base_uri (uri); - ai = g_hash_table_lookup (accounts_1_0, base_uri); - - if (ai == NULL) { - g_free (base_uri); - return NULL; - } - - dir_sep = ai->u.imap.dir_sep; - if (dir_sep == 0) { - /* no dir_sep listed, try get it from the namespace, if set */ - if (ai->u.imap.namespace != NULL) { - p = ai->u.imap.namespace; - while ((dir_sep = *p++)) { - if (dir_sep < '0' - || (dir_sep > '9' && dir_sep < 'A') - || (dir_sep > 'Z' && dir_sep < 'a') - || (dir_sep > 'z')) { - break; - } - p++; - } - } - - /* give up ... */ - if (dir_sep == 0) { - g_free (base_uri); - return NULL; - } - } - - folder = g_strdup (uri + strlen (base_uri) + 1); - - /* Add the namespace before the mailbox name, unless the mailbox is INBOX */ - if (ai->u.imap.namespace && strcmp ((gchar *)folder, "INBOX") != 0) - out = g_strdup_printf ("%s/%s/%s", base_uri, ai->u.imap.namespace, folder); - else - out = g_strdup_printf ("%s/%s", base_uri, folder); - - p = out; - while (*p) { - if (*p == dir_sep) - *p = '/'; - p++; - } - - g_free (folder); - g_free (base_uri); - } else if (strncmp (uri, "exchange:", 9) == 0) { - gchar *base_uri, *folder, *p; - - /* exchange://user@host/exchange/ * -> exchange://user@host/personal/ * */ - /* Any url encoding (%xx) in the folder name is also removed */ - base_uri = get_base_uri (uri); - uri += strlen (base_uri) + 1; - if (strncmp (uri, "exchange/", 9) == 0) { - folder = e_bconf_url_decode (uri + 9); - p = strchr (folder, '/'); - out = g_strdup_printf ("%s/personal%s", base_uri, p ? p : "/"); - g_free (folder); - } - } else if (strncmp (uri, "exchanget:", 10) == 0) { - /* these should be converted in the accounts table when it is loaded */ - g_warning ("exchanget: uri not converted: '%s'", uri); - } - - return out; -} - -static gchar * -parse_lsub (const gchar *lsub, gchar *dir_sep) -{ - static gint comp; - static regex_t pat; - regmatch_t match[3]; - const gchar *m = "^\\* LSUB \\([^)]*\\) \"?([^\" ]+)\"? \"?(.*)\"?$"; - - if (!comp) { - if (regcomp (&pat, m, REG_EXTENDED|REG_ICASE) == -1) { - g_warning ("reg comp '%s' failed: %s", m, g_strerror (errno)); - return NULL; - } - comp = 1; - } - - if (regexec (&pat, lsub, 3, match, 0) == 0) { - if (match[1].rm_so != -1 && match[2].rm_so != -1) { - if (dir_sep) - *dir_sep = (match[1].rm_eo - match[1].rm_so == 1) ? lsub[match[1].rm_so] : 0; - return g_strndup (lsub + match[2].rm_so, match[2].rm_eo - match[2].rm_so); - } - } - - return NULL; -} - -static gboolean -read_imap_storeinfo (struct _account_info_1_0 *si) -{ - FILE *storeinfo; - guint32 tmp; - gchar *buf, *folder, dir_sep, *path, *name, *p; - struct _imap_folder_info_1_0 *fi; - - si->u.imap.folders = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) imap_folder_info_1_0_free); - - /* get details from uri first */ - name = strstr (si->uri, ";override_namespace"); - if (name) { - name = strstr (si->uri, ";namespace="); - if (name) { - gchar *end; - - name += strlen (";namespace="); - if (*name == '\"') { - name++; - end = strchr (name, '\"'); - } else { - end = strchr (name, ';'); - } - - if (end) { - /* try get the dir_sep from the namespace */ - si->u.imap.namespace = g_strndup (name, end-name); - - p = si->u.imap.namespace; - while ((dir_sep = *p++)) { - if (dir_sep < '0' - || (dir_sep > '9' && dir_sep < 'A') - || (dir_sep > 'Z' && dir_sep < 'a') - || (dir_sep > 'z')) { - si->u.imap.dir_sep = dir_sep; - break; - } - p++; - } - } - } - } - - /* now load storeinfo if it exists */ - path = g_build_filename (g_get_home_dir (), "evolution", "mail", "imap", si->base_uri + 7, "storeinfo", NULL); - storeinfo = fopen (path, "r"); - g_free (path); - if (storeinfo == NULL) { - g_warning ("could not find imap store info '%s'", path); - return FALSE; - } - - /* ignore version */ - camel_file_util_decode_uint32 (storeinfo, &tmp); - camel_file_util_decode_uint32 (storeinfo, &si->u.imap.capabilities); - g_free (si->u.imap.namespace); - camel_file_util_decode_string (storeinfo, &si->u.imap.namespace); - camel_file_util_decode_uint32 (storeinfo, &tmp); - si->u.imap.dir_sep = tmp; - /* strip trailing dir_sep or / */ - if (si->u.imap.namespace - && (si->u.imap.namespace[strlen (si->u.imap.namespace) - 1] == si->u.imap.dir_sep - || si->u.imap.namespace[strlen (si->u.imap.namespace) - 1] == '/')) { - si->u.imap.namespace[strlen (si->u.imap.namespace) - 1] = 0; - } - - d(printf ("namespace '%s' dir_sep '%c'\n", si->u.imap.namespace, si->u.imap.dir_sep ? si->u.imap.dir_sep : '?')); - - while (camel_file_util_decode_string (storeinfo, &buf) == 0) { - folder = parse_lsub (buf, &dir_sep); - if (folder) { - fi = g_new0 (struct _imap_folder_info_1_0, 1); - fi->folder = folder; - fi->dir_sep = dir_sep; -#if d(!)0 - printf (" add folder '%s' ", folder); - if (dir_sep) - printf ("'%c'\n", dir_sep); - else - printf ("NIL\n"); -#endif - g_hash_table_insert (si->u.imap.folders, fi->folder, fi); - } else { - g_warning ("Could not parse LIST result '%s'\n", buf); - } - } - - fclose (storeinfo); - - return TRUE; -} - -static gboolean -load_accounts_1_0 (xmlDocPtr doc) -{ - xmlNodePtr source; - gchar *val, *tmp; - gint count = 0, i; - gchar key[32]; - - if (!(source = e_bconf_get_path (doc, "/Mail/Accounts"))) - return TRUE; - - if ((val = e_bconf_get_value (source, "num"))) { - count = atoi (val); - xmlFree (val); - } - - /* load account upgrade info for each account */ - for (i = 0; i < count; i++) { - struct _account_info_1_0 *ai; - gchar *rawuri; - - sprintf (key, "source_url_%d", i); - if (!(rawuri = e_bconf_get_value (source, key))) - continue; - - ai = g_malloc0 (sizeof (struct _account_info_1_0)); - ai->uri = e_bconf_hex_decode (rawuri); - ai->base_uri = get_base_uri (ai->uri); - sprintf (key, "account_name_%d", i); - ai->name = e_bconf_get_string (source, key); - - d(printf("load account '%s'\n", ai->uri)); - - if (!strncmp (ai->uri, "imap:", 5)) { - read_imap_storeinfo (ai); - } else if (!strncmp (ai->uri, "exchange:", 9)) { - xmlNodePtr node; - - d(printf (" upgrade exchange account\n")); - /* small hack, poke the source_url into the transport_url for exchanget: transports - - this will be picked up later in the conversion */ - sprintf (key, "transport_url_%d", i); - node = e_bconf_get_entry (source, key); - if (node && (val = (gchar *)xmlGetProp (node, (const guchar *)"value"))) { - tmp = e_bconf_hex_decode (val); - xmlFree (val); - if (strncmp (tmp, "exchanget:", 10) == 0) - xmlSetProp (node, (const guchar *)"value", (guchar *)rawuri); - g_free (tmp); - } else { - d(printf (" couldn't find transport uri?\n")); - } - } - xmlFree (rawuri); - - g_hash_table_insert (accounts_1_0, ai->base_uri, ai); - if (ai->name) - g_hash_table_insert (accounts_name_1_0, ai->name, ai); - } - - return TRUE; -} - -static gboolean -em_migrate_1_0 (const gchar *data_dir, xmlDocPtr config_xmldb, xmlDocPtr filters, xmlDocPtr vfolders, GError **error) -{ - accounts_1_0 = g_hash_table_new_full ( - g_str_hash, g_str_equal, - (GDestroyNotify) NULL, - (GDestroyNotify) account_info_1_0_free); - accounts_name_1_0 = g_hash_table_new (g_str_hash, g_str_equal); - load_accounts_1_0 (config_xmldb); - - upgrade_xml_uris(filters, upgrade_xml_uris_1_0); - upgrade_xml_uris(vfolders, upgrade_xml_uris_1_0); - - g_hash_table_destroy (accounts_1_0); - g_hash_table_destroy (accounts_name_1_0); - - return TRUE; -} - -/* 1.2 upgrade functions */ -static gboolean -is_xml1encoded (const gchar *txt) -{ - const guchar *p; - gint isxml1 = FALSE; - gint is8bit = FALSE; - - p = (const guchar *)txt; - while (*p) { - if (p[0] == '\\' && p[1] == 'U' && p[2] == '+' - && isxdigit (p[3]) && isxdigit (p[4]) && isxdigit (p[5]) && isxdigit (p[6]) - && p[7] == '\\') { - isxml1 = TRUE; - p+=7; - } else if (p[0] >= 0x80) - is8bit = TRUE; - p++; - } - - /* check for invalid utf8 that needs cleaning */ - if (is8bit && !isxml1) - isxml1 = !g_utf8_validate (txt, -1, NULL); - - return isxml1; -} - -static gchar * -decode_xml1 (const gchar *txt) -{ - GString *out = g_string_new (""); - const guchar *p; - gchar *res; - - /* convert: - \U+XXXX\ -> utf8 - 8 bit characters -> utf8 (iso-8859-1) */ - - p = (const guchar *) txt; - while (*p) { - if (p[0] > 0x80 - || (p[0] == '\\' && p[1] == 'U' && p[2] == '+' - && isxdigit (p[3]) && isxdigit (p[4]) && isxdigit (p[5]) && isxdigit (p[6]) - && p[7] == '\\')) { - gchar utf8[8]; - gunichar u; - - if (p[0] == '\\') { - memcpy (utf8, p + 3, 4); - utf8[4] = 0; - u = strtoul (utf8, NULL, 16); - p+=7; - } else - u = p[0]; - utf8[g_unichar_to_utf8 (u, utf8)] = 0; - g_string_append (out, utf8); - } else { - g_string_append_c (out, *p); - } - p++; - } - - res = out->str; - g_string_free (out, FALSE); - - return res; -} - -static gchar * -utf8_reencode (const gchar *txt) -{ - GString *out = g_string_new (""); - gchar *p; - gchar *res; - - /* convert: - libxml1 8 bit utf8 converted to xml entities byte-by-byte chars -> utf8 */ - - p = (gchar *)txt; - - while (*p) { - g_string_append_c (out, (gchar)g_utf8_get_char ((const gchar *)p)); - p = (gchar *)g_utf8_next_char (p); - } - - res = out->str; - if (g_utf8_validate (res, -1, NULL)) { - g_string_free (out, FALSE); - return res; - } else { - g_string_free (out, TRUE); - return g_strdup (txt); - } -} - -static gboolean -upgrade_xml_1_2_rec (xmlNodePtr node) -{ - const gchar *value_tags[] = { "string", "address", "regex", "file", "command", NULL }; - const gchar *rule_tags[] = { "title", NULL }; - const gchar *item_props[] = { "name", NULL }; - struct { - const gchar *name; - const gchar **tags; - const gchar **props; - } tags[] = { - { "value", value_tags, NULL }, - { "rule", rule_tags, NULL }, - { "item", NULL, item_props }, - { 0 }, - }; - xmlNodePtr work; - gint i,j; - gchar *txt, *tmp; - - /* upgrades the content of a node, if the node has a specific parent/node name */ - - for (i = 0; tags[i].name; i++) { - if (!strcmp ((gchar *)node->name, tags[i].name)) { - if (tags[i].tags != NULL) { - work = node->children; - while (work) { - for (j = 0; tags[i].tags[j]; j++) { - if (!strcmp ((gchar *)work->name, tags[i].tags[j])) { - txt = (gchar *)xmlNodeGetContent (work); - if (is_xml1encoded (txt)) { - tmp = decode_xml1 (txt); - d(printf ("upgrading xml node %s/%s '%s' -> '%s'\n", - tags[i].name, tags[i].tags[j], txt, tmp)); - xmlNodeSetContent (work, (guchar *)tmp); - g_free (tmp); - } - xmlFree (txt); - } - } - work = work->next; - } - break; - } - - if (tags[i].props != NULL) { - for (j = 0; tags[i].props[j]; j++) { - txt = (gchar *)xmlGetProp (node, (guchar *)tags[i].props[j]); - tmp = utf8_reencode (txt); - d(printf ("upgrading xml property %s on node %s '%s' -> '%s'\n", - tags[i].props[j], tags[i].name, txt, tmp)); - xmlSetProp (node, (const guchar *)tags[i].props[j], (guchar *)tmp); - g_free (tmp); - xmlFree (txt); - } - } - } - } - - node = node->children; - while (node) { - upgrade_xml_1_2_rec (node); - node = node->next; - } - - return TRUE; -} - -static gboolean -em_upgrade_xml_1_2 (xmlDocPtr doc) -{ - xmlNodePtr root; - - if (!doc || !(root = xmlDocGetRootElement (doc))) - return TRUE; - - return upgrade_xml_1_2_rec (root); -} - -/* ********************************************************************** */ -/* Tables for converting flat bonobo conf -> gconf xml blob */ -/* ********************************************************************** */ - -/* Mail/Accounts/ * */ -static e_bconf_map_t cc_map[] = { - { "account_always_cc_%i", "always", E_BCONF_MAP_BOOL }, - { "account_always_cc_addrs_%i", "recipients", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL }, -}; - -static e_bconf_map_t bcc_map[] = { - { "account_always_cc_%i", "always", E_BCONF_MAP_BOOL }, - { "account_always_bcc_addrs_%i", "recipients", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL }, -}; - -static e_bconf_map_t pgp_map[] = { - { "account_pgp_encrypt_to_self_%i", "encrypt-to-self", E_BCONF_MAP_BOOL }, - { "account_pgp_always_trust_%i", "always-trust", E_BCONF_MAP_BOOL }, - { "account_pgp_always_sign_%i", "always-sign", E_BCONF_MAP_BOOL }, - { "account_pgp_no_imip_sign_%i", "no-imip-sign", E_BCONF_MAP_BOOL }, - { "account_pgp_key_%i", "key-id", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL }, -}; - -static e_bconf_map_t smime_map[] = { - { "account_smime_encrypt_to_self_%i", "encrypt-to-self", E_BCONF_MAP_BOOL }, - { "account_smime_always_sign_%i", "always-sign", E_BCONF_MAP_BOOL }, - { "account_smime_key_%i", "key-id", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL }, -}; - -static e_bconf_map_t identity_sig_map[] = { - { "identity_autogenerated_signature_%i", "auto", E_BCONF_MAP_BOOL }, - { "identity_def_signature_%i", "default", E_BCONF_MAP_LONG }, - { NULL }, -}; - -static e_bconf_map_t identity_map[] = { - { "identity_name_%i", "name", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { "identity_address_%i", "addr-spec", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { "identity_reply_to_%i", "reply-to", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { "identity_organization_%i", "organization", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL, "signature", E_BCONF_MAP_CHILD, identity_sig_map }, - { NULL }, -}; - -static e_bconf_map_t source_map[] = { - { "source_save_passwd_%i", "save-passwd", E_BCONF_MAP_BOOL }, - { "source_keep_on_server_%i", "keep-on-server", E_BCONF_MAP_BOOL }, - { "source_auto_check_%i", "auto-check", E_BCONF_MAP_BOOL }, - { "source_auto_check_time_%i", "auto-check-timeout", E_BCONF_MAP_LONG }, - { "source_url_%i", "url", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL }, -}; - -static e_bconf_map_t transport_map[] = { - { "transport_save_passwd_%i", "save-passwd", E_BCONF_MAP_BOOL }, - { "transport_url_%i", "url", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL }, -}; - -static e_bconf_map_t account_map[] = { - { "account_name_%i", "name", E_BCONF_MAP_STRING }, - { "source_enabled_%i", "enabled", E_BCONF_MAP_BOOL }, - { NULL, "identity", E_BCONF_MAP_CHILD, identity_map }, - { NULL, "source", E_BCONF_MAP_CHILD, source_map }, - { NULL, "transport", E_BCONF_MAP_CHILD, transport_map }, - { "account_drafts_folder_uri_%i", "drafts-folder", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { "account_sent_folder_uri_%i", "sent-folder", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL, "auto-cc", E_BCONF_MAP_CHILD, cc_map }, - { NULL, "auto-bcc", E_BCONF_MAP_CHILD, bcc_map }, - { NULL, "pgp", E_BCONF_MAP_CHILD, pgp_map }, - { NULL, "smime", E_BCONF_MAP_CHILD, smime_map }, - { NULL }, -}; - -/* /Mail/Signatures/ * */ -static e_bconf_map_t signature_format_map[] = { - { "text/plain", }, - { "text/html", }, - { NULL } -}; - -static e_bconf_map_t signature_map[] = { - { "name_%i", "name", E_BCONF_MAP_STRING }, - { "html_%i", "format", E_BCONF_MAP_ENUM, signature_format_map }, - { "filename_%i", "filename", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { "script_%i", "script", E_BCONF_MAP_STRING|E_BCONF_MAP_CONTENT }, - { NULL }, -}; - -/* ********************************************************************** */ -/* Tables for bonobo conf -> gconf conversion */ -/* ********************************************************************** */ - -static e_gconf_map_t mail_accounts_map[] = { - /* /Mail/Accounts - most entries are processed via the xml blob routine */ - /* This also works because the initial uid mapping is 1:1 with the list order */ - { "default_account", "mail/default_account", E_GCONF_MAP_SIMPLESTRING }, - { 0 }, -}; - -static e_gconf_map_t mail_display_map[] = { - /* /Mail/Display */ - { "side_bar_search", "mail/display/side_bar_search", E_GCONF_MAP_BOOL }, - { "thread_subject", "mail/display/thread_subject", E_GCONF_MAP_BOOL }, - { "hide_deleted", "mail/display/show_deleted", E_GCONF_MAP_BOOLNOT }, - { "paned_size", "mail/display/paned_size", E_GCONF_MAP_INT }, - { "seen_timeout", "mail/display/mark_seen_timeout", E_GCONF_MAP_INT }, - { "do_seen_timeout", "mail/display/mark_seen", E_GCONF_MAP_BOOL }, - { "http_images", "mail/display/load_http_images", E_GCONF_MAP_INT }, - { "citation_highlight", "mail/display/mark_citations", E_GCONF_MAP_BOOL }, - { "citation_color", "mail/display/citation_colour", E_GCONF_MAP_COLOUR }, - { 0 }, -}; - -static e_gconf_map_t mail_format_map[] = { - /* /Mail/Format */ - { "message_display_style", "mail/display/message_style", E_GCONF_MAP_INT }, - { "send_html", "mail/composer/send_html", E_GCONF_MAP_BOOL }, - { "default_reply_style", "mail/format/reply_style", E_GCONF_MAP_INT }, - { "default_forward_style", "mail/format/forward_style", E_GCONF_MAP_INT }, - { "default_charset", "mail/composer/charset", E_GCONF_MAP_STRING }, - { "confirm_unwanted_html", "mail/prompts/unwanted_html", E_GCONF_MAP_BOOL }, - { 0 }, -}; - -static e_gconf_map_t mail_trash_map[] = { - /* /Mail/Trash */ - { "empty_on_exit", "mail/trash/empty_on_exit", E_GCONF_MAP_BOOL }, - { 0 }, -}; - -static e_gconf_map_t mail_prompts_map[] = { - /* /Mail/Prompts */ - { "confirm_expunge", "mail/prompts/expunge", E_GCONF_MAP_BOOL }, - { "empty_subject", "mail/prompts/empty_subject", E_GCONF_MAP_BOOL }, - { "only_bcc", "mail/prompts/only_bcc", E_GCONF_MAP_BOOL }, - { 0 } -}; - -static e_gconf_map_t mail_filters_map[] = { - /* /Mail/Filters */ - { "log", "mail/filters/log", E_GCONF_MAP_BOOL }, - { "log_path", "mail/filters/logfile", E_GCONF_MAP_STRING }, - { 0 } -}; - -static e_gconf_map_t mail_notify_map[] = { - /* /Mail/Notify */ - { "new_mail_notification", "mail/notify/type", E_GCONF_MAP_INT }, - { "new_mail_notification_sound_file", "mail/notify/sound", E_GCONF_MAP_STRING }, - { 0 } -}; - -static e_gconf_map_t mail_filesel_map[] = { - /* /Mail/Filesel */ - { "last_filesel_dir", "mail/save_dir", E_GCONF_MAP_STRING }, - { 0 } -}; - -static e_gconf_map_t mail_composer_map[] = { - /* /Mail/Composer */ - { "ViewFrom", "mail/composer/view/From", E_GCONF_MAP_BOOL }, - { "ViewReplyTo", "mail/composer/view/ReplyTo", E_GCONF_MAP_BOOL }, - { "ViewCC", "mail/composer/view/Cc", E_GCONF_MAP_BOOL }, - { "ViewBCC", "mail/composer/view/Bcc", E_GCONF_MAP_BOOL }, - { "ViewSubject", "mail/composer/view/Subject", E_GCONF_MAP_BOOL }, - { 0 }, -}; - -/* ********************************************************************** */ - -static e_gconf_map_t importer_elm_map[] = { - /* /Importer/Elm */ - { "mail", "importer/elm/mail", E_GCONF_MAP_BOOL }, - { "mail-imported", "importer/elm/mail-imported", E_GCONF_MAP_BOOL }, - { 0 }, -}; - -static e_gconf_map_t importer_pine_map[] = { - /* /Importer/Pine */ - { "mail", "importer/elm/mail", E_GCONF_MAP_BOOL }, - { "address", "importer/elm/address", E_GCONF_MAP_BOOL }, - { 0 }, -}; - -static e_gconf_map_t importer_netscape_map[] = { - /* /Importer/Netscape */ - { "mail", "importer/netscape/mail", E_GCONF_MAP_BOOL }, - { "settings", "importer/netscape/settings", E_GCONF_MAP_BOOL }, - { "filters", "importer/netscape/filters", E_GCONF_MAP_BOOL }, - { 0 }, -}; -/* ********************************************************************** */ - -static e_gconf_map_list_t gconf_remap_list[] = { - { "/Mail/Accounts", mail_accounts_map }, - { "/Mail/Display", mail_display_map }, - { "/Mail/Format", mail_format_map }, - { "/Mail/Trash", mail_trash_map }, - { "/Mail/Prompts", mail_prompts_map }, - { "/Mail/Filters", mail_filters_map }, - { "/Mail/Notify", mail_notify_map }, - { "/Mail/Filesel", mail_filesel_map }, - { "/Mail/Composer", mail_composer_map }, - - { "/Importer/Elm", importer_elm_map }, - { "/Importer/Pine", importer_pine_map }, - { "/Importer/Netscape", importer_netscape_map }, - - { 0 }, -}; - -static struct { - const gchar *label; - const gchar *colour; -} label_default[5] = { - { N_("Important"), "#EF2929" }, /* red */ - { N_("Work"), "#F57900" }, /* orange */ - { N_("Personal"), "#4E9A06" }, /* green */ - { N_("To Do"), "#3465A4" }, /* blue */ - { N_("Later"), "#75507B" } /* purple */ -}; - -/* remaps mail config from bconf to gconf */ static gboolean -bconf_import(GConfClient *gconf, xmlDocPtr config_xmldb) -{ - xmlNodePtr source; - gchar labx[16], colx[16]; - gchar *val, *lab, *col; - GSList *list, *l; - gint i; - - e_bconf_import(gconf, config_xmldb, gconf_remap_list); - - /* Labels: - label string + label colour as integer - -> label string:# colour as hex */ - source = e_bconf_get_path(config_xmldb, "/Mail/Labels"); - if (source) { - list = NULL; - for (i = 0; i < 5; i++) { - sprintf(labx, "label_%d", i); - sprintf(colx, "color_%d", i); - lab = e_bconf_get_string(source, labx); - if ((col = e_bconf_get_value(source, colx))) { - sprintf(colx, "#%06x", atoi(col) & 0xffffff); - g_free(col); - } else - strcpy(colx, label_default[i].colour); - - val = g_strdup_printf("%s:%s", lab ? lab : label_default[i].label, colx); - list = g_slist_append(list, val); - g_free(lab); - } - - gconf_client_set_list(gconf, "/apps/evolution/mail/labels", GCONF_VALUE_STRING, list, NULL); - while (list) { - l = list->next; - g_free(list->data); - g_slist_free_1(list); - list = l; - } - } else { - g_warning("could not find /Mail/Labels in old config database, skipping"); - } - - /* Accounts: The flat bonobo-config structure is remapped to a list of xml blobs. Upgrades as necessary */ - e_bconf_import_xml_blob(gconf, config_xmldb, account_map, "/Mail/Accounts", - "/apps/evolution/mail/accounts", "account", "uid"); - - /* Same for signatures */ - e_bconf_import_xml_blob(gconf, config_xmldb, signature_map, "/Mail/Signatures", - "/apps/evolution/mail/signatures", "signature", NULL); - - return TRUE; -} - -static gboolean -em_migrate_1_2(const gchar *data_dir, xmlDocPtr config_xmldb, xmlDocPtr filters, xmlDocPtr vfolders, GError **error) -{ - GConfClient *gconf; - - gconf = gconf_client_get_default(); - bconf_import(gconf, config_xmldb); - g_object_unref(gconf); - - em_upgrade_xml_1_2(filters); - em_upgrade_xml_1_2(vfolders); - - return TRUE; -} - -#endif /* !G_OS_WIN32 */ +update_states_in_main_thread (const struct _migrate_state_info *info); /* 1.4 upgrade functions */ @@ -1199,162 +242,6 @@ em_migrate_set_progress (double percent) gtk_main_iteration (); } -#ifndef G_OS_WIN32 - -static gboolean -is_mail_folder (const gchar *metadata) -{ - xmlNodePtr node; - xmlDocPtr doc; - gchar *type; - - if (!(doc = xmlParseFile (metadata))) { - g_warning ("Cannot parse '%s'", metadata); - return FALSE; - } - - if (!(node = xmlDocGetRootElement (doc))) { - g_warning ("'%s' corrupt: document contains no root node", metadata); - xmlFreeDoc (doc); - return FALSE; - } - - if (!node->name || strcmp ((gchar *)node->name, "efolder") != 0) { - g_warning ("'%s' corrupt: root node is not 'efolder'", metadata); - xmlFreeDoc (doc); - return FALSE; - } - - node = node->children; - while (node != NULL) { - if (node->name && !strcmp ((gchar *)node->name, "type")) { - type = (gchar *)xmlNodeGetContent (node); - if (!strcmp ((gchar *)type, "mail")) { - xmlFreeDoc (doc); - xmlFree (type); - - return TRUE; - } - - xmlFree (type); - - break; - } - - node = node->next; - } - - xmlFreeDoc (doc); - - return FALSE; -} - -static gboolean -get_local_et_expanded (const gchar *dirname) -{ - xmlNodePtr node; - xmlDocPtr doc; - struct stat st; - gchar *buf, *p; - gint thread_list; - - buf = g_strdup_printf ("%s/evolution/config/file:%s", g_get_home_dir (), dirname); - p = buf + strlen (g_get_home_dir ()) + strlen ("/evolution/config/file:"); - e_filename_make_safe (p); - - if (stat (buf, &st) == -1) { - g_free (buf); - return FALSE; - } - - if (!(doc = xmlParseFile (buf))) { - g_free (buf); - return FALSE; - } - - g_free (buf); - - if (!(node = xmlDocGetRootElement (doc)) || strcmp ((gchar *)node->name, "expanded_state") != 0) { - xmlFreeDoc (doc); - return FALSE; - } - - if (!(buf = (gchar *)xmlGetProp (node, (const guchar *)"default"))) { - xmlFreeDoc (doc); - return FALSE; - } - - thread_list = strcmp (buf, "0") == 0 ? 0 : 1; - xmlFree (buf); - - xmlFreeDoc (doc); - - return thread_list; -} - -static gchar * -get_local_store_uri (const gchar *dirname, gchar **namep, gint *indexp) -{ - gchar *name, *protocol, *metadata, *tmp; - gint index; - struct stat st; - xmlNodePtr node; - xmlDocPtr doc; - - metadata = g_build_filename(dirname, "local-metadata.xml", NULL); - - /* in 1.4, any errors are treated as defaults, this function cannot fail */ - - /* defaults */ - name = (gchar *) "mbox"; - protocol = (gchar *) "mbox"; - index = TRUE; - - if (stat (metadata, &st) == -1 || !S_ISREG (st.st_mode)) - goto nofile; - - doc = xmlParseFile(metadata); - if (doc == NULL) - goto nofile; - - node = doc->children; - if (strcmp((gchar *)node->name, "folderinfo")) - goto dodefault; - - for (node = node->children; node; node = node->next) { - if (node->name && !strcmp ((gchar *)node->name, "folder")) { - tmp = (gchar *)xmlGetProp (node, (const guchar *)"type"); - if (tmp) { - protocol = g_alloca(strlen(tmp)+1); - strcpy(protocol, tmp); - xmlFree(tmp); - } - tmp = (gchar *)xmlGetProp (node, (const guchar *)"name"); - if (tmp) { - name = g_alloca(strlen(tmp)+1); - strcpy(name, tmp); - xmlFree(tmp); - } - tmp = (gchar *)xmlGetProp (node, (const guchar *)"index"); - if (tmp) { - index = atoi(tmp); - xmlFree(tmp); - } - } - } -dodefault: - xmlFreeDoc (doc); -nofile: - g_free(metadata); - - *namep = g_strdup(name); - *indexp = index; - - return g_strdup_printf("%s:%s", protocol, dirname); -} - -#endif /* !G_OS_WIN32 */ - enum { CP_UNIQUE = 0, CP_OVERWRITE, @@ -1449,1163 +336,9 @@ cp (const gchar *src, const gchar *dest, gboolean show_progress, gint mode) #ifndef G_OS_WIN32 -static gboolean -cp_r (const gchar *src, const gchar *dest, const gchar *pattern, gint mode) -{ - GString *srcpath, *destpath; - struct dirent *dent; - gsize slen, dlen; - struct stat st; - DIR *dir; - - if (g_mkdir_with_parents (dest, 0700) == -1) - return FALSE; - - if (!(dir = opendir (src))) - return FALSE; - - srcpath = g_string_new (src); - g_string_append_c (srcpath, '/'); - slen = srcpath->len; - - destpath = g_string_new (dest); - g_string_append_c (destpath, '/'); - dlen = destpath->len; - - while ((dent = readdir (dir))) { - if (!strcmp (dent->d_name, ".") || !strcmp (dent->d_name, "..")) - continue; - - g_string_truncate (srcpath, slen); - g_string_truncate (destpath, dlen); - - g_string_append (srcpath, dent->d_name); - g_string_append (destpath, dent->d_name); - - if (stat (srcpath->str, &st) == -1) - continue; - - if (S_ISDIR (st.st_mode)) { - cp_r (srcpath->str, destpath->str, pattern, mode); - } else if (!pattern || !strcmp (dent->d_name, pattern)) { - cp (srcpath->str, destpath->str, FALSE, mode); - } - } - - closedir (dir); - - g_string_free (destpath, TRUE); - g_string_free (srcpath, TRUE); - - return TRUE; -} - -static void -mbox_build_filename (GString *path, const gchar *toplevel_dir, const gchar *full_name) -{ - const gchar *start, *inptr = full_name; - gint subdirs = 0; - - while (*inptr != '\0') { - if (*inptr == '/') - subdirs++; - inptr++; - } - - g_string_assign(path, toplevel_dir); - g_string_append_c (path, '/'); - - inptr = full_name; - while (*inptr != '\0') { - start = inptr; - while (*inptr != '/' && *inptr != '\0') - inptr++; - - g_string_append_len (path, start, inptr - start); - - if (*inptr == '/') { - g_string_append (path, ".sbd/"); - inptr++; - - /* strip extranaeous '/'s */ - while (*inptr == '/') - inptr++; - } - } -} - -static gboolean -em_migrate_folder(EMMigrateSession *session, const gchar *dirname, const gchar *full_name, GError **error) -{ - CamelFolder *old_folder = NULL, *new_folder = NULL; - CamelStore *local_store = NULL; - CamelException ex; - gchar *name, *uri; - GPtrArray *uids; - struct stat st; - gboolean thread_list; - gint index, i; - GString *src, *dest; - gboolean success = FALSE; - struct _migrate_state_info * info; - - camel_exception_init (&ex); - - src = g_string_new(""); - - g_string_printf(src, "%s/folder-metadata.xml", dirname); - if (stat (src->str, &st) == -1 - || !S_ISREG (st.st_mode) - || !is_mail_folder(src->str)) { - /* Not an evolution mail folder */ - g_string_free(src, TRUE); - return TRUE; - } - - dest = g_string_new(""); - uri = get_local_store_uri(dirname, &name, &index); - info = g_malloc (sizeof(struct _migrate_state_info)); - info->label_name = g_strdup (full_name); - info->progress = 0.0; - g_idle_add ((GSourceFunc) update_states_in_main_thread, info); - - thread_list = get_local_et_expanded (dirname); - - /* Manually copy local mbox files, its much faster */ - if (!strncmp (uri, "mbox:", 5)) { - static const gchar *meta_ext[] = { ".summary", ".ibex.index", ".ibex.index.data" }; - gsize slen, dlen; - FILE *fp; - gchar *p; - gint mode; - - g_string_printf (src, "%s/%s", uri + 5, name); - mbox_build_filename (dest, ((CamelService *)session->store)->url->path, full_name); - p = strrchr (dest->str, '/'); - *p = '\0'; - - slen = src->len; - dlen = dest->len; - - if (g_mkdir_with_parents (dest->str, 0700) == -1 && errno != EEXIST) { - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Unable to create new folder '%s': %s"), - dest->str, g_strerror (errno)); - goto fatal; - } - - *p = '/'; - mode = CP_UNIQUE; - retry_copy: - if (!cp (src->str, dest->str, TRUE, mode)) { - if (errno == EEXIST) { - gint save = errno; - - switch (e_alert_run_dialog_for_args (e_shell_get_active_window (NULL), "mail:ask-migrate-existing", src->str, dest->str, NULL)) { - case GTK_RESPONSE_ACCEPT: - mode = CP_OVERWRITE; - goto retry_copy; - case GTK_RESPONSE_OK: - mode = CP_APPEND; - goto retry_copy; - case GTK_RESPONSE_REJECT: - goto ignore; - } - - errno = save; - } - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Unable to copy folder '%s' to '%s': %s"), - src->str, dest->str, g_strerror (errno)); - goto fatal; - } - ignore: - - /* create a .cmeta file specifying to index and/or thread the folder */ - g_string_truncate (dest, dlen); - g_string_append (dest, ".cmeta"); - if ((fp = fopen (dest->str, "w")) != NULL) { - gint fd = fileno (fp); - - /* write the magic string */ - if (fwrite ("CLMD", 4, 1, fp) != 1) - goto cmeta_err; - - /* write the version (1) */ - if (camel_file_util_encode_uint32 (fp, 1) == -1) - goto cmeta_err; - - /* write the meta count */ - if (camel_file_util_encode_uint32 (fp, thread_list ? 1 : 0) == -1) - goto cmeta_err; - - if (!thread_list) { - if (camel_file_util_encode_string (fp, "evolution:thread_list") == -1) - goto cmeta_err; - - if (camel_file_util_encode_string (fp, !thread_list ? "1" : "0") == -1) - goto cmeta_err; - } - - /* write the prop count (only prop is the index prop) */ - if (camel_file_util_encode_uint32 (fp, 1) == -1) - goto cmeta_err; - - /* write the index prop tag (== CAMEL_FOLDER_ARG_LAST|CAMEL_ARG_BOO) */ - if (camel_file_util_encode_uint32 (fp, CAMEL_FOLDER_ARG_LAST|CAMEL_ARG_BOO) == -1) - goto cmeta_err; - - /* write the index prop value */ - if (camel_file_util_encode_uint32 (fp, 1) == -1) - goto cmeta_err; - - fflush (fp); - - if (fsync (fd) == -1) { - cmeta_err: - fclose (fp); - unlink (dest->str); - } else { - fclose (fp); - } - } - - /* copy over the metadata files */ - for (i = 0; i < G_N_ELEMENTS (meta_ext); i++) { - g_string_truncate (src, slen); - g_string_truncate (dest, dlen); - - g_string_append (src, meta_ext[i]); - g_string_append (dest, meta_ext[i]); - cp (src->str, dest->str, FALSE, CP_OVERWRITE); - } - } else { - guint32 flags = CAMEL_STORE_FOLDER_CREATE; - - if (!(local_store = camel_session_get_store ((CamelSession *) session, uri, &ex)) - || !(old_folder = camel_store_get_folder (local_store, name, 0, &ex))) - goto fatal; - - flags |= (index ? CAMEL_STORE_FOLDER_BODY_INDEX : 0); - if (!(new_folder = camel_store_get_folder (session->store, full_name, flags, &ex))) - goto fatal; - - if (!thread_list) { - camel_object_meta_set (new_folder, "evolution:thread_list", !thread_list ? "1" : "0"); - camel_object_state_write (new_folder); - } - - uids = camel_folder_get_uids (old_folder); - for (i = 0; i < uids->len; i++) { - CamelMimeMessage *message; - CamelMessageInfo *info; - - if (!(info = camel_folder_get_message_info (old_folder, uids->pdata[i]))) - continue; - - if (!(message = camel_folder_get_message (old_folder, uids->pdata[i], &ex))) { - camel_folder_free_message_info (old_folder, info); - camel_folder_free_uids (old_folder, uids); - goto fatal; - } - - camel_folder_append_message (new_folder, message, info, NULL, &ex); - camel_folder_free_message_info (old_folder, info); - camel_object_unref (message); - - if (camel_exception_is_set (&ex)) - break; - - em_migrate_set_progress (((double) i + 1) / ((double) uids->len)); - } - - camel_folder_free_uids (old_folder, uids); - - if (camel_exception_is_set (&ex)) - goto fatal; - } - success = TRUE; -fatal: - g_free (uri); - g_free (name); - g_string_free(src, TRUE); - g_string_free(dest, TRUE); - if (local_store) - camel_object_unref(local_store); - if (old_folder) - camel_object_unref(old_folder); - if (new_folder) - camel_object_unref(new_folder); - - if (camel_exception_is_set (&ex)) { - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - "%s", camel_exception_get_description (&ex)); - camel_exception_clear (&ex); - } - - return success; -} - -static gboolean -em_migrate_dir (EMMigrateSession *session, const gchar *dirname, const gchar *full_name, GError **error) -{ - gchar *path; - DIR *dir; - struct stat st; - struct dirent *dent; - gboolean success = TRUE; - - if (!em_migrate_folder(session, dirname, full_name, error)) - return FALSE; - - /* no subfolders, not readable, don't care */ - path = g_strdup_printf ("%s/subfolders", dirname); - if (stat (path, &st) == -1 || !S_ISDIR (st.st_mode)) { - g_free (path); - return TRUE; - } - - if (!(dir = opendir (path))) { - g_free (path); - return TRUE; - } - - while (success && (dent = readdir (dir))) { - gchar *full_path; - gchar *name; - - if (dent->d_name[0] == '.') - continue; - - full_path = g_strdup_printf ("%s/%s", path, dent->d_name); - if (stat (full_path, &st) == -1 || !S_ISDIR (st.st_mode)) { - g_free (full_path); - continue; - } - - name = g_strdup_printf ("%s/%s", full_name, dent->d_name); - success = em_migrate_dir (session, full_path, name, error); - g_free (full_path); - g_free (name); - } - - closedir (dir); - - g_free (path); - - return success; -} - -static gboolean -em_migrate_local_folders_1_4 (EMMigrateSession *session, GError **error) -{ - struct dirent *dent; - struct stat st; - DIR *dir; - gboolean success = TRUE; - - if (!(dir = opendir (session->srcdir))) { - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Unable to scan for existing mailboxes at " - "'%s': %s"), session->srcdir, g_strerror (errno)); - return FALSE; - } - - em_migrate_setup_progress_dialog ( - _("Migrating Folders"), - _("The location and hierarchy of the Evolution mailbox " - "folders has changed since Evolution 1.x.\n\nPlease be " - "patient while Evolution migrates your folders...")); - - while (success && (dent = readdir (dir))) { - gchar *full_path; - - if (dent->d_name[0] == '.') - continue; - - full_path = g_strdup_printf ("%s/%s", session->srcdir, dent->d_name); - if (stat (full_path, &st) == -1 || !S_ISDIR (st.st_mode)) { - g_free (full_path); - continue; - } - - success = em_migrate_dir (session, full_path, dent->d_name, error); - g_free (full_path); - } - - closedir (dir); - - em_migrate_close_progress_dialog (); - - return success; -} - -static gchar * -upgrade_xml_uris_1_4 (const gchar *uri) -{ - gchar *path, *prefix, *p; - CamelURL *url; - - if (!strncmp (uri, "file:", 5)) { - url = camel_url_new (uri, NULL); - camel_url_set_protocol (url, "email"); - camel_url_set_user (url, "local"); - camel_url_set_host (url, "local"); - - prefix = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); - if (strncmp (url->path, prefix, strlen (prefix)) != 0) { - /* uri is busticated - user probably copied from another user's home directory */ - camel_url_free (url); - g_free (prefix); - - return g_strdup (uri); - } - path = g_strdup (url->path + strlen (prefix)); - g_free (prefix); - - /* modify the path in-place */ - p = path + strlen (path) - 12; - while (p > path) { - if (!strncmp (p, "/subfolders/", 12)) - memmove (p, p + 11, strlen (p + 11) + 1); - - p--; - } - - camel_url_set_path (url, path); - g_free (path); - - path = camel_url_to_string (url, 0); - camel_url_free (url); - - return path; - } else { - return em_uri_from_camel (uri); - } -} - -static void -upgrade_vfolder_sources_1_4 (xmlDocPtr doc) -{ - xmlNodePtr root, node; - - if (!doc || !(root = xmlDocGetRootElement (doc))) - return; - - if (!root->name || strcmp ((gchar *)root->name, "filteroptions") != 0) { - /* root node is not <filteroptions>, nothing to upgrade */ - return; - } - - if (!(node = xml_find_node (root, "ruleset"))) { - /* no ruleset node, nothing to upgrade */ - return; - } - - node = node->children; - while (node != NULL) { - if (node->name && !strcmp ((gchar *)node->name, "rule")) { - xmlNodePtr sources; - gchar *src; - - if (!(src = (gchar *)xmlGetProp (node, (const guchar *)"source"))) - src = (gchar *)xmlStrdup ((const guchar *)"local"); /* default to all local folders? */ - - xmlSetProp (node, (const guchar *)"source", (const guchar *)"incoming"); - - if (!(sources = xml_find_node (node, "sources"))) - sources = xmlNewChild (node, NULL, (const guchar *)"sources", NULL); - - xmlSetProp (sources, (const guchar *)"with", (guchar *)src); - xmlFree (src); - } - - node = node->next; - } -} - -static gchar * -get_nth_sig (gint id) -{ - ESignatureList *list; - ESignature *sig; - EIterator *iter; - gchar *uid = NULL; - gint i = 0; - - list = e_get_signature_list (); - iter = e_list_get_iterator ((EList *) list); - - while (e_iterator_is_valid (iter) && i < id) { - e_iterator_next (iter); - i++; - } - - if (i == id && e_iterator_is_valid (iter)) { - sig = (ESignature *) e_iterator_get (iter); - uid = g_strdup (e_signature_get_uid (sig)); - } - - g_object_unref (iter); - - return uid; -} - -static void -em_upgrade_accounts_1_4 (void) -{ - EAccountList *accounts; - EIterator *iter; - - if (!(accounts = e_get_account_list ())) - return; - - iter = e_list_get_iterator ((EList *) accounts); - while (e_iterator_is_valid (iter)) { - EAccount *account = (EAccount *) e_iterator_get (iter); - gchar *url; - - if (account->drafts_folder_uri) { - url = upgrade_xml_uris_1_4 (account->drafts_folder_uri); - g_free (account->drafts_folder_uri); - account->drafts_folder_uri = url; - } - - if (account->sent_folder_uri) { - url = upgrade_xml_uris_1_4 (account->sent_folder_uri); - g_free (account->sent_folder_uri); - account->sent_folder_uri = url; - } - - if (account->id->sig_uid && !strncmp (account->id->sig_uid, "::", 2)) { - gint sig_id; - - sig_id = strtol (account->id->sig_uid + 2, NULL, 10); - g_free (account->id->sig_uid); - account->id->sig_uid = get_nth_sig (sig_id); - } - - e_iterator_next (iter); - } - - g_object_unref (iter); - - e_account_list_save (accounts); -} - -static gboolean -em_migrate_pop_uid_caches_1_4 (const gchar *data_dir, GError **error) -{ - GString *oldpath, *newpath; - struct dirent *dent; - gsize olen, nlen; - gchar *cache_dir; - DIR *dir; - gboolean success = TRUE; - - /* Sigh, too many unique strings to translate, for cases which shouldn't ever happen */ - - /* open the old cache dir */ - cache_dir = g_build_filename (g_get_home_dir (), "evolution", "mail", "pop3", NULL); - if (!(dir = opendir (cache_dir))) { - if (errno == ENOENT) { - g_free(cache_dir); - return TRUE; - } - - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Unable to open old POP keep-on-server data " - "'%s': %s"), cache_dir, g_strerror (errno)); - g_free (cache_dir); - return FALSE; - } - - oldpath = g_string_new (cache_dir); - g_string_append_c (oldpath, '/'); - olen = oldpath->len; - g_free (cache_dir); - - cache_dir = g_build_filename (data_dir, "pop", NULL); - if (g_mkdir_with_parents (cache_dir, 0700) == -1) { - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Unable to create POP3 keep-on-server data " - "directory '%s': %s"), cache_dir, - g_strerror (errno)); - g_string_free (oldpath, TRUE); - g_free (cache_dir); - closedir (dir); - return FALSE; - } - - newpath = g_string_new (cache_dir); - g_string_append_c (newpath, '/'); - nlen = newpath->len; - g_free (cache_dir); - - while (success && (dent = readdir (dir))) { - if (strncmp (dent->d_name, "cache-pop:__", 12) != 0) - continue; - - g_string_truncate (oldpath, olen); - g_string_truncate (newpath, nlen); - - g_string_append (oldpath, dent->d_name); - g_string_append (newpath, dent->d_name + 12); - - /* strip the trailing '_' */ - g_string_truncate (newpath, newpath->len - 1); - - if (g_mkdir_with_parents (newpath->str, 0700) == -1 - || !cp(oldpath->str, (g_string_append(newpath, "/uid-cache"))->str, FALSE, CP_UNIQUE)) { - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Unable to copy POP3 keep-on-server data " - "'%s': %s"), oldpath->str, - g_strerror (errno)); - success = FALSE; - } - - } - - g_string_free (oldpath, TRUE); - g_string_free (newpath, TRUE); - - closedir (dir); - - return success; -} - -static gboolean -em_migrate_imap_caches_1_4 (const gchar *data_dir, GError **error) -{ - gchar *src, *dest; - struct stat st; - - src = g_build_filename (g_get_home_dir (), "evolution", "mail", "imap", NULL); - if (stat (src, &st) == -1 || !S_ISDIR (st.st_mode)) { - g_free (src); - return TRUE; - } - - dest = g_build_filename (data_dir, "imap", NULL); - - /* we don't care if this fails, it's only a cache... */ - cp_r (src, dest, "summary", CP_OVERWRITE); - - g_free (dest); - g_free (src); - - return TRUE; -} - -static gboolean -em_migrate_folder_expand_state_1_4 (const gchar *data_dir, GError **error) -{ - GString *srcpath, *destpath; - gsize slen, dlen, rlen; - gchar *evo14_mbox_root; - struct dirent *dent; - struct stat st; - DIR *dir; - - srcpath = g_string_new (g_get_home_dir ()); - g_string_append (srcpath, "/evolution/config"); - if (stat (srcpath->str, &st) == -1 || !S_ISDIR (st.st_mode)) { - g_string_free (srcpath, TRUE); - return TRUE; - } - - destpath = g_string_new (data_dir); - g_string_append (destpath, "/config"); - if (g_mkdir_with_parents (destpath->str, 0700) == -1 || !(dir = opendir (srcpath->str))) { - g_string_free (destpath, TRUE); - g_string_free (srcpath, TRUE); - return TRUE; - } - - g_string_append (srcpath, "/et-expanded-"); - slen = srcpath->len; - g_string_append (destpath, "/et-expanded-"); - dlen = destpath->len; - - evo14_mbox_root = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); - e_filename_make_safe (evo14_mbox_root); - rlen = strlen (evo14_mbox_root); - evo14_mbox_root = g_realloc (evo14_mbox_root, rlen + 2); - evo14_mbox_root[rlen++] = '_'; - evo14_mbox_root[rlen] = '\0'; - - while ((dent = readdir (dir))) { - gchar *full_name, *inptr, *buf = NULL; - const gchar *filename; - GString *new; - - if (strncmp (dent->d_name, "et-expanded-", 12) != 0) - continue; - - if (!strncmp (dent->d_name + 12, "file:", 5)) { - /* need to munge the filename */ - inptr = dent->d_name + 17; - - if (!strncmp (inptr, evo14_mbox_root, rlen)) { - /* this should always be the case afaik... */ - inptr += rlen; - new = g_string_new ("mbox:"); - g_string_append_printf (new, "%s/local#", data_dir); - - full_name = g_strdup (inptr); - inptr = full_name + strlen (full_name) - 12; - while (inptr > full_name) { - if (!strncmp (inptr, "_subfolders_", 12)) - memmove (inptr, inptr + 11, strlen (inptr + 11) + 1); - - inptr--; - } - - g_string_append (new, full_name); - g_free (full_name); - - filename = buf = new->str; - g_string_free (new, FALSE); - e_filename_make_safe (buf); - } else { - /* but just in case... */ - filename = dent->d_name + 12; - } - } else { - /* no munging needed */ - filename = dent->d_name + 12; - } - - g_string_append (srcpath, dent->d_name + 12); - g_string_append (destpath, filename); - g_free (buf); - - cp (srcpath->str, destpath->str, FALSE, CP_UNIQUE); - - g_string_truncate (srcpath, slen); - g_string_truncate (destpath, dlen); - } - - closedir (dir); - - g_free (evo14_mbox_root); - g_string_free (destpath, TRUE); - g_string_free (srcpath, TRUE); - - return TRUE; -} - -static gboolean -em_migrate_folder_view_settings_1_4 (const gchar *data_dir, GError **error) -{ - GString *srcpath, *destpath; - gsize slen, dlen, rlen; - gchar *evo14_mbox_root; - struct dirent *dent; - struct stat st; - DIR *dir; - - srcpath = g_string_new (g_get_home_dir ()); - g_string_append (srcpath, "/evolution/views/mail"); - if (stat (srcpath->str, &st) == -1 || !S_ISDIR (st.st_mode)) { - g_string_free (srcpath, TRUE); - return TRUE; - } - - destpath = g_string_new (data_dir); - g_string_append (destpath, "/views"); - if (g_mkdir_with_parents (destpath->str, 0700) == -1 || !(dir = opendir (srcpath->str))) { - g_string_free (destpath, TRUE); - g_string_free (srcpath, TRUE); - return TRUE; - } - - g_string_append_c (srcpath, '/'); - slen = srcpath->len; - g_string_append_c (destpath, '/'); - dlen = destpath->len; - - evo14_mbox_root = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); - e_filename_make_safe (evo14_mbox_root); - rlen = strlen (evo14_mbox_root); - evo14_mbox_root = g_realloc (evo14_mbox_root, rlen + 2); - evo14_mbox_root[rlen++] = '_'; - evo14_mbox_root[rlen] = '\0'; - - while ((dent = readdir (dir))) { - gchar *full_name, *inptr, *buf = NULL; - const gchar *filename, *ext; - gsize prelen = 0; - GString *new; - - if (dent->d_name[0] == '.') - continue; - - if (!(ext = strrchr (dent->d_name, '.'))) - continue; - - if (!strcmp (ext, ".galview") || !strcmp ((gchar *)dent->d_name, "galview.xml")) { - /* just copy the file */ - filename = dent->d_name; - goto copy; - } else if (strcmp (ext, ".xml") != 0) { - continue; - } - - if (!strncmp ((const gchar *)dent->d_name, "current_view-", 13)) { - prelen = 13; - } else if (!strncmp ((const gchar *)dent->d_name, "custom_view-", 12)) { - prelen = 12; - } else { - /* huh? wtf is this file? */ - continue; - } - - if (!strncmp (dent->d_name + prelen, "file:", 5)) { - /* need to munge the filename */ - inptr = dent->d_name + prelen + 5; - - if (!strncmp (inptr, evo14_mbox_root, rlen)) { - /* this should always be the case afaik... */ - inptr += rlen; - new = g_string_new ("mbox:"); - g_string_append_printf (new, "%s/local#", data_dir); - - full_name = g_strdup (inptr); - inptr = full_name + strlen (full_name) - 12; - while (inptr > full_name) { - if (!strncmp (inptr, "_subfolders_", 12)) - memmove (inptr, inptr + 11, strlen (inptr + 11) + 1); - - inptr--; - } - - g_string_append (new, full_name); - g_free (full_name); - - filename = buf = new->str; - g_string_free (new, FALSE); - e_filename_make_safe (buf); - } else { - /* but just in case... */ - filename = dent->d_name + prelen; - } - } else { - /* no munging needed */ - filename = dent->d_name + prelen; - } - - copy: - g_string_append (srcpath, dent->d_name); - if (prelen > 0) - g_string_append_len (destpath, dent->d_name, prelen); - g_string_append (destpath, filename); - g_free (buf); - - cp (srcpath->str, destpath->str, FALSE, CP_UNIQUE); - - g_string_truncate (srcpath, slen); - g_string_truncate (destpath, dlen); - } - - closedir (dir); - - g_free (evo14_mbox_root); - g_string_free (destpath, TRUE); - g_string_free (srcpath, TRUE); - - return TRUE; -} - #define SUBFOLDER_DIR_NAME "subfolders" #define SUBFOLDER_DIR_NAME_LEN 10 -static gchar * -e_path_to_physical (const gchar *prefix, const gchar *vpath) -{ - const gchar *p, *newp; - gchar *dp; - gchar *ppath; - gint ppath_len; - gint prefix_len; - - while (*vpath == '/') - vpath++; - if (!prefix) - prefix = ""; - - /* Calculate the length of the real path. */ - ppath_len = strlen (vpath); - ppath_len++; /* For the ending zero. */ - - prefix_len = strlen (prefix); - ppath_len += prefix_len; - ppath_len++; /* For the separating slash. */ - - /* Take account of the fact that we need to translate every - * separator into 'subfolders/'. - */ - p = vpath; - while (1) { - newp = strchr (p, '/'); - if (newp == NULL) - break; - - ppath_len += SUBFOLDER_DIR_NAME_LEN; - ppath_len++; /* For the separating slash. */ - - /* Skip consecutive slashes. */ - while (*newp == '/') - newp++; - - p = newp; - }; - - ppath = g_malloc (ppath_len); - dp = ppath; - - memcpy (dp, prefix, prefix_len); - dp += prefix_len; - *(dp++) = '/'; - - /* Copy the mangled path. */ - p = vpath; - while (1) { - newp = strchr (p, '/'); - if (newp == NULL) { - strcpy (dp, p); - break; - } - - memcpy (dp, p, newp - p + 1); /* '+ 1' to copy the slash too. */ - dp += newp - p + 1; - - memcpy (dp, SUBFOLDER_DIR_NAME, SUBFOLDER_DIR_NAME_LEN); - dp += SUBFOLDER_DIR_NAME_LEN; - - *(dp++) = '/'; - - /* Skip consecutive slashes. */ - while (*newp == '/') - newp++; - - p = newp; - } - - return ppath; -} - -static gboolean -em_migrate_imap_cmeta_1_4(const gchar *data_dir, GError **error) -{ - GConfClient *gconf; - GSList *paths, *p; - EAccountList *accounts; - const EAccount *account; - - if (!(accounts = e_get_account_list ())) - return TRUE; - - gconf = gconf_client_get_default(); - paths = gconf_client_get_list(gconf, "/apps/evolution/shell/offline/folder_paths", GCONF_VALUE_STRING, NULL); - for (p = paths;p;p = g_slist_next(p)) { - gchar *name, *path; - - name = p->data; - if (*name) - name++; - path = strchr(name, '/'); - if (path) { - *path++ = 0; - account = e_account_list_find(accounts, E_ACCOUNT_FIND_NAME, name); - if (account && !strncmp(account->source->url, "imap:", 5)) { - CamelURL *url = camel_url_new(account->source->url, NULL); - - if (url) { - gchar *dir, *base; - - base = g_strdup_printf("%s/imap/%s@%s/folders", - data_dir, - url->user?url->user:"", - url->host?url->host:""); - - dir = e_path_to_physical(base, path); - if (g_mkdir_with_parents(dir, 0700) == 0) { - gchar *cmeta; - FILE *fp; - - cmeta = g_build_filename(dir, "cmeta", NULL); - fp = fopen(cmeta, "w"); - if (fp) { - /* header/version */ - fwrite("CLMD", 4, 1, fp); - camel_file_util_encode_uint32(fp, 1); - /* meta count, do we have any metadata? */ - camel_file_util_encode_uint32(fp, 0); - /* prop count */ - camel_file_util_encode_uint32(fp, 1); - /* sync offline property */ - camel_file_util_encode_uint32(fp, CAMEL_DISCO_FOLDER_OFFLINE_SYNC); - camel_file_util_encode_uint32(fp, 1); - fclose(fp); - } else { - g_warning("couldn't create imap folder cmeta file '%s'", cmeta); - } - g_free(cmeta); - } else { - g_warning("couldn't create imap folder directory '%s'", dir); - } - g_free(dir); - g_free(base); - camel_url_free(url); - } - } else - g_warning("can't find offline folder '%s' '%s'", name, path); - } - g_free(p->data); - } - g_slist_free(paths); - g_object_unref(gconf); - - /* we couldn't care less if this doesn't work */ - - return TRUE; -} - -static void -remove_system_searches(xmlDocPtr searches) -{ - xmlNodePtr node; - - /* in pre 2.0, system searches were stored in the user - * searches.xml file with the source set to 'demand'. In 2.0+ - * the system searches are stored in the system - * searchtypes.xml file instead */ - - node = xmlDocGetRootElement(searches); - if (!node->name || strcmp((gchar *)node->name, "filteroptions")) - return; - - if (!(node = xml_find_node(node, "ruleset"))) - return; - - node = node->children; - while (node != NULL) { - xmlNodePtr nnode = node->next; - - if (node->name && !strcmp ((gchar *)node->name, "rule")) { - gchar *src; - - src = (gchar *)xmlGetProp(node, (guchar *)"source"); - if (src && !strcmp((gchar *)src, "demand")) { - xmlUnlinkNode(node); - xmlFreeNodeList(node); - } - xmlFree (src); - } - - node = nnode; - } -} - -static gboolean -em_migrate_1_4 (const gchar *data_dir, xmlDocPtr filters, xmlDocPtr vfolders, GError **error) -{ - EMMigrateSession *session; - CamelException lex; - struct stat st; - gchar *path; - xmlDocPtr searches; - - camel_init (data_dir, TRUE); - camel_provider_init(); - session = (EMMigrateSession *) em_migrate_session_new (data_dir); - - session->srcdir = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); - - path = g_strdup_printf ("mbox:%s/.evolution/mail/local", g_get_home_dir ()); - if (stat (path + 5, &st) == -1) { - if (errno != ENOENT || g_mkdir_with_parents (path + 5, 0700) == -1) { - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Failed to create local mail storage " - "'%s': %s"), path + 5, g_strerror (errno)); - g_free (session->srcdir); - camel_object_unref (session); - g_free (path); - return FALSE; - } - } - - camel_exception_init (&lex); - if (!(session->store = camel_session_get_store ((CamelSession *) session, path, &lex))) { - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Failed to create local mail storage '%s': %s"), - path, lex.desc); - g_free (session->srcdir); - camel_object_unref (session); - camel_exception_clear (&lex); - g_free (path); - return FALSE; - } - g_free (path); - - if (!em_migrate_local_folders_1_4 (session, error)) - return FALSE; - - camel_object_unref (session->store); - g_free (session->srcdir); - - camel_object_unref (session); - - em_upgrade_accounts_1_4(); - - upgrade_xml_uris(filters, upgrade_xml_uris_1_4); - upgrade_vfolder_sources_1_4(vfolders); - upgrade_xml_uris(vfolders, upgrade_xml_uris_1_4); - - path = g_build_filename(g_get_home_dir(), "evolution", NULL); - searches = emm_load_xml(path, "searches.xml"); - g_free(path); - if (searches) { - remove_system_searches(searches); - emm_save_xml(searches, data_dir, "searches.xml"); - xmlFreeDoc(searches); - } - - if (!em_migrate_pop_uid_caches_1_4 (data_dir, error)) - return FALSE; - - /* these are non-fatal */ - em_migrate_imap_caches_1_4 (data_dir, error); - g_clear_error (error); - em_migrate_folder_expand_state_1_4 (data_dir, error); - g_clear_error (error); - em_migrate_folder_view_settings_1_4 (data_dir, error); - g_clear_error (error); - em_migrate_imap_cmeta_1_4 (data_dir, error); - g_clear_error (error); - - return TRUE; -} - static void em_update_accounts_2_11 (void) { @@ -3019,7 +752,6 @@ e_mail_migrate (EShellBackend *shell_backend, { struct stat st; const gchar *data_dir; - gchar *path; /* make sure ~/.evolution/mail exists */ data_dir = e_shell_backend_get_data_dir (shell_backend); @@ -3037,67 +769,6 @@ e_mail_migrate (EShellBackend *shell_backend, if (major == 0) return emm_setup_initial (data_dir); - if (major == 1 && minor < 5) { -#ifndef G_OS_WIN32 - xmlDocPtr config_xmldb = NULL, filters, vfolders; - - path = g_build_filename (g_get_home_dir (), "evolution", NULL); - if (minor <= 2 && !(config_xmldb = emm_load_xml (path, "config.xmldb"))) { - g_set_error ( - error, E_SHELL_MIGRATE_ERROR, - E_SHELL_MIGRATE_ERROR_FAILED, - _("Unable to read settings from previous " - "Evolution install, 'evolution/config.xmldb' " - "does not exist or is corrupt.")); - return FALSE; - } - filters = emm_load_xml (path, "filters.xml"); - vfolders = emm_load_xml (path, "vfolders.xml"); - - if (minor == 0) { - if (!em_migrate_1_0 (data_dir, config_xmldb, filters, vfolders, error)) { - xmlFreeDoc (config_xmldb); - xmlFreeDoc (filters); - xmlFreeDoc (vfolders); - return FALSE; - } - } - - if (minor <= 2) { - if (!em_migrate_1_2 (data_dir, config_xmldb, filters, vfolders, error)) { - xmlFreeDoc (config_xmldb); - xmlFreeDoc (filters); - xmlFreeDoc (vfolders); - return FALSE; - } - - xmlFreeDoc (config_xmldb); - } - - if (minor <= 4) { - if (!em_migrate_1_4 (data_dir, filters, vfolders, error)) { - xmlFreeDoc (filters); - xmlFreeDoc (vfolders); - return FALSE; - } - } - - if (filters) { - emm_save_xml (filters, path, "filters.xml"); - xmlFreeDoc (filters); - } - - if (vfolders) { - emm_save_xml (vfolders, path, "vfolders.xml"); - xmlFreeDoc (vfolders); - } - - g_free (path); -#else - g_error ("Upgrading from ancient versions not supported on Windows"); -#endif - } - if (major < 2 || (major == 2 && minor < 12)) { #ifndef G_OS_WIN32 em_update_accounts_2_11 (); diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c index 8999a1dd15..5d4dd4468d 100644 --- a/mail/mail-vfolder.c +++ b/mail/mail-vfolder.c @@ -66,7 +66,7 @@ static GList *source_folders_local; /* list of source folder uri's - local ones static GHashTable *vfolder_hash; /* This is a slightly hacky solution to shutting down, we poll this variable in various loops, and just quit processing if it is set. */ -static volatile gint shutdown; /* are we shutting down? */ +static volatile gint vfolder_shutdown; /* are we shutting down? */ static void rule_changed(EFilterRule *rule, CamelFolder *folder); @@ -98,7 +98,7 @@ vfolder_setup_exec (struct _setup_msg *m) camel_vee_folder_set_expression((CamelVeeFolder *)m->folder, m->query); l = m->sources_uri; - while (l && !shutdown) { + while (l && !vfolder_shutdown) { d(printf(" Adding uri: %s\n", (gchar *)l->data)); folder = mail_tool_uri_to_folder (l->data, 0, &m->base.ex); @@ -112,14 +112,14 @@ vfolder_setup_exec (struct _setup_msg *m) } l = m->sources_folder; - while (l && !shutdown) { + while (l && !vfolder_shutdown) { d(printf(" Adding folder: %s\n", ((CamelFolder *)l->data)->full_name)); camel_object_ref(l->data); list = g_list_append(list, l->data); l = l->next; } - if (!shutdown) + if (!vfolder_shutdown) camel_vee_folder_set_folders((CamelVeeFolder *)m->folder, list); l = list; @@ -247,7 +247,7 @@ vfolder_adduri_exec (struct _adduri_msg *m) GList *l; CamelFolder *folder = NULL; - if (shutdown) + if (vfolder_shutdown) return; d(printf("%s uri to vfolder: %s\n", m->remove?"Removing":"Adding", m->uri)); @@ -266,7 +266,7 @@ vfolder_adduri_exec (struct _adduri_msg *m) if (folder != NULL) { l = m->folders; - while (l && !shutdown) { + while (l && !vfolder_shutdown) { if (m->remove) camel_vee_folder_remove_folder((CamelVeeFolder *)l->data, folder); else @@ -1335,7 +1335,7 @@ vfolder_foreach_cb (gpointer key, gpointer data, gpointer user_data) void mail_vfolder_shutdown (void) { - shutdown = 1; + vfolder_shutdown = 1; if (vfolder_hash) { g_hash_table_foreach (vfolder_hash, vfolder_foreach_cb, NULL); diff --git a/modules/addressbook/e-book-shell-migrate.c b/modules/addressbook/e-book-shell-migrate.c index 55246ce047..5cc22a50d6 100644 --- a/modules/addressbook/e-book-shell-migrate.c +++ b/modules/addressbook/e-book-shell-migrate.c @@ -45,7 +45,6 @@ #include "e-util/e-util.h" #include "e-util/e-util-private.h" #include "e-util/e-xml-utils.h" -#include "e-util/e-folder-map.h" #include "e-book-shell-migrate.h" @@ -67,378 +66,6 @@ typedef struct { GtkWidget *progress; } MigrationContext; -static void -setup_progress_dialog (MigrationContext *context) -{ - GtkWidget *vbox, *hbox; - - context->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (context->window), _("Migrating...")); - gtk_window_set_modal (GTK_WINDOW (context->window), TRUE); - gtk_container_set_border_width (GTK_CONTAINER (context->window), 6); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_widget_show (vbox); - gtk_container_add (GTK_CONTAINER (context->window), vbox); - - context->label = gtk_label_new (""); - gtk_label_set_line_wrap (GTK_LABEL (context->label), TRUE); - gtk_widget_show (context->label); - gtk_box_pack_start (GTK_BOX (vbox), context->label, TRUE, TRUE, 0); - - hbox = gtk_hbox_new (FALSE, 6); - gtk_widget_show (hbox); - gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); - - context->folder_label = gtk_label_new (""); - gtk_widget_show (context->folder_label); - gtk_box_pack_start (GTK_BOX (hbox), context->folder_label, TRUE, TRUE, 0); - - context->progress = gtk_progress_bar_new (); - gtk_widget_show (context->progress); - gtk_box_pack_start (GTK_BOX (hbox), context->progress, TRUE, TRUE, 0); - - gtk_widget_show (context->window); -} - -static void -dialog_close (MigrationContext *context) -{ - gtk_widget_destroy (context->window); -} - -static void -dialog_set_label (MigrationContext *context, const gchar *str) -{ - gtk_label_set_text (GTK_LABEL (context->label), str); - - while (gtk_events_pending ()) - gtk_main_iteration (); - -#ifdef SLOW_MIGRATION - sleep (1); -#endif -} - -static void -dialog_set_folder_name (MigrationContext *context, const gchar *folder_name) -{ - gchar *text; - - text = g_strdup_printf (_("Migrating '%s':"), folder_name); - gtk_label_set_text (GTK_LABEL (context->folder_label), text); - g_free (text); - - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (context->progress), 0.0); - - while (gtk_events_pending ()) - gtk_main_iteration (); - -#ifdef SLOW_MIGRATION - sleep (1); -#endif -} - -static void -dialog_set_progress (MigrationContext *context, double percent) -{ - gchar text[5]; - - snprintf (text, sizeof (text), "%d%%", (gint) (percent * 100.0f)); - - gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (context->progress), percent); - gtk_progress_bar_set_text (GTK_PROGRESS_BAR (context->progress), text); - - while (gtk_events_pending ()) - gtk_main_iteration (); - -#ifdef SLOW_MIGRATION - sleep (1); -#endif -} - -static gboolean -check_for_conflict (ESourceGroup *group, gchar *name) -{ - GSList *sources; - GSList *s; - - sources = e_source_group_peek_sources (group); - - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - - if (!strcmp (e_source_peek_name (source), name)) - return TRUE; - } - - return FALSE; -} - -static gchar * -get_source_name (ESourceGroup *group, const gchar *path) -{ -#ifndef G_OS_WIN32 - gchar **p = g_strsplit (path, "/", 0); -#else - gchar **p = g_strsplit_set (path, "\\/", 0); -#endif - gint i, j, starting_index; - gint num_elements; - gboolean conflict; - GString *s = g_string_new (""); - - for (i = 0; p[i]; i ++); - - num_elements = i; - i--; - - /* p[i] is now the last path element */ - - /* check if it conflicts */ - starting_index = i; - do { - g_string_assign (s, ""); - for (j = starting_index; j < num_elements; j += 2) { - if (j != starting_index) - g_string_append_c (s, '_'); - g_string_append (s, p[j]); - } - - conflict = check_for_conflict (group, s->str); - - /* if there was a conflict back up 2 levels (skipping the /subfolder/ element) */ - if (conflict) - starting_index -= 2; - - /* we always break out if we can't go any further, - regardless of whether or not we conflict. */ - if (starting_index < 0) - break; - - } while (conflict); - - g_strfreev (p); - - return g_string_free (s, FALSE); -} - -static void -migrate_contacts (MigrationContext *context, EBook *old_book, EBook *new_book) -{ - EBookQuery *query = e_book_query_any_field_contains (""); - GList *l, *contacts; - gint num_added = 0; - gint num_contacts; - - /* both books are loaded, start the actual migration */ - e_book_get_contacts (old_book, query, &contacts, NULL); - e_book_query_unref (query); - - num_contacts = g_list_length (contacts); - for (l = contacts; l; l = l->next) { - EContact *contact = l->data; - GError *e = NULL; - GList *attrs, *attr; - - /* do some last minute massaging of the contact's attributes */ - - attrs = e_vcard_get_attributes (E_VCARD (contact)); - for (attr = attrs; attr;) { - EVCardAttribute *a = attr->data; - - /* evo 1.4 used the non-standard X-EVOLUTION-OFFICE attribute, - evo 1.5 uses the third element in the ORG list attribute. */ - if (!strcmp ("X-EVOLUTION-OFFICE", e_vcard_attribute_get_name (a))) { - GList *v = e_vcard_attribute_get_values (a); - GList *next_attr; - - if (v && v->data) - e_contact_set (contact, E_CONTACT_OFFICE, v->data); - - next_attr = attr->next; - e_vcard_remove_attribute (E_VCARD (contact), a); - attr = next_attr; - } - /* evo 1.4 didn't put TYPE=VOICE in for phone numbers. - evo 1.5 does. - - so we search through the attribute params for - either TYPE=VOICE or TYPE=FAX. If we find - either we do nothing. If we find neither, we - add TYPE=VOICE. - */ - else if (!strcmp ("TEL", e_vcard_attribute_get_name (a))) { - GList *params, *param; - gboolean found = FALSE; - - params = e_vcard_attribute_get_params (a); - for (param = params; param; param = param->next) { - EVCardAttributeParam *p = param->data; - if (!strcmp (EVC_TYPE, e_vcard_attribute_param_get_name (p))) { - GList *v = e_vcard_attribute_param_get_values (p); - while (v && v->data) { - if (!strcmp ("VOICE", v->data) - || !strcmp ("FAX", v->data)) { - found = TRUE; - break; - } - v = v->next; - } - } - } - - if (!found) - e_vcard_attribute_add_param_with_value (a, - e_vcard_attribute_param_new (EVC_TYPE), - "VOICE"); - attr = attr->next; - } - /* Replace "POSTAL" (1.4) addresses with "OTHER" (1.5) */ - else if (!strcmp ("ADR", e_vcard_attribute_get_name (a))) { - GList *params, *param; - gboolean found = FALSE; - EVCardAttributeParam *p; - - params = e_vcard_attribute_get_params (a); - for (param = params; param; param = param->next) { - p = param->data; - if (!strcmp (EVC_TYPE, e_vcard_attribute_param_get_name (p))) { - GList *v = e_vcard_attribute_param_get_values (p); - while (v && v->data ) { - if (!strcmp ("POSTAL", v->data)) { - found = TRUE; - break; - } - v = v->next; - } - if (found) - break; - } - } - - if (found) { - e_vcard_attribute_param_remove_values (p); - e_vcard_attribute_param_add_value (p, "OTHER"); - } - - attr = attr->next; - } - /* this is kinda gross. The new vcard parser - needs ';'s to be escaped by \'s. but the - 1.4 vcard generator would put unescaped xml - (including entities like >) in the value - of attributes, so we need to go through and - escape those ';'s. */ - else if (!strcmp ("EMAIL", e_vcard_attribute_get_name (a))) { - GList *params; - GList *v = e_vcard_attribute_get_values (a); - - /* Add TYPE=OTHER if there is no type set */ - params = e_vcard_attribute_get_params (a); - if (!params) - e_vcard_attribute_add_param_with_value (a, - e_vcard_attribute_param_new (EVC_TYPE), - "OTHER"); - - if (v && v->data) { - if (!strncmp ((gchar *)v->data, "<?xml", 5)) { - /* k, this is the nasty part. we glomb all the - value strings back together again (if there is - more than one), then work our magic */ - GString *str = g_string_new (""); - while (v) { - g_string_append (str, v->data); - if (v->next) - g_string_append_c (str, ';'); - v = v->next; - } - - e_vcard_attribute_remove_values (a); - e_vcard_attribute_add_value (a, str->str); - g_string_free (str, TRUE); - } - } - - attr = attr->next; - } - else { - attr = attr->next; - } - } - - if (!e_book_add_contact (new_book, - contact, - &e)) - g_warning ("contact add failed: '%s'", e->message); - - num_added ++; - - dialog_set_progress (context, (double)num_added / num_contacts); - } - - g_list_foreach (contacts, (GFunc)g_object_unref, NULL); - g_list_free (contacts); -} - -static void -migrate_contact_folder_to_source (MigrationContext *context, gchar *old_path, ESource *new_source) -{ - gchar *old_uri = g_filename_to_uri (old_path, NULL, NULL); - GError *e = NULL; - - EBook *old_book = NULL, *new_book = NULL; - ESource *old_source; - ESourceGroup *group; - - group = e_source_group_new ("", old_uri); - old_source = e_source_new ("", ""); - e_source_group_add_source (group, old_source, -1); - - dialog_set_folder_name (context, e_source_peek_name (new_source)); - - old_book = e_book_new (old_source, &e); - if (!old_book - || !e_book_open (old_book, TRUE, &e)) { - g_warning ("failed to load source book for migration: '%s'", e->message); - goto finish; - } - - new_book = e_book_new (new_source, &e); - if (!new_book - || !e_book_open (new_book, FALSE, &e)) { - g_warning ("failed to load destination book for migration: '%s'", e->message); - goto finish; - } - - migrate_contacts (context, old_book, new_book); - - finish: - g_object_unref (old_source); - g_object_unref (group); - if (old_book) - g_object_unref (old_book); - if (new_book) - g_object_unref (new_book); - g_free (old_uri); -} - -static void -migrate_contact_folder (MigrationContext *context, gchar *old_path, ESourceGroup *dest_group, gchar *source_name) -{ - ESource *new_source; - - new_source = e_source_new (source_name, source_name); - e_source_set_relative_uri (new_source, e_source_peek_uid (new_source)); - e_source_group_add_source (dest_group, new_source, -1); - - g_hash_table_insert (context->folder_uid_map, g_strdup (old_path), g_strdup (e_source_peek_uid (new_source))); - - migrate_contact_folder_to_source (context, old_path, new_source); - - g_object_unref (new_source); -} - #define LDAP_BASE_URI "ldap://" #define PERSONAL_RELATIVE_URI "system" @@ -524,562 +151,6 @@ create_groups (MigrationContext *context, g_free (base_uri); } -static gboolean -migrate_local_folders (MigrationContext *context, ESourceGroup *on_this_computer, ESource *personal_source) -{ - gchar *old_path = NULL; - GSList *dirs, *l; - gchar *local_contact_folder = NULL; - - old_path = g_strdup_printf ("%s/evolution/local", g_get_home_dir ()); - - dirs = e_folder_map_local_folders (old_path, "contacts"); - - /* migrate the local addressbook first, to local/system */ - local_contact_folder = g_build_filename (g_get_home_dir (), - "evolution", "local", "Contacts", - NULL); - - for (l = dirs; l; l = l->next) { - gchar *source_name; - /* we handle the system folder differently */ - if (personal_source && !strcmp ((gchar *)l->data, local_contact_folder)) { - g_hash_table_insert (context->folder_uid_map, g_strdup (l->data), g_strdup (e_source_peek_uid (personal_source))); - migrate_contact_folder_to_source (context, local_contact_folder, personal_source); - continue; - } - - source_name = get_source_name (on_this_computer, (gchar *)l->data); - migrate_contact_folder (context, l->data, on_this_computer, source_name); - g_free (source_name); - } - - g_slist_foreach (dirs, (GFunc)g_free, NULL); - g_slist_free (dirs); - g_free (local_contact_folder); - g_free (old_path); - - return TRUE; -} - -static gchar * -get_string_child (xmlNode *node, - const gchar *name) -{ - xmlNode *p; - xmlChar *xml_string; - gchar *retval; - - p = e_xml_get_child_by_name (node, (xmlChar *) name); - if (p == NULL) - return NULL; - - p = e_xml_get_child_by_name (p, (xmlChar *) "text"); - if (p == NULL) /* there's no text between the tags, return the empty string */ - return g_strdup(""); - - xml_string = xmlNodeListGetString (node->doc, p, 1); - retval = g_strdup ((gchar *) xml_string); - xmlFree (xml_string); - - return retval; -} - -static gint -get_integer_child (xmlNode *node, - const gchar *name, - gint defval) -{ - xmlNode *p; - xmlChar *xml_string; - gint retval; - - p = e_xml_get_child_by_name (node, (xmlChar *) name); - if (p == NULL) - return defval; - - p = e_xml_get_child_by_name (p, (xmlChar *) "text"); - if (p == NULL) /* there's no text between the tags, return the default */ - return defval; - - xml_string = xmlNodeListGetString (node->doc, p, 1); - retval = atoi ((gchar *)xml_string); - xmlFree (xml_string); - - return retval; -} - -static gboolean -migrate_ldap_servers (MigrationContext *context, ESourceGroup *on_ldap_servers) -{ - gchar *sources_xml = g_strdup_printf ("%s/evolution/addressbook-sources.xml", - g_get_home_dir ()); - - printf ("trying to migrate from %s\n", sources_xml); - - if (g_file_test (sources_xml, G_FILE_TEST_EXISTS)) { - xmlDoc *doc = xmlParseFile (sources_xml); - xmlNode *root; - xmlNode *child; - gint num_contactservers; - gint servernum; - - if (!doc) - return FALSE; - - root = xmlDocGetRootElement (doc); - if (root == NULL || strcmp ((const gchar *)root->name, "addressbooks") != 0) { - xmlFreeDoc (doc); - return FALSE; - } - - /* count the number of servers, so we can give progress */ - num_contactservers = 0; - for (child = root->children; child; child = child->next) { - if (!strcmp ((const gchar *)child->name, "contactserver")) { - num_contactservers++; - } - } - printf ("found %d contact servers to migrate\n", num_contactservers); - - dialog_set_folder_name (context, _("LDAP Servers")); - - servernum = 0; - for (child = root->children; child; child = child->next) { - if (!strcmp ((const gchar *)child->name, "contactserver")) { - gchar *port, *host, *rootdn, *scope, *authmethod, *ssl; - gchar *emailaddr, *binddn, *limitstr; - gint limit; - gchar *name, *description; - GString *uri = g_string_new (""); - ESource *source; - - name = get_string_child (child, "name"); - description = get_string_child (child, "description"); - port = get_string_child (child, "port"); - host = get_string_child (child, "host"); - rootdn = get_string_child (child, "rootdn"); - scope = get_string_child (child, "scope"); - authmethod = get_string_child (child, "authmethod"); - ssl = get_string_child (child, "ssl"); - emailaddr = get_string_child (child, "emailaddr"); - binddn = get_string_child (child, "binddn"); - limit = get_integer_child (child, "limit", 100); - limitstr = g_strdup_printf ("%d", limit); - - g_string_append_printf (uri, - "%s:%s/%s?"/*trigraph prevention*/"?%s", - host, port, rootdn, scope); - - source = e_source_new (name, uri->str); - e_source_set_property (source, "description", description); - e_source_set_property (source, "limit", limitstr); - e_source_set_property (source, "ssl", ssl); - e_source_set_property (source, "auth", authmethod); - if (emailaddr) - e_source_set_property (source, "email_addr", emailaddr); - if (binddn) - e_source_set_property (source, "binddn", binddn); - - e_source_group_add_source (on_ldap_servers, source, -1); - - g_string_free (uri, TRUE); - g_free (port); - g_free (host); - g_free (rootdn); - g_free (scope); - g_free (authmethod); - g_free (ssl); - g_free (emailaddr); - g_free (binddn); - g_free (limitstr); - g_free (name); - g_free (description); - - servernum++; - dialog_set_progress (context, (double)servernum/num_contactservers); - } - } - - xmlFreeDoc (doc); - } - - g_free (sources_xml); - - return TRUE; -} - -static ESource* -get_source_by_name (ESourceList *source_list, const gchar *name) -{ - GSList *groups; - GSList *g; - - groups = e_source_list_peek_groups (source_list); - if (!groups) - return NULL; - - for (g = groups; g; g = g->next) { - GSList *sources; - GSList *s; - ESourceGroup *group = E_SOURCE_GROUP (g->data); - - sources = e_source_group_peek_sources (group); - if (!sources) - continue; - - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - const gchar *source_name = e_source_peek_name (source); - - if (!strcmp (name, source_name)) - return source; - } - } - - return NULL; -} - -static gboolean -migrate_completion_folders (MigrationContext *context) -{ - GConfClient *client; - const gchar *key; - gchar *uris_xml; - - printf ("trying to migrate completion folders\n"); - - client = gconf_client_get_default (); - key = "/apps/evolution/addressbook/completion/uris"; - uris_xml = gconf_client_get_string (client, key, NULL); - g_object_unref (client); - - if (uris_xml) { - xmlDoc *doc = xmlParseMemory (uris_xml, strlen (uris_xml)); - xmlNode *root; - xmlNode *child; - - if (!doc) - return FALSE; - - dialog_set_folder_name (context, _("Autocompletion Settings")); - - root = xmlDocGetRootElement (doc); - if (root == NULL || strcmp ((const gchar *)root->name, "EvolutionFolderList") != 0) { - xmlFreeDoc (doc); - return FALSE; - } - - for (child = root->children; child; child = child->next) { - if (!strcmp ((const gchar *)child->name, "folder")) { - gchar *physical_uri = e_xml_get_string_prop_by_name (child, (const guchar *)"physical-uri"); - ESource *source = NULL; - - /* if the physical uri is file://... - we look it up in our folder_uid_map - hashtable. If it's a folder we - converted over, we should get back - a uid we can search for. - - if the physical_uri is anything - else, we strip off the args - (anything after;) before searching - for the uri. */ - - if (!strncmp (physical_uri, "file://", 7)) { - gchar *filename = g_filename_from_uri (physical_uri, NULL, NULL); - gchar *uid = NULL; - - if (filename) - uid = g_hash_table_lookup (context->folder_uid_map, - filename); - g_free (filename); - if (uid) - source = e_source_list_peek_source_by_uid (context->source_list, uid); - } - else { - gchar *name = e_xml_get_string_prop_by_name (child, (const guchar *)"display-name"); - - source = get_source_by_name (context->source_list, name); - - g_free (name); - } - - if (source) { - e_source_set_property (source, "completion", "true"); - } - else { - g_warning ("found completion folder with uri '%s' that " - "doesn't correspond to anything we migrated.", physical_uri); - } - - g_free (physical_uri); - } - } - - g_free (uris_xml); - } - else { - g_message ("no completion folder settings to migrate"); - } - - return TRUE; -} - -static void -migrate_contact_lists_for_local_folders (MigrationContext *context, ESourceGroup *on_this_computer) -{ - GSList *sources, *s; - - sources = e_source_group_peek_sources (on_this_computer); - for (s = sources; s; s = s->next) { - ESource *source = s->data; - EBook *book; - EBookQuery *query; - GList *l, *contacts; - gint num_contacts, num_converted; - - dialog_set_folder_name (context, e_source_peek_name (source)); - - book = e_book_new (source, NULL); - if (!book - || !e_book_open (book, TRUE, NULL)) { - gchar *uri = e_source_get_uri (source); - g_warning ("failed to migrate contact lists for source %s", uri); - g_free (uri); - continue; - } - - query = e_book_query_any_field_contains (""); - e_book_get_contacts (book, query, &contacts, NULL); - e_book_query_unref (query); - - num_converted = 0; - num_contacts = g_list_length (contacts); - for (l = contacts; l; l = l->next) { - EContact *contact = l->data; - GError *e = NULL; - GList *attrs, *attr; - gboolean converted = FALSE; - - attrs = e_contact_get_attributes (contact, E_CONTACT_EMAIL); - for (attr = attrs; attr; attr = attr->next) { - EVCardAttribute *a = attr->data; - GList *v = e_vcard_attribute_get_values (a); - - if (v && v->data) { - if (!strncmp ((gchar *)v->data, "<?xml", 5)) { - EDestination *dest = e_destination_import ((gchar *)v->data); - - e_destination_export_to_vcard_attribute (dest, a); - - g_object_unref (dest); - - converted = TRUE; - } - } - } - - if (converted) { - e_contact_set_attributes (contact, E_CONTACT_EMAIL, attrs); - - if (!e_book_commit_contact (book, - contact, - &e)) - g_warning ("contact commit failed: '%s'", e->message); - } - - num_converted ++; - - dialog_set_progress (context, (double)num_converted / num_contacts); - } - - g_list_foreach (contacts, (GFunc)g_object_unref, NULL); - g_list_free (contacts); - - g_object_unref (book); - } -} - -static void -migrate_company_phone_for_local_folders (MigrationContext *context, ESourceGroup *on_this_computer) -{ - GSList *sources, *s; - - sources = e_source_group_peek_sources (on_this_computer); - for (s = sources; s; s = s->next) { - ESource *source = s->data; - EBook *book; - EBookQuery *query; - GList *l, *contacts; - gint num_contacts, num_converted; - - dialog_set_folder_name (context, e_source_peek_name (source)); - - book = e_book_new (source, NULL); - if (!book - || !e_book_open (book, TRUE, NULL)) { - gchar *uri = e_source_get_uri (source); - g_warning ("failed to migrate company phone numbers for source %s", uri); - g_free (uri); - continue; - } - - query = e_book_query_any_field_contains (""); - e_book_get_contacts (book, query, &contacts, NULL); - e_book_query_unref (query); - - num_converted = 0; - num_contacts = g_list_length (contacts); - for (l = contacts; l; l = l->next) { - EContact *contact = l->data; - GError *e = NULL; - GList *attrs, *attr; - gboolean converted = FALSE; - gint num_work_voice = 0; - - attrs = e_vcard_get_attributes (E_VCARD (contact)); - for (attr = attrs; attr;) { - EVCardAttribute *a = attr->data; - GList *next_attr = attr->next; - - if (!strcmp ("TEL", e_vcard_attribute_get_name (a))) { - GList *params, *param; - gboolean found_voice = FALSE; - gboolean found_work = FALSE; - - params = e_vcard_attribute_get_params (a); - for (param = params; param; param = param->next) { - EVCardAttributeParam *p = param->data; - if (!strcmp (EVC_TYPE, e_vcard_attribute_param_get_name (p))) { - GList *v = e_vcard_attribute_param_get_values (p); - while (v && v->data) { - if (!strcmp ("VOICE", v->data)) - found_voice = TRUE; - else if (!strcmp ("WORK", v->data)) - found_work = TRUE; - v = v->next; - } - } - - if (found_work && found_voice) - num_work_voice++; - - if (num_work_voice == 3) { - GList *v = e_vcard_attribute_get_values (a); - - if (v && v->data) - e_contact_set (contact, E_CONTACT_PHONE_COMPANY, v->data); - - e_vcard_remove_attribute (E_VCARD (contact), a); - - converted = TRUE; - break; - } - } - } - - attr = next_attr; - - if (converted) - break; - } - - if (converted) { - if (!e_book_commit_contact (book, - contact, - &e)) - g_warning ("contact commit failed: '%s'", e->message); - } - - num_converted ++; - - dialog_set_progress (context, (double)num_converted / num_contacts); - } - - g_list_foreach (contacts, (GFunc)g_object_unref, NULL); - g_list_free (contacts); - - g_object_unref (book); - } -} - -static void -migrate_pilot_data (const gchar *old_path, const gchar *new_path) -{ - const gchar *dent; - const gchar *ext; - gchar *filename; - GDir *dir; - - if (!(dir = g_dir_open (old_path, 0, NULL))) - return; - - while ((dent = g_dir_read_name (dir))) { - if ((!strncmp (dent, "pilot-map-", 10) && - ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) || - (!strncmp (dent, "pilot-sync-evolution-addressbook-", 33) && - ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db")))) { - /* src and dest file formats are identical for both map and changelog files */ - guchar inbuf[4096]; - gsize nread, nwritten; - gint fd0, fd1; - gssize n; - - filename = g_build_filename (old_path, dent, NULL); - if ((fd0 = g_open (filename, O_RDONLY | O_BINARY, 0)) == -1) { - g_free (filename); - continue; - } - - g_free (filename); - filename = g_build_filename (new_path, dent, NULL); - if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) { - g_free (filename); - close (fd0); - continue; - } - - do { - do { - n = read (fd0, inbuf, sizeof (inbuf)); - } while (n == -1 && errno == EINTR); - - if (n < 1) - break; - - nread = n; - nwritten = 0; - do { - do { - n = write (fd1, inbuf + nwritten, nread - nwritten); - } while (n == -1 && errno == EINTR); - - if (n > 0) - nwritten += n; - } while (nwritten < nread && n != -1); - - if (n == -1) - break; - } while (1); - - if (n != -1) - n = fsync (fd1); - - if (n == -1) { - g_warning ("Failed to migrate %s: %s", dent, g_strerror (errno)); - g_unlink (filename); - } - - close (fd0); - close (fd1); - g_free (filename); - } - } - - g_dir_close (dir); -} - static MigrationContext * migration_context_new (const gchar *data_dir) { @@ -1121,7 +192,6 @@ e_book_shell_backend_migrate (EShellBackend *shell_backend, ESourceGroup *on_ldap_servers; ESource *personal_source; MigrationContext *context; - gboolean need_dialog = FALSE; const gchar *data_dir; g_return_val_if_fail (E_IS_SHELL_BACKEND (shell_backend), FALSE); @@ -1134,87 +204,6 @@ e_book_shell_backend_migrate (EShellBackend *shell_backend, groups/sources. */ create_groups (context, &on_this_computer, &on_ldap_servers, &personal_source); - /* figure out if we need the dialog displayed */ - if (major == 1 - /* we only need the most recent upgrade point here. - further decomposition will happen below. */ - && (minor < 5 || (minor == 5 && micro <= 10))) - need_dialog = TRUE; - - if (need_dialog) - setup_progress_dialog (context); - - if (major == 1) { - - if (minor < 5 || (minor == 5 && micro <= 2)) { - /* initialize our dialog */ - dialog_set_label (context, - _("The location and hierarchy of the Evolution contact " - "folders has changed since Evolution 1.x.\n\nPlease be " - "patient while Evolution migrates your folders...")); - - if (on_this_computer) - migrate_local_folders (context, on_this_computer, personal_source); - if (on_ldap_servers) - migrate_ldap_servers (context, on_ldap_servers); - - migrate_completion_folders (context); - } - - if (minor < 5 || (minor == 5 && micro <= 7)) { - dialog_set_label (context, - _("The format of mailing list contacts has changed.\n\n" - "Please be patient while Evolution migrates your " - "folders...")); - - migrate_contact_lists_for_local_folders (context, on_this_computer); - } - - if (minor < 5 || (minor == 5 && micro <= 8)) { - dialog_set_label (context, - _("The way Evolution stores some phone numbers has changed.\n\n" - "Please be patient while Evolution migrates your " - "folders...")); - - migrate_company_phone_for_local_folders (context, on_this_computer); - } - - if (minor < 5 || (minor == 5 && micro <= 10)) { - gchar *old_path, *new_path; - - dialog_set_label (context, _("Evolution's Palm Sync changelog and map files have changed.\n\n" - "Please be patient while Evolution migrates your Pilot Sync data...")); - - old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Contacts", NULL); - new_path = g_build_filename (data_dir, "local", "system", NULL); - migrate_pilot_data (old_path, new_path); - g_free (new_path); - g_free (old_path); - } - - /* we only need to do this next step if people ran - older versions of 1.5. We need to clear out the - absolute URI's that were assigned to ESources - during one phase of development, as they take - precedent over relative uris (but aren't updated - when editing an ESource). */ - if (minor == 5 && micro <= 11) { - GSList *g; - for (g = e_source_list_peek_groups (context->source_list); g; g = g->next) { - ESourceGroup *group = g->data; - GSList *s; - - for (s = e_source_group_peek_sources (group); s; s = s->next) { - ESource *source = s->data; - e_source_set_absolute_uri (source, NULL); - } - } - } - } - - if (need_dialog) - dialog_close (context); - if (on_this_computer) g_object_unref (on_this_computer); if (on_ldap_servers) diff --git a/modules/calendar/e-cal-shell-migrate.c b/modules/calendar/e-cal-shell-migrate.c index 0e5dee9363..c7511f69f8 100644 --- a/modules/calendar/e-cal-shell-migrate.c +++ b/modules/calendar/e-cal-shell-migrate.c @@ -36,8 +36,6 @@ #include <libedataserver/e-source-list.h> #include <libedataserver/e-xml-hash-utils.h> -#include "e-util/e-bconf-map.h" -#include "e-util/e-folder-map.h" #include "e-util/e-util-private.h" #include "calendar/gui/calendar-config.h" #include "calendar/gui/calendar-config-keys.h" @@ -49,427 +47,6 @@ #define BAD_CONTACTS_BASE_URI "contact://" #define PERSONAL_RELATIVE_URI "system" -static e_gconf_map_t calendar_display_map[] = { - /* /Calendar/Display */ - { "Timezone", "calendar/display/timezone", E_GCONF_MAP_STRING }, - { "Use24HourFormat", "calendar/display/use_24hour_format", E_GCONF_MAP_BOOL }, - { "WeekStartDay", "calendar/display/week_start_day", E_GCONF_MAP_INT }, - { "DayStartHour", "calendar/display/day_start_hour", E_GCONF_MAP_INT }, - { "DayStartMinute", "calendar/display/day_start_minute", E_GCONF_MAP_INT }, - { "DayEndHour", "calendar/display/day_end_hour", E_GCONF_MAP_INT }, - { "DayEndMinute", "calendar/display/day_end_minute", E_GCONF_MAP_INT }, - { "TimeDivisions", "calendar/display/time_divisions", E_GCONF_MAP_INT }, - { "View", "calendar/display/default_view", E_GCONF_MAP_INT }, - { "HPanePosition", "calendar/display/hpane_position", E_GCONF_MAP_FLOAT }, - { "VPanePosition", "calendar/display/vpane_position", E_GCONF_MAP_FLOAT }, - { "MonthHPanePosition", "calendar/display/month_hpane_position", E_GCONF_MAP_FLOAT }, - { "MonthVPanePosition", "calendar/display/month_vpane_position", E_GCONF_MAP_FLOAT }, - { "CompressWeekend", "calendar/display/compress_weekend", E_GCONF_MAP_BOOL }, - { "ShowEventEndTime", "calendar/display/show_event_end", E_GCONF_MAP_BOOL }, - { "WorkingDays", "calendar/display/working_days", E_GCONF_MAP_INT }, - { NULL }, -}; - -static e_gconf_map_t calendar_other_map[] = { - /* /Calendar/Other */ - { "ConfirmDelete", "calendar/prompts/confirm_delete", E_GCONF_MAP_BOOL }, - { "ConfirmExpunge", "calendar/prompts/confirm_purge", E_GCONF_MAP_BOOL }, - { "UseDefaultReminder", "calendar/other/use_default_reminder", E_GCONF_MAP_BOOL }, - { "DefaultReminderInterval", "calendar/other/default_reminder_interval", E_GCONF_MAP_INT }, - { "DefaultReminderUnits", "calendar/other/default_reminder_units", E_GCONF_MAP_STRING }, - { NULL }, -}; - -static e_gconf_map_t calendar_datenavigator_map[] = { - /* /Calendar/DateNavigator */ - { "ShowWeekNumbers", "calendar/date_navigator/show_week_numbers", E_GCONF_MAP_BOOL }, - { NULL }, -}; - -static e_gconf_map_t calendar_alarmnotify_map[] = { - /* /Calendar/AlarmNotify */ - { "LastNotificationTime", "calendar/notify/last_notification_time", E_GCONF_MAP_INT }, - { "CalendarToLoad%i", "calendar/notify/calendars", E_GCONF_MAP_STRING|E_GCONF_MAP_LIST }, - { "BlessedProgram%i", "calendar/notify/programs", E_GCONF_MAP_STRING|E_GCONF_MAP_LIST }, - { NULL }, -}; - -static e_gconf_map_list_t calendar_remap_list[] = { - - { "/Calendar/Display", calendar_display_map }, - { "/Calendar/Other/Map", calendar_other_map }, - { "/Calendar/DateNavigator", calendar_datenavigator_map }, - { "/Calendar/AlarmNotify", calendar_alarmnotify_map }, - - { NULL }, -}; - -static GtkWidget *window; -static GtkLabel *label; -static GtkProgressBar *progress; - -#ifndef G_OS_WIN32 - -/* No previous versions have been available on Win32, so don't - * bother with upgrade support from 1.x on Win32. - */ - -static void -setup_progress_dialog (void) -{ - GtkWidget *vbox, *hbox, *w; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title ((GtkWindow *) window, _("Migrating...")); - gtk_window_set_modal ((GtkWindow *) window, TRUE); - gtk_container_set_border_width ((GtkContainer *) window, 6); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_widget_show (vbox); - gtk_container_add ((GtkContainer *) window, vbox); - - w = gtk_label_new (_("The location and hierarchy of the Evolution calendar " - "folders has changed since Evolution 1.x.\n\nPlease be " - "patient while Evolution migrates your folders...")); - - gtk_label_set_line_wrap ((GtkLabel *) w, TRUE); - gtk_widget_show (w); - gtk_box_pack_start ((GtkBox *) vbox, w, TRUE, TRUE, 0); - - hbox = gtk_hbox_new (FALSE, 6); - gtk_widget_show (hbox); - gtk_box_pack_start ((GtkBox *) vbox, hbox, TRUE, TRUE, 0); - - label = (GtkLabel *) gtk_label_new (""); - gtk_widget_show ((GtkWidget *) label); - gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) label, TRUE, TRUE, 0); - - progress = (GtkProgressBar *) gtk_progress_bar_new (); - gtk_widget_show ((GtkWidget *) progress); - gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) progress, TRUE, TRUE, 0); - - gtk_widget_show (window); -} - -static void -dialog_close (void) -{ - gtk_widget_destroy ((GtkWidget *) window); -} - -static void -dialog_set_folder_name (const gchar *folder_name) -{ - gchar *text; - - text = g_strdup_printf (_("Migrating '%s':"), folder_name); - gtk_label_set_text (label, text); - g_free (text); - - gtk_progress_bar_set_fraction (progress, 0.0); - - while (gtk_events_pending ()) - gtk_main_iteration (); -} - -static void -dialog_set_progress (double percent) -{ - gchar text[5]; - - snprintf (text, sizeof (text), "%d%%", (gint) (percent * 100.0f)); - - gtk_progress_bar_set_fraction (progress, percent); - gtk_progress_bar_set_text (progress, text); - - while (gtk_events_pending ()) - gtk_main_iteration (); -} - -static gboolean -check_for_conflict (ESourceGroup *group, gchar *name) -{ - GSList *sources; - GSList *s; - - sources = e_source_group_peek_sources (group); - - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - - if (!strcmp (e_source_peek_name (source), name)) - return TRUE; - } - - return FALSE; -} - -static gchar * -get_source_name (ESourceGroup *group, const gchar *path) -{ - gchar **p = g_strsplit (path, "/", 0); - gint i, j, starting_index; - gint num_elements; - gboolean conflict; - GString *s = g_string_new (NULL); - - for (i = 0; p[i]; i ++); - - num_elements = i; - i--; - - /* p[i] is now the last path element */ - - /* check if it conflicts */ - starting_index = i; - do { - for (j = starting_index; j < num_elements; j += 2) { - if (j != starting_index) - g_string_append_c (s, '_'); - g_string_append (s, p[j]); - } - - conflict = check_for_conflict (group, s->str); - - /* if there was a conflict back up 2 levels (skipping the /subfolder/ element) */ - if (conflict) - starting_index -= 2; - - /* we always break out if we can't go any further, - regardless of whether or not we conflict. */ - if (starting_index < 0) - break; - - } while (conflict); - g_strfreev (p); - - return g_string_free (s, FALSE); -} - -static gboolean -migrate_ical (ECal *old_ecal, ECal *new_ecal) -{ - GList *l, *objects; - gint num_added = 0; - gint num_objects; - gboolean retval = TRUE; - - /* both ecals are loaded, start the actual migration */ - if (!e_cal_get_object_list (old_ecal, "#t", &objects, NULL)) - return FALSE; - - num_objects = g_list_length (objects); - for (l = objects; l; l = l->next) { - icalcomponent *ical_comp = l->data; - GError *error = NULL; - - if (!e_cal_create_object (new_ecal, ical_comp, NULL, &error)) { - g_warning ("Migration of object failed: %s", error->message); - retval = FALSE; - } - - g_clear_error (&error); - - num_added ++; - dialog_set_progress ((double)num_added / num_objects); - } - - g_list_foreach (objects, (GFunc) icalcomponent_free, NULL); - g_list_free (objects); - - return retval; -} - -static gboolean -migrate_ical_folder_to_source (gchar *old_path, ESource *new_source, ECalSourceType type) -{ - ECal *old_ecal = NULL, *new_ecal = NULL; - ESource *old_source; - ESourceGroup *group; - gchar *old_uri = g_strdup_printf ("file://%s", old_path); - GError *error = NULL; - gboolean retval = FALSE; - - group = e_source_group_new ("", old_uri); - old_source = e_source_new ("", ""); - e_source_group_add_source (group, old_source, -1); - - dialog_set_folder_name (e_source_peek_name (new_source)); - - if (!(old_ecal = e_cal_new (old_source, type))) { - g_warning ("could not find a backend for '%s'", e_source_get_uri (old_source)); - goto finish; - } - if (!e_cal_open (old_ecal, FALSE, &error)) { - g_warning ("failed to load source ecal for migration: '%s' (%s)", error->message, - e_source_get_uri (old_source)); - goto finish; - } - - if (!(new_ecal = e_cal_new (new_source, type))) { - g_warning ("could not find a backend for '%s'", e_source_get_uri (new_source)); - goto finish; - } - if (!e_cal_open (new_ecal, FALSE, &error)) { - g_warning ("failed to load destination ecal for migration: '%s' (%s)", error->message, - e_source_get_uri (new_source)); - goto finish; - } - - retval = migrate_ical (old_ecal, new_ecal); - -finish: - g_clear_error (&error); - if (old_ecal) - g_object_unref (old_ecal); - g_object_unref (group); - if (new_ecal) - g_object_unref (new_ecal); - g_free (old_uri); - - return retval; -} - -static gboolean -migrate_ical_folder (gchar *old_path, ESourceGroup *dest_group, gchar *source_name, ECalSourceType type) -{ - ESource *new_source; - gboolean retval; - - new_source = e_source_new (source_name, source_name); - e_source_set_relative_uri (new_source, e_source_peek_uid (new_source)); - e_source_group_add_source (dest_group, new_source, -1); - - retval = migrate_ical_folder_to_source (old_path, new_source, type); - - g_object_unref (new_source); - - return retval; -} - -#endif /* !G_OS_WIN32 */ - -#ifndef G_OS_WIN32 - -static void -migrate_pilot_db_key (const gchar *key, gpointer user_data) -{ - EXmlHash *xmlhash = user_data; - - e_xmlhash_add (xmlhash, key, ""); -} - -static void -migrate_pilot_data (const gchar *component, const gchar *conduit, const gchar *old_path, const gchar *new_path) -{ - gchar *changelog, *map; - const gchar *dent; - const gchar *ext; - gchar *filename; - GDir *dir; - - if (!(dir = g_dir_open (old_path, 0, NULL))) - return; - - map = g_alloca (12 + strlen (conduit)); - sprintf (map, "pilot-map-%s-", conduit); - - changelog = g_alloca (24 + strlen (conduit)); - sprintf (changelog, "pilot-sync-evolution-%s-", conduit); - - while ((dent = g_dir_read_name (dir))) { - if (!strncmp (dent, map, strlen (map)) && - ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) { - /* pilot map file - src and dest file formats are identical */ - guchar inbuf[4096]; - gsize nread, nwritten; - gint fd0, fd1; - gssize n; - - filename = g_build_filename (old_path, dent, NULL); - if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) { - g_free (filename); - continue; - } - - g_free (filename); - filename = g_build_filename (new_path, dent, NULL); - if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) { - g_free (filename); - close (fd0); - continue; - } - - do { - do { - n = read (fd0, inbuf, sizeof (inbuf)); - } while (n == -1 && errno == EINTR); - - if (n < 1) - break; - - nread = n; - nwritten = 0; - do { - do { - n = write (fd1, inbuf + nwritten, nread - nwritten); - } while (n == -1 && errno == EINTR); - - if (n > 0) - nwritten += n; - } while (nwritten < nread && n != -1); - - if (n == -1) - break; - } while (1); - - if (n != -1) - n = fsync (fd1); - - if (n == -1) { - g_warning ("Failed to migrate %s: %s", dent, strerror (errno)); - g_unlink (filename); - } - - close (fd0); - close (fd1); - g_free (filename); - } else if (!strncmp (dent, changelog, strlen (changelog)) && - ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) { - /* src and dest formats differ, src format is db3 while dest format is xml */ - EXmlHash *xmlhash; - EDbHash *dbhash; - struct stat st; - - filename = g_build_filename (old_path, dent, NULL); - if (g_stat (filename, &st) == -1) { - g_free (filename); - continue; - } - - dbhash = e_dbhash_new (filename); - g_free (filename); - - filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent); - if (g_stat (filename, &st) != -1) - g_unlink (filename); - xmlhash = e_xmlhash_new (filename); - g_free (filename); - - e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash); - - e_dbhash_destroy (dbhash); - - e_xmlhash_write (xmlhash); - e_xmlhash_destroy (xmlhash); - } - } - - g_dir_close (dir); -} - -#endif - static ESourceGroup * create_calendar_contact_source (ESourceList *source_list) { @@ -624,7 +201,6 @@ e_cal_shell_backend_migrate (EShellBackend *shell_backend, ESourceList *source_list; ECalEvent *ece; ECalEventTargetBackend *target; - gboolean retval = FALSE; g_object_get (shell_backend, "source-list", &source_list, NULL); @@ -635,133 +211,6 @@ e_cal_shell_backend_migrate (EShellBackend *shell_backend, shell_backend, source_list, &on_this_computer, &personal_source, &on_the_web, &contacts); -#ifndef G_OS_WIN32 - if (major == 1) { - xmlDocPtr config_doc = NULL; - gchar *conf_file; - struct stat st; - - conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL); - if (lstat (conf_file, &st) == 0 && S_ISREG (st.st_mode)) - config_doc = xmlParseFile (conf_file); - g_free (conf_file); - - if (config_doc && minor <= 2) { - GConfClient *gconf; - gint res = 0; - - /* move bonobo config to gconf */ - gconf = gconf_client_get_default (); - - res = e_bconf_import (gconf, config_doc, calendar_remap_list); - - g_object_unref (gconf); - - xmlFreeDoc(config_doc); - - if (res != 0) { - /* FIXME: set proper domain/code */ - g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb")); - goto fail; - } - } - - if (minor <= 4) { - GSList *migration_dirs, *l; - gchar *path, *local_cal_folder; - - setup_progress_dialog (); - - path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); - migration_dirs = e_folder_map_local_folders (path, "calendar"); - local_cal_folder = g_build_filename (path, "Calendar", NULL); - g_free (path); - - if (personal_source) - migrate_ical_folder_to_source (local_cal_folder, personal_source, E_CAL_SOURCE_TYPE_EVENT); - - for (l = migration_dirs; l; l = l->next) { - gchar *source_name; - - if (personal_source && !strcmp ((gchar *)l->data, local_cal_folder)) - continue; - - source_name = get_source_name (on_this_computer, (gchar *)l->data); - - if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_EVENT)) { - /* FIXME: domain/code */ - g_set_error(error, 0, 0, _("Unable to migrate calendar '%s'"), source_name); - g_free(source_name); - goto fail; - } - - g_free (source_name); - } - - g_free (local_cal_folder); - - dialog_close (); - } - - if (minor <= 4 || (minor == 5 && micro < 5)) { - GConfClient *gconf; - GConfValue *gconf_val; - gint i; - const gchar *keys[] = { - CALENDAR_CONFIG_HPANE_POS, - CALENDAR_CONFIG_VPANE_POS, - CALENDAR_CONFIG_MONTH_HPANE_POS, - CALENDAR_CONFIG_MONTH_VPANE_POS, - NULL - }; - - gconf = gconf_client_get_default (); - - for (i = 0; keys[i]; i++) { - gconf_val = gconf_client_get (gconf, keys[i], NULL); - if (gconf_val) { - if (gconf_val->type != GCONF_VALUE_INT) - gconf_client_unset (gconf, keys[i], NULL); - gconf_value_free (gconf_val); - } - } - - g_object_unref (gconf); - } - - if (minor < 5 || (minor == 5 && micro <= 10)) { - gchar *old_path, *new_path; - - old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Calendar", NULL); - new_path = g_build_filename (e_shell_backend_get_data_dir (shell_backend), - "local", "system", NULL); - migrate_pilot_data ("calendar", "calendar", old_path, new_path); - g_free (new_path); - g_free (old_path); - } - - /* we only need to do this next step if people ran - older versions of 1.5. We need to clear out the - absolute URI's that were assigned to ESources - during one phase of development, as they take - precedent over relative uris (but aren't updated - when editing an ESource). */ - if (minor == 5 && micro <= 11) { - GSList *g; - for (g = e_source_list_peek_groups (source_list); g; g = g->next) { - ESourceGroup *group = g->data; - GSList *s; - - for (s = e_source_group_peek_sources (group); s; s = s->next) { - ESource *source = s->data; - e_source_set_absolute_uri (source, NULL); - } - } - } - - } -#endif /* !G_OS_WIN32 */ - e_source_list_sync (source_list, NULL); /** @Event: component.migration @@ -778,8 +227,6 @@ e_cal_shell_backend_migrate (EShellBackend *shell_backend, target = e_cal_event_target_new_module (ece, shell_backend, source_list, 0); e_event_emit ((EEvent *) ece, "module.migration", (EEventTarget *) target); - retval = TRUE; -fail: if (on_this_computer) g_object_unref (on_this_computer); if (on_the_web) @@ -789,6 +236,6 @@ fail: if (personal_source) g_object_unref (personal_source); - return retval; + return TRUE; } diff --git a/modules/calendar/e-task-shell-migrate.c b/modules/calendar/e-task-shell-migrate.c index 3c3210b472..9fe9870c73 100644 --- a/modules/calendar/e-task-shell-migrate.c +++ b/modules/calendar/e-task-shell-migrate.c @@ -37,8 +37,6 @@ #include <libedataserver/e-xml-hash-utils.h> #include <libedataserver/e-xml-utils.h> -#include "e-util/e-bconf-map.h" -#include "e-util/e-folder-map.h" #include "e-util/e-util-private.h" #include "calendar/gui/calendar-config.h" #include "calendar/gui/calendar-config-keys.h" @@ -47,396 +45,6 @@ #define WEBCAL_BASE_URI "webcal://" #define PERSONAL_RELATIVE_URI "system" -static e_gconf_map_t calendar_tasks_map[] = { - /* /Calendar/Tasks */ - { "HideCompletedTasks", "calendar/tasks/hide_completed", E_GCONF_MAP_BOOL }, - { "HideCompletedTasksUnits", "calendar/tasks/hide_completed_units", E_GCONF_MAP_STRING }, - { "HideCompletedTasksValue", "calendar/tasks/hide_completed_value", E_GCONF_MAP_INT }, - { NULL }, -}; - -static e_gconf_map_t calendar_tasks_colours_map[] = { - /* /Calendar/Tasks/Colors */ - { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING }, - { "TasksOverDue", "calendar/tasks/colors/overdue", E_GCONF_MAP_STRING }, - { "TasksDueToday", "calendar/tasks/colors/due_today", E_GCONF_MAP_STRING }, - { NULL }, -}; - -static e_gconf_map_list_t task_remap_list[] = { - - { "/Calendar/Tasks", calendar_tasks_map }, - { "/Calendar/Tasks/Colors", calendar_tasks_colours_map }, - - { NULL }, -}; - -static GtkWidget *window; -static GtkLabel *label; -static GtkProgressBar *progress; - -#ifndef G_OS_WIN32 - -/* No previous versions have been available on Win32, so don't - * bother with upgrade support from 1.x on Win32. - */ - -static void -setup_progress_dialog (void) -{ - GtkWidget *vbox, *hbox, *w; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title ((GtkWindow *) window, _("Migrating...")); - gtk_window_set_modal ((GtkWindow *) window, TRUE); - gtk_container_set_border_width ((GtkContainer *) window, 6); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_widget_show (vbox); - gtk_container_add ((GtkContainer *) window, vbox); - - w = gtk_label_new (_("The location and hierarchy of the Evolution task " - "folders has changed since Evolution 1.x.\n\nPlease be " - "patient while Evolution migrates your folders...")); - - gtk_label_set_line_wrap ((GtkLabel *) w, TRUE); - gtk_widget_show (w); - gtk_box_pack_start ((GtkBox *) vbox, w, TRUE, TRUE, 0); - - hbox = gtk_hbox_new (FALSE, 6); - gtk_widget_show (hbox); - gtk_box_pack_start ((GtkBox *) vbox, hbox, TRUE, TRUE, 0); - - label = (GtkLabel *) gtk_label_new (""); - gtk_widget_show ((GtkWidget *) label); - gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) label, TRUE, TRUE, 0); - - progress = (GtkProgressBar *) gtk_progress_bar_new (); - gtk_widget_show ((GtkWidget *) progress); - gtk_box_pack_start ((GtkBox *) hbox, (GtkWidget *) progress, TRUE, TRUE, 0); - - gtk_widget_show (window); -} - -static void -dialog_close (void) -{ - gtk_widget_destroy ((GtkWidget *) window); -} - -static void -dialog_set_folder_name (const gchar *folder_name) -{ - gchar *text; - - text = g_strdup_printf (_("Migrating '%s':"), folder_name); - gtk_label_set_text (label, text); - g_free (text); - - gtk_progress_bar_set_fraction (progress, 0.0); - - while (gtk_events_pending ()) - gtk_main_iteration (); -} - -static void -dialog_set_progress (double percent) -{ - gchar text[5]; - - snprintf (text, sizeof (text), "%d%%", (gint) (percent * 100.0f)); - - gtk_progress_bar_set_fraction (progress, percent); - gtk_progress_bar_set_text (progress, text); - - while (gtk_events_pending ()) - gtk_main_iteration (); -} - -static gboolean -check_for_conflict (ESourceGroup *group, gchar *name) -{ - GSList *sources; - GSList *s; - - sources = e_source_group_peek_sources (group); - - for (s = sources; s; s = s->next) { - ESource *source = E_SOURCE (s->data); - - if (!strcmp (e_source_peek_name (source), name)) - return TRUE; - } - - return FALSE; -} - -static gchar * -get_source_name (ESourceGroup *group, const gchar *path) -{ - gchar **p = g_strsplit (path, "/", 0); - gint i, j, starting_index; - gint num_elements; - gboolean conflict; - GString *s = g_string_new (NULL); - - for (i = 0; p[i]; i ++); - - num_elements = i; - i--; - - /* p[i] is now the last path element */ - - /* check if it conflicts */ - starting_index = i; - do { - for (j = starting_index; j < num_elements; j += 2) { - if (j != starting_index) - g_string_append_c (s, '_'); - g_string_append (s, p[j]); - } - - conflict = check_for_conflict (group, s->str); - - /* if there was a conflict back up 2 levels (skipping the /subfolder/ element) */ - if (conflict) - starting_index -= 2; - - /* we always break out if we can't go any further, - regardless of whether or not we conflict. */ - if (starting_index < 0) - break; - - } while (conflict); - g_strfreev (p); - - return g_string_free (s, FALSE); -} - -static gboolean -migrate_ical (ECal *old_ecal, ECal *new_ecal) -{ - GList *l, *objects; - gint num_added = 0; - gint num_objects; - gboolean retval = TRUE; - - /* both ecals are loaded, start the actual migration */ - if (!e_cal_get_object_list (old_ecal, "#t", &objects, NULL)) - return FALSE; - - num_objects = g_list_length (objects); - for (l = objects; l; l = l->next) { - icalcomponent *ical_comp = l->data; - GError *error = NULL; - - if (!e_cal_create_object (new_ecal, ical_comp, NULL, &error)) { - g_warning ("Migration of object failed: %s", error->message); - retval = FALSE; - } - - g_clear_error (&error); - - num_added ++; - dialog_set_progress ((double)num_added / num_objects); - } - - g_list_foreach (objects, (GFunc) icalcomponent_free, NULL); - g_list_free (objects); - - return retval; -} - -static gboolean -migrate_ical_folder_to_source (gchar *old_path, ESource *new_source, ECalSourceType type) -{ - ECal *old_ecal = NULL, *new_ecal = NULL; - ESource *old_source; - ESourceGroup *group; - gchar *old_uri = g_strdup_printf ("file://%s", old_path); - GError *error = NULL; - gboolean retval = FALSE; - - group = e_source_group_new ("", old_uri); - old_source = e_source_new ("", ""); - e_source_group_add_source (group, old_source, -1); - - dialog_set_folder_name (e_source_peek_name (new_source)); - - if (!(old_ecal = e_cal_new (old_source, type))) { - g_warning ("could not find a backend for '%s'", e_source_get_uri (old_source)); - goto finish; - } - if (!e_cal_open (old_ecal, FALSE, &error)) { - g_warning ("failed to load source ecal for migration: '%s' (%s)", error->message, - e_source_get_uri (old_source)); - goto finish; - } - - if (!(new_ecal = e_cal_new (new_source, type))) { - g_warning ("could not find a backend for '%s'", e_source_get_uri (new_source)); - goto finish; - } - if (!e_cal_open (new_ecal, FALSE, &error)) { - g_warning ("failed to load destination ecal for migration: '%s' (%s)", error->message, - e_source_get_uri (new_source)); - goto finish; - } - - retval = migrate_ical (old_ecal, new_ecal); - -finish: - g_clear_error (&error); - if (old_ecal) - g_object_unref (old_ecal); - g_object_unref (group); - if (new_ecal) - g_object_unref (new_ecal); - g_free (old_uri); - - return retval; -} - -static gboolean -migrate_ical_folder (gchar *old_path, ESourceGroup *dest_group, gchar *source_name, ECalSourceType type) -{ - ESource *new_source; - gboolean retval; - - new_source = e_source_new (source_name, source_name); - e_source_set_relative_uri (new_source, e_source_peek_uid (new_source)); - e_source_group_add_source (dest_group, new_source, -1); - - retval = migrate_ical_folder_to_source (old_path, new_source, type); - - g_object_unref (new_source); - - return retval; -} - -#endif /* !G_OS_WIN32 */ - -#ifndef G_OS_WIN32 - -static void -migrate_pilot_db_key (const gchar *key, gpointer user_data) -{ - EXmlHash *xmlhash = user_data; - - e_xmlhash_add (xmlhash, key, ""); -} - -static void -migrate_pilot_data (const gchar *component, const gchar *conduit, const gchar *old_path, const gchar *new_path) -{ - gchar *changelog, *map; - const gchar *dent; - const gchar *ext; - gchar *filename; - GDir *dir; - - if (!(dir = g_dir_open (old_path, 0, NULL))) - return; - - map = g_alloca (12 + strlen (conduit)); - sprintf (map, "pilot-map-%s-", conduit); - - changelog = g_alloca (24 + strlen (conduit)); - sprintf (changelog, "pilot-sync-evolution-%s-", conduit); - - while ((dent = g_dir_read_name (dir))) { - if (!strncmp (dent, map, strlen (map)) && - ((ext = strrchr (dent, '.')) && !strcmp (ext, ".xml"))) { - /* pilot map file - src and dest file formats are identical */ - guchar inbuf[4096]; - gsize nread, nwritten; - gint fd0, fd1; - gssize n; - - filename = g_build_filename (old_path, dent, NULL); - if ((fd0 = g_open (filename, O_RDONLY|O_BINARY, 0)) == -1) { - g_free (filename); - continue; - } - - g_free (filename); - filename = g_build_filename (new_path, dent, NULL); - if ((fd1 = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666)) == -1) { - g_free (filename); - close (fd0); - continue; - } - - do { - do { - n = read (fd0, inbuf, sizeof (inbuf)); - } while (n == -1 && errno == EINTR); - - if (n < 1) - break; - - nread = n; - nwritten = 0; - do { - do { - n = write (fd1, inbuf + nwritten, nread - nwritten); - } while (n == -1 && errno == EINTR); - - if (n > 0) - nwritten += n; - } while (nwritten < nread && n != -1); - - if (n == -1) - break; - } while (1); - - if (n != -1) - n = fsync (fd1); - - if (n == -1) { - g_warning ("Failed to migrate %s: %s", dent, strerror (errno)); - g_unlink (filename); - } - - close (fd0); - close (fd1); - g_free (filename); - } else if (!strncmp (dent, changelog, strlen (changelog)) && - ((ext = strrchr (dent, '.')) && !strcmp (ext, ".db"))) { - /* src and dest formats differ, src format is db3 while dest format is xml */ - EXmlHash *xmlhash; - EDbHash *dbhash; - struct stat st; - - filename = g_build_filename (old_path, dent, NULL); - if (g_stat (filename, &st) == -1) { - g_free (filename); - continue; - } - - dbhash = e_dbhash_new (filename); - g_free (filename); - - filename = g_strdup_printf ("%s/%s.ics-%s", new_path, component, dent); - if (g_stat (filename, &st) != -1) - g_unlink (filename); - xmlhash = e_xmlhash_new (filename); - g_free (filename); - - e_dbhash_foreach_key (dbhash, migrate_pilot_db_key, xmlhash); - - e_dbhash_destroy (dbhash); - - e_xmlhash_write (xmlhash); - e_xmlhash_destroy (xmlhash); - } - } - - g_dir_close (dir); -} - -#endif - static void create_task_sources (EShellBackend *shell_backend, ESourceList *source_list, @@ -553,7 +161,6 @@ e_task_shell_backend_migrate (EShellBackend *shell_backend, ESourceGroup *on_the_web = NULL; ESource *personal_source = NULL; ESourceList *source_list; - gboolean retval = FALSE; g_object_get (shell_backend, "source-list", &source_list, NULL); @@ -564,106 +171,8 @@ e_task_shell_backend_migrate (EShellBackend *shell_backend, shell_backend, source_list, &on_this_computer, &on_the_web, &personal_source); -#ifndef G_OS_WIN32 - if (major == 1) { - xmlDocPtr config_doc = NULL; - gchar *conf_file; - - conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL); - if (g_file_test (conf_file, G_FILE_TEST_IS_REGULAR)) - config_doc = e_xml_parse_file (conf_file); - g_free (conf_file); - - if (config_doc && minor <= 2) { - GConfClient *gconf; - gint res = 0; - - /* move bonobo config to gconf */ - gconf = gconf_client_get_default (); - - res = e_bconf_import (gconf, config_doc, task_remap_list); - - g_object_unref (gconf); - - xmlFreeDoc(config_doc); - - if (res != 0) { - g_set_error(error, 0, 0, _("Unable to migrate old settings from evolution/config.xmldb")); - goto fail; - } - } - - if (minor <= 4) { - GSList *migration_dirs, *l; - gchar *path, *local_task_folder; - - setup_progress_dialog (); - - path = g_build_filename (g_get_home_dir (), "evolution", "local", NULL); - migration_dirs = e_folder_map_local_folders (path, "tasks"); - local_task_folder = g_build_filename (path, "Tasks", NULL); - g_free (path); - - if (personal_source) - migrate_ical_folder_to_source (local_task_folder, personal_source, E_CAL_SOURCE_TYPE_TODO); - - for (l = migration_dirs; l; l = l->next) { - gchar *source_name; - - if (personal_source && !strcmp ((gchar *)l->data, local_task_folder)) - continue; - - source_name = get_source_name (on_this_computer, (gchar *)l->data); - - if (!migrate_ical_folder (l->data, on_this_computer, source_name, E_CAL_SOURCE_TYPE_TODO)) { - /* FIXME: domain/code */ - g_set_error(error, 0, 0, _("Unable to migrate tasks '%s'"), source_name); - g_free(source_name); - goto fail; - } - - g_free (source_name); - } - - g_free (local_task_folder); - - dialog_close (); - } - - if (minor < 5 || (minor == 5 && micro <= 10)) { - gchar *old_path, *new_path; - - old_path = g_build_filename (g_get_home_dir (), "evolution", "local", "Tasks", NULL); - new_path = g_build_filename (e_shell_backend_get_data_dir (shell_backend), - "local", "system", NULL); - migrate_pilot_data ("tasks", "todo", old_path, new_path); - g_free (new_path); - g_free (old_path); - } - - /* we only need to do this next step if people ran - older versions of 1.5. We need to clear out the - absolute URI's that were assigned to ESources - during one phase of development, as they take - precedent over relative uris (but aren't updated - when editing an ESource). */ - if (minor == 5 && micro <= 11) { - GSList *g; - for (g = e_source_list_peek_groups (source_list); g; g = g->next) { - ESourceGroup *group = g->data; - GSList *s; - - for (s = e_source_group_peek_sources (group); s; s = s->next) { - ESource *source = s->data; - e_source_set_absolute_uri (source, NULL); - } - } - } - } -#endif /* !G_OS_WIN32 */ e_source_list_sync (source_list, NULL); - retval = TRUE; -fail: + if (on_this_computer) g_object_unref (on_this_computer); if (on_the_web) @@ -671,5 +180,5 @@ fail: if (personal_source) g_object_unref (personal_source); - return retval; + return TRUE; } diff --git a/shell/Makefile.am b/shell/Makefile.am index 0a93912680..103953d906 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -117,9 +117,7 @@ evolution_CPPFLAGS = \ $(SHELL_CFLAGS) evolution_SOURCES = \ - e-config-upgrade.c \ - e-config-upgrade.h \ - main.c + main.c evolution_LDADD = \ libeshell.la \ diff --git a/shell/e-config-upgrade.c b/shell/e-config-upgrade.c deleted file mode 100644 index a933972b9b..0000000000 --- a/shell/e-config-upgrade.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * e-upgrade.c - upgrade previous config versions - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Michael Zucchi <notzed@ximian.com> - * Jeffery Stedfast <fejj@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#include <config.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <ctype.h> - -#include <glib.h> - -#include <gconf/gconf.h> -#include <gconf/gconf-client.h> - -#include <libedataserver/e-xml-utils.h> - -#include "e-util/e-bconf-map.h" - -#include "e-config-upgrade.h" - -/* ********************************************************************** */ -/* Tables for bonobo conf -> gconf conversion */ -/* ********************************************************************** */ - -/* ********************************************************************** */ - -static e_gconf_map_t importer_elm_map[] = { - /* /Importer/Elm */ - { "mail", "importer/elm/mail", E_GCONF_MAP_BOOL }, - { "mail-imported", "importer/elm/mail-imported", E_GCONF_MAP_BOOL }, - { NULL }, -}; - -static e_gconf_map_t importer_pine_map[] = { - /* /Importer/Pine */ - { "mail", "importer/elm/mail", E_GCONF_MAP_BOOL }, - { "address", "importer/elm/address", E_GCONF_MAP_BOOL }, - { NULL }, -}; - -static e_gconf_map_t importer_netscape_map[] = { - /* /Importer/Netscape */ - { "mail", "importer/netscape/mail", E_GCONF_MAP_BOOL }, - { "settings", "importer/netscape/settings", E_GCONF_MAP_BOOL }, - { "filters", "importer/netscape/filters", E_GCONF_MAP_BOOL }, - { NULL }, -}; - -/* ********************************************************************** */ - -/* This grabs the defaults from the first view ... (?) */ -static e_gconf_map_t shell_views_map[] = { - /* /Shell/Views/0 */ - { "Width", "shell/view_defaults/width", E_GCONF_MAP_INT }, - { "Height", "shell/view_defaults/height", E_GCONF_MAP_INT }, - { "ViewPanedPosition", "shell/view_defaults/folder_bar/width", E_GCONF_MAP_INT }, - { NULL }, -}; - -static e_gconf_map_t offlinefolders_map[] = { - /* /OfflineFolders */ - { "paths", "shell/offline/folder_paths", E_GCONF_MAP_ANYLIST }, - { NULL }, -}; - -static e_gconf_map_t shell_map[] = { - /* /Shell */ - { "StartOffline", "shell/start_offline", E_GCONF_MAP_BOOL }, - { NULL }, -}; - -/* ********************************************************************** */ - -static e_gconf_map_t addressbook_map[] = { - /* /Addressbook */ - { "select_names_uri", "addressbook/select_names/last_used_uri", E_GCONF_MAP_STRING }, - { NULL }, -}; - -static e_gconf_map_t addressbook_completion_map[] = { - /* /Addressbook/Completion */ - { "uris", "addressbook/completion/uris", E_GCONF_MAP_STRING }, - { NULL }, -}; - -/* ********************************************************************** */ - -static e_gconf_map_t general_map[] = { - /* /General */ - { "CategoryMasterList", "general/category_master_list", E_GCONF_MAP_STRING } -}; - -/* ********************************************************************** */ - -static e_gconf_map_list_t remap_list[] = { - { "/Importer/Elm", importer_elm_map }, - { "/Importer/Pine", importer_pine_map }, - { "/Importer/Netscape", importer_netscape_map }, - - { "/Shell", shell_map }, - { "/Shell/Views/0", shell_views_map }, - { "/OfflineFolders", offlinefolders_map }, - - { "/Addressbook", addressbook_map }, - { "/Addressbook/Completion", addressbook_completion_map }, - - { "/General", general_map }, - - { NULL }, -}; - -gint -e_config_upgrade(gint major, gint minor, gint revision) -{ - xmlDocPtr config_doc; - gchar *conf_file; - gint res = 0; - - conf_file = g_build_filename (g_get_home_dir (), "evolution", "config.xmldb", NULL); - config_doc = e_xml_parse_file (conf_file); - g_free (conf_file); - - if (config_doc && major <=1 && minor < 3) { - GConfClient *gconf; - - /* move bonobo config to gconf */ - gconf = gconf_client_get_default (); - - res = e_bconf_import (gconf, config_doc, remap_list); - if (res != 0) - g_warning("Could not move config from bonobo-conf to gconf"); - - g_object_unref (gconf); - - xmlFreeDoc(config_doc); - } - - return res; -} diff --git a/shell/e-config-upgrade.h b/shell/e-config-upgrade.h deleted file mode 100644 index 36901109d7..0000000000 --- a/shell/e-config-upgrade.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Authors: - * Michael Zucchi <notzed@ximian.com> - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef _E_CONFIG_UPGRADE_H -#define _E_CONFIG_UPGRADE_H - -gint e_config_upgrade (gint major, gint minor, gint revision); - -#endif /* _E_CONFIG_UPGRADE_H */ diff --git a/shell/e-shell-migrate.c b/shell/e-shell-migrate.c index dd5ad07b24..d26c9a83d1 100644 --- a/shell/e-shell-migrate.c +++ b/shell/e-shell-migrate.c @@ -27,7 +27,6 @@ #include <glib/gstdio.h> #include <libedataserver/e-xml-utils.h> -#include "e-util/e-bconf-map.h" #include "e-util/e-alert-dialog.h" #include "e-util/e-file-utils.h" #include "e-util/e-util.h" @@ -37,29 +36,36 @@ #define GCONF_VERSION_KEY "/apps/evolution/version" #define GCONF_LAST_VERSION_KEY "/apps/evolution/last_version" -static const gchar * -shell_migrate_get_old_data_dir (void) -{ - static gchar *old_data_dir = NULL; - - if (G_UNLIKELY (old_data_dir == NULL)) - old_data_dir = g_build_filename ( - g_get_home_dir (), "evolution", NULL); - - return old_data_dir; -} - static gboolean shell_migrate_attempt (EShell *shell, gint major, gint minor, gint micro) { + GtkWindow *parent; GList *backends; gboolean success = TRUE; + parent = e_shell_get_active_window (shell); backends = e_shell_get_shell_backends (shell); + /* We only support migrating from version 2 now. */ + if (major < 2) { + gchar *version; + gint response; + + version = g_strdup_printf ("%d.%d", major, minor); + response = e_alert_run_dialog_for_args ( + parent, "shell:upgrade-version-too-old", + version, NULL); + g_free (version); + + return (response == GTK_RESPONSE_OK); + } + + /* Ask each of the shell backends to migrate their own data. + * XXX If something fails the user may end up with only partially + * migrated data. Need transaction semantics here, but how? */ while (success && backends != NULL) { EShellBackend *shell_backend = backends->data; GError *error = NULL; @@ -71,11 +77,10 @@ shell_migrate_attempt (EShell *shell, gint response; response = e_alert_run_dialog_for_args ( - e_shell_get_active_window (shell), "shell:upgrade-failed", + parent, "shell:upgrade-failed", error->message, NULL); - if (response == GTK_RESPONSE_CANCEL) - success = FALSE; + success = (response == GTK_RESPONSE_OK); g_error_free (error); } @@ -94,11 +99,8 @@ shell_migrate_get_version (EShell *shell, { GConfClient *client; const gchar *key; - const gchar *old_data_dir; gchar *string; - old_data_dir = shell_migrate_get_old_data_dir (); - key = GCONF_VERSION_KEY; client = e_shell_get_gconf_client (shell); string = gconf_client_get_string (client, key, NULL); @@ -108,90 +110,12 @@ shell_migrate_get_version (EShell *shell, sscanf (string, "%d.%d.%d", major, minor, micro); g_free (string); - } else if (!g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) { - /* If the old data directory does not exist, - * it must be a new installation. */ + } else { + /* Otherwise, assume it's a new installation. */ *major = 0; *minor = 0; *micro = 0; - - } else { - xmlDocPtr doc; - xmlNodePtr source; - gchar *filename; - - filename = g_build_filename ( - old_data_dir, "config.xmldb", NULL); - doc = e_xml_parse_file (filename); - g_free (filename); - - if (doc == NULL) - return; - - source = e_bconf_get_path (doc, "/Shell"); - if (source != NULL) { - key = "upgrade_from_1_0_to_1_2_performed"; - string = e_bconf_get_value (source, key); - } - - if (string != NULL && *string == '1') { - *major = 1; - *minor = 2; - *micro = 0; - } else { - *major = 1; - *minor = 0; - *micro = 0; - } - - g_free (string); - - if (doc != NULL) - xmlFreeDoc (doc); - } -} - -static gint -shell_migrate_remove_dir (const gchar *root, - const gchar *path) -{ - GDir *dir; - const gchar *basename; - gchar *filename = NULL; - gint result = -1; - - /* Recursively removes a directory and its contents. */ - - dir = g_dir_open (path, 0, NULL); - if (dir == NULL) - return -1; - - while ((basename = g_dir_read_name (dir)) != NULL) { - filename = g_build_filename (path, basename, NULL); - - /* Make sure we haven't strayed from the evolution dir. */ - g_return_val_if_fail (strlen (path) >= strlen (root), -1); - g_return_val_if_fail (g_str_has_prefix (path, root), -1); - - if (g_file_test (filename, G_FILE_TEST_IS_DIR)) { - if (shell_migrate_remove_dir (root, filename) < 0) - goto fail; - } else { - if (g_unlink (filename) < 0) - goto fail; - } - - g_free (filename); - filename = NULL; } - - result = g_rmdir (path); - -fail: - g_free (filename); - g_dir_close (dir); - - return result; } static void @@ -241,7 +165,6 @@ e_shell_migrate_attempt (EShell *shell) ESEvent *ese; GConfClient *client; const gchar *key; - const gchar *old_data_dir; gint major, minor, micro; gint last_major, last_minor, last_micro; gint curr_major, curr_minor, curr_micro; @@ -251,7 +174,6 @@ e_shell_migrate_attempt (EShell *shell) g_return_val_if_fail (E_IS_SHELL (shell), FALSE); client = e_shell_get_gconf_client (shell); - old_data_dir = shell_migrate_get_old_data_dir (); if (sscanf (BASE_VERSION, "%d.%d", &curr_major, &curr_minor) != 2) { g_warning ("Could not parse BASE_VERSION (%s)", BASE_VERSION); @@ -271,38 +193,12 @@ e_shell_migrate_attempt (EShell *shell) (curr_major == major && curr_minor == minor && curr_micro > micro))) goto check_old; - /* If upgrading from < 1.5, we need to copy most data from - * ~/evolution to ~/.evolution. Make sure we have the disk - * space for it before proceeding. */ - if (major == 1 && minor < 5) { - glong avail; - glong usage; - - usage = e_fsutils_usage (old_data_dir); - avail = e_fsutils_avail (g_get_home_dir ()); - if (usage >= 0 && avail >= 0 && avail < usage) { - gchar *need; - gchar *have; - - need = g_strdup_printf (_("%ld KB"), usage); - have = g_strdup_printf (_("%ld KB"), avail); - - e_alert_run_dialog_for_args ( - e_shell_get_active_window (shell), "shell:upgrade-nospace", - need, have, NULL); - - g_free (need); - g_free (have); - - _exit (EXIT_SUCCESS); - } - } - if (!shell_migrate_attempt (shell, major, minor, micro)) _exit (EXIT_SUCCESS); /* Record a successful migration. */ - string = g_strdup_printf ("%d.%d.%d", curr_major, curr_minor, curr_micro); + string = g_strdup_printf ( + "%d.%d.%d", curr_major, curr_minor, curr_micro); gconf_client_set_string (client, GCONF_VERSION_KEY, string, NULL); g_free (string); @@ -322,46 +218,6 @@ check_old: } g_free (string); - /* If the last migrated version was old, check for stuff to remove. */ - if (last_major == 1 && last_minor < 5 && - g_file_test (old_data_dir, G_FILE_TEST_IS_DIR)) { - - gint response; - - string = g_strdup_printf ( - "%d.%d.%d", last_major, last_minor, last_micro); - response = e_alert_run_dialog_for_args ( - e_shell_get_active_window (shell), "shell:upgrade-remove-1-4", string, NULL); - g_free (string); - - switch (response) { - case GTK_RESPONSE_OK: /* delete */ - response = e_alert_run_dialog_for_args ( - e_shell_get_active_window (shell), - "shell:upgrade-remove-1-4-confirm", - NULL); - if (response == GTK_RESPONSE_OK) - shell_migrate_remove_dir ( - old_data_dir, old_data_dir); - else - break; - /* fall through */ - - case GTK_RESPONSE_ACCEPT: /* keep */ - last_major = curr_major; - last_minor = curr_minor; - last_micro = curr_micro; - break; - - default: - break; - } - } else { - last_major = curr_major; - last_minor = curr_minor; - last_micro = curr_micro; - } - string = g_strdup_printf ( "%d.%d.%d", last_major, last_minor, last_micro); gconf_client_set_string (client, key, string, NULL); diff --git a/shell/main.c b/shell/main.c index e3d69412a6..469df2df11 100644 --- a/shell/main.c +++ b/shell/main.c @@ -49,10 +49,8 @@ #include "e-shell.h" #include "e-shell-migrate.h" -#include "e-config-upgrade.h" #include "es-event.h" -#include "e-util/e-bconf-map.h" #include "e-util/e-dialog-utils.h" #include "e-util/e-import.h" #include "e-util/e-plugin.h" @@ -82,9 +80,6 @@ static gboolean start_online = FALSE; static gboolean start_offline = FALSE; static gboolean setup_only = FALSE; static gboolean force_shutdown = FALSE; -#ifdef DEVELOPMENT -static gboolean force_migrate = FALSE; -#endif static gboolean disable_eplugin = FALSE; static gboolean disable_preview = FALSE; static gboolean import_uris = FALSE; @@ -214,21 +209,6 @@ show_development_warning(void) return skip; } -static void -destroy_config (GConfClient *client) -{ - /* Unset the source stuff */ - gconf_client_unset (client, "/apps/evolution/calendar/sources", NULL); - gconf_client_unset (client, "/apps/evolution/tasks/sources", NULL); - gconf_client_unset (client, "/apps/evolution/addressbook/sources", NULL); - - /* Reset the version */ - gconf_client_set_string (client, "/apps/evolution/version", "1.4.0", NULL); - - /* Clear the dir */ - system ("rm -Rf ~/.evolution"); -} - #endif /* DEVELOPMENT */ /* This is for doing stuff that requires the GTK+ loop to be running already. */ @@ -332,10 +312,6 @@ static GOptionEntry entries[] = { { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &force_shutdown, N_("Forcibly shut down Evolution"), NULL }, #endif -#ifdef DEVELOPMENT - { "force-migrate", '\0', 0, G_OPTION_ARG_NONE, &force_migrate, - N_("Forcibly re-migrate from Evolution 1.4"), NULL }, -#endif { "debug", '\0', 0, G_OPTION_ARG_STRING, &evolution_debug_log, N_("Send the debugging output of all components to a file."), "FILE" }, { "disable-eplugin", '\0', 0, G_OPTION_ARG_NONE, &disable_eplugin, @@ -499,11 +475,6 @@ main (gint argc, gchar **argv) client = gconf_client_get_default (); -#ifdef DEVELOPMENT - if (force_migrate) - destroy_config (client); -#endif - if (disable_preview) { const gchar *key; diff --git a/shell/shell.error.xml b/shell/shell.error.xml index 3f3f0e2f86..6c75baa9df 100644 --- a/shell/shell.error.xml +++ b/shell/shell.error.xml @@ -7,45 +7,23 @@ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/> </error> - <error id="upgrade-nospace" type="error"> - <_primary>Insufficient disk space for upgrade.</_primary> - <_secondary xml:space="preserve">Upgrading your data and settings will require up to {0} of disk space, but you only have {1} available. - -You will need to make more space available in your home directory before you can continue.</_secondary> - <button stock="gtk-quit" response="GTK_RESPONSE_CANCEL"/> - </error> - <error id="upgrade-failed" type="error"> <_primary>Upgrade from previous version failed:</_primary> <_secondary xml:space="preserve">{0} If you choose to continue, you may not have access to some of your old data. </_secondary> - <button stock="gtk-quit" response="GTK_RESPONSE_CANCEL"/> - <button stock="gtk-ok" _label="Continue" response="GTK_RESPONSE_OK"/> + <button _label="Continue Anyway" response="GTK_RESPONSE_OK"/> + <button _label="Quit Now" response="GTK_RESPONSE_CANCEL"/> </error> - <error id="upgrade-remove-1-4" type="question" default="GTK_RESPONSE_CANCEL"> - <_primary>Delete old data from version {0}?</_primary> - <_secondary xml:space="preserve">The previous version of Evolution stored its data in a different location. - -If you choose to remove this data, the entire contents of the "evolution" directory will be removed permanently. If you choose to keep this data, then you may manually remove the contents of "evolution" at your convenience. -</_secondary> - <button _label="_Remind Me Later" response="GTK_RESPONSE_CANCEL"/> - <button _label="_Keep Data" response="GTK_RESPONSE_ACCEPT"/> - <button stock="gtk-delete" response="GTK_RESPONSE_OK"/> - </error> - - <error id="upgrade-remove-1-4-confirm" type="warning" default="GTK_RESPONSE_CANCEL"> - <_primary>Really delete old data?</_primary> - <_secondary xml:space="preserve">The entire contents of the "evolution" directory are about to be permanently removed. - -It is suggested you manually verify that all of your mail, contact, and calendar data is present, and that this version of Evolution operates correctly before deleting this old data. - -Once deleted, you cannot downgrade to the previous version of Evolution without manual intervention. -</_secondary> - <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/> - <button stock="gtk-delete" response="GTK_RESPONSE_OK"/> + <error id="upgrade-version-too-old" type="warning" default="GTK_RESPONSE_CANCEL"> + <_primary>Cannot upgrade directly from version {0}</_primary> + <_secondary>Evolution no longer supports upgrading directly from + version {0}. However as a workaround you might try first upgrading + to Evolution 2, and then upgrading to Evolution 3.</_secondary> + <button _label="Continue Anyway" response="GTK_RESPONSE_OK"/> + <button _label="Quit Now" response="GTK_RESPONSE_CANCEL"/> </error> <error id="forget-passwords" type="question" default="GTK_RESPONSE_CANCEL"> |