gconf_utils.c

Go to the documentation of this file.
00001 /**
00002  * \file gconf_utils.c
00003  * \brief A lightweight wrapper for gconf library.
00004  */
00005 
00006 /*
00007  * This file is part of liberutils.
00008  *
00009  * liberutils is free software: you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation, either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * liberutils is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00021  */
00022 
00023 /**
00024  * Copyright (C) 2009 iRex Technologies B.V.
00025  * All rights reserved.
00026  */
00027 
00028 //----------------------------------------------------------------------------
00029 // Include Files
00030 //----------------------------------------------------------------------------
00031 
00032 // system include files, between < >
00033 
00034 #include <string.h>
00035 #include <gconf/gconf-client.h>
00036 
00037 // ereader library include files, between < >
00038 
00039 #include "er_error.h"
00040 
00041 // local include files, between " "
00042 #include "log.h"
00043 #include "gconf_utils.h"
00044 
00045 #define UNUSED(x) (void)(x)
00046 
00047 
00048 //----------------------------------------------------------------------------
00049 // Type Declarations
00050 //----------------------------------------------------------------------------
00051 
00052 typedef struct
00053 {
00054     const char *key;
00055     gboolean found;
00056 } FindKeyInfo;
00057 
00058 //----------------------------------------------------------------------------
00059 // Constants
00060 //----------------------------------------------------------------------------
00061 
00062 
00063 //----------------------------------------------------------------------------
00064 // Static Variables
00065 //----------------------------------------------------------------------------
00066 
00067 static GConfClient*             client             = NULL;
00068 static gconf_cb_value_changed_t g_cb_value_changed = NULL;
00069 
00070 //============================================================================
00071 // Local Function Definitions
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 // implementation of virtual methods
00079 
00080 
00081 // signal handlers
00082 
00083 
00084 //============================================================================
00085 // Functions Implementation
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,  // const_cast
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;  // exit for loop
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; /* get rid of the full path */
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     /* Delete GConf entries that are not in the hash table to be written */
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,  // const_cast
00345                                find_gconf_key,
00346                                &fk_info );
00347         //TODO: Why not use g_hash_table_lookup_extended() here ??
00348         //TODO  Seems we don't need FindKeyInfo and find_gconf_key then.
00349         /* Be sure to never delete "special" VPN keys */
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     /* Now update entries and write new ones */
00361     g_hash_table_foreach ( (GHashTable*)new_value,  // const_cast
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         /* Got all members; add to the array */
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 }
Generated by  doxygen 1.6.2-20100208