~darkxst/ubuntu/saucy/gdm/lp1212408

« back to all changes in this revision

Viewing changes to common/gdm-config.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2008-09-02 10:37:20 UTC
  • mfrom: (1.4.27 upstream)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: james.westby@ubuntu.com-20080902103720-p810vv530hqj45wg
Tags: 2.20.7-3
* Install the debian-moreblue-orbit theme, thanks Andre Luiz Rodrigues 
  Ferreira. Closes: #497440.
* 35_gdm.conf.patch: make it the default.
* copyright: fix encoding.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 
2
 *
 
3
 * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Library General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Library General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Library General Public
 
16
 * License along with this library; if not, write to the
 
17
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
 * Boston, MA 02111-1307, USA.
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
 
 
23
#include <string.h>
 
24
#include <unistd.h>
 
25
#include <stdlib.h>
 
26
#include <locale.h>
 
27
#include <syslog.h>
 
28
#include <errno.h>
 
29
#include <sys/stat.h>
 
30
 
 
31
#include <glib.h>
 
32
#include <glib/gstdio.h>
 
33
#include <glib/gi18n.h>
 
34
 
 
35
#include "gdm-config.h"
 
36
 
 
37
struct _GdmConfig
 
38
{
 
39
        char            *mandatory_filename;
 
40
        char            *default_filename;
 
41
        char            *custom_filename;
 
42
 
 
43
        gboolean         mandatory_loaded;
 
44
        gboolean         default_loaded;
 
45
        gboolean         custom_loaded;
 
46
 
 
47
        GKeyFile        *mandatory_key_file;
 
48
        GKeyFile        *default_key_file;
 
49
        GKeyFile        *custom_key_file;
 
50
 
 
51
        time_t           mandatory_mtime;
 
52
        time_t           default_mtime;
 
53
        time_t           custom_mtime;
 
54
 
 
55
        GPtrArray       *entries;
 
56
 
 
57
        GHashTable      *value_hash;
 
58
 
 
59
        GdmConfigFunc    validate_func;
 
60
        gpointer         validate_func_data;
 
61
        GdmConfigFunc    notify_func;
 
62
        gpointer         notify_func_data;
 
63
};
 
64
 
 
65
 
 
66
typedef struct _GdmConfigRealValue
 
67
{
 
68
        GdmConfigValueType type;
 
69
        union {
 
70
                gboolean bool;
 
71
                int      integer;
 
72
                char    *str;
 
73
                char   **array;
 
74
        } val;
 
75
} GdmConfigRealValue;
 
76
 
 
77
#define REAL_VALUE(x) ((GdmConfigRealValue *)(x))
 
78
 
 
79
GQuark
 
80
gdm_config_error_quark (void)
 
81
{
 
82
        return g_quark_from_static_string ("gdm-config-error-quark");
 
83
}
 
84
 
 
85
GdmConfigEntry *
 
86
gdm_config_entry_copy (const GdmConfigEntry *src)
 
87
{
 
88
        GdmConfigEntry *dest;
 
89
 
 
90
        dest = g_new0 (GdmConfigEntry, 1);
 
91
        dest->group = g_strdup (src->group);
 
92
        dest->key = g_strdup (src->key);
 
93
        dest->default_value = g_strdup (src->default_value);
 
94
        dest->type = src->type;
 
95
        dest->id = src->id;
 
96
 
 
97
        return dest;
 
98
}
 
99
 
 
100
void
 
101
gdm_config_entry_free (GdmConfigEntry *entry)
 
102
{
 
103
        g_free (entry->group);
 
104
        g_free (entry->key);
 
105
        g_free (entry->default_value);
 
106
 
 
107
        g_free (entry);
 
108
}
 
109
 
 
110
GdmConfigValue *
 
111
gdm_config_value_new (GdmConfigValueType type)
 
112
{
 
113
        GdmConfigValue *value;
 
114
 
 
115
        g_return_val_if_fail (type != GDM_CONFIG_VALUE_INVALID, NULL);
 
116
 
 
117
        value = (GdmConfigValue *) g_slice_new0 (GdmConfigRealValue);
 
118
        value->type = type;
 
119
 
 
120
        return value;
 
121
}
 
122
 
 
123
void
 
124
gdm_config_value_free (GdmConfigValue *value)
 
125
{
 
126
        GdmConfigRealValue *real;
 
127
 
 
128
        real = REAL_VALUE (value);
 
129
 
 
130
        switch (real->type) {
 
131
        case GDM_CONFIG_VALUE_INVALID:
 
132
        case GDM_CONFIG_VALUE_BOOL:
 
133
        case GDM_CONFIG_VALUE_INT:
 
134
                break;
 
135
        case GDM_CONFIG_VALUE_STRING:
 
136
        case GDM_CONFIG_VALUE_LOCALE_STRING:
 
137
                g_free (real->val.str);
 
138
                break;
 
139
        case GDM_CONFIG_VALUE_STRING_ARRAY:
 
140
        case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY:
 
141
                g_strfreev (real->val.array);
 
142
                break;
 
143
        default:
 
144
                g_assert_not_reached ();
 
145
                break;
 
146
        }
 
147
 
 
148
        g_slice_free (GdmConfigRealValue, real);
 
149
}
 
150
 
 
151
static void
 
152
set_string (char      **dest,
 
153
            const char *src)
 
154
{
 
155
        if (*dest != NULL) {
 
156
                g_free (*dest);
 
157
        }
 
158
 
 
159
        *dest = src ? g_strdup (src) : NULL;
 
160
}
 
161
 
 
162
static void
 
163
set_string_array (char      ***dest,
 
164
                  const char **src)
 
165
{
 
166
        if (*dest != NULL) {
 
167
                g_strfreev (*dest);
 
168
        }
 
169
 
 
170
        *dest = src ? g_strdupv ((char **)src) : NULL;
 
171
}
 
172
 
 
173
GdmConfigValue *
 
174
gdm_config_value_copy (const GdmConfigValue *src)
 
175
{
 
176
        GdmConfigRealValue *dest;
 
177
        GdmConfigRealValue *real;
 
178
 
 
179
        g_return_val_if_fail (src != NULL, NULL);
 
180
 
 
181
        real = REAL_VALUE (src);
 
182
        dest = REAL_VALUE (gdm_config_value_new (src->type));
 
183
 
 
184
        switch (real->type) {
 
185
        case GDM_CONFIG_VALUE_INT:
 
186
        case GDM_CONFIG_VALUE_BOOL:
 
187
        case GDM_CONFIG_VALUE_INVALID:
 
188
                dest->val = real->val;
 
189
                break;
 
190
        case GDM_CONFIG_VALUE_STRING:
 
191
        case GDM_CONFIG_VALUE_LOCALE_STRING:
 
192
                set_string (&dest->val.str, real->val.str);
 
193
                break;
 
194
        case GDM_CONFIG_VALUE_STRING_ARRAY:
 
195
        case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY:
 
196
                set_string_array (&dest->val.array, (const char **)real->val.array);
 
197
                break;
 
198
        default:
 
199
                g_assert_not_reached();
 
200
        }
 
201
 
 
202
        return (GdmConfigValue *) dest;
 
203
}
 
204
 
 
205
const char *
 
206
gdm_config_value_get_string (const GdmConfigValue *value)
 
207
{
 
208
        g_return_val_if_fail (value != NULL, NULL);
 
209
        g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_STRING, NULL);
 
