00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <string.h>
00035 #include <gconf/gconf-client.h>
00036
00037
00038
00039 #include "er_error.h"
00040
00041
00042 #include "log.h"
00043 #include "gconf_utils.h"
00044
00045 #define UNUSED(x) (void)(x)
00046
00047
00048
00049
00050
00051
00052 typedef struct
00053 {
00054 const char *key;
00055 gboolean found;
00056 } FindKeyInfo;
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 static GConfClient* client = NULL;
00068 static gconf_cb_value_changed_t g_cb_value_changed = NULL;
00069
00070
00071
00072
00073
00074 static void find_gconf_key (gpointer key, gpointer value, gpointer user_data);
00075 static void write_properties_stringhash (gpointer key, gpointer value, gpointer user_data);
00076 static void on_value_changed (GConfClient *client, const gchar* key, GConfValue* value);
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 void ergconf_initialize()
00089 {
00090 if (client == NULL)
00091 {
00092 client = gconf_client_get_default();
00093 g_signal_connect(G_OBJECT(client), "value-changed", G_CALLBACK(on_value_changed), NULL);
00094 }
00095 }
00096
00097 void ergconf_finalize()
00098 {
00099 if (client)
00100 {
00101 g_object_unref(client);
00102 client = NULL;
00103 }
00104 }
00105
00106 void ergconf_set_cb_value_changed(gconf_cb_value_changed_t callback)
00107 {
00108 g_cb_value_changed = callback;
00109 }
00110
00111 void on_value_changed (GConfClient *client, const gchar* key, GConfValue* value)
00112 {
00113 UNUSED(client);
00114 if (g_cb_value_changed)
00115 {
00116 (*g_cb_value_changed)(key, value);
00117 }
00118 }
00119
00120 void ergconf_add_monitor_dir(const gchar *dir)
00121 {
00122 g_assert(client);
00123 g_assert(dir && *dir == '/');
00124 gconf_client_add_dir(client, dir, GCONF_CLIENT_PRELOAD_NONE, NULL);
00125 }
00126
00127 void ergconf_unset(const gchar* key)
00128 {
00129 g_assert(client);
00130 g_assert(key && *key);
00131 gconf_client_unset(client, key, NULL);
00132 }
00133
00134 void ergconf_recursive_unset(const gchar *dir)
00135 {
00136 g_assert(client);
00137 g_assert(dir && *dir);
00138 gconf_client_recursive_unset (client, dir, 0, NULL);
00139 }
00140
00141 int ergconf_get_int(const gchar* key)
00142 {
00143 g_assert(client);
00144 g_assert(key && *key);
00145 return gconf_client_get_int(client, key, NULL);
00146 }
00147
00148 int ergconf_set_int(const gchar* key, int new_value)
00149 {
00150 gboolean ok;
00151
00152 g_assert(client);
00153 g_assert(key && *key);
00154
00155 ok = gconf_client_set_int(client, key, new_value, NULL);
00156 return (ok ? ER_OK : ER_FAIL);
00157 }
00158
00159 gboolean ergconf_get_bool(const gchar* key)
00160 {
00161 g_assert(client);
00162 g_assert(key && *key);
00163 return gconf_client_get_bool(client, key, NULL);
00164 }
00165
00166 int ergconf_set_bool(const gchar* key, gboolean new_value)
00167 {
00168 gboolean ok;
00169
00170 g_assert(client);
00171 g_assert(key && *key);
00172
00173 ok = gconf_client_set_bool(client, key, new_value, NULL);
00174 return (ok ? ER_OK : ER_FAIL);
00175 }
00176
00177 gchar* ergconf_get_string(const gchar* key)
00178 {
00179 g_assert(client);
00180 g_assert(key && *key);
00181 return gconf_client_get_string(client, key, NULL);
00182 }
00183
00184 int ergconf_set_string(const gchar* key, const gchar* new_value)
00185 {
00186 gboolean ok;
00187
00188 g_assert(client);
00189 g_assert(key && *key);
00190 g_assert(new_value);
00191
00192 ok = gconf_client_set_string(client, key, new_value, NULL);
00193 return (ok ? ER_OK : ER_FAIL);
00194 }
00195
00196 GSList* ergconf_get_string_list(const gchar* key)
00197 {
00198 g_assert(client);
00199 g_assert(key && *key);
00200 return gconf_client_get_list(client, key, GCONF_VALUE_STRING, NULL);
00201 }
00202
00203 int ergconf_set_string_list(const gchar* key, const GSList *new_value)
00204 {
00205 gboolean ok;
00206
00207 g_assert(client);
00208 g_assert(key && *key);
00209 g_return_val_if_fail (new_value != NULL, FALSE);
00210
00211 ok = gconf_client_set_list ( client,
00212 key,
00213 GCONF_VALUE_STRING,
00214 (GSList*)new_value,
00215 NULL );
00216 return (ok ? ER_OK : ER_FAIL);
00217 }
00218
00219 GByteArray* ergconf_get_byte_array(const gchar* key)
00220 {
00221 g_assert(client);
00222 g_assert(key && *key);
00223
00224 GByteArray *ret = NULL;
00225 GConfValue *gc_value = gconf_client_get (client, key, NULL);
00226 if (gc_value == NULL )
00227 {
00228 return NULL;
00229 }
00230
00231 if (gc_value->type == GCONF_VALUE_LIST &&
00232 gconf_value_get_list_type (gc_value) == GCONF_VALUE_INT)
00233 {
00234 GSList *elt;
00235
00236 ret = g_byte_array_new ();
00237 for (elt = gconf_value_get_list (gc_value); elt != NULL; elt = g_slist_next (elt))
00238 {
00239 int i = gconf_value_get_int ((GConfValue *) elt->data);
00240 guint8 val = (guint8) (i & 0xFF);
00241
00242 if (i < 0 || i > 255)
00243 {
00244 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
00245 "value %d out-of-range for a byte value", i);
00246 g_byte_array_free (ret, TRUE);
00247 ret = NULL;
00248 break;
00249 }
00250
00251 g_byte_array_append (ret, &val, 1);
00252 }
00253 }
00254
00255 if (gc_value != NULL)
00256 {
00257 gconf_value_free (gc_value);
00258 }
00259 return ret;
00260 }
00261
00262 int ergconf_set_byte_array(const gchar* key, const GByteArray *new_value)
00263 {
00264 gboolean ok;
00265 GSList *list = NULL;
00266
00267 g_assert(client);
00268 g_assert(key && *key);
00269
00270 unsigned int i;
00271 for (i = 0; i < new_value->len; i++)
00272 {
00273 list = g_slist_append(list, GINT_TO_POINTER ((int) new_value->data[i]));
00274 }
00275
00276 ok = gconf_client_set_list (client, key, GCONF_VALUE_INT, list, NULL);
00277
00278 g_slist_free (list);
00279 return (ok ? ER_OK : ER_FAIL);
00280 }
00281
00282 GHashTable* ergconf_get_string_hash(const gchar* dir)
00283 {
00284 g_assert(client);
00285 g_assert(dir && *dir);
00286
00287 char *gc_key = NULL;
00288 int prefix_len = strlen (dir);
00289 GSList *iter;
00290 GSList *gconf_entries = gconf_client_all_entries (client, dir, NULL);
00291
00292 if (gconf_entries == NULL)
00293 {
00294 return NULL;
00295 }
00296
00297 GHashTable *ret = g_hash_table_new_full (g_str_hash,
00298 g_str_equal,
00299 (GDestroyNotify) g_free,
00300 (GDestroyNotify) g_free);
00301
00302 for (iter = gconf_entries; iter; iter = iter->next)
00303 {
00304 GConfEntry *entry = (GConfEntry *) iter->data;
00305
00306 gc_key = (char *) gconf_entry_get_key (entry);
00307 gc_key += prefix_len + 1;
00308
00309 const GConfValue *gc_val = gconf_entry_get_value (entry);
00310
00311 if (gc_val)
00312 {
00313 const char *gc_str = gconf_value_get_string (gc_val);
00314
00315 if (gc_str != NULL && strlen (gc_str) > 0)
00316 {
00317 g_hash_table_insert (ret, gconf_unescape_key (gc_key, -1), g_strdup (gc_str));
00318 }
00319 }
00320 gconf_entry_free (entry);
00321 }
00322
00323 g_slist_free (gconf_entries);
00324 return ret;
00325 }
00326
00327 int ergconf_set_string_hash(const gchar* dir, const GHashTable *new_value)
00328 {
00329 GSList *existing = NULL;
00330 GSList *iter;
00331
00332 g_assert(client);
00333 g_assert(dir && *dir);
00334 g_return_val_if_fail(new_value != NULL, FALSE);
00335
00336
00337 existing = gconf_client_all_entries (client, dir, NULL);
00338 for (iter = existing; iter; iter = g_slist_next (iter))
00339 {
00340 GConfEntry *entry = (GConfEntry *) iter->data;
00341 char *basename = g_path_get_basename (entry->key);
00342 FindKeyInfo fk_info = { basename, FALSE };
00343
00344 g_hash_table_foreach ( (GHashTable*)new_value,
00345 find_gconf_key,
00346 &fk_info );
00347
00348
00349
00350 if (fk_info.found == FALSE)
00351 {
00352 ergconf_unset (entry->key);
00353 }
00354
00355 gconf_entry_free (entry);
00356 g_free (basename);
00357 }
00358 g_slist_free (existing);
00359
00360
00361 g_hash_table_foreach ( (GHashTable*)new_value,
00362 write_properties_stringhash,
00363 (gpointer)dir );
00364 return ER_OK;
00365 }
00366
00367 static void find_gconf_key (gpointer key, gpointer value, gpointer user_data)
00368 {
00369 UNUSED(value);
00370 FindKeyInfo *info = (FindKeyInfo *) user_data;
00371
00372 if ( !info->found
00373 && strcmp ((char *) key, info->key) == 0 )
00374 {
00375 info->found = TRUE;
00376 }
00377 }
00378
00379 static void write_properties_stringhash (gpointer key, gpointer value, gpointer user_data)
00380 {
00381 char *esc_key;
00382 char *full_key;
00383 const char *path = (const char*) user_data;
00384 const char *str_value = (const char *) value;
00385
00386 if (str_value && *str_value)
00387 {
00388 esc_key = gconf_escape_key ((char *) key, -1);
00389 full_key = g_strconcat (path, "/", esc_key, NULL);
00390 gconf_client_set_string (client, full_key, (char *) str_value, NULL);
00391 g_free (esc_key);
00392 g_free (full_key);
00393 }
00394 }
00395
00396 GArray* ergconf_get_int_array(const gchar* key)
00397 {
00398 GConfValue *gc_value = NULL;
00399 GArray *ret = NULL;
00400
00401 g_assert(client);
00402 g_assert(key && *key);
00403
00404 gc_value = gconf_client_get (client, key, NULL);
00405 if (gc_value == NULL)
00406 {
00407 return NULL;
00408 }
00409
00410 if (gc_value->type == GCONF_VALUE_LIST
00411 && gconf_value_get_list_type (gc_value) == GCONF_VALUE_INT)
00412 {
00413 GSList *elt;
00414
00415 ret = g_array_new (FALSE, FALSE, sizeof (gint));
00416 for (elt = gconf_value_get_list (gc_value); elt != NULL; elt = g_slist_next (elt))
00417 {
00418 int i = gconf_value_get_int ((GConfValue *) elt->data);
00419 g_array_append_val (ret, i);
00420 }
00421 }
00422
00423 if (gc_value != NULL)
00424 {
00425 gconf_value_free (gc_value);
00426 }
00427 return ret;
00428 }
00429
00430 int ergconf_set_int_array(const gchar* key, const GArray* new_value)
00431 {
00432 gboolean ret = FALSE;
00433 GSList *list = NULL;
00434
00435 g_assert(client);
00436 g_assert(key && *key);
00437 g_return_val_if_fail(new_value != NULL, FALSE);
00438
00439 unsigned int i;
00440 for (i = 0; i < new_value->len; i++)
00441 {
00442 gint val = g_array_index (new_value, gint, i);
00443 list = g_slist_append (list, GINT_TO_POINTER(val));
00444 }
00445
00446 ret = gconf_client_set_list (client, key, GCONF_VALUE_INT, list, NULL);
00447
00448 g_slist_free (list);
00449 return ret == TRUE ? ER_OK : ER_FAIL;
00450 }
00451
00452 GPtrArray* ergconf_get_int_tuples(const gchar* key, guint tuple_len)
00453 {
00454 GConfValue *gc_value = NULL;
00455 GPtrArray *ret = NULL;
00456 GSList *values, *iter;
00457 GArray *tuple = NULL;
00458
00459 g_assert(client);
00460 g_assert(key && *key);
00461 g_return_val_if_fail (tuple_len > 0, FALSE);
00462
00463 if (!(gc_value = gconf_client_get (client, key, NULL)))
00464 {
00465 goto out;
00466 }
00467
00468 if ( (gc_value->type != GCONF_VALUE_LIST)
00469 || (gconf_value_get_list_type (gc_value) != GCONF_VALUE_INT))
00470 {
00471 goto out;
00472 }
00473
00474 values = gconf_value_get_list (gc_value);
00475 if (g_slist_length (values) % tuple_len != 0)
00476 {
00477 g_warning ("%s: %s format invalid; # elements not divisible by %d",
00478 __func__, key, tuple_len);
00479 goto out;
00480 }
00481
00482 ret = g_ptr_array_sized_new (1);
00483 for (iter = values; iter; iter = g_slist_next (iter))
00484 {
00485 int i = gconf_value_get_int ((GConfValue *) iter->data);
00486
00487 if (tuple == NULL)
00488 {
00489 tuple = g_array_sized_new (FALSE, TRUE, sizeof (guint32), tuple_len);
00490 }
00491
00492 g_array_append_val (tuple, i);
00493
00494
00495 if (tuple->len == tuple_len)
00496 {
00497 g_ptr_array_add (ret, tuple);
00498 tuple = NULL;
00499 }
00500 }
00501
00502 out:
00503 if (gc_value)
00504 {
00505 gconf_value_free (gc_value);
00506 }
00507 return ret;
00508 }
00509
00510 int ergconf_set_int_tuples(const gchar* key, const GPtrArray* value, guint tuple_len)
00511 {
00512 GSList *list = NULL;
00513 gboolean ret = FALSE;
00514
00515 g_assert(client);
00516 g_assert(key && *key);
00517 g_return_val_if_fail(value != NULL, FALSE);
00518 g_return_val_if_fail (tuple_len > 0, FALSE);
00519
00520 unsigned int i;
00521 for (i = 0; i < value->len; i++)
00522 {
00523 GArray *tuple = g_ptr_array_index (value, i);
00524
00525 if (tuple->len != tuple_len)
00526 {
00527 g_warning ("%s: invalid IPv4 address/route structure!", __func__);
00528 goto out;
00529 }
00530
00531 unsigned int j;
00532 for (j = 0; j < tuple_len; j++)
00533 {
00534 list = g_slist_append (list, GUINT_TO_POINTER (g_array_index (tuple, guint32, j)));
00535 }
00536 }
00537
00538 ret = gconf_client_set_list (client, key, GCONF_VALUE_INT, list, NULL);
00539
00540 out:
00541 g_slist_free (list);
00542 return ret == TRUE ? ER_OK : ER_FAIL;
00543 }
00544
00545 void ergconf_free_int_tuples(GPtrArray* tuple_list)
00546 {
00547 g_return_if_fail(tuple_list);
00548
00549 unsigned int i;
00550 for (i = 0; i < tuple_list->len; i++)
00551 {
00552 GArray *tuple = g_ptr_array_index (tuple_list, i);
00553 g_array_free(tuple, TRUE);
00554 }
00555 g_ptr_array_free(tuple_list, TRUE);
00556 }
00557
00558 GSList* ergconf_get_sub_dirs(const gchar *dir)
00559 {
00560 g_assert(client);
00561 g_assert(dir && *dir);
00562
00563 GError *err = NULL;
00564 GSList *list = gconf_client_all_dirs(client, dir, &err);
00565
00566 if (err != NULL )
00567 {
00568 g_warning ("Error while reading connection: %s", err->message);
00569 g_error_free (err);
00570 return NULL;
00571 }
00572
00573 return list;
00574 }
00575
00576 void ergconf_free_string_list(GSList* str_list)
00577 {
00578 GSList* p = str_list;
00579
00580 g_assert(client);
00581
00582 while (p)
00583 {
00584 g_free(p->data);
00585 p = p->next;
00586 }
00587
00588 g_slist_free(str_list);
00589 }
00590
00591 gboolean ergconf_dir_exist(const gchar* dir)
00592 {
00593 return gconf_client_dir_exists(client, dir, NULL);
00594 }
00595
00596 gboolean ergconf_is_default(const gchar* key)
00597 {
00598 g_assert(client);
00599 g_assert(key && *key);
00600 GConfEntry *entry = gconf_client_get_entry(client, key, NULL, TRUE, NULL);
00601 return gconf_entry_get_is_default(entry);
00602 }