1    	/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2    	/*
3    	 * This program is free software; you can redistribute it and/or modify
4    	 * it under the terms of the GNU General Public License as published by
5    	 * the Free Software Foundation; either version 2 of the License, or
6    	 * (at your option) any later version.
7    	 *
8    	 * This program is distributed in the hope that it will be useful,
9    	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   	 * GNU General Public License for more details.
12   	 *
13   	 * You should have received a copy of the GNU General Public License along
14   	 * with this program; if not, write to the Free Software Foundation, Inc.,
15   	 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16   	 *
17   	 * (C) Copyright 2010 Red Hat, Inc.
18   	 */
19   	
20   	/*
21   	 * The example shows how to call the D-Bus properties interface to get the
22   	 * list of currently active connections known to NetworkManager.  It uses
23   	 * dbus-glib and libnm-util libraries.
24   	 *
25   	 * Compile with:
26   	 *   gcc -Wall `pkg-config --libs --cflags glib-2.0 dbus-glib-1 libnm-util` get-active-connections-dbus-glib.c -o get-active-connections-dbus-glib
27   	 */
28   	
29   	#include <glib.h>
30   	#include <dbus/dbus-glib.h>
31   	
32   	#include <nm-connection.h>
33   	#include <nm-setting-connection.h>
34   	#include <nm-setting-wired.h>
35   	#include <nm-setting-ip4-config.h>
36   	#include <NetworkManager.h>
37   	#include <nm-utils.h>
38   	
39   	#define DBUS_TYPE_G_MAP_OF_VARIANT          (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
40   	#define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT   (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT))
41   	#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH    (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))
42   	
43   	static void
44   	print_connection (DBusGConnection *bus, const char *service, const char *path)
45   	{
46   		DBusGProxy *proxy;
47   		GError *error = NULL;
48   		GHashTable *hash = NULL;
49   		NMConnection *connection = NULL;
50   	
51   		/* This function asks the Settings Service that provides this network
52   		 * configuration for the details of that configuration.
53   		 */
54   	
55   		/* Create the D-Bus proxy for the Settings Service so we can ask it for the
56   		 * connection configuration details.
57   		 */
58   		proxy = dbus_g_proxy_new_for_name (bus,
59   		                                   service,
60   		                                   path,
61   		                                   NM_DBUS_IFACE_SETTINGS_CONNECTION);
62   		g_assert (proxy);
63   	
64   		/* Request the all the configuration of the Connection */
(5) Event example_checked: Example3: "dbus_g_proxy_call(proxy, "GetSettings", &error, 0UL, dbus_g_type_get_map("GHashTable", 64UL, dbus_g_type_get_map("GHashTable", 64UL, g_value_get_type())), &hash, 0UL)" has its value checked in "dbus_g_proxy_call(proxy, "GetSettings", &error, 0UL, dbus_g_type_get_map("GHashTable", 64UL, dbus_g_type_get_map("GHashTable", 64UL, g_value_get_type())), &hash, 0UL)".
Also see events: [check_return][example_checked][example_checked][example_checked][example_checked][unchecked_value]
65   		if (!dbus_g_proxy_call (proxy, "GetSettings", &error,
66   		                        G_TYPE_INVALID,
67   		                        DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &hash,
68   		                        G_TYPE_INVALID)) {
69   			g_warning ("Failed to get active connection Connection property: %s",
70   			           error->message);
71   			g_error_free (error);
72   			goto out;
73   		}
74   	
75   		/* Using the raw configuration, create an NMConnection object for it.  This
76   		 * step also verifies that the data we got from the settings service is
77   		 * valid. */
78   		connection = nm_connection_new_from_hash (hash, &error);
79   		if (!connection) {
80   			g_warning ("Received invalid connection data: %s", error->message);
81   			g_error_free (error);
82   			goto out;
83   		}
84   	
85   		/* And finally dump all the configuration to stdout */
86   		g_message ("%s => %s", service, path);
87   		nm_connection_dump (connection);
88   	
89   	out:
90   		if (connection)
91   			g_object_unref (connection);
92   		if (hash)
93   			g_hash_table_destroy (hash);
94   		g_object_unref (proxy);
95   	}
96   	
97   	static void
98   	get_active_connection_details (DBusGConnection *bus, const char *obj_path)
99   	{
100  		DBusGProxy *props_proxy;
101  		GValue path_value = G_VALUE_INIT;
102  		GValue serv_value = G_VALUE_INIT;
103  		GError *error = NULL;
104  		const char *path = NULL, *service = NULL;
105  	
106  		/* This function gets the backing Connection object that describes the
107  		 * network configuration that the ActiveConnection object is actually using.
108  		 * The ActiveConnection object contains the mapping between the configuration
109  		 * and the actual network interfaces that are using that configuration.
110  		 */
111  	
112  		/* Create a D-Bus object proxy for the active connection object's properties */
113  		props_proxy = dbus_g_proxy_new_for_name (bus,
114  		                                         NM_DBUS_SERVICE,
115  		                                         obj_path,
116  		                                         DBUS_INTERFACE_PROPERTIES);
117  		g_assert (props_proxy);
118  		
119  		/* Get the object path of the Connection details */
120  		if (!dbus_g_proxy_call (props_proxy, "Get", &error,
121  		                        G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
122  		                        G_TYPE_STRING, "Connection",
123  		                        G_TYPE_INVALID,
124  		                        G_TYPE_VALUE, &path_value,
125  		                        G_TYPE_INVALID)) {
126  			g_warning ("Failed to get active connection Connection property: %s",
127  			           error->message);
128  			g_error_free (error);
129  			goto out;
130  		}
131  	
132  		if (!G_VALUE_HOLDS (&path_value, DBUS_TYPE_G_OBJECT_PATH)) {
133  			g_warning ("Unexpected type returned getting Connection property: %s",
134  			           G_VALUE_TYPE_NAME (&path_value));
135  			goto out;
136  		}
137  	
138  		path = g_value_get_boxed (&path_value);
139  		if (!path) {
140  			g_warning ("Missing connection path!");
141  			goto out;
142  		}
143  	
144  		/* Get the service name of the D-Bus service that provides the Connection */
145  		if (!dbus_g_proxy_call (props_proxy, "Get", &error,
146  		                        G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
147  		                        G_TYPE_STRING, "ServiceName",
148  		                        G_TYPE_INVALID,
149  		                        G_TYPE_VALUE, &serv_value,
150  		                        G_TYPE_INVALID)) {
151  			g_warning ("Failed to get active connection ServiceName property: %s",
152  			           error->message);
153  			g_error_free (error);
154  			goto out;
155  		}
156  	
157  		if (!G_VALUE_HOLDS (&serv_value, G_TYPE_STRING)) {
158  			g_warning ("Unexpected type returned getting Connection property: %s",
159  			           G_VALUE_TYPE_NAME (&serv_value));
160  			goto out;
161  		}
162  	
163  		service = g_value_get_string (&serv_value);
164  		if (!service) {
165  			g_warning ("Missing connection service name!");
166  			goto out;
167  		}
168  	
169  		/* Print out the actual connection details */
170  		print_connection (bus, service, path);
171  	
172  	out:
173  		g_value_unset (&path_value);
174  		g_value_unset (&serv_value);
175  		g_object_unref (props_proxy);
176  	}
177  	
178  	static void
179  	get_active_connections (DBusGConnection *bus, DBusGProxy *proxy)
180  	{
181  		GError *error = NULL;
182  		GValue value = G_VALUE_INIT;
183  		GPtrArray *paths = NULL;
184  		int i;
185  	
186  		/* Get the ActiveConnections property from the NM Manager object */
187  		if (!dbus_g_proxy_call (proxy, "Get", &error,
188  		                        G_TYPE_STRING, NM_DBUS_INTERFACE,
189  		                        G_TYPE_STRING, "ActiveConnections",
190  		                        G_TYPE_INVALID,
191  		                        G_TYPE_VALUE, &value,
192  		                        G_TYPE_INVALID)) {
193  			g_warning ("Failed to get ActiveConnections property: %s", error->message);
194  			g_error_free (error);
195  			return;
196  		}
197  	
198  		/* Make sure the ActiveConnections property is the type we expect it to be */
199  		if (!G_VALUE_HOLDS (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) {
200  			g_warning ("Unexpected type returned getting ActiveConnections: %s",
201  			           G_VALUE_TYPE_NAME (&value));
202  			goto out;
203  		}
204  	
205  		/* Extract the active connections array from the GValue */
206  		paths = g_value_get_boxed (&value);
207  		if (!paths) {
208  			g_warning ("Could not retrieve active connections property");
209  			goto out;
210  		}
211  	
212  		/* And print out the details of each active connection */
213  		for (i = 0; i < paths->len; i++)
214  			get_active_connection_details (bus, g_ptr_array_index (paths, i));
215  	
216  	out:
217  		g_value_unset (&value);
218  	}
219  	
220  	
221  	int main (int argc, char *argv[])
222  	{
223  		DBusGConnection *bus;
224  		DBusGProxy *props_proxy;
225  	
226  		/* Initialize GType system */
227  		g_type_init ();
228  	
229  		/* Get system bus */
230  		bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
231  	
232  		/* Create a D-Bus proxy to get the object properties from the NM Manager
233  		 * object.  NM_DBUS_* defines are from NetworkManager.h.
234  		 */
235  		props_proxy = dbus_g_proxy_new_for_name (bus,
236  		                                         NM_DBUS_SERVICE,
237  		                                         NM_DBUS_PATH,
238  		                                         DBUS_INTERFACE_PROPERTIES);
239  		g_assert (props_proxy);
240  	
241  		/* Get active connections */
242  		get_active_connections (bus, props_proxy);
243  	
244  		g_object_unref (props_proxy);
245  		dbus_g_connection_unref (bus);
246  	
247  		return 0;
248  	}
249