210
        return REAL_VALUE (value)->val.str;
 
211
}
 
212
 
 
213
const char *
 
214
gdm_config_value_get_locale_string (const GdmConfigValue *value)
 
215
{
 
216
        g_return_val_if_fail (value != NULL, NULL);
 
217
        g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_LOCALE_STRING, NULL);
 
218
        return REAL_VALUE (value)->val.str;
 
219
}
 
220
 
 
221
const char **
 
222
gdm_config_value_get_string_array (const GdmConfigValue *value)
 
223
{
 
224
        g_return_val_if_fail (value != NULL, NULL);
 
225
        g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_STRING_ARRAY, NULL);
 
226
        return (const char **)REAL_VALUE (value)->val.array;
 
227
}
 
228
 
 
229
gboolean
 
230
gdm_config_value_get_bool (const GdmConfigValue *value)
 
231
{
 
232
        g_return_val_if_fail (value != NULL, FALSE);
 
233
        g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_BOOL, FALSE);
 
234
        return REAL_VALUE (value)->val.bool;
 
235
}
 
236
 
 
237
int
 
238
gdm_config_value_get_int (const GdmConfigValue *value)
 
239
{
 
240
        g_return_val_if_fail (value != NULL, 0);
 
241
        g_return_val_if_fail (value->type == GDM_CONFIG_VALUE_INT, 0);
 
242
        return REAL_VALUE (value)->val.integer;
 
243
}
 
244
 
 
245
static gint
 
246
safe_strcmp (const char *a,
 
247
             const char *b)
 
248
{
 
249
        return strcmp (a ? a : "", b ? b : "");
 
250
}
 
251
 
 
252
/* based on code from gconf */
 
253
int
 
254
gdm_config_value_compare (const GdmConfigValue *value_a,
 
255
                          const GdmConfigValue *value_b)
 
256
{
 
257
        g_return_val_if_fail (value_a != NULL, 0);
 
258
        g_return_val_if_fail (value_b != NULL, 0);
 
259
 
 
260
        if (value_a->type < value_b->type) {
 
261
                return -1;
 
262
        } else if (value_a->type > value_b->type) {
 
263
                return 1;
 
264
        }
 
265
 
 
266
        switch (value_a->type) {
 
267
        case GDM_CONFIG_VALUE_INT:
 
268
                if (gdm_config_value_get_int (value_a) < gdm_config_value_get_int (value_b)) {
 
269
                        return -1;
 
270
                } else if (gdm_config_value_get_int (value_a) > gdm_config_value_get_int (value_b)) {
 
271
                        return 1;
 
272
                } else {
 
273
                        return 0;
 
274
                }
 
275
        case GDM_CONFIG_VALUE_STRING:
 
276
                return safe_strcmp (gdm_config_value_get_string (value_a),
 
277
                                    gdm_config_value_get_string (value_b));
 
278
        case GDM_CONFIG_VALUE_LOCALE_STRING:
 
279
                return safe_strcmp (gdm_config_value_get_locale_string (value_a),
 
280
                                    gdm_config_value_get_locale_string (value_b));
 
281
        case GDM_CONFIG_VALUE_STRING_ARRAY:
 
282
        case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY:
 
283
                {
 
284
                        char *str_a;
 
285
                        char *str_b;
 
286
                        int   res;
 
287
 
 
288
                        str_a = gdm_config_value_to_string (value_a);
 
289
                        str_b = gdm_config_value_to_string (value_b);
 
290
                        res = safe_strcmp (str_a, str_b);
 
291
                        g_free (str_a);
 
292
                        g_free (str_b);
 
293
 
 
294
                        return res;
 
295
                }
 
296
        case GDM_CONFIG_VALUE_BOOL:
 
297
                if (gdm_config_value_get_bool (value_a) == gdm_config_value_get_bool (value_b)) {
 
298
                        return 0;
 
299
                } else if (gdm_config_value_get_bool (value_a)) {
 
300
                        return 1;
 
301
                } else {
 
302
                        return -1;
 
303
                }
 
304
        case GDM_CONFIG_VALUE_INVALID:
 
305
        default:
 
306
                g_assert_not_reached ();
 
307
                break;
 
308
        }
 
309
 
 
310
        return 0;
 
311
}
 
312
 
 
313
/* based on code from gconf */
 
314
GdmConfigValue *
 
315
gdm_config_value_new_from_string (GdmConfigValueType type,
 
316
                                  const char        *value_str,
 
317
                                  GError           **error)
 
318
{
 
319
        GdmConfigValue *value;
 
320
 
 
321
        g_return_val_if_fail (type != GDM_CONFIG_VALUE_INVALID, NULL);
 
322
        g_return_val_if_fail (value_str != NULL, NULL);
 
323
 
 
324
        value = gdm_config_value_new (type);
 
325
 
 
326
        switch (value->type) {
 
327
        case GDM_CONFIG_VALUE_INT:
 
328
                {
 
329
                        char* endptr = NULL;
 
330
                        glong result;
 
331
 
 
332
                        errno = 0;
 
333
                        result = strtol (value_str, &endptr, 10);
 
334
                        if (endptr == value_str) {
 
335
                                g_set_error (error,
 
336
                                             GDM_CONFIG_ERROR,
 
337
                                             GDM_CONFIG_ERROR_PARSE_ERROR,
 
338
                                             _("Didn't understand `%s' (expected integer)"),
 
339
                                             value_str);
 
340
                                gdm_config_value_free (value);
 
341
                                value = NULL;
 
342
                        } else if (errno == ERANGE) {
 
343
                                g_set_error (error,
 
344
                                             GDM_CONFIG_ERROR,
 
345
                                             GDM_CONFIG_ERROR_PARSE_ERROR,
 
346
                                             _("Integer `%s' is too large or small"),
 
347
                                             value_str);
 
348
                                gdm_config_value_free (value);
 
349
                                value = NULL;
 
350
                        } else {
 
351
                                gdm_config_value_set_int (value, result);
 
352
                        }
 
353
                }
 
354
                break;
 
355
        case GDM_CONFIG_VALUE_BOOL:
 
356
                switch (*value_str) {
 
357
                case 't':
 
358
                case 'T':
 
359
                case '1':
 
360
                case 'y':
 
361
                case 'Y':
 
362
                        gdm_config_value_set_bool (value, TRUE);
 
363
                        break;
 
364
 
 
365
                case 'f':
 
366
                case 'F':
 
367
                case '0':
 
368
                case 'n':
 
369
                case 'N':
 
370
                        gdm_config_value_set_bool (value, FALSE);
 
371
                        break;
 
372
                default:
 
373
                        g_set_error (error,
 
374
                                     GDM_CONFIG_ERROR,
 
375
                                     GDM_CONFIG_ERROR_PARSE_ERROR,
 
376
                                     _("Didn't understand `%s' (expected true or false)"),
 
377
                                     value_str);
 
378
                        gdm_config_value_free (value);
 
379
                        value = NULL;
 
380
                        break;
 
381
                }
 
382
                break;
 
383
        case GDM_CONFIG_VALUE_STRING:
 
384
                if (! g_utf8_validate (value_str, -1, NULL)) {
 
385
                        g_set_error (error,
 
386
                                     GDM_CONFIG_ERROR,
 
387
                                     GDM_CONFIG_ERROR_PARSE_ERROR,
 
388
                                     _("Text contains invalid UTF-8"));
 
389
                        gdm_config_value_free (value);
 
390
                        value = NULL;
 
391
                } else {
 
392
                        gdm_config_value_set_string (value, value_str);
 
393
                }
 
394
                break;
 
395
        case GDM_CONFIG_VALUE_LOCALE_STRING:
 
396
                if (! g_utf8_validate (value_str, -1, NULL)) {
 
397
                        g_set_error (error,
 
398
                                     GDM_CONFIG_ERROR,
 
399
                                     GDM_CONFIG_ERROR_PARSE_ERROR,
 
400
                                     _("Text contains invalid UTF-8"));
 
401
                        gdm_config_value_free (value);
 
402
                        value = NULL;
 
403
                } else {
 
404
                        gdm_config_value_set_locale_string (value, value_str);
 
405
                }
 
406
                break;
 
407
        case GDM_CONFIG_VALUE_STRING_ARRAY:
 
408
                if (! g_utf8_validate (value_str, -1, NULL)) {
 
409
                        g_set_error (error,
 
410
                                     GDM_CONFIG_ERROR,
 
411
                                     GDM_CONFIG_ERROR_PARSE_ERROR,
 
412
                                     _("Text contains invalid UTF-8"));
 
413
                        gdm_config_value_free (value);
 
414
                        value = NULL;
 
415
                } else {
 
416
                        char **split;
 
417
                        split = g_strsplit (value_str, ";", -1);
 
418
                        gdm_config_value_set_string_array (value, (const char **)split);
 
419
                        g_strfreev (split);
 
420
                }
 
421
                break;
 
422
        case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY:
 
423
                if (! g_utf8_validate (value_str, -1, NULL)) {
 
424
                        g_set_error (error,
 
425
                                     GDM_CONFIG_ERROR,
 
426
                                     GDM_CONFIG_ERROR_PARSE_ERROR,
 
427
                                     _("Text contains invalid UTF-8"));
 
428
                        gdm_config_value_free (value);
 
429
                        value = NULL;
 
430
                } else {
 
431
                        char **split;
 
432
                        split = g_strsplit (value_str, ";", -1);
 
433
                        gdm_config_value_set_locale_string_array (value, (const char **)split);
 
434
                        g_strfreev (split);
 
435
                }
 
436
                break;
 
437
        case GDM_CONFIG_VALUE_INVALID:
 
438
        default:
 
439
                g_assert_not_reached ();
 
440
                break;
 
441
        }
 
442
 
 
443
        return value;
 
444
}
 
