~ubuntu-branches/ubuntu/precise/telepathy-mission-control-5/precise

« back to all changes in this revision

Viewing changes to util/mc-account-convert.c

Tags: upstream-5.5.0
ImportĀ upstreamĀ versionĀ 5.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 8 -*- */
2
 
/*
3
 
 * This file is part of mission-control
4
 
 *
5
 
 * Copyright (C) 2007 Nokia Corporation. 
6
 
 *
7
 
 * Contact: Alberto Mardegan  <alberto.mardegan@nokia.com>
8
 
 *
9
 
 * This library is free software; you can redistribute it and/or
10
 
 * modify it under the terms of the GNU Lesser General Public License
11
 
 * version 2.1 as published by the Free Software Foundation.
12
 
 *
13
 
 * This library is distributed in the hope that it will be useful, but
14
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
 
 * Lesser General Public License for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public
19
 
 * License along with this library; if not, write to the Free Software
20
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21
 
 * 02110-1301 USA
22
 
 *
23
 
 */
24
 
 
25
 
#include <glib.h>
26
 
#include <gconf/gconf-client.h>
27
 
#include <stdio.h>
28
 
#include <string.h>
29
 
#include <config.h>
30
 
#include <dbus/dbus.h>
31
 
#include <dbus/dbus-glib.h>
32
 
#include <telepathy-glib/dbus.h>
33
 
#include <libmcclient/mc-account-manager.h>
34
 
#include <libmcclient/mc-account.h>
35
 
 
36
 
#define MC_ACCOUNTS_GCONF_BASE "/apps/telepathy/mc/accounts"
37
 
#define MC_ACCOUNTS_GCONF_KEY_DELETED "deleted"
38
 
#define MC_ACCOUNTS_GCONF_KEY_PROFILE "profile"
39
 
 
40
 
#define MC_ACCOUNTS_KEY_MANAGER "manager"
41
 
#define MC_ACCOUNTS_KEY_PROTOCOL "protocol"
42
 
#define MC_ACCOUNTS_KEY_PRESETS "presets"
43
 
 
44
 
#define PROFILE_GROUP "Profile"
45
 
 
46
 
#define PROFILE_SUFFIX ".profile"
47
 
#define MANAGER_SUFFIX ".manager"
48
 
 
49
 
static GMainLoop *main_loop;
50
 
GConfClient *client = NULL;
51
 
static gint num_processing_accounts = 0;
52
 
 
53
 
typedef struct
54
 
{
55
 
    gchar *manager;
56
 
    gchar *protocol;
57
 
    gchar *profile;
58
 
    GHashTable *parameters;
59
 
    GKeyFile *manager_cfg;
60
 
    gchar *protocol_grp;
61
 
 
62
 
    gchar *alias;
63
 
    GArray avatar;
64
 
    gchar *avatar_mime;
65
 
    gchar *display_name;
66
 
    gchar *normalized_name;
67
 
    gboolean enabled;
68
 
 
69
 
    gint active_calls;
70
 
} AccountInfo;
71
 
    
72
 
typedef union
73
 
{
74
 
    gchar *v_string;
75
 
    gint v_int;
76
 
    gboolean v_bool;
77
 
} ParamValue;
78
 
 
79
 
static void
80
 
account_info_free (AccountInfo *ai)
81
 
{
82
 
    g_free (ai->manager);
83
 
    g_free (ai->protocol);
84
 
    g_free (ai->profile);
85
 
    g_free (ai->protocol_grp);
86
 
    g_key_file_free (ai->manager_cfg);
87
 
    g_hash_table_destroy (ai->parameters);
88
 
    g_free (ai->alias);
89
 
    g_free (ai->avatar.data);
90
 
    g_free (ai->avatar_mime);
91
 
    g_free (ai->display_name);
92
 
    g_free (ai->normalized_name);
93
 
 
94
 
    g_free (ai);
95
 
}
96
 
 
97
 
static inline void
98
 
account_creation_ended (AccountInfo *ai)
99
 
