2
* Copyright (C) 2009 Collabora Ltd.
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; either version 2 of the
7
* License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* General Public License for more details.
14
* You should have received a copy of the GNU General Public
15
* License along with this program; if not, write to the
16
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17
* Boston, MA 02110-1301 USA
19
* Authors: Arnaud Maillet <arnaud.maillet@collabora.co.uk>
27
#include <glib/gi18n-lib.h>
28
#include <gconf/gconf-client.h>
29
#include <telepathy-glib/account-manager.h>
30
#include <telepathy-glib/util.h>
31
#include <telepathy-glib/defs.h>
32
#include <dbus/dbus-protocol.h>
33
#include <gnome-keyring.h>
34
#include <libempathy/empathy-account-settings.h>
35
#include <libempathy/empathy-connection-managers.h>
37
#include "empathy-import-mc4-accounts.h"
39
#define DEBUG_FLAG EMPATHY_DEBUG_IMPORT_MC4_ACCOUNTS
40
#include <libempathy/empathy-debug.h>
42
#define MC_ACCOUNTS_GCONF_BASE "/apps/telepathy/mc/accounts"
43
#define IMPORTED_MC4_ACCOUNTS "/apps/empathy/accounts/imported_mc4_accounts"
49
} ProfileProtocolMapItem;
51
static ProfileProtocolMapItem profile_protocol_map[] =
55
{ "gtalk", "jabber" },
56
{ "msn-haze", "msn" },
57
{ "salut", "local-xmpp" },
58
{ "sipphone", "sip" },
59
{ "sofiasip", "sip" },
68
_account_name_from_key (const gchar *key)
70
guint base_len = strlen (MC_ACCOUNTS_GCONF_BASE);
71
const gchar *base, *slash;
73
g_assert (g_str_has_prefix (key, MC_ACCOUNTS_GCONF_BASE));
74
g_assert (strlen (key) > base_len + 1);
76
base = key + base_len + 1;
77
slash = strchr (base, '/');
80
return g_strdup (base);
82
return g_strndup (base, slash - base);
86
_param_name_from_key (const gchar *key)
88
const gchar *base, *slash;
92
account_name = _account_name_from_key (key);
93
base = strstr (key, account_name);
94
slash = strchr (base, '/');
96
ret = g_strdup (slash+1);
97
g_free (account_name);
103
_create_default_display_name (const gchar *protocol)
105
if (!tp_strdiff (protocol, "local-xmpp"))
106
return g_strdup (_("People Nearby"));
108
return g_strdup_printf (_("%s account"), protocol);
112
_get_manager_for_protocol (EmpathyConnectionManagers *managers,
113
const gchar *protocol)
115
GList *cms = empathy_connection_managers_get_cms (managers);
117
TpConnectionManager *haze = NULL;
118
TpConnectionManager *cm = NULL;
120
for (l = cms; l; l = l->next)
122
TpConnectionManager *tp_cm = l->data;
124
/* Only use haze if no other cm provides this protocol */
125
if (!tp_strdiff (tp_connection_manager_get_name (tp_cm), "haze"))
131
if (tp_connection_manager_has_protocol (tp_cm, protocol))
138
if (haze != NULL && tp_connection_manager_has_protocol (haze, protocol))
139
return tp_connection_manager_get_name (haze);
142
return cm != NULL ? tp_connection_manager_get_name (cm) : NULL;
146
_move_contents (const gchar *old, const gchar *new)
152
ret = g_mkdir_with_parents (new, 0777);
156
source = g_dir_open (old, 0, NULL);
160
while ((f = g_dir_read_name (source)) != NULL)
165
old_path = g_build_path (G_DIR_SEPARATOR_S, old, f, NULL);
166
new_path = g_build_path (G_DIR_SEPARATOR_S, new, f, NULL);
168
if (g_file_test (old_path, G_FILE_TEST_IS_DIR))
170
_move_contents (old_path, new_path);
174
GFile *f_old, *f_new;
176
f_old = g_file_new_for_path (old_path);
177
f_new = g_file_new_for_path (new_path);
179
g_file_move (f_old, f_new, G_FILE_COPY_NONE,
180
NULL, NULL, NULL, NULL);
182
g_object_unref (f_old);
183
g_object_unref (f_new);
190
g_dir_close (source);
194
_move_logs (TpAccount *account, const gchar *account_name)
196
gchar *old_path, *new_path, *escaped;
199
name = tp_proxy_get_object_path (account);
200
if (g_str_has_prefix (name, TP_ACCOUNT_OBJECT_PATH_BASE))
201
name += strlen (TP_ACCOUNT_OBJECT_PATH_BASE);
203
escaped = g_strdelimit (g_strdup (name), "/", '_');
204
new_path = g_build_path (G_DIR_SEPARATOR_S, g_get_user_data_dir (),
205
PACKAGE_NAME, "logs", escaped, NULL);
208
old_path = g_build_path (G_DIR_SEPARATOR_S,
210
".gnome2", PACKAGE_NAME, "logs", account_name, NULL);
212
_move_contents (old_path, new_path);
216
_create_account_cb (GObject *source,
217
GAsyncResult *result,
221
GError *error = NULL;
222
Misc *misc = (Misc *) user_data;
224
if (!empathy_account_settings_apply_finish (
225
EMPATHY_ACCOUNT_SETTINGS (source), result, &error))
227
DEBUG ("Failed to create account: %s", error->message);
228
g_error_free (error);
232
DEBUG ("account created");
233
account = empathy_account_settings_get_account (
234
EMPATHY_ACCOUNT_SETTINGS (source));
236
_move_logs (account, misc->account_name);
238
tp_account_set_enabled_async (account,
239
misc->enable, NULL, NULL);
241
g_free (misc->account_name);
242
g_slice_free (Misc, misc);
245
g_object_unref (source);
249
_get_protocol_from_profile (const gchar *profile)
253
DEBUG ("profile: %s", profile);
255
for (i = 0; i < G_N_ELEMENTS (profile_protocol_map); i++)
256
if (!tp_strdiff (profile, profile_protocol_map[i].profile))
257
return g_strdup (profile_protocol_map[i].protocol);
259
return g_strdup (profile);
263
_set_password_from_keyring (EmpathyAccountSettings *settings,
264
const gchar *account_name, const gchar *key)
266
GnomeKeyringResult res;
268
GnomeKeyringPasswordSchema keyring_schema = {
269
GNOME_KEYRING_ITEM_GENERIC_SECRET,
271
{ "account", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
272
{ "param", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
277
res = gnome_keyring_find_password_sync (&keyring_schema,
279
"account", account_name,
283
if (res == GNOME_KEYRING_RESULT_OK)
285
empathy_account_settings_set_string (settings, key, password);
286
gnome_keyring_free_password (password);
291
_handle_entry (EmpathyAccountSettings *settings, const gchar *account_name,
295
const gchar *signature;
297
signature = empathy_account_settings_get_dbus_signature (settings, key);
298
if (signature == NULL)
300
DEBUG ("Parameter %s is unknown", signature);
304
switch ((int)*signature)
306
case DBUS_TYPE_INT16:
307
case DBUS_TYPE_INT32:
309
gint v = gconf_value_get_int (gconf_entry_get_value (entry));
310
empathy_account_settings_set_int32 (settings, key, v);
313
case DBUS_TYPE_UINT16:
314
case DBUS_TYPE_UINT32:
316
gint v = gconf_value_get_int (gconf_entry_get_value (entry));
317
empathy_account_settings_set_uint32 (settings, key, v);
320
case DBUS_TYPE_STRING:
322
const gchar *v = gconf_value_get_string (
323
gconf_entry_get_value (entry));
325
/* MC 4 would put password in the keyring and leave the password in
328
if (!tp_strdiff (key, "password") && !tp_strdiff (v, "keyring"))
329
_set_password_from_keyring (settings, account_name, key);
331
empathy_account_settings_set_string (settings, key, v);
334
case DBUS_TYPE_BOOLEAN:
336
gboolean v = gconf_value_get_bool (
337
gconf_entry_get_value (entry));
339
empathy_account_settings_set_boolean (settings, key, v);
343
DEBUG ("Unsupported type in signature: %s", signature);
348
_recurse_account (GSList *entries, EmpathyAccountSettings *settings,
349
const gchar *account_name)
353
for (tmp = entries; tmp != NULL; tmp = tmp->next)
359
entry = (GConfEntry *) tmp->data;
360
param = _param_name_from_key (gconf_entry_get_key (entry));
362
if (g_str_has_prefix (param, "param-"))
364
_handle_entry (settings, account_name, param + strlen ("param-"),
369
gconf_entry_unref (entry);
374
import_one_account (const char *path,
375
EmpathyConnectionManagers *managers,
378
gchar *account_name = _account_name_from_key (path);
379
EmpathyAccountSettings *settings = NULL;
380
GError *error = NULL;
381
GSList *entries = NULL;
382
gchar *profile = NULL;
383
gchar *protocol = NULL;
384
const gchar *manager;
387
gboolean enabled = FALSE;
388
gboolean ret = FALSE;
391
DEBUG ("Starting import of %s (%s)", path, account_name);
393
key = g_strdup_printf ("%s/profile", path);
394
profile = gconf_client_get_string (client, key, NULL);
399
DEBUG ("Account is missing a profile entry");
403
protocol = _get_protocol_from_profile (profile);
404
manager = _get_manager_for_protocol (managers, protocol);
407
DEBUG ("No manager available for this protocol %s", protocol);
411
key = g_strdup_printf ("%s/display_name", path);
412
display_name = gconf_client_get_string (client, key, NULL);
415
if (display_name == NULL)
416
display_name = _create_default_display_name (protocol);
418
settings = empathy_account_settings_new (manager, protocol, display_name);
419
g_free (display_name);
421
/* Bit of a hack, as we know EmpathyConnectionManagers is ready the
422
* EmpathyAccountSettings should be ready right away as well */
423
g_assert (empathy_account_settings_is_ready (settings));
425
entries = gconf_client_all_entries (client, path, &error);
429
DEBUG ("Failed to get all entries: %s", error->message);
430
g_error_free (error);
434
_recurse_account (entries, settings, account_name);
436
key = g_strdup_printf ("%s/enabled", path);
437
enabled = gconf_client_get_bool (client, key, NULL);
440
misc = g_slice_new (Misc);
441
misc->account_name = account_name;
442
misc->enable = enabled;
444
empathy_account_settings_apply_async (settings,
445
_create_account_cb, misc);
451
g_slist_free (entries);
456
DEBUG ("Failed to import %s", path);
457
g_free (account_name);
458
if (settings != NULL)
459
g_object_unref (settings);
464
empathy_import_mc4_has_imported (void)
469
client = gconf_client_get_default ();
471
ret = gconf_client_get_bool (client, IMPORTED_MC4_ACCOUNTS, NULL);
472
g_object_unref (client);
478
empathy_import_mc4_accounts (EmpathyConnectionManagers *managers)
481
GError *error = NULL;
482
GSList *dir, *dirs = NULL;
483
gboolean imported_mc4_accounts;
484
gboolean imported = FALSE;
486
g_return_val_if_fail (empathy_connection_managers_is_ready (managers),
489
client = gconf_client_get_default ();
491
imported_mc4_accounts = gconf_client_get_bool (client,
492
IMPORTED_MC4_ACCOUNTS, &error);
496
DEBUG ("Failed to get import_mc4_accounts key: %s", error->message);
497
g_error_free (error);
501
if (imported_mc4_accounts)
503
DEBUG ("Mc4 accounts previously imported");
507
DEBUG ("MC 4 accounts are going to be imported");
509
dirs = gconf_client_all_dirs (client, MC_ACCOUNTS_GCONF_BASE, &error);
513
DEBUG ("Failed to get MC4 account dirs: %s",
515
g_clear_error (&error);
516
g_object_unref (client);
520
for (dir = dirs; NULL != dir; dir = dir->next)
522
if (import_one_account ((gchar *) dir->data, managers, client))
528
gconf_client_set_bool (client, IMPORTED_MC4_ACCOUNTS, TRUE, NULL);
531
g_object_unref (client);