summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-06-08 19:51:30 +0200
committerThomas Haller <thaller@redhat.com>2016-02-14 11:22:49 +0100
commitaf56b71a9555045cebd956fbfc5e77460de7bcf5 (patch)
treebf274d7eab85ee0943ac0fbd8956df8b0c7934c9
parentafaa27ddbbb7a47ba062d1d58df7186a314f0b47 (diff)
downloadNetworkManager-th/libnm-keyfile-bgo749363.tar.gz
Add support to read/write arbitrary additional flags to a [.meta-data] section of keyfile. This data can be passed-on separate from NMConnection, so that their meaning is entirely up to the reader/writer.
-rw-r--r--libnm-core/nm-keyfile-internal.h2
-rw-r--r--libnm-core/nm-keyfile-reader.c40
-rw-r--r--libnm-core/nm-keyfile-utils.h1
-rw-r--r--libnm-core/nm-keyfile-writer.c19
-rw-r--r--libnm-core/tests/test-keyfile.c54
-rw-r--r--shared/nm-test-utils.h6
-rw-r--r--src/settings/plugins/keyfile/reader.c2
-rw-r--r--src/settings/plugins/keyfile/writer.c2
8 files changed, 119 insertions, 7 deletions
diff --git a/libnm-core/nm-keyfile-internal.h b/libnm-core/nm-keyfile-internal.h
index 7873aa7cdb..655a275665 100644
--- a/libnm-core/nm-keyfile-internal.h
+++ b/libnm-core/nm-keyfile-internal.h
@@ -93,6 +93,7 @@ NMConnection *nm_keyfile_read (GKeyFile *keyfile,
const char *base_dir,
NMKeyfileReadHandler handler,
void *user_data,
+ GHashTable **out_meta_data,
GError **error);
/*********************************************************/
@@ -152,6 +153,7 @@ typedef struct {
GKeyFile *nm_keyfile_write (NMConnection *connection,
+ GHashTable *meta_data,
NMKeyfileWriteHandler handler,
void *user_data,
GError **error);
diff --git a/libnm-core/nm-keyfile-reader.c b/libnm-core/nm-keyfile-reader.c
index 1e972cf4f3..0a5818380e 100644
--- a/libnm-core/nm-keyfile-reader.c
+++ b/libnm-core/nm-keyfile-reader.c
@@ -1551,6 +1551,34 @@ read_vpn_secrets (KeyfileReaderInfo *info, NMSettingVpn *s_vpn)
g_strfreev (keys);
}
+static GHashTable *
+read_meta_data (GKeyFile *keyfile)
+{
+ char **keys;
+ GHashTable *meta_data;
+ guint k;
+
+ meta_data = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+ keys = g_key_file_get_keys (keyfile, NM_KEYFILE_GROUP_META_DATA, NULL, NULL);
+ for (k = 0; keys && keys[k]; k++) {
+ char *value;
+
+ value = g_key_file_get_string (keyfile, NM_KEYFILE_GROUP_META_DATA, keys[k], NULL);
+ if (value)
+ g_hash_table_insert (meta_data, keys[k], value);
+ else
+ g_free (keys[k]);
+ }
+ g_free (keys);
+
+ if (g_hash_table_size (meta_data) == 0) {
+ g_hash_table_unref (meta_data);
+ return NULL;
+ }
+ return meta_data;
+}
+
/**
* nm_keyfile_read:
* @keyfile: the keyfile from which to create the connection
@@ -1567,6 +1595,8 @@ read_vpn_secrets (KeyfileReaderInfo *info, NMSettingVpn *s_vpn)
* (if it is given as absolute path). As last, fallback to the current path.
* @handler: read handler
* @user_data: user data for read handler
+ * @out_meta_data: (transfer-full): (allow-none): returns a hash table with
+ * meta data.
* @error: error
*
* Tries to create a NMConnection from a keyfile. The resulting keyfile is
@@ -1580,6 +1610,7 @@ nm_keyfile_read (GKeyFile *keyfile,
const char *base_dir,
NMKeyfileReadHandler handler,
void *user_data,
+ GHashTable **out_meta_data,
GError **error)
{
NMConnection *connection = NULL;
@@ -1591,6 +1622,7 @@ nm_keyfile_read (GKeyFile *keyfile,
gboolean vpn_secrets = FALSE;
KeyfileReaderInfo info = { 0 };
gs_free char *base_dir_free = NULL;
+ gboolean has_meta_data = TRUE;
g_return_val_if_fail (keyfile, NULL);
g_return_val_if_fail (!error || !*error, NULL);
@@ -1624,6 +1656,10 @@ nm_keyfile_read (GKeyFile *keyfile,
vpn_secrets = TRUE;
continue;
}
+ if (!strcmp (groups[i], NM_KEYFILE_GROUP_META_DATA)) {
+ has_meta_data = TRUE;
+ continue;
+ }
info.group = groups[i];
setting = read_setting (&info);
@@ -1702,8 +1738,12 @@ nm_keyfile_read (GKeyFile *keyfile,
}
}
+ if (out_meta_data)
+ *out_meta_data = has_meta_data ? read_meta_data (keyfile) : NULL;
return connection;
out_error:
+ if (out_meta_data)
+ *out_meta_data = NULL;
g_propagate_error (error, info.error);
g_free (connection);
return NULL;
diff --git a/libnm-core/nm-keyfile-utils.h b/libnm-core/nm-keyfile-utils.h
index faa027db3f..ede85ec6f8 100644
--- a/libnm-core/nm-keyfile-utils.h
+++ b/libnm-core/nm-keyfile-utils.h
@@ -24,6 +24,7 @@
#include <glib.h>
#define NM_KEYFILE_GROUP_VPN_SECRETS "vpn-secrets"
+#define NM_KEYFILE_GROUP_META_DATA ".meta-data"
const char *nm_keyfile_plugin_get_alias_for_setting_name (const char *setting_name);
diff --git a/libnm-core/nm-keyfile-writer.c b/libnm-core/nm-keyfile-writer.c
index b794079ff3..212cbed201 100644
--- a/libnm-core/nm-keyfile-writer.c
+++ b/libnm-core/nm-keyfile-writer.c
@@ -747,8 +747,24 @@ write_setting_value (NMSetting *setting,
g_warn_if_reached ();
}
+static void
+write_meta_data (GKeyFile *keyfile, GHashTable *meta_data)
+{
+ GHashTableIter iter;
+ const char *key, *value;
+
+ if (!meta_data || g_hash_table_size (meta_data) == 0)
+ return;
+ g_hash_table_iter_init (&iter, meta_data);
+ while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value)) {
+ if (key && *key && value)
+ g_key_file_set_string (keyfile, NM_KEYFILE_GROUP_META_DATA, key, value);
+ }
+}
+
GKeyFile *
nm_keyfile_write (NMConnection *connection,
+ GHashTable *meta_data,
NMKeyfileWriteHandler handler,
void *user_data,
GError **error)
@@ -773,6 +789,9 @@ nm_keyfile_write (NMConnection *connection,
g_key_file_unref (info.keyfile);
return NULL;
}
+
+ write_meta_data (info.keyfile, meta_data);
+
return info.keyfile;
}
diff --git a/libnm-core/tests/test-keyfile.c b/libnm-core/tests/test-keyfile.c
index d6ba8d4bc8..10905cdae0 100644
--- a/libnm-core/tests/test-keyfile.c
+++ b/libnm-core/tests/test-keyfile.c
@@ -91,7 +91,7 @@ _nm_keyfile_write (NMConnection *connection,
g_assert (NM_IS_CONNECTION (connection));
- kf = nm_keyfile_write (connection, handler, user_data, &error);
+ kf = nm_keyfile_write (connection, NULL, handler, user_data, &error);
g_assert_no_error (error);
g_assert (kf);
return kf;
@@ -110,7 +110,7 @@ _nm_keyfile_read (GKeyFile *keyfile,
g_assert (keyfile);
- con = nm_keyfile_read (keyfile, keyfile_name, base_dir, read_handler, read_data, &error);
+ con = nm_keyfile_read (keyfile, keyfile_name, base_dir, read_handler, read_data, NULL, &error);
g_assert_no_error (error);
g_assert (NM_IS_CONNECTION (con));
if (needs_normalization)
@@ -520,6 +520,55 @@ test_8021x_cert_read (void)
/******************************************************************************/
+static void
+test_meta_data ()
+{
+ GKeyFile *keyfile;
+ NMConnection *con;
+ GHashTable *meta_data;
+ GError *error = NULL;
+ char *value;
+
+ keyfile = _keyfile_load_from_data (
+ "[connection]\n"
+ "type=ethernet\n"
+ "[.meta-data]\n"
+ "key1=value1\n"
+ "key2=value2\n"
+ );
+ con = nm_keyfile_read (keyfile, "/test/meta-data/1", "somewhere/", NULL, NULL, &meta_data, &error);
+ g_assert (con);
+ g_assert_no_error (error);
+ g_assert (meta_data);
+ g_assert_cmpstr (g_hash_table_lookup (meta_data, "key1"), ==, "value1");
+ g_assert_cmpstr (g_hash_table_lookup (meta_data, "key2"), ==, "value2");
+ g_assert_cmpstr (g_hash_table_lookup (meta_data, "key3"), ==, NULL);
+ g_key_file_unref (keyfile);
+
+ nmtst_assert_connection_verifies_after_normalization (con, 0, 0);
+
+ keyfile = nm_keyfile_write (con, meta_data, NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (keyfile);
+
+ value = g_key_file_get_string (keyfile, NM_KEYFILE_GROUP_META_DATA, "key1", NULL);
+ g_assert_cmpstr (value, ==, "value1");
+ g_free (value);
+
+ value = g_key_file_get_string (keyfile, NM_KEYFILE_GROUP_META_DATA, "key2", NULL);
+ g_assert_cmpstr (value, ==, "value2");
+ g_free (value);
+
+ value = g_key_file_get_string (keyfile, NM_KEYFILE_GROUP_META_DATA, "key3", NULL);
+ g_assert (!value);
+
+ g_hash_table_unref (meta_data);
+ g_key_file_unref (keyfile);
+ g_object_unref (con);
+}
+
+/******************************************************************************/
+
NMTST_DEFINE ();
int main (int argc, char **argv)
@@ -528,6 +577,7 @@ int main (int argc, char **argv)
g_test_add_func ("/core/keyfile/test_8021x_cert", test_8021x_cert);
g_test_add_func ("/core/keyfile/test_8021x_cert_read", test_8021x_cert_read);
+ g_test_add_func ("/core/keyfile/test_meta_data", test_meta_data);
return g_test_run ();
}
diff --git a/shared/nm-test-utils.h b/shared/nm-test-utils.h
index b49e49f461..8e2d3c13ab 100644
--- a/shared/nm-test-utils.h
+++ b/shared/nm-test-utils.h
@@ -1537,8 +1537,8 @@ nmtst_assert_connection_equals (NMConnection *a, gboolean normalize_a, NMConnect
gs_unref_keyfile GKeyFile *kf_a = NULL, *kf_b = NULL;
gs_free char *str_a = NULL, *str_b = NULL;
- kf_a = nm_keyfile_write (a, NULL, NULL, NULL);
- kf_b = nm_keyfile_write (b, NULL, NULL, NULL);
+ kf_a = nm_keyfile_write (a, NULL, NULL, NULL, NULL);
+ kf_b = nm_keyfile_write (b, NULL, NULL, NULL, NULL);
if (kf_a)
str_a = g_key_file_to_data (kf_a, NULL, NULL);
@@ -1748,7 +1748,7 @@ nmtst_create_connection_from_keyfile (const char *keyfile_str, const char *keyfi
g_assert_no_error (error);
g_assert (success);
- con = nm_keyfile_read (keyfile, keyfile_name, base_dir, NULL, NULL, &error);
+ con = nm_keyfile_read (keyfile, keyfile_name, base_dir, NULL, NULL, NULL, &error);
g_assert_no_error (error);
g_assert (NM_IS_CONNECTION (con));
diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c
index 1c984a16d4..93d6a236ae 100644
--- a/src/settings/plugins/keyfile/reader.c
+++ b/src/settings/plugins/keyfile/reader.c
@@ -120,7 +120,7 @@ nm_keyfile_plugin_connection_from_file (const char *filename, GError **error)
if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error))
goto out;
- connection = nm_keyfile_read (key_file, filename, NULL, _handler_read, NULL, error);
+ connection = nm_keyfile_read (key_file, filename, NULL, _handler_read, NULL, NULL, error);
if (!connection)
goto out;
diff --git a/src/settings/plugins/keyfile/writer.c b/src/settings/plugins/keyfile/writer.c
index d03aba8ae6..1f4df23159 100644
--- a/src/settings/plugins/keyfile/writer.c
+++ b/src/settings/plugins/keyfile/writer.c
@@ -249,7 +249,7 @@ _internal_write_connection (NMConnection *connection,
info.keyfile_dir = keyfile_dir;
- key_file = nm_keyfile_write (connection, _handler_write, &info, error);
+ key_file = nm_keyfile_write (connection, NULL, _handler_write, &info, error);
if (!key_file)
return FALSE;
data = g_key_file_to_data (key_file, &len, error);