{
100
 
    account_info_free (ai);
101
 
    num_processing_accounts--;
102
 
    if (num_processing_accounts == 0)
103
 
        g_main_loop_quit (main_loop);
104
 
}
105
 
 
106
 
static gchar *
107
 
gc_dup_string (const GConfValue *value)
108
 
{
109
 
    return g_strdup (gconf_value_get_string (value));
110
 
}
111
 
 
112
 
static const gchar**
113
 
_mc_manager_get_dirs (void)
114
 
{
115
 
    GSList *dir_list = NULL, *slist;
116
 
    const gchar *dirname;
117
 
    static gchar **manager_dirs = NULL;
118
 
    guint n;
119
 
 
120
 
    if (manager_dirs) return (const gchar **)manager_dirs;
121
 
 
122
 
    dirname = g_getenv ("MC_MANAGER_DIR");
123
 
    if (dirname && g_file_test (dirname, G_FILE_TEST_IS_DIR))
124
 
        dir_list = g_slist_prepend (dir_list, (gchar *)dirname);
125
 
 
126
 
    if (MANAGERS_DIR[0] == '/')
127
 
    {
128
 
        if (g_file_test (MANAGERS_DIR, G_FILE_TEST_IS_DIR))
129
 
            dir_list = g_slist_prepend (dir_list, MANAGERS_DIR);
130
 
    }
131
 
    else
132
 
    {
133
 
        const gchar * const *dirs;
134
 
        gchar *dir;
135
 
 
136
 
        dir = g_build_filename (g_get_user_data_dir(), MANAGERS_DIR, NULL);
137
 
        if (g_file_test (dir, G_FILE_TEST_IS_DIR))
138
 
            dir_list = g_slist_prepend (dir_list, dir);
139
 
        else g_free (dir);
140
 
 
141
 
        dirs = g_get_system_data_dirs();
142
 
        for (dirname = *dirs; dirname; dirs++, dirname = *dirs)
143
 
        {
144
 
            dir = g_build_filename (dirname, MANAGERS_DIR, NULL);
145
 
            if (g_file_test (dir, G_FILE_TEST_IS_DIR))
146
 
                dir_list = g_slist_prepend (dir_list, dir);
147
 
            else g_free (dir);
148
 
        }
149
 
    }
150
 
 
151
 
    /* build the string array */
152
 
    n = g_slist_length (dir_list);
153
 
    manager_dirs = g_new (gchar *, n + 1);
154
 
    manager_dirs[n--] = NULL;
155
 
    for (slist = dir_list; slist; slist = slist->next)
156
 
        manager_dirs[n--] = slist->data;
157
 
    g_slist_free (dir_list);
158
 
    return (const gchar **)manager_dirs;
159
 
}
160
 
 
161
 
static gchar *
162
 
_mc_manager_filename (const gchar *unique_name)
163
 
{
164
 
    const gchar **manager_dirs;
165
 
    const gchar *dirname;
166
 
    gchar *filename, *filepath = NULL;
167
 
 
168
 
    manager_dirs = _mc_manager_get_dirs ();
169
 
    if (!manager_dirs) return NULL;
170
 
 
171
 
    filename = g_strconcat (unique_name, MANAGER_SUFFIX, NULL);
172
 
    for (dirname = *manager_dirs; dirname; manager_dirs++, dirname = *manager_dirs)
173
 
    {
174
 
        filepath = g_build_filename (dirname, filename, NULL);
175
 
        if (g_file_test (filepath, G_FILE_TEST_EXISTS)) break;
176
 
        g_free (filepath);
177
 
        filepath = NULL;
178
 
    }
179
 
    g_free (filename);
180
 
    return filepath;
181
 
}
182
 
 
183
 
static const gchar**
184
 
_mc_profile_get_dirs (void)
185
 