445
 
 
446
void
 
447
gdm_config_value_set_string_array (GdmConfigValue *value,
 
448
                                   const char    **array)
 
449
{
 
450
        GdmConfigRealValue *real;
 
451
 
 
452
        g_return_if_fail (value != NULL);
 
453
        g_return_if_fail (value->type == GDM_CONFIG_VALUE_STRING_ARRAY);
 
454
 
 
455
        real = REAL_VALUE (value);
 
456
 
 
457
        g_strfreev (real->val.array);
 
458
        real->val.array = g_strdupv ((char **)array);
 
459
}
 
460
 
 
461
void
 
462
gdm_config_value_set_locale_string_array (GdmConfigValue *value,
 
463
                                          const char    **array)
 
464
{
 
465
        GdmConfigRealValue *real;
 
466
 
 
467
        g_return_if_fail (value != NULL);
 
468
        g_return_if_fail (value->type == GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY);
 
469
 
 
470
        real = REAL_VALUE (value);
 
471
 
 
472
        g_strfreev (real->val.array);
 
473
        real->val.array = g_strdupv ((char **)array);
 
474
}
 
475
 
 
476
void
 
477
gdm_config_value_set_int (GdmConfigValue *value,
 
478
                          int             integer)
 
479
{
 
480
        GdmConfigRealValue *real;
 
481
 
 
482
        g_return_if_fail (value != NULL);
 
483
        g_return_if_fail (value->type == GDM_CONFIG_VALUE_INT);
 
484
 
 
485
        real = REAL_VALUE (value);
 
486
 
 
487
        real->val.integer = integer;
 
488
}
 
489
 
 
490
void
 
491
gdm_config_value_set_bool (GdmConfigValue *value,
 
492
                           gboolean        bool)
 
493
{
 
494
        GdmConfigRealValue *real;
 
495
 
 
496
        g_return_if_fail (value != NULL);
 
497
        g_return_if_fail (value->type == GDM_CONFIG_VALUE_BOOL);
 
498
 
 
499
        real = REAL_VALUE (value);
 
500
 
 
501
        real->val.bool = bool;
 
502
}
 
503
 
 
504
void
 
505
gdm_config_value_set_string (GdmConfigValue *value,
 
506
                             const char     *str)
 
507
{
 
508
        GdmConfigRealValue *real;
 
509
 
 
510
        g_return_if_fail (value != NULL);
 
511
        g_return_if_fail (value->type == GDM_CONFIG_VALUE_STRING);
 
512
 
 
513
        real = REAL_VALUE (value);
 
514
 
 
515
        g_free (real->val.str);
 
516
        real->val.str = g_strdup (str);
 
517
}
 
518
 
 
519
void
 
520
gdm_config_value_set_locale_string (GdmConfigValue *value,
 
521
                                    const char     *str)
 
522
{
 
523
        GdmConfigRealValue *real;
 
524
 
 
525
        g_return_if_fail (value != NULL);
 
526
        g_return_if_fail (value->type == GDM_CONFIG_VALUE_LOCALE_STRING);
 
527
 
 
528
        real = REAL_VALUE (value);
 
529
 
 
530
        g_free (real->val.str);
 
531
        real->val.str = g_strdup (str);
 
532
}
 
533
 
 
534
char *
 
535
gdm_config_value_to_string (const GdmConfigValue *value)
 
536
{
 
537
        GdmConfigRealValue *real;
 
538
        char               *ret;
 
539
 
 
540
        g_return_val_if_fail (value != NULL, NULL);
 
541
 
 
542
        ret = NULL;
 
543
        real = REAL_VALUE (value);
 
544
 
 
545
        switch (real->type) {
 
546
        case GDM_CONFIG_VALUE_INVALID:
 
547
                break;
 
548
        case GDM_CONFIG_VALUE_BOOL:
 
549
                ret = real->val.bool ? g_strdup ("true") : g_strdup ("false");
 
550
                break;
 
551
        case GDM_CONFIG_VALUE_INT:
 
552
                ret = g_strdup_printf ("%d", real->val.integer);
 
553
                break;
 
554
        case GDM_CONFIG_VALUE_STRING:
 
555
        case GDM_CONFIG_VALUE_LOCALE_STRING:
 
556
                ret = g_strdup (real->val.str);
 
557
                break;
 
558
        case GDM_CONFIG_VALUE_STRING_ARRAY:
 
559
        case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY:
 
560
                ret = g_strjoinv (";", real->val.array);
 
561
                break;
 
562
        default:
 
563
                g_assert_not_reached ();
 
564
                break;
 
565
        }
 
566
        return ret;
 
567
}
 
568
 
 
569
static void
 
570
gdm_config_init (GdmConfig *config)
 
571
{
 
572
        config->entries = g_ptr_array_new ();
 
573
        config->value_hash = g_hash_table_new_full (g_str_hash,
 
574
                                                    g_str_equal,
 
575
                                                    (GDestroyNotify)g_free,
 
576
                                                    (GDestroyNotify)gdm_config_value_free);
 
577
}
 
