aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2008-07-01 18:31:48 +0800
committerMilan Crha <mcrha@src.gnome.org>2008-07-01 18:31:48 +0800
commit51b273e5b321133422cc9c1764dbf9a9638e8187 (patch)
tree0206f3ca8df0b38d90ccd3e694f6d2289ef22b97
parent75edd1a5a13ad88659a641a3336c5a94d85b7f01 (diff)
downloadgsoc2013-evolution-51b273e5b321133422cc9c1764dbf9a9638e8187.tar
gsoc2013-evolution-51b273e5b321133422cc9c1764dbf9a9638e8187.tar.gz
gsoc2013-evolution-51b273e5b321133422cc9c1764dbf9a9638e8187.tar.bz2
gsoc2013-evolution-51b273e5b321133422cc9c1764dbf9a9638e8187.tar.lz
gsoc2013-evolution-51b273e5b321133422cc9c1764dbf9a9638e8187.tar.xz
gsoc2013-evolution-51b273e5b321133422cc9c1764dbf9a9638e8187.tar.zst
gsoc2013-evolution-51b273e5b321133422cc9c1764dbf9a9638e8187.zip
** Fix for bug #540274
2008-07-01 Milan Crha <mcrha@redhat.com> ** Fix for bug #540274 * Makefile.am: Link with libraries we require now. * backup.c: (rc), (s): Exchange $HOME with g_get_home_dir in commands. * backup.c: (ensure_locals), (fix_account_folder_uri), (restore): After restore walk through all account, addressbook, calendar, task and memo sources and fix the base uri if required. (One should be able to import also into different user than one where the backup was done.) svn path=/trunk/; revision=35710
-rw-r--r--plugins/backup-restore/ChangeLog11
-rw-r--r--plugins/backup-restore/Makefile.am6
-rw-r--r--plugins/backup-restore/backup.c178
3 files changed, 192 insertions, 3 deletions
diff --git a/plugins/backup-restore/ChangeLog b/plugins/backup-restore/ChangeLog
index cfa1dcc8ad..94e88e2bf2 100644
--- a/plugins/backup-restore/ChangeLog
+++ b/plugins/backup-restore/ChangeLog
@@ -1,3 +1,14 @@
+2008-07-01 Milan Crha <mcrha@redhat.com>
+
+ ** Fix for bug #540274
+
+ * Makefile.am: Link with libraries we require now.
+ * backup.c: (rc), (s): Exchange $HOME with g_get_home_dir in commands.
+ * backup.c: (ensure_locals), (fix_account_folder_uri), (restore):
+ After restore walk through all account, addressbook, calendar, task
+ and memo sources and fix the base uri if required. (One should be able
+ to import also into different user than one where the backup was done.)
+
2008-06-30 Milan Crha <mcrha@redhat.com>
** Fix for bug #536488
diff --git a/plugins/backup-restore/Makefile.am b/plugins/backup-restore/Makefile.am
index 251da8b1dd..d83b7fb2f9 100644
--- a/plugins/backup-restore/Makefile.am
+++ b/plugins/backup-restore/Makefile.am
@@ -22,7 +22,11 @@ liborg_gnome_backup_restore_la_LDFLAGS = -module -avoid-version
privlibexec_PROGRAMS = evolution-backup
evolution_backup_SOURCES = backup.c
-evolution_backup_LDADD = $(SHELL_LIBS)
+evolution_backup_LDADD = $(SHELL_LIBS) \
+ $(EVOLUTION_CALENDAR_LIBS) \
+ $(EVOLUTION_ADDRESSBOOK_LIBS) \
+ $(top_builddir)/e-util/libeutil.la
+
EXTRA_DIST = \
org-gnome-backup-restore.eplug.xml \
diff --git a/plugins/backup-restore/backup.c b/plugins/backup-restore/backup.c
index d923b3bd92..50421ff9bd 100644
--- a/plugins/backup-restore/backup.c
+++ b/plugins/backup-restore/backup.c
@@ -12,6 +12,12 @@
#include <gtk/gtk.h>
#include <libgnome/gnome-util.h>
+#include <libebook/e-book.h>
+#include <libecal/e-cal.h>
+#include <libedataserver/e-account.h>
+#include <libedataserver/e-account-list.h>
+#include "e-util/e-util.h"
+
#define EVOLUTION "evolution"
#define EVOLUTION_DIR "$HOME/.evolution/"
#define EVOLUTION_DIR_BACKUP "$HOME/.evolution-old/"
@@ -53,12 +59,40 @@ static const GOptionEntry options[] = {
#define d(x) x
-/* #define s(x) system (x) */
-#define s(x) G_STMT_START { g_message (x); system (x); } G_STMT_END
+#define rc(x) G_STMT_START { g_message (x); system (x); } G_STMT_END
#define CANCEL(x) if (x) return;
static void
+s (const char *cmd)
+{
+ if (!cmd)
+ return;
+
+ if (strstr (cmd, "$HOME") != NULL) {
+ /* read the doc for g_get_home_dir to know why replacing it here */
+ const char *home = g_get_home_dir ();
+ const char *p, *next;
+ GString *str = g_string_new ("");
+
+ p = cmd;
+ while (next = strstr (p, "$HOME"), next) {
+ if (p + 1 < next)
+ g_string_append_len (str, p, next - p);
+ g_string_append (str, home);
+
+ p = next + 5;
+ }
+
+ g_string_append (str, p);
+
+ rc (str->str);
+ g_string_free (str, TRUE);
+ } else
+ rc (cmd);
+}
+
+static void
backup (const char *filename)
{
char *command;
@@ -104,10 +138,97 @@ backup (const char *filename)
}
static void
+ensure_locals (ESourceList *source_list, const char *base_dir)
+{
+ GSList *groups, *sources;
+
+ if (!source_list)
+ return;
+
+ for (groups = e_source_list_peek_groups (source_list); groups; groups = groups->next) {
+ char *base_filename, *base_uri;
+ ESourceGroup *group = E_SOURCE_GROUP (groups->data);
+
+ if (!group || !e_source_group_peek_base_uri (group) || !g_str_has_prefix (e_source_group_peek_base_uri (group), "file://"))
+ continue;
+
+ base_filename = g_build_filename (base_dir, "local", NULL);
+ base_uri = g_filename_to_uri (base_filename, NULL, NULL);
+
+ if (base_uri && !g_str_equal (base_uri, e_source_group_peek_base_uri (group))) {
+ /* groups base_uri differs from the new one, maybe users imports
+ to the account with different user name, thus fixing this */
+ e_source_group_set_base_uri (group, base_uri);
+ }
+
+ for (sources = e_source_group_peek_sources (group); sources; sources = sources->next) {
+ ESource *source = E_SOURCE (sources->data);
+
+ if (!source || !e_source_peek_absolute_uri (source))
+ continue;
+
+ if (!g_str_has_prefix (e_source_peek_absolute_uri (source), base_uri)) {
+ char *abs_uri = e_source_build_absolute_uri (source);
+
+ e_source_set_absolute_uri (source, abs_uri);
+ g_free (abs_uri);
+ }
+ }
+
+ g_free (base_filename);
+ g_free (base_uri);
+ }
+}
+
+/* returns whether changed the item */
+static gboolean
+fix_account_folder_uri (EAccount *account, e_account_item_t item, const char *base_dir)
+{
+ gboolean changed = FALSE;
+ const char *uri;
+
+ /* the base_dir should always contain that part, so just a sanity check */
+ if (!account || !base_dir || strstr (base_dir, "/.evolution/mail/local") == NULL)
+ return FALSE;
+
+ uri = e_account_get_string (account, item);
+ if (uri && strstr (uri, "/.evolution/mail/local") != NULL) {
+ const char *path = strchr (uri, ':') + 1;
+
+ if (!g_str_has_prefix (path, base_dir)) {
+ GString *new_uri = g_string_new ("");
+
+ /* prefix, like "mbox:" */
+ g_string_append_len (new_uri, uri, path - uri);
+ /* middle, changing old patch with new path */
+ g_string_append_len (new_uri, base_dir, strstr (base_dir, "/.evolution/mail/local") - base_dir);
+ /* sufix, the rest beginning with "/.evolution/..." */
+ g_string_append (new_uri, strstr (uri, "/.evolution/mail/local"));
+
+ changed = TRUE;
+ e_account_set_string (account, item, new_uri->str);
+ g_string_free (new_uri, TRUE);
+ }
+ }
+
+ return changed;
+}
+
+static void
restore (const char *filename)
{
+ struct _calendars { ECalSourceType type; const char *dir; }
+ calendars[] = {
+ { E_CAL_SOURCE_TYPE_EVENT, "calendar"},
+ { E_CAL_SOURCE_TYPE_TODO, "tasks"},
+ { E_CAL_SOURCE_TYPE_JOURNAL, "memos"},
+ { E_CAL_SOURCE_TYPE_LAST, NULL} };
+ int i;
char *command;
char *quotedfname;
+ ESourceList *sources = NULL;
+ EAccountList *accounts;
+ GConfClient *gconf;
g_return_if_fail (filename && *filename);
quotedfname = g_shell_quote(filename);
@@ -140,6 +261,59 @@ restore (const char *filename)
s ("rm -rf $HOME/.camel_certs_old");
s ("rm $HOME/.evolution/.running");
+ CANCEL (complete);
+ txt = _("Ensuring local sources");
+
+ if (e_book_get_addressbooks (&sources, NULL)) {
+ char *base_dir = g_build_filename (e_get_user_data_dir (), "addressbook", NULL);
+
+ ensure_locals (sources, base_dir);
+ g_object_unref (sources);
+ sources = NULL;
+
+ g_free (base_dir);
+ }
+
+ for (i = 0; calendars[i].dir; i++) {
+ if (e_cal_get_sources (&sources, calendars [i].type, NULL)) {
+ char *base_dir = g_build_filename (e_get_user_data_dir (), calendars [i].dir, NULL);
+
+ ensure_locals (sources, base_dir);
+ g_object_unref (sources);
+ sources = NULL;
+
+ g_free (base_dir);
+ }
+ }
+
+ gconf = gconf_client_get_default ();
+ accounts = e_account_list_new (gconf);
+
+ if (accounts) {
+ gboolean changed = FALSE;
+ char *base_dir = g_build_filename (e_get_user_data_dir (), "mail", "local", NULL);
+ EIterator *it;
+
+ for (it = e_list_get_iterator (E_LIST (accounts)); e_iterator_is_valid (it); e_iterator_next (it)) {
+ /* why does this return a 'const' object?!? */
+ EAccount *account = (EAccount *) e_iterator_get (it);
+
+ if (account) {
+ changed = fix_account_folder_uri (account, E_ACCOUNT_DRAFTS_FOLDER_URI, base_dir) || changed;
+ changed = fix_account_folder_uri (account, E_ACCOUNT_SENT_FOLDER_URI, base_dir) || changed;
+ }
+ }
+
+ if (changed)
+ e_account_list_save (accounts);
+
+ g_object_unref (it);
+ g_object_unref (accounts);
+ g_free (base_dir);
+ }
+
+ g_object_unref (gconf);
+
if (restart_arg) {
CANCEL (complete);
txt = _("Restarting Evolution");