{
186
 
    GSList *dir_list = NULL, *slist;
187
 
    const gchar *dirname;
188
 
    static gchar **profile_dirs = NULL;
189
 
    guint n;
190
 
 
191
 
    if (profile_dirs) return (const gchar **)profile_dirs;
192
 
 
193
 
    dirname = g_getenv ("MC_PROFILE_DIR");
194
 
    if (dirname && g_file_test (dirname, G_FILE_TEST_IS_DIR))
195
 
        dir_list = g_slist_prepend (dir_list, (gchar *)dirname);
196
 
 
197
 
    if (PROFILES_DIR[0] == '/')
198
 
    {
199
 
        if (g_file_test (PROFILES_DIR, G_FILE_TEST_IS_DIR))
200
 
            dir_list = g_slist_prepend (dir_list, PROFILES_DIR);
201
 
    }
202
 
    else
203
 
    {
204
 
        const gchar * const *dirs;
205
 
        gchar *dir;
206
 
        
207
 
        dir = g_build_filename (g_get_user_data_dir(), PROFILES_DIR, NULL);
208
 
        if (g_file_test (dir, G_FILE_TEST_IS_DIR))
209
 
            dir_list = g_slist_prepend (dir_list, dir);
210
 
        else g_free (dir);
211
 
 
212
 
        dirs = g_get_system_data_dirs();
213
 
        for (dirname = *dirs; dirname; dirs++, dirname = *dirs)
214
 
        {
215
 
            dir = g_build_filename (dirname, PROFILES_DIR, NULL);
216
 
            if (g_file_test (dir, G_FILE_TEST_IS_DIR))
217
 
                dir_list = g_slist_prepend (dir_list, dir);
218
 
            else g_free (dir);
219
 
        }
220
 
    }
221
 
 
222
 
    /* build the string array */
223
 
    n = g_slist_length (dir_list);
224
 
    profile_dirs = g_new (gchar *, n + 1);
225
 
    profile_dirs[n--] = NULL;
226
 
    for (slist = dir_list; slist; slist = slist->next)
227
 
        profile_dirs[n--] = slist->data;
228
 
    g_slist_free (dir_list);
229
 
    return (const gchar **)profile_dirs;
230
 
}
231
 
 
232
 
static gchar *
233
 
get_profile_path (const gchar *name)
234
 
{
235
 
    const gchar **profile_dirs;
236
 
    const gchar *dirname;
237
 
    gchar *filename, *filepath = NULL;
238
 
 
239
 
    profile_dirs = _mc_profile_get_dirs ();
240
 
    if (!profile_dirs) return NULL;
241
 
 
242
 
    filename = g_strconcat (name, PROFILE_SUFFIX, NULL);
243
 
    for (dirname = *profile_dirs; dirname; profile_dirs++, dirname = *profile_dirs)
244
 
    {
245
 
        filepath = g_build_filename (dirname, filename, NULL);
246
 
        if (g_file_test (filepath, G_FILE_TEST_EXISTS)) break;
247
 
        g_free (filepath);
248
 
        filepath = NULL;
249
 
    }
250
 
    g_free (filename);
251
 
    return filepath;
252
 
}
253
 
 
254
 
static const gchar *
255
 
account_key (const gchar *account, const gchar *key)
256
 
{
257
 
    static gchar buffer[2048];
258
 
 
259
 
    g_snprintf (buffer, sizeof (buffer), "%s/%s/%s", MC_ACCOUNTS_GCONF_BASE, account, key);
260
 
    return buffer;
261
 
}
262
 
 
263
 
static void
264
 
add_parameter (AccountInfo *ai, const gchar *name, ParamValue pv, gchar signature)
265
 