578
 
 
579
GdmConfig *
 
580
gdm_config_new (void)
 
581
{
 
582
        GdmConfig *config;
 
583
 
 
584
        config = g_slice_new0 (GdmConfig);
 
585
        gdm_config_init (config);
 
586
 
 
587
        return config;
 
588
}
 
589
 
 
590
/*
 
591
 * Note that this function can be called a second time while 
 
592
 * GDM is in the middle of processing this function.  This is
 
593
 * because some GDM signal handlers (such as main_daemon_abrt)
 
594
 * call gdm_final_cleanup, which ends up calling this function.
 
595
 * To fix the sort of crashing problem reported in bugzilla bug
 
596
 * #517526.  This function could probably be made more thread
 
597
 * safe.
 
598
 */
 
599
void
 
600
gdm_config_free (GdmConfig *config)
 
601
{
 
602
        GdmConfigEntry *e;
 
603
        GKeyFile       *mkf, *dkf, *ckf;
 
604
        GHashTable     *hash;
 
605
 
 
606
        g_return_if_fail (config != NULL);
 
607
 
 
608
        /*
 
609
         * Set local variables equal to the memory that we
 
610
         * intend to free, and set the structure variables
 
611
         * to NULL, so if this function is called again, we
 
612
         * do not try to free the same data structures again.
 
613
         */
 
614
        e    = config->entries;
 
615
        mkf  = config->mandatory_key_file;
 
616
        dkf  = config->default_key_file;
 
617
        ckf  = config->custom_key_file;
 
618
        hash = config->value_hash;
 
619
 
 
620
        config->entries            = NULL;
 
621
        config->mandatory_key_file = NULL;
 
622
        config->default_key_file   = NULL;
 
623
        config->custom_key_file    = NULL;
 
624
        config->value_hash         = NULL;
 
625
 
 
626
        g_free (config->mandatory_filename);
 
627
        g_free (config->default_filename);
 
628
        g_free (config->custom_filename);
 
629
 
 
630
        g_slice_free (GdmConfig, config);
 
631
 
 
632
        if (e != NULL) {
 
633
                g_ptr_array_foreach (e, (GFunc)gdm_config_entry_free, NULL);
 
634
                g_ptr_array_free (e, TRUE);
 
635
        }
 
636
        if (mkf != NULL)
 
637
                g_key_file_free (mkf);
 
638
        if (dkf != NULL)
 
639
                g_key_file_free (dkf);
 
640
        if (ckf != NULL)
 
641
                g_key_file_free (ckf);
 
642
        if (hash != NULL)
 
643
                g_hash_table_destroy (hash);
 
644
}
 
645
 
 
646
static void
 
647
add_server_group_once (GPtrArray *server_groups, char *group)
 
648
{
 
649
        int i;
 
650
 
 
651
        for (i=0; i < server_groups->len; i++) {
 
652
                if (strcmp (g_ptr_array_index (server_groups, i), group) == 0) {
 
653
                        g_debug ("server group %s already exists, skipping",
 
654
                                group);
 
655
                        return;
 
656
                }
 
657
        }
 
658
        g_ptr_array_add (server_groups, g_strdup (group));
 
659
}
 
660
 
 
661
GPtrArray *
 
662
gdm_config_get_server_groups (GdmConfig *config)
 
663
{
 
664
        GPtrArray       *server_groups;
 
665
        GError          *error;
 
666
        char           **groups;
 
667
        gsize            len;
 
668
        int              i;
 
669
        
 
670
        server_groups = g_ptr_array_new ();
 
671
 
 
672
        if (config->mandatory_key_file != NULL) {
 
673
                groups = g_key_file_get_groups (config->mandatory_key_file, &len);
 
674
 
 
675
                for (i = 0; i < len; i++)
 
676
                {
 
677
                        if (g_str_has_prefix (groups[i], "server-")) {
 
678
                                add_server_group_once (server_groups, groups[i]);
 
679
                        }
 
680
                }
 
681
                g_strfreev (groups);
 
682
        }
 
683
 
 
684
        if (config->default_key_file != NULL) {
 
685
                groups = g_key_file_get_groups (config->default_key_file, &len);
 
686
 
 
687
                for (i = 0; i < len; i++)
 
688
                {
 
689
                        if (g_str_has_prefix (groups[i], "server-")) {
 
690
                                add_server_group_once (server_groups, groups[i]);
 
691
                        }
 
692
                }
 
693
                g_strfreev (groups);
 
694
        }
 
695
 
 
696
        if (config->custom_key_file != NULL) {
 
697
                groups = g_key_file_get_groups (config->custom_key_file, &len);
 
698
 
 
699
                for (i = 0; i < len; i++)
 
700
                {
 
701
                        if (g_str_has_prefix (groups[i], "server-")) {
 
702
                                add_server_group_once (server_groups, groups[i]);
 
703
                        }
 
704
                }
 
705
                g_strfreev (groups);
 
706
        }
 
707
 
 
708
        return server_groups;
 
709
}
 
710
 
 
711
const GdmConfigEntry *
 
712
gdm_config_lookup_entry (GdmConfig  *config,
 
713
                         const char *group,
 
714
                         const char *key)
 
715
{
 
716
        int                   i;
 
717
        const GdmConfigEntry *entry;
 
718
 
 
719
        g_return_val_if_fail (config != NULL, NULL);
 
720
        g_return_val_if_fail (group != NULL, NULL);
 
721
        g_return_val_if_fail (key != NULL, NULL);
 
722
 
 
723
        entry = NULL;
 
724
 
 
725
        for (i = 0; i < config->entries->len; i++) {
 
726
                GdmConfigEntry *this;
 
727
                this = g_ptr_array_index (config->entries, i);
 
728
                if (strcmp (this->group, group) == 0
 
729
                    && strcmp (this->key, key) == 0) {
 
730
                        entry = (const GdmConfigEntry *)this;
 
731
                        break;
 
732
                }
 
733
        }
 
734
 
 
735
        return entry;
 
736
}
 
737
 
 
738
const GdmConfigEntry *
 
739
gdm_config_lookup_entry_for_id (GdmConfig  *config,
 
740
                                int         id)
 
741
{
 
742
        int                   i;
 
743
        const GdmConfigEntry *entry;
 
744
 
 
745
        g_return_val_if_fail (config != NULL, NULL);
 
746
 
 
747
        entry = NULL;
 
748
 
 
749
        for (i = 0; i < config->entries->len; i++) {
 
750
                GdmConfigEntry *this;
 
751
                this = g_ptr_array_index (config->entries, i);
 
752
                if (this->id == id) {
 
753
                        entry = (const GdmConfigEntry *)this;
 
754
                        break;
 
755
                }
 
756
        }
 
757
 
 
758
        return entry;
 
759
}
 
760
 
 
761
void
 
762
gdm_config_add_entry (GdmConfig            *config,
 
763
                      const GdmConfigEntry *entry)
 
764
{
 
765
        GdmConfigEntry *new_entry;
 
766
 
 
767
        g_return_if_fail (config != NULL);
 
768
        g_return_if_fail (entry != NULL);
 
769
 
 
770
        new_entry = gdm_config_entry_copy (entry);
 
771
        g_ptr_array_add (config->entries, new_entry);
 
772
}
 
773
 
 
774
void
 
775
gdm_config_add_static_entries (GdmConfig            *config,
 
776
                               const GdmConfigEntry *entries)
 
