1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
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.
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.
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.
32
#include <glib/gstdio.h>
33
#include <glib/gi18n.h>
35
#include "gdm-config.h"
39
char *mandatory_filename;
40
char *default_filename;
41
char *custom_filename;
43
gboolean mandatory_loaded;
44
gboolean default_loaded;
45
gboolean custom_loaded;
47
GKeyFile *mandatory_key_file;
48
GKeyFile *default_key_file;
49
GKeyFile *custom_key_file;
51
time_t mandatory_mtime;
57
GHashTable *value_hash;
59
GdmConfigFunc validate_func;
60
gpointer validate_func_data;
61
GdmConfigFunc notify_func;
62
gpointer notify_func_data;
66
typedef struct _GdmConfigRealValue
68
GdmConfigValueType type;
77
#define REAL_VALUE(x) ((GdmConfigRealValue *)(x))
80
gdm_config_error_quark (void)
82
return g_quark_from_static_string ("gdm-config-error-quark");
86
gdm_config_entry_copy (const GdmConfigEntry *src)
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;
101
gdm_config_entry_free (GdmConfigEntry *entry)
103
g_free (entry->group);
105
g_free (entry->default_value);
111
gdm_config_value_new (GdmConfigValueType type)
113
GdmConfigValue *value;
115
g_return_val_if_fail (type != GDM_CONFIG_VALUE_INVALID, NULL);
117
value = (GdmConfigValue *) g_slice_new0 (GdmConfigRealValue);
124
gdm_config_value_free (GdmConfigValue *value)
126
GdmConfigRealValue *real;
128
real = REAL_VALUE (value);
130
switch (real->type) {
131
case GDM_CONFIG_VALUE_INVALID:
132
case GDM_CONFIG_VALUE_BOOL:
133
case GDM_CONFIG_VALUE_INT:
135
case GDM_CONFIG_VALUE_STRING:
136
case GDM_CONFIG_VALUE_LOCALE_STRING:
137
g_free (real->val.str);
139
case GDM_CONFIG_VALUE_STRING_ARRAY:
140
case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY:
141
g_strfreev (real->val.array);
144
g_assert_not_reached ();
148
g_slice_free (GdmConfigRealValue, real);
152
set_string (char **dest,
159
*dest = src ? g_strdup (src) : NULL;
163
set_string_array (char ***dest,
170
*dest = src ? g_strdupv ((char **)src) : NULL;
174
gdm_config_value_copy (const GdmConfigValue *src)
176
GdmConfigRealValue *dest;
177
GdmConfigRealValue *real;
179
g_return_val_if_fail (src != NULL, NULL);
181
real = REAL_VALUE (src);
182
dest = REAL_VALUE (gdm_config_value_new (src->type));
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;
190
case GDM_CONFIG_VALUE_STRING:
191
case GDM_CONFIG_VALUE_LOCALE_STRING:
192
set_string (&dest->val.str, real->val.str);
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);
199
g_assert_not_reached();
202
return (GdmConfigValue *) dest;
206
gdm_config_value_get_string (const GdmConfigValue *value)
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;
214
gdm_config_value_get_locale_string (const GdmConfigValue *value)
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;
222
gdm_config_value_get_string_array (const GdmConfigValue *value)
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;
230
gdm_config_value_get_bool (const GdmConfigValue *value)
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;
238
gdm_config_value_get_int (const GdmConfigValue *value)
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;
246
safe_strcmp (const char *a,
249
return strcmp (a ? a : "", b ? b : "");
252
/* based on code from gconf */
254
gdm_config_value_compare (const GdmConfigValue *value_a,
255
const GdmConfigValue *value_b)
257
g_return_val_if_fail (value_a != NULL, 0);
258
g_return_val_if_fail (value_b != NULL, 0);
260
if (value_a->type < value_b->type) {
262
} else if (value_a->type > value_b->type) {
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)) {
270
} else if (gdm_config_value_get_int (value_a) > gdm_config_value_get_int (value_b)) {
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:
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);
296
case GDM_CONFIG_VALUE_BOOL:
297
if (gdm_config_value_get_bool (value_a) == gdm_config_value_get_bool (value_b)) {
299
} else if (gdm_config_value_get_bool (value_a)) {
304
case GDM_CONFIG_VALUE_INVALID:
306
g_assert_not_reached ();
313
/* based on code from gconf */
315
gdm_config_value_new_from_string (GdmConfigValueType type,
316
const char *value_str,
319
GdmConfigValue *value;
321
g_return_val_if_fail (type != GDM_CONFIG_VALUE_INVALID, NULL);
322
g_return_val_if_fail (value_str != NULL, NULL);
324
value = gdm_config_value_new (type);
326
switch (value->type) {
327
case GDM_CONFIG_VALUE_INT:
333
result = strtol (value_str, &endptr, 10);
334
if (endptr == value_str) {
337
GDM_CONFIG_ERROR_PARSE_ERROR,
338
_("Didn't understand `%s' (expected integer)"),
340
gdm_config_value_free (value);
342
} else if (errno == ERANGE) {
345
GDM_CONFIG_ERROR_PARSE_ERROR,
346
_("Integer `%s' is too large or small"),
348
gdm_config_value_free (value);
351
gdm_config_value_set_int (value, result);
355
case GDM_CONFIG_VALUE_BOOL:
356
switch (*value_str) {
362
gdm_config_value_set_bool (value, TRUE);
370
gdm_config_value_set_bool (value, FALSE);
375
GDM_CONFIG_ERROR_PARSE_ERROR,
376
_("Didn't understand `%s' (expected true or false)"),
378
gdm_config_value_free (value);
383
case GDM_CONFIG_VALUE_STRING:
384
if (! g_utf8_validate (value_str, -1, NULL)) {
387
GDM_CONFIG_ERROR_PARSE_ERROR,
388
_("Text contains invalid UTF-8"));
389
gdm_config_value_free (value);
392
gdm_config_value_set_string (value, value_str);
395
case GDM_CONFIG_VALUE_LOCALE_STRING:
396
if (! g_utf8_validate (value_str, -1, NULL)) {
399
GDM_CONFIG_ERROR_PARSE_ERROR,
400
_("Text contains invalid UTF-8"));
401
gdm_config_value_free (value);
404
gdm_config_value_set_locale_string (value, value_str);
407
case GDM_CONFIG_VALUE_STRING_ARRAY:
408
if (! g_utf8_validate (value_str, -1, NULL)) {
411
GDM_CONFIG_ERROR_PARSE_ERROR,
412
_("Text contains invalid UTF-8"));
413
gdm_config_value_free (value);
417
split = g_strsplit (value_str, ";", -1);
418
gdm_config_value_set_string_array (value, (const char **)split);
422
case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY:
423
if (! g_utf8_validate (value_str, -1, NULL)) {
426
GDM_CONFIG_ERROR_PARSE_ERROR,
427
_("Text contains invalid UTF-8"));
428
gdm_config_value_free (value);
432
split = g_strsplit (value_str, ";", -1);
433
gdm_config_value_set_locale_string_array (value, (const char **)split);
437
case GDM_CONFIG_VALUE_INVALID:
439
g_assert_not_reached ();
447
gdm_config_value_set_string_array (GdmConfigValue *value,
450
GdmConfigRealValue *real;
452
g_return_if_fail (value != NULL);
453
g_return_if_fail (value->type == GDM_CONFIG_VALUE_STRING_ARRAY);
455
real = REAL_VALUE (value);
457
g_strfreev (real->val.array);
458
real->val.array = g_strdupv ((char **)array);
462
gdm_config_value_set_locale_string_array (GdmConfigValue *value,
465
GdmConfigRealValue *real;
467
g_return_if_fail (value != NULL);
468
g_return_if_fail (value->type == GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY);
470
real = REAL_VALUE (value);
472
g_strfreev (real->val.array);
473
real->val.array = g_strdupv ((char **)array);
477
gdm_config_value_set_int (GdmConfigValue *value,
480
GdmConfigRealValue *real;
482
g_return_if_fail (value != NULL);
483
g_return_if_fail (value->type == GDM_CONFIG_VALUE_INT);
485
real = REAL_VALUE (value);
487
real->val.integer = integer;
491
gdm_config_value_set_bool (GdmConfigValue *value,
494
GdmConfigRealValue *real;
496
g_return_if_fail (value != NULL);
497
g_return_if_fail (value->type == GDM_CONFIG_VALUE_BOOL);
499
real = REAL_VALUE (value);
501
real->val.bool = bool;
505
gdm_config_value_set_string (GdmConfigValue *value,
508
GdmConfigRealValue *real;
510
g_return_if_fail (value != NULL);
511
g_return_if_fail (value->type == GDM_CONFIG_VALUE_STRING);
513
real = REAL_VALUE (value);
515
g_free (real->val.str);
516
real->val.str = g_strdup (str);
520
gdm_config_value_set_locale_string (GdmConfigValue *value,
523
GdmConfigRealValue *real;
525
g_return_if_fail (value != NULL);
526
g_return_if_fail (value->type == GDM_CONFIG_VALUE_LOCALE_STRING);
528
real = REAL_VALUE (value);
530
g_free (real->val.str);
531
real->val.str = g_strdup (str);
535
gdm_config_value_to_string (const GdmConfigValue *value)
537
GdmConfigRealValue *real;
540
g_return_val_if_fail (value != NULL, NULL);
543
real = REAL_VALUE (value);
545
switch (real->type) {
546
case GDM_CONFIG_VALUE_INVALID:
548
case GDM_CONFIG_VALUE_BOOL:
549
ret = real->val.bool ? g_strdup ("true") : g_strdup ("false");
551
case GDM_CONFIG_VALUE_INT:
552
ret = g_strdup_printf ("%d", real->val.integer);
554
case GDM_CONFIG_VALUE_STRING:
555
case GDM_CONFIG_VALUE_LOCALE_STRING:
556
ret = g_strdup (real->val.str);
558
case GDM_CONFIG_VALUE_STRING_ARRAY:
559
case GDM_CONFIG_VALUE_LOCALE_STRING_ARRAY:
560
ret = g_strjoinv (";", real->val.array);
563
g_assert_not_reached ();
570
gdm_config_init (GdmConfig *config)
572
config->entries = g_ptr_array_new ();
573
config->value_hash = g_hash_table_new_full (g_str_hash,
575
(GDestroyNotify)g_free,
576
(GDestroyNotify)gdm_config_value_free);
580
gdm_config_new (void)
584
config = g_slice_new0 (GdmConfig);
585
gdm_config_init (config);
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
600
gdm_config_free (GdmConfig *config)
603
GKeyFile *mkf, *dkf, *ckf;
606
g_return_if_fail (config != NULL);
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.
615
mkf = config->mandatory_key_file;
616
dkf = config->default_key_file;
617
ckf = config->custom_key_file;
618
hash = config->value_hash;
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;
626
g_free (config->mandatory_filename);
627
g_free (config->default_filename);
628
g_free (config->custom_filename);
630
g_slice_free (GdmConfig, config);
633
g_ptr_array_foreach (e, (GFunc)gdm_config_entry_free, NULL);
634
g_ptr_array_free (e, TRUE);
637
g_key_file_free (mkf);
639
g_key_file_free (dkf);
641
g_key_file_free (ckf);
643
g_hash_table_destroy (hash);
647
add_server_group_once (GPtrArray *server_groups, char *group)
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",
658
g_ptr_array_add (server_groups, g_strdup (group));
662
gdm_config_get_server_groups (GdmConfig *config)
664
GPtrArray *server_groups;
670
server_groups = g_ptr_array_new ();
672
if (config->mandatory_key_file != NULL) {
673
groups = g_key_file_get_groups (config->mandatory_key_file, &len);
675
for (i = 0; i < len; i++)
677
if (g_str_has_prefix (groups[i], "server-")) {
678
add_server_group_once (server_groups, groups[i]);
684
if (config->default_key_file != NULL) {
685
groups = g_key_file_get_groups (config->default_key_file, &len);
687
for (i = 0; i < len; i++)
689
if (g_str_has_prefix (groups[i], "server-")) {
690
add_server_group_once (server_groups, groups[i]);
696
if (config->custom_key_file != NULL) {
697
groups = g_key_file_get_groups (config->custom_key_file, &len);
699
for (i = 0; i < len; i++)
701
if (g_str_has_prefix (groups[i], "server-")) {
702
add_server_group_once (server_groups, groups[i]);
708
return server_groups;
711
const GdmConfigEntry *
712
gdm_config_lookup_entry (GdmConfig *config,
717
const GdmConfigEntry *entry;
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);
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;
738
const GdmConfigEntry *
739
gdm_config_lookup_entry_for_id (GdmConfig *config,
743
const GdmConfigEntry *entry;
745
g_return_val_if_fail (config != NULL, NULL);
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;
762
gdm_config_add_entry (GdmConfig *config,
763
const GdmConfigEntry *entry)
765
GdmConfigEntry *new_entry;
767
g_return_if_fail (config != NULL);
768
g_return_if_fail (entry != NULL);
770
new_entry = gdm_config_entry_copy (entry);
771
g_ptr_array_add (config->entries, new_entry);
775
gdm_config_add_static_entries (GdmConfig *config,
776
const GdmConfigEntry *entries)
780
g_return_if_fail (config != NULL);
781
g_return_if_fail (entries != NULL);
783
for (i = 0; entries[i].group != NULL; i++) {
784
gdm_config_add_entry (config, &entries[i]);
789
gdm_config_set_validate_func (GdmConfig *config,
793
g_return_if_fail (config != NULL);
795
config->validate_func = func;
796
config->validate_func_data = data;
800
gdm_config_set_mandatory_file (GdmConfig *config,
803
g_return_if_fail (config != NULL);
805
g_free (config->mandatory_filename);
806
config->mandatory_filename = g_strdup (name);
810
gdm_config_set_default_file (GdmConfig *config,
813
g_return_if_fail (config != NULL);
815
g_free (config->default_filename);
816
config->default_filename = g_strdup (name);
820
gdm_config_set_custom_file (GdmConfig *config,
823
g_return_if_fail (config != NULL);
825
g_free (config->custom_filename);
826
config->custom_filename = g_strdup (name);
830
gdm_config_set_notify_func (GdmConfig *config,
834
g_return_if_fail (config != NULL);
836
config->notify_func = func;
837
config->notify_func_data = data;
841
key_file_get_value (GdmConfig *config,
845
GdmConfigValueType type,
846
GdmConfigValue **valuep)
850
GdmConfigValue *value;
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,
865
g_debug ("Loading locale string: %s %s", key, val ? val : "(null)");
868
g_debug ("%s", error->message);
869
g_error_free (error);
873
val = g_key_file_get_value (key_file,
877
g_debug ("Loading non-locale string: %s %s", key, val ? val : "(null)");
880
val = g_key_file_get_value (key_file,
887
g_error_free (error);
896
value = gdm_config_value_new_from_string (type, val, &error);
898
g_warning ("%s", error->message);
899
g_error_free (error);
914
entry_get_default_value (GdmConfig *config,
915
const GdmConfigEntry *entry,
916
GdmConfigValue **valuep)
918
GdmConfigValue *value;
922
value = gdm_config_value_new_from_string (entry->type,
923
entry->default_value ? entry->default_value : "",
926
g_warning ("%s", error->message);
927
g_error_free (error);
934
load_value_entry (GdmConfig *config,
935
const GdmConfigEntry *entry,
936
GdmConfigValue **valuep,
937
GdmConfigSourceType *sourcep)
939
GdmConfigValue *value;
940
GdmConfigSourceType source;
946
/* Look for the first occurence of the key in:
947
mandatory file, custom file, default file, or built-in-default
950
if (config->mandatory_filename != NULL) {
951
source = GDM_CONFIG_SOURCE_MANDATORY;
952
res = key_file_get_value (config,
953
config->mandatory_key_file,
962
if (config->custom_filename != NULL) {
963
source = GDM_CONFIG_SOURCE_CUSTOM;
964
res = key_file_get_value (config,
965
config->custom_key_file,
974
if (config->default_filename != NULL) {
975
source = GDM_CONFIG_SOURCE_DEFAULT;
976
res = key_file_get_value (config,
977
config->default_key_file,
988
source = GDM_CONFIG_SOURCE_BUILT_IN;
989
entry_get_default_value (config, entry, &value);
1006
lookup_id_for_key (GdmConfig *config,
1011
const GdmConfigEntry *entry;
1013
id = GDM_CONFIG_INVALID_ID;
1014
entry = gdm_config_lookup_entry (config, group, key);
1015
if (entry != NULL) {
1023
internal_set_value (GdmConfig *config,
1024
GdmConfigSourceType source,
1027
GdmConfigValue *value)
1034
g_return_if_fail (config != NULL);
1036
key_path = g_strdup_printf ("%s/%s", group, key);
1039
res = g_hash_table_lookup_extended (config->value_hash,
1045
if (v != NULL && gdm_config_value_compare (v, value) == 0) {
1046
/* value is the same - don't update */
1051
g_hash_table_insert (config->value_hash,
1052
g_strdup (key_path),
1053
gdm_config_value_copy (value));
1055
id = lookup_id_for_key (config, group, key);
1057
if (config->notify_func) {
1058
(* config->notify_func) (config, source, group, key, value, id, config->notify_func_data);
1065
store_entry_value (GdmConfig *config,
1066
const GdmConfigEntry *entry,
1067
GdmConfigSourceType source,
1068
GdmConfigValue *value)
1070
internal_set_value (config, source, entry->group, entry->key, value);
1074
load_entry (GdmConfig *config,
1075
const GdmConfigEntry *entry)
1077
GdmConfigValue *value;
1078
GdmConfigSourceType source;
1082
source = GDM_CONFIG_SOURCE_INVALID;
1084
res = load_value_entry (config, entry, &value, &source);
1090
if (config->validate_func) {
1091
res = (* config->validate_func) (config, source, entry->group, entry->key, value, entry->id, config->validate_func_data);
1095
/* store runs notify */
1096
store_entry_value (config, entry, source, value);
1103
add_keys_to_hash (GKeyFile *key_file,
1104
const char *group_name,
1107
GError *local_error;
1114
keys = g_key_file_get_keys (key_file,
1118
if (local_error != NULL) {
1119
g_error_free (local_error);
1124
for (i = 0; i < len; i++) {
1125
g_hash_table_insert (hash, g_strdup (keys[i]), GINT_TO_POINTER (1));
1132
collect_hash_keys (const char *key,
1136
g_message ("Adding %s", key);
1137
g_ptr_array_add (*array, g_strdup (key));
1141
gdm_config_get_keys_for_group (GdmConfig *config,
1150
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1152
if (config->mandatory_filename != NULL) {
1153
add_keys_to_hash (config->mandatory_key_file, group, hash);
1156
if (config->default_filename != NULL) {
1157
add_keys_to_hash (config->default_key_file, group, hash);
1160
if (config->custom_filename != NULL) {
1161
add_keys_to_hash (config->custom_key_file, group, hash);
1164
len = g_hash_table_size (hash);
1165
array = g_ptr_array_sized_new (len);
1167
g_hash_table_foreach (hash, (GHFunc)collect_hash_keys, &array);
1168
g_ptr_array_add (array, NULL);
1170
g_hash_table_destroy (hash);
1172
if (length != NULL) {
1173
*length = array->len - 1;
1176
return (char **)g_ptr_array_free (array, FALSE);
1180
load_backend (GdmConfig *config,
1181
const char *filename,
1182
GKeyFile **key_file,
1185
GError *local_error;
1188
struct stat statbuf;
1192
if (filename == NULL) {
1196
if (g_stat (filename, &statbuf) != 0) {
1199
lmtime = statbuf.st_mtime;
1201
/* if already loaded check whether reload is necessary */
1202
if (*key_file != NULL) {
1203
if (lmtime > *mtime) {
1205
/* needs an update */
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.
1219
g_key_file_free (kf);
1221
/* no reload necessary so we're done */
1226
kf = g_key_file_new ();
1229
res = g_key_file_load_from_file (kf,
1231
G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
1234
g_error_free (local_error);
1235
g_key_file_free (kf);
1250
gdm_config_load (GdmConfig *config,
1253
g_return_val_if_fail (config != NULL, FALSE);
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);
1272
process_entries (GdmConfig *config,
1273
const GdmConfigEntry **entries,
1282
for (i = 0; i < n_entries; i++) {
1283
load_entry (config, entries[i]);
1290
gdm_config_process_entry (GdmConfig *config,
1291
const GdmConfigEntry *entry,
1296
g_return_val_if_fail (config != NULL, FALSE);
1297
g_return_val_if_fail (entry != NULL, FALSE);
1299
ret = load_entry (config, entry);
1305
gdm_config_process_entries (GdmConfig *config,
1306
const GdmConfigEntry **entries,
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);
1316
ret = process_entries (config, entries, n_entries, error);
1322
gdm_config_process_all (GdmConfig *config,
1327
g_return_val_if_fail (config != NULL, FALSE);
1329
ret = process_entries (config,
1330
(const GdmConfigEntry **)config->entries->pdata,
1331
config->entries->len,
1338
gdm_config_peek_value (GdmConfig *config,
1341
const GdmConfigValue **valuep)
1345
const GdmConfigValue *value;
1347
g_return_val_if_fail (config != NULL, FALSE);
1349
key_path = g_strdup_printf ("%s/%s", group, key);
1351
ret = g_hash_table_lookup_extended (config->value_hash,
1354
(gpointer *)&value);
1357
if (valuep != NULL) {
1369
gdm_config_get_value (GdmConfig *config,
1372
GdmConfigValue **valuep)
1375
const GdmConfigValue *value;
1377
res = gdm_config_peek_value (config, group, key, &value);
1378
if (valuep != NULL) {
1379
*valuep = (value == NULL) ? NULL : gdm_config_value_copy (value);
1386
gdm_config_set_value (GdmConfig *config,
1389
GdmConfigValue *value)
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);
1396
internal_set_value (config, GDM_CONFIG_SOURCE_RUNTIME_USER, group, key, value);
1402
gdm_config_peek_value_for_id (GdmConfig *config,
1404
const GdmConfigValue **valuep)
1406
const GdmConfigEntry *entry;
1408
g_return_val_if_fail (config != NULL, FALSE);
1410
entry = gdm_config_lookup_entry_for_id (config, id);
1411
if (entry == NULL) {
1415
return gdm_config_peek_value (config, entry->group, entry->key, valuep);
1419
gdm_config_get_value_for_id (GdmConfig *config,
1421
GdmConfigValue **valuep)
1423
const GdmConfigEntry *entry;
1425
g_return_val_if_fail (config != NULL, FALSE);
1427
entry = gdm_config_lookup_entry_for_id (config, id);
1428
if (entry == NULL) {
1432
return gdm_config_get_value (config, entry->group, entry->key, valuep);
1436
gdm_config_set_value_for_id (GdmConfig *config,
1438
GdmConfigValue *valuep)
1440
const GdmConfigEntry *entry;
1442
g_return_val_if_fail (config != NULL, FALSE);
1444
entry = gdm_config_lookup_entry_for_id (config, id);
1445
if (entry == NULL) {
1449
return gdm_config_set_value (config, entry->group, entry->key, valuep);
1453
gdm_config_peek_string_for_id (GdmConfig *config,
1457
const GdmConfigValue *value;
1461
g_return_val_if_fail (config != NULL, FALSE);
1463
res = gdm_config_peek_value_for_id (config, id, &value);
1468
str = gdm_config_value_get_string (value);
1477
gdm_config_get_string_for_id (GdmConfig *config,
1484
res = gdm_config_peek_string_for_id (config, id, &str);
1486
*strp = g_strdup (str);
1493
gdm_config_get_bool_for_id (GdmConfig *config,
1497
GdmConfigValue *value;
1501
g_return_val_if_fail (config != NULL, FALSE);
1503
res = gdm_config_get_value_for_id (config, id, &value);
1508
bool = gdm_config_value_get_bool (value);
1509
if (boolp != NULL) {
1513
gdm_config_value_free (value);
1519
gdm_config_get_int_for_id (GdmConfig *config,
1523
GdmConfigValue *value;
1527
g_return_val_if_fail (config != NULL, FALSE);
1529
res = gdm_config_get_value_for_id (config, id, &value);
1534
integer = gdm_config_value_get_int (value);
1535
if (integerp != NULL) {
1536
*integerp = integer;
1539
gdm_config_value_free (value);
1545
gdm_config_set_string_for_id (GdmConfig *config,
1549
GdmConfigValue *value;
1552
g_return_val_if_fail (config != NULL, FALSE);
1554
value = gdm_config_value_new (GDM_CONFIG_VALUE_STRING);
1555
gdm_config_value_set_string (value, str);
1557
res = gdm_config_set_value_for_id (config, id, value);
1558
gdm_config_value_free (value);
1564
gdm_config_set_bool_for_id (GdmConfig *config,
1568
GdmConfigValue *value;
1571
g_return_val_if_fail (config != NULL, FALSE);
1573
value = gdm_config_value_new (GDM_CONFIG_VALUE_BOOL);
1574
gdm_config_value_set_bool (value, bool);
1576
res = gdm_config_set_value_for_id (config, id, value);
1577
gdm_config_value_free (value);
1583
gdm_config_set_int_for_id (GdmConfig *config,
1587
GdmConfigValue *value;
1590
g_return_val_if_fail (config != NULL, FALSE);
1592
value = gdm_config_value_new (GDM_CONFIG_VALUE_INT);
1593
gdm_config_value_set_int (value, integer);
1595
res = gdm_config_set_value_for_id (config, id, value);
1596
gdm_config_value_free (value);