{
266
 
    GValue *value;
267
 
 
268
 
    value = g_new0(GValue, 1);
269
 
 
270
 
    switch (signature)
271
 
    {
272
 
    case DBUS_TYPE_STRING:
273
 
        g_value_init (value, G_TYPE_STRING);
274
 
        g_value_take_string (value, pv.v_string);
275
 
        break;
276
 
    case DBUS_TYPE_INT16:
277
 
    case DBUS_TYPE_INT32:
278
 
        g_value_init (value, G_TYPE_INT);
279
 
        g_value_set_int (value, pv.v_int);
280
 
        break;
281
 
    case DBUS_TYPE_UINT16:
282
 
    case DBUS_TYPE_UINT32:
283
 
        g_value_init (value, G_TYPE_UINT);
284
 
        g_value_set_uint (value, (guint)pv.v_int);
285
 
        break;
286
 
    case DBUS_TYPE_BOOLEAN:
287
 
        g_value_init (value, G_TYPE_BOOLEAN);
288
 
        g_value_set_boolean (value, pv.v_bool);
289
 
        break;
290
 
    }
291
 
 
292
 
    g_hash_table_replace (ai->parameters, g_strdup (name), value);
293
 
}
294
 
 
295
 
static gboolean
296
 
read_gconf_data (AccountInfo *ai, const gchar *unique_name)
297
 
{
298
 
    GSList *entries, *list;
299
 
    gchar dir[200], signature, *avatar_filename = NULL;
300
 
    ParamValue pv;
301
 
    gint len;
302
 
 
303
 
    len = g_snprintf (dir, sizeof (dir), "%s/%s", MC_ACCOUNTS_GCONF_BASE, unique_name);
304
 
    len++;
305
 
    entries = gconf_client_all_entries (client, dir, NULL);
306
 
    for (list = entries; list != NULL; list = list->next)
307
 
    {
308
 
        GConfEntry *entry = list->data;
309
 
        const gchar *key = entry->key + len;
310
 
        GConfValue *value = entry->value;
311
 
 
312
 
        if (strncmp (key, "param-", 6) == 0)
313
 
        {
314
 
            switch (value->type)
315
 
            {
316
 
            case GCONF_VALUE_STRING:
317
 
                pv.v_string = gc_dup_string (value);
318
 
                signature = DBUS_TYPE_STRING;
319
 
                break;
320
 
            case GCONF_VALUE_INT:
321
 
                pv.v_int = gconf_value_get_int (value);
322
 
                signature = DBUS_TYPE_INT32;
323
 
                break;
324
 
            case GCONF_VALUE_BOOL:
325
 
                pv.v_bool = gconf_value_get_bool (value);
326
 
                signature = DBUS_TYPE_BOOLEAN;
327
 
                break;
328
 
            default:
329
 
                g_warning ("Parameter %s has unrecognized type: %u", key, value->type);
330
 
                return FALSE;
331
 
            }
332
 
            add_parameter (ai, key + 6, pv, signature);
333
 
        }
334
 
        else if (strcmp (key, "alias") == 0)
335
 
        {
336
 
            ai->alias = gc_dup_string (value);
337
 
        }
338
 
        else if (strcmp (key, "avatar_mime") == 0)
339
 
        {
340
 
            ai->avatar_mime = gc_dup_string (value);
341
 
        }
342
 
        else if (strcmp (key, "display_name") == 0)
343
 
        {
344
 
            ai->display_name = gc_dup_string (value);
345
 
        }
346
 
        else if (strcmp (key, "normalized_name") == 0)
347
 
        {
348
 
            ai->normalized_name = gc_dup_string (value);
349
 
        }
350
 
        else if (strcmp (key, "enabled") == 0)
351
 
        {
352
 
            ai->enabled = gconf_value_get_bool (value);
353
 
        }
354
 
        else if (strcmp (key, "data_dir") == 0)
355
 
        {
356
 
            const gchar *data_dir = gconf_value_get_string (value);
357
 
            avatar_filename = g_build_filename (data_dir, "avatar.bin", NULL);
358
 
        }
359
 
    }
360
 
    g_slist_foreach (entries, (GFunc)gconf_entry_free, NULL);
361
 
    g_slist_free (entries);
362
 
 
363
 
    /* read the avatar */
364
 
    if (avatar_filename && g_file_test (avatar_filename, G_FILE_TEST_EXISTS))
365
 
    {
366
 
        GError *error = NULL;
367
 
        gchar *data;
368
 
        gsize avatar_len;
369
 
        if (g_file_get_contents (avatar_filename, &data, &avatar_len, &error))
370
 
        {
371
 
            ai->avatar.data = (gchar *)data;
372
 
            ai->avatar.len = avatar_len;
373
 
        }
374
 
        else
375
 
        {
376
 
            g_warning ("%s: reading file %s failed (%s)", G_STRLOC,
377
 
                       avatar_filename, error->message);
378
 
            g_error_free (error);
379
 
        }
380
 
    }
381
 
    g_free (avatar_filename);
382
 
    return TRUE;
383
 
}
384
 
 
385
 
