4
#include "greeterconfiguration.h"
7
static GKeyFile* greeter_config = NULL;
8
static GKeyFile* state_config = NULL;
9
static gchar* state_filename = NULL;
11
static GKeyFile* get_file_for_group (const gchar** group);
12
static void save_key_file (GKeyFile* config, const gchar* path);
13
static gboolean get_int (GKeyFile* config, const gchar* group, const gchar* key, gint* out);
14
static gboolean get_bool (GKeyFile* config, const gchar* group, const gchar* key, gboolean* out);
19
append_directory_content(GList* files, const gchar* path)
22
GList *content = NULL;
23
GList *list_iter = NULL;
24
gchar *full_path = g_build_filename(path, "lightdm", "lightdm-gtk-greeter.conf.d", NULL);
25
GDir *dir = g_dir_open(full_path, 0, &error);
27
if(error && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
28
g_warning("[Configuration] Failed to read configuration directory '%s': %s", full_path, error->message);
29
g_clear_error(&error);
34
while((name = g_dir_read_name(dir)))
36
if(!g_str_has_suffix(name, ".conf"))
38
content = g_list_prepend(content, g_build_filename(full_path, name, NULL));
43
content = g_list_sort(content, (GCompareFunc)g_strcmp0);
46
content = g_list_append(content, g_build_filename(path, "lightdm", "lightdm-gtk-greeter.conf", NULL));
48
for(list_iter = content; list_iter; list_iter = g_list_next(list_iter))
50
if(g_file_test(list_iter->data, G_FILE_TEST_IS_REGULAR))
51
files = g_list_prepend(files, list_iter->data);
53
g_free(list_iter->data);
64
GKeyFile *tmp_config = NULL;
67
GList *file_iter = NULL;
68
const gchar* const *dirs;
69
gchar *state_config_dir;
70
gchar *config_path_tmp;
74
state_config_dir = g_build_filename(g_get_user_cache_dir(), "lightdm-gtk-greeter", NULL);
75
state_filename = g_build_filename(state_config_dir, "state", NULL);
76
g_mkdir_with_parents(state_config_dir, 0775);
77
g_free(state_config_dir);
79
state_config = g_key_file_new();
80
g_key_file_load_from_file(state_config, state_filename, G_KEY_FILE_NONE, &error);
81
if (error && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
82
g_warning("[Configuration] Failed to load state from %s: %s", state_filename, error->message);
83
g_clear_error(&error);
85
dirs = g_get_system_data_dirs();
86
for(i = 0; dirs[i]; ++i)
87
files = append_directory_content(files, dirs[i]);
89
dirs = g_get_system_config_dirs();
90
for(i = 0; dirs[i]; ++i)
91
files = append_directory_content(files, dirs[i]);
93
config_path_tmp = g_path_get_dirname(CONFIG_FILE);
94
config_path = g_path_get_dirname(config_path_tmp);
95
files = append_directory_content(files, config_path);
96
g_free(config_path_tmp);
99
files = g_list_reverse(files);
101
for(file_iter = files; file_iter; file_iter = g_list_next(file_iter))
103
const gchar *path = file_iter->data;
104
gchar **group_iter = NULL;
108
tmp_config = g_key_file_new();
110
if(!g_key_file_load_from_file(tmp_config, path, G_KEY_FILE_NONE, &error))
114
g_warning("[Configuration] Failed to read file '%s': %s", path, error->message);
115
g_clear_error(&error);
118
g_warning("[Configuration] Failed to read file '%s'", path);
121
g_message("[Configuration] Reading file: %s", path);
125
greeter_config = tmp_config;
130
groups = g_key_file_get_groups(tmp_config, NULL);
131
for(group_iter = groups; *group_iter; ++group_iter)
133
gchar **key_iter = NULL;
135
if(**group_iter == '-')
137
g_key_file_remove_group(greeter_config, *group_iter + 1, NULL);
141
keys = g_key_file_get_keys(tmp_config, *group_iter, NULL, NULL);
142
for(key_iter = keys; *key_iter; ++key_iter)
146
if(**key_iter == '-')
148
g_key_file_remove_key(greeter_config, *group_iter, *key_iter + 1, NULL);
152
value = g_key_file_get_value(tmp_config, *group_iter, *key_iter, NULL);
155
g_key_file_set_value(greeter_config, *group_iter, *key_iter, value);
164
g_key_file_unref(tmp_config);
165
g_list_free_full(files, g_free);
168
greeter_config = g_key_file_new();
172
get_file_for_group(const gchar** group)
175
*group = CONFIG_GROUP_DEFAULT;
183
return greeter_config;
187
save_key_file(GKeyFile* config, const gchar* path)
189
GError* error = NULL;
190
gsize data_length = 0;
191
gchar* data = g_key_file_to_data(config, &data_length, &error);
195
g_warning("[Configuration] Failed to save file: %s", error->message);
196
g_clear_error(&error);
201
g_file_set_contents(path, data, data_length, &error);
204
g_warning("[Configuration] Failed to save file: %s", error->message);
205
g_clear_error(&error);
212
get_int(GKeyFile* config, const gchar* group, const gchar* key, gint* out)
214
GError* error = NULL;
215
*out = g_key_file_get_integer(config, group, key, &error);
218
if(g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE))
219
g_warning("[Configuration] Failed to parse integer value [%s] %s: %s", group, key, error->message);
220
g_clear_error(&error);
225
get_bool(GKeyFile* config, const gchar* group, const gchar* key, gboolean* out)
227
GError* error = NULL;
228
*out = g_key_file_get_boolean(config, group, key, &error);
231
if(g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE))
232
g_warning("[Configuration] Failed to parse boolean value [%s] %s: %s", group, key, error->message);
233
g_clear_error(&error);
238
config_get_groups(const gchar* prefix)
240
gsize groups_size = 0, i, next;
241
gchar** groups = g_key_file_get_groups(greeter_config, &groups_size);
243
for(i = next = 0; i < groups_size; ++i)
244
if(groups[i] && g_str_has_prefix(groups[i], prefix))
248
g_free (groups[next]);
249
groups[next] = groups[i];
262
config_has_key(const gchar* group, const gchar* key)
264
GKeyFile* file = get_file_for_group(&group);
265
return g_key_file_has_key(file, group, key, NULL);
269
config_get_string(const gchar* group, const gchar* key, const gchar* fallback)
271
GKeyFile* file = get_file_for_group(&group);
272
gchar* value = g_key_file_get_value(file, group, key, NULL);
273
return value || !fallback ? value : g_strdup(fallback);
277
config_set_string(const gchar* group, const gchar* key, const gchar* value)
279
if(get_file_for_group(&group) != state_config)
281
g_warning("[Configuration] %s(%s, %s, '%s')", __func__, group, key, value);
285
g_key_file_set_value(state_config, group, key, value);
286
save_key_file(state_config, state_filename);
290
config_get_string_list(const gchar* group, const gchar* key, gchar** fallback)
292
GKeyFile* file = get_file_for_group(&group);
293
gchar** value = g_key_file_get_string_list(file, group, key, NULL, NULL);
294
return value || !fallback ? value : g_strdupv(fallback);
298
config_get_int(const gchar* group, const gchar* key, gint fallback)
300
GKeyFile* file = get_file_for_group(&group);
302
if(!get_int(file, group, key, &value))
308
config_set_int(const gchar* group, const gchar* key, gint value)
310
if(get_file_for_group(&group) != state_config)
312
g_warning("[Configuration] %s(%s, %s, %d)", __func__, group, key, value);
316
g_key_file_set_integer(state_config, group, key, value);
317
save_key_file(state_config, state_filename);
321
config_get_bool(const gchar* group, const gchar* key, gboolean fallback)
323
GKeyFile* file = get_file_for_group(&group);
325
if(!get_bool(file, group, key, &value))
331
config_set_bool(const gchar* group, const gchar* key, gboolean value)
333
if(get_file_for_group(&group) != state_config)
335
g_warning("[Configuration] %s(%s, %s, %d)", __func__, group, key, value);
339
g_key_file_set_boolean(state_config, group, key, value);
340
save_key_file(state_config, state_filename);
344
config_get_enum(const gchar* group, const gchar* key, gint fallback, const gchar* first_item, ...)
346
const gchar *item_name;
349
gboolean found = FALSE;
355
file = get_file_for_group(&group);
356
value = g_key_file_get_value(file, group, key, NULL);
361
va_start(var_args, first_item);
363
item_name = first_item;
366
gint item_value = va_arg(var_args, gint);
367
if(g_strcmp0(value, item_name) == 0)
370
fallback = item_value;
373
item_name = va_arg(var_args, gchar*);
378
g_warning("[Configuration] Failed to parse enum value [%s] %s: %s", group, key, value);