777
{
 
778
        int i;
 
779
 
 
780
        g_return_if_fail (config != NULL);
 
781
        g_return_if_fail (entries != NULL);
 
782
 
 
783
        for (i = 0; entries[i].group != NULL; i++) {
 
784
                gdm_config_add_entry (config, &entries[i]);
 
785
        }
 
786
}
 
787
 
 
788
void
 
789
gdm_config_set_validate_func (GdmConfig       *config,
 
790
                              GdmConfigFunc    func,
 
791
                              gpointer         data)
 
792
{
 
793
        g_return_if_fail (config != NULL);
 
794
 
 
795
        config->validate_func = func;
 
796
        config->validate_func_data = data;
 
797
}
 
798
 
 
799
void
 
800
gdm_config_set_mandatory_file (GdmConfig  *config,
 
801
                               const char *name)
 
802
{
 
803
        g_return_if_fail (config != NULL);
 
804
 
 
805
        g_free (config->mandatory_filename);
 
806
        config->mandatory_filename = g_strdup (name);
 
807
}
 
808
 
 
809
void
 
810
gdm_config_set_default_file (GdmConfig  *config,
 
811
                             const char *name)
 
812
{
 
813
        g_return_if_fail (config != NULL);
 
814
 
 
815
        g_free (config->default_filename);
 
816
        config->default_filename = g_strdup (name);
 
817
}
 
818
 
 
819
void
 
820
gdm_config_set_custom_file (GdmConfig  *config,
 
821
                            const char *name)
 
822
{
 
823
        g_return_if_fail (config != NULL);
 
824
 
 
825
        g_free (config->custom_filename);
 
826
        config->custom_filename = g_strdup (name);
 
827
}
 
828
 
 
829
void
 
830
gdm_config_set_notify_func (GdmConfig       *config,
 
831
                            GdmConfigFunc    func,
 
832
                            gpointer         data)
 
833
{
 
834
        g_return_if_fail (config != NULL);
 
835
 
 
836
        config->notify_func = func;
 
837
        config->notify_func_data = data;
 
838
}
 
839
 
 
840
static gboolean
 
841
key_file_get_value (GdmConfig            *config,
 
842
                    GKeyFile             *key_file,
 
843
                    const char           *group,
 
844
                    const char           *key,
 
845
                    GdmConfigValueType    type,
 
846
                    GdmConfigValue      **valuep)
 
847
{
 
848
        char           *val;
 
849
        GError         *error;
 
850
        GdmConfigValue *value;
 
851
        gboolean        ret;
 
852
 
 
853
        ret = FALSE;
 
854
        value = NULL;
 
855
 
 
856
        error = NULL;
 
857
        if (type == GDM_CONFIG_VALUE_LOCALE_STRING ||
 
858
            type == GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY) {
 
859
                /* Use NULL locale to detect current locale */
 
860
                val = g_key_file_get_locale_string (key_file,
 
861
                                                    group,
 
862
                                                    key,
 
863
                                                    NULL,
 
864
                                                    &error);
 
865
                g_debug ("Loading locale string: %s %s", key, val ? val : "(null)");
 
866
 
 
867
                if (error != NULL) {
 
868
                        g_debug ("%s", error->message);
 
869
                        g_error_free (error);
 
870
                }
 
871
                if (val == NULL) {
 
872
                        error = NULL;
 
873
                        val = g_key_file_get_value (key_file,
 
874
                                                    group,
 
875
                                                    key,
 
876
                                                    &error);
 
877
                        g_debug ("Loading non-locale string: %s %s", key, val ? val : "(null)");
 
878
                }
 
879
        } else {
 
880
                val = g_key_file_get_value (key_file,
 
881
                                            group,
 
882
                                            key,
 
883
                                            &error);
 
884
        }
 
885
 
 
886
        if (error != NULL) {
 
887
                g_error_free (error);
 
888
                goto out;
 
889
        }
 
890
 
 
891
        if (val == NULL) {
 
892
                goto out;
 
893
        }
 
894
 
 
895
        error = NULL;
 
896
        value = gdm_config_value_new_from_string (type, val, &error);
 
897
        if (error != NULL) {
 
898
                g_warning ("%s", error->message);
 
899
                g_error_free (error);
 
900
                goto out;
 
901
        }
 
902
 
 
903
        ret = TRUE;
 
904
 
 
905
 out:
 
906
        *valuep = value;
 
907
 
 
908
        g_free (val);
 
909
 
 
910
        return ret;
 
911
}
 
912
 
 
913
static void
 
914
entry_get_default_value (GdmConfig            *config,
 
915
                         const GdmConfigEntry *entry,
 
916
                         GdmConfigValue      **valuep)
 
917
{
 
918
        GdmConfigValue *value;
 
919
        GError         *error;
 
920
 
 
921
        error = NULL;
 
922
        value = gdm_config_value_new_from_string (entry->type,
 
923
                                                  entry->default_value ? entry->default_value : "",
 
924
                                                  &error);
 
925
        if (error != NULL) {
 
926
                g_warning ("%s", error->message);
 
927
                g_error_free (error);
 
928
        }
 
929
 
 
930
        *valuep = value;
 
931
}
 
932
 
 
933
static gboolean
 
934
load_value_entry (GdmConfig            *config,
 
935
                  const GdmConfigEntry *entry,
 
936
                  GdmConfigValue      **valuep,
 
937
                  GdmConfigSourceType  *sourcep)
 
938
{
 
939
        GdmConfigValue     *value;
 
940
        GdmConfigSourceType source;
 
941
        gboolean            ret;
 
942
        gboolean            res;
 
943
 
 
944
        value = NULL;
 
945
 
 
946
        /* Look for the first occurence of the key in:
 
947
           mandatory file, custom file, default file, or built-in-default
 
948
         */
 
949
 
 
950
        if (config->mandatory_filename != NULL) {
 
951
                source = GDM_CONFIG_SOURCE_MANDATORY;
 
952
                res = key_file_get_value (config,
 
953
                                          config->mandatory_key_file,
 
954
                                          entry->group,
 
955
                                          entry->key,
 
956
                                          entry->type,
 
957
                                          &value);
 
958
                if (res) {
 
959
                        goto done;
 
960
                }
 
961
        }
 
962
        if (config->custom_filename != NULL) {
 
963
                source = GDM_CONFIG_SOURCE_CUSTOM;
 
964
                res = key_file_get_value (config,
 
965
                                          config->custom_key_file,
 
966
                                          entry->group,
 
967
                                          entry->key,
 
968
                                          entry->type,
 
969
                                          &value);
 
970
                if (res) {
 
971
                        goto done;
 
972
                }
 
973
        }
 
974
        if (config->default_filename != NULL) {
 
975
                source = GDM_CONFIG_SOURCE_DEFAULT;
 
976
                res = key_file_get_value (config,
 
977
                                          config->default_key_file,
 
978
                                          entry->group,
 
979
                                          entry->key,
 
980
                                          entry->type,
 
981
                                          &value);
 
982
                if (res) {
 
983
                        goto done;
 
984
                }
 
985
        }
 
986
 
 
987
 
 
988
        source = GDM_CONFIG_SOURCE_BUILT_IN;
 
989
        entry_get_default_value (config, entry, &value);
 
990
 
 
991
 done:
 
992
 
 
993
        if (value != NULL) {
 
994
                ret = TRUE;
 
995
        } else {
 
996
                ret = FALSE;
 
997
        }
 
998
 
 
999
        *valuep = value;
 
1000
        *sourcep = source;
 
1001
 
 
1002
        return ret;
 
1003
}
 