static gboolean
386
 
parse_profile_param (AccountInfo *ai, GKeyFile *profile, const gchar *key)
387
 
{
388
 
    gchar *param_info, signature, param_str[200];
389
 
    GError *error = NULL;
390
 
    ParamValue pv;
391
 
 
392
 
    /* read the parameter signature from the manager file */
393
 
    /* key + 8, to skip the "Default-" */
394
 
    g_snprintf (param_str, sizeof (param_str), "param-%s", key + 8);
395
 
    param_info = g_key_file_get_string (ai->manager_cfg, ai->protocol_grp, param_str, NULL);
396
 
    if (!param_info) return FALSE;
397
 
    signature = param_info[0];
398
 
    g_free (param_info);
399
 
 
400
 
    switch (signature)
401
 
    {
402
 
    case DBUS_TYPE_STRING:
403
 
        pv.v_string = g_key_file_get_string (profile, PROFILE_GROUP,
404
 
                                             key, &error);
405
 
        break;
406
 
    case DBUS_TYPE_INT16:
407
 
    case DBUS_TYPE_INT32:
408
 
    case DBUS_TYPE_UINT16:
409
 
    case DBUS_TYPE_UINT32:
410
 
        pv.v_int = g_key_file_get_integer (profile, PROFILE_GROUP,
411
 
                                           key, &error);
412
 
        break;
413
 
    case DBUS_TYPE_BOOLEAN:
414
 
        pv.v_bool = g_key_file_get_boolean (profile, PROFILE_GROUP,
415
 
                                            key, &error);
416
 
        break;
417
 
    default:
418
 
        g_warning ("%s: skipping parameter %s, unknown type %c", G_STRFUNC, key + 8, signature);
419
 
        return FALSE;
420
 
    }
421
 
    if (error)
422
 
    {
423
 
        g_error_free (error);
424
 
        return FALSE;
425
 
    }
426
 
 
427
 
    add_parameter (ai, key + 8, pv, signature);
428
 
    return FALSE;
429
 
}
430
 
 
431
 
static gboolean
432
 
read_manager (AccountInfo *ai)
433
 
{
434
 
    GError *error = NULL;
435
 
    gchar *filename;
436
 
    gboolean ret = FALSE;
437
 
 
438
 
    if (!ai->manager) return FALSE;
439
 
    filename = _mc_manager_filename (ai->manager);
440
 
 
441
 
    ai->manager_cfg = g_key_file_new ();
442
 
    if (!ai->manager_cfg)
443
 
        goto free_filename;
444
 
 
445
 
    if (!g_key_file_load_from_file (ai->manager_cfg, filename, G_KEY_FILE_NONE, &error))
446
 
    {
447
 
        g_warning ("%s: loading %s failed: %s", G_STRFUNC,
448
 
                   filename, error->message);
449
 
        g_error_free (error);
450
 
        g_key_file_free (ai->manager_cfg);
451
 
        goto free_filename;
452
 
    }
453
 
 
454
 
    ai->protocol_grp = g_strdup_printf ("Protocol %s", ai->protocol);
455
 
    ret = TRUE;
456
 
free_filename:
457
 
    g_free (filename);
458
 
    return ret;
459
 
}
460
 
 
461
 
static void
462
 
_g_value_free (gpointer data)
463
 
