libnm-glib: handle NULL object paths generically

Since D-Bus doesn't allow NULL or zero-length object paths, NM
uses "/" as a placeholder here.  Make sure the generic marshalling
code handles that so we don't have to do it in multiple places and
simplify handling of NULL objects somewhat.
This commit is contained in:
Dan Williams 2011-05-26 18:25:55 -05:00
parent 459e7b9518
commit 8afce8590a
4 changed files with 101 additions and 85 deletions

View file

@ -55,7 +55,7 @@ typedef struct {
NM80211Mode mode;
guint32 rate;
NMAccessPoint *active_ap;
gboolean null_active_ap;
gboolean got_active_ap;
NMDeviceWifiCapabilities wireless_caps;
GPtrArray *aps;
@ -271,6 +271,7 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
NMDeviceState state;
char *path;
GValue value = { 0, };
GError *error = NULL;
g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
@ -291,21 +292,20 @@ nm_device_wifi_get_active_access_point (NMDeviceWifi *device)
}
priv = NM_DEVICE_WIFI_GET_PRIVATE (device);
if (priv->active_ap)
if (priv->got_active_ap == TRUE)
return priv->active_ap;
if (priv->null_active_ap)
return NULL;
path = _nm_object_get_object_path_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
DBUS_PROP_ACTIVE_ACCESS_POINT,
NULL);
if (path) {
NM_DBUS_INTERFACE_DEVICE_WIRELESS,
DBUS_PROP_ACTIVE_ACCESS_POINT,
&error);
if (error == NULL) {
g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
g_value_take_boxed (&value, path);
demarshal_active_ap (NM_OBJECT (device), NULL, &value, &priv->active_ap);
g_value_unset (&value);
}
g_clear_error (&error);
return priv->active_ap;
}
@ -427,9 +427,8 @@ access_point_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
if (ap == priv->active_ap) {
g_object_unref (priv->active_ap);
priv->active_ap = NULL;
priv->null_active_ap = FALSE;
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
priv->rate = 0;
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIFI_BITRATE);
}
@ -620,7 +619,6 @@ state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data)
if (priv->active_ap) {
g_object_unref (priv->active_ap);
priv->active_ap = NULL;
priv->null_active_ap = FALSE;
}
_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT);
priv->rate = 0;
@ -642,13 +640,11 @@ demarshal_active_ap (NMObject *object, GParamSpec *pspec, GValue *value, gpointe
if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
return FALSE;
priv->null_active_ap = FALSE;
priv->got_active_ap = TRUE;
path = g_value_get_boxed (value);
if (path) {
if (!strcmp (path, "/"))
priv->null_active_ap = TRUE;
else {
if (value) {
path = g_value_get_boxed (value);
if (path) {
ap = NM_ACCESS_POINT (_nm_object_cache_get (path));
if (!ap) {
connection = nm_object_get_connection (object);

View file

@ -50,7 +50,7 @@ typedef struct {
char *hw_address;
NMWimaxNsp *active_nsp;
gboolean null_active_nsp;
gboolean got_active_nsp;
GPtrArray *nsps;
guint center_freq;
@ -153,6 +153,7 @@ nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax)
NMDeviceState state;
char *path;
GValue value = { 0, };
GError *error = NULL;
g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL);
@ -173,21 +174,20 @@ nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax)
}
priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax);
if (priv->active_nsp)
if (priv->got_active_nsp == TRUE)
return priv->active_nsp;
if (priv->null_active_nsp)
return NULL;
path = _nm_object_get_object_path_property (NM_OBJECT (wimax),
NM_DBUS_INTERFACE_DEVICE_WIMAX,
DBUS_PROP_ACTIVE_NSP,
NULL);
if (path) {
&error);
if (error == NULL) {
g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
g_value_take_boxed (&value, path);
demarshal_active_nsp (NM_OBJECT (wimax), NULL, &value, &priv->active_nsp);
g_value_unset (&value);
}
g_clear_error (&error);
return priv->active_nsp;
}
@ -309,8 +309,6 @@ nsp_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
if (nsp == priv->active_nsp) {
g_object_unref (priv->active_nsp);
priv->active_nsp = NULL;
priv->null_active_nsp = FALSE;
_nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP);
}
@ -607,7 +605,6 @@ state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data)
if (priv->active_nsp) {
g_object_unref (priv->active_nsp);
priv->active_nsp = NULL;
priv->null_active_nsp = FALSE;
}
_nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIMAX_ACTIVE_NSP);
clear_link_status (self);
@ -634,13 +631,11 @@ demarshal_active_nsp (NMObject *object, GParamSpec *pspec, GValue *value, gpoint
if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
return FALSE;
priv->null_active_nsp = FALSE;
priv->got_active_nsp = TRUE;
path = g_value_get_boxed (value);
if (path) {
if (!strcmp (path, "/"))
priv->null_active_nsp = TRUE;
else {
if (value) {
path = g_value_get_boxed (value);
if (path) {
nsp = NM_WIMAX_NSP (_nm_object_cache_get (path));
if (!nsp) {
connection = nm_object_get_connection (object);

View file

@ -56,13 +56,13 @@ typedef struct {
gboolean managed;
gboolean firmware_missing;
NMIP4Config *ip4_config;
gboolean null_ip4_config;
gboolean got_ip4_config;
NMDHCP4Config *dhcp4_config;
gboolean null_dhcp4_config;
gboolean got_dhcp4_config;
NMIP6Config *ip6_config;
gboolean null_ip6_config;
gboolean got_ip6_config;
NMDHCP6Config *dhcp6_config;
gboolean null_dhcp6_config;
gboolean got_dhcp6_config;
NMDeviceState state;
GUdevClient *client;
@ -119,13 +119,11 @@ demarshal_ip4_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoint
if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
return FALSE;
priv->null_ip4_config = FALSE;
priv->got_ip4_config = TRUE;
path = g_value_get_boxed (value);
if (path) {
if (!strcmp (path, "/"))
priv->null_ip4_config = TRUE;
else {
if (value) {
path = g_value_get_boxed (value);
if (path) {
config = NM_IP4_CONFIG (_nm_object_cache_get (path));
if (!config) {
connection = nm_object_get_connection (object);
@ -157,13 +155,11 @@ demarshal_dhcp4_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoi
if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
return FALSE;
priv->null_dhcp4_config = FALSE;
priv->got_dhcp4_config = TRUE;
path = g_value_get_boxed (value);
if (path) {
if (!strcmp (path, "/"))
priv->null_dhcp4_config = TRUE;
else {
if (value) {
path = g_value_get_boxed (value);
if (path) {
config = NM_DHCP4_CONFIG (_nm_object_cache_get (path));
if (!config) {
connection = nm_object_get_connection (object);
@ -195,13 +191,11 @@ demarshal_ip6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoint
if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
return FALSE;
priv->null_ip6_config = FALSE;
priv->got_ip6_config = TRUE;
path = g_value_get_boxed (value);
if (path) {
if (!strcmp (path, "/"))
priv->null_ip6_config = TRUE;
else {
if (value) {
path = g_value_get_boxed (value);
if (path) {
config = NM_IP6_CONFIG (_nm_object_cache_get (path));
if (!config) {
connection = nm_object_get_connection (object);
@ -233,13 +227,11 @@ demarshal_dhcp6_config (NMObject *object, GParamSpec *pspec, GValue *value, gpoi
if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
return FALSE;
priv->null_dhcp6_config = FALSE;
priv->got_dhcp6_config = TRUE;
path = g_value_get_boxed (value);
if (path) {
if (!strcmp (path, "/"))
priv->null_dhcp6_config = TRUE;
else {
if (value) {
path = g_value_get_boxed (value);
if (path) {
config = NM_DHCP6_CONFIG (_nm_object_cache_get (path));
if (!config) {
connection = nm_object_get_connection (object);
@ -998,22 +990,25 @@ nm_device_get_ip4_config (NMDevice *device)
NMDevicePrivate *priv;
char *path;
GValue value = { 0, };
GError *error = NULL;
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
priv = NM_DEVICE_GET_PRIVATE (device);
if (priv->ip4_config)
if (priv->got_ip4_config == TRUE)
return priv->ip4_config;
if (priv->null_ip4_config)
return NULL;
path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Ip4Config", NULL);
if (path) {
path = _nm_object_get_object_path_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE,
"Ip4Config",
&error);
if (error == NULL) {
g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
g_value_take_boxed (&value, path);
demarshal_ip4_config (NM_OBJECT (device), NULL, &value, &priv->ip4_config);
g_value_unset (&value);
}
g_clear_error (&error);
return priv->ip4_config;
}
@ -1033,22 +1028,25 @@ nm_device_get_dhcp4_config (NMDevice *device)
NMDevicePrivate *priv;
char *path;
GValue value = { 0, };
GError *error = NULL;
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
priv = NM_DEVICE_GET_PRIVATE (device);
if (priv->dhcp4_config)
if (priv->got_dhcp4_config == TRUE)
return priv->dhcp4_config;
if (priv->null_dhcp4_config)
return NULL;
path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Dhcp4Config", NULL);
if (path) {
path = _nm_object_get_object_path_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE,
"Dhcp4Config",
&error);
if (error == NULL) {
g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
g_value_take_boxed (&value, path);
demarshal_dhcp4_config (NM_OBJECT (device), NULL, &value, &priv->dhcp4_config);
g_value_unset (&value);
}
g_clear_error (&error);
return priv->dhcp4_config;
}
@ -1067,22 +1065,25 @@ nm_device_get_ip6_config (NMDevice *device)
NMDevicePrivate *priv;
char *path;
GValue value = { 0, };
GError *error = NULL;
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
priv = NM_DEVICE_GET_PRIVATE (device);
if (priv->ip6_config)
if (priv->got_ip6_config == TRUE)
return priv->ip6_config;
if (priv->null_ip6_config)
return NULL;
path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Ip6Config", NULL);
if (path) {
path = _nm_object_get_object_path_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE,
"Ip6Config",
&error);
if (error == NULL) {
g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
g_value_take_boxed (&value, path);
demarshal_ip6_config (NM_OBJECT (device), NULL, &value, &priv->ip6_config);
g_value_unset (&value);
}
g_clear_error (&error);
return priv->ip6_config;
}
@ -1102,22 +1103,25 @@ nm_device_get_dhcp6_config (NMDevice *device)
NMDevicePrivate *priv;
char *path;
GValue value = { 0, };
GError *error = NULL;
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
priv = NM_DEVICE_GET_PRIVATE (device);
if (priv->dhcp6_config)
if (priv->got_dhcp6_config == TRUE)
return priv->dhcp6_config;
if (priv->null_dhcp6_config)
return NULL;
path = _nm_object_get_object_path_property (NM_OBJECT (device), NM_DBUS_INTERFACE_DEVICE, "Dhcp6Config", NULL);
if (path) {
path = _nm_object_get_object_path_property (NM_OBJECT (device),
NM_DBUS_INTERFACE_DEVICE,
"Dhcp6Config",
&error);
if (error == NULL) {
g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
g_value_take_boxed (&value, path);
demarshal_dhcp6_config (NM_OBJECT (device), NULL, &value, &priv->dhcp6_config);
g_value_unset (&value);
}
g_clear_error (&error);
return priv->dhcp6_config;
}

View file

@ -333,6 +333,7 @@ handle_property_changed (gpointer key, gpointer data, gpointer user_data)
GParamSpec *pspec;
gboolean success = FALSE, found = FALSE;
GSList *iter;
GValue *value = data;
prop_name = wincaps_to_dash ((char *) key);
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (self)), prop_name);
@ -344,12 +345,19 @@ handle_property_changed (gpointer key, gpointer data, gpointer user_data)
goto out;
}
/* Iterate through the object and it's parents to find the property */
/* Iterate through the object and its parents to find the property */
for (iter = priv->pcs; iter; iter = g_slist_next (iter)) {
pci = g_hash_table_lookup ((GHashTable *) iter->data, prop_name);
if (pci) {
found = TRUE;
success = (*(pci->func)) (self, pspec, (GValue *) data, pci->field);
/* Handle NULL object paths */
if (G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH)) {
if (g_strcmp0 (g_value_get_boxed (value), "/") == 0)
value = NULL;
}
success = (*(pci->func)) (self, pspec, value, pci->field);
if (success)
break;
}
@ -453,6 +461,11 @@ _nm_object_demarshal_generic (NMObject *object,
char **param = (char **) field;
g_free (*param);
*param = g_strdup (g_value_get_boxed (value));
/* Handle "NULL" object paths */
if (g_strcmp0 (*param, "/") == 0) {
g_free (*param);
*param = NULL;
}
} else {
success = FALSE;
goto done;
@ -558,13 +571,18 @@ _nm_object_get_string_property (NMObject *object,
GError **error)
{
char *str = NULL;
const char *tmp;
GValue value = {0,};
if (_nm_object_get_property (object, interface, prop_name, &value, error)) {
if (G_VALUE_HOLDS_STRING (&value))
str = g_strdup (g_value_get_string (&value));
else if (G_VALUE_HOLDS (&value, DBUS_TYPE_G_OBJECT_PATH))
str = g_strdup (g_value_get_boxed (&value));
else if (G_VALUE_HOLDS (&value, DBUS_TYPE_G_OBJECT_PATH)) {
tmp = g_value_get_boxed (&value);
/* Handle "NULL" object paths */
if (g_strcmp0 (tmp, "/") != 0)
str = g_strdup (tmp);
}
g_value_unset (&value);
}
@ -578,10 +596,13 @@ _nm_object_get_object_path_property (NMObject *object,
GError **error)
{
char *path = NULL;
const char *tmp;
GValue value = {0,};
if (_nm_object_get_property (object, interface, prop_name, &value, error)) {
path = g_strdup (g_value_get_boxed (&value));
tmp = g_value_get_boxed (&value);
if (g_strcmp0 (tmp, "/") != 0)
path = g_strdup (tmp);
g_value_unset (&value);
}