aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook
diff options
context:
space:
mode:
authorChris Toshok <toshok@ximian.com>2004-01-07 05:43:07 +0800
committerChris Toshok <toshok@src.gnome.org>2004-01-07 05:43:07 +0800
commit38941f937253e2c208e0165267bd9f61a075988c (patch)
tree5cef0437cfcc6a95c4a73a59de268a60a3b73b67 /addressbook
parent10fdfe795f82850d8e6dcf1923bc6780eced0763 (diff)
downloadgsoc2013-evolution-38941f937253e2c208e0165267bd9f61a075988c.tar
gsoc2013-evolution-38941f937253e2c208e0165267bd9f61a075988c.tar.gz
gsoc2013-evolution-38941f937253e2c208e0165267bd9f61a075988c.tar.bz2
gsoc2013-evolution-38941f937253e2c208e0165267bd9f61a075988c.tar.lz
gsoc2013-evolution-38941f937253e2c208e0165267bd9f61a075988c.tar.xz
gsoc2013-evolution-38941f937253e2c208e0165267bd9f61a075988c.tar.zst
gsoc2013-evolution-38941f937253e2c208e0165267bd9f61a075988c.zip
add addressbook-migrate.[ch].
2004-01-06 Chris Toshok <toshok@ximian.com> * gui/component/Makefile.am (libevolution_addressbook_la_SOURCES): add addressbook-migrate.[ch]. * gui/component/addressbook-component.c (addressbook_component_init): remove the source creation from here, it's in the migration code now. (impl_upgradeFromVersion): new function, call the addressbook-migration stuff. (addressbook_component_class_init): fill in epv->upgradeFromVersion, and call smime_component_init. (addressbook_component_peek_base_directory): new function. (addressbook_component_peek_source_list): same. * gui/component/addressbook-component.h: add prototypes for _peek_base_directory and _peek_source_list. * gui/component/addressbook-migrate.[ch]: add migration code to convert stuff from 1.x over to 1.5/2.0. svn path=/trunk/; revision=24079
Diffstat (limited to 'addressbook')
-rw-r--r--addressbook/ChangeLog21
-rw-r--r--addressbook/gui/component/Makefile.am2
-rw-r--r--addressbook/gui/component/addressbook-component.c87
-rw-r--r--addressbook/gui/component/addressbook-component.h6
-rw-r--r--addressbook/gui/component/addressbook-migrate.c559
-rw-r--r--addressbook/gui/component/addressbook-migrate.h29
6 files changed, 658 insertions, 46 deletions
diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog
index e2dec01eac..d4bc67b350 100644
--- a/addressbook/ChangeLog
+++ b/addressbook/ChangeLog
@@ -1,3 +1,24 @@
+2004-01-06 Chris Toshok <toshok@ximian.com>
+
+ * gui/component/Makefile.am (libevolution_addressbook_la_SOURCES):
+ add addressbook-migrate.[ch].
+
+ * gui/component/addressbook-component.c
+ (addressbook_component_init): remove the source creation from
+ here, it's in the migration code now.
+ (impl_upgradeFromVersion): new function, call the
+ addressbook-migration stuff.
+ (addressbook_component_class_init): fill in
+ epv->upgradeFromVersion, and call smime_component_init.
+ (addressbook_component_peek_base_directory): new function.
+ (addressbook_component_peek_source_list): same.
+
+ * gui/component/addressbook-component.h: add prototypes for
+ _peek_base_directory and _peek_source_list.
+
+ * gui/component/addressbook-migrate.[ch]: add migration code to
+ convert stuff from 1.x over to 1.5/2.0.
+
2004-01-06 Rodney Dawes <dobey@ximian.com>
* gui/contact-editor/e-contact-editor-address.c: Apply
diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am
index 09dcb8e537..d9f179c442 100644
--- a/addressbook/gui/component/Makefile.am
+++ b/addressbook/gui/component/Makefile.am
@@ -29,6 +29,8 @@ libevolution_addressbook_la_SOURCES = \
addressbook-component.h \
addressbook-config.c \
addressbook-config.h \
+ addressbook-migrate.c \
+ addressbook-migrate.h \
autocompletion-config.c \
autocompletion-config.h \
addressbook.c \
diff --git a/addressbook/gui/component/addressbook-component.c b/addressbook/gui/component/addressbook-component.c
index 999baed5bc..1bc0799a73 100644
--- a/addressbook/gui/component/addressbook-component.c
+++ b/addressbook/gui/component/addressbook-component.c
@@ -26,6 +26,7 @@
#include <config.h>
#include "addressbook-component.h"
+#include "addressbook-migrate.h"
#include "addressbook.h"
#include "addressbook-config.h"
@@ -47,6 +48,10 @@
#include <gconf/gconf-client.h>
#include <gal/util/e-util.h>
+#if HAVE_NSS
+#include "smime/gui/component.h"
+#endif
+
#define PARENT_TYPE bonobo_object_get_type ()
static BonoboObjectClass *parent_class = NULL;
@@ -55,6 +60,7 @@ struct _AddressbookComponentPrivate {
GConfClient *gconf_client;
ESourceList *source_list;
GtkWidget *source_selector;
+ char *base_directory;
EActivityHandler *activity_handler;
};
@@ -349,6 +355,23 @@ impl_requestCreateItem (PortableServer_Servant servant,
g_free (uri);
}
+static CORBA_boolean
+impl_upgradeFromVersion (PortableServer_Servant servant, short major, short minor, short revision, CORBA_Environment *ev)
+{
+ switch (major) {
+ case 1:
+ switch (minor) {
+ case 0:
+ case 2:
+ case 4:
+ addressbook_migrate (addressbook_component_peek ());
+ break;
+ }
+ break;
+ }
+
+ return TRUE;
+}
/* GObject methods. */
@@ -402,18 +425,20 @@ addressbook_component_class_init (AddressbookComponentClass *class)
epv->createControls = impl_createControls;
epv->_get_userCreatableItems = impl__get_userCreatableItems;
epv->requestCreateItem = impl_requestCreateItem;
+ epv->upgradeFromVersion = impl_upgradeFromVersion;
object_class->dispose = impl_dispose;
object_class->finalize = impl_finalize;
parent_class = g_type_class_peek_parent (class);
+
+ smime_component_init ();
}
static void
addressbook_component_init (AddressbookComponent *component)
{
AddressbookComponentPrivate *priv;
- GSList *groups;
priv = g_new0 (AddressbookComponentPrivate, 1);
@@ -425,49 +450,7 @@ addressbook_component_init (AddressbookComponent *component)
"/apps/evolution/addressbook/sources");
priv->activity_handler = e_activity_handler_new ();
-
- /* Create default addressbooks if there are no groups */
- groups = e_source_list_peek_groups (priv->source_list);
- if (!groups) {
- ESourceGroup *group;
- ESource *source;
- char *base_uri, *base_uri_proto, *new_dir;
-
- /* create the local source group */
- base_uri = g_build_filename (g_get_home_dir (),
- "/.evolution/addressbook/local/OnThisComputer/",
- NULL);
-
- base_uri_proto = g_strconcat ("file://", base_uri, NULL);
-
- group = e_source_group_new (_("On This Computer"), base_uri_proto);
- e_source_list_add_group (priv->source_list, group, -1);
-
- g_free (base_uri_proto);
-
- /* FIXME: Migrate addressbooks from older setup? */
-
- /* Create default addressbooks */
- new_dir = g_build_filename (base_uri, "Personal/", NULL);
- if (!e_mkdir_hier (new_dir, 0700)) {
- source = e_source_new (_("Personal"), "Personal");
- e_source_group_add_source (group, source, -1);
- }
- g_free (new_dir);
-
- new_dir = g_build_filename (base_uri, "Work/", NULL);
- if (!e_mkdir_hier (new_dir, 0700)) {
- source = e_source_new (_("Work"), "Work");
- e_source_group_add_source (group, source, -1);
- }
- g_free (new_dir);
-
- g_free (base_uri);
-
- /* Create the LDAP source group */
- group = e_source_group_new (_("On LDAP Servers"), "ldap://");
- e_source_list_add_group (priv->source_list, group, -1);
- }
+ priv->base_directory = g_build_filename (g_get_home_dir (), ".evolution", NULL);
component->priv = priv;
}
@@ -486,6 +469,22 @@ addressbook_component_peek (void)
return component;
}
+const char *
+addressbook_component_peek_base_directory (AddressbookComponent *component)
+{
+ g_return_val_if_fail (ADDRESSBOOK_IS_COMPONENT (component), NULL);
+
+ return component->priv->base_directory;
+}
+
+ESourceList *
+addressbook_component_peek_source_list (AddressbookComponent *component)
+{
+ g_return_val_if_fail (ADDRESSBOOK_IS_COMPONENT (component), NULL);
+
+ return component->priv->source_list;
+}
+
EActivityHandler *
addressbook_component_peek_activity_handler (AddressbookComponent *component)
diff --git a/addressbook/gui/component/addressbook-component.h b/addressbook/gui/component/addressbook-component.h
index f08f54aaaf..70cf548c22 100644
--- a/addressbook/gui/component/addressbook-component.h
+++ b/addressbook/gui/component/addressbook-component.h
@@ -27,6 +27,7 @@
#include "Evolution.h"
#include "e-activity-handler.h"
+#include <libedataserver/e-source-list.h>
#define ADDRESSBOOK_TYPE_COMPONENT (addressbook_component_get_type ())
#define ADDRESSBOOK_COMPONENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ADDRESSBOOK_TYPE_COMPONENT, AddressbookComponent))
@@ -56,7 +57,8 @@ GType addressbook_component_get_type (void);
AddressbookComponent *addressbook_component_peek (void);
-EActivityHandler *addressbook_component_peek_activity_handler (AddressbookComponent *component);
-
+const char * addressbook_component_peek_base_directory (AddressbookComponent *component);
+EActivityHandler *addressbook_component_peek_activity_handler (AddressbookComponent *component);
+ESourceList *addressbook_component_peek_source_list (AddressbookComponent *component);
#endif /* _ADDRESSBOOK_COMPONENT_H_ */
diff --git a/addressbook/gui/component/addressbook-migrate.c b/addressbook/gui/component/addressbook-migrate.c
new file mode 100644
index 0000000000..daeb642f84
--- /dev/null
+++ b/addressbook/gui/component/addressbook-migrate.c
@@ -0,0 +1,559 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2004, Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Chris Toshok (toshok@ximian.com)
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "addressbook-migrate.h"
+#include <libebook/e-book-async.h>
+#include <libgnome/gnome-i18n.h>
+#include <gal/util/e-util.h>
+#include <gal/util/e-xml-utils.h>
+#include <gtk/gtkwidget.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkprogressbar.h>
+
+static GtkWidget *window;
+static GtkLabel *label;
+static GtkProgressBar *progress;
+
+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 contact "
+ "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_defaults ((GtkBox *) vbox, w);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_widget_show (hbox);
+ gtk_box_pack_start_defaults ((GtkBox *) vbox, hbox);
+
+ label = (GtkLabel *) gtk_label_new ("");
+ gtk_widget_show ((GtkWidget *) label);
+ gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) label);
+
+ progress = (GtkProgressBar *) gtk_progress_bar_new ();
+ gtk_widget_show ((GtkWidget *) progress);
+ gtk_box_pack_start_defaults ((GtkBox *) hbox, (GtkWidget *) progress);
+
+ gtk_widget_show (window);
+}
+
+static void
+dialog_close (void)
+{
+ gtk_widget_destroy ((GtkWidget *) window);
+}
+
+static void
+dialog_set_folder_name (const char *folder_name)
+{
+ char *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)
+{
+ char text[5];
+
+ snprintf (text, sizeof (text), "%d%%", (int) (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 GList*
+find_addressbook_dirs (char *path, gboolean toplevel)
+{
+ char *db_path;
+ char *subfolder_path;
+ GList *list = NULL;
+
+ printf ("find_addressbook_dirs (%s)\n", path);
+
+ /* check if the present path is a db */
+ db_path = g_build_filename (path, "addressbook.db", NULL);
+ if (g_file_test (db_path, G_FILE_TEST_EXISTS))
+ list = g_list_append (list, g_strdup (path));
+ g_free (db_path);
+
+ /* recurse to subfolders */
+ if (toplevel)
+ subfolder_path = g_strdup (path);
+ else
+ subfolder_path = g_build_filename (path, "subfolders", NULL);
+ if (g_file_test (subfolder_path, G_FILE_TEST_IS_DIR)) {
+ GDir *dir = g_dir_open (subfolder_path, 0, NULL);
+
+ if (dir) {
+ const char *name;
+ while ((name = g_dir_read_name (dir))) {
+ if (strcmp (name, ".") && strcmp (name, "..")) {
+ char *p;
+ GList *sublist;
+
+ if (toplevel)
+ p = g_build_filename (path, name, NULL);
+ else
+ p = g_build_filename (path, "subfolders", name, NULL);
+
+ sublist = find_addressbook_dirs (p, FALSE);
+ g_free (p);
+ list = g_list_concat (list, sublist);
+ }
+ }
+ g_dir_close (dir);
+ }
+ }
+
+ g_free (subfolder_path);
+
+ return list;
+}
+
+static gboolean
+check_for_conflict (ESourceGroup *group, char *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);
+
+ printf ("checking %s against %s\n", e_source_peek_name (source), name);
+ if (!strcmp (e_source_peek_name (source), name))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static char *
+get_source_name (ESourceGroup *group, const char *path)
+{
+ char **p = g_strsplit (path, "/", 0);
+ int i, j, starting_index;
+ int 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]);
+ }
+
+ printf ("attempting %s\n", s->str);
+
+ 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);
+
+ return g_string_free (s, FALSE);
+}
+
+static void
+migrate_contacts (EBook *old_book, EBook *new_book)
+{
+ EBookQuery *query = e_book_query_any_field_contains ("");
+ GList *l, *contacts;
+ int num_added = 0;
+ int num_contacts;
+
+ /* both books are loaded, start the actual migration */
+ printf ("starting contact copy\n");
+ e_book_get_contacts (old_book, query, &contacts, NULL);
+
+ num_contacts = g_list_length (contacts);
+ for (l = contacts; l; l = l->next) {
+ EContact *contact = l->data;
+ GError *e = NULL;
+ if (!e_book_add_contact (new_book,
+ contact,
+ &e))
+ g_warning ("contact add failed: `%s'", e->message);
+
+ num_added ++;
+
+ dialog_set_progress ((double)num_added / num_contacts);
+ }
+}
+
+static void
+migrate_contact_folder (char *old_path, ESourceGroup *dest_group, char *source_name)
+{
+ char *old_uri = g_strdup_printf ("file://%s", old_path);
+ GError *e = NULL;
+
+ EBook *old_book = NULL, *new_book = NULL;
+ ESource *old_source;
+ ESource *new_source;
+ ESourceGroup *group;
+
+ group = e_source_group_new ("", old_uri);
+ old_source = e_source_new ("", "");
+ e_source_set_group (old_source, group);
+ g_object_unref (group);
+
+ new_source = e_source_new (source_name, source_name);
+ e_source_set_group (new_source, dest_group);
+
+ dialog_set_folder_name (source_name);
+
+ printf ("migrating `%s' to `%s'\n", old_uri, e_source_get_uri (new_source));
+
+ old_book = e_book_new ();
+ if (!e_book_load_source (old_book, old_source, TRUE, &e)) {
+ g_warning ("failed to load source book for migration: `%s'", e->message);
+ goto finish;
+ }
+
+ new_book = e_book_new ();
+ if (!e_book_load_source (new_book, new_source, FALSE, &e)) {
+ g_warning ("failed to load destination book for migration: `%s'", e->message);
+ goto finish;
+ }
+
+ migrate_contacts (old_book, new_book);
+
+ finish:
+ g_object_unref (old_book);
+ g_object_unref (new_book);
+ g_free (old_uri);
+}
+
+static gboolean
+create_groups (AddressbookComponent *component,
+ ESourceList *source_list,
+ ESourceGroup **on_this_computer,
+ ESourceGroup **on_ldap_servers)
+{
+ GSList *groups;
+
+ groups = e_source_list_peek_groups (source_list);
+ if (groups) {
+ /* groups are already there, we need to search for things... */
+ g_warning ("can't migrate when existing groups are present");
+ return FALSE;
+ }
+ else {
+ ESourceGroup *group;
+ ESource *source;
+ char *base_uri, *base_uri_proto, *new_dir;
+
+ /* create the local source group */
+ base_uri = g_build_filename (addressbook_component_peek_base_directory (component),
+ "/addressbook/local/OnThisComputer/",
+ NULL);
+
+ base_uri_proto = g_strconcat ("file://", base_uri, NULL);
+
+ group = e_source_group_new (_("On This Computer"), base_uri_proto);
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_this_computer = group;
+
+ g_free (base_uri_proto);
+
+ /* Create default addressbooks */
+ new_dir = g_build_filename (base_uri, "Personal/", NULL);
+ if (!e_mkdir_hier (new_dir, 0700)) {
+ source = e_source_new (_("Personal"), "Personal");
+ e_source_group_add_source (group, source, -1);
+ }
+ g_free (new_dir);
+
+ g_free (base_uri);
+
+ /* Create the LDAP source group */
+ group = e_source_group_new (_("On LDAP Servers"), "ldap://");
+ e_source_list_add_group (source_list, group, -1);
+
+ *on_ldap_servers = group;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+migrate_local_folders (AddressbookComponent *component, ESourceGroup *on_this_computer)
+{
+ char *old_path = NULL;
+ char *local_contact_folder = NULL;
+ char *source_name = NULL;
+ GList *dirs, *l;
+
+ old_path = g_strdup_printf ("%s/evolution/local", g_get_home_dir ());
+
+ dirs = find_addressbook_dirs (old_path, TRUE);
+
+ printf ("found the following dirs to migrate:\n");
+ for (l = dirs; l; l = l->next) {
+ printf ("l->data = %s\n", (char*)l->data);
+ }
+
+ /* migrate the local addressbook first, to OnThisComputer/Personal */
+ local_contact_folder = g_build_filename (g_get_home_dir (), "/evolution/local/Contacts",
+ NULL);
+ source_name = "Personal";
+ migrate_contact_folder (local_contact_folder, on_this_computer, source_name);
+
+ for (l = dirs; l; l = l->next) {
+ ESource *source;
+
+ /* skip the local contact folder, since we handle that
+ specifically, mapping it to Personal */
+ if (!strcmp ((char*)l->data, local_contact_folder))
+ continue;
+
+ source_name = get_source_name (on_this_computer, (char*)l->data + strlen (old_path) + 1);
+
+ source = e_source_new (source_name, source_name);
+ e_source_group_add_source (on_this_computer, source, -1);
+
+ migrate_contact_folder (l->data, on_this_computer, source_name);
+ g_free (source_name);
+ }
+
+ g_free (local_contact_folder);
+ g_free (old_path);
+
+ return TRUE;
+}
+
+static char *
+get_string_value (xmlNode *node,
+ const char *name)
+{
+ xmlNode *p;
+ xmlChar *xml_string;
+ char *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 ((char *) xml_string);
+ xmlFree (xml_string);
+
+ return retval;
+}
+
+static int
+get_integer_value (xmlNode *node,
+ const char *name,
+ int defval)
+{
+ xmlNode *p;
+ xmlChar *xml_string;
+ int 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 (xml_string);
+ xmlFree (xml_string);
+
+ return retval;
+}
+
+static gboolean
+migrate_ldap_servers (AddressbookComponent *component, ESourceGroup *on_ldap_servers)
+{
+ char *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;
+ int num_contactservers;
+ int servernum;
+
+ if (!doc)
+ return FALSE;
+
+ root = xmlDocGetRootElement (doc);
+ if (root == NULL || strcmp (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 (child->name, "contactserver")) {
+ num_contactservers++;
+ }
+ }
+ printf ("found %d contact servers to migrate\n", num_contactservers);
+
+ dialog_set_folder_name (_("LDAP Servers"));
+
+ servernum = 0;
+ for (child = root->children; child; child = child->next) {
+ if (!strcmp (child->name, "contactserver")) {
+ char *port, *host, *rootdn, *scope, *authmethod, *ssl;
+ char *emailaddr, *binddn, *limitstr;
+ int limit;
+ char *name, *description;
+ GString *uri = g_string_new ("");
+ ESource *source;
+
+ name = get_string_value (child, "name");
+ description = get_string_value (child, "description");
+ port = get_string_value (child, "port");
+ host = get_string_value (child, "host");
+ rootdn = get_string_value (child, "rootdn");
+ scope = get_string_value (child, "scope");
+ authmethod = get_string_value (child, "authmethod");
+ ssl = get_string_value (child, "ssl");
+ emailaddr = get_string_value (child, "emailaddr");
+ binddn = get_string_value (child, "binddn");
+ limit = get_integer_value (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 ((double)servernum/num_contactservers);
+ }
+ }
+
+ xmlFreeDoc (doc);
+ }
+
+ g_free (sources_xml);
+
+ return TRUE;
+}
+
+int
+addressbook_migrate (AddressbookComponent *component)
+{
+ ESourceList *source_list = addressbook_component_peek_source_list (component);
+ ESourceGroup *on_this_computer;
+ ESourceGroup *on_ldap_servers;
+
+ if (!create_groups (component, source_list, &on_this_computer, &on_ldap_servers))
+ return FALSE;
+
+ setup_progress_dialog ();
+
+ migrate_local_folders (component, on_this_computer);
+ migrate_ldap_servers (component, on_ldap_servers);
+
+ dialog_close ();
+
+ e_source_list_sync (source_list, NULL);
+
+ return TRUE;
+}
diff --git a/addressbook/gui/component/addressbook-migrate.h b/addressbook/gui/component/addressbook-migrate.h
new file mode 100644
index 0000000000..15512e2183
--- /dev/null
+++ b/addressbook/gui/component/addressbook-migrate.h
@@ -0,0 +1,29 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2004, Novell, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Chris Toshok (toshok@ximian.com)
+ */
+
+#ifndef _ADDRESSBOOK_MIGRATE_H_
+#define _ADDRESSBOOK_MIGRATE_H_
+
+#include "addressbook-component.h"
+
+int addressbook_migrate (AddressbookComponent *component);
+
+#endif /* _ADDRESSBOOK_MIGRATE_H_ */