{
464
 
    GValue *value = (GValue *) data;
465
 
    g_value_unset (value);
466
 
    g_free (value);
467
 
}
468
 
 
469
 
static void
470
 
set_prop_cb (TpProxy *proxy, const GError *error,
471
 
             gpointer user_data, GObject *weak_object)
472
 
{
473
 
    McAccount *account = MC_ACCOUNT (proxy);
474
 
    AccountInfo *ai = user_data;
475
 
 
476
 
    ai->active_calls--;
477
 
    g_debug ("%s (%s): active calls left: %d",
478
 
             G_STRFUNC, account->name, ai->active_calls);
479
 
    if (error)
480
 
    {
481
 
        g_warning ("%s failed: %s", G_STRFUNC, error->message);
482
 
        g_object_unref (proxy);
483
 
        account_creation_ended (ai);
484
 
    }
485
 
 
486
 
    if (ai->active_calls == 0)
487
 
    {
488
 
        g_debug ("No more active calls");
489
 
        account_creation_ended (ai);
490
 
    }
491
 
}
492
 
 
493
 
static gboolean
494
 
set_account_prop (McAccount *account, const gchar *iface, const gchar *name,
495
 
                  GValue *value, AccountInfo *ai)
496
 
{
497
 
    TpProxyPendingCall *call;
498
 
 
499
 
    call = tp_cli_dbus_properties_call_set (account, -1,
500
 
                                            iface, name, value,
501
 
                                            set_prop_cb, ai, NULL,
502
 
                                            NULL);
503
 
    g_value_unset (value);
504
 
    if (!call)
505
 
    {
506
 
        g_object_unref (account);
507
 
        account_creation_ended (ai);
508
 
        return FALSE;
509
 
    }
510
 
    ai->active_calls++;
511
 
    return TRUE;
512
 
}
513
 
 
514
 
static void
515
 
create_account_cb (TpProxy *proxy, const gchar *obj_path, const GError *error,
516
 
                   gpointer user_data, GObject *weak_object)
517
 
{
518
 
    AccountInfo *ai = user_data;
519
 
    McAccount *account;
520
 
    GValue value = { 0 };
521
 
    gboolean ok;
522
 
    GType type;
523
 
 
524
 
    g_debug ("%s called", G_STRFUNC);
525
 
    if (error)
526
 
    {
527
 
        g_warning ("got error %s", error->message);
528
 
        account_creation_ended (ai);
529
 
        return;
530
 
    }
531
 
 
532
 
    account = mc_account_new (proxy->dbus_daemon, obj_path);
533
 
    g_debug ("Created account %s", account->name);
534
 
 
535
 
    /* Set all account properties */
536
 
    g_value_init (&value, G_TYPE_STRING);
537
 
    g_value_set_static_string (&value, ai->profile);
538
 
    ok = set_account_prop (account,
539
 
                           MC_IFACE_ACCOUNT_INTERFACE_COMPAT, "Profile",
540
 
                           &value, ai);
541
 
    if (!ok) return;
542
 
 
543
 
    g_value_init (&value, G_TYPE_STRING);
544
 
    g_value_set_static_string (&value, ai->alias);
545
 
    ok = set_account_prop (account,
546
 
                           MC_IFACE_ACCOUNT, "Nickname",
547
 
                           &value, ai);
548
 
    if (!ok) return;
549
 
 
550
 
    g_value_init (&value, G_TYPE_BOOLEAN);
551
 
    g_value_set_boolean (&value, ai->enabled);
552
 
    ok = set_account_prop (account,
553
 
                           MC_IFACE_ACCOUNT, "Enabled",
554
 
                           &value, ai);
555
 
    if (!ok) return;
556
 
 
557
 
    if (ai->avatar.data && ai->avatar_mime)
558
 
    {
559
 
        GValueArray *va;
560
 
 
561
 
        type = dbus_g_type_get_struct ("GValueArray",
562
 
                                       dbus_g_type_get_collection ("GArray",
563
 
                                                                   G_TYPE_UCHAR),
564
 
                                       G_TYPE_STRING,
565
 
                                       G_TYPE_INVALID);
566
 
        g_value_init (&value, type);
567
 
        g_value_take_boxed (&value, dbus_g_type_specialized_construct (type));
568
 
        va = (GValueArray *) g_value_get_boxed (&value);
569
 
        g_value_set_static_boxed (va->values, &ai->avatar);
570
 
        g_value_set_static_string (va->values + 1, ai->avatar_mime);
571
 
        ok = set_account_prop (account,
572
 
                               MC_IFACE_ACCOUNT_INTERFACE_AVATAR, "Avatar",
573
 
                               &value, ai);
574
 
        if (!ok) return;
575
 
    }
576
 
}
577
 
 
578
 
