4 * Copyright (C) 2012 Intel Corporation. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU Lesser General Public License,
8 * version 2.1, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 * Ludovic Ferrandis <ludovic.ferrandis@intel.com>
27 struct msu_settings_context_t_ {
29 GFileMonitor *monitor;
37 msu_log_type_t log_type;
41 #define MSU_SETTINGS_KEYFILE_NAME "media-service-upnp.conf"
43 #define MSU_SETTINGS_GROUP_GENERAL "general"
44 #define MSU_SETTINGS_KEY_NEVER_QUIT "never-quit"
46 #define MSU_SETTINGS_GROUP_LOG "log"
47 #define MSU_SETTINGS_KEY_LOG_TYPE "log-type"
48 #define MSU_SETTINGS_KEY_LOG_LEVEL "log-level"
50 #define MSU_SETTINGS_DEFAULT_NEVER_QUIT MSU_NEVER_QUIT
51 #define MSU_SETTINGS_DEFAULT_LOG_TYPE MSU_LOG_TYPE
52 #define MSU_SETTINGS_DEFAULT_LOG_LEVEL MSU_LOG_LEVEL
54 #define MSU_SETTINGS_LOG_KEYS(sys, loc, settings) \
57 MSU_LOG_INFO("Load file [%s]", loc ? loc : sys); \
59 MSU_LOG_DEBUG("[General settings]"); \
60 MSU_LOG_DEBUG("Never Quit: %s", (settings)->never_quit ? "T" : "F"); \
62 MSU_LOG_DEBUG("[Logging settings]"); \
63 MSU_LOG_DEBUG("Log Type : %d", (settings)->log_type); \
64 MSU_LOG_DEBUG("Log Level: 0x%02X", (settings)->log_level); \
69 static void prv_msu_settings_get_keyfile_path(gchar **sys_path,
74 if (sys_path != NULL) {
78 *sys_path = g_strdup_printf("%s/%s", SYS_CONFIG_DIR,
79 MSU_SETTINGS_KEYFILE_NAME);
82 if (loc_path != NULL) {
83 loc_dir = g_get_user_config_dir();
86 if (loc_dir && *loc_dir)
87 *loc_path = g_strdup_printf("%s/%s", loc_dir,
88 MSU_SETTINGS_KEYFILE_NAME);
92 static void prv_msu_settings_check_local_keyfile(const gchar *sys_path,
93 const gchar *loc_path)
95 GFile *sys_file = NULL;
99 loc_file = g_file_new_for_path(loc_path);
100 loc_dir = g_file_get_parent(loc_file);
102 if (g_file_query_exists(loc_file, NULL) || (sys_path == NULL))
105 if (!g_file_query_exists(loc_dir, NULL)) {
106 if (!g_file_make_directory(loc_dir, NULL, NULL))
110 sys_file = g_file_new_for_path(sys_path);
112 (void) g_file_copy(sys_file, loc_file, G_FILE_COPY_TARGET_DEFAULT_PERMS,
113 NULL, NULL, NULL, NULL);
117 g_object_unref(loc_dir);
120 g_object_unref(loc_file);
123 g_object_unref(sys_file);
126 static GKeyFile *prv_msu_settings_load_keyfile(const gchar *filepath)
128 GKeyFile *keyfile = NULL;
130 if (filepath == NULL)
133 keyfile = g_key_file_new();
135 if (!g_key_file_load_from_file(keyfile, filepath, G_KEY_FILE_NONE,
137 g_key_file_free(keyfile);
145 static int prv_msu_settings_to_log_level(gint *int_list, gsize length)
150 int log_level_array[] = { MSU_LOG_LEVEL_DISABLED,
151 MSU_LOG_LEVEL_ERROR, MSU_LOG_LEVEL_CRITICAL,
152 MSU_LOG_LEVEL_WARNING, MSU_LOG_LEVEL_MESSAGE,
153 MSU_LOG_LEVEL_INFO, MSU_LOG_LEVEL_DEBUG,
154 MSU_LOG_LEVEL_DEFAULT, MSU_LOG_LEVEL_ALL };
158 /* Take all valid values, even duplicated ones, and skip all others.
159 * Priority is single value (0,7,8) over multi value (1..6)
160 * Priority for single values is first found */
161 for (i = 0; i < length; ++i) {
164 if (level > 0 && level < 7)
165 log_level_value |= log_level_array[level];
166 else if ((level == 0) || (level == 7) || (level == 8)) {
167 log_level_value = log_level_array[level];
172 return log_level_value;
175 static msu_log_type_t prv_msu_settings_to_log_type(int type)
177 msu_log_type_t log_type = MSU_LOG_TYPE_SYSLOG;
183 log_type = MSU_LOG_TYPE_GLIB;
192 static void prv_msu_settings_read_keys(msu_settings_context_t *settings)
194 GError *error = NULL;
195 GKeyFile *keyfile = settings->keyfile;
201 b_val = g_key_file_get_boolean(keyfile, MSU_SETTINGS_GROUP_GENERAL,
202 MSU_SETTINGS_KEY_NEVER_QUIT,
206 settings->never_quit = b_val;
212 int_val = g_key_file_get_integer(keyfile, MSU_SETTINGS_GROUP_LOG,
213 MSU_SETTINGS_KEY_LOG_TYPE,
217 settings->log_type = prv_msu_settings_to_log_type(int_val);
223 g_key_file_set_list_separator(keyfile, ',');
225 int_star = g_key_file_get_integer_list(keyfile, MSU_SETTINGS_GROUP_LOG,
226 MSU_SETTINGS_KEY_LOG_LEVEL,
231 settings->log_level = prv_msu_settings_to_log_level(int_star,
240 static void prv_msu_settings_init_default(msu_settings_context_t *settings)
242 settings->never_quit = MSU_SETTINGS_DEFAULT_NEVER_QUIT;
244 settings->log_type = MSU_SETTINGS_DEFAULT_LOG_TYPE;
245 settings->log_level = MSU_SETTINGS_DEFAULT_LOG_LEVEL;
248 static void prv_msu_settings_keyfile_init(msu_settings_context_t *settings,
249 const gchar *sys_path,
250 const gchar *loc_path)
252 settings->keyfile = prv_msu_settings_load_keyfile(loc_path);
254 if (settings->keyfile == NULL)
255 settings->keyfile = prv_msu_settings_load_keyfile(sys_path);
257 if (settings->keyfile != NULL) {
258 prv_msu_settings_read_keys(settings);
259 msu_log_update_type_level(settings->log_type,
260 settings->log_level);
264 static void prv_msu_settings_keyfile_finalize(msu_settings_context_t *settings)
266 if (settings->keyfile != NULL) {
267 g_key_file_free(settings->keyfile);
268 settings->keyfile = NULL;
272 static void prv_msu_settings_reload(msu_settings_context_t *settings)
274 gchar *sys_path = NULL;
275 gchar *loc_path = NULL;
277 MSU_LOG_INFO("Reload local configuration file");
279 prv_msu_settings_keyfile_finalize(settings);
280 prv_msu_settings_init_default(settings);
281 prv_msu_settings_get_keyfile_path(&sys_path, &loc_path);
283 if (sys_path || loc_path)
284 prv_msu_settings_keyfile_init(settings, sys_path, loc_path);
286 MSU_SETTINGS_LOG_KEYS(sys_path, loc_path, settings);
292 static gboolean prv_msu_settings_monitor_timout_cb(gpointer user_data)
294 msu_settings_context_t *data = (msu_settings_context_t *) user_data;
296 MSU_LOG_INFO("Change in local settings file: Reload");
298 prv_msu_settings_reload(data);
304 static void prv_msu_settings_monitor_keyfile_cb(GFileMonitor *monitor,
307 GFileMonitorEvent event_type,
310 msu_settings_context_t *data = (msu_settings_context_t *) user_data;
312 switch (event_type) {
313 case G_FILE_MONITOR_EVENT_CHANGED:
314 case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
315 case G_FILE_MONITOR_EVENT_DELETED:
316 case G_FILE_MONITOR_EVENT_CREATED:
317 case G_FILE_MONITOR_EVENT_MOVED:
318 /* Reset the timer to prevent running the cb if monitoring
319 * event are raised 1 sec after the timer has been set */
320 if (data->ev_id != 0)
321 (void) g_source_remove(data->ev_id);
323 data->ev_id = g_timeout_add_seconds(1,
324 prv_msu_settings_monitor_timout_cb, user_data);
331 static void prv_msu_settings_monitor_local_keyfile(
332 msu_settings_context_t *settings, const gchar *loc_path)
335 GFileMonitor *monitor = NULL;
338 loc_file = g_file_new_for_path(loc_path);
339 monitor = g_file_monitor_file(loc_file, G_FILE_MONITOR_SEND_MOVED, NULL,
341 g_object_unref(loc_file);
343 if (monitor != NULL) {
344 handler_id = g_signal_connect(monitor, "changed",
345 G_CALLBACK(prv_msu_settings_monitor_keyfile_cb),
348 settings->monitor = monitor;
349 settings->handler_id = handler_id;
353 gboolean msu_settings_is_never_quit(msu_settings_context_t *settings)
355 return settings->never_quit;
358 void msu_settings_new(msu_settings_context_t **settings)
360 gchar *sys_path = NULL;
361 gchar *loc_path = NULL;
363 *settings = g_malloc0(sizeof(**settings));
364 prv_msu_settings_init_default(*settings);
366 prv_msu_settings_get_keyfile_path(&sys_path, &loc_path);
369 prv_msu_settings_check_local_keyfile(sys_path, loc_path);
370 prv_msu_settings_monitor_local_keyfile(*settings, loc_path);
373 if (sys_path || loc_path)
374 prv_msu_settings_keyfile_init(*settings, sys_path, loc_path);
376 MSU_SETTINGS_LOG_KEYS(sys_path, loc_path, *settings);
382 void msu_settings_delete(msu_settings_context_t *settings)
384 if (settings->monitor) {
385 if (settings->handler_id)
386 g_signal_handler_disconnect(settings->monitor,
387 settings->handler_id);
389 g_file_monitor_cancel(settings->monitor);
390 g_object_unref(settings->monitor);
393 prv_msu_settings_keyfile_finalize(settings);