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
This commit is contained in:
Dan Williams 2008-05-08 01:02:42 +00:00
parent 16877b0672
commit 9559a7a260
3 changed files with 261 additions and 53 deletions

View file

@ -1,3 +1,18 @@
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

View file

@ -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));

View file

@ -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