summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2014-09-18 11:50:23 -0400
committerDan Winship <danw@gnome.org>2014-09-18 11:50:23 -0400
commit5f5a89b98ada1e23b6357aedaa6baef25afb1e0a (patch)
treef3fc35954477550c994063d330543142201b9b48
parentb99b632b473cf9d1058c472347d2714684e4f53d (diff)
parent8d26c45184cef91e0fc4b21378c25beaba682797 (diff)
downloadNetworkManager-5f5a89b98ada1e23b6357aedaa6baef25afb1e0a.tar.gz
Port callouts to gdbus (bgo #622927)
-rw-r--r--.gitignore1
-rw-r--r--callouts/Makefile.am33
-rw-r--r--callouts/nm-avahi-autoipd-action.c144
-rw-r--r--callouts/nm-dispatcher-api.h4
-rw-r--r--callouts/nm-dispatcher-utils.c384
-rw-r--r--callouts/nm-dispatcher-utils.h18
-rw-r--r--callouts/nm-dispatcher.c258
-rw-r--r--callouts/nm-dispatcher.xml4
-rw-r--r--callouts/tests/Makefile.am4
-rw-r--r--callouts/tests/test-dispatcher-envp.c291
-rw-r--r--libnm-core/nm-utils.c508
-rw-r--r--libnm-core/nm-utils.h14
-rw-r--r--libnm/libnm.ver12
13 files changed, 1053 insertions, 622 deletions
diff --git a/.gitignore b/.gitignore
index 57325ccf51..c4790edc87 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,7 @@ valgrind-*.log
/callouts/nm-avahi-autoipd.action
/callouts/nm-dispatcher
+/callouts/nmdbus-dispatcher.*
/callouts/org.freedesktop.nm_dispatcher.service
/callouts/tests/test-dispatcher-envp
diff --git a/callouts/Makefile.am b/callouts/Makefile.am
index 1d1eb3c764..d305554cc0 100644
--- a/callouts/Makefile.am
+++ b/callouts/Makefile.am
@@ -46,11 +46,33 @@ nm_dispatcher_SOURCES = \
nm_dispatcher_LDADD = \
$(top_builddir)/libnm/libnm.la \
- $(DBUS_LIBS) \
+ libnmdbus-dispatcher.la \
$(GLIB_LIBS)
-nm-dispatcher-glue.h: nm-dispatcher.xml
- $(AM_V_GEN) dbus-binding-tool --prefix=nm_dispatcher --mode=glib-server --output=$@ $<
+# We have to build the gdbus generated code separately, without
+# -DGLIB_VERSION_MAX_ALLOWED, due to a bug in GLib 2.38
+
+noinst_LTLIBRARIES += libnmdbus-dispatcher.la
+
+libnmdbus_dispatcher_la_SOURCES = \
+ nmdbus-dispatcher.c \
+ nmdbus-dispatcher.h
+
+libnmdbus_dispatcher_la_CPPFLAGS = $(filter-out -DGLIB_VERSION_MAX_ALLOWED%,$(AM_CPPFLAGS))
+
+nmdbus-dispatcher.h: nm-dispatcher.xml
+ $(AM_V_GEN) gdbus-codegen \
+ --generate-c-code $(basename $@) \
+ --c-namespace NMDBus \
+ --interface-prefix org.freedesktop \
+ $<
+
+nmdbus-dispatcher.c: nmdbus-dispatcher.h
+ @true
+
+BUILT_SOURCES = \
+ nmdbus-dispatcher.c \
+ nmdbus-dispatcher.h
###########################################
# dispatcher envp
@@ -65,8 +87,7 @@ libtest_dispatcher_envp_la_CPPFLAGS = \
libtest_dispatcher_envp_la_LIBADD = \
$(top_builddir)/libnm/libnm.la \
- $(GLIB_LIBS) \
- $(DBUS_LIBS)
+ $(GLIB_LIBS)
if WITH_UDEV_DIR
@@ -93,8 +114,6 @@ install-data-hook:
$(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)/pre-down.d
$(mkinstalldirs) -m 0755 $(DESTDIR)$(dispatcherdir)/pre-up.d
-BUILT_SOURCES = nm-dispatcher-glue.h
-
CLEANFILES = $(BUILT_SOURCES) $(dbusactivation_DATA)
EXTRA_DIST = \
diff --git a/callouts/nm-avahi-autoipd-action.c b/callouts/nm-avahi-autoipd-action.c
index 02d5207b30..48969df1b9 100644
--- a/callouts/nm-avahi-autoipd-action.c
+++ b/callouts/nm-avahi-autoipd-action.c
@@ -15,87 +15,48 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2008 Red Hat, Inc.
+ * Copyright 2008, 2014 Red Hat, Inc.
*/
-#include <stdio.h>
-#include <unistd.h>
#include <stdlib.h>
#include <string.h>
-#include <glib.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib.h>
+#include <gio/gio.h>
#define NM_AVAHI_AUTOIPD_DBUS_SERVICE "org.freedesktop.nm_avahi_autoipd"
#define NM_AVAHI_AUTOIPD_DBUS_INTERFACE "org.freedesktop.nm_avahi_autoipd"
-static DBusConnection *
-dbus_init (void)
+static void
+on_name_acquired (GDBusConnection *connection,
+ const gchar *name,
+ gpointer loop)
{
- DBusConnection * connection;
- DBusError error;
- int ret;
-
- dbus_connection_set_change_sigpipe (TRUE);
-
- dbus_error_init (&error);
- connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
- if (dbus_error_is_set (&error)) {
- fprintf (stderr, "Error: could not get the system bus. Make sure "
- "the message bus daemon is running! Message: (%s) %s\n",
- error.name,
- error.message);
- goto error;
- }
-
- dbus_connection_set_exit_on_disconnect (connection, FALSE);
-
- dbus_error_init (&error);
- ret = dbus_bus_request_name (connection,
- NM_AVAHI_AUTOIPD_DBUS_SERVICE,
- DBUS_NAME_FLAG_DO_NOT_QUEUE,
- &error);
- if (dbus_error_is_set (&error)) {
- fprintf (stderr, "Error: Could not acquire the NM DHCP client service. "
- "Message: (%s) %s\n",
- error.name,
- error.message);
- goto error;
- }
-
- if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- fprintf (stderr, "Error: Could not acquire the NM DHCP client service "
- "as it is already taken. Return: %d\n",
- ret);
- goto error;
- }
-
- return connection;
+ g_main_loop_quit (loop);
+}
-error:
- if (dbus_error_is_set (&error))
- dbus_error_free (&error);
- if (connection)
- dbus_connection_unref (connection);
- return NULL;
+static void
+on_name_lost (GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ g_printerr ("Error: Could not acquire the NM autoipd service.");
+ exit (1);
}
int
main (int argc, char *argv[])
{
- DBusConnection *connection;
- DBusMessage *message;
- dbus_bool_t result;
+ GDBusConnection *connection;
char *event, *iface, *address;
+ GMainLoop *loop;
+ GError *error = NULL;
#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
#endif
if (argc != 4) {
- fprintf (stderr, "Error: expected 3 arguments (event, interface, address).\n");
+ g_printerr ("Error: expected 3 arguments (event, interface, address).\n");
exit (1);
}
@@ -104,41 +65,60 @@ main (int argc, char *argv[])
address = argv[3] ? argv[3] : "";
if (!event || !iface || !strlen (event) || !strlen (iface)) {
- fprintf (stderr, "Error: unexpected arguments received from avahi-autoipd.\n");
+ g_printerr ("Error: unexpected arguments received from avahi-autoipd.\n");
exit (1);
}
/* Get a connection to the system bus */
- connection = dbus_init ();
- if (connection == NULL)
- exit (1);
+ connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (error) {
+ char *remote_error = g_dbus_error_get_remote_error (error);
- message = dbus_message_new_signal ("/", NM_AVAHI_AUTOIPD_DBUS_INTERFACE, "Event");
- if (message == NULL) {
- fprintf (stderr, "Error: not enough memory to send autoip Event signal.\n");
- exit (1);
+ g_dbus_error_strip_remote_error (error);
+ g_printerr ("Error: could not get the system bus. Make sure "
+ "the message bus daemon is running! Message: (%s) %s\n",
+ remote_error, error->message);
+ g_free (remote_error);
+ g_error_free (error);
+ return 1;
}
- if (!dbus_message_append_args (message,
- DBUS_TYPE_STRING, &event,
- DBUS_TYPE_STRING, &iface,
- DBUS_TYPE_STRING, &address,
- DBUS_TYPE_INVALID)) {
- fprintf (stderr, "Error: failed to construct autoip Event signal.\n");
- exit (1);
+ /* Acquire the bus name */
+ loop = g_main_loop_new (NULL, FALSE);
+ g_bus_own_name_on_connection (connection,
+ NM_AVAHI_AUTOIPD_DBUS_SERVICE,
+ 0,
+ on_name_acquired,
+ on_name_lost,
+ loop, NULL);
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+
+ /* Send the signal */
+ if (!g_dbus_connection_emit_signal (connection,
+ NULL,
+ "/",
+ NM_AVAHI_AUTOIPD_DBUS_INTERFACE,
+ "Event",
+ g_variant_new ("(sss)",
+ event,
+ iface,
+ address),
+ &error)) {
+ g_dbus_error_strip_remote_error (error);
+ g_printerr ("Error: Could not send autoipd Event signal: %s\n", error->message);
+ g_error_free (error);
+ return 1;
}
- /* queue the message */
- result = dbus_connection_send (connection, message, NULL);
- if (!result) {
- fprintf (stderr, "Error: could not send send autoip Event signal.\n");
- exit (1);
+ if (!g_dbus_connection_flush_sync (connection, NULL, &error)) {
+ g_dbus_error_strip_remote_error (error);
+ g_printerr ("Error: Could not flush D-Bus connection: %s\n", error->message);
+ g_error_free (error);
+ return 1;
}
- dbus_message_unref (message);
-
- /* Send out the message */
- dbus_connection_flush (connection);
+ g_object_unref (connection);
return 0;
}
diff --git a/callouts/nm-dispatcher-api.h b/callouts/nm-dispatcher-api.h
index bc156aa0f7..df1bced456 100644
--- a/callouts/nm-dispatcher-api.h
+++ b/callouts/nm-dispatcher-api.h
@@ -18,13 +18,11 @@
* Copyright (C) 2008 - 2012 Red Hat, Inc.
*/
-#include <dbus/dbus-glib.h>
-
#define NMD_SCRIPT_DIR_DEFAULT NMCONFDIR "/dispatcher.d"
#define NMD_SCRIPT_DIR_PRE_UP NMD_SCRIPT_DIR_DEFAULT "/pre-up.d"
#define NMD_SCRIPT_DIR_PRE_DOWN NMD_SCRIPT_DIR_DEFAULT "/pre-down.d"
-/* dbus-glib types for dispatcher call return value */
+/* dbus-glib types for dispatcher call return value (used by src/nm-dispatcher.c) */
#define DISPATCHER_TYPE_RESULT (dbus_g_type_get_struct ("GValueArray", G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID))
#define DISPATCHER_TYPE_RESULT_ARRAY (dbus_g_type_get_collection ("GPtrArray", DISPATCHER_TYPE_RESULT))
diff --git a/callouts/nm-dispatcher-utils.c b/callouts/nm-dispatcher-utils.c
index d48244f5a2..9a16880a57 100644
--- a/callouts/nm-dispatcher-utils.c
+++ b/callouts/nm-dispatcher-utils.c
@@ -24,7 +24,6 @@
#include <glib-object.h>
#include <nm-dbus-interface.h>
-#include <nm-dbus-glib-types.h>
#include <nm-connection.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-ip6-config.h>
@@ -55,25 +54,26 @@ construct_basic_items (GSList *list,
static GSList *
add_domains (GSList *items,
- GHashTable *hash,
+ GVariant *dict,
const char *prefix,
const char four_or_six)
{
- GValue *val;
+ GVariant *val;
char **domains = NULL;
GString *tmp;
guint i;
/* Search domains */
- val = g_hash_table_lookup (hash, "domains");
+ val = g_variant_lookup_value (dict, "domains", G_VARIANT_TYPE_STRING_ARRAY);
if (!val)
return items;
- g_return_val_if_fail (G_VALUE_HOLDS (val, G_TYPE_STRV), items);
-
- domains = (char **) g_value_get_boxed (val);
- if (!domains || !domains[0])
+ domains = g_variant_dup_strv (val, NULL);
+ g_variant_unref (val);
+ if (!domains[0]) {
+ g_strfreev (domains);
return items;
+ }
tmp = g_string_new (NULL);
g_string_append_printf (tmp, "%sIP%c_DOMAINS=", prefix, four_or_six);
@@ -82,22 +82,22 @@ add_domains (GSList *items,
g_string_append_c (tmp, ' ');
g_string_append (tmp, domains[i]);
}
- items = g_slist_prepend (items, tmp->str);
- g_string_free (tmp, FALSE);
+ items = g_slist_prepend (items, g_string_free (tmp, FALSE));
+ g_strfreev (domains);
return items;
}
static GSList *
-construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix)
+construct_ip4_items (GSList *items, GVariant *ip4_config, const char *prefix)
{
- GSList *addresses = NULL, *routes = NULL, *iter;
- GArray *dns = NULL, *wins = NULL;
- guint32 num, i;
+ GPtrArray *addresses, *routes;
+ char **dns, **wins;
GString *tmp;
- GValue *val;
+ GVariant *val;
char str_addr[INET_ADDRSTRLEN];
char str_gw[INET_ADDRSTRLEN];
+ int i;
if (ip4_config == NULL)
return items;
@@ -106,114 +106,112 @@ construct_ip4_items (GSList *items, GHashTable *ip4_config, const char *prefix)
prefix = "";
/* IP addresses */
- val = g_hash_table_lookup (ip4_config, "addresses");
- if (val)
- addresses = nm_utils_ip4_addresses_from_gvalue (val);
+ val = g_variant_lookup_value (ip4_config, "addresses", G_VARIANT_TYPE ("aau"));
+ if (val) {
+ addresses = nm_utils_ip4_addresses_from_variant (val);
- for (iter = addresses, num = 0; iter; iter = g_slist_next (iter)) {
- NMIP4Address *addr = (NMIP4Address *) iter->data;
- guint32 ip_prefix = nm_ip4_address_get_prefix (addr);
- char *addrtmp;
+ for (i = 0; i < addresses->len; i++) {
+ NMIP4Address *addr = addresses->pdata[i];
+ guint32 ip_prefix = nm_ip4_address_get_prefix (addr);
+ char *addrtmp;
- nm_utils_inet4_ntop (nm_ip4_address_get_address (addr), str_addr);
- nm_utils_inet4_ntop (nm_ip4_address_get_gateway (addr), str_gw);
+ nm_utils_inet4_ntop (nm_ip4_address_get_address (addr), str_addr);
+ nm_utils_inet4_ntop (nm_ip4_address_get_gateway (addr), str_gw);
- addrtmp = g_strdup_printf ("%sIP4_ADDRESS_%d=%s/%d %s", prefix, num++, str_addr, ip_prefix, str_gw);
- items = g_slist_prepend (items, addrtmp);
+ addrtmp = g_strdup_printf ("%sIP4_ADDRESS_%d=%s/%d %s", prefix, i, str_addr, ip_prefix, str_gw);
+ items = g_slist_prepend (items, addrtmp);
+ }
+ if (addresses->len)
+ items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ADDRESSES=%d", prefix, addresses->len));
+ g_ptr_array_unref (addresses);
+ g_variant_unref (val);
}
- if (num)
- items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ADDRESSES=%d", prefix, num));
- if (addresses)
- g_slist_free_full (addresses, (GDestroyNotify) nm_ip4_address_unref);
/* DNS servers */
- val = g_hash_table_lookup (ip4_config, "nameservers");
- if (val && G_VALUE_HOLDS (val, DBUS_TYPE_G_UINT_ARRAY))
- dns = (GArray *) g_value_get_boxed (val);
-
- if (dns && (dns->len > 0)) {
- gboolean first = TRUE;
-
- tmp = g_string_new (NULL);
- g_string_append_printf (tmp, "%sIP4_NAMESERVERS=", prefix);
- for (i = 0; i < dns->len; i++) {
- guint32 addr;
-
- addr = g_array_index (dns, guint32, i);
- if (!first)
- g_string_append_c (tmp, ' ');
- g_string_append (tmp, nm_utils_inet4_ntop (addr, NULL));
- first = FALSE;
+ val = g_variant_lookup_value (ip4_config, "nameservers", G_VARIANT_TYPE ("au"));
+ if (val) {
+ dns = nm_utils_ip4_dns_from_variant (val);
+
+ if (dns[0]) {
+ tmp = g_string_new (NULL);
+ g_string_append_printf (tmp, "%sIP4_NAMESERVERS=", prefix);
+ for (i = 0; dns[i]; i++) {
+ if (i != 0)
+ g_string_append_c (tmp, ' ');
+ g_string_append (tmp, dns[i]);
+ }
+
+ items = g_slist_prepend (items, g_string_free (tmp, FALSE));
}
- items = g_slist_prepend (items, tmp->str);
- g_string_free (tmp, FALSE);
+ g_strfreev (dns);
+ g_variant_unref (val);
}
/* Search domains */
items = add_domains (items, ip4_config, prefix, '4');
/* WINS servers */
- val = g_hash_table_lookup (ip4_config, "wins-servers");
- if (val && G_VALUE_HOLDS (val, DBUS_TYPE_G_UINT_ARRAY))
- wins = (GArray *) g_value_get_boxed (val);
-
- if (wins && wins->len) {
- gboolean first = TRUE;
-
- tmp = g_string_new (NULL);
- g_string_append_printf (tmp, "%sIP4_WINS_SERVERS=", prefix);
- for (i = 0; i < wins->len; i++) {
- guint32 addr;
-
- addr = g_array_index (wins, guint32, i);
- if (!first)
- g_string_append_c (tmp, ' ');
- g_string_append (tmp, nm_utils_inet4_ntop (addr, NULL));
- first = FALSE;
+ val = g_variant_lookup_value (ip4_config, "wins-servers", G_VARIANT_TYPE ("au"));
+ if (val) {
+ wins = nm_utils_ip4_dns_from_variant (val);
+
+ if (wins[0]) {
+ tmp = g_string_new (NULL);
+ g_string_append_printf (tmp, "%sIP4_WINS_SERVERS=", prefix);
+
+ for (i = 0; wins[i]; i++) {
+ if (i != 0)
+ g_string_append_c (tmp, ' ');
+ g_string_append (tmp, wins[i]);
+ }
+
+ items = g_slist_prepend (items, g_string_free (tmp, FALSE));
}
- items = g_slist_prepend (items, tmp->str);
- g_string_free (tmp, FALSE);
+ g_strfreev (wins);
+ g_variant_unref (val);
}
/* Static routes */
- val = g_hash_table_lookup (ip4_config, "routes");
- if (val)
- routes = nm_utils_ip4_routes_from_gvalue (val);
+ val = g_variant_lookup_value (ip4_config, "routes", G_VARIANT_TYPE ("aau"));
+ if (val) {
+ routes = nm_utils_ip4_routes_from_variant (val);
- for (iter = routes, num = 0; iter; iter = g_slist_next (iter)) {
- NMIP4Route *route = (NMIP4Route *) iter->data;
- guint32 ip_prefix = nm_ip4_route_get_prefix (route);
- guint32 metric = nm_ip4_route_get_metric (route);
- char *routetmp;
+ for (i = 0; i < routes->len; i++) {
+ NMIP4Route *route = routes->pdata[i];
+ guint32 ip_prefix = nm_ip4_route_get_prefix (route);
+ guint32 metric = nm_ip4_route_get_metric (route);
+ char *routetmp;
- nm_utils_inet4_ntop (nm_ip4_route_get_dest (route), str_addr);
- nm_utils_inet4_ntop (nm_ip4_route_get_next_hop (route), str_gw);
+ nm_utils_inet4_ntop (nm_ip4_route_get_dest (route), str_addr);
+ nm_utils_inet4_ntop (nm_ip4_route_get_next_hop (route), str_gw);
- routetmp = g_strdup_printf ("%sIP4_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_gw, metric);
- items = g_slist_prepend (items, routetmp);
- }
- items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ROUTES=%d", prefix, num));
- if (routes)
- g_slist_free_full (routes, (GDestroyNotify) nm_ip4_route_unref);
+ routetmp = g_strdup_printf ("%sIP4_ROUTE_%d=%s/%d %s %d", prefix, i, str_addr, ip_prefix, str_gw, metric);
+ items = g_slist_prepend (items, routetmp);
+ }
+ items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ROUTES=%d", prefix, routes->len));
+ g_ptr_array_unref (routes);
+ g_variant_unref (val);
+ } else
+ items = g_slist_prepend (items, g_strdup_printf ("%sIP4_NUM_ROUTES=0", prefix));
return items;
}
static GSList *
-construct_device_dhcp4_items (GSList *items, GHashTable *dhcp4_config)
+construct_device_dhcp4_items (GSList *items, GVariant *dhcp4_config)
{
- GHashTableIter iter;
+ GVariantIter iter;
const char *key, *tmp;
- GValue *val;
+ GVariant *val;
char *ucased;
if (dhcp4_config == NULL)
return items;
- g_hash_table_iter_init (&iter, dhcp4_config);
- while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) {
+ g_variant_iter_init (&iter, dhcp4_config);
+ while (g_variant_iter_next (&iter, "{&sv}", &key, &val)) {
ucased = g_ascii_strup (key, -1);
- tmp = g_value_get_string (val);
+ tmp = g_variant_get_string (val, NULL);
items = g_slist_prepend (items, g_strdup_printf ("DHCP4_%s=%s", ucased, tmp));
g_free (ucased);
}
@@ -221,14 +219,15 @@ construct_device_dhcp4_items (GSList *items, GHashTable *dhcp4_config)
}
static GSList *
-construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix)
+construct_ip6_items (GSList *items, GVariant *ip6_config, const char *prefix)
{
- GSList *addresses = NULL, *routes = NULL, *dns = NULL, *iter;
- guint32 num;
+ GPtrArray *addresses, *routes;
+ char **dns;
GString *tmp;
- GValue *val;
+ GVariant *val;
char str_addr[INET6_ADDRSTRLEN];
char str_gw[INET6_ADDRSTRLEN];
+ int i;
if (ip6_config == NULL)
return items;
@@ -237,93 +236,92 @@ construct_ip6_items (GSList *items, GHashTable *ip6_config, const char *prefix)
prefix = "";
/* IP addresses */
- val = g_hash_table_lookup (ip6_config, "addresses");
- if (val)
- addresses = nm_utils_ip6_addresses_from_gvalue (val);
+ val = g_variant_lookup_value (ip6_config, "addresses", G_VARIANT_TYPE ("a(ayuay)"));
+ if (val) {
+ addresses = nm_utils_ip6_addresses_from_variant (val);
- for (iter = addresses, num = 0; iter; iter = g_slist_next (iter)) {
- NMIP6Address *addr = (NMIP6Address *) iter->data;
- guint32 ip_prefix = nm_ip6_address_get_prefix (addr);
- char *addrtmp;
+ for (i = 0; i < addresses->len; i++) {
+ NMIP6Address *addr = addresses->pdata[i];
+ guint32 ip_prefix = nm_ip6_address_get_prefix (addr);
+ char *addrtmp;
- nm_utils_inet6_ntop (nm_ip6_address_get_address (addr), str_addr);
- nm_utils_inet6_ntop (nm_ip6_address_get_gateway (addr), str_gw);
+ nm_utils_inet6_ntop (nm_ip6_address_get_address (addr), str_addr);
+ nm_utils_inet6_ntop (nm_ip6_address_get_gateway (addr), str_gw);
- addrtmp = g_strdup_printf ("%sIP6_ADDRESS_%d=%s/%d %s", prefix, num++, str_addr, ip_prefix, str_gw);
- items = g_slist_prepend (items, addrtmp);
+ addrtmp = g_strdup_printf ("%sIP6_ADDRESS_%d=%s/%d %s", prefix, i, str_addr, ip_prefix, str_gw);
+ items = g_slist_prepend (items, addrtmp);
+ }
+ if (addresses->len)
+ items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ADDRESSES=%d", prefix, addresses->len));
+ g_ptr_array_unref (addresses);
+ g_variant_unref (val);
}
- if (num)
- items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ADDRESSES=%d", prefix, num));
- if (addresses)
- g_slist_free_full (addresses, (GDestroyNotify) nm_ip6_address_unref);
/* DNS servers */
- val = g_hash_table_lookup (ip6_config, "nameservers");
- if (val)
- dns = nm_utils_ip6_dns_from_gvalue (val);
+ val = g_variant_lookup_value (ip6_config, "nameservers", G_VARIANT_TYPE ("aay"));
+ if (val) {
+ dns = nm_utils_ip6_dns_from_variant (val);
- if (g_slist_length (dns)) {
- gboolean first = TRUE;
+ if (dns[0]) {
+ tmp = g_string_new (NULL);
+ g_string_append_printf (tmp, "%sIP6_NAMESERVERS=", prefix);
- tmp = g_string_new (NULL);
- g_string_append_printf (tmp, "%sIP6_NAMESERVERS=", prefix);
+ for (i = 0; dns[i]; i++) {
+ if (i != 0)
+ g_string_append_c (tmp, ' ');
+ g_string_append (tmp, dns[i]);
+ }
- for (iter = dns; iter; iter = g_slist_next (iter)) {
- const struct in6_addr *addr = iter->data;
-
- if (!first)
- g_string_append_c (tmp, ' ');
- g_string_append (tmp, nm_utils_inet6_ntop (addr, NULL));
- first = FALSE;
+ items = g_slist_prepend (items, g_string_free (tmp, FALSE));
}
-
- items = g_slist_prepend (items, tmp->str);
- g_string_free (tmp, FALSE);
+ g_strfreev (dns);
+ g_variant_unref (val);
}
/* Search domains */
items = add_domains (items, ip6_config, prefix, '6');
/* Static routes */
- val = g_hash_table_lookup (ip6_config, "routes");
- if (val)
- routes = nm_utils_ip6_routes_from_gvalue (val);
+ val = g_variant_lookup_value (ip6_config, "routes", G_VARIANT_TYPE ("a(ayuayu)"));
+ if (val) {
+ routes = nm_utils_ip6_routes_from_variant (val);
- for (iter = routes, num = 0; iter; iter = g_slist_next (iter)) {
- NMIP6Route *route = (NMIP6Route *) iter->data;
- guint32 ip_prefix = nm_ip6_route_get_prefix (route);
- guint32 metric = nm_ip6_route_get_metric (route);
- char *routetmp;
+ for (i = 0; i < routes->len; i++) {
+ NMIP6Route *route = routes->pdata[i];
+ guint32 ip_prefix = nm_ip6_route_get_prefix (route);
+ guint32 metric = nm_ip6_route_get_metric (route);
+ char *routetmp;
- nm_utils_inet6_ntop (nm_ip6_route_get_dest (route), str_addr);
- nm_utils_inet6_ntop (nm_ip6_route_get_next_hop (route), str_gw);
+ nm_utils_inet6_ntop (nm_ip6_route_get_dest (route), str_addr);
+ nm_utils_inet6_ntop (nm_ip6_route_get_next_hop (route), str_gw);
- routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %d", prefix, num++, str_addr, ip_prefix, str_gw, metric);
- items = g_slist_prepend (items, routetmp);
+ routetmp = g_strdup_printf ("%sIP6_ROUTE_%d=%s/%d %s %d", prefix, i, str_addr, ip_prefix, str_gw, metric);
+ items = g_slist_prepend (items, routetmp);
+ }
+ if (routes->len)
+ items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ROUTES=%d", prefix, routes->len));
+ g_ptr_array_unref (routes);
+ g_variant_unref (val);
}
- if (num)
- items = g_slist_prepend (items, g_strdup_printf ("%sIP6_NUM_ROUTES=%d", prefix, num));
- if (routes)
- g_slist_free_full (routes, (GDestroyNotify) nm_ip6_route_unref);
return items;
}
static GSList *
-construct_device_dhcp6_items (GSList *items, GHashTable *dhcp6_config)
+construct_device_dhcp6_items (GSList *items, GVariant *dhcp6_config)
{
- GHashTableIter iter;
+ GVariantIter iter;
const char *key, *tmp;
- GValue *val;
+ GVariant *val;
char *ucased;
if (dhcp6_config == NULL)
return items;
- g_hash_table_iter_init (&iter, dhcp6_config);
- while (g_hash_table_iter_next (&iter, (gpointer) &key, (gpointer) &val)) {
+ g_variant_iter_init (&iter, dhcp6_config);
+ while (g_variant_iter_next (&iter, "{&sv}", &key, &val)) {
ucased = g_ascii_strup (key, -1);
- tmp = g_value_get_string (val);
+ tmp = g_variant_get_string (val, NULL);
items = g_slist_prepend (items, g_strdup_printf ("DHCP6_%s=%s", ucased, tmp));
g_free (ucased);
}
@@ -332,26 +330,26 @@ construct_device_dhcp6_items (GSList *items, GHashTable *dhcp6_config)
char **
nm_dispatcher_utils_construct_envp (const char *action,
- GHashTable *connection_hash,
- GHashTable *connection_props,
- GHashTable *device_props,
- GHashTable *device_ip4_props,
- GHashTable *device_ip6_props,
- GHashTable *device_dhcp4_props,
- GHashTable *device_dhcp6_props,
+ GVariant *connection_dict,
+ GVariant *connection_props,
+ GVariant *device_props,
+ GVariant *device_ip4_props,
+ GVariant *device_ip6_props,
+ GVariant *device_dhcp4_props,
+ GVariant *device_dhcp6_props,
const char *vpn_ip_iface,
- GHashTable *vpn_ip4_props,
- GHashTable *vpn_ip6_props,
+ GVariant *vpn_ip4_props,
+ GVariant *vpn_ip6_props,
char **out_iface)
{
const char *iface = NULL, *ip_iface = NULL;
const char *uuid = NULL, *id = NULL, *path;
NMDeviceState dev_state = NM_DEVICE_STATE_UNKNOWN;
- GValue *value;
+ GVariant *value;
char **envp = NULL, *path_item;
GSList *items = NULL, *iter;
guint i;
- GHashTable *con_setting_hash;
+ GVariant *con_setting;
g_return_val_if_fail (action != NULL, NULL);
g_return_val_if_fail (out_iface != NULL, NULL);
@@ -367,69 +365,67 @@ nm_dispatcher_utils_construct_envp (const char *action,
if (vpn_ip_iface && !strlen (vpn_ip_iface))
vpn_ip_iface = NULL;
- con_setting_hash = g_hash_table_lookup (connection_hash, NM_SETTING_CONNECTION_SETTING_NAME);
- if (!con_setting_hash) {
- g_warning ("Failed to read connection setting");
- return NULL;
- }
-
- value = g_hash_table_lookup (con_setting_hash, NM_SETTING_CONNECTION_UUID);
- if (!value || !G_VALUE_HOLDS (value, G_TYPE_STRING)) {
- g_warning ("Connection hash did not contain the UUID");
- return NULL;
- }
- uuid = g_value_get_string (value);
-
- value = g_hash_table_lookup (con_setting_hash, NM_SETTING_CONNECTION_ID);
- if (!value || !G_VALUE_HOLDS (value, G_TYPE_STRING)) {
- g_warning ("Connection hash did not contain the ID");
- return NULL;
- }
- id = g_value_get_string (value);
-
/* interface name */
- value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_INTERFACE);
- if (!value || !G_VALUE_HOLDS_STRING (value)) {
+ if (!g_variant_lookup (device_props, NMD_DEVICE_PROPS_INTERFACE, "&s", &iface)) {
g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_INTERFACE "!");
return NULL;
}
- iface = g_value_get_string (value);
- if (iface && !strlen (iface))
+ if (!*iface)
iface = NULL;
/* IP interface name */
- value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_IP_INTERFACE);
+ value = g_variant_lookup_value (device_props, NMD_DEVICE_PROPS_IP_INTERFACE, NULL);
if (value) {
- if (!G_VALUE_HOLDS_STRING (value)) {
- g_warning ("Invalid required value " NMD_DEVICE_PROPS_IP_INTERFACE "!");
+ if (!g_variant_is_of_type (value, G_VARIANT_TYPE_STRING)) {
+ g_warning ("Invalid value " NMD_DEVICE_PROPS_IP_INTERFACE "!");
return NULL;
}
- ip_iface = g_value_get_string (value);
+ g_variant_unref (value);
+ g_variant_lookup (device_props, NMD_DEVICE_PROPS_IP_INTERFACE, "&s", &ip_iface);
}
/* Device type */
- value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_TYPE);
- if (!value || !G_VALUE_HOLDS_UINT (value)) {
+ if (!g_variant_lookup (device_props, NMD_DEVICE_PROPS_TYPE, "u", NULL)) {
g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_TYPE "!");
return NULL;
}
/* Device state */
- value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_STATE);
- if (!value || !G_VALUE_HOLDS_UINT (value)) {
+ value = g_variant_lookup_value (device_props, NMD_DEVICE_PROPS_STATE, G_VARIANT_TYPE_UINT32);
+ if (!value) {
g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_STATE "!");
return NULL;
}
- dev_state = g_value_get_uint (value);
+ dev_state = g_variant_get_uint32 (value);
+ g_variant_unref (value);
/* device itself */
- value = g_hash_table_lookup (device_props, NMD_DEVICE_PROPS_PATH);
- if (!value || (G_VALUE_TYPE (value) != DBUS_TYPE_G_OBJECT_PATH)) {
+ if (!g_variant_lookup (device_props, NMD_DEVICE_PROPS_PATH, "o", NULL)) {
g_warning ("Missing or invalid required value " NMD_DEVICE_PROPS_PATH "!");
return NULL;
}
+ /* UUID and ID */
+ con_setting = g_variant_lookup_value (connection_dict, NM_SETTING_CONNECTION_SETTING_NAME, G_VARIANT_TYPE ("a{sv}"));
+ if (!con_setting) {
+ g_warning ("Failed to read connection setting");
+ return NULL;
+ }
+
+ if (!g_variant_lookup (con_setting, NM_SETTING_CONNECTION_UUID, "&s", &uuid)) {
+ g_warning ("Connection hash did not contain the UUID");
+ g_variant_unref (con_setting);
+ return NULL;
+ }
+
+ if (!g_variant_lookup (con_setting, NM_SETTING_CONNECTION_ID, "&s", &id)) {
+ g_warning ("Connection hash did not contain the ID");
+ g_variant_unref (con_setting);
+ return NULL;
+ }
+
items = construct_basic_items (items, uuid, id, iface, ip_iface);
+ g_variant_unref (con_setting);
/* Device it's aren't valid if the device isn't activated */
if (iface && (dev_state == NM_DEVICE_STATE_ACTIVATED)) {
diff --git a/callouts/nm-dispatcher-utils.h b/callouts/nm-dispatcher-utils.h
index d64dfce190..665a0d4eaf 100644
--- a/callouts/nm-dispatcher-utils.h
+++ b/callouts/nm-dispatcher-utils.h
@@ -25,16 +25,16 @@
char **
nm_dispatcher_utils_construct_envp (const char *action,
- GHashTable *connection_hash,
- GHashTable *connection_props,
- GHashTable *device_props,
- GHashTable *device_ip4_props,
- GHashTable *device_ip6_props,
- GHashTable *device_dhcp4_props,
- GHashTable *device_dhcp6_props,
+ GVariant *connection_dict,
+ GVariant *connection_props,
+ GVariant *device_props,
+ GVariant *device_ip4_props,
+ GVariant *device_ip6_props,
+ GVariant *device_dhcp4_props,
+ GVariant *device_dhcp6_props,
const char *vpn_ip_iface,
- GHashTable *vpn_ip4_props,
- GHashTable *vpn_ip6_props,
+ GVariant *vpn_ip4_props,
+ GVariant *vpn_ip6_props,
char **out_iface);
#endif /* __NETWORKMANAGER_DISPATCHER_UTILS_H__ */
diff --git a/callouts/nm-dispatcher.c b/callouts/nm-dispatcher.c
index 733af511fb..a7a83d5aa5 100644
--- a/callouts/nm-dispatcher.c
+++ b/callouts/nm-dispatcher.c
@@ -32,17 +32,18 @@
#include <glib.h>
#include <glib-unix.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-#include <dbus/dbus-glib.h>
#include "nm-dispatcher-api.h"
#include "nm-dispatcher-utils.h"
#include "nm-glib-compat.h"
+#include "nmdbus-dispatcher.h"
+
static GMainLoop *loop = NULL;
static gboolean debug = FALSE;
+static gboolean persist = FALSE;
+static guint quit_id;
typedef struct Request Request;
@@ -50,10 +51,10 @@ typedef struct {
GObject parent;
/* Private data */
+ NMDBusDispatcher *dbus_dispatcher;
+
Request *current_request;
GQueue *pending_requests;
- guint quit_id;
- gboolean persist;
} Handler;
typedef struct {
@@ -68,28 +69,30 @@ GType handler_get_type (void);
G_DEFINE_TYPE(Handler, handler, G_TYPE_OBJECT)
-static void
-impl_dispatch (Handler *h,
- const char *action,
- GHashTable *connection_hash,
- GHashTable *connection_props,
- GHashTable *device_props,
- GHashTable *device_ip4_props,
- GHashTable *device_ip6_props,
- GHashTable *device_dhcp4_props,
- GHashTable *device_dhcp6_props,
+static gboolean
+handle_action (NMDBusDispatcher *dbus_dispatcher,
+ GDBusMethodInvocation *context,
+ const char *str_action,
+ GVariant *connection_dict,
+ GVariant *connection_props,
+ GVariant *device_props,
+ GVariant *device_ip4_props,
+ GVariant *device_ip6_props,
+ GVariant *device_dhcp4_props,
+ GVariant *device_dhcp6_props,
const char *vpn_ip_iface,
- GHashTable *vpn_ip4_props,
- GHashTable *vpn_ip6_props,
+ GVariant *vpn_ip4_props,
+ GVariant *vpn_ip6_props,
gboolean request_debug,
- DBusGMethodInvocation *context);
-
-#include "nm-dispatcher-glue.h"
-
+ gpointer user_data);
static void
handler_init (Handler *h)
{
+ h->pending_requests = g_queue_new ();
+ h->dbus_dispatcher = nmdbus_dispatcher_skeleton_new ();
+ g_signal_connect (h->dbus_dispatcher, "handle-action",
+ G_CALLBACK (handle_action), h);
}
static void
@@ -111,7 +114,7 @@ typedef struct {
struct Request {
Handler *handler;
- DBusGMethodInvocation *context;
+ GDBusMethodInvocation *context;
char *action;
char *iface;
char **envp;
@@ -152,20 +155,20 @@ quit_timeout_cb (gpointer user_data)
}
static void
-quit_timeout_cancel (Handler *h)
+quit_timeout_cancel (void)
{
- if (h->quit_id) {
- g_source_remove (h->quit_id);
- h->quit_id = 0;
+ if (quit_id) {
+ g_source_remove (quit_id);
+ quit_id = 0;
}
}
static void
-quit_timeout_reschedule (Handler *h)
+quit_timeout_reschedule (void)
{
- quit_timeout_cancel (h);
- if (!h->persist)
- h->quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL);
+ quit_timeout_cancel ();
+ if (!persist)
+ quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL);
}
static void
@@ -191,7 +194,7 @@ next_request (Handler *h)
}
h->current_request = NULL;
- quit_timeout_reschedule (h);
+ quit_timeout_reschedule ();
}
static gboolean
@@ -199,8 +202,8 @@ next_script (gpointer user_data)
{
Request *request = user_data;
Handler *h = request->handler;
- GPtrArray *results;
- GValueArray *item;
+ GVariantBuilder results;
+ GVariant *ret;
guint i;
request->idx++;
@@ -210,36 +213,18 @@ next_script (gpointer user_data)
}
/* All done */
- results = g_ptr_array_new_full (request->scripts->len, (GDestroyNotify) g_value_array_free);
+ g_variant_builder_init (&results, G_VARIANT_TYPE ("a(sus)"));
for (i = 0; i < request->scripts->len; i++) {
ScriptInfo *script = g_ptr_array_index (request->scripts, i);
- GValue elt = G_VALUE_INIT;
-
- item = g_value_array_new (3);
-
- /* Script path */
- g_value_init (&elt, G_TYPE_STRING);
- g_value_set_string (&elt, script->script);
- g_value_array_append (item, &elt);
- g_value_unset (&elt);
-
- /* Result */
- g_value_init (&elt, G_TYPE_UINT);
- g_value_set_uint (&elt, script->result);
- g_value_array_append (item, &elt);
- g_value_unset (&elt);
-
- /* Error */
- g_value_init (&elt, G_TYPE_STRING);
- g_value_set_string (&elt, script->error ? script->error : "");
- g_value_array_append (item, &elt);
- g_value_unset (&elt);
- g_ptr_array_add (results, item);
+ g_variant_builder_add (&results, "(sus)",
+ script->script,
+ script->result,
+ script->error ? script->error : "");
}
- dbus_g_method_return (request->context, results);
- g_ptr_array_unref (results);
+ ret = g_variant_new ("(a(sus))", &results);
+ g_dbus_method_invocation_return_value (request->context, ret);
if (request->debug) {
if (request->iface)
@@ -470,22 +455,24 @@ find_scripts (const char *str_action)
return sorted;
}
-static void
-impl_dispatch (Handler *h,
+static gboolean
+handle_action (NMDBusDispatcher *dbus_dispatcher,
+ GDBusMethodInvocation *context,
const char *str_action,
- GHashTable *connection_hash,
- GHashTable *connection_props,
- GHashTable *device_props,
- GHashTable *device_ip4_props,
- GHashTable *device_ip6_props,
- GHashTable *device_dhcp4_props,
- GHashTable *device_dhcp6_props,
+ GVariant *connection_dict,
+ GVariant *connection_props,
+ GVariant *device_props,
+ GVariant *device_ip4_props,
+ GVariant *device_ip6_props,
+ GVariant *device_dhcp4_props,
+ GVariant *device_dhcp6_props,
const char *vpn_ip_iface,
- GHashTable *vpn_ip4_props,
- GHashTable *vpn_ip6_props,
+ GVariant *vpn_ip4_props,
+ GVariant *vpn_ip6_props,
gboolean request_debug,
- DBusGMethodInvocation *context)
+ gpointer user_data)
{
+ Handler *h = user_data;
GSList *sorted_scripts = NULL;
GSList *iter;
Request *request;
@@ -495,11 +482,14 @@ impl_dispatch (Handler *h,
sorted_scripts = find_scripts (str_action);
if (!sorted_scripts) {
- dbus_g_method_return (context, g_ptr_array_new ());
- return;
+ GVariant *results;
+
+ results = g_variant_new_array (G_VARIANT_TYPE ("sus"), NULL, 0);
+ g_dbus_method_invocation_return_value (context, g_variant_new ("(@a(sus))", results));
+ return TRUE;
}
- quit_timeout_cancel (h);
+ quit_timeout_cancel ();
request = g_malloc0 (sizeof (*request));
request->handler = h;
@@ -508,7 +498,7 @@ impl_dispatch (Handler *h,
request->action = g_strdup (str_action);
request->envp = nm_dispatcher_utils_construct_envp (str_action,
- connection_hash,
+ connection_dict,
connection_props,
device_props,
device_ip4_props,
@@ -543,76 +533,35 @@ impl_dispatch (Handler *h,
g_queue_push_tail (h->pending_requests, request);
else
start_request (request);
+
+ return TRUE;
}
+static gboolean ever_acquired_name = FALSE;
+
static void
-destroy_cb (DBusGProxy *proxy, gpointer user_data)
+on_name_acquired (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
{
- g_warning ("Disconnected from the system bus, exiting.");
- g_main_loop_quit (loop);
+ ever_acquired_name = TRUE;
}
-static DBusGConnection *
-dbus_init (void)
+static void
+on_name_lost (GDBusConnection *connection,
+ const char *name,
+ gpointer user_data)
{
- GError *error = NULL;
- DBusGConnection *bus;
- DBusConnection *connection;
- DBusGProxy *proxy;
- int result;
-
- dbus_connection_set_change_sigpipe (TRUE);
-
- bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
- if (!bus) {
- g_warning ("Could not get the system bus. Make sure "
- "the message bus daemon is running! Message: %s",
- error->message);
- g_error_free (error);
- return NULL;
- }
-
- /* Clean up nicely if we get kicked off the bus */
- connection = dbus_g_connection_get_connection (bus);
- dbus_connection_set_exit_on_disconnect (connection, FALSE);
-
- proxy = dbus_g_proxy_new_for_name (bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus");
- if (!proxy) {
- g_warning ("Could not create the DBus proxy!");
- goto error;
- }
-
- g_signal_connect (proxy, "destroy", G_CALLBACK (destroy_cb), NULL);
-
- if (!dbus_g_proxy_call (proxy, "RequestName", &error,
- G_TYPE_STRING, NM_DISPATCHER_DBUS_SERVICE,
- G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
- G_TYPE_INVALID,
- G_TYPE_UINT, &result,
- G_TYPE_INVALID)) {
- g_warning ("Could not acquire the " NM_DISPATCHER_DBUS_SERVICE " service.\n"
- " Message: '%s'", error->message);
- g_error_free (error);
- goto error;
- }
-
- if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_warning ("Could not acquire the " NM_DISPATCHER_DBUS_SERVICE " service "
- "as it is already taken. Result: %d",
- result);
- goto error;
+ if (!connection) {
+ g_warning ("Could not get the system bus. Make sure the message bus daemon is running!");
+ exit (1);
+ } else if (!ever_acquired_name) {
+ g_warning ("Could not acquire the " NM_DISPATCHER_DBUS_SERVICE " service.");
+ exit (1);
+ } else {
+ g_message ("Lost the " NM_DISPATCHER_DBUS_SERVICE " name. Exiting");
+ exit (0);
}
-
- return bus;
-
-error:
- if (proxy)
- g_object_unref (proxy);
- dbus_g_connection_unref (bus);
- return NULL;
}
static void
@@ -681,8 +630,7 @@ main (int argc, char **argv)
{
GOptionContext *opt_ctx;
GError *error = NULL;
- gboolean persist = FALSE;
- DBusGConnection *bus;
+ GDBusConnection *bus;
Handler *handler;
GOptionEntry entries[] = {
@@ -715,31 +663,41 @@ main (int argc, char **argv)
loop = g_main_loop_new (NULL, FALSE);
- bus = dbus_init ();
- if (!bus)
+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (!bus) {
+ g_warning ("Could not get the system bus (%s). Make sure the message bus daemon is running!",
+ error->message);
+ g_error_free (error);
return 1;
+ }
handler = g_object_new (HANDLER_TYPE, NULL);
- if (!handler)
+ g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (handler->dbus_dispatcher),
+ bus,
+ NM_DISPATCHER_DBUS_PATH,
+ &error);
+ if (error) {
+ g_warning ("Could not export Dispatcher D-Bus interface: %s", error->message);
+ g_error_free (error);
return 1;
- handler->persist = persist;
- handler->pending_requests = g_queue_new ();
+ }
- dbus_g_object_type_install_info (HANDLER_TYPE, &dbus_glib_nm_dispatcher_object_info);
- dbus_g_connection_register_g_object (bus,
- NM_DISPATCHER_DBUS_PATH,
- G_OBJECT (handler));
+ g_bus_own_name_on_connection (bus,
+ NM_DISPATCHER_DBUS_SERVICE,
+ G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_name_acquired,
+ on_name_lost,
+ NULL, NULL);
+ g_object_unref (bus);
if (!persist)
- handler->quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL);
+ quit_id = g_timeout_add_seconds (10, quit_timeout_cb, NULL);
g_main_loop_run (loop);
g_queue_free (handler->pending_requests);
g_object_unref (handler);
- dbus_g_connection_unref (bus);
-
if (!debug)
logging_shutdown ();
diff --git a/callouts/nm-dispatcher.xml b/callouts/nm-dispatcher.xml
index 1ae138b35b..b2c4a21aec 100644
--- a/callouts/nm-dispatcher.xml
+++ b/callouts/nm-dispatcher.xml
@@ -2,15 +2,13 @@
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.nm_dispatcher">
+ <annotation name="org.gtk.GDBus.C.Name" value="Dispatcher"/>
<method name="Action">
<tp:docstring>
INTERNAL; not public API. Perform an action.
</tp:docstring>
- <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_dispatch"/>
- <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
-
<arg name="action" type="s" direction="in">
<tp:docstring>
The action being performed.
diff --git a/callouts/tests/Makefile.am b/callouts/tests/Makefile.am
index c06178b225..db73ef9372 100644
--- a/callouts/tests/Makefile.am
+++ b/callouts/tests/Makefile.am
@@ -7,6 +7,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/callouts \
-DNETWORKMANAGER_COMPILATION \
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
+ -DSRCDIR=\"$(abs_srcdir)\" \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS)
@@ -26,8 +27,7 @@ test_dispatcher_envp_LDADD = \
###########################################
-check-local: test-dispatcher-envp
- $(abs_builddir)/test-dispatcher-envp $(abs_srcdir)
+TESTS = test-dispatcher-envp
EXTRA_DIST= \
dispatcher-old-down \
diff --git a/callouts/tests/test-dispatcher-envp.c b/callouts/tests/test-dispatcher-envp.c
index 05c2e8ed9c..b51c1c16a5 100644
--- a/callouts/tests/test-dispatcher-envp.c
+++ b/callouts/tests/test-dispatcher-envp.c
@@ -28,107 +28,31 @@
#include "nm-connection.h"
#include "nm-setting-connection.h"
#include "nm-dispatcher-utils.h"
-#include "nm-dbus-glib-types.h"
#include "nm-dispatcher-api.h"
#include "nm-utils.h"
+#include "nm-dbus-glib-types.h"
/*******************************************/
-static void
-value_destroy (gpointer data)
-{
- GValue *value = (GValue *) data;
-
- g_value_unset (value);
- g_slice_free (GValue, value);
-}
-
-static GHashTable *
-value_hash_create (void)
-{
- return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, value_destroy);
-}
-
-static void
-value_hash_add (GHashTable *hash,
- const char *key,
- GValue *value)
-{
- g_hash_table_insert (hash, g_strdup (key), value);
-}
-
-static void
-value_hash_add_string (GHashTable *hash,
- const char *key,
- const char *str)
+static GVariant *
+connection_hash_to_dict (GHashTable *hash)
{
- GValue *value;
+ GValue val = { 0, };
+ GVariant *dict;
- value = g_slice_new0 (GValue);
- g_value_init (value, G_TYPE_STRING);
- g_value_set_string (value, str);
+ g_value_init (&val, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT);
+ g_value_set_boxed (&val, hash);
+ dict = dbus_g_value_build_g_variant (&val);
+ g_value_unset (&val);
- value_hash_add (hash, key, value);
-}
-
-static void
-value_hash_add_object_path (GHashTable *hash,
- const char *key,
- const char *op)
-{
- GValue *value;
-
- value = g_slice_new0 (GValue);
- g_value_init (value, DBUS_TYPE_G_OBJECT_PATH);
- g_value_set_boxed (value, op);
-
- value_hash_add (hash, key, value);
-}
-
-static void
-value_hash_add_uint (GHashTable *hash,
- const char *key,
- guint32 val)
-{
- GValue *value;
-
- value = g_slice_new0 (GValue);
- g_value_init (value, G_TYPE_UINT);
- g_value_set_uint (value, val);
-
- value_hash_add (hash, key, value);
-}
-
-static void
-value_hash_add_strv (GHashTable *hash,
- const char *key,
- char **strv)
-{
- GValue *value;
-
- value = g_slice_new0 (GValue);
- g_value_init (value, G_TYPE_STRV);
- g_value_take_boxed (value, strv);
- value_hash_add (hash, key, value);
-}
-
-static void
-value_hash_add_uint_array (GHashTable *hash,
- const char *key,
- GArray *array)
-{
- GValue *value;
-
- value = g_slice_new0 (GValue);
- g_value_init (value, DBUS_TYPE_G_UINT_ARRAY);
- g_value_take_boxed (value, array);
- value_hash_add (hash, key, value);
+ g_variant_ref_sink (dict);
+ return dict;
}
static gboolean
parse_main (GKeyFile *kf,
- GHashTable **out_con_hash,
- GHashTable **out_con_props,
+ GVariant **out_con_dict,
+ GVariant **out_con_props,
char **out_expected_iface,
char **out_action,
char **out_vpn_ip_iface,
@@ -137,6 +61,8 @@ parse_main (GKeyFile *kf,
char *uuid, *id;
NMConnection *connection;
NMSettingConnection *s_con;
+ GVariantBuilder props;
+ GHashTable *con_hash;
*out_expected_iface = g_key_file_get_string (kf, "main", "expected-iface", error);
if (*out_expected_iface == NULL)
@@ -167,57 +93,74 @@ parse_main (GKeyFile *kf,
g_free (id);
nm_connection_add_setting (connection, NM_SETTING (s_con));
- *out_con_hash = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
+ con_hash = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
g_object_unref (connection);
+ *out_con_dict = connection_hash_to_dict (con_hash);
+ g_hash_table_unref (con_hash);
- *out_con_props = value_hash_create ();
- value_hash_add_object_path (*out_con_props, "connection-path", "/org/freedesktop/NetworkManager/Connections/5");
+ g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_add (&props, "{sv}",
+ "connection-path",
+ g_variant_new_object_path ("/org/freedesktop/NetworkManager/Connections/5"));
+ *out_con_props = g_variant_builder_end (&props);
return TRUE;
}
static gboolean
-parse_device (GKeyFile *kf, GHashTable **out_device_props, GError **error)
+parse_device (GKeyFile *kf, GVariant **out_device_props, GError **error)
{
+ GVariantBuilder props;
char *tmp;
gint i;
- *out_device_props = value_hash_create ();
+ g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}"));
i = g_key_file_get_integer (kf, "device", "state", error);
if (i == 0)
return FALSE;
- value_hash_add_uint (*out_device_props, NMD_DEVICE_PROPS_STATE, (guint) i);
+ g_variant_builder_add (&props, "{sv}",
+ NMD_DEVICE_PROPS_STATE,
+ g_variant_new_uint32 (i));
i = g_key_file_get_integer (kf, "device", "type", error);
if (i == 0)
return FALSE;
- value_hash_add_uint (*out_device_props, NMD_DEVICE_PROPS_TYPE, (guint) i);
+ g_variant_builder_add (&props, "{sv}",
+ NMD_DEVICE_PROPS_TYPE,
+ g_variant_new_uint32 (i));
tmp = g_key_file_get_string (kf, "device", "interface", error);
if (tmp == NULL)
return FALSE;
- value_hash_add_string (*out_device_props, NMD_DEVICE_PROPS_INTERFACE, tmp);
+ g_variant_builder_add (&props, "{sv}",
+ NMD_DEVICE_PROPS_INTERFACE,
+ g_variant_new_string (tmp));
g_free (tmp);
tmp = g_key_file_get_string (kf, "device", "ip-interface", error);
if (tmp == NULL)
return FALSE;
- value_hash_add_string (*out_device_props, NMD_DEVICE_PROPS_IP_INTERFACE, tmp);
+ g_variant_builder_add (&props, "{sv}",
+ NMD_DEVICE_PROPS_IP_INTERFACE,
+ g_variant_new_string (tmp));
g_free (tmp);
tmp = g_key_file_get_string (kf, "device", "path", error);
if (tmp == NULL)
return FALSE;
- value_hash_add_object_path (*out_device_props, NMD_DEVICE_PROPS_PATH, tmp);
+ g_variant_builder_add (&props, "{sv}",
+ NMD_DEVICE_PROPS_PATH,
+ g_variant_new_object_path (tmp));
g_free (tmp);
+ *out_device_props = g_variant_builder_end (&props);
return TRUE;
}
static gboolean
add_uint_array (GKeyFile *kf,
- GHashTable *props,
+ GVariantBuilder *props,
const char *section,
const char *key,
GError **error)
@@ -244,21 +187,25 @@ add_uint_array (GKeyFile *kf,
g_array_append_val (items, addr);
}
}
- value_hash_add_uint_array (props, key, items);
+ g_variant_builder_add (props, "{sv}", key,
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
+ items->data, items->len,
+ sizeof (guint32)));
+ g_array_unref (items);
}
g_strfreev (split);
return TRUE;
}
static gboolean
-parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **error)
+parse_ip4 (GKeyFile *kf, GVariant **out_props, const char *section, GError **error)
{
+ GVariantBuilder props;
char *tmp;
char **split, **iter;
- GSList *list;
- GValue *val;
+ GPtrArray *addresses, *routes;
- *out_props = value_hash_create ();
+ g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}"));
/* search domains */
/* Use char** for domains. (DBUS_TYPE_G_ARRAY_OF_STRING of NMIP4Config
@@ -273,14 +220,15 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
if (g_strv_length (split) > 0) {
for (iter = split; iter && *iter; iter++)
g_strstrip (*iter);
- value_hash_add_strv (*out_props, "domains", split);
+ g_variant_builder_add (&props, "{sv}", "domains", g_variant_new_strv ((gpointer) split, -1));
+ g_strfreev (split);
}
/* nameservers */
- if (!add_uint_array (kf, *out_props, "ip4", "nameservers", error))
+ if (!add_uint_array (kf, &props, "ip4", "nameservers", error))
return FALSE;
/* wins-servers */
- if (!add_uint_array (kf, *out_props, "ip4", "wins-servers", error))
+ if (!add_uint_array (kf, &props, "ip4", "wins-servers", error))
return FALSE;
/* Addresses */
@@ -291,7 +239,7 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
g_free (tmp);
if (g_strv_length (split) > 0) {
- list = NULL;
+ addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_address_unref);
for (iter = split; iter && *iter; iter++) {
NMIP4Address *addr;
guint32 a;
@@ -317,13 +265,12 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
g_assert_cmpint (inet_pton (AF_INET, p, &a), ==, 1);
nm_ip4_address_set_gateway (addr, a);
- list = g_slist_append (list, addr);
+ g_ptr_array_add (addresses, addr);
}
- val = g_slice_new0 (GValue);
- g_value_init (val, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT);
- nm_utils_ip4_addresses_to_gvalue (list, val);
- value_hash_add (*out_props, "addresses", val);
+ g_variant_builder_add (&props, "{sv}", "addresses",
+ nm_utils_ip4_addresses_to_variant (addresses));
+ g_ptr_array_unref (addresses);
}
g_strfreev (split);
@@ -335,7 +282,7 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
g_free (tmp);
if (g_strv_length (split) > 0) {
- list = NULL;
+ routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_route_unref);
for (iter = split; iter && *iter; iter++) {
NMIP4Route *route;
guint32 a;
@@ -366,56 +313,58 @@ parse_ip4 (GKeyFile *kf, GHashTable **out_props, const char *section, GError **e
p++;
nm_ip4_route_set_metric (route, (guint) atoi (p));
- list = g_slist_append (list, route);
+ g_ptr_array_add (routes, route);
}
- val = g_slice_new0 (GValue);
- g_value_init (val, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT);
- nm_utils_ip4_routes_to_gvalue (list, val);
- value_hash_add (*out_props, "routes", val);
+ g_variant_builder_add (&props, "{sv}", "routes",
+ nm_utils_ip4_routes_to_variant (routes));
+ g_ptr_array_unref (routes);
}
g_strfreev (split);
}
+ *out_props = g_variant_builder_end (&props);
return TRUE;
}
static gboolean
parse_dhcp (GKeyFile *kf,
const char *group_name,
- GHashTable **out_props,
+ GVariant **out_props,
GError **error)
{
char **keys, **iter, *val;
+ GVariantBuilder props;
keys = g_key_file_get_keys (kf, group_name, NULL, error);
if (!keys)
return FALSE;
- *out_props = value_hash_create ();
+ g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}"));
for (iter = keys; iter && *iter; iter++) {
val = g_key_file_get_string (kf, group_name, *iter, error);
if (!val)
return FALSE;
- value_hash_add_string (*out_props, *iter, val);
+ g_variant_builder_add (&props, "{sv}", *iter, g_variant_new_string (val));
g_free (val);
}
+ *out_props = g_variant_builder_end (&props);
return TRUE;
}
static gboolean
get_dispatcher_file (const char *file,
- GHashTable **out_con_hash,
- GHashTable **out_con_props,
- GHashTable **out_device_props,
- GHashTable **out_device_ip4_props,
- GHashTable **out_device_ip6_props,
- GHashTable **out_device_dhcp4_props,
- GHashTable **out_device_dhcp6_props,
+ GVariant **out_con_dict,
+ GVariant **out_con_props,
+ GVariant **out_device_props,
+ GVariant **out_device_ip4_props,
+ GVariant **out_device_ip6_props,
+ GVariant **out_device_dhcp4_props,
+ GVariant **out_device_dhcp6_props,
char **out_vpn_ip_iface,
- GHashTable **out_vpn_ip4_props,
- GHashTable **out_vpn_ip6_props,
+ GVariant **out_vpn_ip4_props,
+ GVariant **out_vpn_ip6_props,
char **out_expected_iface,
char **out_action,
GHashTable **out_env,
@@ -430,7 +379,7 @@ get_dispatcher_file (const char *file,
return FALSE;
if (!parse_main (kf,
- out_con_hash,
+ out_con_dict,
out_con_props,
out_expected_iface,
out_action,
@@ -480,18 +429,18 @@ out:
/*******************************************/
static void
-test_generic (const char *path, const char *file, const char *override_vpn_ip_iface)
+test_generic (const char *file, const char *override_vpn_ip_iface)
{
- GHashTable *con_hash = NULL;
- GHashTable *con_props = NULL;
- GHashTable *device_props = NULL;
- GHashTable *device_ip4_props = NULL;
- GHashTable *device_ip6_props = NULL;
- GHashTable *device_dhcp4_props = NULL;
- GHashTable *device_dhcp6_props = NULL;
+ GVariant *con_dict = NULL;
+ GVariant *con_props = NULL;
+ GVariant *device_props = NULL;
+ GVariant *device_ip4_props = NULL;
+ GVariant *device_ip6_props = NULL;
+ GVariant *device_dhcp4_props = NULL;
+ GVariant *device_dhcp6_props = NULL;
char *vpn_ip_iface = NULL;
- GHashTable *vpn_ip4_props = NULL;
- GHashTable *vpn_ip6_props = NULL;
+ GVariant *vpn_ip4_props = NULL;
+ GVariant *vpn_ip6_props = NULL;
char *expected_iface = NULL;
char *action = NULL;
char *out_iface = NULL;
@@ -502,9 +451,9 @@ test_generic (const char *path, const char *file, const char *override_vpn_ip_if
char **denv, **iter;
/* Read in the test file */
- p = g_strdup_printf ("%s/%s", path, file);
+ p = g_build_filename (SRCDIR, file, NULL);
success = get_dispatcher_file (p,
- &con_hash,
+ &con_dict,
&con_props,
&device_props,
&device_ip4_props,
@@ -524,7 +473,7 @@ test_generic (const char *path, const char *file, const char *override_vpn_ip_if
/* Get the environment from the dispatcher code */
denv = nm_dispatcher_utils_construct_envp (action,
- con_hash,
+ con_dict,
con_props,
device_props,
device_ip4_props,
@@ -581,57 +530,57 @@ test_generic (const char *path, const char *file, const char *override_vpn_ip_if
g_free (vpn_ip_iface);
g_free (expected_iface);
g_free (action);
- g_hash_table_destroy (con_hash);
- g_hash_table_destroy (con_props);
- g_hash_table_destroy (device_props);
+ g_variant_unref (con_dict);
+ g_variant_unref (con_props);
+ g_variant_unref (device_props);
if (device_ip4_props)
- g_hash_table_destroy (device_ip4_props);
+ g_variant_unref (device_ip4_props);
if (device_ip6_props)
- g_hash_table_destroy (device_ip6_props);
+ g_variant_unref (device_ip6_props);
if (device_dhcp4_props)
- g_hash_table_destroy (device_dhcp4_props);
+ g_variant_unref (device_dhcp4_props);
if (device_dhcp6_props)
- g_hash_table_destroy (device_dhcp6_props);
+ g_variant_unref (device_dhcp6_props);
if (vpn_ip4_props)
- g_hash_table_destroy (vpn_ip4_props);
+ g_variant_unref (vpn_ip4_props);
if (vpn_ip6_props)
- g_hash_table_destroy (vpn_ip6_props);
+ g_variant_unref (vpn_ip6_props);
g_hash_table_destroy (expected_env);
}
/*******************************************/
static void
-test_old_up (const char *path)
+test_old_up (void)
{
- test_generic (path, "dispatcher-old-up", NULL);
+ test_generic ("dispatcher-old-up", NULL);
}
static void
-test_old_down (const char *path)
+test_old_down (void)
{
- test_generic (path, "dispatcher-old-down", NULL);
+ test_generic ("dispatcher-old-down", NULL);
}
static void
-test_old_vpn_up (const char *path)
+test_old_vpn_up (void)
{
- test_generic (path, "dispatcher-old-vpn-up", NULL);
+ test_generic ("dispatcher-old-vpn-up", NULL);
}
static void
-test_old_vpn_down (const char *path)
+test_old_vpn_down (void)
{
- test_generic (path, "dispatcher-old-vpn-down", NULL);
+ test_generic ("dispatcher-old-vpn-down", NULL);
}
static void
-test_up_empty_vpn_iface (const char *path)
+test_up_empty_vpn_iface (void)
{
/* Test that an empty VPN iface variable, like is passed through D-Bus
* from NM, is ignored by the dispatcher environment construction code.
*/
- test_generic (path, "dispatcher-old-up", "");
+ test_generic ("dispatcher-old-up", "");
}
/*******************************************/
@@ -639,20 +588,18 @@ test_up_empty_vpn_iface (const char *path)
int
main (int argc, char **argv)
{
- g_assert (argc > 1);
-
g_test_init (&argc, &argv, NULL);
#if !GLIB_CHECK_VERSION (2, 35, 0)
g_type_init ();
#endif
- g_test_add_data_func ("/dispatcher/old_up", argv[1], (GTestDataFunc) test_old_up);
- g_test_add_data_func ("/dispatcher/old_down", argv[1], (GTestDataFunc) test_old_down);
- g_test_add_data_func ("/dispatcher/old_vpn_up", argv[1], (GTestDataFunc) test_old_vpn_up);
- g_test_add_data_func ("/dispatcher/old_vpn_down", argv[1], (GTestDataFunc) test_old_vpn_down);
+ g_test_add_func ("/dispatcher/old_up", test_old_up);
+ g_test_add_func ("/dispatcher/old_down", test_old_down);
+ g_test_add_func ("/dispatcher/old_vpn_up", test_old_vpn_up);
+ g_test_add_func ("/dispatcher/old_vpn_down", test_old_vpn_down);
- g_test_add_data_func ("/dispatcher/up_empty_vpn_iface", argv[1], (GTestDataFunc) test_up_empty_vpn_iface);
+ g_test_add_func ("/dispatcher/up_empty_vpn_iface", test_up_empty_vpn_iface);
return g_test_run ();
}
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index d386440606..2a0497c342 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -1432,6 +1432,232 @@ nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value)
}
/**
+ * nm_utils_ip4_dns_to_variant:
+ * @dns: (type utf8): an array of IP address strings
+ *
+ * Utility function to convert an array of IP address strings int a #GVariant of
+ * type 'au' representing an array of IPv4 addresses.
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @dns.
+ **/
+GVariant *
+nm_utils_ip4_dns_to_variant (char **dns)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("au"));
+
+ if (dns) {
+ for (i = 0; dns[i]; i++) {
+ guint32 ip = 0;
+
+ inet_pton (AF_INET, dns[i], &ip);
+ g_variant_builder_add (&builder, "u", ip);
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip4_dns_from_variant:
+ * @value: a #GVariant of type 'au'
+ *
+ * Utility function to convert a #GVariant of type 'au' representing a list of
+ * IPv4 addresses into an array of IP address strings.
+ *
+ * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings.
+ **/
+char **
+nm_utils_ip4_dns_from_variant (GVariant *value)
+{
+ const guint32 *array;
+ gsize length;
+ char **dns;
+ int i;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("au")), NULL);
+
+ array = g_variant_get_fixed_array (value, &length, sizeof (guint32));
+ dns = g_new (char *, length + 1);
+
+ for (i = 0; i < length; i++)
+ dns[i] = g_strdup (nm_utils_inet4_ntop (array[i], NULL));
+ dns[i] = NULL;
+
+ return dns;
+}
+
+/**
+ * nm_utils_ip4_addresses_to_variant:
+ * @addresses: (element-type NMIP4Address): an array of #NMIP4Address objects
+ *
+ * Utility function to convert a #GPtrArray of #NMIP4Address objects into a
+ * #GVariant of type 'aau' representing an array of NetworkManager IPv4
+ * addresses (which are tuples of address, prefix, and gateway).
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @addresses.
+ **/
+GVariant *
+nm_utils_ip4_addresses_to_variant (GPtrArray *addresses)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau"));
+
+ if (addresses) {
+ for (i = 0; i < addresses->len; i++) {
+ NMIP4Address *addr = addresses->pdata[i];
+ guint32 array[3];
+
+ array[0] = nm_ip4_address_get_address (addr);
+ array[1] = nm_ip4_address_get_prefix (addr);
+ array[2] = nm_ip4_address_get_gateway (addr);
+
+ g_variant_builder_add (&builder, "@au",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
+ array, 3, sizeof (guint32)));
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip4_addresses_from_variant:
+ * @value: a #GVariant of type 'aau'
+ *
+ * Utility function to convert a #GVariant of type 'aau' representing a list of
+ * NetworkManager IPv4 addresses (which are tuples of address, prefix, and
+ * gateway) into a #GPtrArray of #NMIP4Address objects.
+ *
+ * Returns: (transfer full) (element-type NMIP4Address): a newly allocated
+ * #GPtrArray of #NMIP4Address objects
+ **/
+GPtrArray *
+nm_utils_ip4_addresses_from_variant (GVariant *value)
+{
+ GPtrArray *addresses;
+ GVariantIter iter;
+ GVariant *addr_var;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aau")), NULL);
+
+ g_variant_iter_init (&iter, value);
+ addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_address_unref);
+
+ while (g_variant_iter_next (&iter, "@au", &addr_var)) {
+ const guint32 *addr_array;
+ gsize length;
+ NMIP4Address *addr;
+
+ addr_array = g_variant_get_fixed_array (addr_var, &length, sizeof (guint32));
+ if (length < 3) {
+ g_warning ("Ignoring invalid IP4 address");
+ g_variant_unref (addr_var);
+ continue;
+ }
+
+ addr = nm_ip4_address_new ();
+ nm_ip4_address_set_address (addr, addr_array[0]);
+ nm_ip4_address_set_prefix (addr, addr_array[1]);
+ nm_ip4_address_set_gateway (addr, addr_array[2]);
+
+ g_ptr_array_add (addresses, addr);
+ g_variant_unref (addr_var);
+ }
+
+ return addresses;
+}
+
+/**
+ * nm_utils_ip4_routes_to_variant:
+ * @routes: (element-type NMIP4Route): an array of #NMIP4Route objects
+ *
+ * Utility function to convert a #GPtrArray of #NMIP4Route objects into a
+ * #GVariant of type 'aau' representing an array of NetworkManager IPv4 routes
+ * (which are tuples of route, prefix, next hop, and metric).
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @routes.
+ **/
+GVariant *
+nm_utils_ip4_routes_to_variant (GPtrArray *routes)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aau"));
+
+ if (routes) {
+ for (i = 0; i < routes->len; i++) {
+ NMIP4Route *route = routes->pdata[i];
+ guint32 array[4];
+
+ array[0] = nm_ip4_route_get_dest (route);
+ array[1] = nm_ip4_route_get_prefix (route);
+ array[2] = nm_ip4_route_get_next_hop (route);
+ array[3] = nm_ip4_route_get_metric (route);
+
+ g_variant_builder_add (&builder, "@au",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32,
+ array, 4, sizeof (guint32)));
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip4_routes_from_variant:
+ * @value: #GVariant of type 'aau'
+ *
+ * Utility function to convert a #GVariant of type 'aau' representing an array
+ * of NetworkManager IPv4 routes (which are tuples of route, prefix, next hop,
+ * and metric) into a #GPtrArray of #NMIP4Route objects.
+ *
+ * Returns: (transfer full) (element-type NMIP4Route): a newly allocated
+ * #GPtrArray of #NMIP4Route objects
+ **/
+GPtrArray *
+nm_utils_ip4_routes_from_variant (GVariant *value)
+{
+ GVariantIter iter;
+ GVariant *route_var;
+ GPtrArray *routes;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aau")), NULL);
+
+ g_variant_iter_init (&iter, value);
+ routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip4_route_unref);
+
+ while (g_variant_iter_next (&iter, "@au", &route_var)) {
+ const guint32 *route_array;
+ gsize length;
+ NMIP4Route *route;
+
+ route_array = g_variant_get_fixed_array (route_var, &length, sizeof (guint32));
+ if (length < 4) {
+ g_warning ("Ignoring invalid IP4 route");
+ g_variant_unref (route_var);
+ continue;
+ }
+
+ route = nm_ip4_route_new ();
+ nm_ip4_route_set_dest (route, route_array[0]);
+ nm_ip4_route_set_prefix (route, route_array[1]);
+ nm_ip4_route_set_next_hop (route, route_array[2]);
+ nm_ip4_route_set_metric (route, route_array[3]);
+
+ g_ptr_array_add (routes, route);
+ g_variant_unref (route_var);
+ }
+
+ return routes;
+}
+
+/**
* nm_utils_ip4_netmask_to_prefix:
* @netmask: an IPv4 netmask in network byte order
*
@@ -2117,6 +2343,288 @@ nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value)
}
/**
+ * nm_utils_ip6_dns_to_variant:
+ * @dns: (type utf8): an array of IP address strings
+ *
+ * Utility function to convert an array of IP address strings int a #GVariant of
+ * type 'aay' representing an array of IPv6 addresses.
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @dns.
+ **/
+GVariant *
+nm_utils_ip6_dns_to_variant (char **dns)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aay"));
+
+ if (dns) {
+ for (i = 0; dns[i]; i++) {
+ struct in6_addr ip;
+
+ inet_pton (AF_INET6, dns[i], &ip);
+ g_variant_builder_add (&builder, "@ay",
+ g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ &ip, sizeof (ip), 1));
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip6_dns_from_variant:
+ * @value: a #GVariant of type 'aay'
+ *
+ * Utility function to convert a #GVariant of type 'aay' representing a list of
+ * IPv6 addresses into an array of IP address strings.
+ *
+ * Returns: (transfer full) (type utf8): a %NULL-terminated array of IP address strings.
+ **/
+char **
+nm_utils_ip6_dns_from_variant (GVariant *value)
+{
+ GVariantIter iter;
+ GVariant *ip_var;
+ char **dns;
+ int i;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aay")), NULL);
+
+ dns = g_new (char *, g_variant_n_children (value) + 1);
+
+ g_variant_iter_init (&iter, value);
+ i = 0;
+ while (g_variant_iter_next (&iter, "@ay", &ip_var)) {
+ gsize length;
+ const struct in6_addr *ip = g_variant_get_fixed_array (ip_var, &length, 1);
+
+ if (length != sizeof (struct in6_addr)) {
+ g_warning ("%s: ignoring invalid IP6 address of length %d",
+ __func__, (int) length);
+ g_variant_unref (ip_var);
+ continue;
+ }
+
+ dns[i++] = g_strdup (nm_utils_inet6_ntop (ip, NULL));
+ g_variant_unref (ip_var);
+ }
+ dns[i] = NULL;
+
+ return dns;
+}
+
+/**
+ * nm_utils_ip6_addresses_to_variant:
+ * @addresses: (element-type NMIP6Address): an array of #NMIP6Address objects
+ *
+ * Utility function to convert a #GPtrArray of #NMIP6Address objects into a
+ * #GVariant of type 'a(ayuay)' representing an array of NetworkManager IPv6
+ * addresses (which are tuples of address, prefix, and gateway).
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @addresses.
+ **/
+GVariant *
+nm_utils_ip6_addresses_to_variant (GPtrArray *addresses)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuay)"));
+
+ if (addresses) {
+ for (i = 0; i < addresses->len; i++) {
+ NMIP6Address *addr = addresses->pdata[i];
+ GVariant *ip, *gateway;
+ guint32 prefix;
+
+ ip = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ nm_ip6_address_get_address (addr),
+ 16, 1);
+ prefix = nm_ip6_address_get_prefix (addr);
+ gateway = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ nm_ip6_address_get_gateway (addr),
+ 16, 1);
+
+ g_variant_builder_add (&builder, "(@ayu@ay)", ip, prefix, gateway);
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip6_addresses_from_variant:
+ * @value: a #GVariant of type 'a(ayuay)'
+ *
+ * Utility function to convert a #GVariant of type 'a(ayuay)' representing a
+ * list of NetworkManager IPv6 addresses (which are tuples of address, prefix,
+ * and gateway) into a #GPtrArray of #NMIP6Address objects.
+ *
+ * Returns: (transfer full) (element-type NMIP6Address): a newly allocated
+ * #GPtrArray of #NMIP6Address objects
+ **/
+GPtrArray *
+nm_utils_ip6_addresses_from_variant (GVariant *value)
+{
+ GVariantIter iter;
+ GVariant *addr_var, *gateway_var;
+ guint32 prefix;
+ GPtrArray *addresses;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(ayuay)")), NULL);
+
+ g_variant_iter_init (&iter, value);
+ addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_address_unref);
+
+ while (g_variant_iter_next (&iter, "(@ayu@ay)", &addr_var, &prefix, &gateway_var)) {
+ NMIP6Address *addr;
+ const struct in6_addr *addr_bytes, *gateway_bytes;
+ gsize addr_len, gateway_len;
+
+ if ( !g_variant_is_of_type (addr_var, G_VARIANT_TYPE_BYTESTRING)
+ || !g_variant_is_of_type (gateway_var, G_VARIANT_TYPE_BYTESTRING)) {
+ g_warning ("%s: ignoring invalid IP6 address structure", __func__);
+ goto next;
+ }
+
+ addr_bytes = g_variant_get_fixed_array (addr_var, &addr_len, 1);
+ if (addr_len != 16) {
+ g_warning ("%s: ignoring invalid IP6 address of length %d",
+ __func__, (int) addr_len);
+ goto next;
+ }
+ if (prefix > 128) {
+ g_warning ("%s: ignoring invalid IP6 prefix %d",
+ __func__, prefix);
+ goto next;
+ }
+ gateway_bytes = g_variant_get_fixed_array (gateway_var, &gateway_len, 1);
+ if (gateway_len != 16) {
+ g_warning ("%s: ignoring invalid IP6 address of length %d",
+ __func__, (int) gateway_len);
+ goto next;
+ }
+
+ addr = nm_ip6_address_new ();
+ nm_ip6_address_set_address (addr, addr_bytes);
+ nm_ip6_address_set_prefix (addr, prefix);
+ nm_ip6_address_set_gateway (addr, gateway_bytes);
+ g_ptr_array_add (addresses, addr);
+
+ next:
+ g_variant_unref (addr_var);
+ g_variant_unref (gateway_var);
+ }
+
+ return addresses;
+}
+
+/**
+ * nm_utils_ip6_routes_to_variant:
+ * @routes: (element-type NMIP6Route): an array of #NMIP6Route objects
+ *
+ * Utility function to convert a #GPtrArray of #NMIP6Route objects into a
+ * #GVariant of type 'a(ayuayu)' representing an array of NetworkManager IPv6
+ * routes (which are tuples of route, prefix, next hop, and metric).
+ *
+ * Returns: (transfer none): a new floating #GVariant representing @routes.
+ **/
+GVariant *
+nm_utils_ip6_routes_to_variant (GPtrArray *routes)
+{
+ GVariantBuilder builder;
+ int i;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayuayu)"));
+
+ if (routes) {
+ for (i = 0; i < routes->len; i++) {
+ NMIP6Route *route = routes->pdata[i];
+ GVariant *dest, *next_hop;
+ guint32 prefix, metric;
+
+ dest = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ nm_ip6_route_get_dest (route),
+ 16, 1);
+ prefix = nm_ip6_route_get_prefix (route);
+ next_hop = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
+ nm_ip6_route_get_next_hop (route),
+ 16, 1);
+ metric = nm_ip6_route_get_metric (route);
+
+ g_variant_builder_add (&builder, "(@ayu@ayu)", dest, prefix, next_hop, metric);
+ }
+ }
+
+ return g_variant_builder_end (&builder);
+}
+
+/**
+ * nm_utils_ip6_routes_from_variant:
+ * @value: #GVariant of type 'a(ayuayu)'
+ *
+ * Utility function to convert a #GVariant of type 'a(ayuayu)' representing an
+ * array of NetworkManager IPv6 routes (which are tuples of route, prefix, next
+ * hop, and metric) into a #GPtrArray of #NMIP6Route objects.
+ *
+ * Returns: (transfer full) (element-type NMIP6Route): a newly allocated
+ * #GPtrArray of #NMIP6Route objects
+ **/
+GPtrArray *
+nm_utils_ip6_routes_from_variant (GVariant *value)
+{
+ GPtrArray *routes;
+ GVariantIter iter;
+ GVariant *dest_var, *next_hop_var;
+ const struct in6_addr *dest, *next_hop;
+ gsize dest_len, next_hop_len;
+ guint32 prefix, metric;
+
+ g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("a(ayuayu)")), NULL);
+
+ routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip6_route_unref);
+
+ g_variant_iter_init (&iter, value);
+ while (g_variant_iter_next (&iter, "(@ayu@ayu)", &dest_var, &prefix, &next_hop_var, &metric)) {
+ NMIP6Route *route;
+
+ if ( !g_variant_is_of_type (dest_var, G_VARIANT_TYPE_BYTESTRING)
+ || !g_variant_is_of_type (next_hop_var, G_VARIANT_TYPE_BYTESTRING)) {
+ g_warning ("%s: ignoring invalid IP6 address structure", __func__);
+ goto next;
+ }
+
+ dest = g_variant_get_fixed_array (dest_var, &dest_len, 1);
+ if (dest_len != 16) {
+ g_warning ("%s: ignoring invalid IP6 address of length %d",
+ __func__, (int) dest_len);
+ goto next;
+ }
+ next_hop = g_variant_get_fixed_array (next_hop_var, &next_hop_len, 1);
+ if (next_hop_len != 16) {
+ g_warning ("%s: ignoring invalid IP6 address of length %d",
+ __func__, (int) next_hop_len);
+ goto next;
+ }
+
+ route = nm_ip6_route_new ();
+ nm_ip6_route_set_dest (route, dest);
+ nm_ip6_route_set_prefix (route, prefix);
+ nm_ip6_route_set_next_hop (route, next_hop);
+ nm_ip6_route_set_metric (route, metric);
+ g_ptr_array_add (routes, route);
+
+ next:
+ g_variant_unref (dest_var);
+ g_variant_unref (next_hop_var);
+ }
+
+ return routes;
+}
+
+/**
* nm_utils_uuid_generate:
*
* Returns: a newly allocated UUID suitable for use as the #NMSettingConnection
diff --git a/libnm-core/nm-utils.h b/libnm-core/nm-utils.h
index b6b9db583b..5c11112357 100644
--- a/libnm-core/nm-utils.h
+++ b/libnm-core/nm-utils.h
@@ -101,6 +101,13 @@ void nm_utils_ip4_addresses_to_gvalue (GSList *list, GValue *value);
GSList *nm_utils_ip4_routes_from_gvalue (const GValue *value);
void nm_utils_ip4_routes_to_gvalue (GSList *list, GValue *value);
+GVariant *nm_utils_ip4_dns_to_variant (char **dns);
+char **nm_utils_ip4_dns_from_variant (GVariant *value);
+GVariant *nm_utils_ip4_addresses_to_variant (GPtrArray *addresses);
+GPtrArray *nm_utils_ip4_addresses_from_variant (GVariant *value);
+GVariant *nm_utils_ip4_routes_to_variant (GPtrArray *routes);
+GPtrArray *nm_utils_ip4_routes_from_variant (GVariant *value);
+
guint32 nm_utils_ip4_netmask_to_prefix (guint32 netmask);
guint32 nm_utils_ip4_prefix_to_netmask (guint32 prefix);
guint32 nm_utils_ip4_get_default_prefix (guint32 ip);
@@ -114,6 +121,13 @@ void nm_utils_ip6_routes_to_gvalue (GSList *list, GValue *value);
GSList *nm_utils_ip6_dns_from_gvalue (const GValue *value);
void nm_utils_ip6_dns_to_gvalue (GSList *list, GValue *value);
+GVariant *nm_utils_ip6_dns_to_variant (char **dns);
+char **nm_utils_ip6_dns_from_variant (GVariant *value);
+GVariant *nm_utils_ip6_addresses_to_variant (GPtrArray *addresses);
+GPtrArray *nm_utils_ip6_addresses_from_variant (GVariant *value);
+GVariant *nm_utils_ip6_routes_to_variant (GPtrArray *routes);
+GPtrArray *nm_utils_ip6_routes_from_variant (GVariant *value);
+
char *nm_utils_uuid_generate (void);
char *nm_utils_uuid_generate_from_string (const char *s);
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index e0592f548f..d48731c474 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -880,18 +880,30 @@ global:
nm_utils_inet6_ntop;
nm_utils_init;
nm_utils_ip4_addresses_from_gvalue;
+ nm_utils_ip4_addresses_from_variant;
nm_utils_ip4_addresses_to_gvalue;
+ nm_utils_ip4_addresses_to_variant;
+ nm_utils_ip4_dns_from_variant;
+ nm_utils_ip4_dns_to_variant;
nm_utils_ip4_get_default_prefix;
nm_utils_ip4_netmask_to_prefix;
nm_utils_ip4_prefix_to_netmask;
nm_utils_ip4_routes_from_gvalue;
+ nm_utils_ip4_routes_from_variant;
nm_utils_ip4_routes_to_gvalue;
+ nm_utils_ip4_routes_to_variant;
nm_utils_ip6_addresses_from_gvalue;
+ nm_utils_ip6_addresses_from_variant;
nm_utils_ip6_addresses_to_gvalue;
+ nm_utils_ip6_addresses_to_variant;
nm_utils_ip6_dns_from_gvalue;
+ nm_utils_ip6_dns_from_variant;
nm_utils_ip6_dns_to_gvalue;
+ nm_utils_ip6_dns_to_variant;
nm_utils_ip6_routes_from_gvalue;
+ nm_utils_ip6_routes_from_variant;
nm_utils_ip6_routes_to_gvalue;
+ nm_utils_ip6_routes_to_variant;
nm_utils_is_empty_ssid;
nm_utils_is_uuid;
nm_utils_rsa_key_encrypt;