static gboolean
579
 
write_account (McAccountManager *am, AccountInfo *ai)
580
 
{
581
 
    TpProxyPendingCall *call;
582
 
    GHashTable *empty;
583
 
 
584
 
    empty = g_hash_table_new (g_str_hash, g_str_equal);
585
 
    call = mc_cli_account_manager_call_create_account (am, -1,
586
 
                                                       ai->manager,
587
 
                                                       ai->protocol,
588
 
                                                       ai->display_name,
589
 
                                                       ai->parameters,
590
 
                                                       empty,
591
 
                                                       create_account_cb,
592
 
                                                       ai,
593
 
                                                       NULL,
594
 
                                                       NULL);
595
 
    g_hash_table_unref (empty);
596
 
    if (!call) return FALSE;
597
 
 
598
 
    return TRUE;
599
 
}
600
 
 
601
 
static gboolean
602
 
convert_account (const gchar *unique_name, McAccountManager *am)
603
 
{
604
 
    AccountInfo *ai;
605
 
    const gchar *key;
606
 
    GKeyFile *profile;
607
 
    GError *error = NULL;
608
 
    gchar *profile_name, *profile_path;
609
 
    gchar **keys, **i_key;
610
 
    gboolean ret;
611
 
 
612
 
    key = account_key (unique_name, MC_ACCOUNTS_GCONF_KEY_DELETED);
613
 
    if (gconf_client_get_bool (client, key, NULL)) return TRUE;
614
 
 
615
 
    g_debug ("Converting account %s", unique_name);
616
 
 
617
 
    key = account_key (unique_name, MC_ACCOUNTS_GCONF_KEY_PROFILE);
618
 
    profile_name = gconf_client_get_string (client, key, NULL);
619
 
    if (!profile_name) return FALSE;
620
 
 
621
 
    profile_path = get_profile_path (profile_name);
622
 
    if (!profile_path)
623
 
    {
624
 
        g_warning ("Profile `%s' not found", profile_name);
625
 
        g_free (profile_name);
626
 
        return FALSE;
627
 
    }
628
 
 
629
 
    profile = g_key_file_new ();
630
 
    g_key_file_load_from_file (profile, profile_path, 0, &error);
631
 
    g_free (profile_path);
632
 
    if (error)
633
 
    {
634
 
        g_warning ("Couldn't load profile `%s': %s", profile_name, error->message);
635
 
        g_error_free (error);
636
 
        g_key_file_free (profile);
637
 
        g_free (profile_name);
638
 
        return FALSE;
639
 
    }
640
 
 
641
 
    ai = g_new0 (AccountInfo, 1);
642
 
    ai->profile = profile_name;
643
 
    ai->parameters = g_hash_table_new_full (g_str_hash, g_str_equal,
644
 
                                            g_free, _g_value_free);
645
 
    ai->manager = g_key_file_get_string (profile, PROFILE_GROUP, "Manager", NULL);
646
 
    ai->protocol = g_key_file_get_string (profile, PROFILE_GROUP, "Protocol", NULL);
647
 
    read_manager (ai);
648
 
 
649
 
    keys = g_key_file_get_keys (profile, PROFILE_GROUP, NULL, NULL);
650
 
    for (i_key = keys; *i_key != NULL; i_key++)
651
 
    {
652
 
        if (strncmp (*i_key, "Default-", 8) == 0)
653
 
        {
654
 
            parse_profile_param (ai, profile, *i_key);
655
 
            g_debug ("Copying param %s from profile", *i_key + 8);
656
 
        }
657
 
    }
658
 
    g_strfreev (keys);
659
 
    g_key_file_free (profile);
660
 
 
661
 
    if (!read_gconf_data (ai, unique_name))
662
 
    {
663
 
        account_info_free (ai);
664
 
        return FALSE;
665
 
    }
666
 
 
667
 
    num_processing_accounts++;
668
 
    ret = write_account (am, ai);
669
 
    if (!ret)
670
 
        account_info_free (ai);
671
 
 
672
 
    return ret;
673
 
}
674
 
 
675
 
