2 * Copyright © 2010 Codethink Limited
3 * Copyright © 2012 Canonical Limited
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the licence, 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 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 * Author: Ryan Lortie <desrt@desrt.ca>
23 #include "dconf-gvdb-utils.h"
25 #include "../common/dconf-paths.h"
26 #include "../gvdb/gvdb-builder.h"
27 #include "../gvdb/gvdb-reader.h"
32 dconf_gvdb_utils_read_file (const gchar
*filename
,
33 gboolean
*file_missing
,
36 DConfChangeset
*database
;
37 GError
*my_error
= NULL
;
38 GvdbTable
*table
= NULL
;
42 if (g_file_get_contents (filename
, &contents
, &size
, &my_error
))
46 bytes
= g_bytes_new_take (contents
, size
);
47 table
= gvdb_table_new_from_bytes (bytes
, FALSE
, &my_error
);
48 g_bytes_unref (bytes
);
51 /* It is perfectly fine if the file does not exist -- then it's
54 if (g_error_matches (my_error
, G_FILE_ERROR
, G_FILE_ERROR_NOENT
))
55 g_clear_error (&my_error
);
57 /* Otherwise, we should report errors to prevent ourselves from
58 * overwriting the database in other situations...
62 g_propagate_prefixed_error (error
, my_error
, "Cannot open dconf database: ");
66 /* Only allocate once we know we are in a non-error situation */
67 database
= dconf_changeset_new_database (NULL
);
69 /* Fill the table up with the initial state */
76 names
= gvdb_table_get_names (table
, &n_names
);
77 for (i
= 0; i
< n_names
; i
++)
79 if (dconf_is_key (names
[i
], NULL
))
83 value
= gvdb_table_get_value (table
, names
[i
]);
87 dconf_changeset_set (database
, names
[i
], value
);
88 g_variant_unref (value
);
95 gvdb_table_free (table
);
100 *file_missing
= (table
== NULL
);
106 dconf_gvdb_utils_get_parent (GHashTable
*table
,
109 GvdbItem
*grandparent
, *parent
;
113 if (g_str_equal (key
, "/"))
117 if (key
[len
- 1] == '/')
120 while (key
[len
- 1] != '/')
123 parent_name
= g_strndup (key
, len
);
124 parent
= g_hash_table_lookup (table
, parent_name
);
128 parent
= gvdb_hash_table_insert (table
, parent_name
);
130 grandparent
= dconf_gvdb_utils_get_parent (table
, parent_name
);
132 if (grandparent
!= NULL
)
133 gvdb_item_set_parent (parent
, grandparent
);
136 g_free (parent_name
);
142 dconf_gvdb_utils_add_key (const gchar
*path
,
146 GHashTable
*gvdb
= user_data
;
149 g_assert (g_hash_table_lookup (gvdb
, path
) == NULL
);
150 item
= gvdb_hash_table_insert (gvdb
, path
);
151 gvdb_item_set_parent (item
, dconf_gvdb_utils_get_parent (gvdb
, path
));
152 gvdb_item_set_value (item
, value
);
158 dconf_gvdb_utils_write_file (const gchar
*filename
,
159 DConfChangeset
*database
,
165 gvdb
= gvdb_hash_table_new (NULL
, NULL
);
166 dconf_changeset_all (database
, dconf_gvdb_utils_add_key
, gvdb
);
167 success
= gvdb_table_write_contents (gvdb
, filename
, FALSE
, error
);
173 /* Maybe it failed because the directory doesn't exist. Try
174 * again, after mkdir().
176 dirname
= g_path_get_dirname (filename
);
177 g_mkdir_with_parents (dirname
, 0700);
180 g_clear_error (error
);
181 success
= gvdb_table_write_contents (gvdb
, filename
, FALSE
, error
);
184 g_hash_table_unref (gvdb
);