1004
 
 
1005
static int
 
1006
lookup_id_for_key (GdmConfig  *config,
 
1007
                   const char *group,
 
1008
                   const char *key)
 
1009
{
 
1010
        int                   id;
 
1011
        const GdmConfigEntry *entry;
 
1012
 
 
1013
        id = GDM_CONFIG_INVALID_ID;
 
1014
        entry = gdm_config_lookup_entry (config, group, key);
 
1015
        if (entry != NULL) {
 
1016
                id = entry->id;
 
1017
        }
 
1018
 
 
1019
        return id;
 
1020
}
 
1021
 
 
1022
static void
 
1023
internal_set_value (GdmConfig          *config,
 
1024
                    GdmConfigSourceType source,
 
1025
                    const char         *group,
 
1026
                    const char         *key,
 
1027
                    GdmConfigValue     *value)
 
1028
{
 
1029
        char           *key_path;
 
1030
        int             id;
 
1031
        GdmConfigValue *v;
 
1032
        gboolean        res;
 
1033
 
 
1034
        g_return_if_fail (config != NULL);
 
1035
 
 
1036
        key_path = g_strdup_printf ("%s/%s", group, key);
 
1037
 
 
1038
        v = NULL;
 
1039
        res = g_hash_table_lookup_extended (config->value_hash,
 
1040
                                            key_path,
 
1041
                                            NULL,
 
1042
                                            (gpointer *)&v);
 
1043
 
 
1044
        if (res) {
 
1045
                if (v != NULL && gdm_config_value_compare (v, value) == 0) {
 
1046
                        /* value is the same - don't update */
 
1047
                        goto out;
 
1048
                }
 
1049
        }
 
1050
 
 
1051
        g_hash_table_insert (config->value_hash,
 
1052
                             g_strdup (key_path),
 
1053
                             gdm_config_value_copy (value));
 
1054
 
 
1055
        id = lookup_id_for_key (config, group, key);
 
1056
 
 
1057
        if (config->notify_func) {
 
1058
                (* config->notify_func) (config, source, group, key, value, id, config->notify_func_data);
 
1059
        }
 
1060
 out:
 
1061
        g_free (key_path);
 
1062
}
 
1063
 
 
1064
static void
 
1065
store_entry_value (GdmConfig            *config,
 
1066
                   const GdmConfigEntry *entry,
 
1067
                   GdmConfigSourceType   source,
 
1068
                   GdmConfigValue       *value)
 
1069
{
 
1070
        internal_set_value (config, source, entry->group, entry->key, value);
 
1071
}
 
1072
 
 
1073
static gboolean
 
1074
load_entry (GdmConfig            *config,
 
1075
            const GdmConfigEntry *entry)
 
1076
{
 
1077
        GdmConfigValue     *value;
 
1078
        GdmConfigSourceType source;
 
1079
        gboolean            res;
 
1080
 
 
1081
        value = NULL;
 
1082
        source = GDM_CONFIG_SOURCE_INVALID;
 
1083
 
 
1084
        res = load_value_entry (config, entry, &value, &source);
 
1085
        if (!res) {
 
1086
                return FALSE;
 
1087
        }
 
1088
 
 
1089
        res = TRUE;
 
1090
        if (config->validate_func) {
 
1091
                res = (* config->validate_func) (config, source, entry->group, entry->key, value, entry->id, config->validate_func_data);
 
1092
        }
 
1093
 
 
1094
        if (res) {
 
1095
                /* store runs notify */
 
1096
                store_entry_value (config, entry, source, value);
 
1097
        }
 
1098
 
 
1099
        return TRUE;
 
1100
}
 
1101
 
 
1102
static void
 
1103
add_keys_to_hash (GKeyFile   *key_file,
 
1104
                  const char *group_name,
 
1105
                  GHashTable *hash)
 
1106
{
 
1107
        GError     *local_error;
 
1108
        gchar      **keys;
 
1109
        gsize       len;
 
1110
        int         i;
 
1111
 
 
1112
        local_error = NULL;
 
1113
        len = 0;
 
1114
        keys = g_key_file_get_keys (key_file,
 
1115
                                    group_name,
 
1116
                                    &len,
 
1117
                                    &local_error);
 
1118
        if (local_error != NULL) {
 
1119
                g_error_free (local_error);
 
1120
                g_strfreev (keys);
 
1121
                return;
 
1122
        }
 
1123
 
 
1124
        for (i = 0; i < len; i++) {
 
1125
                g_hash_table_insert (hash, g_strdup (keys[i]), GINT_TO_POINTER (1));
 
1126
        }
 
1127
 
 
1128
        g_strfreev (keys);
 
1129
}
 
1130
 
 
1131
static void
 
1132
collect_hash_keys (const char *key,
 
1133
                   gpointer    value,
 
1134
                   GPtrArray **array)
 
1135
{
 
1136
        g_message ("Adding %s", key);
 
1137
        g_ptr_array_add (*array, g_strdup (key));
 
1138
}
 
1139
 
 
1140
char **
 
1141
gdm_config_get_keys_for_group (GdmConfig  *config,
 
1142
                               const char *group,
 
1143
                               gsize      *length,
 
1144
                               GError    **error)
 
1145
{
 
1146
        GHashTable *hash;
 
1147
        gsize       len;
 
1148
        GPtrArray  *array;
 
1149
 
 
1150
        hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 
1151
 
 
1152
        if (config->mandatory_filename != NULL) {
 
1153
                add_keys_to_hash (config->mandatory_key_file, group, hash);
 
1154
        }
 
1155
 
 
1156
        if (config->default_filename != NULL) {
 
1157
                add_keys_to_hash (config->default_key_file, group, hash);
 
1158
        }
 
1159
 
 
1160
        if (config->custom_filename != NULL) {
 
1161
                add_keys_to_hash (config->custom_key_file, group, hash);
 
1162
        }
 
1163
 
 
1164
        len = g_hash_table_size (hash);
 
1165
        array = g_ptr_array_sized_new (len);
 
1166
 
 
1167
        g_hash_table_foreach (hash, (GHFunc)collect_hash_keys, &array);
 
1168
        g_ptr_array_add (array, NULL);
 
1169
 
 
1170
        g_hash_table_destroy (hash);
 
1171
 
 
1172
        if (length != NULL) {
 
1173
                *length = array->len - 1;
 
1174
        }
 
1175
 
 
1176
        return (char **)g_ptr_array_free (array, FALSE);
 
1177
}
 
1178
 
 
1179
static gboolean
 
1180
load_backend (GdmConfig  *config,
 
1181
              const char *filename,
 
1182
              GKeyFile  **key_file,
 
1183
              time_t     *mtime)
 