static gchar *
676
 
_account_name_from_key (const gchar *key)
677
 
{
678
 
    guint base_len = strlen (MC_ACCOUNTS_GCONF_BASE);
679
 
    const gchar *base, *slash;
680
 
 
681
 
    g_assert (key == strstr (key, MC_ACCOUNTS_GCONF_BASE));
682
 
    g_assert (strlen (key) > base_len + 1);
683
 
 
684
 
    base = key + base_len + 1;
685
 
    slash = strchr (base, '/');
686
 
 
687
 
    if (slash == NULL)
688
 
        return g_strdup (base);
689
 
    else
690
 
        return g_strndup (base, slash - base);
691
 
}
692
 
 
693
 
static gboolean
694
 
convert_accounts (McAccountManager *am)
695
 
{
696
 
    GError *error = NULL;
697
 
    GSList *dirs, *list;
698
 
 
699
 
    dirs = gconf_client_all_dirs (client, MC_ACCOUNTS_GCONF_BASE, &error);
700
 
    if (error)
701
 
    {
702
 
        g_warning ("gconf_client_all_dirs failed: %s", error->message);
703
 
        g_error_free (error);
704
 
        return FALSE;
705
 
    }
706
 
 
707
 
    for (list = dirs; list; list = list->next)
708
 
    {
709
 
        gchar *unique_name = _account_name_from_key (list->data);
710
 
        if (!convert_account (unique_name, am))
711
 
        {
712
 
            num_processing_accounts--;
713
 
            g_debug ("...FAILED!");
714
 
        }
715
 
        g_free (unique_name);
716
 
    }
717
 
    g_slist_foreach (dirs, (GFunc)g_free, NULL);
718
 
    g_slist_free (dirs);
719
 
 
720
 
    g_debug ("processing accounts: %d", num_processing_accounts);
721
 
    if (num_processing_accounts == 0)
722
 
        g_main_loop_quit (main_loop);
723
 
    return FALSE;
724
 
}
725
 
 
726
 
int
727
 
main (int argc, char **argv)
728
 
{
729
 
    McAccountManager *am;
730
 
    DBusGConnection *dbus_conn;
731
 
    TpDBusDaemon *daemon;
732
 
    gint ret = 0;
733
 
 
734
 
    g_type_init ();
735
 
 
736
 
    dbus_conn = tp_get_bus ();
737
 
    daemon = tp_dbus_daemon_new (dbus_conn);
738
 
    dbus_g_connection_unref (dbus_conn);
739
 
 
740
 
    am = mc_account_manager_new (daemon);
741
 
    g_object_unref (daemon);
742
 
 
743
 
    client = gconf_client_get_default ();
744
 
 
745
 
    g_idle_add ((GSourceFunc)convert_accounts, am);
746
 
 
747
 
    main_loop = g_main_loop_new (NULL, FALSE);
748
 
    g_main_loop_run (main_loop);
749
 
 
750
 
    g_object_unref (am);
751
 
    g_object_unref (client);
752
 
 
753
 
    return ret;
754
 
}
755
 
 
756