1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /* NetworkManager system settings service
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 * (C) Copyright 2010 Red Hat, Inc.
21 #include "nm-default.h"
26 #include "nm-keyfile-utils.h"
27 #include "nm-keyfile-internal.h"
28 #include "nm-setting-wired.h"
29 #include "nm-setting-wireless.h"
30 #include "nm-setting-wireless-security.h"
37 static const SettingAlias alias_list[] = {
38 { NM_SETTING_WIRED_SETTING_NAME, "ethernet" },
39 { NM_SETTING_WIRELESS_SETTING_NAME, "wifi" },
40 { NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, "wifi-security" },
44 nm_keyfile_plugin_get_alias_for_setting_name (const char *setting_name)
48 g_return_val_if_fail (setting_name != NULL, NULL);
50 for (i = 0; i < G_N_ELEMENTS (alias_list); i++) {
51 if (strcmp (setting_name, alias_list[i].setting) == 0)
52 return alias_list[i].alias;
58 nm_keyfile_plugin_get_setting_name_for_alias (const char *alias)
62 g_return_val_if_fail (alias != NULL, NULL);
64 for (i = 0; i < G_N_ELEMENTS (alias_list); i++) {
65 if (strcmp (alias, alias_list[i].alias) == 0)
66 return alias_list[i].setting;
71 /**********************************************************************/
74 #define DEFINE_KF_LIST_WRAPPER(stype, get_ctype, set_ctype) \
76 nm_keyfile_plugin_kf_get_##stype##_list (GKeyFile *kf, \
84 GError *local = NULL; \
86 list = g_key_file_get_##stype##_list (kf, group, key, out_length, &local); \
87 if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \
88 alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \
90 g_clear_error (&local); \
91 list = g_key_file_get_##stype##_list (kf, alias, key, out_length, &local); \
95 g_propagate_error (error, local); \
100 nm_keyfile_plugin_kf_set_##stype##_list (GKeyFile *kf, \
108 alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \
109 g_key_file_set_##stype##_list (kf, alias ? alias : group, key, list, length); \
112 DEFINE_KF_LIST_WRAPPER(integer, gint*, gint);
113 DEFINE_KF_LIST_WRAPPER(string, gchar **, const gchar* const);
115 /* Single value helpers */
116 #define DEFINE_KF_WRAPPER(stype, get_ctype, set_ctype) \
118 nm_keyfile_plugin_kf_get_##stype (GKeyFile *kf, \
125 GError *local = NULL; \
127 val = g_key_file_get_##stype (kf, group, key, &local); \
128 if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) { \
129 alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \
131 g_clear_error (&local); \
132 val = g_key_file_get_##stype (kf, alias, key, &local); \
136 g_propagate_error (error, local); \
141 nm_keyfile_plugin_kf_set_##stype (GKeyFile *kf, \
148 alias = nm_keyfile_plugin_get_alias_for_setting_name (group); \
149 g_key_file_set_##stype (kf, alias ? alias : group, key, value); \
152 DEFINE_KF_WRAPPER(string, gchar*, const gchar*);
153 DEFINE_KF_WRAPPER(integer, gint, gint);
154 DEFINE_KF_WRAPPER(uint64, guint64, guint64);
155 DEFINE_KF_WRAPPER(boolean, gboolean, gboolean);
156 DEFINE_KF_WRAPPER(value, gchar*, const gchar*);
160 nm_keyfile_plugin_kf_get_keys (GKeyFile *kf,
167 GError *local = NULL;
169 keys = g_key_file_get_keys (kf, group, out_length, &local);
170 if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
171 alias = nm_keyfile_plugin_get_alias_for_setting_name (group);
173 g_clear_error (&local);
174 keys = g_key_file_get_keys (kf, alias, out_length, &local);
178 g_propagate_error (error, local);
183 nm_keyfile_plugin_kf_has_key (GKeyFile *kf,
190 GError *local = NULL;
192 has = g_key_file_has_key (kf, group, key, &local);
193 if (g_error_matches (local, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND)) {
194 alias = nm_keyfile_plugin_get_alias_for_setting_name (group);
196 g_clear_error (&local);
197 has = g_key_file_has_key (kf, alias, key, &local);
201 g_propagate_error (error, local);
205 /************************************************************************/
208 _nm_keyfile_copy (GKeyFile *dst, GKeyFile *src)
210 gs_strfreev char **groups = NULL;
213 groups = g_key_file_get_groups (src, NULL);
214 for (g = 0; groups && groups[g]; g++) {
215 const char *group = groups[g];
216 gs_strfreev char **keys = NULL;
218 keys = g_key_file_get_keys (src, group, NULL, NULL);
222 for (k = 0; keys[k]; k++) {
223 const char *key = keys[k];
224 gs_free char *value = NULL;
226 value = g_key_file_get_value (src, group, key, NULL);
228 g_key_file_set_value (dst, group, key, value);
230 g_key_file_remove_key (dst, group, key, NULL);
235 /************************************************************************/
238 _nm_keyfile_a_contains_all_in_b (GKeyFile *kf_a, GKeyFile *kf_b)
240 gs_strfreev char **groups = NULL;
248 groups = g_key_file_get_groups (kf_a, NULL);
249 for (i = 0; groups && groups[i]; i++) {
250 gs_strfreev char **keys = NULL;
252 keys = g_key_file_get_keys (kf_a, groups[i], NULL, NULL);
256 for (j = 0; keys[j]; j++) {
257 gs_free char *key_a = g_key_file_get_value (kf_a, groups[i], keys[j], NULL);
258 gs_free char *key_b = g_key_file_get_value (kf_b, groups[i], keys[j], NULL);
260 if (g_strcmp0 (key_a, key_b) != 0)
269 _nm_keyfile_equals_ordered (GKeyFile *kf_a, GKeyFile *kf_b)
271 gs_strfreev char **groups = NULL;
272 gs_strfreev char **groups_b = NULL;
280 groups = g_key_file_get_groups (kf_a, NULL);
281 groups_b = g_key_file_get_groups (kf_b, NULL);
282 if (!groups && !groups_b)
284 if (!groups || !groups_b)
286 for (i = 0; groups[i] && groups_b[i] && !strcmp (groups[i], groups_b[i]); i++)
288 if (groups[i] || groups_b[i])
291 for (i = 0; groups[i]; i++) {
292 gs_strfreev char **keys = NULL;
293 gs_strfreev char **keys_b = NULL;
295 keys = g_key_file_get_keys (kf_a, groups[i], NULL, NULL);
296 keys_b = g_key_file_get_keys (kf_b, groups[i], NULL, NULL);
298 if ((!keys) != (!keys_b))
303 for (j = 0; keys[j] && keys_b[j] && !strcmp (keys[j], keys_b[j]); j++)
305 if (keys[j] || keys_b[j])
308 for (j = 0; keys[j]; j++) {
309 gs_free char *key_a = g_key_file_get_value (kf_a, groups[i], keys[j], NULL);
310 gs_free char *key_b = g_key_file_get_value (kf_b, groups[i], keys[j], NULL);
312 if (g_strcmp0 (key_a, key_b) != 0)
320 _nm_keyfile_equals (GKeyFile *kf_a, GKeyFile *kf_b, gboolean consider_order)
322 if (!consider_order) {
323 return _nm_keyfile_a_contains_all_in_b (kf_a, kf_b)
324 && _nm_keyfile_a_contains_all_in_b (kf_b, kf_a);
326 return _nm_keyfile_equals_ordered (kf_a, kf_b);
331 _nm_keyfile_has_values (GKeyFile *keyfile)
333 gs_strfreev char **groups = NULL;
335 g_return_val_if_fail (keyfile, FALSE);
337 groups = g_key_file_get_groups (keyfile, NULL);
338 return groups && groups[0];