1184
{
 
1185
        GError     *local_error;
 
1186
        gboolean    res;
 
1187
        gboolean    ret;
 
1188
        struct stat statbuf;
 
1189
        GKeyFile   *kf;
 
1190
        time_t      lmtime;
 
1191
 
 
1192
        if (filename == NULL) {
 
1193
                return FALSE;
 
1194
        }
 
1195
 
 
1196
        if (g_stat (filename, &statbuf) != 0) {
 
1197
                return FALSE;
 
1198
        }
 
1199
        lmtime = statbuf.st_mtime;
 
1200
 
 
1201
        /* if already loaded check whether reload is necessary */
 
1202
        if (*key_file != NULL) {
 
1203
                if (lmtime > *mtime) {
 
1204
 
 
1205
                        /* needs an update */
 
1206
 
 
1207
                        /*
 
1208
                         * As in gdm-config-free, set a local
 
1209
                         * variable equal to the memory to 
 
1210
                         * free, and set the structure to 
 
1211
                         * NULL, so if this function is 
 
1212
                         * called again, we do not free the
 
1213
                         * same data stucture again.  Similar
 
1214
                         * to bug #517526.  Again, this could
 
1215
                         * probably be made more thread safe.
 
1216
                         */
 
1217
                        kf = *key_file;
 
1218
                        *key_file = NULL;
 
1219
                        g_key_file_free (kf);
 
1220
                } else {
 
1221
                        /* no reload necessary so we're done */
 
1222
                        return TRUE;
 
1223
                }
 
1224
        }
 
1225
 
 
1226
        kf = g_key_file_new ();
 
1227
 
 
1228
        local_error = NULL;
 
1229
        res = g_key_file_load_from_file (kf,
 
1230
                                         filename,
 
1231
                                         G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
 
1232
                                         &local_error);
 
1233
        if (! res) {
 
1234
                g_error_free (local_error);
 
1235
                g_key_file_free (kf);
 
1236
                kf = NULL;
 
1237
                lmtime = 0;
 
1238
                ret = FALSE;
 
1239
        } else {
 
1240
                ret = TRUE;
 
1241
        }
 
1242
 
 
1243
        *key_file = kf;
 
1244
        *mtime = lmtime;
 
1245
 
 
1246
        return ret;
 
1247
}
 
1248
 
 
1249
gboolean
 
1250
gdm_config_load (GdmConfig *config,
 
1251
                 GError   **error)
 
1252
{
 
1253
        g_return_val_if_fail (config != NULL, FALSE);
 
1254
 
 
1255
        config->mandatory_loaded = load_backend (config,
 
1256
                                                 config->mandatory_filename,
 
1257
                                                 &config->mandatory_key_file,
 
1258
                                                 &config->mandatory_mtime);
 
1259
        config->default_loaded = load_backend (config,
 
1260
                                               config->default_filename,
 
1261
                                               &config->default_key_file,
 
1262
                                               &config->default_mtime);
 
1263
        config->custom_loaded = load_backend (config,
 
1264
                                              config->custom_filename,
 
1265
                                              &config->custom_key_file,
 
1266
                                              &config->custom_mtime);
 
1267
 
 
1268
        return TRUE;
 
1269
}
 
1270
 
 
1271
static gboolean
 
1272
process_entries (GdmConfig             *config,
 
1273
                 const GdmConfigEntry **entries,
 
1274
                 gsize                  n_entries,
 
1275
                 GError               **error)
 
1276
{
 
1277
        gboolean ret;
 
1278
        int      i;
 
1279
 
 
1280
        ret = TRUE;
 
1281
 
 
1282
        for (i = 0; i < n_entries; i++) {
 
1283
                load_entry (config, entries[i]);
 
1284
        }
 
1285
 
 
1286
        return ret;
 
1287
}
 
1288
 
 
1289
gboolean
 
1290
gdm_config_process_entry (GdmConfig            *config,
 
1291
                          const GdmConfigEntry *entry,
 
1292
                          GError              **error)
 
1293
{
 
1294
        gboolean  ret;
 
1295
 
 
1296
        g_return_val_if_fail (config != NULL, FALSE);
 
1297
        g_return_val_if_fail (entry != NULL, FALSE);
 
1298
 
 
1299
        ret = load_entry (config, entry);
 
1300
 
 
1301
        return ret;
 
1302
}
 
1303
 
 
1304
gboolean
 
1305
gdm_config_process_entries (GdmConfig             *config,
 
1306
                            const GdmConfigEntry **entries,
 
1307
                            gsize                  n_entries,
 
1308
                            GError               **error)
 
1309
{
 
1310
        gboolean  ret;
 
1311
 
 
1312
        g_return_val_if_fail (config != NULL, FALSE);
 
1313
        g_return_val_if_fail (entries != NULL, FALSE);
 
1314
        g_return_val_if_fail (n_entries > 0, FALSE);
 
1315
 
 
1316
        ret = process_entries (config, entries, n_entries, error);
 
1317
 
 
1318
        return ret;
 
1319
}
 
1320
 
 
1321
gboolean
 
1322
gdm_config_process_all (GdmConfig *config,
 
1323
                        GError   **error)
 
1324
{
 
1325
        gboolean  ret;
 
1326
 
 
1327
        g_return_val_if_fail (config != NULL, FALSE);
 
1328
 
 
1329
        ret = process_entries (config,
 
1330
                               (const GdmConfigEntry **)config->entries->pdata,
 
1331
                               config->entries->len,
 
1332
                               error);
 
1333
 
 
1334
        return ret;
 
1335
}
 
1336
 
 
1337
gboolean
 
1338
gdm_config_peek_value (GdmConfig             *config,
 
1339
                       const char            *group,
 
1340
                       const char            *key,
 
1341
                       const GdmConfigValue **valuep)
 
1342
{
 
1343
        gboolean              ret;
 
1344
        char                 *key_path;
 
1345
        const GdmConfigValue *value;
 
1346
 
 
1347
        g_return_val_if_fail (config != NULL, FALSE);
 
1348
 
 
1349
        key_path = g_strdup_printf ("%s/%s", group, key);
 
1350
        value = NULL;
 
1351
        ret = g_hash_table_lookup_extended (config->value_hash,
 
1352
                                            key_path,
 
1353
                                            NULL,
 
1354
                                            (gpointer *)&value);
 
1355
        g_free (key_path);
 
1356
 
 
1357
        if (valuep != NULL) {
 
1358
                if (ret) {
 
1359
                        *valuep = value;
 
1360
                } else {
 
1361
                        *valuep = NULL;
 
1362
                }
 
1363
        }
 
1364
 
 
1365
        return ret;
 
1366
}
 
1367
 
 
1368
gboolean
 
1369
gdm_config_get_value (GdmConfig       *config,
 
1370
                      const char      *group,
 
1371
                      const char      *key,
 
1372
                      GdmConfigValue **valuep)
 
1373
{
 
1374
        gboolean              res;
 
1375
        const GdmConfigValue *value;
 
1376
 
 
1377
        res = gdm_config_peek_value (config, group, key, &value);
 
1378
        if (valuep != NULL) {
 
1379
                *valuep = (value == NULL) ? NULL : gdm_config_value_copy (value);
 
1380
        }
 
1381
 
 
1382
        return res;
 
1383
}
 
1384
 
 
1385
gboolean
 
1386
gdm_config_set_value (GdmConfig       *config,
 
1387
                      const char      *group,
 
1388
                      const char      *key,
 
1389
                      GdmConfigValue  *value)
 
1390
{
 
1391
        g_return_val_if_fail (config != NULL, FALSE);
 
1392
        g_return_val_if_fail (group != NULL, FALSE);
 
1393
        g_return_val_if_fail (key != NULL, FALSE);
 
1394
        g_return_val_if_fail (value != NULL, FALSE);
 
1395
 
 
1396
        internal_set_value (config, GDM_CONFIG_SOURCE_RUNTIME_USER, group, key, value);
 
1397
 
 
1398
        return TRUE;
 
1399
}
 
