summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2008-05-08 01:02:42 +0000
committerDan Williams <dcbw@redhat.com>2008-05-08 01:02:42 +0000
commit9559a7a26021efa7ef49681b93a3b3bd4eadcef6 (patch)
treebd4ecb888fd9d8681b5b6e8ddc5dfe15fe59e8c4
parent16877b06721c53d42e5d342d684bf3e42a994479 (diff)
2008-05-07 Dan Williams <dcbw@redhat.com>
* system-settings/plugins/keyfile/reader.c - (read_one_setting_value): handle IP address items separately - (read_array_of_uint): read IPv4 DNS option as a string array - (read_array_of_array_of_uint): read IPv4 address tuples as a string array * system-settings/plugins/keyfile/writer.c - (write_setting_value): handle IP address items separately - (write_array_of_uint): handle IPv4 DNS option as a string array, not an array of uint, so that it's user-editable - (write_array_of_array_of_uint): handle IPv4 address tuples as string arrays, so they are user-editable git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3643 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
-rw-r--r--ChangeLog15
-rw-r--r--system-settings/plugins/keyfile/reader.c160
-rw-r--r--system-settings/plugins/keyfile/writer.c139
3 files changed, 261 insertions, 53 deletions
diff --git a/ChangeLog b/ChangeLog
index fe8f5c373..21da44ff2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2008-05-07 Dan Williams <dcbw@redhat.com>
+ * system-settings/plugins/keyfile/reader.c
+ - (read_one_setting_value): handle IP address items separately
+ - (read_array_of_uint): read IPv4 DNS option as a string array
+ - (read_array_of_array_of_uint): read IPv4 address tuples as a string
+ array
+
+ * system-settings/plugins/keyfile/writer.c
+ - (write_setting_value): handle IP address items separately
+ - (write_array_of_uint): handle IPv4 DNS option as a string array,
+ not an array of uint, so that it's user-editable
+ - (write_array_of_array_of_uint): handle IPv4 address tuples as string
+ arrays, so they are user-editable
+
+2008-05-07 Dan Williams <dcbw@redhat.com>
+
* system-settings/plugins/keyfile/Makefile.am
- Change location of the keyfile plugin settings to
/etc/NetworkManager/system-connections
diff --git a/system-settings/plugins/keyfile/reader.c b/system-settings/plugins/keyfile/reader.c
index 05cc73a00..5c59bb23b 100644
--- a/system-settings/plugins/keyfile/reader.c
+++ b/system-settings/plugins/keyfile/reader.c
@@ -5,11 +5,133 @@
#include <sys/types.h>
#include <dbus/dbus-glib.h>
#include <nm-setting.h>
+#include <nm-setting-ip4-config.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include "nm-dbus-glib-types.h"
#include "reader.h"
-#define DBUS_TYPE_G_ARRAY_OF_UINT (dbus_g_type_get_collection ("GArray", G_TYPE_UINT))
-#define DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_ARRAY_OF_UINT))
+static gboolean
+read_array_of_uint (GKeyFile *file,
+ NMSetting *setting,
+ const char *key)
+{
+ GArray *array = NULL;
+ gsize length;
+ int i;
+
+ if (NM_IS_SETTING_IP4_CONFIG (setting) && !strcmp (key, NM_SETTING_IP4_CONFIG_DNS)) {
+ char **list, **iter;
+ int ret;
+
+ list = g_key_file_get_string_list (file, setting->name, key, &length, NULL);
+ if (!list || !g_strv_length (list))
+ return TRUE;
+
+ array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length);
+ for (iter = list; *iter; iter++) {
+ struct in_addr addr;
+
+ ret = inet_pton (AF_INET, *iter, &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid DNS server address '%s'", __func__, *iter);
+ continue;
+ }
+
+ g_array_append_val (array, addr.s_addr);
+ }
+ } else {
+ gint *tmp;
+
+ tmp = g_key_file_get_integer_list (file, setting->name, key, &length, NULL);
+
+ array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length);
+ for (i = 0; i < length; i++)
+ g_array_append_val (array, tmp[i]);
+ }
+
+ if (array) {
+ g_object_set (setting, key, array, NULL);
+ g_array_free (array, TRUE);
+ }
+
+ return TRUE;
+}
+
+static void
+free_one_address (gpointer data, gpointer user_data)
+{
+ g_array_free ((GArray *) data, TRUE);
+}
+
+static gboolean
+read_array_of_array_of_uint (GKeyFile *file,
+ NMSetting *setting,
+ const char *key)
+{
+ GPtrArray *addresses;
+ int i = 0;
+
+ /* Only handle IPv4 addresses for now */
+ if ( !NM_IS_SETTING_IP4_CONFIG (setting)
+ || strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES))
+ return FALSE;
+
+ addresses = g_ptr_array_sized_new (3);
+
+ /* Look for individual addresses */
+ while (i++ < 1000) {
+ gchar **tmp, **iter;
+ char *key_name;
+ gsize length = 0;
+ int ret;
+ GArray *address;
+ guint32 empty = 0;
+
+ key_name = g_strdup_printf ("address%d", i);
+ tmp = g_key_file_get_string_list (file, setting->name, key_name, &length, NULL);
+ g_free (key_name);
+
+ if (!tmp || !length)
+ break; /* all done */
+
+ if ((length < 2) || (length > 3)) {
+ g_warning ("%s: ignoring invalid IPv4 address item '%s'", __func__, key_name);
+ goto next;
+ }
+
+ /* convert the string array into IP addresses */
+ address = g_array_sized_new (FALSE, TRUE, sizeof (guint32), 3);
+ for (iter = tmp; *iter; iter++) {
+ struct in_addr addr;
+
+ ret = inet_pton (AF_INET, *iter, &addr);
+ if (ret <= 0) {
+ g_warning ("%s: ignoring invalid IPv4 %s element '%s'", __func__, key_name, *iter);
+ g_array_free (address, TRUE);
+ goto next;
+ }
+
+ g_array_append_val (address, addr.s_addr);
+ }
+
+ /* fill in blank gateway if not specified */
+ if (address->len == 2)
+ g_array_append_val (address, empty);
+
+ g_ptr_array_add (addresses, address);
+
+next:
+ g_strfreev (tmp);
+ }
+
+ g_object_set (setting, key, addresses, NULL);
+
+ g_ptr_array_foreach (addresses, free_one_address, NULL);
+ g_ptr_array_free (addresses, TRUE);
+ return TRUE;
+}
static void
read_one_setting_value (NMSetting *setting,
@@ -21,8 +143,17 @@ read_one_setting_value (NMSetting *setting,
GKeyFile *file = (GKeyFile *) user_data;
GType type;
GError *err = NULL;
+ gboolean check_for_key = TRUE;
- if (!g_key_file_has_key (file, setting->name, key, &err)) {
+ /* Setting name gets picked up from the keyfile's section name instead */
+ if (!strcmp (key, NM_SETTING_NAME))
+ return;
+
+ /* IPv4 addresses don't have the exact key name */
+ if (NM_IS_SETTING_IP4_CONFIG (setting) && !strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES))
+ check_for_key = FALSE;
+
+ if (check_for_key && !g_key_file_has_key (file, setting->name, key, &err)) {
if (err) {
g_warning ("Error loading setting '%s' value: %s", setting->name, err->message);
g_error_free (err);
@@ -111,22 +242,15 @@ read_one_setting_value (NMSetting *setting,
/* FIXME */
g_warning ("Implement me");
} else if (type == DBUS_TYPE_G_UINT_ARRAY) {
- gint *tmp;
- GArray *array;
- gsize length;
- int i;
-
- tmp = g_key_file_get_integer_list (file, setting->name, key, &length, NULL);
-
- array = g_array_sized_new (FALSE, FALSE, sizeof (guint32), length);
- for (i = 0; i < length; i++)
- g_array_append_val (array, tmp[i]);
-
- g_object_set (setting, key, array, NULL);
- g_array_free (array, TRUE);
+ if (!read_array_of_uint (file, setting, key)) {
+ g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
+ setting->name, key, G_VALUE_TYPE_NAME (value));
+ }
} else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT) {
- /* FIXME */
- g_warning ("Implement me");
+ if (!read_array_of_array_of_uint (file, setting, key)) {
+ g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
+ setting->name, key, G_VALUE_TYPE_NAME (value));
+ }
} else {
g_warning ("Unhandled setting property type (read): '%s/%s' : '%s'",
setting->name, key, G_VALUE_TYPE_NAME (value));
diff --git a/system-settings/plugins/keyfile/writer.c b/system-settings/plugins/keyfile/writer.c
index daef9c709..8a994e8af 100644
--- a/system-settings/plugins/keyfile/writer.c
+++ b/system-settings/plugins/keyfile/writer.c
@@ -6,11 +6,101 @@
#include <dbus/dbus-glib.h>
#include <nm-setting.h>
#include <nm-setting-connection.h>
+#include <nm-setting-ip4-config.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include "nm-dbus-glib-types.h"
#include "writer.h"
-#define DBUS_TYPE_G_ARRAY_OF_UINT (dbus_g_type_get_collection ("GArray", G_TYPE_UINT))
-#define DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_ARRAY_OF_UINT))
+static gboolean
+write_array_of_uint (GKeyFile *file,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GArray *array;
+ int i;
+
+ array = (GArray *) g_value_get_boxed (value);
+ if (!array || !array->len)
+ return TRUE;
+
+ if (NM_IS_SETTING_IP4_CONFIG (setting) && !strcmp (key, NM_SETTING_IP4_CONFIG_DNS)) {
+ char **list;
+
+ list = g_new0 (char *, array->len + 1);
+
+ for (i = 0; i < array->len; i++) {
+ char buf[INET_ADDRSTRLEN + 1];
+ struct in_addr addr;
+
+ addr.s_addr = g_array_index (array, guint32, i);
+ list[i] = g_strdup (inet_ntop (AF_INET, &addr, buf, sizeof (buf)));
+ }
+
+ g_key_file_set_string_list (file, setting->name, key, (const char **) list, array->len);
+ g_strfreev (list);
+ } else {
+ int *tmp_array;
+
+ tmp_array = g_new (gint, array->len);
+ for (i = 0; i < array->len; i++)
+ tmp_array[i] = g_array_index (array, int, i);
+
+ g_key_file_set_integer_list (file, setting->name, key, tmp_array, array->len);
+ g_free (tmp_array);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+write_array_of_array_of_uint (GKeyFile *file,
+ NMSetting *setting,
+ const char *key,
+ const GValue *value)
+{
+ GPtrArray *array;
+ int i, j;
+
+ /* Only handle IPv4 addresses for now */
+ if ( !NM_IS_SETTING_IP4_CONFIG (setting)
+ || strcmp (key, NM_SETTING_IP4_CONFIG_ADDRESSES))
+ return FALSE;
+
+ array = (GPtrArray *) g_value_get_boxed (value);
+ if (!array || !array->len)
+ return TRUE;
+
+ for (i = 0, j = 0; i < array->len; i++, j++) {
+ GArray *tuple = g_ptr_array_index (array, i);
+ char buf[INET_ADDRSTRLEN + 1];
+ struct in_addr addr;
+ char *list[3] = { NULL, NULL, NULL };
+ char *key_name;
+
+ addr.s_addr = g_array_index (tuple, guint32, 0);
+ list[0] = g_strdup (inet_ntop (AF_INET, &addr, buf, sizeof (buf)));
+
+ addr.s_addr = g_array_index (tuple, guint32, 1);
+ list[1] = g_strdup (inet_ntop (AF_INET, &addr, buf, sizeof (buf)));
+
+ addr.s_addr = g_array_index (tuple, guint32, 2);
+ if (addr.s_addr)
+ list[2] = g_strdup (inet_ntop (AF_INET, &addr, buf, sizeof (buf)));
+
+ key_name = g_strdup_printf ("address%d", j + 1);
+ g_key_file_set_string_list (file, setting->name, key_name, (const char **) list, list[2] ? 3 : 2);
+ g_free (key_name);
+
+ g_free (list[0]);
+ g_free (list[1]);
+ g_free (list[2]);
+ }
+
+ return TRUE;
+}
static void
write_setting_value (NMSetting *setting,
@@ -24,6 +114,10 @@ write_setting_value (NMSetting *setting,
type = G_VALUE_TYPE (value);
+ /* Setting name gets picked up from the keyfile's section name instead */
+ if (!strcmp (key, NM_SETTING_NAME))
+ return;
+
if (type == G_TYPE_STRING) {
const char *str;
@@ -79,44 +173,19 @@ write_setting_value (NMSetting *setting,
/* FIXME */
g_warning ("Implement me");
} else if (type == DBUS_TYPE_G_UINT_ARRAY) {
- GArray *array;
-
- array = (GArray *) g_value_get_boxed (value);
- if (array && array->len > 0) {
- int *tmp_array;
- int i;
-
- tmp_array = g_new (gint, array->len);
- for (i = 0; i < array->len; i++)
- tmp_array[i] = (int) array->data[i];
-
- g_key_file_set_integer_list (file, setting->name, key, tmp_array, array->len);
- g_free (tmp_array);
+ if (!write_array_of_uint (file, setting, key, value)) {
+ g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'",
+ setting->name, key, g_type_name (type));
}
} else if (type == DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT) {
- GPtrArray *array;
-
- array = (GPtrArray *) g_value_get_boxed (value);
- if (array && array->len > 0) {
- int i, j;
- int* list;
-
- list = g_new (int, array->len * 3);
-
- for (i = 0, j = 0; i < array->len; i++) {
- GArray *tuple = g_ptr_array_index (array, i);
-
- list[j++] = g_array_index (tuple, guint32, 0);
- list[j++] = g_array_index (tuple, guint32, 1);
- list[j++] = tuple->len == 3 ? g_array_index (tuple, guint32, 2) : 0;
- }
-
- g_key_file_set_integer_list (file, setting->name, key, list, j);
- g_free (list);
+ if (!write_array_of_array_of_uint (file, setting, key, value)) {
+ g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'",
+ setting->name, key, g_type_name (type));
}
- } else
+ } else {
g_warning ("Unhandled setting property type (write) '%s/%s' : '%s'",
setting->name, key, g_type_name (type));
+ }
}
gboolean