1400
 
 
1401
static gboolean
 
1402
gdm_config_peek_value_for_id (GdmConfig             *config,
 
1403
                              int                    id,
 
1404
                              const GdmConfigValue **valuep)
 
1405
{
 
1406
        const GdmConfigEntry *entry;
 
1407
 
 
1408
        g_return_val_if_fail (config != NULL, FALSE);
 
1409
 
 
1410
        entry = gdm_config_lookup_entry_for_id (config, id);
 
1411
        if (entry == NULL) {
 
1412
                return FALSE;
 
1413
        }
 
1414
 
 
1415
        return gdm_config_peek_value (config, entry->group, entry->key, valuep);
 
1416
}
 
1417
 
 
1418
gboolean
 
1419
gdm_config_get_value_for_id (GdmConfig       *config,
 
1420
                             int              id,
 
1421
                             GdmConfigValue **valuep)
 
1422
{
 
1423
        const GdmConfigEntry *entry;
 
1424
 
 
1425
        g_return_val_if_fail (config != NULL, FALSE);
 
1426
 
 
1427
        entry = gdm_config_lookup_entry_for_id (config, id);
 
1428
        if (entry == NULL) {
 
1429
                return FALSE;
 
1430
        }
 
1431
 
 
1432
        return gdm_config_get_value (config, entry->group, entry->key, valuep);
 
1433
}
 
1434
 
 
1435
gboolean
 
1436
gdm_config_set_value_for_id (GdmConfig      *config,
 
1437
                             int             id,
 
1438
                             GdmConfigValue *valuep)
 
1439
{
 
1440
        const GdmConfigEntry *entry;
 
1441
 
 
1442
        g_return_val_if_fail (config != NULL, FALSE);
 
1443
 
 
1444
        entry = gdm_config_lookup_entry_for_id (config, id);
 
1445
        if (entry == NULL) {
 
1446
                return FALSE;
 
1447
        }
 
1448
 
 
1449
        return gdm_config_set_value (config, entry->group, entry->key, valuep);
 
1450
}
 
1451
 
 
1452
gboolean
 
1453
gdm_config_peek_string_for_id (GdmConfig       *config,
 
1454
                               int              id,
 
1455
                               const char     **strp)
 
1456
{
 
1457
        const GdmConfigValue *value;
 
1458
        const char           *str;
 
1459
        gboolean              res;
 
1460
 
 
1461
        g_return_val_if_fail (config != NULL, FALSE);
 
1462
 
 
1463
        res = gdm_config_peek_value_for_id (config, id, &value);
 
1464
        if (! res) {
 
1465
                return FALSE;
 
1466
        }
 
1467
 
 
1468
        str = gdm_config_value_get_string (value);
 
1469
        if (strp != NULL) {
 
1470
                *strp = str;
 
1471
        }
 
1472
 
 
1473
        return res;
 
1474
}
 
1475
 
 
1476
gboolean
 
1477
gdm_config_get_string_for_id (GdmConfig       *config,
 
1478
                              int              id,
 
1479
                              char           **strp)
 
1480
{
 
1481
        gboolean    res;
 
1482
        const char *str;
 
1483
 
 
1484
        res = gdm_config_peek_string_for_id (config, id, &str);
 
1485
        if (strp != NULL) {
 
1486
                *strp = g_strdup (str);
 
1487
        }
 
1488
 
 
1489
        return res;
 
1490
}
 
1491
 
 
1492
gboolean
 
1493
gdm_config_get_bool_for_id (GdmConfig       *config,
 
1494
                            int              id,
 
1495
                            gboolean        *boolp)
 
1496
{
 
1497
        GdmConfigValue *value;
 
1498
        gboolean        bool;
 
1499
        gboolean        res;
 
1500
 
 
1501
        g_return_val_if_fail (config != NULL, FALSE);
 
1502
 
 
1503
        res = gdm_config_get_value_for_id (config, id, &value);
 
1504
        if (! res) {
 
1505
                return FALSE;
 
1506
        }
 
1507
 
 
1508
        bool = gdm_config_value_get_bool (value);
 
1509
        if (boolp != NULL) {
 
1510
                *boolp = bool;
 
1511
        }
 
1512
 
 
1513
        gdm_config_value_free (value);
 
1514
 
 
1515
        return res;
 
1516
}
 
1517
 
 
1518
gboolean
 
1519
gdm_config_get_int_for_id (GdmConfig       *config,
 
1520
                           int              id,
 
1521
                           int             *integerp)
 
1522
{
 
1523
        GdmConfigValue *value;
 
1524
        gboolean        integer;
 
1525
        gboolean        res;
 
1526
 
 
1527
        g_return_val_if_fail (config != NULL, FALSE);
 
1528
 
 
1529
        res = gdm_config_get_value_for_id (config, id, &value);
 
1530
        if (! res) {
 
1531
                return FALSE;
 
1532
        }
 
1533
 
 
1534
        integer = gdm_config_value_get_int (value);
 
1535
        if (integerp != NULL) {
 
1536
                *integerp = integer;
 
1537
        }
 
1538
 
 
1539
        gdm_config_value_free (value);
 
1540
 
 
1541
        return res;
 
1542
}
 
1543
 
 
1544
gboolean
 
1545
gdm_config_set_string_for_id (GdmConfig      *config,
 
1546
                              int             id,
 
1547
                              char           *str)
 
1548
{
 
1549
        GdmConfigValue *value;
 
1550
        gboolean        res;
 
1551
 
 
1552
        g_return_val_if_fail (config != NULL, FALSE);
 
1553
 
 
1554
        value = gdm_config_value_new (GDM_CONFIG_VALUE_STRING);
 
1555
        gdm_config_value_set_string (value, str);
 
1556
 
 
1557
        res = gdm_config_set_value_for_id (config, id, value);
 
1558
        gdm_config_value_free (value);
 
1559
 
 
1560
        return res;
 
1561
}
 
1562
 
 
1563
gboolean
 
1564
gdm_config_set_bool_for_id (GdmConfig      *config,
 
1565
                            int             id,
 
1566
                            gboolean        bool)
 
1567
{
 
1568
        GdmConfigValue *value;
 
1569
        gboolean        res;
 
1570
 
 
1571
        g_return_val_if_fail (config != NULL, FALSE);
 
1572
 
 
1573
        value = gdm_config_value_new (GDM_CONFIG_VALUE_BOOL);
 
1574
        gdm_config_value_set_bool (value, bool);
 
1575
 
 
1576
        res = gdm_config_set_value_for_id (config, id, value);
 
1577
        gdm_config_value_free (value);
 
1578
 
 
1579
        return res;
 
1580
}
 
1581
 
 
1582
gboolean
 
1583
gdm_config_set_int_for_id (GdmConfig      *config,
 
1584
                           int             id,
 
1585
                           int             integer)
 
1586
{
 
1587
        GdmConfigValue *value;
 
1588
        gboolean        res;
 
1589
 
 
1590
        g_return_val_if_fail (config != NULL, FALSE);
 
1591
 
 
1592
        value = gdm_config_value_new (GDM_CONFIG_VALUE_INT);
 
1593
        gdm_config_value_set_int (value, integer);
 
1594
 
 
1595
        res = gdm_config_set_value_for_id (config, id, value);
 
1596
        gdm_config_value_free (value);
 
1597
 
 
1598
        return res;
 
1599
}