2006-10-13 Dan Williams <dcbw@redhat.com>

* Huge DBus refactor:
		- Create a "DBus Manager" object which manages the connection and
		sends signals on NameOwnerChanged and connection/disconnection events,
		handles reconnection to the bus if NM gets kicked off, and abstracts
		signal handling
		- Remove DBusConnection members from places where they are no
		longer needed due to the refactor, like the dbus-connection
		property of the named manager, and from NMData
		- Reformats a bunch of the code to gnome style
		(8-space tabs, braces on same line as statement, 80-col width).
		Consider it open season to reformat any bits to gnome style.
		style that aren't already.


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2061 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2006-10-13 19:41:47 +00:00
parent 129d0ca46d
commit 84678fc9fe
38 changed files with 4569 additions and 2771 deletions

View File

@@ -1,3 +1,18 @@
2006-10-13 Dan Williams <dcbw@redhat.com>
* Huge DBus refactor:
- Create a "DBus Manager" object which manages the connection and
sends signals on NameOwnerChanged and connection/disconnection events,
handles reconnection to the bus if NM gets kicked off, and abstracts
signal handling
- Remove DBusConnection members from places where they are no
longer needed due to the refactor, like the dbus-connection
property of the named manager, and from NMData
- Reformats a bunch of the code to gnome style
(8-space tabs, braces on same line as statement, 80-col width).
Consider it open season to reformat any bits to gnome style.
style that aren't already.
2006-10-13 Dan Williams <dcbw@redhat.com> 2006-10-13 Dan Williams <dcbw@redhat.com>
* src/supplicant-manager/Makefile.am * src/supplicant-manager/Makefile.am

View File

@@ -27,6 +27,8 @@ NetworkManager_SOURCES = \
NetworkManagerDbusUtils.c \ NetworkManagerDbusUtils.c \
NetworkManagerDialup.h \ NetworkManagerDialup.h \
NetworkManagerDbusUtils.h \ NetworkManagerDbusUtils.h \
nm-dbus-manager.h \
nm-dbus-manager.c \
nm-dbus-nm.c \ nm-dbus-nm.c \
nm-dbus-nm.h \ nm-dbus-nm.h \
nm-dbus-device.c \ nm-dbus-device.c \

View File

@@ -52,6 +52,10 @@
#include "nm-named-manager.h" #include "nm-named-manager.h"
#include "nm-vpn-act-request.h" #include "nm-vpn-act-request.h"
#include "nm-dbus-vpn.h" #include "nm-dbus-vpn.h"
#include "nm-dbus-nm.h"
#include "nm-dbus-manager.h"
#include "nm-dbus-device.h"
#include "nm-dbus-net.h"
#include "nm-netlink-monitor.h" #include "nm-netlink-monitor.h"
#include "nm-dhcp-manager.h" #include "nm-dhcp-manager.h"
#include "nm-logging.h" #include "nm-logging.h"
@@ -60,6 +64,8 @@
#define NM_DEFAULT_PID_FILE LOCALSTATEDIR"/run/NetworkManager.pid" #define NM_DEFAULT_PID_FILE LOCALSTATEDIR"/run/NetworkManager.pid"
#define NO_HAL_MSG "Could not initialize connection to the HAL daemon."
/* /*
* Globals * Globals
*/ */
@@ -67,6 +73,7 @@ static NMData *nm_data = NULL;
static gboolean sigterm_pipe_handler (GIOChannel *src, GIOCondition condition, gpointer data); static gboolean sigterm_pipe_handler (GIOChannel *src, GIOCondition condition, gpointer data);
static void nm_data_free (NMData *data); static void nm_data_free (NMData *data);
static void nm_hal_deinit (NMData *data);
/* /*
* nm_get_device_interface_from_hal * nm_get_device_interface_from_hal
@@ -208,21 +215,6 @@ NMDevice *nm_get_active_device (NMData *data)
} }
/* Hal doesn't really give us any way to pass a GMainContext to our
* mainloop integration function unfortunately. So we have to use
* a global.
*/
GMainContext *main_context = NULL;
/*
* nm_hal_mainloop_integration
*
*/
static void nm_hal_mainloop_integration (LibHalContext *ctx, DBusConnection * dbus_connection)
{
dbus_connection_setup_with_g_main (dbus_connection, main_context);
}
/* /*
* nm_hal_device_added * nm_hal_device_added
* *
@@ -348,10 +340,16 @@ void nm_add_initial_devices (NMData *data)
static gboolean nm_state_change_signal_broadcast (gpointer user_data) static gboolean nm_state_change_signal_broadcast (gpointer user_data)
{ {
NMData *data = (NMData *)user_data; NMData *data = (NMData *)user_data;
NMDBusManager *dbus_mgr = NULL;
DBusConnection *dbus_connection = NULL;
g_return_val_if_fail (data != NULL, FALSE); g_return_val_if_fail (data != NULL, FALSE);
nm_dbus_signal_state_change (data->dbus_connection, data); dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (dbus_connection)
nm_dbus_signal_state_change (dbus_connection, data);
g_object_unref (dbus_mgr);
return FALSE; return FALSE;
} }
@@ -413,6 +411,87 @@ nm_monitor_setup (NMData *data)
return monitor; return monitor;
} }
static gboolean
nm_hal_init (NMData *data,
DBusConnection *connection)
{
gboolean success = FALSE;
DBusError error;
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
/* Clean up an old context */
if (data->hal_ctx) {
nm_warning ("a HAL context already existed. BUG.");
nm_hal_deinit (data);
}
/* Initialize a new libhal context */
if (!(data->hal_ctx = libhal_ctx_new ())) {
nm_warning ("Could not get connection to the HAL service.");
goto out;
}
libhal_ctx_set_dbus_connection (data->hal_ctx, connection);
dbus_error_init (&error);
if (!libhal_ctx_init (data->hal_ctx, &error)) {
nm_error ("libhal_ctx_init() failed: %s\n"
"Make sure the hal daemon is running?",
error.message);
goto out;
}
libhal_ctx_set_user_data (data->hal_ctx, data->main_context);
libhal_ctx_set_device_added (data->hal_ctx, nm_hal_device_added);
libhal_ctx_set_device_removed (data->hal_ctx, nm_hal_device_removed);
libhal_ctx_set_device_new_capability (data->hal_ctx, nm_hal_device_new_capability);
libhal_device_property_watch_all (data->hal_ctx, &error);
if (dbus_error_is_set (&error)) {
nm_error ("libhal_device_property_watch_all(): %s", error.message);
libhal_ctx_shutdown (data->hal_ctx, NULL);
goto out;
}
/* Add any devices we know about */
nm_add_initial_devices (data);
success = TRUE;
out:
if (!success) {
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (data->hal_ctx) {
libhal_ctx_free (data->hal_ctx);
data->hal_ctx = NULL;
}
}
return success;
}
static void
nm_hal_deinit (NMData *data)
{
DBusError error;
g_return_if_fail (data != NULL);
if (!data->hal_ctx)
return;
dbus_error_init (&error);
libhal_ctx_shutdown (data->hal_ctx, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("libhal shutdown failed - %s", error.message);
dbus_error_free (&error);
}
libhal_ctx_free (data->hal_ctx);
data->hal_ctx = NULL;
}
/* /*
* nm_data_new * nm_data_new
@@ -524,6 +603,9 @@ static void nm_data_free (NMData *data)
nm_ap_list_unref (data->allowed_ap_list); nm_ap_list_unref (data->allowed_ap_list);
nm_ap_list_unref (data->invalid_ap_list); nm_ap_list_unref (data->invalid_ap_list);
nm_dbus_method_list_unref (data->nm_methods);
nm_dbus_method_list_unref (data->device_methods);
nm_vpn_manager_dispose (data->vpn_manager); nm_vpn_manager_dispose (data->vpn_manager);
nm_dhcp_manager_dispose (data->dhcp_manager); nm_dhcp_manager_dispose (data->dhcp_manager);
g_object_unref (data->named_manager); g_object_unref (data->named_manager);
@@ -552,81 +634,55 @@ static gboolean sigterm_pipe_handler (GIOChannel *src, GIOCondition condition, g
return FALSE; return FALSE;
} }
static LibHalContext *nm_get_hal_ctx (NMData *data) static void
nm_name_owner_changed_handler (NMDBusManager *mgr,
DBusConnection *connection,
const char *name,
const char *old,
const char *new,
gpointer user_data)
{ {
LibHalContext * ctx = NULL; NMData * data = (NMData *) user_data;
DBusError error; gboolean old_owner_good = (old && (strlen (old) > 0));
gboolean new_owner_good = (new && (strlen (new) > 0));
g_return_val_if_fail (data != NULL, NULL); /* Only care about signals from HAL */
if (strcmp (name, "org.freedesktop.Hal") != 0)
return;
/* Initialize libhal. We get a connection to the hal daemon here. */ if (!old_owner_good && new_owner_good) {
if ((ctx = libhal_ctx_new()) == NULL) /* HAL just appeared */
{ if (!nm_hal_init (data, connection)) {
nm_error ("libhal_ctx_new() failed, exiting..."); nm_error (NO_HAL_MSG);
return NULL; exit (EXIT_FAILURE);
} }
} else if (old_owner_good && !new_owner_good) {
nm_hal_mainloop_integration (ctx, data->dbus_connection); /* HAL went away. Bad HAL. */
libhal_ctx_set_dbus_connection (ctx, data->dbus_connection); nm_hal_deinit (data);
dbus_error_init (&error);
if(!libhal_ctx_init (ctx, &error))
{
nm_error ("libhal_ctx_init() failed: %s\n"
"Make sure the hal daemon is running?",
error.message);
dbus_error_free (&error);
libhal_ctx_free (ctx);
return NULL;
}
libhal_ctx_set_user_data (ctx, data);
libhal_ctx_set_device_added (ctx, nm_hal_device_added);
libhal_ctx_set_device_removed (ctx, nm_hal_device_removed);
libhal_ctx_set_device_new_capability (ctx, nm_hal_device_new_capability);
dbus_error_init (&error);
libhal_device_property_watch_all (ctx, &error);
if (dbus_error_is_set (&error))
{
nm_error ("libhal_device_property_watch_all(): %s", error.message);
dbus_error_free (&error);
libhal_ctx_free (ctx);
}
return ctx;
}
void nm_hal_init (NMData *data)
{
g_return_if_fail (data != NULL);
if ((data->hal_ctx = nm_get_hal_ctx (data)))
nm_add_initial_devices (data);
}
void nm_hal_deinit (NMData *data)
{
g_return_if_fail (data != NULL);
if (data->hal_ctx)
{
DBusError error;
dbus_error_init (&error);
libhal_ctx_shutdown (data->hal_ctx, &error);
if (dbus_error_is_set (&error))
{
nm_warning ("libhal shutdown failed - %s", error.message);
dbus_error_free (&error);
}
libhal_ctx_free (data->hal_ctx);
data->hal_ctx = NULL;
} }
} }
static void
nm_dbus_connection_changed_handler (NMDBusManager *mgr,
DBusConnection *connection,
gpointer user_data)
{
NMData *data = (NMData *) user_data;
char * owner;
if (!connection) {
nm_hal_deinit (data);
return;
}
if ((owner = nm_dbus_manager_get_name_owner (mgr, "org.freedesktop.Hal"))) {
if (!nm_hal_init (data, connection)) {
nm_error (NO_HAL_MSG);
exit (EXIT_FAILURE);
}
g_free (owner);
}
}
static void static void
write_pidfile (const char *pidfile) write_pidfile (const char *pidfile)
@@ -669,28 +725,19 @@ static void nm_print_usage (void)
* main * main
* *
*/ */
int main( int argc, char *argv[] ) int
main (int argc, char *argv[])
{ {
GOptionContext *opt_ctx = NULL;
gboolean become_daemon = FALSE; gboolean become_daemon = FALSE;
gboolean enable_test_devices = FALSE; gboolean enable_test_devices = FALSE;
gboolean show_usage = FALSE; gboolean show_usage = FALSE;
char * owner;
char * pidfile = NULL; char * pidfile = NULL;
char * user_pidfile = NULL; char * user_pidfile = NULL;
NMDBusManager * dbus_mgr;
DBusConnection *dbus_connection;
int exit_status = EXIT_FAILURE;
if (getuid () != 0)
{
g_printerr ("You must be root to run NetworkManager!\n");
return (EXIT_FAILURE);
}
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
/* Parse options */
{
GOptionContext *opt_ctx = NULL;
GOptionEntry options[] = { GOptionEntry options[] = {
{"no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL}, {"no-daemon", 0, 0, G_OPTION_ARG_NONE, &become_daemon, "Don't become a daemon", NULL},
{"pid-file", 0, 0, G_OPTION_ARG_STRING, &user_pidfile, "Specify the location of a PID file", NULL}, {"pid-file", 0, 0, G_OPTION_ARG_STRING, &user_pidfile, "Specify the location of a PID file", NULL},
@@ -698,34 +745,44 @@ int main( int argc, char *argv[] )
{"info", 0, 0, G_OPTION_ARG_NONE, &show_usage, "Show application information", NULL}, {"info", 0, 0, G_OPTION_ARG_NONE, &show_usage, "Show application information", NULL},
{NULL} {NULL}
}; };
if (getuid () != 0) {
g_printerr ("You must be root to run NetworkManager!\n");
goto exit;
}
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE);
/* Parse options */
opt_ctx = g_option_context_new(""); opt_ctx = g_option_context_new("");
g_option_context_add_main_entries(opt_ctx, options, NULL); g_option_context_add_main_entries(opt_ctx, options, NULL);
g_option_context_parse(opt_ctx, &argc, &argv, NULL); g_option_context_parse(opt_ctx, &argc, &argv, NULL);
g_option_context_free(opt_ctx); g_option_context_free(opt_ctx);
}
/* Tricky: become_daemon is FALSE by default, so unless it's TRUE because of a CLI if (show_usage == TRUE) {
* option, it'll become TRUE after this */
become_daemon = !become_daemon;
if (show_usage == TRUE)
{
nm_print_usage(); nm_print_usage();
exit (EXIT_SUCCESS); exit_status = EXIT_SUCCESS;
goto exit;
} }
if (become_daemon) pidfile = g_strdup (user_pidfile ? user_pidfile : NM_DEFAULT_PID_FILE);
{
if (daemon (0, 0) < 0) /* Tricky: become_daemon is FALSE by default, so unless it's TRUE because
{ * of a CLI option, it'll become TRUE after this
*/
become_daemon = !become_daemon;
if (become_daemon) {
if (daemon (0, 0) < 0) {
int saved_errno; int saved_errno;
saved_errno = errno; saved_errno = errno;
nm_error ("NetworkManager could not daemonize: %s [error %u]", nm_error ("Could not daemonize: %s [error %u]",
g_strerror (saved_errno), saved_errno); g_strerror (saved_errno),
exit (EXIT_FAILURE); saved_errno);
goto exit;
} }
pidfile = user_pidfile ? user_pidfile : NM_DEFAULT_PID_FILE;
write_pidfile (pidfile); write_pidfile (pidfile);
} }
@@ -748,46 +805,76 @@ int main( int argc, char *argv[] )
/* Initialize our instance data */ /* Initialize our instance data */
nm_data = nm_data_new (enable_test_devices); nm_data = nm_data_new (enable_test_devices);
if (!nm_data) if (!nm_data) {
{ nm_error ("Failed to initialize.");
nm_error ("nm_data_new() failed... Not enough memory?"); goto pidfile;
exit (EXIT_FAILURE);
} }
/* Create our dbus service */ /* Initialize our DBus service & connection */
nm_data->dbus_connection = nm_dbus_init (nm_data); dbus_mgr = nm_dbus_manager_get (nm_data->main_context);
if (!nm_data->dbus_connection) dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
{ if (!dbus_connection) {
nm_error ("nm_dbus_init() failed, exiting. " nm_error ("Failed to initialize. "
"Either dbus is not running, or the " "Either dbus is not running, or the "
"NetworkManager dbus security policy " "NetworkManager dbus security policy "
"was not loaded."); "was not loaded.");
exit (EXIT_FAILURE); goto done;
}
g_signal_connect (G_OBJECT (dbus_mgr), "name-owner-changed",
G_CALLBACK (nm_name_owner_changed_handler), nm_data);
g_signal_connect (G_OBJECT (dbus_mgr), "dbus-connection-changed",
G_CALLBACK (nm_dbus_connection_changed_handler), nm_data);
nm_dbus_manager_register_signal_handler (dbus_mgr,
NMI_DBUS_INTERFACE,
NULL,
nm_dbus_nmi_signal_handler,
nm_data);
/* Register DBus method handlers for the main NM objects */
nm_data->nm_methods = nm_dbus_nm_methods_setup (nm_data);
nm_dbus_manager_register_method_list (dbus_mgr, nm_data->nm_methods);
nm_data->device_methods = nm_dbus_device_methods_setup (nm_data);
nm_dbus_manager_register_method_list (dbus_mgr, nm_data->device_methods);
nm_data->net_methods = nm_dbus_net_methods_setup (nm_data);
nm_data->vpn_manager = nm_vpn_manager_new (nm_data);
if (!nm_data->vpn_manager) {
nm_warning ("Failed to start the VPN manager.");
goto done;
} }
/* Need to happen after DBUS is initialized */ nm_data->dhcp_manager = nm_dhcp_manager_new (nm_data, nm_data->main_context);
nm_data->vpn_manager = nm_vpn_manager_new (nm_data); if (!nm_data->dhcp_manager) {
nm_data->dhcp_manager = nm_dhcp_manager_new (nm_data); nm_warning ("Failed to start the DHCP manager.");
nm_data->named_manager = nm_named_manager_new (nm_data->dbus_connection); goto done;
}
nm_data->named_manager = nm_named_manager_new ();
if (!nm_data->named_manager) {
nm_warning ("Failed to start the named manager.");
goto done;
}
/* Start our DBus service */
if (!nm_dbus_manager_start_service (dbus_mgr)) {
nm_warning ("Failed to start the named manager.");
goto done;
}
/* If Hal is around, grab a device list from it */
if (nm_dbus_manager_name_has_owner (dbus_mgr, "org.freedesktop.Hal")) {
if (!nm_hal_init (nm_data, dbus_connection)) {
nm_error (NO_HAL_MSG);
goto done;
}
}
/* If NMI is running, grab allowed wireless network lists from it ASAP */ /* If NMI is running, grab allowed wireless network lists from it ASAP */
if (nm_dbus_is_info_daemon_running (nm_data->dbus_connection)) if (nm_dbus_manager_name_has_owner (dbus_mgr, NMI_DBUS_SERVICE)) {
{
nm_policy_schedule_allowed_ap_list_update (nm_data); nm_policy_schedule_allowed_ap_list_update (nm_data);
nm_dbus_vpn_schedule_vpn_connections_update (nm_data); nm_dbus_vpn_schedule_vpn_connections_update (nm_data);
} }
/* Right before we init hal, we have to make sure our mainloop
* integration function knows about our GMainContext. HAL doesn't give
* us any way to pass that into its mainloop integration callback, so
* its got to be a global.
*/
main_context = nm_data->main_context;
/* If Hal is around, grab a device list from it */
if ((owner = get_name_owner (nm_data->dbus_connection, "org.freedesktop.Hal")))
nm_hal_init (nm_data);
/* We run dhclient when we need to, and we don't want any stray ones /* We run dhclient when we need to, and we don't want any stray ones
* lying around upon launch. * lying around upon launch.
*/ */
@@ -802,16 +889,23 @@ int main( int argc, char *argv[] )
/* Run the main loop */ /* Run the main loop */
nm_policy_schedule_device_change_check (nm_data); nm_policy_schedule_device_change_check (nm_data);
nm_schedule_state_change_signal_broadcast (nm_data); nm_schedule_state_change_signal_broadcast (nm_data);
exit_status = EXIT_SUCCESS;
g_main_loop_run (nm_data->main_loop); g_main_loop_run (nm_data->main_loop);
done:
nm_print_open_socks (); nm_print_open_socks ();
nm_data_free (nm_data); nm_data_free (nm_data);
/* nm_data_free needs the dbus connection, so must kill the
* dbus manager after that.
*/
g_object_unref (dbus_mgr);
nm_logging_shutdown (); nm_logging_shutdown ();
/* Clean up pidfile */ pidfile:
if (pidfile) if (pidfile)
unlink (pidfile); unlink (pidfile);
g_free (user_pidfile); g_free (pidfile);
exit (0); exit:
exit (exit_status);
} }

View File

@@ -27,6 +27,7 @@
#include "NetworkManagerUtils.h" #include "NetworkManagerUtils.h"
#include "NetworkManagerDbus.h" #include "NetworkManagerDbus.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-dbus-manager.h"
struct NMAccessPointList struct NMAccessPointList
@@ -433,21 +434,20 @@ NMAccessPoint *nm_ap_list_get_ap_by_address (NMAccessPointList *list, const stru
* TRUE if the ap was completely new * TRUE if the ap was completely new
* *
*/ */
gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointList *list, NMAccessPoint *merge_ap) gboolean
nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev,
NMAccessPointList *list,
NMAccessPoint *merge_ap)
{ {
NMAccessPoint * list_ap = NULL; NMAccessPoint * list_ap = NULL;
gboolean strength_changed = FALSE; gboolean strength_changed = FALSE;
gboolean new = FALSE; gboolean new = FALSE;
NMData * app_data;
const struct ether_addr * merge_bssid; const struct ether_addr * merge_bssid;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (list != NULL, FALSE); g_return_val_if_fail (list != NULL, FALSE);
g_return_val_if_fail (merge_ap != NULL, FALSE); g_return_val_if_fail (merge_ap != NULL, FALSE);
app_data = nm_device_get_app_data (NM_DEVICE (dev));
g_return_val_if_fail (app_data != NULL, FALSE);
merge_bssid = nm_ap_get_address (merge_ap); merge_bssid = nm_ap_get_address (merge_ap);
if (nm_ethernet_address_is_valid (merge_bssid) && (list_ap = nm_ap_list_get_ap_by_address (list, merge_bssid))) if (nm_ethernet_address_is_valid (merge_bssid) && (list_ap = nm_ap_list_get_ap_by_address (list, merge_bssid)))
{ {
@@ -464,14 +464,13 @@ gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointL
/* Did the AP's name change? */ /* Did the AP's name change? */
if (!devlist_essid || !merge_essid || nm_null_safe_strcmp (devlist_essid, merge_essid)) if (!devlist_essid || !merge_essid || nm_null_safe_strcmp (devlist_essid, merge_essid))
{ {
nm_dbus_signal_wireless_network_change (app_data->dbus_connection, nm_dbus_signal_wireless_network_change (dev, list_ap,
dev, list_ap, NETWORK_STATUS_DISAPPEARED, -1); NETWORK_STATUS_DISAPPEARED, -1);
new = TRUE; new = TRUE;
} }
nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap)); nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap));
if (nm_ap_get_strength (merge_ap) != nm_ap_get_strength (list_ap)) if (nm_ap_get_strength (merge_ap) != nm_ap_get_strength (list_ap)) {
{
nm_ap_set_strength (list_ap, nm_ap_get_strength (merge_ap)); nm_ap_set_strength (list_ap, nm_ap_get_strength (merge_ap));
strength_changed = TRUE; strength_changed = TRUE;
} }
@@ -518,26 +517,22 @@ gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointL
* artificial, since it clearly exists somewhere. * artificial, since it clearly exists somewhere.
*/ */
nm_ap_set_artificial (list_ap, FALSE); nm_ap_set_artificial (list_ap, FALSE);
} } else {
else
{
/* Add the merge AP to the list. */ /* Add the merge AP to the list. */
nm_ap_list_append_ap (list, merge_ap); nm_ap_list_append_ap (list, merge_ap);
list_ap = merge_ap; list_ap = merge_ap;
new = TRUE; new = TRUE;
} }
if (list_ap && strength_changed && !new) if (list_ap && strength_changed && !new) {
{
const int new_strength = nm_ap_get_strength (list_ap); const int new_strength = nm_ap_get_strength (list_ap);
nm_dbus_signal_wireless_network_change (app_data->dbus_connection, nm_dbus_signal_wireless_network_change (dev, list_ap,
dev, list_ap, NETWORK_STATUS_STRENGTH_CHANGED, new_strength); NETWORK_STATUS_STRENGTH_CHANGED, new_strength);
} }
if (list_ap && new) if (list_ap && new) {
{ nm_dbus_signal_wireless_network_change (dev, list_ap,
nm_dbus_signal_wireless_network_change (app_data->dbus_connection, NETWORK_STATUS_APPEARED, -1);
dev, list_ap, NETWORK_STATUS_APPEARED, -1);
} }
return TRUE; return TRUE;
@@ -560,8 +555,9 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
if (!dest || !source) if (!dest || !source)
return; return;
if ((iter = nm_ap_list_iter_new (dest))) if (!(iter = nm_ap_list_iter_new (dest)))
{ return;
while ((dest_ap = nm_ap_list_iter_next (iter))) while ((dest_ap = nm_ap_list_iter_next (iter)))
{ {
NMAccessPoint *src_ap = NULL; NMAccessPoint *src_ap = NULL;
@@ -575,7 +571,6 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
} }
nm_ap_list_iter_free (iter); nm_ap_list_iter_free (iter);
} }
}
/* /*
@@ -586,8 +581,8 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
* If one is found, copy the essid over to the original access point. * If one is found, copy the essid over to the original access point.
* *
*/ */
void nm_ap_list_copy_one_essid_by_address (NMData *app_data, void
NMDevice80211Wireless *dev, nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev,
NMAccessPoint *ap, NMAccessPoint *ap,
NMAccessPointList *search_list) NMAccessPointList *search_list)
{ {
@@ -596,13 +591,16 @@ void nm_ap_list_copy_one_essid_by_address (NMData *app_data,
if (!ap || !search_list) if (!ap || !search_list)
return; return;
if (!nm_ap_get_essid (ap) && (found_ap = nm_ap_list_get_ap_by_address (search_list, nm_ap_get_address (ap)))) if (!nm_ap_get_essid (ap))
{ return;
if (nm_ap_get_essid (found_ap))
{ found_ap = nm_ap_list_get_ap_by_address (search_list, nm_ap_get_address (ap));
if (!found_ap)
return;
if (nm_ap_get_essid (found_ap)) {
nm_ap_set_essid (ap, nm_ap_get_essid (found_ap)); nm_ap_set_essid (ap, nm_ap_get_essid (found_ap));
nm_dbus_signal_wireless_network_change (app_data->dbus_connection, dev, ap, NETWORK_STATUS_APPEARED, 0); nm_dbus_signal_wireless_network_change (dev, ap, NETWORK_STATUS_APPEARED, 0);
}
} }
} }
@@ -615,8 +613,8 @@ void nm_ap_list_copy_one_essid_by_address (NMData *app_data,
* its found, copy the source access point's essid to the dest access point. * its found, copy the source access point's essid to the dest access point.
* *
*/ */
void nm_ap_list_copy_essids_by_address (NMData *app_data, void
NMDevice80211Wireless *dev, nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev,
NMAccessPointList *dest, NMAccessPointList *dest,
NMAccessPointList *source) NMAccessPointList *source)
{ {
@@ -626,14 +624,13 @@ void nm_ap_list_copy_essids_by_address (NMData *app_data,
if (!dest || !source) if (!dest || !source)
return; return;
if ((iter = nm_ap_list_iter_new (dest))) if (!(iter = nm_ap_list_iter_new (dest)))
{ return;
while ((dest_ap = nm_ap_list_iter_next (iter)))
nm_ap_list_copy_one_essid_by_address (app_data, dev, dest_ap, source);
while ((dest_ap = nm_ap_list_iter_next (iter)))
nm_ap_list_copy_one_essid_by_address (dev, dest_ap, source);
nm_ap_list_iter_free (iter); nm_ap_list_iter_free (iter);
} }
}
/* /*

View File

@@ -48,8 +48,8 @@ NMAccessPoint * nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char
NMAccessPoint * nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr); NMAccessPoint * nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr);
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source); void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_essids_by_address (NMData *app_data, NMDevice80211Wireless *dev, NMAccessPointList *dest, NMAccessPointList *source); void nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev, NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_one_essid_by_address (NMData *app_data, NMDevice80211Wireless *dev, NMAccessPoint *ap, NMAccessPointList *search_list); void nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev, NMAccessPoint *ap, NMAccessPointList *search_list);
gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointList *list, NMAccessPoint *merge_ap); gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointList *list, NMAccessPoint *merge_ap);

View File

@@ -43,10 +43,13 @@
#include "nm-dbus-nmi.h" #include "nm-dbus-nmi.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-dhcp-manager.h" #include "nm-dhcp-manager.h"
#include "nm-dbus-manager.h"
#if 0
static char *get_nmi_match_string (const char *owner); static char *get_nmi_match_string (const char *owner);
static gpointer nm_dbus_reinit (gpointer user_data); static gpointer nm_dbus_reinit (gpointer user_data);
#endif
/* /*
* nm_dbus_create_error_message * nm_dbus_create_error_message
@@ -54,8 +57,12 @@ static gpointer nm_dbus_reinit (gpointer user_data);
* Make a DBus error message * Make a DBus error message
* *
*/ */
DBusMessage *nm_dbus_create_error_message (DBusMessage *message, const char *exception_namespace, DBusMessage *
const char *exception, const char *format, ...) nm_dbus_create_error_message (DBusMessage *message,
const char *exception_namespace,
const char *exception,
const char *format,
...)
{ {
char *exception_text; char *exception_text;
DBusMessage *reply_message; DBusMessage *reply_message;
@@ -74,6 +81,17 @@ DBusMessage *nm_dbus_create_error_message (DBusMessage *message, const char *exc
} }
DBusMessage *
nm_dbus_new_invalid_args_error (DBusMessage *replyto,
const char *namespace)
{
return nm_dbus_create_error_message (replyto,
namespace,
"InvalidArguments",
"Invalid method arguments.");
}
/* /*
* nm_dbus_get_object_path_for_device * nm_dbus_get_object_path_for_device
* *
@@ -155,6 +173,7 @@ NMDevice *nm_dbus_get_device_from_escaped_object_path (NMData *data, const char
&& ((path[len] == '\0' || path[len] == '/'))) && ((path[len] == '\0' || path[len] == '/')))
{ {
g_free (escaped_compare_path); g_free (escaped_compare_path);
g_object_ref (G_OBJECT (dev));
break; break;
} }
g_free (escaped_compare_path); g_free (escaped_compare_path);
@@ -204,55 +223,61 @@ static DeviceStatusSignals dev_status_signals[] =
* Notifies the bus that a particular device has had a status change * Notifies the bus that a particular device has had a status change
* *
*/ */
static gboolean nm_dbus_signal_device_status_change (gpointer user_data) static gboolean
nm_dbus_signal_device_status_change (gpointer user_data)
{ {
NMStatusChangeData *cb_data = (NMStatusChangeData *)user_data; NMStatusChangeData *cb_data = (NMStatusChangeData *)user_data;
DBusMessage * message; DBusMessage * message;
char * dev_path; char * dev_path = NULL;
const char * sig = NULL; const char * sig = NULL;
int i = 0; int i = 0;
NMDBusManager * dbus_mgr = NULL;
DBusConnection *dbus_connection;
g_return_val_if_fail (cb_data->data, FALSE); g_return_val_if_fail (cb_data->data, FALSE);
g_return_val_if_fail (cb_data->data->dbus_connection, FALSE);
g_return_val_if_fail (cb_data->dev, FALSE); g_return_val_if_fail (cb_data->dev, FALSE);
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
while ((dev_status_signals[i].status != DEVICE_STATUS_INVALID) && (dev_status_signals[i].status != cb_data->status)) while ((dev_status_signals[i].status != DEVICE_STATUS_INVALID) && (dev_status_signals[i].status != cb_data->status))
i++; i++;
if (!(sig = dev_status_signals[i].signal)) if (!(sig = dev_status_signals[i].signal))
return FALSE; goto out;
if (!(dev_path = nm_dbus_get_object_path_for_device (cb_data->dev))) if (!(dev_path = nm_dbus_get_object_path_for_device (cb_data->dev)))
return FALSE; goto out;
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, sig))) message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, sig);
{ if (!message) {
nm_warning ("nm_dbus_signal_device_status_change(): Not enough memory for new dbus message!"); nm_warning ("nm_dbus_signal_device_status_change(): Not enough memory for new dbus message!");
g_free (dev_path); goto out;
return FALSE;
} }
/* If the device was wireless, attach the name of the wireless network that failed to activate */ /* If the device was wireless, attach the name of the wireless network that failed to activate */
if (cb_data->ap) if (cb_data->ap) {
{
const char *essid = nm_ap_get_essid (cb_data->ap); const char *essid = nm_ap_get_essid (cb_data->ap);
if (essid) if (essid)
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID); dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID);
nm_ap_unref (cb_data->ap); nm_ap_unref (cb_data->ap);
} } else {
else
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INVALID); dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INVALID);
}
g_free (dev_path); dbus_connection_send (dbus_connection, message, NULL);
if (!dbus_connection_send (cb_data->data->dbus_connection, message, NULL))
nm_warning ("nm_dbus_signal_device_status_change(): Could not raise the signal!");
dbus_message_unref (message); dbus_message_unref (message);
g_object_unref (G_OBJECT (cb_data->dev)); g_object_unref (G_OBJECT (cb_data->dev));
g_slice_free (NMStatusChangeData, cb_data); g_slice_free (NMStatusChangeData, cb_data);
out:
g_object_unref (dbus_mgr);
g_free (dev_path);
return FALSE; return FALSE;
} }
@@ -345,25 +370,36 @@ void nm_dbus_signal_state_change (DBusConnection *connection, NMData *data)
* Notifies the bus that a new wireless network has come into range * Notifies the bus that a new wireless network has come into range
* *
*/ */
void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice80211Wireless *dev, NMAccessPoint *ap, NMNetworkStatus status, gint strength) void
nm_dbus_signal_wireless_network_change (NMDevice80211Wireless *dev,
NMAccessPoint *ap,
NMNetworkStatus status,
gint strength)
{ {
NMDBusManager * dbus_mgr = NULL;
DBusConnection *dbus_connection;
DBusMessage * message; DBusMessage * message;
char * dev_path = NULL; char * dev_path = NULL;
char * net_path = NULL; char * net_path = NULL;
const char * sig = NULL; const char * sig = NULL;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
g_return_if_fail (ap != NULL); g_return_if_fail (ap != NULL);
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
if (!(dev_path = nm_dbus_get_object_path_for_device (NM_DEVICE (dev)))) if (!(dev_path = nm_dbus_get_object_path_for_device (NM_DEVICE (dev))))
goto out; goto out;
if (!(net_path = nm_dbus_get_object_path_for_network (NM_DEVICE (dev), ap))) if (!(net_path = nm_dbus_get_object_path_for_network (NM_DEVICE (dev), ap)))
goto out; goto out;
switch (status) switch (status) {
{
case NETWORK_STATUS_DISAPPEARED: case NETWORK_STATUS_DISAPPEARED:
sig = "WirelessNetworkDisappeared"; sig = "WirelessNetworkDisappeared";
break; break;
@@ -377,483 +413,129 @@ void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevic
break; break;
} }
if (!sig) if (!sig) {
{ nm_warning ("tried to broadcast unknown signal.");
nm_warning ("nm_dbus_signal_wireless_network_change(): tried to broadcast unknown signal.");
goto out; goto out;
} }
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, sig))) message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, sig);
{ if (!message) {
nm_warning ("nm_dbus_signal_wireless_network_change(): Not enough memory for new dbus message!"); nm_warning ("could not allocate the dbus message.");
goto out; goto out;
} }
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_OBJECT_PATH, &net_path, DBUS_TYPE_INVALID); dbus_message_append_args (message,
if (status == NETWORK_STATUS_STRENGTH_CHANGED) DBUS_TYPE_OBJECT_PATH, &dev_path,
dbus_message_append_args (message, DBUS_TYPE_INT32, &strength, DBUS_TYPE_INVALID); DBUS_TYPE_OBJECT_PATH, &net_path,
DBUS_TYPE_INVALID);
if (!dbus_connection_send (connection, message, NULL)) if (status == NETWORK_STATUS_STRENGTH_CHANGED) {
nm_warning ("nm_dbus_signal_wireless_network_change(): Could not raise the WirelessNetwork* signal!"); dbus_message_append_args (message,
DBUS_TYPE_INT32, &strength,
DBUS_TYPE_INVALID);
}
dbus_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message); dbus_message_unref (message);
out: out:
g_free (net_path); g_free (net_path);
g_free (dev_path); g_free (dev_path);
g_object_unref (dbus_mgr);
} }
void nm_dbus_signal_device_strength_change (DBusConnection *connection, NMDevice80211Wireless *dev, gint strength) void
nm_dbus_signal_device_strength_change (NMDevice80211Wireless *dev,
gint strength)
{ {
NMDBusManager * dbus_mgr = NULL;
DBusConnection *dbus_connection;
DBusMessage * message; DBusMessage * message;
char * dev_path = NULL; char * dev_path = NULL;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
if (!(dev_path = nm_dbus_get_object_path_for_device (NM_DEVICE (dev)))) if (!(dev_path = nm_dbus_get_object_path_for_device (NM_DEVICE (dev))))
goto out; goto out;
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceStrengthChanged"))) message = dbus_message_new_signal (NM_DBUS_PATH,
{ NM_DBUS_INTERFACE,
nm_warning ("nm_dbus_signal_device_strength_change(): Not enough memory for new dbus message!"); "DeviceStrengthChanged");
if (!message) {
nm_warning ("could not allocate the dbus message.");
goto out; goto out;
} }
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INT32, &strength, DBUS_TYPE_INVALID); dbus_message_append_args (message,
if (!dbus_connection_send (connection, message, NULL)) DBUS_TYPE_OBJECT_PATH, &dev_path,
nm_warning ("nm_dbus_signal_device_strength_change(): Could not raise the DeviceStrengthChanged signal!"); DBUS_TYPE_INT32, &strength,
DBUS_TYPE_INVALID);
dbus_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message); dbus_message_unref (message);
out: out:
g_free (dev_path); g_free (dev_path);
g_object_unref (dbus_mgr);
} }
gboolean
/* nm_dbus_nmi_signal_handler (DBusConnection *connection,
* nm_dbus_signal_filter DBusMessage *message,
* gpointer user_data)
* Respond to NetworkManagerInfo signals about changing Allowed Networks
*
*/
static DBusHandlerResult nm_dbus_signal_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
{ {
NMData * data = (NMData *) user_data; NMData * data = (NMData *) user_data;
const char * object_path; const char * object_path;
const char * method;
gboolean handled = FALSE; gboolean handled = FALSE;
DBusError error;
g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
method = dbus_message_get_member (message);
if (!(object_path = dbus_message_get_path (message))) if (!(object_path = dbus_message_get_path (message)))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; return FALSE;
if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL) if (strcmp (object_path, NMI_DBUS_PATH) != 0)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; return FALSE;
/* nm_debug ("nm_dbus_nmi_filter() got method %s for path %s", method, object_path); */ if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "WirelessNetworkUpdate")) {
dbus_error_init (&error);
if (strcmp (object_path, NMI_DBUS_PATH) == 0)
{
if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "WirelessNetworkUpdate"))
{
char *network = NULL; char *network = NULL;
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID)) if (dbus_message_get_args (message,
{ NULL,
DBUS_TYPE_STRING, &network,
DBUS_TYPE_INVALID)) {
/* Update a single wireless network's data */ /* Update a single wireless network's data */
nm_debug ("NetworkManagerInfo triggered update of wireless network '%s'", network); nm_debug ("NetworkManagerInfo triggered update of wireless network "
nm_dbus_update_one_allowed_network (connection, network, data); "'%s'",
network);
nm_dbus_update_one_allowed_network (network, data);
handled = TRUE; handled = TRUE;
} }
} } else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "VPNConnectionUpdate")) {
else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "VPNConnectionUpdate"))
{
char *name = NULL; char *name = NULL;
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) if (dbus_message_get_args (message,
{ NULL,
nm_debug ("NetworkManagerInfo triggered update of VPN connection '%s'", name); DBUS_TYPE_STRING, &name,
nm_dbus_vpn_update_one_vpn_connection (data->dbus_connection, name, data); DBUS_TYPE_INVALID)) {
nm_debug ("NetworkManagerInfo triggered update of VPN connection "
" '%s'",
name);
nm_dbus_vpn_update_one_vpn_connection (connection, name, data);
handled = TRUE; handled = TRUE;
} }
} } else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "UserInterfaceActivated")) {
else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "UserInterfaceActivated")) nm_device_802_11_wireless_set_scan_interval (data,
{ NULL,
nm_device_802_11_wireless_set_scan_interval (data, NULL, NM_WIRELESS_SCAN_INTERVAL_ACTIVE); NM_WIRELESS_SCAN_INTERVAL_ACTIVE);
handled = TRUE;
}
}
else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected"))
{
nm_hal_deinit (data);
dbus_connection_unref (data->dbus_connection);
data->dbus_connection = NULL;
nm_dhcp_manager_dispose (data->dhcp_manager);
g_thread_create ((GThreadFunc) nm_dbus_reinit, (gpointer) data, FALSE, NULL);
handled = TRUE;
}
else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged"))
{
char *service;
char *old_owner;
char *new_owner;
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &old_owner,
DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID))
{
gboolean old_owner_good = (old_owner && (strlen (old_owner) > 0));
gboolean new_owner_good = (new_owner && (strlen (new_owner) > 0));
if (strcmp (service, NMI_DBUS_SERVICE) == 0)
{
if (!old_owner_good && new_owner_good) /* NMI just appeared */
{
char *match = get_nmi_match_string (new_owner);
dbus_bus_add_match (connection, match, NULL);
nm_policy_schedule_allowed_ap_list_update (data);
nm_dbus_vpn_schedule_vpn_connections_update (data);
g_free (match);
handled = TRUE;
}
else if (old_owner_good && !new_owner_good) /* NMI went away */
{
char *match = get_nmi_match_string (old_owner);
dbus_bus_remove_match (connection, match, NULL);
g_free (match);
}
}
else if (strcmp (service, "org.freedesktop.Hal") == 0)
{
if (!old_owner_good && new_owner_good) /* Hal just appeared */
{
nm_hal_init (data);
handled = TRUE;
}
else if (old_owner_good && !new_owner_good) /* Hal went away */
{
nm_hal_deinit (data);
handled = TRUE;
}
}
else if (nm_dhcp_manager_process_name_owner_changed (data->dhcp_manager, service, old_owner, new_owner) == TRUE)
handled = TRUE;
else if (nm_vpn_manager_process_name_owner_changed (data->vpn_manager, service, old_owner, new_owner) == TRUE)
handled = TRUE;
else if (nm_named_manager_process_name_owner_changed (data->named_manager, service, old_owner, new_owner) == TRUE)
handled = TRUE;
}
}
else if (nm_dhcp_manager_process_signal (data->dhcp_manager, message) == TRUE)
handled = TRUE;
else if (nm_vpn_manager_process_signal (data->vpn_manager, message) == TRUE)
handled = TRUE;
if (dbus_error_is_set (&error))
dbus_error_free (&error);
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
/*
* nm_dbus_nm_message_handler
*
* Dispatch messages against our NetworkManager object
*
*/
static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
{
NMData *data = (NMData *)user_data;
gboolean handled = TRUE;
DBusMessage *reply = NULL;
NMDbusCBData cb_data;
g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (data->nm_methods != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
cb_data.data = data;
cb_data.dev = NULL;
handled = nm_dbus_method_dispatch (data->nm_methods, connection, message, &cb_data, &reply);
if (reply)
{
dbus_connection_send (connection, reply, NULL);
dbus_message_unref (reply);
}
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
/*
* nm_dbus_devices_message_handler
*
* Dispatch messages against individual network devices
*
*/
static DBusHandlerResult nm_dbus_devices_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
{
NMData *data = (NMData *)user_data;
gboolean handled = FALSE;
const char *path;
DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
path = dbus_message_get_path (message);
if (!(dev = nm_dbus_get_device_from_escaped_object_path (data, path)))
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound", "The requested network device does not exist.");
else
{
char *object_path, *escaped_object_path;
NMDbusCBData cb_data;
cb_data.data = data;
cb_data.dev = dev;
/* Test whether or not the _networks_ of a device were queried instead of the device itself */
object_path = g_strdup_printf ("%s/%s/Networks/", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
escaped_object_path = nm_dbus_escape_object_path (object_path);
g_free (object_path);
if (strncmp (path, escaped_object_path, strlen (escaped_object_path)) == 0)
handled = nm_dbus_method_dispatch (data->net_methods, connection, message, &cb_data, &reply);
else
handled = nm_dbus_method_dispatch (data->device_methods, connection, message, &cb_data, &reply);
g_free (escaped_object_path);
}
if (reply)
{
dbus_connection_send (connection, reply, NULL);
dbus_message_unref (reply);
handled = TRUE; handled = TRUE;
} }
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED); return handled;
} }
/*
* nm_dbus_vpn_message_handler
*
* Dispatch messages against our NetworkManager VPNConnections object
*
*/
static DBusHandlerResult nm_dbus_vpn_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
{
NMData *data = (NMData *)user_data;
gboolean handled = TRUE;
DBusMessage *reply = NULL;
NMDbusCBData cb_data;
g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (data->vpn_methods != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
cb_data.data = data;
cb_data.dev = NULL;
handled = nm_dbus_method_dispatch (data->vpn_methods, connection, message, &cb_data, &reply);
if (reply)
{
dbus_connection_send (connection, reply, NULL);
dbus_message_unref (reply);
}
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
/*
* nm_dbus_is_info_daemon_running
*
* Ask dbus whether or not the info daemon is providing its dbus service
*
*/
gboolean nm_dbus_is_info_daemon_running (DBusConnection *connection)
{
DBusError error;
gboolean running = FALSE;
g_return_val_if_fail (connection != NULL, FALSE);
dbus_error_init (&error);
running = dbus_bus_name_has_owner (connection, NMI_DBUS_SERVICE, &error);
if (dbus_error_is_set (&error))
{
running = FALSE;
dbus_error_free (&error);
}
return running;
}
char *get_name_owner (DBusConnection *con, const char *name)
{
DBusMessage * message;
DBusMessage * reply;
char * owner = NULL;
g_return_val_if_fail (con != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
if ((message = dbus_message_new_method_call (DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetNameOwner")))
{
dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
if ((reply = dbus_connection_send_with_reply_and_block (con, message, -1, NULL)))
{
const char *tmp_name = NULL;
if (dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &tmp_name, DBUS_TYPE_INVALID))
owner = g_strdup (tmp_name);
dbus_message_unref (reply);
}
dbus_message_unref (message);
}
return owner;
}
static char *get_nmi_match_string (const char *owner)
{
g_return_val_if_fail (owner != NULL, NULL);
return g_strdup_printf ("type='signal',interface='" NMI_DBUS_INTERFACE "',sender='%s',path='" NMI_DBUS_PATH "'", owner);
}
/*
* nm_dbus_reinit
*
* Reconnect to the system message bus if the connection was dropped.
*
*/
static gpointer nm_dbus_reinit (gpointer user_data)
{
NMData *data = (NMData *) user_data;
char *owner;
g_return_val_if_fail (data != NULL, NULL);
while ((data->dbus_connection = nm_dbus_init (data)) == NULL)
g_usleep (G_USEC_PER_SEC * 3);
/* if HAL was quick it is already back on the bus. Thus, we do not receive NameOwnerChanged */
if ((owner = get_name_owner (data->dbus_connection, "org.freedesktop.Hal")))
nm_hal_init (data);
data->dhcp_manager = nm_dhcp_manager_new (data);
nm_info ("Successfully reconnected to the system bus.");
return NULL;
}
/*
* nm_dbus_init
*
* Connect to the system messagebus and register ourselves as a service.
*
*/
DBusConnection *nm_dbus_init (NMData *data)
{
DBusError error;
DBusConnection * connection;
DBusObjectPathVTable nm_vtable = {NULL, &nm_dbus_nm_message_handler, NULL, NULL, NULL, NULL};
DBusObjectPathVTable devices_vtable = {NULL, &nm_dbus_devices_message_handler, NULL, NULL, NULL, NULL};
DBusObjectPathVTable vpn_vtable = {NULL, &nm_dbus_vpn_message_handler, NULL, NULL, NULL, NULL};
char * owner;
int flags, ret;
dbus_connection_set_change_sigpipe (TRUE);
dbus_error_init (&error);
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
if ((connection == NULL) || dbus_error_is_set (&error))
{
nm_warning ("nm_dbus_init() could not get the system bus. Make sure the message bus daemon is running!");
connection = NULL;
goto out;
}
dbus_connection_set_exit_on_disconnect (connection, FALSE);
dbus_connection_setup_with_g_main (connection, data->main_context);
data->nm_methods = nm_dbus_nm_methods_setup ();
data->device_methods = nm_dbus_device_methods_setup ();
data->net_methods = nm_dbus_net_methods_setup ();
data->vpn_methods = nm_dbus_vpn_methods_setup ();
if ( !dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data)
|| !dbus_connection_register_fallback (connection, NM_DBUS_PATH_DEVICES, &devices_vtable, data)
|| !dbus_connection_register_object_path (connection, NM_DBUS_PATH_VPN, &vpn_vtable, data))
{
nm_error ("nm_dbus_init() could not register D-BUS handlers. Cannot continue.");
connection = NULL;
goto out;
}
if (!dbus_connection_add_filter (connection, nm_dbus_signal_filter, data, NULL))
{
nm_error ("nm_dbus_init() could not attach a dbus message filter. The NetworkManager dbus security policy may not be loaded. Restart dbus?");
connection = NULL;
goto out;
}
dbus_bus_add_match (connection,
"type='signal',"
"interface='" DBUS_INTERFACE_DBUS "',"
"sender='" DBUS_SERVICE_DBUS "'",
NULL);
if ((owner = get_name_owner (connection, NMI_DBUS_SERVICE)))
{
char *match = get_nmi_match_string (owner);
dbus_bus_add_match (connection, match, NULL);
g_free (match);
g_free (owner);
}
dbus_error_init (&error);
#if (DBUS_VERSION_MAJOR == 0) && (DBUS_VERSION_MINOR >= 60)
flags = DBUS_NAME_FLAG_DO_NOT_QUEUE; /* Prohibit replacement is now the default */
#else
flags = DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT;
#endif
ret = dbus_bus_request_name (connection, NM_DBUS_SERVICE, flags, &error);
if (dbus_error_is_set (&error))
{
nm_warning ("nm_dbus_init() could not acquire the NetworkManager service.\n Message: '%s'", error.message);
connection = NULL;
goto out;
}
else if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
{
nm_warning ("nm_dbus_init() could not acquire the NetworkManager service as it is already taken (ret=%d). Is the daemon already running?",
ret);
connection = NULL;
goto out;
}
out:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
return (connection);
}

View File

@@ -54,11 +54,6 @@ static inline gboolean message_is_error (DBusMessage *msg)
return (dbus_message_get_type (msg) == DBUS_MESSAGE_TYPE_ERROR); return (dbus_message_get_type (msg) == DBUS_MESSAGE_TYPE_ERROR);
} }
DBusConnection *nm_dbus_init (NMData *data);
gboolean nm_dbus_is_info_daemon_running (DBusConnection *connection);
char * get_name_owner (DBusConnection *con, const char *name);
char * nm_dbus_get_object_path_for_device (NMDevice *dev); char * nm_dbus_get_object_path_for_device (NMDevice *dev);
char * nm_dbus_get_object_path_for_network (NMDevice *dev, NMAccessPoint *ap); char * nm_dbus_get_object_path_for_network (NMDevice *dev, NMAccessPoint *ap);
@@ -66,8 +61,8 @@ void nm_dbus_schedule_device_status_change_signal (NMData *data, NMDevice *dev
void nm_dbus_signal_state_change (DBusConnection *connection, NMData *data); void nm_dbus_signal_state_change (DBusConnection *connection, NMData *data);
void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevice80211Wireless *dev, NMAccessPoint *ap, NMNetworkStatus status, gint strength); void nm_dbus_signal_wireless_network_change (NMDevice80211Wireless *dev, NMAccessPoint *ap, NMNetworkStatus status, gint strength);
void nm_dbus_signal_device_strength_change (DBusConnection *connection, NMDevice80211Wireless *dev, gint strength); void nm_dbus_signal_device_strength_change (NMDevice80211Wireless *dev, gint strength);
NMDevice * nm_dbus_get_device_from_escaped_object_path (NMData *data, const char *path); NMDevice * nm_dbus_get_device_from_escaped_object_path (NMData *data, const char *path);
@@ -75,4 +70,10 @@ NMState nm_get_app_state_from_data (NMData *data);
DBusMessage * nm_dbus_create_error_message (DBusMessage *message, const char *exception_namespace, const char *exception, const char *format, ...); DBusMessage * nm_dbus_create_error_message (DBusMessage *message, const char *exception_namespace, const char *exception, const char *format, ...);
DBusMessage * nm_dbus_new_invalid_args_error (DBusMessage *replyto, const char *namespace);
gboolean nm_dbus_nmi_signal_handler (DBusConnection *connection,
DBusMessage *message,
gpointer user_data);
#endif #endif

View File

@@ -20,28 +20,108 @@
*/ */
#include <syslog.h> #include <syslog.h>
#include <string.h>
#include "NetworkManagerDbusUtils.h" #include "NetworkManagerDbusUtils.h"
struct NMDbusMethodList struct NMDbusMethodList
{ {
NMDbusMethod validate_method; guint32 refcount;
GHashTable * methods; GHashTable * methods;
char * path;
gboolean is_fallback;
DBusObjectPathMessageFunction handler_func;
gpointer user_data;
DBusFreeFunction user_data_free_func;
}; };
NMDbusMethodList * nm_dbus_method_list_new (NMDbusMethod validate_method) /**
* @param path DBus object path for which the handler applies
* @param is_fallback whether the handlers should be registered as a fallback
*/
NMDbusMethodList *
nm_dbus_method_list_new (const char *path,
gboolean is_fallback,
gpointer user_data,
DBusFreeFunction user_data_free_func)
{ {
NMDbusMethodList *list = g_slice_new0 (NMDbusMethodList); NMDbusMethodList * list;
list->validate_method = validate_method; g_return_val_if_fail (path != NULL, NULL);
list = g_slice_new0 (NMDbusMethodList);
list->refcount = 1;
list->path = g_strdup (path);
list->is_fallback = is_fallback;
list->user_data = user_data;
list->user_data_free_func = user_data_free_func;
list->methods = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); list->methods = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
return list; return list;
} }
void
nm_dbus_method_list_ref (NMDbusMethodList *list)
{
g_return_if_fail (list != NULL);
void nm_dbus_method_list_add_method (NMDbusMethodList *list, const char *method, NMDbusMethod callback) list->refcount += 1;
}
void
nm_dbus_method_list_unref (NMDbusMethodList *list)
{
g_return_if_fail (list != NULL);
g_return_if_fail (list->refcount >= 1);
list->refcount -= 1;
if (list->refcount <= 0) {
if (list->user_data && list->user_data_free_func)
(*list->user_data_free_func)(list->user_data);
g_hash_table_destroy (list->methods);
memset (list, 0, sizeof (NMDbusMethodList));
g_slice_free (NMDbusMethodList, list);
}
}
DBusObjectPathMessageFunction
nm_dbus_method_list_get_custom_handler_func (NMDbusMethodList *list)
{
g_return_val_if_fail (list != NULL, NULL);
return list->handler_func;
}
gpointer
nm_dbus_method_list_get_user_data (NMDbusMethodList *list)
{
g_return_val_if_fail (list != NULL, NULL);
return list->user_data;
}
/**
* @param handler_func NULL, or handler function which overrides the default one
*/
void
nm_dbus_method_list_set_custom_handler_func (NMDbusMethodList *list,
DBusObjectPathMessageFunction handler_func)
{
g_return_if_fail (list != NULL);
g_return_if_fail (handler_func != NULL);
g_return_if_fail (list->handler_func == NULL);
list->handler_func = handler_func;
}
void
nm_dbus_method_list_add_method (NMDbusMethodList *list,
const char *method,
NMDBusHandleMessageFunc callback)
{ {
g_return_if_fail (list != NULL); g_return_if_fail (list != NULL);
g_return_if_fail (list->methods != NULL); g_return_if_fail (list->methods != NULL);
@@ -52,46 +132,49 @@ void nm_dbus_method_list_add_method (NMDbusMethodList *list, const char *method,
} }
gboolean nm_dbus_method_dispatch (NMDbusMethodList *list, DBusConnection *connection, DBusMessage *message, gpointer user_data, DBusMessage **reply) gboolean
nm_dbus_method_list_dispatch (NMDbusMethodList *list,
DBusConnection *connection,
DBusMessage *message,
gpointer user_data,
DBusMessage **reply)
{ {
NMDbusMethod callback = NULL; NMDBusHandleMessageFunc callback = NULL;
const char * method; const char * method;
DBusMessage *temp_reply = NULL;
if (reply)
*reply = NULL;
g_return_val_if_fail (list != NULL, FALSE); g_return_val_if_fail (list != NULL, FALSE);
g_return_val_if_fail (list->methods != NULL, FALSE); g_return_val_if_fail (list->methods != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (message != NULL, FALSE); g_return_val_if_fail (message != NULL, FALSE);
if (reply)
*reply = NULL;
if (!(method = dbus_message_get_member (message))) if (!(method = dbus_message_get_member (message)))
return FALSE; return FALSE;
if (!(callback = g_hash_table_lookup (list->methods, method))) if (!(callback = g_hash_table_lookup (list->methods, method)))
return FALSE; return FALSE;
/* Call the optional validate method first, if it returns NULL then we /* Dispatch the method call */
* actually dispatch the call. *reply = (*callback) (connection, message, user_data);
*/
if (list->validate_method)
temp_reply = (*(list->validate_method)) (connection, message, (NMDbusCBData *)user_data);
if (!temp_reply)
temp_reply = (*callback) (connection, message, (NMDbusCBData *)user_data);
if (reply) return TRUE;
*reply = temp_reply;
return (TRUE);
} }
gboolean
void nm_dbus_method_list_free (NMDbusMethodList *list) nm_dbus_method_list_get_is_fallback (NMDbusMethodList *list)
{ {
if (list) g_return_val_if_fail (list != NULL, FALSE);
return list->is_fallback;
}
const char *
nm_dbus_method_list_get_path (NMDbusMethodList *list)
{ {
g_hash_table_destroy (list->methods); g_return_val_if_fail (list != NULL, NULL);
g_slice_free (NMDbusMethodList, list);
} return list->path;
} }

View File

@@ -27,27 +27,42 @@
#include <dbus/dbus-glib-lowlevel.h> #include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include "nm-device.h" typedef struct NMDbusMethodList NMDbusMethodList;
#include "NetworkManagerMain.h"
typedef struct NMDbusCBData
{
NMData *data;
NMDevice *dev;
NMAccessPoint *ap;
} NMDbusCBData;
typedef DBusMessage* (*NMDbusMethod) (DBusConnection *, DBusMessage *, NMDbusCBData *);
NMDbusMethodList * nm_dbus_method_list_new (NMDbusMethod validate_method); typedef DBusMessage * (* NMDBusHandleMessageFunc) (DBusConnection * connection,
DBusMessage * message,
gpointer user_data);
void nm_dbus_method_list_add_method (NMDbusMethodList *list, const char *method, NMDbusMethod callback);
gboolean nm_dbus_method_dispatch (NMDbusMethodList *list, DBusConnection *connection, DBusMessage *message, NMDbusMethodList * nm_dbus_method_list_new (const char *path,
gpointer user_data, DBusMessage **reply); gboolean is_fallback,
gpointer user_data,
DBusFreeFunction user_data_free_func);
void nm_dbus_method_list_free (NMDbusMethodList *list); void nm_dbus_method_list_ref (NMDbusMethodList *list);
void nm_dbus_method_list_unref (NMDbusMethodList *list);
DBusObjectPathMessageFunction nm_dbus_method_list_get_custom_handler_func (NMDbusMethodList *list);
gpointer nm_dbus_method_list_get_user_data (NMDbusMethodList *list);
void nm_dbus_method_list_set_custom_handler_func (NMDbusMethodList *list,
DBusObjectPathMessageFunction handler_func);
void nm_dbus_method_list_add_method (NMDbusMethodList *list,
const char *method,
NMDBusHandleMessageFunc callback);
gboolean nm_dbus_method_list_dispatch (NMDbusMethodList *list,
DBusConnection *connection,
DBusMessage *message,
gpointer user_data,
DBusMessage **reply);
gboolean nm_dbus_method_list_get_is_fallback (NMDbusMethodList *list);
const char * nm_dbus_method_list_get_path (NMDbusMethodList *list);
#endif #endif

View File

@@ -31,6 +31,7 @@
#include "nm-netlink-monitor.h" #include "nm-netlink-monitor.h"
#include "nm-named-manager.h" #include "nm-named-manager.h"
#include "nm-device.h" #include "nm-device.h"
#include "NetworkManagerDbusUtils.h"
typedef enum NMIntState typedef enum NMIntState
@@ -45,7 +46,6 @@ typedef enum NMIntState
} NMIntState; } NMIntState;
typedef struct NMDbusMethodList NMDbusMethodList;
typedef struct NMActRequest NMActRequest; typedef struct NMActRequest NMActRequest;
typedef struct NMVPNActRequest NMVPNActRequest; typedef struct NMVPNActRequest NMVPNActRequest;
typedef struct NMVPNManager NMVPNManager; typedef struct NMVPNManager NMVPNManager;
@@ -67,11 +67,9 @@ typedef struct NMData
NMVPNManager * vpn_manager; NMVPNManager * vpn_manager;
NMDHCPManager * dhcp_manager; NMDHCPManager * dhcp_manager;
DBusConnection * dbus_connection;
NMDbusMethodList * nm_methods; NMDbusMethodList * nm_methods;
NMDbusMethodList * device_methods; NMDbusMethodList * device_methods;
NMDbusMethodList * net_methods; NMDbusMethodList * net_methods;
NMDbusMethodList * vpn_methods;
GMainContext * main_context; GMainContext * main_context;
GMainLoop * main_loop; GMainLoop * main_loop;
@@ -105,10 +103,6 @@ void nm_remove_device (NMData *data, NMDevice *dev);
void nm_schedule_state_change_signal_broadcast (NMData *data); void nm_schedule_state_change_signal_broadcast (NMData *data);
void nm_hal_init (NMData *data);
void nm_hal_deinit (NMData *data);
int nm_get_sigterm_pipe (void); int nm_get_sigterm_pipe (void);
#endif #endif

View File

@@ -38,6 +38,7 @@
#include "nm-dbus-nmi.h" #include "nm-dbus-nmi.h"
#include "nm-device-802-11-wireless.h" #include "nm-device-802-11-wireless.h"
#include "nm-device-802-3-ethernet.h" #include "nm-device-802-3-ethernet.h"
#include "nm-dbus-manager.h"
/* /*
@@ -537,7 +538,8 @@ static gboolean allowed_list_update_pending = FALSE;
* allowed wireless networks. * allowed wireless networks.
* *
*/ */
static gboolean nm_policy_allowed_ap_list_update (gpointer user_data) static gboolean
nm_policy_allowed_ap_list_update (gpointer user_data)
{ {
NMData * data = (NMData *)user_data; NMData * data = (NMData *)user_data;
@@ -551,9 +553,8 @@ static gboolean nm_policy_allowed_ap_list_update (gpointer user_data)
if (data->allowed_ap_list) if (data->allowed_ap_list)
nm_ap_list_unref (data->allowed_ap_list); nm_ap_list_unref (data->allowed_ap_list);
if ((data->allowed_ap_list = nm_ap_list_new (NETWORK_TYPE_ALLOWED))) if ((data->allowed_ap_list = nm_ap_list_new (NETWORK_TYPE_ALLOWED)))
nm_dbus_update_allowed_networks (data->dbus_connection, data->allowed_ap_list, data); nm_dbus_update_allowed_networks (data->allowed_ap_list, data);
return FALSE;
return (FALSE);
} }
@@ -597,7 +598,8 @@ static gboolean device_list_update_pending = FALSE;
* allowed wireless networks. * allowed wireless networks.
* *
*/ */
static gboolean nm_policy_device_list_update_from_allowed_list (NMData *data) static gboolean
nm_policy_device_list_update_from_allowed_list (NMData *data)
{ {
GSList * elt; GSList * elt;
@@ -605,28 +607,31 @@ static gboolean nm_policy_device_list_update_from_allowed_list (NMData *data)
g_return_val_if_fail (data != NULL, FALSE); g_return_val_if_fail (data != NULL, FALSE);
for (elt = data->dev_list; elt != NULL; elt = g_slist_next (elt)) for (elt = data->dev_list; elt != NULL; elt = g_slist_next (elt)) {
{
NMDevice *dev = (NMDevice *)(elt->data); NMDevice *dev = (NMDevice *)(elt->data);
if (nm_device_is_802_11_wireless (dev)) NMDevice80211Wireless * wdev;
{
NMDevice80211Wireless * wdev = NM_DEVICE_802_11_WIRELESS (dev);
if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_WIRELESS_SCAN) if (!nm_device_is_802_11_wireless (dev))
{ continue;
/* Once we have the list, copy in any relevant information from our Allowed list and fill
* in the ESSID of base stations that aren't broadcasting their ESSID, if we have their wdev = NM_DEVICE_802_11_WIRELESS (dev);
* MAC address in our allowed list. if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_WIRELESS_SCAN) {
/* Once we have the list, copy in any relevant information from our
* Allowed list and fill in the ESSID of base stations that aren't
* broadcasting their ESSID, if we have their MAC address in our
* allowed list.
*/ */
nm_ap_list_copy_essids_by_address (data, wdev, nm_device_802_11_wireless_ap_list_get (wdev), data->allowed_ap_list); nm_ap_list_copy_essids_by_address (wdev,
nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (wdev), data->allowed_ap_list); nm_device_802_11_wireless_ap_list_get (wdev),
} data->allowed_ap_list);
else nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (wdev),
data->allowed_ap_list);
} else {
nm_device_802_11_wireless_copy_allowed_to_dev_list (wdev, data->allowed_ap_list); nm_device_802_11_wireless_copy_allowed_to_dev_list (wdev, data->allowed_ap_list);
}
nm_ap_list_remove_duplicate_essids (nm_device_802_11_wireless_ap_list_get (wdev)); nm_ap_list_remove_duplicate_essids (nm_device_802_11_wireless_ap_list_get (wdev));
} }
}
nm_policy_schedule_device_change_check (data); nm_policy_schedule_device_change_check (data);

View File

@@ -32,32 +32,42 @@
#include "NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
#include "nm-activation-request.h" #include "nm-activation-request.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-dbus-manager.h"
#define NM_DHCP_TIMEOUT 45 /* DHCP timeout, in seconds */ #define NM_DHCP_TIMEOUT 45 /* DHCP timeout, in seconds */
static gboolean nm_dhcp_manager_process_signal (DBusConnection *connection,
DBusMessage *message,
gpointer user_data);
static void nm_dhcp_manager_name_owner_changed (NMDBusManager *dbus_mgr,
DBusConnection *connection,
const char *name,
const char *old,
const char *new,
gpointer user_data);
static void nm_dhcp_manager_dbus_connection_changed (NMDBusManager *dbus_mgr,
DBusConnection *dbus_connection,
gpointer user_data);
struct NMDHCPManager struct NMDHCPManager
{ {
NMData * data; NMData * data;
GMainContext * main_ctx;
gboolean running; gboolean running;
size_t dhcp_sn_len; size_t dhcp_sn_len;
NMDBusManager * dbus_mgr;
}; };
char *get_dhcp_match_string (const char *owner)
{
g_return_val_if_fail (owner != NULL, NULL);
return g_strdup_printf ("type='signal',interface='" DHCP_SERVICE_NAME ".state',sender='%s'", owner);
}
static gboolean state_is_bound (guint8 state) static gboolean state_is_bound (guint8 state)
{ {
if ( (state == 2) /* BOUND */ if ( (state == DHCDBD_BOUND)
|| (state == 3) /* RENEW */ || (state == DHCDBD_RENEW)
|| (state == 4) /* REBOOT */ || (state == DHCDBD_REBOOT)
|| (state == 5)) /* REBIND */ || (state == DHCDBD_REBIND))
return TRUE; return TRUE;
return FALSE; return FALSE;
@@ -66,36 +76,46 @@ static gboolean state_is_bound (guint8 state)
static gboolean state_is_down (guint8 state) static gboolean state_is_down (guint8 state)
{ {
if ( (state == 0) /* NBI */ if ( (state == DHCDBD_NBI)
|| (state == 11) /* RELEASE */ || (state == DHCDBD_RELEASE)
|| (state == 13) /* ABEND */ || (state == DHCDBD_ABEND)
|| (state == 14)) /* END */ || (state == DHCDBD_END))
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
NMDHCPManager * nm_dhcp_manager_new (NMData *data) NMDHCPManager *
nm_dhcp_manager_new (NMData *data,
GMainContext *main_ctx)
{ {
NMDHCPManager * manager; NMDHCPManager * manager;
char * owner;
g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dbus_connection != NULL, NULL); g_return_val_if_fail (main_ctx != NULL, NULL);
manager = g_malloc0 (sizeof (NMDHCPManager)); manager = g_slice_new0 (NMDHCPManager);
manager->data = data; manager->data = data;
manager->running = dbus_bus_name_has_owner (manager->data->dbus_connection, DHCP_SERVICE_NAME, NULL); manager->main_ctx = main_ctx;
manager->dbus_mgr = nm_dbus_manager_get (NULL);
manager->running = nm_dbus_manager_name_has_owner (manager->dbus_mgr,
DHCP_SERVICE_NAME);
manager->dhcp_sn_len = strlen (DHCP_SERVICE_NAME); manager->dhcp_sn_len = strlen (DHCP_SERVICE_NAME);
if (manager->running && (owner = get_name_owner (data->dbus_connection, DHCP_SERVICE_NAME))) nm_dbus_manager_register_signal_handler (manager->dbus_mgr,
{ DHCP_SERVICE_NAME ".state",
char *match = get_dhcp_match_string (owner); DHCP_SERVICE_NAME,
dbus_bus_add_match (data->dbus_connection, match, NULL); nm_dhcp_manager_process_signal,
g_free (match); manager);
g_free (owner); g_signal_connect (G_OBJECT (manager->dbus_mgr),
} "name-owner-changed",
G_CALLBACK (nm_dhcp_manager_name_owner_changed),
manager);
g_signal_connect (G_OBJECT (manager->dbus_mgr),
"dbus-connection-changed",
G_CALLBACK (nm_dhcp_manager_dbus_connection_changed),
manager);
return manager; return manager;
} }
@@ -105,53 +125,71 @@ void nm_dhcp_manager_dispose (NMDHCPManager *manager)
{ {
g_return_if_fail (manager != NULL); g_return_if_fail (manager != NULL);
g_object_unref (manager->dbus_mgr);
memset (manager, 0, sizeof (NMDHCPManager)); memset (manager, 0, sizeof (NMDHCPManager));
g_free (manager); g_slice_free (NMDHCPManager, manager);
} }
guint32 nm_dhcp_manager_get_state_for_device (NMDHCPManager *manager, NMDevice *dev) guint32
nm_dhcp_manager_get_state_for_device (NMDHCPManager *manager,
NMDevice *dev)
{ {
DBusMessage * message; DBusMessage * message;
DBusMessage * reply; DBusMessage * reply;
char * path; char * path;
guint32 state = 0; guint32 state = 0;
DBusError error; DBusError error;
DBusConnection *dbus_connection;
g_return_val_if_fail (manager != NULL, 0); g_return_val_if_fail (manager != NULL, 0);
g_return_val_if_fail (dev != NULL, 0); g_return_val_if_fail (dev != NULL, 0);
if (!manager->running) if (!manager->running) {
{
nm_warning ("dhcdbd not running!"); nm_warning ("dhcdbd not running!");
return 0; return 0;
} }
dbus_connection = nm_dbus_manager_get_dbus_connection (manager->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get dbus connection.");
goto out;
}
path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev)); path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev));
message = dbus_message_new_method_call (DHCP_SERVICE_NAME, path, DHCP_SERVICE_NAME".dbus.get", "reason"); message = dbus_message_new_method_call (DHCP_SERVICE_NAME,
path,
DHCP_SERVICE_NAME ".dbus.get",
"reason");
g_free (path); g_free (path);
if (message == NULL) if (message == NULL) {
{ nm_warning ("couldn't allocate the dbus message.");
nm_warning ("nm_dhcp_manager_get_state_for_device(): Couldn't allocate the dbus message"); goto out;
return 0;
} }
dbus_error_init (&error); dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (manager->data->dbus_connection, message, -1, &error); reply = dbus_connection_send_with_reply_and_block (dbus_connection,
message,
-1,
&error);
dbus_message_unref (message); dbus_message_unref (message);
if (dbus_error_is_set (&error)) if (dbus_error_is_set (&error)) {
{ if (strcmp (error.name, "org.freedesktop.DBus.Error.UnknownMethod") != 0) {
if (strcmp (error.name, "org.freedesktop.DBus.Error.UnknownMethod") != 0) nm_info ("Error from dhcdbd on 'reason' request because: name '%s',"
nm_info ("Error from dhcdbd on 'reason' request because: name '%s', message '%s'.", error.name, error.message); " message '%s'.",
error.name,
error.message);
}
dbus_error_free (&error); dbus_error_free (&error);
} }
else if (reply)
{ if (reply) {
if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID)) if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
state = 0; state = 0;
dbus_message_unref (reply); dbus_message_unref (reply);
} }
out:
return state; return state;
} }
@@ -189,7 +227,9 @@ static gboolean nm_dhcp_manager_handle_timeout (NMActRequest *req)
} }
gboolean nm_dhcp_manager_begin_transaction (NMDHCPManager *manager, NMActRequest *req) gboolean
nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
NMActRequest *req)
{ {
DBusError error; DBusError error;
DBusMessage * message; DBusMessage * message;
@@ -199,55 +239,74 @@ gboolean nm_dhcp_manager_begin_transaction (NMDHCPManager *manager, NMActRequest
const guint32 opt1 = 31; /* turns off ALL actions and dhclient-script just writes options to dhcdbd */ const guint32 opt1 = 31; /* turns off ALL actions and dhclient-script just writes options to dhcdbd */
const guint32 opt2 = 2; /* dhclient is run in ONE SHOT mode and releases existing leases when brought down */ const guint32 opt2 = 2; /* dhclient is run in ONE SHOT mode and releases existing leases when brought down */
GSource * source; GSource * source;
DBusConnection * dbus_connection;
gboolean success = FALSE;
g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (req != NULL, FALSE); g_return_val_if_fail (req != NULL, FALSE);
if (!manager->running) if (!manager->running) {
{
nm_warning ("dhcdbd not running!"); nm_warning ("dhcdbd not running!");
return FALSE; return FALSE;
} }
else
{ dbus_connection = nm_dbus_manager_get_dbus_connection (manager->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get dbus connection.");
goto out;
}
/* Cancel any DHCP transaction already in progress */ /* Cancel any DHCP transaction already in progress */
nm_dhcp_manager_cancel_transaction (manager, req); nm_dhcp_manager_cancel_transaction (manager, req);
/* FIXME don't sleep */ /* FIXME don't sleep */
sleep (1); sleep (1);
}
dev = nm_act_request_get_dev (req); dev = nm_act_request_get_dev (req);
g_assert (dev); g_assert (dev);
nm_info ("Activation (%s) Beginning DHCP transaction.", nm_device_get_iface (dev)); nm_info ("Activation (%s) Beginning DHCP transaction.",
nm_device_get_iface (dev));
path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev)); path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev));
message = dbus_message_new_method_call (DHCP_SERVICE_NAME, path, DHCP_SERVICE_NAME, "up"); message = dbus_message_new_method_call (DHCP_SERVICE_NAME,
path,
DHCP_SERVICE_NAME,
"up");
g_free (path); g_free (path);
if (message == NULL) if (message == NULL) {
{ nm_warning ("couldn't allocate dbus message");
nm_warning ("nm_dhcp_manager_begin_transaction(): Couldn't allocate the dbus message"); goto out;
return FALSE;
} }
dbus_message_append_args (message, DBUS_TYPE_UINT32, &opt1, DBUS_TYPE_UINT32, &opt2, DBUS_TYPE_INVALID); dbus_message_append_args (message,
DBUS_TYPE_UINT32, &opt1,
DBUS_TYPE_UINT32, &opt2,
DBUS_TYPE_INVALID);
dbus_error_init (&error); dbus_error_init (&error);
if ((reply = dbus_connection_send_with_reply_and_block (manager->data->dbus_connection, message, -1, &error))) if ((reply = dbus_connection_send_with_reply_and_block (dbus_connection, message, -1, &error)))
dbus_message_unref (reply); dbus_message_unref (reply);
dbus_message_unref (message); dbus_message_unref (message);
if (dbus_error_is_set (&error)) if (dbus_error_is_set (&error)) {
{ nm_info ("Couldn't send DHCP 'up' message because: name '%s', message "
nm_info ("Couldn't send DHCP 'up' message because: name '%s', message '%s'.", error.name, error.message); " '%s'.",
error.name,
error.message);
dbus_error_free (&error); dbus_error_free (&error);
return FALSE; goto out;
} }
/* Set up a timeout on the transaction to kill it after NM_DHCP_TIMEOUT seconds */ /* Set up a timeout on the transaction to kill it after NM_DHCP_TIMEOUT seconds */
source = g_timeout_source_new (NM_DHCP_TIMEOUT * 1000); source = g_timeout_source_new (NM_DHCP_TIMEOUT * 1000);
g_source_set_callback (source, (GSourceFunc) nm_dhcp_manager_handle_timeout, req, NULL); g_source_set_callback (source,
nm_act_request_set_dhcp_timeout (req, g_source_attach (source, manager->data->main_context)); (GSourceFunc) nm_dhcp_manager_handle_timeout,
req,
NULL);
nm_act_request_set_dhcp_timeout (req, g_source_attach (source, manager->main_ctx));
g_source_unref (source); g_source_unref (source);
success = TRUE;
out:
return TRUE; return TRUE;
} }
@@ -262,7 +321,7 @@ static void remove_timeout (NMDHCPManager *manager, NMActRequest *req)
/* Remove any pending timeouts on the request */ /* Remove any pending timeouts on the request */
if ((id = nm_act_request_get_dhcp_timeout (req)) > 0) if ((id = nm_act_request_get_dhcp_timeout (req)) > 0)
{ {
GSource * source = g_main_context_find_source_by_id (manager->data->main_context, id); GSource * source = g_main_context_find_source_by_id (manager->main_ctx, id);
nm_act_request_set_dhcp_timeout (req, 0); nm_act_request_set_dhcp_timeout (req, 0);
g_source_destroy (source); g_source_destroy (source);
} }
@@ -274,24 +333,42 @@ static void remove_timeout (NMDHCPManager *manager, NMActRequest *req)
* Stop any in-progress DHCP transaction on a particular device. * Stop any in-progress DHCP transaction on a particular device.
* *
*/ */
void nm_dhcp_manager_cancel_transaction (NMDHCPManager *manager, NMActRequest *req) void
nm_dhcp_manager_cancel_transaction (NMDHCPManager *manager,
NMActRequest *req)
{ {
NMDevice *dev; NMDevice *dev;
DBusMessage *message = NULL;
char *path;
DBusConnection *dbus_connection;
g_return_if_fail (manager != NULL); g_return_if_fail (manager != NULL);
g_return_if_fail (req != NULL); g_return_if_fail (req != NULL);
if (!manager->running || state_is_down (nm_act_request_get_dhcp_state (req)))
return;
dev = nm_act_request_get_dev (req); dev = nm_act_request_get_dev (req);
g_assert (dev); g_assert (dev);
if (manager->running && !state_is_down (nm_act_request_get_dhcp_state (req))) dbus_connection = nm_dbus_manager_get_dbus_connection (manager->dbus_mgr);
{ if (!dbus_connection) {
DBusMessage * message; nm_warning ("could not get dbus connection.");
char * path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev)); goto out;
}
if ((message = dbus_message_new_method_call (DHCP_SERVICE_NAME, path, DHCP_SERVICE_NAME, "down"))) path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev));
{ message = dbus_message_new_method_call (DHCP_SERVICE_NAME,
dbus_connection_send (manager->data->dbus_connection, message, NULL); path,
DHCP_SERVICE_NAME,
"down");
g_free (path);
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
dbus_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message); dbus_message_unref (message);
/* Give dhcdbd/dhclient some time to send out a RELEASE if they like */ /* Give dhcdbd/dhclient some time to send out a RELEASE if they like */
@@ -300,140 +377,192 @@ void nm_dhcp_manager_cancel_transaction (NMDHCPManager *manager, NMActRequest *r
*/ */
if (!manager->data->asleep) if (!manager->data->asleep)
sleep (1); sleep (1);
}
g_free (path);
remove_timeout (manager, req); remove_timeout (manager, req);
}
out:
return;
} }
static gboolean get_ip4_uint32s (NMDHCPManager *manager, NMDevice *dev, const char *item, static gboolean
guint32 **ip4_uint32, guint32 *num_items, gboolean ignore_error) get_ip4_uint32s (NMDHCPManager *manager,
NMDevice *dev,
const char *item,
guint32 **ip4_uint32,
guint32 *num_items,
gboolean ignore_error)
{ {
DBusMessage * message = NULL; DBusMessage * message = NULL;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
char * path; char * path;
gboolean success = FALSE; gboolean success = FALSE;
DBusConnection *dbus_connection;
DBusError error;
GArray * buffer;
DBusMessageIter iter;
g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (ip4_uint32 != NULL, FALSE); g_return_val_if_fail (ip4_uint32 != NULL, FALSE);
g_return_val_if_fail (num_items != NULL, FALSE); g_return_val_if_fail (num_items != NULL, FALSE);
dbus_connection = nm_dbus_manager_get_dbus_connection (manager->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get dbus connection.");
goto out;
}
*ip4_uint32 = NULL; *ip4_uint32 = NULL;
*num_items = 0; *num_items = 0;
path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev)); path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev));
if ((message = dbus_message_new_method_call (DHCP_SERVICE_NAME, path, DHCP_SERVICE_NAME".dbus.get", item))) message = dbus_message_new_method_call (DHCP_SERVICE_NAME,
{ path,
DBusError error; DHCP_SERVICE_NAME".dbus.get",
item);
g_free (path);
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
dbus_error_init (&error); dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (manager->data->dbus_connection, message, -1, &error); reply = dbus_connection_send_with_reply_and_block (dbus_connection,
if (reply) message,
{ -1,
GArray *buffer; &error);
DBusMessageIter iter; dbus_message_unref (message);
if (dbus_error_is_set (&error)) {
if (!ignore_error) {
nm_warning ("error calling '%s', DHCP daemon returned error '%s', "
"message '%s'.",
item,
error.name,
error.message);
}
dbus_error_free (&error);
goto out;
}
if (!reply) {
nm_warning ("error calling '%s', DHCP daemon did not respond.", item);
goto out;
}
dbus_message_iter_init (reply, &iter); dbus_message_iter_init (reply, &iter);
buffer = g_array_new (TRUE, TRUE, sizeof (guint32)); buffer = g_array_new (TRUE, TRUE, sizeof (guint32));
while (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32) while (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32) {
{ guint32 uint32_value;
guint32 value;
dbus_message_iter_get_basic (&iter, &value); dbus_message_iter_get_basic (&iter, &uint32_value);
g_array_append_val (buffer, value); g_array_append_val (buffer, uint32_value);
dbus_message_iter_next (&iter); dbus_message_iter_next (&iter);
success = TRUE; success = TRUE;
} }
if (success) if (success) {
{
*ip4_uint32 = (guint32 *)(buffer->data); *ip4_uint32 = (guint32 *)(buffer->data);
*num_items = buffer->len; *num_items = buffer->len;
} }
g_array_free (buffer, FALSE); g_array_free (buffer, FALSE);
dbus_message_unref (reply); dbus_message_unref (reply);
}
if (dbus_error_is_set (&error))
{
if (!ignore_error)
nm_warning ("get_ip4_uint32s(): error calling '%s', DHCP daemon returned error '%s', message '%s'.",
item, error.name, error.message);
dbus_error_free (&error);
}
dbus_message_unref (message);
}
g_free (path);
out:
return success; return success;
} }
static gboolean get_ip4_string (NMDHCPManager *manager, NMDevice *dev, const char *item, static gboolean
char **string, gboolean ignore_error) get_ip4_string (NMDHCPManager *manager,
NMDevice *dev,
const char *item,
char **string,
gboolean ignore_error)
{ {
DBusMessage * message = NULL; DBusMessage * message = NULL;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
char * path; char * path;
gboolean success = FALSE; gboolean success = FALSE;
DBusError error;
DBusConnection *dbus_connection;
DBusMessageIter iter;
g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (string != NULL, FALSE); g_return_val_if_fail (string != NULL, FALSE);
dbus_connection = nm_dbus_manager_get_dbus_connection (manager->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get dbus connection.");
goto out;
}
*string = NULL; *string = NULL;
path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev)); path = g_strdup_printf (DHCP_OBJECT_PATH"/%s", nm_device_get_iface (dev));
if ((message = dbus_message_new_method_call (DHCP_SERVICE_NAME, path, DHCP_SERVICE_NAME".dbus.get", item))) message = dbus_message_new_method_call (DHCP_SERVICE_NAME,
{ path,
DBusError error; DHCP_SERVICE_NAME".dbus.get",
item);
g_free (path);
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
dbus_error_init (&error); dbus_error_init (&error);
if ((reply = dbus_connection_send_with_reply_and_block (manager->data->dbus_connection, message, -1, &error))) reply = dbus_connection_send_with_reply_and_block (dbus_connection,
{ message,
DBusMessageIter iter; -1,
&error);
dbus_message_unref (message);
if (dbus_error_is_set (&error)) {
if (!ignore_error) {
nm_warning ("error calling '%s', DHCP daemon returned error '%s', "
"message '%s'.",
item,
error.name,
error.message);
}
dbus_error_free (&error);
*string = NULL;
goto out;
}
if (!reply) {
nm_warning ("error calling '%s', DHCP daemon did not respond.", item);
goto out;
}
dbus_message_iter_init (reply, &iter); dbus_message_iter_init (reply, &iter);
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) {
{
char *dbus_string; char *dbus_string;
dbus_error_init (&error); dbus_error_init (&error);
if (dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &dbus_string, DBUS_TYPE_INVALID)) if (dbus_message_get_args (reply,
{ &error,
DBUS_TYPE_STRING, &dbus_string,
DBUS_TYPE_INVALID)) {
*string = g_strdup (dbus_string); *string = g_strdup (dbus_string);
success = TRUE; success = TRUE;
} }
} } else if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY) {
else if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY)
{
char *byte_array = NULL; char *byte_array = NULL;
int len = 0; int len = 0;
dbus_error_init (&error); dbus_error_init (&error);
if (dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &byte_array, &len, DBUS_TYPE_INVALID)) if (dbus_message_get_args (reply,
{ &error,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &byte_array, &len,
DBUS_TYPE_INVALID)) {
byte_array[len] = '\0'; byte_array[len] = '\0';
*string = g_strdup (byte_array); *string = g_strdup (byte_array);
success = TRUE; success = TRUE;
} }
} }
}
if (dbus_error_is_set (&error))
{
if (!ignore_error)
nm_warning ("get_ip4_string(): error calling '%s', DHCP daemon returned error '%s', message '%s'.",
item, error.name, error.message);
dbus_error_free (&error);
*string = NULL;
}
dbus_message_unref (message);
}
g_free (path);
out:
return success; return success;
} }
@@ -627,8 +756,12 @@ static inline const char * state_to_string (guint8 state)
* active DHCP daemon, if any. Return TRUE if processed, FALSE if not. * active DHCP daemon, if any. Return TRUE if processed, FALSE if not.
* *
*/ */
gboolean nm_dhcp_manager_process_signal (NMDHCPManager *manager, DBusMessage *message) static gboolean
nm_dhcp_manager_process_signal (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDHCPManager * manager = (NMDHCPManager *) user_data;
const char * object_path; const char * object_path;
const char * member; const char * member;
const char * interface; const char * interface;
@@ -648,6 +781,7 @@ gboolean nm_dhcp_manager_process_signal (NMDHCPManager *manager, DBusMessage *me
return FALSE; return FALSE;
if (!(interface = dbus_message_get_interface (message))) if (!(interface = dbus_message_get_interface (message)))
return FALSE; return FALSE;
/* Ignore non-DHCP related messages */ /* Ignore non-DHCP related messages */
if (strncmp (interface, DHCP_SERVICE_NAME, manager->dhcp_sn_len)) if (strncmp (interface, DHCP_SERVICE_NAME, manager->dhcp_sn_len))
return FALSE; return FALSE;
@@ -702,7 +836,7 @@ gboolean nm_dhcp_manager_process_signal (NMDHCPManager *manager, DBusMessage *me
case DHCDBD_FAIL: /* all attempts to contact server timed out, sleeping */ case DHCDBD_FAIL: /* all attempts to contact server timed out, sleeping */
case DHCDBD_ABEND: /* dhclient exited abnormally */ case DHCDBD_ABEND: /* dhclient exited abnormally */
// case DHCDBD_END: /* dhclient exited normally */ case DHCDBD_END: /* dhclient exited normally */
if (nm_act_request_get_stage (req) == NM_ACT_STAGE_IP_CONFIG_START) if (nm_act_request_get_stage (req) == NM_ACT_STAGE_IP_CONFIG_START)
{ {
nm_policy_schedule_activation_failed (req); nm_policy_schedule_activation_failed (req);
@@ -726,43 +860,44 @@ out:
* Respond to "service created"/"service deleted" signals from dbus for the active DHCP daemon. * Respond to "service created"/"service deleted" signals from dbus for the active DHCP daemon.
* *
*/ */
gboolean nm_dhcp_manager_process_name_owner_changed (NMDHCPManager *manager, const char *changed_service_name, const char *old_owner, const char *new_owner) static void
nm_dhcp_manager_name_owner_changed (NMDBusManager *dbus_mgr,
DBusConnection *connection,
const char *name,
const char *old,
const char *new,
gpointer user_data)
{ {
gboolean handled = FALSE; NMDHCPManager * self = (NMDHCPManager *) user_data;
gboolean old_owner_good = (old_owner && strlen (old_owner)); gboolean old_owner_good = (old && strlen (old));
gboolean new_owner_good = (new_owner && strlen (new_owner)); gboolean new_owner_good = (new && strlen (new));
g_return_val_if_fail (manager != NULL, FALSE); g_return_if_fail (self != NULL);
g_return_val_if_fail (changed_service_name != NULL, FALSE); g_return_if_fail (name != NULL);
/* Can't handle the signal if its not from the DHCP service */ /* Can't handle the signal if its not from the DHCP service */
if (strcmp (DHCP_SERVICE_NAME, changed_service_name) != 0) if (strcmp (DHCP_SERVICE_NAME, name) != 0)
return FALSE; return;
if (!old_owner_good && new_owner_good) if (!old_owner_good && new_owner_good) {
self->running = TRUE;
} else if (old_owner_good && !new_owner_good) {
self->running = FALSE;
}
}
static void
nm_dhcp_manager_dbus_connection_changed (NMDBusManager *dbus_mgr,
DBusConnection *dbus_connection,
gpointer user_data)
{ {
char *match = get_dhcp_match_string (new_owner); NMDHCPManager * self = (NMDHCPManager *) user_data;
/* DHCP service got created */ if (dbus_connection) {
dbus_bus_add_match (manager->data->dbus_connection, match, NULL); if (nm_dbus_manager_name_has_owner (dbus_mgr, DHCP_SERVICE_NAME))
g_free (match); self->running = TRUE;
} else {
manager->running = TRUE; self->running = FALSE;
handled = TRUE;
} }
else if (old_owner_good && !new_owner_good)
{
char *match = get_dhcp_match_string (old_owner);
/* DHCP service went away */
dbus_bus_remove_match (manager->data->dbus_connection, match, NULL);
g_free (match);
manager->running = FALSE;
handled = TRUE;
} }
return handled;
}

View File

@@ -49,9 +49,7 @@ enum dhcdbd_state
DHCDBD_END_OPTIONS, /* last option in subscription sent */ DHCDBD_END_OPTIONS, /* last option in subscription sent */
}; };
char * get_dhcp_match_string (const char *owner); NMDHCPManager * nm_dhcp_manager_new (NMData *data, GMainContext *main_ctx);
NMDHCPManager * nm_dhcp_manager_new (NMData *data);
void nm_dhcp_manager_dispose (NMDHCPManager *manager); void nm_dhcp_manager_dispose (NMDHCPManager *manager);
gboolean nm_dhcp_manager_begin_transaction (NMDHCPManager *manager, NMActRequest *req); gboolean nm_dhcp_manager_begin_transaction (NMDHCPManager *manager, NMActRequest *req);
@@ -59,9 +57,6 @@ void nm_dhcp_manager_cancel_transaction (NMDHCPManager *manager, NMActReque
NMIP4Config * nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, NMActRequest *req); NMIP4Config * nm_dhcp_manager_get_ip4_config (NMDHCPManager *manager, NMActRequest *req);
gboolean nm_dhcp_manager_process_signal (NMDHCPManager *manager, DBusMessage *message);
gboolean nm_dhcp_manager_process_name_owner_changed (NMDHCPManager *manager, const char *changed_service_name, const char *old_owner, const char *new_owner);
guint32 nm_dhcp_manager_get_state_for_device (NMDHCPManager *manager, NMDevice *dev); guint32 nm_dhcp_manager_get_state_for_device (NMDHCPManager *manager, NMDevice *dev);
#endif #endif

View File

@@ -39,6 +39,7 @@
#include "nm-ip4-config.h" #include "nm-ip4-config.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
#include "nm-dbus-manager.h"
#ifdef HAVE_SELINUX #ifdef HAVE_SELINUX
#include <selinux/selinux.h> #include <selinux/selinux.h>
@@ -54,26 +55,11 @@
#define NAMED_DBUS_PATH "/com/redhat/named" #define NAMED_DBUS_PATH "/com/redhat/named"
#endif #endif
enum
{
PROP_0,
PROP_DBUS_CONNECTION
};
G_DEFINE_TYPE(NMNamedManager, nm_named_manager, G_TYPE_OBJECT) G_DEFINE_TYPE(NMNamedManager, nm_named_manager, G_TYPE_OBJECT)
static void nm_named_manager_finalize (GObject *object); #define NM_NAMED_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
static void nm_named_manager_dispose (GObject *object); NM_TYPE_NAMED_MANAGER, \
static GObject *nm_named_manager_constructor (GType type, guint n_construct_properties, NMNamedManagerPrivate))
GObjectConstructParam *construct_properties);
static void nm_named_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void nm_named_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static NMIP4Config *get_last_default_domain (NMNamedManager *mgr); static NMIP4Config *get_last_default_domain (NMNamedManager *mgr);
@@ -83,139 +69,15 @@ static gboolean rewrite_resolv_conf (NMNamedManager *mgr, NMIP4Config *config, G
static gboolean remove_ip4_config_from_named (NMNamedManager *mgr, NMIP4Config *config); static gboolean remove_ip4_config_from_named (NMNamedManager *mgr, NMIP4Config *config);
struct NMNamedManagerPrivate
{
gboolean use_named;
DBusConnection *connection;
struct NMNamedManagerPrivate {
gboolean use_named;
NMDBusManager * dbus_mgr;
GSList * configs; GSList * configs;
gboolean disposed; gboolean disposed;
}; };
static void
nm_named_manager_class_init (NMNamedManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = nm_named_manager_dispose;
object_class->finalize = nm_named_manager_finalize;
object_class->constructor = nm_named_manager_constructor;
object_class->set_property = nm_named_manager_set_property;
object_class->get_property = nm_named_manager_get_property;
g_object_class_install_property (object_class,
PROP_DBUS_CONNECTION,
g_param_spec_pointer ("dbus-connection",
"DBusConnection",
"dbus connection",
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
static void
nm_named_manager_init (NMNamedManager *mgr)
{
mgr->priv = g_new0 (NMNamedManagerPrivate, 1);
mgr->priv->use_named = FALSE;
}
static void
nm_named_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NMNamedManager *mgr = NM_NAMED_MANAGER (object);
switch (prop_id)
{
case PROP_DBUS_CONNECTION:
mgr->priv->connection = g_value_get_pointer (value);
mgr->priv->use_named = (gboolean) dbus_bus_name_has_owner (mgr->priv->connection,
NAMED_DBUS_SERVICE, NULL);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_named_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NMNamedManager *mgr = NM_NAMED_MANAGER (object);
switch (prop_id)
{
case PROP_DBUS_CONNECTION:
g_value_set_pointer (value, mgr->priv->connection);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_named_manager_dispose (GObject *object)
{
NMNamedManager *mgr = NM_NAMED_MANAGER (object);
GSList *elt;
if (mgr->priv->disposed)
return;
mgr->priv->disposed = TRUE;
for (elt = mgr->priv->configs; elt; elt = g_slist_next (elt))
remove_ip4_config_from_named (mgr, (NMIP4Config *)(elt->data));
}
static void
nm_named_manager_finalize (GObject *object)
{
NMNamedManager *mgr = NM_NAMED_MANAGER (object);
g_return_if_fail (mgr->priv != NULL);
g_slist_foreach (mgr->priv->configs, (GFunc) nm_ip4_config_unref, NULL);
g_slist_free (mgr->priv->configs);
g_free (mgr->priv);
G_OBJECT_CLASS (nm_named_manager_parent_class)->finalize (object);
}
static GObject *
nm_named_manager_constructor (GType type, guint n_construct_properties,
GObjectConstructParam *construct_properties)
{
NMNamedManager *mgr;
NMNamedManagerClass *klass;
GObjectClass *parent_class;
klass = NM_NAMED_MANAGER_CLASS (g_type_class_peek (NM_TYPE_NAMED_MANAGER));
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
mgr = NM_NAMED_MANAGER (parent_class->constructor (type, n_construct_properties,
construct_properties));
return G_OBJECT (mgr);
}
NMNamedManager *
nm_named_manager_new (DBusConnection *connection)
{
return NM_NAMED_MANAGER (g_object_new (NM_TYPE_NAMED_MANAGER,
"dbus-connection",
connection,
NULL));
}
GQuark GQuark
nm_named_manager_error_quark (void) nm_named_manager_error_quark (void)
@@ -234,49 +96,78 @@ nm_named_manager_error_quark (void)
* Respond to "service created"/"service deleted" signals from dbus for named. * Respond to "service created"/"service deleted" signals from dbus for named.
* *
*/ */
gboolean static void
nm_named_manager_process_name_owner_changed (NMNamedManager *mgr, nm_named_manager_name_owner_changed (NMDBusManager *dbus_mgr,
const char *changed_service_name, DBusConnection *connection,
const char *old_owner, const char *new_owner) const char *name,
const char *old,
const char *new,
gpointer user_data)
{ {
NMNamedManager *mgr = (NMNamedManager *) user_data;
gboolean handled = FALSE; gboolean handled = FALSE;
gboolean old_owner_good = (old_owner && strlen (old_owner)); gboolean old_owner_good = (old && strlen (old));
gboolean new_owner_good = (new_owner && strlen (new_owner)); gboolean new_owner_good = (new && strlen (new));
g_return_val_if_fail (mgr != NULL, FALSE); g_return_if_fail (mgr != NULL);
g_return_val_if_fail (changed_service_name != NULL, FALSE); g_return_if_fail (name != NULL);
/* Ensure signal is for named's service */ /* Ensure signal is for named's service */
if (strcmp (NAMED_DBUS_SERVICE, changed_service_name) != 0) if (strcmp (NAMED_DBUS_SERVICE, name) != 0)
return FALSE; return;
if (!old_owner_good && new_owner_good) if (!old_owner_good && new_owner_good) {
{
mgr->priv->use_named = TRUE; mgr->priv->use_named = TRUE;
if (!add_all_ip4_configs_to_named (mgr)) if (!add_all_ip4_configs_to_named (mgr))
nm_warning ("Could not set fowarders in named."); nm_warning ("Could not set fowarders in named.");
handled = TRUE; handled = TRUE;
} } else if (old_owner_good && !new_owner_good) {
else if (old_owner_good && !new_owner_good)
{
mgr->priv->use_named = FALSE; mgr->priv->use_named = FALSE;
/* FIXME: change resolv.conf */
handled = TRUE; handled = TRUE;
} }
if (handled) if (handled) {
{
GError *error = NULL; GError *error = NULL;
if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error)) if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error)) {
{ nm_warning ("Could not write resolv.conf. Error: '%s'",
nm_warning ("Could not write resolv.conf. Error: '%s'", error ? error->message : "(none)"); error ? error->message : "(none)");
g_error_free (error); g_error_free (error);
} }
} }
}
return handled; static void
nm_named_manager_dbus_connection_changed (NMDBusManager *dbus_mgr,
DBusConnection *dbus_connection,
gpointer user_data)
{
NMNamedManager *mgr = (NMNamedManager *) user_data;
gboolean handled = FALSE;
g_return_if_fail (mgr != NULL);
if (dbus_connection) {
if (nm_dbus_manager_name_has_owner (dbus_mgr, NAMED_DBUS_SERVICE)) {
mgr->priv->use_named = TRUE;
if (!add_all_ip4_configs_to_named (mgr))
nm_warning ("Could not set fowarders in named.");
handled = TRUE;
}
} else {
mgr->priv->use_named = FALSE;
handled = TRUE;
}
if (handled) {
GError *error = NULL;
if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error)) {
nm_warning ("Could not write resolv.conf. Error: '%s'",
error ? error->message : "(none)");
g_error_free (error);
}
}
} }
static char * static char *
@@ -439,64 +330,88 @@ add_ip4_config_to_named (NMNamedManager *mgr, NMIP4Config *config)
{ {
const char *domain; const char *domain;
int i, num_nameservers; int i, num_nameservers;
gboolean success = FALSE;
DBusMessage * message; DBusMessage * message;
DBusMessage * reply; DBusMessage * reply = NULL;
DBusError error; DBusError error;
gboolean dflt = FALSE; gboolean dflt = FALSE;
DBusConnection *dbus_connection;
g_return_val_if_fail (mgr != NULL, FALSE); g_return_val_if_fail (mgr != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE); g_return_val_if_fail (config != NULL, FALSE);
dbus_error_init (&error);
dbus_connection = nm_dbus_manager_get_dbus_connection (mgr->priv->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get dbus connection.");
goto out;
}
if (!(domain = get_domain_for_config (config, &dflt))) if (!(domain = get_domain_for_config (config, &dflt)))
return FALSE; goto out;
if (!(message = dbus_message_new_method_call (NAMED_DBUS_SERVICE, NAMED_DBUS_PATH, NAMED_DBUS_INTERFACE, "SetForwarders"))) message = dbus_message_new_method_call (NAMED_DBUS_SERVICE,
return FALSE; NAMED_DBUS_PATH,
NAMED_DBUS_INTERFACE,
"SetForwarders");
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, &domain, DBUS_TYPE_INVALID); dbus_message_append_args (message,
DBUS_TYPE_STRING, &domain,
DBUS_TYPE_INVALID);
num_nameservers = nm_ip4_config_get_num_nameservers (config); num_nameservers = nm_ip4_config_get_num_nameservers (config);
for (i = 0; i < num_nameservers; i++) for (i = 0; i < num_nameservers; i++) {
{
dbus_uint32_t server = nm_ip4_config_get_nameserver (config, i); dbus_uint32_t server = nm_ip4_config_get_nameserver (config, i);
dbus_uint16_t port = htons (53); /* default DNS port */ dbus_uint16_t port = htons (53); /* default DNS port */
char fwd_policy = dflt ? 1 : 2; /* 'first' : 'only' */ char fwd_policy = dflt ? 1 : 2; /* 'first' : 'only' */
dbus_message_append_args (message, DBUS_TYPE_UINT32, &server, dbus_message_append_args (message,
DBUS_TYPE_UINT32, &server,
DBUS_TYPE_UINT16, &port, DBUS_TYPE_UINT16, &port,
DBUS_TYPE_BYTE, &fwd_policy, DBUS_TYPE_BYTE, &fwd_policy,
DBUS_TYPE_INVALID); DBUS_TYPE_INVALID);
} }
dbus_error_init (&error); reply = dbus_connection_send_with_reply_and_block (dbus_connection,
reply = dbus_connection_send_with_reply_and_block (mgr->priv->connection, message, -1, &error); message, -1, &error);
dbus_message_unref (message); dbus_message_unref (message);
if (dbus_error_is_set (&error)) {
if (dbus_error_is_set (&error)) nm_warning ("Could not set forwarders for zone '%s'. Error: '%s'.",
{ domain,
nm_warning ("Could not set forwarders for zone '%s'. Error: '%s'.", domain, error.message); error.message);
dbus_error_free (&error); goto out;
return FALSE;
} }
if (!reply) if (!reply) {
{ nm_warning ("Could not set forwarders for zone '%s', did not receive "
nm_warning ("Could not set forwarders for zone '%s', did not receive a reply from named.", domain); "a reply from named.",
dbus_error_free (&error); domain);
return FALSE; goto out;
} }
if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
{
const char *err_msg = NULL; const char *err_msg = NULL;
dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); dbus_message_get_args (reply,
nm_warning ("Could not set forwarders for zone '%s'. Named replied: '%s'", domain, err_msg); NULL,
dbus_message_unref (reply); DBUS_TYPE_STRING, &err_msg,
return FALSE; DBUS_TYPE_INVALID);
nm_warning ("Could not set forwarders for zone '%s'. "
"Named replied: '%s'",
domain,
err_msg);
} }
dbus_message_unref (reply); success = TRUE;
return TRUE; out:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
dbus_message_unref (reply);
return success;
} }
static gboolean static gboolean
@@ -515,47 +430,76 @@ add_all_ip4_configs_to_named (NMNamedManager *mgr)
static gboolean static gboolean
remove_one_zone_from_named (NMNamedManager *mgr, const char *zone) remove_one_zone_from_named (NMNamedManager *mgr, const char *zone)
{ {
DBusMessage * message; gboolean success = FALSE;
DBusMessage * reply; DBusMessage * message = NULL;
DBusMessage * reply = NULL;
DBusError error; DBusError error;
DBusConnection *dbus_connection;
g_return_val_if_fail (mgr != NULL, FALSE); g_return_val_if_fail (mgr != NULL, FALSE);
g_return_val_if_fail (zone != NULL, FALSE); g_return_val_if_fail (zone != NULL, FALSE);
if (!(message = dbus_message_new_method_call (NAMED_DBUS_SERVICE, NAMED_DBUS_PATH, NAMED_DBUS_INTERFACE, "SetForwarders")))
return FALSE;
dbus_message_append_args (message, DBUS_TYPE_STRING, &zone, DBUS_TYPE_INVALID);
dbus_error_init (&error); dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (mgr->priv->connection, message, -1, &error);
dbus_connection = nm_dbus_manager_get_dbus_connection (mgr->priv->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get dbus connection.");
goto out;
}
message = dbus_message_new_method_call (NAMED_DBUS_SERVICE,
NAMED_DBUS_PATH,
NAMED_DBUS_INTERFACE,
"SetForwarders");
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
dbus_message_append_args (message,
DBUS_TYPE_STRING, &zone,
DBUS_TYPE_INVALID);
reply = dbus_connection_send_with_reply_and_block (dbus_connection,
message,
-1,
&error);
dbus_message_unref (message); dbus_message_unref (message);
if (dbus_error_is_set (&error)) if (dbus_error_is_set (&error)) {
{ nm_warning ("Could not remove forwarders for zone '%s'. "
nm_warning ("Could not remove forwarders for zone '%s'. Error: '%s'.", zone, error.message); "Error: '%s'.",
dbus_error_free (&error); zone,
return FALSE; error.message);
goto out;
} }
if (!reply) if (!reply) {
{ nm_warning ("Could not remove forwarders for zone '%s', did not "
nm_warning ("Could not remove forwarders for zone '%s', did not receive a reply from named.", zone); " receive a reply from named.",
dbus_error_free (&error); zone);
return FALSE; goto out;
} }
if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
{
const char *err_msg = NULL; const char *err_msg = NULL;
dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); dbus_message_get_args (reply,
nm_warning ("Could not remove forwarders for zone '%s'. Named replied: '%s'", zone, err_msg); NULL,
dbus_message_unref (reply); DBUS_TYPE_STRING, &err_msg,
return FALSE; DBUS_TYPE_INVALID);
nm_warning ("Could not remove forwarders for zone '%s'. "
"Named replied: '%s'",
zone,
err_msg);
goto out;
} }
dbus_message_unref (reply); success = TRUE;
return TRUE; out:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
dbus_message_unref (reply);
return success;
} }
static gboolean static gboolean
@@ -576,59 +520,75 @@ static void
remove_all_zones_from_named (NMNamedManager *mgr) remove_all_zones_from_named (NMNamedManager *mgr)
{ {
DBusMessage * message; DBusMessage * message;
DBusMessage * reply; DBusMessage * reply = NULL;
DBusError error; DBusError error;
DBusMessageIter iter; DBusMessageIter iter;
GSList * zones = NULL; GSList * zones = NULL;
GSList * elt = NULL; GSList * elt = NULL;
DBusConnection * dbus_connection;
g_return_if_fail (mgr != NULL); g_return_if_fail (mgr != NULL);
if (!mgr->priv->use_named) if (!mgr->priv->use_named)
return; return;
if (!(message = dbus_message_new_method_call (NAMED_DBUS_SERVICE, NAMED_DBUS_PATH, NAMED_DBUS_INTERFACE, "GetForwarders"))) dbus_connection = nm_dbus_manager_get_dbus_connection (mgr->priv->dbus_mgr);
return; if (!dbus_connection) {
nm_warning ("could not get dbus connection.");
goto out;
}
message = dbus_message_new_method_call (NAMED_DBUS_SERVICE,
NAMED_DBUS_PATH,
NAMED_DBUS_INTERFACE,
"GetForwarders");
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
dbus_error_init (&error); dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (mgr->priv->connection, message, -1, &error); reply = dbus_connection_send_with_reply_and_block (dbus_connection,
message,
-1,
&error);
dbus_message_unref (message); dbus_message_unref (message);
if (dbus_error_is_set (&error)) if (dbus_error_is_set (&error)) {
{ nm_warning ("Could not get forwarder list from named. Error: '%s'.",
nm_warning ("Could not get forwarder list from named. Error: '%s'.", error.message); error.message);
dbus_error_free (&error); goto out;
return;
} }
if (!reply) if (!reply) {
{ nm_warning ("Could not get forarder list from named, did not receive "
nm_warning ("Could not get forarder list from named, did not receive a reply from named."); " a reply from named.");
dbus_error_free (&error); goto out;
return;
} }
if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
{
const char *err_msg = NULL; const char *err_msg = NULL;
dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); dbus_message_get_args (reply,
nm_warning ("Could not get forwarder list from named. Named replied: '%s'", err_msg); NULL,
dbus_message_unref (reply); DBUS_TYPE_STRING, &err_msg,
return; DBUS_TYPE_INVALID);
nm_warning ("Could not get forwarder list from named. "
"Named replied: '%s'",
err_msg);
goto out;
} }
dbus_message_iter_init (reply, &iter); dbus_message_iter_init (reply, &iter);
do do {
{ /* We depend on zones being the only strings in what
/* We depend on zones being the only strings in what named returns obviously */ * named returns (obviously)
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) */
{ if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) {
char *zone = NULL; char *zone = NULL;
dbus_message_iter_get_basic (&iter, &zone); dbus_message_iter_get_basic (&iter, &zone);
zones = g_slist_append (zones, g_strdup (zone)); zones = g_slist_append (zones, g_strdup (zone));
} }
} while (dbus_message_iter_next (&iter)); } while (dbus_message_iter_next (&iter));
dbus_message_unref (reply);
/* Remove all the zones from named */ /* Remove all the zones from named */
for (elt = zones; elt; elt = g_slist_next (elt)) for (elt = zones; elt; elt = g_slist_next (elt))
@@ -636,6 +596,11 @@ remove_all_zones_from_named (NMNamedManager *mgr)
g_slist_foreach (zones, (GFunc) g_free, NULL); g_slist_foreach (zones, (GFunc) g_free, NULL);
g_slist_free (zones); g_slist_free (zones);
out:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
dbus_message_unref (reply);
} }
gboolean gboolean
@@ -735,3 +700,66 @@ nm_named_manager_remove_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
return TRUE; return TRUE;
} }
static void
nm_named_manager_init (NMNamedManager *mgr)
{
mgr->priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
mgr->priv->use_named = FALSE;
mgr->priv->dbus_mgr = nm_dbus_manager_get (NULL);
g_signal_connect (G_OBJECT (mgr->priv->dbus_mgr),
"name-owner-changed",
G_CALLBACK (nm_named_manager_name_owner_changed),
mgr);
g_signal_connect (G_OBJECT (mgr->priv->dbus_mgr),
"dbus-connection-changed",
G_CALLBACK (nm_named_manager_dbus_connection_changed),
mgr);
}
static void
nm_named_manager_dispose (GObject *object)
{
NMNamedManager *mgr = NM_NAMED_MANAGER (object);
GSList *elt;
if (mgr->priv->disposed)
return;
mgr->priv->disposed = TRUE;
for (elt = mgr->priv->configs; elt; elt = g_slist_next (elt))
remove_ip4_config_from_named (mgr, (NMIP4Config *)(elt->data));
}
static void
nm_named_manager_finalize (GObject *object)
{
NMNamedManager *mgr = NM_NAMED_MANAGER (object);
g_return_if_fail (mgr->priv != NULL);
g_slist_foreach (mgr->priv->configs, (GFunc) nm_ip4_config_unref, NULL);
g_slist_free (mgr->priv->configs);
g_object_unref (mgr->priv->dbus_mgr);
G_OBJECT_CLASS (nm_named_manager_parent_class)->finalize (object);
}
NMNamedManager *
nm_named_manager_new (void)
{
return NM_NAMED_MANAGER (g_object_new (NM_TYPE_NAMED_MANAGER, NULL));
}
static void
nm_named_manager_class_init (NMNamedManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = nm_named_manager_dispose;
object_class->finalize = nm_named_manager_finalize;
g_type_class_add_private (object_class, sizeof (NMNamedManagerPrivate));
}

View File

@@ -50,26 +50,19 @@ G_BEGIN_DECLS
typedef struct NMNamedManagerPrivate NMNamedManagerPrivate; typedef struct NMNamedManagerPrivate NMNamedManagerPrivate;
typedef struct typedef struct {
{
GObject parent; GObject parent;
NMNamedManagerPrivate *priv; NMNamedManagerPrivate *priv;
} NMNamedManager; } NMNamedManager;
typedef struct typedef struct {
{
GObjectClass parent; GObjectClass parent;
} NMNamedManagerClass; } NMNamedManagerClass;
GType nm_named_manager_get_type (void); GType nm_named_manager_get_type (void);
NMNamedManager * nm_named_manager_new (DBusConnection *connection); NMNamedManager * nm_named_manager_new (void);
gboolean nm_named_manager_process_name_owner_changed (NMNamedManager *mgr,
const char *changed_service_name,
const char *old_owner, const char *new_owner);
gboolean nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config); gboolean nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config);

View File

@@ -27,6 +27,7 @@
#include "nm-device.h" #include "nm-device.h"
#include "NetworkManagerDbus.h" #include "NetworkManagerDbus.h"
#include "nm-dhcp-manager.h" #include "nm-dhcp-manager.h"
#include "nm-dbus-manager.h"
#include "nm-utils.h" #include "nm-utils.h"
@@ -170,7 +171,9 @@ NMActStage nm_act_request_get_stage (NMActRequest *req)
void nm_act_request_set_stage (NMActRequest *req, NMActStage stage) void nm_act_request_set_stage (NMActRequest *req, NMActStage stage)
{ {
DBusMessage * message; DBusMessage * message;
char * dev_path; char * dev_path = NULL;
NMDBusManager * dbus_mgr = NULL;
DBusConnection *dbus_connection;
g_return_if_fail (req != NULL); g_return_if_fail (req != NULL);
@@ -179,23 +182,34 @@ void nm_act_request_set_stage (NMActRequest *req, NMActStage stage)
g_return_if_fail (req->data); g_return_if_fail (req->data);
g_return_if_fail (req->dev); g_return_if_fail (req->dev);
if (!(dev_path = nm_dbus_get_object_path_for_device (req->dev))) dbus_mgr = nm_dbus_manager_get (NULL);
return; dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceActivationStage"))) nm_warning ("couldn't get the dbus connection.");
{ goto out;
nm_warning ("nm_act_request_set_stage(): Not enough memory for new dbus message!");
g_free (dev_path);
return;
} }
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_UINT32, &stage, DBUS_TYPE_INVALID); if (!(dev_path = nm_dbus_get_object_path_for_device (req->dev)))
g_free (dev_path); goto out;
if (!dbus_connection_send (req->data->dbus_connection, message, NULL)) message = dbus_message_new_signal (NM_DBUS_PATH,
nm_warning ("nm_act_request_set_stage(): Could not raise the signal!"); NM_DBUS_INTERFACE,
"DeviceActivationStage");
if (!message) {
nm_warning ("couldn't allocate the dbus message.");
goto out;
}
dbus_message_append_args (message,
DBUS_TYPE_OBJECT_PATH, &dev_path,
DBUS_TYPE_UINT32, &stage,
DBUS_TYPE_INVALID);
dbus_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message); dbus_message_unref (message);
out:
g_free (dev_path);
g_object_unref (dbus_mgr);
} }
DBusPendingCall * nm_act_request_get_user_key_pending_call (NMActRequest *req) DBusPendingCall * nm_act_request_get_user_key_pending_call (NMActRequest *req)

View File

@@ -36,206 +36,275 @@
#include "nm-dbus-device.h" #include "nm-dbus-device.h"
#include "nm-device-802-3-ethernet.h" #include "nm-device-802-3-ethernet.h"
#include "nm-device-802-11-wireless.h" #include "nm-device-802-11-wireless.h"
#include "nm-device-private.h"
#include "nm-dbus-net.h"
static DBusMessage *nm_dbus_device_get_name (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
new_invalid_device_type_error (DBusMessage *replyto)
{ {
return nm_dbus_create_error_message (replyto,
NM_DBUS_INTERFACE,
"InvalidDeviceType",
"Invalid device type for this"
"request.");
}
static DBusMessage *
nm_dbus_device_get_name (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
dev = data->dev;
if ((reply = dbus_message_new_method_return (message))) {
const char *iface; const char *iface;
iface = nm_device_get_iface (dev);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
iface = nm_device_get_iface (data->dev);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &iface, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_STRING, &iface, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_type (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_type (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
dev = data->dev;
if ((reply = dbus_message_new_method_return (message)))
{
dbus_int32_t type; dbus_int32_t type;
type = nm_device_get_device_type (dev);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
type = nm_device_get_device_type (data->dev);
dbus_message_append_args (reply, DBUS_TYPE_INT32, &type, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_INT32, &type, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_hal_udi (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_hal_udi (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
dev = data->dev;
if ((reply = dbus_message_new_method_return (message))) {
const char *udi; const char *udi;
udi = nm_device_get_udi (dev);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
} }
udi = nm_device_get_udi (data->dev);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &udi, DBUS_TYPE_INVALID);
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_ip4_address (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_ip4_address (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
dev = data->dev;
if ((reply = dbus_message_new_method_return (message))) {
dbus_uint32_t address; dbus_uint32_t address;
address = nm_device_get_ip4_address (dev); g_return_val_if_fail (connection != NULL, NULL);
dbus_message_append_args (reply, DBUS_TYPE_UINT32, &address, DBUS_TYPE_INVALID); g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
} }
address = nm_device_get_ip4_address (data->dev);
dbus_message_append_args (reply, DBUS_TYPE_UINT32, &address, DBUS_TYPE_INVALID);
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_hw_address (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_hw_address (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
dev = data->dev;
if ((reply = dbus_message_new_method_return (message)))
{
struct ether_addr addr; struct ether_addr addr;
char char_addr[20]; char char_addr[20];
char * ptr = &char_addr[0]; char * ptr = &char_addr[0];
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
memset (&addr, 0, sizeof (struct ether_addr)); memset (&addr, 0, sizeof (struct ether_addr));
if (nm_device_is_802_3_ethernet (dev)) if (nm_device_is_802_3_ethernet (data->dev)) {
nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &addr); nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (data->dev), &addr);
else if (nm_device_is_802_11_wireless (dev)) } else if (nm_device_is_802_11_wireless (data->dev)) {
nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &addr); nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (data->dev), &addr);
}
memset (char_addr, 0, 20); memset (char_addr, 0, 20);
iw_ether_ntop (&addr, char_addr); iw_ether_ntop (&addr, char_addr);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_mode (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_mode (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev; dbus_int32_t mode;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
dev = data->dev; if (!nm_device_is_802_11_wireless (data->dev)) {
if (!nm_device_is_802_11_wireless (dev)) reply = new_invalid_device_type_error (message);
{ goto out;
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotWireless",
"Wired devices cannot see wireless networks.");
} }
else if ((reply = dbus_message_new_method_return (message)))
{ if (!(reply = dbus_message_new_method_return (message))) {
dbus_int32_t mode = (dbus_int32_t) nm_device_802_11_wireless_get_mode (NM_DEVICE_802_11_WIRELESS (dev)); nm_warning ("Not enough memory to create dbus message.");
goto out;
}
mode = (dbus_int32_t) nm_device_802_11_wireless_get_mode (NM_DEVICE_802_11_WIRELESS (data->dev));
dbus_message_append_args (reply, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID);
}
out:
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_link_active (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_link_active (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
dev = data->dev;
if ((reply = dbus_message_new_method_return (message)))
{
dbus_bool_t is_active; dbus_bool_t is_active;
is_active = nm_device_has_active_link (dev); g_return_val_if_fail (connection != NULL, NULL);
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_active, DBUS_TYPE_INVALID); g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
} }
is_active = nm_device_has_active_link (data->dev);
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_active, DBUS_TYPE_INVALID);
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_active_network (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_active_network (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
gboolean success = FALSE;
NMDevice * dev; NMDevice * dev;
gboolean success = FALSE;
NMActRequest * req;
NMAccessPoint * ap;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
/* Only wireless devices have an active network */ /* Only wireless devices have an active network */
dev = data->dev; dev = data->dev;
if (!nm_device_is_802_11_wireless (dev)) if (!nm_device_is_802_11_wireless (dev))
{ {
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotWireless", reply = new_invalid_device_type_error (message);
"Wired devices cannot have active networks."); goto out;
} }
else if ((reply = dbus_message_new_method_return (message)))
{
NMActRequest * req = nm_device_get_act_request (dev);
NMAccessPoint * ap;
if (req && (ap = nm_act_request_get_ap (req))) if (!(reply = dbus_message_new_method_return (message))) {
{ nm_warning ("Not enough memory to create dbus message.");
goto out;
}
req = nm_device_get_act_request (dev);
if (req && (ap = nm_act_request_get_ap (req))) {
NMAccessPoint *tmp_ap; NMAccessPoint *tmp_ap;
char * object_path = NULL; char * object_path = NULL;
tmp_ap = nm_device_802_11_wireless_ap_list_get_ap_by_essid (NM_DEVICE_802_11_WIRELESS (dev), nm_ap_get_essid (ap)); tmp_ap = nm_device_802_11_wireless_ap_list_get_ap_by_essid (NM_DEVICE_802_11_WIRELESS (dev), nm_ap_get_essid (ap));
if (tmp_ap && (object_path = nm_dbus_get_object_path_for_network (dev, tmp_ap))) if (tmp_ap && (object_path = nm_dbus_get_object_path_for_network (dev, tmp_ap))) {
{
dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &object_path, DBUS_TYPE_INVALID);
g_free (object_path); g_free (object_path);
success = TRUE; success = TRUE;
} }
} }
if (!success)
{ if (!success) {
dbus_message_unref (reply); dbus_message_unref (reply);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoActiveNetwork", reply = nm_dbus_create_error_message (message,
"The device is not associated with any networks at this time."); NM_DBUS_INTERFACE,
} "NoActiveNetwork",
"The device is not associated "
" with any networks at this time.");
} }
out:
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_networks (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_networks (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
NMDevice * dev; NMDevice * dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
/* Only wireless devices have networks */
dev = data->dev;
if (!nm_device_is_802_11_wireless (dev))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotWireless",
"Wired devices cannot see wireless networks.");
}
else if ((reply = dbus_message_new_method_return (message)))
{
DBusMessageIter iter; DBusMessageIter iter;
DBusMessageIter iter_array; DBusMessageIter iter_array;
NMAccessPoint * ap = NULL; NMAccessPoint * ap = NULL;
@@ -244,17 +313,29 @@ static DBusMessage *nm_dbus_device_get_networks (DBusConnection *connection, DBu
NMAPListIter * list_iter; NMAPListIter * list_iter;
char * escaped_object_path; char * escaped_object_path;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
if (!nm_device_is_802_11_wireless (data->dev)) {
reply = new_invalid_device_type_error (message);
goto out;
}
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
goto out;
}
dbus_message_iter_init_append (reply, &iter); dbus_message_iter_init_append (reply, &iter);
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter_array); dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter_array);
if ((ap_list = nm_device_802_11_wireless_ap_list_get (NM_DEVICE_802_11_WIRELESS (dev)))) dev = data->dev;
{ if ((ap_list = nm_device_802_11_wireless_ap_list_get (NM_DEVICE_802_11_WIRELESS (dev)))) {
if ((list_iter = nm_ap_list_iter_new (ap_list))) if ((list_iter = nm_ap_list_iter_new (ap_list))) {
{ while ((ap = nm_ap_list_iter_next (list_iter))) {
while ((ap = nm_ap_list_iter_next (list_iter))) if (nm_ap_get_essid (ap)) {
{
if (nm_ap_get_essid (ap))
{
escaped_object_path = nm_dbus_get_object_path_for_network (dev, ap); escaped_object_path = nm_dbus_get_object_path_for_network (dev, ap);
dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &escaped_object_path); dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &escaped_object_path);
g_free (escaped_object_path); g_free (escaped_object_path);
@@ -264,100 +345,127 @@ static DBusMessage *nm_dbus_device_get_networks (DBusConnection *connection, DBu
nm_ap_list_iter_free (list_iter); nm_ap_list_iter_free (list_iter);
} }
} }
dbus_message_iter_close_container (&iter, &iter_array); dbus_message_iter_close_container (&iter, &iter_array);
if (!success) if (!success) {
{
dbus_message_unref (reply); dbus_message_unref (reply);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoNetworks", reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoNetworks",
"The device cannot see any wireless networks."); "The device cannot see any wireless networks.");
} }
}
out:
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_capabilities (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_capabilities (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev; dbus_uint32_t capabilities;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
dev = data->dev; if (!(reply = dbus_message_new_method_return (message))) {
if ((reply = dbus_message_new_method_return (message))) nm_warning ("Not enough memory to create dbus message.");
{ return NULL;
dbus_uint32_t capabilities = nm_device_get_capabilities (dev); }
capabilities = nm_device_get_capabilities (data->dev);
dbus_message_append_args (reply, DBUS_TYPE_UINT32, &capabilities, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_UINT32, &capabilities, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_driver (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_driver (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev; const char * driver;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
dev = data->dev; if (!(reply = dbus_message_new_method_return (message))) {
if ((reply = dbus_message_new_method_return (message))) nm_warning ("Not enough memory to create dbus message.");
{ return NULL;
const char * driver = nm_device_get_driver (dev); }
driver = nm_device_get_driver (data->dev);
if (!driver) if (!driver)
driver = ""; driver = "";
dbus_message_append_args (reply, DBUS_TYPE_STRING, &driver, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_STRING, &driver, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_set_link_active (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_set_link_active (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData *data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
/* Can only set link status for active devices */
dev = data->dev;
if (!nm_device_is_test_device (dev))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NotTestDevice",
"Only test devices can have their link status set manually.");
}
else if ((reply = dbus_message_new_method_return (message)))
{
DBusError error;
gboolean have_link; gboolean have_link;
dbus_error_init (&error); g_return_val_if_fail (connection != NULL, NULL);
if (dbus_message_get_args (message, &error, DBUS_TYPE_BOOLEAN, &have_link, DBUS_TYPE_INVALID)) g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
/* Can only set link status for test devices */
if (!nm_device_is_test_device (data->dev))
{ {
nm_device_set_active_link (dev, have_link); reply = nm_dbus_create_error_message (message,
nm_policy_schedule_device_change_check (data->data); NM_DBUS_INTERFACE,
} "NotTestDevice",
"Only test devices can have their"
" link status set manually.");
goto out;
} }
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
goto out;
}
if (!dbus_message_get_args (message, NULL,
DBUS_TYPE_BOOLEAN, &have_link,
DBUS_TYPE_INVALID)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
nm_device_set_active_link (data->dev, have_link);
nm_policy_schedule_device_change_check (data->data);
out:
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_device_get_properties (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
NMDevice * dev; NMDevice * dev;
char * op;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); const char * iface;
dbus_uint32_t type;
dev = data->dev; const char * udi;
if ((reply = dbus_message_new_method_return (message)))
{
char * op = nm_dbus_get_object_path_for_device (dev);
const char * iface = nm_device_get_iface (dev);
dbus_uint32_t type = nm_device_get_device_type (dev);
const char * udi = nm_device_get_udi (dev);
gchar * ip4_address; gchar * ip4_address;
gchar * broadcast; gchar * broadcast;
gchar * subnetmask; gchar * subnetmask;
@@ -371,13 +479,13 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
dbus_int32_t strength = -1; dbus_int32_t strength = -1;
dbus_int32_t speed = 0; dbus_int32_t speed = 0;
char * active_network_path = NULL; char * active_network_path = NULL;
dbus_bool_t link_active = (dbus_bool_t) nm_device_has_active_link (dev); dbus_bool_t link_active;
dbus_uint32_t capabilities = (dbus_uint32_t) nm_device_get_capabilities (dev); dbus_uint32_t capabilities;
dbus_uint32_t type_capabilities = (dbus_uint32_t) nm_device_get_type_capabilities (dev); dbus_uint32_t type_capabilities;
char ** networks = NULL; char ** networks = NULL;
int num_networks = 0; int num_networks = 0;
dbus_bool_t active = nm_device_get_act_request (dev) ? TRUE : FALSE; dbus_bool_t active;
NMActStage act_stage = active ? nm_act_request_get_stage (nm_device_get_act_request (dev)) : NM_ACT_STAGE_UNKNOWN; NMActStage act_stage;
NMIP4Config * ip4config; NMIP4Config * ip4config;
guint32 broadcast_addr = 0; guint32 broadcast_addr = 0;
guint32 subnetmask_addr = 0; guint32 subnetmask_addr = 0;
@@ -385,6 +493,28 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
guint32 primary_dns_addr = 0; guint32 primary_dns_addr = 0;
guint32 secondary_dns_addr = 0; guint32 secondary_dns_addr = 0;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
goto out;
}
dev = data->dev;
op = nm_dbus_get_object_path_for_device (dev);
iface = nm_device_get_iface (dev);
type = nm_device_get_device_type (dev);
udi = nm_device_get_udi (dev);
link_active = (dbus_bool_t) nm_device_has_active_link (dev);
capabilities = (dbus_uint32_t) nm_device_get_capabilities (dev);
type_capabilities = (dbus_uint32_t) nm_device_get_type_capabilities (dev);
active = nm_device_get_act_request (dev) ? TRUE : FALSE;
act_stage = active ? nm_act_request_get_stage (nm_device_get_act_request (dev)) : NM_ACT_STAGE_UNKNOWN;
memset (hw_addr_buf, 0, 20); memset (hw_addr_buf, 0, 20);
if (nm_device_is_802_3_ethernet (dev)) if (nm_device_is_802_3_ethernet (dev))
nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr); nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr);
@@ -393,8 +523,7 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
iw_ether_ntop (&hw_addr, hw_addr_buf); iw_ether_ntop (&hw_addr, hw_addr_buf);
ip4config = nm_device_get_ip4_config (dev); ip4config = nm_device_get_ip4_config (dev);
if (ip4config) if (ip4config) {
{
guint32 nr_nameservers; guint32 nr_nameservers;
broadcast_addr = nm_ip4_config_get_broadcast (ip4config); broadcast_addr = nm_ip4_config_get_broadcast (ip4config);
@@ -414,8 +543,7 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
primary_dns = nm_utils_inet_ip4_address_as_string (primary_dns_addr); primary_dns = nm_utils_inet_ip4_address_as_string (primary_dns_addr);
secondary_dns = nm_utils_inet_ip4_address_as_string (secondary_dns_addr); secondary_dns = nm_utils_inet_ip4_address_as_string (secondary_dns_addr);
if (nm_device_is_802_11_wireless (dev)) if (nm_device_is_802_11_wireless (dev)) {
{
NMDevice80211Wireless * wdev = NM_DEVICE_802_11_WIRELESS (dev); NMDevice80211Wireless * wdev = NM_DEVICE_802_11_WIRELESS (dev);
NMActRequest * req = nm_device_get_act_request (dev); NMActRequest * req = nm_device_get_act_request (dev);
NMAccessPoint * ap; NMAccessPoint * ap;
@@ -426,8 +554,7 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
mode = nm_device_802_11_wireless_get_mode (wdev); mode = nm_device_802_11_wireless_get_mode (wdev);
speed = nm_device_802_11_wireless_get_bitrate (wdev); speed = nm_device_802_11_wireless_get_bitrate (wdev);
if (req && (ap = nm_act_request_get_ap (req))) if (req && (ap = nm_act_request_get_ap (req))) {
{
NMAccessPoint *tmp_ap; NMAccessPoint *tmp_ap;
if ((tmp_ap = nm_device_802_11_wireless_ap_list_get_ap_by_essid (wdev, nm_ap_get_essid (ap)))) if ((tmp_ap = nm_device_802_11_wireless_ap_list_get_ap_by_essid (wdev, nm_ap_get_essid (ap))))
@@ -435,15 +562,12 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
} }
ap_list = nm_device_802_11_wireless_ap_list_get (wdev); ap_list = nm_device_802_11_wireless_ap_list_get (wdev);
if (ap_list && (num_networks = nm_ap_list_size (ap_list))) if (ap_list && (num_networks = nm_ap_list_size (ap_list))) {
{ if ((iter = nm_ap_list_iter_new (ap_list))) {
if ((iter = nm_ap_list_iter_new (ap_list)))
{
int i = 0; int i = 0;
networks = g_malloc0 (sizeof (char *) * (num_networks + 1)); networks = g_malloc0 (sizeof (char *) * (num_networks + 1));
while ((ap = nm_ap_list_iter_next (iter))) while ((ap = nm_ap_list_iter_next (iter))) {
{
char *ap_op = nm_dbus_get_object_path_for_network (dev, ap); char *ap_op = nm_dbus_get_object_path_for_network (dev, ap);
if (ap_op) if (ap_op)
networks[i++] = ap_op; networks[i++] = ap_op;
@@ -453,14 +577,15 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
nm_ap_list_iter_free (iter); nm_ap_list_iter_free (iter);
} }
} }
} } else {
else
speed = nm_device_802_3_ethernet_get_speed (NM_DEVICE_802_3_ETHERNET (dev)); speed = nm_device_802_3_ethernet_get_speed (NM_DEVICE_802_3_ETHERNET (dev));
}
if (!active_network_path) if (!active_network_path)
active_network_path = g_strdup (""); active_network_path = g_strdup ("");
dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &op, dbus_message_append_args (reply,
DBUS_TYPE_OBJECT_PATH, &op,
DBUS_TYPE_STRING, &iface, DBUS_TYPE_STRING, &iface,
DBUS_TYPE_UINT32, &type, DBUS_TYPE_UINT32, &type,
DBUS_TYPE_STRING, &udi, DBUS_TYPE_STRING, &udi,
@@ -489,21 +614,99 @@ static DBusMessage *nm_dbus_device_get_properties (DBusConnection *connection, D
g_free (ip4_address); g_free (ip4_address);
g_free (broadcast); g_free (broadcast);
g_free (subnetmask); g_free (subnetmask);
}
out:
return reply; return reply;
} }
/*
* nm_dbus_devices_message_handler
*
* Dispatch messages against individual network devices
*
*/
static DBusHandlerResult
nm_dbus_device_message_handler (DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
NMData * data = (NMData *)user_data;
gboolean handled = FALSE;
const char * path;
DBusMessage * reply = NULL;
NMDevice * dev;
char * object_path;
char * escaped_object_path;
NMDbusCBData * cb_data;
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (data != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
path = dbus_message_get_path (message);
if (!(dev = nm_dbus_get_device_from_escaped_object_path (data, path))) {
reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"DeviceNotFound",
"The requested device does not "
" exist.");
goto out;
}
/* Test whether or not the _networks_ of a device were queried instead of the device itself */
object_path = g_strdup_printf ("%s/%s/Networks/",
NM_DBUS_PATH_DEVICES,
nm_device_get_iface (dev));
escaped_object_path = nm_dbus_escape_object_path (object_path);
g_free (object_path);
cb_data = g_slice_new0 (NMDbusCBData);
cb_data->data = data;
cb_data->dev = dev;
if (strncmp (path, escaped_object_path, strlen (escaped_object_path)) == 0) {
handled = nm_dbus_net_methods_dispatch (data->net_methods,
connection,
message,
cb_data,
&reply);
} else {
handled = nm_dbus_method_list_dispatch (data->device_methods,
connection,
message,
cb_data,
&reply);
}
g_object_unref (G_OBJECT (cb_data->dev));
g_slice_free (NMDbusCBData, cb_data);
g_free (escaped_object_path);
out:
if (reply)
{
dbus_connection_send (connection, reply, NULL);
dbus_message_unref (reply);
handled = TRUE;
}
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
/* /*
* nm_dbus_device_methods_setup * nm_dbus_device_methods_setup
* *
* Register handlers for dbus methods on the org.freedesktop.NetworkManager.Devices object. * Register handlers for dbus methods on the org.freedesktop.NetworkManager.Devices object.
* *
*/ */
NMDbusMethodList *nm_dbus_device_methods_setup (void) NMDbusMethodList *nm_dbus_device_methods_setup (NMData *data)
{ {
NMDbusMethodList *list = nm_dbus_method_list_new (NULL); NMDbusMethodList * list;
g_return_val_if_fail (data != NULL, NULL);
list = nm_dbus_method_list_new (NM_DBUS_PATH_DEVICES, TRUE, data, NULL);
nm_dbus_method_list_set_custom_handler_func (list, nm_dbus_device_message_handler);
nm_dbus_method_list_add_method (list, "getProperties", nm_dbus_device_get_properties); nm_dbus_method_list_add_method (list, "getProperties", nm_dbus_device_get_properties);
nm_dbus_method_list_add_method (list, "getName", nm_dbus_device_get_name); nm_dbus_method_list_add_method (list, "getName", nm_dbus_device_get_name);

View File

@@ -23,7 +23,7 @@
#define NM_DBUS_DEVICE_H #define NM_DBUS_DEVICE_H
NMDbusMethodList *nm_dbus_device_methods_setup (void); NMDbusMethodList *nm_dbus_device_methods_setup (NMData *data);
#endif #endif

822
src/nm-dbus-manager.c Normal file
View File

@@ -0,0 +1,822 @@
/*
* Copyright (C) 2006 Red Hat, Inc.
*
* Written by Dan Williams <dcbw@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include "NetworkManager.h"
#include "nm-dbus-manager.h"
#include "nm-marshal.h"
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <string.h>
#include "nm-utils.h"
static gboolean nm_dbus_manager_init_bus (NMDBusManager *self);
static void nm_dbus_manager_cleanup (NMDBusManager *self);
static void free_signal_handler_data (gpointer data);
static void start_reconnection_timeout (NMDBusManager *self);
enum {
PROP_0,
PROP_MAIN_CONTEXT,
PROP_DBUS_CONNECTION
};
enum {
DBUS_CONNECTION_CHANGED = 0,
NAME_OWNER_CHANGED,
NUMBER_OF_SIGNALS
};
static guint nm_dbus_manager_signals[NUMBER_OF_SIGNALS];
G_DEFINE_TYPE(NMDBusManager, nm_dbus_manager, G_TYPE_OBJECT)
#define NM_DBUS_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_DBUS_MANAGER, \
NMDBusManagerPrivate))
typedef struct SignalHandlerData {
NMDBusSignalHandlerFunc func;
char * sender;
gpointer user_data;
gboolean enabled;
} SignalHandlerData;
typedef struct MethodHandlerData {
NMDbusMethodList * list;
NMDBusManager * self;
} MethodHandlerData;
struct _NMDBusManagerPrivate {
DBusConnection *connection;
GMainContext * main_ctx;
GSList * msg_handlers;
GHashTable * signal_handlers;
gboolean started;
gboolean disposed;
};
NMDBusManager *
nm_dbus_manager_get (GMainContext *ctx)
{
static NMDBusManager *singleton = NULL;
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
/* Ensure that if singleton is NULL, that ctx is non-NULL */
g_return_val_if_fail (singleton ? TRUE : (ctx ? TRUE : FALSE), NULL);
g_static_mutex_lock (&mutex);
if (!singleton) {
singleton = NM_DBUS_MANAGER (g_object_new (NM_TYPE_DBUS_MANAGER,
"main-context", ctx,
NULL));
if (!nm_dbus_manager_init_bus (singleton))
start_reconnection_timeout (singleton);
} else {
g_object_ref (singleton);
}
g_static_mutex_unlock (&mutex);
g_assert (singleton);
return singleton;
}
static void
nm_dbus_manager_init (NMDBusManager *self)
{
self->priv = NM_DBUS_MANAGER_GET_PRIVATE (self);
self->priv->signal_handlers = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
free_signal_handler_data);
}
static void
nm_dbus_manager_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
NMDBusManager *self = NM_DBUS_MANAGER (object);
switch (prop_id) {
case PROP_MAIN_CONTEXT:
if (!self->priv->main_ctx) {
self->priv->main_ctx = g_value_get_pointer (value);
g_main_context_ref (self->priv->main_ctx);
} else {
nm_warning ("already have a valid main context.");
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_dbus_manager_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
NMDBusManager *self = NM_DBUS_MANAGER (object);
switch (prop_id) {
case PROP_DBUS_CONNECTION:
g_value_set_pointer (value, self->priv->connection);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_dbus_manager_dispose (GObject *object)
{
NMDBusManager *self = NM_DBUS_MANAGER (object);
if (self->priv->disposed)
return;
self->priv->disposed = TRUE;
}
static void
cleanup_handler_data (gpointer item, gpointer user_data)
{
MethodHandlerData * data = (MethodHandlerData *) item;
nm_dbus_method_list_unref (data->list);
g_slice_free (MethodHandlerData, item);
}
static void
nm_dbus_manager_finalize (GObject *object)
{
NMDBusManager * self = NM_DBUS_MANAGER (object);
g_return_if_fail (self->priv != NULL);
nm_dbus_manager_cleanup (self);
g_main_context_unref (self->priv->main_ctx);
g_slist_foreach (self->priv->msg_handlers, cleanup_handler_data, NULL);
g_slist_free (self->priv->msg_handlers);
g_hash_table_destroy (self->priv->signal_handlers);
G_OBJECT_CLASS (nm_dbus_manager_parent_class)->finalize (object);
}
static void
nm_dbus_manager_class_init (NMDBusManagerClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = nm_dbus_manager_dispose;
object_class->finalize = nm_dbus_manager_finalize;
object_class->get_property = nm_dbus_manager_get_property;
object_class->set_property = nm_dbus_manager_set_property;
g_object_class_install_property (object_class,
PROP_MAIN_CONTEXT,
g_param_spec_pointer ("main-context",
"GMainContext",
"The mainloop context.",
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)
);
g_object_class_install_property (object_class,
PROP_DBUS_CONNECTION,
g_param_spec_pointer ("dbus-connection",
"DBusConnection",
"The application's dbus connection.",
G_PARAM_READABLE)
);
nm_dbus_manager_signals[DBUS_CONNECTION_CHANGED] =
g_signal_new ("dbus-connection-changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMDBusManagerClass, dbus_connection_changed),
NULL, NULL, nm_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
klass->dbus_connection_changed = NULL;
nm_dbus_manager_signals[NAME_OWNER_CHANGED] =
g_signal_new ("name-owner-changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMDBusManagerClass, name_owner_changed),
NULL, NULL, nm_marshal_VOID__POINTER_STRING_STRING_STRING,
G_TYPE_NONE, 4, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
klass->name_owner_changed = NULL;
g_type_class_add_private (klass, sizeof (NMDBusManagerPrivate));
}
/* Only cleanup a specific dbus connection, not all our private data */
static void
nm_dbus_manager_cleanup (NMDBusManager *self)
{
if (self->priv->connection) {
dbus_connection_close (self->priv->connection);
self->priv->connection = NULL;
}
self->priv->started = FALSE;
}
static gboolean
nm_dbus_manager_reconnect (gpointer user_data)
{
NMDBusManager *self = NM_DBUS_MANAGER (user_data);
gboolean success = FALSE;
g_assert (self != NULL);
if (nm_dbus_manager_init_bus (self)) {
if (nm_dbus_manager_start_service (self)) {
nm_info ("reconnected to the system bus.");
g_signal_emit (G_OBJECT (self),
nm_dbus_manager_signals[DBUS_CONNECTION_CHANGED],
0, self->priv->connection);
success = TRUE;
}
}
if (!success) {
nm_dbus_manager_cleanup (self);
}
/* Remove the source only if reconnection was successful */
return success ? FALSE : TRUE;
}
static char *
get_match_for (const char *interface, const char *sender)
{
return g_strdup_printf ("type='signal',interface='%s',sender='%s'",
interface, sender);
}
static gboolean
add_match_helper (NMDBusManager *self,
const char *interface,
const char *sender)
{
gboolean success = FALSE;
DBusError error;
char * match;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (interface != NULL, FALSE);
g_return_val_if_fail (sender != NULL, FALSE);
match = get_match_for (interface, sender);
dbus_error_init (&error);
dbus_bus_add_match (self->priv->connection, match, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("failed to add signal match for '%s'.", interface);
dbus_error_free (&error);
} else {
success = TRUE;
}
g_free (match);
return success;
}
static void
start_reconnection_timeout (NMDBusManager *self)
{
GSource * source;
/* Schedule timeout for reconnection attempts */
source = g_timeout_source_new (3000);
g_source_set_callback (source,
(GSourceFunc) nm_dbus_manager_reconnect,
self,
NULL);
g_source_attach (source, self->priv->main_ctx);
g_source_unref (source);
}
static DBusHandlerResult
nm_dbus_manager_signal_handler (DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
NMDBusManager * self = NM_DBUS_MANAGER (user_data);
gboolean handled = FALSE;
g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (self != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (0) {
const char * interface = dbus_message_get_interface (message);
const char * path = dbus_message_get_path (message);
const char * member = dbus_message_get_member (message);
const char * sig = dbus_message_get_signature (message);
nm_info ("(signal) iface: %s, path: %s, member: %s, sig: %s",
interface, path, member, sig);
}
if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
gboolean success;
const char * name;
const char * old_owner;
const char * new_owner;
success = dbus_message_get_args (message, NULL,
DBUS_TYPE_STRING, &name,
DBUS_TYPE_STRING, &old_owner,
DBUS_TYPE_STRING, &new_owner,
DBUS_TYPE_INVALID);
if (success) {
SignalHandlerData * sig_data;
gboolean old_owner_good = (old_owner && strlen (old_owner));
gboolean new_owner_good = (new_owner && strlen (new_owner));
sig_data = g_hash_table_lookup (self->priv->signal_handlers,
name);
if (!old_owner_good && new_owner_good) {
/* Add any matches registered with us */
if (sig_data) {
sig_data->enabled = add_match_helper (self,
name,
sig_data->sender);
}
} else if (old_owner_good && !new_owner_good) {
/* Mark any matches for services that have gone away as disabled. */
if (sig_data)
sig_data->enabled = FALSE;
}
g_signal_emit (G_OBJECT (self),
nm_dbus_manager_signals[NAME_OWNER_CHANGED],
0, connection, name, old_owner, new_owner);
handled = TRUE;
}
} else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
/* Clean up existing connection */
nm_info ("disconnected by the system bus.");
nm_dbus_manager_cleanup (self);
g_signal_emit (G_OBJECT (self),
nm_dbus_manager_signals[DBUS_CONNECTION_CHANGED],
0, NULL);
start_reconnection_timeout (self);
handled = TRUE;
} else {
SignalHandlerData * cb_data;
const char * interface;
interface = dbus_message_get_interface (message);
if (interface) {
if ((cb_data = g_hash_table_lookup (self->priv->signal_handlers,
interface))) {
handled = (*cb_data->func) (connection,
message,
cb_data->user_data);
}
}
}
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
char *
nm_dbus_manager_get_name_owner (NMDBusManager *self,
const char *name)
{
DBusError error;
DBusMessage * message;
DBusMessage * reply = NULL;
char * owner = NULL;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
message = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS,
DBUS_INTERFACE_DBUS,
"GetNameOwner");
if (!message) {
nm_warning ("Not enough memory for DBus message.");
goto out;
}
dbus_message_append_args (message, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID);
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (self->priv->connection,
message, 2000, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("Did not get reply from DBus. Message: %s", error.message);
dbus_error_free (&error);
goto out;
}
if (reply) {
const char *tmp_name = NULL;
if (dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING,
&tmp_name, DBUS_TYPE_INVALID))
owner = g_strdup (tmp_name);
}
out:
if (reply)
dbus_message_unref (reply);
if (message)
dbus_message_unref (message);
return owner;
}
gboolean
nm_dbus_manager_name_has_owner (NMDBusManager *self,
const char *name)
{
DBusError error;
gboolean running = FALSE;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (name != NULL, FALSE);
if (!self->priv->connection) {
nm_warning ("Called when manager had no dbus connection.");
return FALSE;
}
dbus_error_init (&error);
running = dbus_bus_name_has_owner (self->priv->connection, name, &error);
if (dbus_error_is_set (&error)) {
running = FALSE;
dbus_error_free (&error);
}
return running;
}
static DBusHandlerResult
nm_dbus_manager_message_handler (DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
MethodHandlerData * data = (MethodHandlerData *) user_data;
NMDBusManager * self = data->self;
NMDbusMethodList * list = data->list;
DBusObjectPathMessageFunction custom_handler_func;
gboolean handled = FALSE;
DBusMessage * reply = NULL;
void * hdlr_user_data;
g_return_val_if_fail (self != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (list != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
hdlr_user_data = nm_dbus_method_list_get_user_data (list);
/* Try the method lists' custom handler first */
custom_handler_func = nm_dbus_method_list_get_custom_handler_func (list);
if (custom_handler_func) {
handled = (*custom_handler_func) (connection, message, hdlr_user_data);
} else {
/* Generic handler for lists that don't specify a custom handler */
handled = nm_dbus_method_list_dispatch (list, connection, message,
hdlr_user_data, &reply);
if (reply) {
dbus_connection_send (connection, reply, NULL);
dbus_message_unref (reply);
}
}
return handled ? DBUS_HANDLER_RESULT_HANDLED
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static gboolean
nm_dbus_manager_init_bus (NMDBusManager *self)
{
DBusError error;
gboolean success = FALSE;
g_return_val_if_fail (self->priv->main_ctx, FALSE);
if (self->priv->connection) {
nm_warning ("DBus Manager already has a valid connection.");
return FALSE;
}
dbus_connection_set_change_sigpipe (TRUE);
dbus_error_init (&error);
self->priv->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("Could not get the system bus. Make sure "
"the message bus daemon is running! Message: %s",
error.message);
dbus_error_free (&error);
goto out;
}
dbus_connection_set_exit_on_disconnect (self->priv->connection, FALSE);
dbus_connection_setup_with_g_main (self->priv->connection,
self->priv->main_ctx);
if (!dbus_connection_add_filter (self->priv->connection,
nm_dbus_manager_signal_handler,
self,
NULL)) {
nm_warning ("Could not register a dbus message filter. The "
"NetworkManager dbus security policy may not be loaded. "
"Restart dbus?");
goto out;
}
success = TRUE;
/* Monitor DBus signals for service start/stop announcements */
dbus_error_init (&error);
dbus_bus_add_match (self->priv->connection,
"type='signal',"
"interface='" DBUS_INTERFACE_DBUS "',"
"sender='" DBUS_SERVICE_DBUS "'",
&error);
if (dbus_error_is_set (&error)) {
nm_warning ("Could not monitor DBus signals. Message: %s",
error.message);
dbus_error_free (&error);
goto out;
}
success = TRUE;
out:
if (!success)
nm_dbus_manager_cleanup (self);
return success;
}
static gboolean
nm_dbus_manager_register_method_handlers (NMDBusManager *self)
{
gboolean success = FALSE;
GSList * elt;
g_return_val_if_fail (self != NULL, FALSE);
for (elt = self->priv->msg_handlers; elt; elt = g_slist_next (elt)) {
MethodHandlerData * data = (MethodHandlerData *) elt->data;
DBusObjectPathVTable vtable = {NULL, &nm_dbus_manager_message_handler,
NULL, NULL, NULL, NULL};
dbus_bool_t ret = FALSE;
const char * path;
if (!nm_dbus_method_list_get_path (data->list)) {
nm_warning ("DBus message handler had no path.");
continue;
}
/* If the method list object specifies a custom handler, use that
* instead of our default built-in one.
*/
path = nm_dbus_method_list_get_path (data->list);
if (nm_dbus_method_list_get_is_fallback (data->list)) {
ret = dbus_connection_register_fallback (self->priv->connection,
path, &vtable, data);
} else {
ret = dbus_connection_register_object_path (self->priv->connection,
path, &vtable, data);
}
if (ret == FALSE) {
nm_warning ("Could not register DBus message handler for path %s.",
path);
goto out;
}
}
success = TRUE;
out:
return success;
}
static void
register_signal_handler (gpointer key,
gpointer value,
gpointer user_data)
{
NMDBusManager *self = NM_DBUS_MANAGER (user_data);
SignalHandlerData * cb_data = (SignalHandlerData *) value;
if (nm_dbus_manager_name_has_owner (self, key))
add_match_helper (self, key, cb_data->sender);
}
static gboolean
nm_dbus_manager_register_signal_handlers (NMDBusManager *self)
{
g_return_val_if_fail (self != NULL, FALSE);
g_hash_table_foreach (self->priv->signal_handlers,
register_signal_handler,
self);
return TRUE;
}
/* Register our service on the bus; shouldn't be called until
* all necessary message handlers have been registered, because
* when we register on the bus, clients may start to call.
*/
gboolean
nm_dbus_manager_start_service (NMDBusManager *self)
{
DBusError error;
gboolean success = FALSE;
int flags, ret;
g_return_val_if_fail (self != NULL, FALSE);
if (self->priv->started) {
nm_warning ("Service has already started.");
return FALSE;
}
/* Register our method handlers */
if (!nm_dbus_manager_register_method_handlers (self))
goto out;
/* And our signal handlers */
if (!nm_dbus_manager_register_signal_handlers (self))
goto out;
dbus_error_init (&error);
#if (DBUS_VERSION_MAJOR == 0) && (DBUS_VERSION_MINOR >= 60)
flags = DBUS_NAME_FLAG_DO_NOT_QUEUE;
#else
flags = DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT;
#endif
ret = dbus_bus_request_name (self->priv->connection, NM_DBUS_SERVICE,
flags, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("Could not acquire the NetworkManager service.\n"
" Message: '%s'", error.message);
dbus_error_free (&error);
goto out;
}
if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
nm_warning ("Could not acquire the NetworkManager service as it is "
" already taken. Return: %d", ret);
goto out;
}
self->priv->started = TRUE;
success = TRUE;
out:
if (!success)
nm_dbus_manager_cleanup (self);
return success;
}
void
nm_dbus_manager_register_method_list (NMDBusManager *self,
NMDbusMethodList *list)
{
MethodHandlerData * data;
g_return_if_fail (self != NULL);
g_return_if_fail (list != NULL);
if (self->priv->started) {
nm_warning ("DBus Manager object already started!");
return;
}
if (self->priv->connection == NULL) {
nm_warning ("DBus Manager object not yet initialized!");
return;
}
if (g_slist_find (self->priv->msg_handlers, list)) {
nm_warning ("Handler already registered.");
return;
}
data = g_slice_new0 (MethodHandlerData);
if (!data) {
nm_warning ("Not enough memory to register the handler.");
return;
}
nm_dbus_method_list_ref (list);
data->list = list;
data->self = self;
self->priv->msg_handlers = g_slist_append (self->priv->msg_handlers, data);
}
static void
free_signal_handler_data (gpointer data)
{
SignalHandlerData * cb_data = (SignalHandlerData *) data;
g_return_if_fail (cb_data != NULL);
g_free (cb_data->sender);
g_slice_free (SignalHandlerData, cb_data);
}
void
nm_dbus_manager_register_signal_handler (NMDBusManager *self,
const char *interface,
const char *sender,
NMDBusSignalHandlerFunc callback,
gpointer user_data)
{
SignalHandlerData * cb_data;
g_return_if_fail (self != NULL);
g_return_if_fail (interface != NULL);
g_return_if_fail (callback != NULL);
if (!(cb_data = g_slice_new0 (SignalHandlerData)))
return;
cb_data->sender = sender ? g_strdup (sender) : g_strdup (interface);
cb_data->func = callback;
cb_data->user_data = user_data;
g_hash_table_insert (self->priv->signal_handlers,
g_strdup (interface),
cb_data);
if (nm_dbus_manager_name_has_owner (self, cb_data->sender))
cb_data->enabled = add_match_helper (self, interface, cb_data->sender);
}
void
nm_dbus_manager_remove_signal_handler (NMDBusManager *self,
const char *interface)
{
SignalHandlerData * cb_data;
DBusError error;
char * match;
g_return_if_fail (self != NULL);
g_return_if_fail (interface != NULL);
cb_data = g_hash_table_lookup (self->priv->signal_handlers, interface);
if (!cb_data)
return;
if (cb_data->enabled == FALSE)
goto out;
if (nm_dbus_manager_name_has_owner (self, cb_data->sender))
goto out;
match = get_match_for (interface, cb_data->sender);
dbus_error_init (&error);
dbus_bus_remove_match (self->priv->connection, match, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("failed to remove signal match for '%s'.", interface);
dbus_error_free (&error);
}
g_free (match);
out:
g_hash_table_remove (self->priv->signal_handlers, interface);
}
DBusConnection *
nm_dbus_manager_get_dbus_connection (NMDBusManager *self)
{
GValue value = {0,};
g_return_val_if_fail (self != NULL, NULL);
g_value_init (&value, G_TYPE_POINTER);
g_object_get_property (G_OBJECT (self), "dbus-connection", &value);
return g_value_get_pointer (&value);
}

96
src/nm-dbus-manager.h Normal file
View File

@@ -0,0 +1,96 @@
/*
* Copyright (C) 2006 Red Hat, Inc.
*
* Written by Dan Williams <dcbw@redhat.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __NM_DBUS_MANAGER_H__
#define __NM_DBUS_MANAGER_H__
#include "config.h"
#include "NetworkManagerDbusUtils.h"
#include <glib-object.h>
#include <dbus/dbus.h>
G_BEGIN_DECLS
typedef gboolean (* NMDBusSignalHandlerFunc) (DBusConnection * connection,
DBusMessage * message,
gpointer user_data);
#define NM_TYPE_DBUS_MANAGER (nm_dbus_manager_get_type ())
#define NM_DBUS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), NM_TYPE_DBUS_MANAGER, NMDBusManager))
#define NM_DBUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), NM_TYPE_DBUS_MANAGER, NMDBusManagerClass))
#define NM_IS_DBUS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), NM_TYPE_DBUS_MANAGER))
#define NM_IS_DBUS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), NM_TYPE_DBUS_MANAGER))
#define NM_DBUS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), NM_TYPE_DBUS_MANAGER, NMDBusManagerClass))
typedef struct _NMDBusManager NMDBusManager;
typedef struct _NMDBusManagerClass NMDBusManagerClass;
typedef struct _NMDBusManagerPrivate NMDBusManagerPrivate;
struct _NMDBusManager {
GObject parent;
/*< private >*/
NMDBusManagerPrivate *priv;
};
struct _NMDBusManagerClass {
GObjectClass parent;
/* Signals */
void (*dbus_connection_changed) (NMDBusManager *mgr,
DBusConnection *connection);
void (*name_owner_changed) (NMDBusManager *mgr,
DBusConnection *connection,
const char *name,
const char *old_owner,
const char *new_owner);
};
GType nm_dbus_manager_get_type (void);
NMDBusManager * nm_dbus_manager_get (GMainContext *ctx);
char * nm_dbus_manager_get_name_owner (NMDBusManager *self,
const char *name);
gboolean nm_dbus_manager_start_service (NMDBusManager *self);
void nm_dbus_manager_register_method_list (NMDBusManager *self,
NMDbusMethodList *list);
gboolean nm_dbus_manager_name_has_owner (NMDBusManager *self,
const char *name);
void nm_dbus_manager_register_signal_handler (NMDBusManager *self,
const char *interface,
const char *sender,
NMDBusSignalHandlerFunc callback,
gpointer user_data);
void nm_dbus_manager_remove_signal_handler (NMDBusManager *self,
const char *interface);
DBusConnection * nm_dbus_manager_get_dbus_connection (NMDBusManager *self);
G_END_DECLS
#endif /* __NM_DBUS_MANAGER_H__ */

View File

@@ -27,6 +27,8 @@
#include "NetworkManagerUtils.h" #include "NetworkManagerUtils.h"
#include "nm-dbus-net.h" #include "nm-dbus-net.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-device-private.h"
/* /*
* nm_dbus_get_ap_from_object_path * nm_dbus_get_ap_from_object_path
@@ -34,25 +36,27 @@
* Returns the network (ap) associated with a dbus object path * Returns the network (ap) associated with a dbus object path
* *
*/ */
static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevice *dev) static NMAccessPoint *
nm_dbus_get_ap_from_object_path (const char *path,
NMDevice *dev)
{ {
NMAccessPoint * ap = NULL; NMAccessPoint * ap = NULL;
NMAccessPointList * ap_list; NMAccessPointList * ap_list;
NMAPListIter * iter; NMAPListIter * iter;
char compare_path[100], *escaped_compare_path; char compare_path[100];
char * escaped_compare_path;
g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (dev != NULL, NULL); g_return_val_if_fail (dev != NULL, NULL);
ap_list = nm_device_802_11_wireless_ap_list_get (NM_DEVICE_802_11_WIRELESS (dev)); ap_list = nm_device_802_11_wireless_ap_list_get (NM_DEVICE_802_11_WIRELESS (dev));
if (!ap_list) if (!ap_list)
return (NULL); return NULL;
if (!(iter = nm_ap_list_iter_new (ap_list))) if (!(iter = nm_ap_list_iter_new (ap_list)))
return (NULL); return NULL;
while ((ap = nm_ap_list_iter_next (iter))) while ((ap = nm_ap_list_iter_next (iter))) {
{
int len; int len;
snprintf (compare_path, 100, "%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES, snprintf (compare_path, 100, "%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES,
@@ -60,92 +64,98 @@ static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevic
escaped_compare_path = nm_dbus_escape_object_path (compare_path); escaped_compare_path = nm_dbus_escape_object_path (compare_path);
len = strlen(escaped_compare_path); len = strlen(escaped_compare_path);
if (strncmp (path, escaped_compare_path, len) == 0) if (strncmp (path, escaped_compare_path, len) == 0) {
{
/* Differentiate between 'foo' and 'foo-a' */ /* Differentiate between 'foo' and 'foo-a' */
if (path[len] == '\0' || path[len] == '/') if (path[len] == '\0' || path[len] == '/') {
{
g_free (escaped_compare_path); g_free (escaped_compare_path);
break; break;
} }
} }
g_free (escaped_compare_path); g_free (escaped_compare_path);
} }
nm_ap_list_iter_free (iter); nm_ap_list_iter_free (iter);
return (ap);
return ap;
} }
static DBusMessage *nm_dbus_net_validate (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_net_get_name (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMAccessPoint *ap; const char *essid;
const char *path;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->ap != NULL, NULL);
path = dbus_message_get_path (message); if (!(reply = dbus_message_new_method_return (message))) {
if ((ap = nm_dbus_get_ap_from_object_path (path, data->dev))) nm_warning ("Not enough memory to create dbus message.");
data->ap = ap; return NULL;
else
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NetworkNotFound",
"The requested network does not exist for this device.");
} }
return reply; essid = nm_ap_get_essid (data->ap);
}
static DBusMessage *nm_dbus_net_get_name (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL);
if ((reply = dbus_message_new_method_return (message)))
{
const char *essid = nm_ap_get_essid (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_net_get_address (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_net_get_address (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL);
if ((reply = dbus_message_new_method_return (message)))
{
char buf[20]; char buf[20];
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->ap != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
memset (&buf[0], 0, 20); memset (&buf[0], 0, 20);
iw_ether_ntop((const struct ether_addr *) (nm_ap_get_address (data->ap)), &buf[0]); iw_ether_ntop((const struct ether_addr *) (nm_ap_get_address (data->ap)), &buf[0]);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &buf, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_STRING, &buf, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_net_get_strength (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_net_get_strength (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
NMAccessPoint * tmp_ap = NULL;
NMAccessPointList * ap_list;
NMAPListIter * iter;
int best_strength;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->ap != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
/* We iterate over the device list and return the best strength for all /* We iterate over the device list and return the best strength for all
* APs with the given ESSID. * APs with the given ESSID.
*/ */
if ((reply = dbus_message_new_method_return (message))) best_strength = nm_ap_get_strength (data->ap);
{
NMAccessPoint *tmp_ap = NULL;
NMAccessPointList *ap_list;
NMAPListIter *iter;
int best_strength = nm_ap_get_strength (data->ap);
if (!(ap_list = nm_device_802_11_wireless_ap_list_get (NM_DEVICE_802_11_WIRELESS (data->dev)))) if (!(ap_list = nm_device_802_11_wireless_ap_list_get (NM_DEVICE_802_11_WIRELESS (data->dev))))
goto append; goto append;
@@ -153,8 +163,7 @@ static DBusMessage *nm_dbus_net_get_strength (DBusConnection *connection, DBusMe
goto append; goto append;
/* Find best strength # among all APs that share this essid */ /* Find best strength # among all APs that share this essid */
while ((tmp_ap = nm_ap_list_iter_next (iter))) while ((tmp_ap = nm_ap_list_iter_next (iter))) {
{
if (nm_null_safe_strcmp (nm_ap_get_essid (data->ap), nm_ap_get_essid (tmp_ap)) == 0) if (nm_null_safe_strcmp (nm_ap_get_essid (data->ap), nm_ap_get_essid (tmp_ap)) == 0)
if (nm_ap_get_strength (tmp_ap) > best_strength) if (nm_ap_get_strength (tmp_ap) > best_strength)
best_strength = nm_ap_get_strength (tmp_ap); best_strength = nm_ap_get_strength (tmp_ap);
@@ -163,96 +172,155 @@ static DBusMessage *nm_dbus_net_get_strength (DBusConnection *connection, DBusMe
append: append:
dbus_message_append_args (reply, DBUS_TYPE_INT32, &best_strength, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_INT32, &best_strength, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_net_get_frequency (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_net_get_frequency (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL);
if ((reply = dbus_message_new_method_return (message))) {
double freq; double freq;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->ap != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
freq = nm_ap_get_freq (data->ap); freq = nm_ap_get_freq (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_DOUBLE, &freq, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_DOUBLE, &freq, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_net_get_rate (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_net_get_rate (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL);
if ((reply = dbus_message_new_method_return (message))) {
dbus_int32_t rate; dbus_int32_t rate;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->ap != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
rate = nm_ap_get_rate (data->ap); rate = nm_ap_get_rate (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_INT32, &rate, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_INT32, &rate, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_net_get_encrypted (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_net_get_encrypted (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL);
if ((reply = dbus_message_new_method_return (message))) {
dbus_bool_t is_encrypted; dbus_bool_t is_encrypted;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->ap != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
is_encrypted = nm_ap_get_encrypted (data->ap); is_encrypted = nm_ap_get_encrypted (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_encrypted, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_encrypted, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_net_get_mode (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_net_get_mode (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
dbus_int32_t mode;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->ap != NULL, NULL);
if ((reply = dbus_message_new_method_return (message))) if (!(reply = dbus_message_new_method_return (message))) {
{ nm_warning ("Not enough memory to create dbus message.");
dbus_int32_t mode = (dbus_int32_t) nm_ap_get_mode (data->ap); return NULL;
}
mode = (dbus_int32_t) nm_ap_get_mode (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_net_get_properties (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_net_get_properties (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
char * op;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL); const char * essid;
if ((reply = dbus_message_new_method_return (message)))
{
char * op = nm_dbus_get_object_path_for_network (data->dev, data->ap);
const char * essid = nm_ap_get_essid (data->ap);
char hw_addr_buf[20]; char hw_addr_buf[20];
char * hw_addr_buf_ptr = &hw_addr_buf[0]; char * hw_addr_buf_ptr = &hw_addr_buf[0];
dbus_int32_t strength = nm_ap_get_strength (data->ap); dbus_int32_t strength;
double freq = nm_ap_get_freq (data->ap); double freq;
dbus_int32_t rate = nm_ap_get_rate (data->ap); dbus_int32_t rate;
dbus_int32_t mode = (dbus_int32_t) nm_ap_get_mode (data->ap); dbus_int32_t mode;
dbus_int32_t capabilities = (dbus_int32_t) nm_ap_get_capabilities (data->ap); dbus_int32_t capabilities;
dbus_bool_t broadcast = (dbus_bool_t) nm_ap_get_broadcast (data->ap); dbus_bool_t broadcast;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->ap != NULL, NULL);
g_return_val_if_fail (data->dev != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
op = nm_dbus_get_object_path_for_network (data->dev, data->ap);
essid = nm_ap_get_essid (data->ap);
strength = nm_ap_get_strength (data->ap);
freq = nm_ap_get_freq (data->ap);
rate = nm_ap_get_rate (data->ap);
mode = (dbus_int32_t) nm_ap_get_mode (data->ap);
capabilities = (dbus_int32_t) nm_ap_get_capabilities (data->ap);
broadcast = (dbus_bool_t) nm_ap_get_broadcast (data->ap);
memset (&hw_addr_buf[0], 0, 20); memset (&hw_addr_buf[0], 0, 20);
if (nm_ap_get_address (data->ap)) if (nm_ap_get_address (data->ap))
iw_ether_ntop((const struct ether_addr *) (nm_ap_get_address (data->ap)), &hw_addr_buf[0]); iw_ether_ntop((const struct ether_addr *) (nm_ap_get_address (data->ap)), &hw_addr_buf[0]);
dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &op, dbus_message_append_args (reply,
DBUS_TYPE_OBJECT_PATH, &op,
DBUS_TYPE_STRING, &essid, DBUS_TYPE_STRING, &essid,
DBUS_TYPE_STRING, &hw_addr_buf_ptr, DBUS_TYPE_STRING, &hw_addr_buf_ptr,
DBUS_TYPE_INT32, &strength, DBUS_TYPE_INT32, &strength,
@@ -263,12 +331,50 @@ static DBusMessage *nm_dbus_net_get_properties (DBusConnection *connection, DBus
DBUS_TYPE_BOOLEAN, &broadcast, DBUS_TYPE_BOOLEAN, &broadcast,
DBUS_TYPE_INVALID); DBUS_TYPE_INVALID);
g_free (op); g_free (op);
}
return reply; return reply;
} }
gboolean
nm_dbus_net_methods_dispatch (NMDbusMethodList *list,
DBusConnection *connection,
DBusMessage *message,
gpointer user_data,
DBusMessage **reply)
{
NMDbusCBData * cb_data = (NMDbusCBData *) user_data;
const char * path;
NMAccessPoint * ap;
gboolean handled = FALSE;
g_return_val_if_fail (list != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (message != NULL, FALSE);
g_return_val_if_fail (cb_data != NULL, FALSE);
g_return_val_if_fail (cb_data->dev != NULL, FALSE);
/* Figure out which network the request is for */
path = dbus_message_get_path (message);
if ((ap = nm_dbus_get_ap_from_object_path (path, cb_data->dev))) {
cb_data->ap = ap;
handled = nm_dbus_method_list_dispatch (list,
connection,
message,
cb_data,
reply);
} else {
*reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"NetworkNotFound",
"The requested network does not "
"exist for this device.");
handled = TRUE;
}
return handled;
}
/* /*
* nm_dbus_net_methods_setup * nm_dbus_net_methods_setup
* *
@@ -276,9 +382,13 @@ static DBusMessage *nm_dbus_net_get_properties (DBusConnection *connection, DBus
* org.freedesktop.NetworkManager.Devices.<dev>.Networks object. * org.freedesktop.NetworkManager.Devices.<dev>.Networks object.
* *
*/ */
NMDbusMethodList *nm_dbus_net_methods_setup (void) NMDbusMethodList *nm_dbus_net_methods_setup (NMData *data)
{ {
NMDbusMethodList *list = nm_dbus_method_list_new (nm_dbus_net_validate); NMDbusMethodList * list;
g_return_val_if_fail (data != NULL, NULL);
list = nm_dbus_method_list_new ("", FALSE, data, NULL);
nm_dbus_method_list_add_method (list, "getProperties", nm_dbus_net_get_properties); nm_dbus_method_list_add_method (list, "getProperties", nm_dbus_net_get_properties);
nm_dbus_method_list_add_method (list, "getName", nm_dbus_net_get_name); nm_dbus_method_list_add_method (list, "getName", nm_dbus_net_get_name);

View File

@@ -23,7 +23,15 @@
#define NM_DBUS_NET_H #define NM_DBUS_NET_H
#include "NetworkManagerDbusUtils.h" #include "NetworkManagerDbusUtils.h"
#include "NetworkManagerMain.h"
NMDbusMethodList *nm_dbus_net_methods_setup (void);
NMDbusMethodList *nm_dbus_net_methods_setup (NMData *data);
gboolean nm_dbus_net_methods_dispatch (NMDbusMethodList *list,
DBusConnection *connection,
DBusMessage *message,
gpointer uesr_data,
DBusMessage **reply);
#endif #endif

View File

@@ -46,168 +46,201 @@
* devices in the device list. * devices in the device list.
* *
*/ */
static DBusMessage *nm_dbus_nm_get_devices (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_nm_get_devices (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
NMData * data = (NMData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
DBusMessageIter iter; DBusMessageIter iter;
DBusMessageIter iter_array; DBusMessageIter iter_array;
g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL); g_return_val_if_fail (message != NULL, NULL);
/* Check for no devices */ /* Check for no devices */
if (!data->data->dev_list) if (!data->dev_list) {
return (nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoDevices", return nm_dbus_create_error_message (message,
"There are no available network devices.")); NM_DBUS_INTERFACE,
"NoDevices",
"There are no available network devices.");
}
if (!(reply = dbus_message_new_method_return (message))) if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL; return NULL;
}
dbus_message_iter_init_append (reply, &iter); dbus_message_iter_init_append (reply, &iter);
if (nm_try_acquire_mutex (data->data->dev_list_mutex, __FUNCTION__)) if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__)) {
{
GSList *elt; GSList *elt;
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter_array); dbus_message_iter_open_container (&iter,
for (elt = data->data->dev_list; elt; elt = g_slist_next (elt)) DBUS_TYPE_ARRAY,
{ DBUS_TYPE_OBJECT_PATH_AS_STRING,
NMDevice *dev = (NMDevice *)(elt->data); &iter_array);
if (dev) for (elt = data->dev_list; elt; elt = g_slist_next (elt)) {
{ NMDevice * dev = (NMDevice *) elt->data;
char * op = nm_dbus_get_object_path_for_device (dev); char * op = nm_dbus_get_object_path_for_device (dev);
dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &op); dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &op);
g_free (op); g_free (op);
} }
}
dbus_message_iter_close_container (&iter, &iter_array);
nm_unlock_mutex (data->data->dev_list_mutex, __FUNCTION__);
}
else
{
dbus_message_unref (reply);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "Retry",
"NetworkManager could not lock device list, try again.");
}
return (reply);
}
static DBusMessage *nm_dbus_nm_get_dialup (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
DBusMessageIter iter;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
/* Check for no dialup devices */
if (!data->data->dialup_list)
return (nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoDialup",
"There are no available dialup devices."));
reply = dbus_message_new_method_return (message);
if (!reply)
return NULL;
dbus_message_iter_init_append (reply, &iter);
if (nm_try_acquire_mutex (data->data->dialup_list_mutex, __FUNCTION__))
{
DBusMessageIter iter_array;
GSList *elt;
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_array);
for (elt = data->data->dialup_list; elt; elt = g_slist_next (elt))
{
NMDialUpConfig *config = (NMDialUpConfig *) elt->data;
dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_STRING, &config->name);
}
dbus_message_iter_close_container (&iter, &iter_array); dbus_message_iter_close_container (&iter, &iter_array);
nm_unlock_mutex (data->data->dialup_list_mutex, __FUNCTION__);
} nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
else } else {
{
dbus_message_unref (reply); dbus_message_unref (reply);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "Retry", reply = nm_dbus_create_error_message (message,
"NetworkManager could not lock dialup list, try again."); NM_DBUS_INTERFACE,
"Retry",
"NetworkManager could not lock "
" device list, try again.");
} }
return reply; return reply;
} }
static DBusMessage *nm_dbus_nm_activate_dialup (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_nm_get_dialup (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
NMData * data = (NMData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
NMData *nm_data = (NMData *) data->data; DBusMessageIter iter;
const char *dialup;
g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL); g_return_val_if_fail (message != NULL, NULL);
reply = dbus_message_new_method_return (message); /* Check for no dialup devices */
if (!reply) if (!data->dialup_list) {
return nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"NoDialup",
"There are no available dialup devices.");
}
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL; return NULL;
}
dbus_message_iter_init_append (reply, &iter);
if (nm_try_acquire_mutex (data->dialup_list_mutex, __FUNCTION__)) {
DBusMessageIter iter_array;
GSList *elt;
dbus_message_iter_open_container (&iter,
DBUS_TYPE_ARRAY,
DBUS_TYPE_STRING_AS_STRING,
&iter_array);
for (elt = data->dialup_list; elt; elt = g_slist_next (elt)) {
NMDialUpConfig *config = (NMDialUpConfig *) elt->data;
dbus_message_iter_append_basic (&iter_array,
DBUS_TYPE_STRING, &config->name);
}
dbus_message_iter_close_container (&iter, &iter_array);
nm_unlock_mutex (data->dialup_list_mutex, __FUNCTION__);
} else {
dbus_message_unref (reply);
reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"Retry",
"NetworkManager could not lock "
" dialup list, try again.");
}
return reply;
}
static DBusMessage *
nm_dbus_nm_activate_dialup (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{
NMData *data = (NMData *) user_data;
DBusMessage *reply = NULL;
const char *dialup;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &dialup, DBUS_TYPE_INVALID)) if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &dialup, DBUS_TYPE_INVALID))
{ {
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments", reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
"NetworkManager::activateDialup called with invalid arguments.");
goto out; goto out;
} }
nm_lock_mutex (nm_data->dialup_list_mutex, __FUNCTION__); nm_lock_mutex (data->dialup_list_mutex, __FUNCTION__);
if (!nm_system_activate_dialup (nm_data->dialup_list, dialup)) if (!nm_system_activate_dialup (data->dialup_list, dialup)) {
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "ActivationFailed", reply = nm_dbus_create_error_message (message,
"Failed to activate the dialup device."); NM_DBUS_INTERFACE,
else "ActivationFailed",
nm_data->modem_active = TRUE; "Failed to activate the dialup "
nm_unlock_mutex (nm_data->dialup_list_mutex, __FUNCTION__); "device.");
} else {
data->modem_active = TRUE;
}
nm_unlock_mutex (data->dialup_list_mutex, __FUNCTION__);
out: out:
return reply; return reply;
} }
static DBusMessage *nm_dbus_nm_deactivate_dialup (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_nm_deactivate_dialup (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
NMData *data = (NMData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMData *nm_data = (NMData *) data->data;
const char *dialup; const char *dialup;
g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL); g_return_val_if_fail (message != NULL, NULL);
reply = dbus_message_new_method_return (message); if (!(reply = dbus_message_new_method_return (message))) {
if (!reply) nm_warning ("Not enough memory to create dbus message.");
return NULL; return NULL;
}
if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &dialup, DBUS_TYPE_INVALID)) if (!dbus_message_get_args (message,
{ NULL,
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments", DBUS_TYPE_STRING, &dialup,
"NetworkManager::deactivateDialup called with invalid arguments."); DBUS_TYPE_INVALID)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out; goto out;
} }
nm_lock_mutex (nm_data->dialup_list_mutex, __FUNCTION__); nm_lock_mutex (data->dialup_list_mutex, __FUNCTION__);
if (!nm_system_deactivate_dialup (nm_data->dialup_list, dialup)) if (!nm_system_deactivate_dialup (data->dialup_list, dialup)) {
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeactivationFailed", reply = nm_dbus_create_error_message (message,
"Failed to deactivate the dialup device."); NM_DBUS_INTERFACE,
else "DeactivationFailed",
nm_data->modem_active = FALSE; "Failed to deactivate the dialup "
nm_unlock_mutex (nm_data->dialup_list_mutex, __FUNCTION__); " device.");
} else {
data->modem_active = FALSE;
}
nm_unlock_mutex (data->dialup_list_mutex, __FUNCTION__);
out: out:
return reply; return reply;
@@ -221,10 +254,12 @@ out:
* device. * device.
* *
*/ */
static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_nm_set_active_device (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
const char * INVALID_ARGS_ERROR = "InvalidArguments"; NMData * data = (NMData *) user_data;
const char * INVALID_ARGS_MESSAGE = "NetworkManager::setActiveDevice called with invalid arguments.";
NMDevice * dev = NULL; NMDevice * dev = NULL;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
char * dev_path; char * dev_path;
@@ -234,51 +269,52 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL); g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
dbus_message_iter_init (message, &iter); dbus_message_iter_init (message, &iter);
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_OBJECT_PATH) if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_OBJECT_PATH) {
{
nm_warning ("%s:%d (%s): Invalid arguments (first arg type was not OBJECT_PATH).", nm_warning ("%s:%d (%s): Invalid arguments (first arg type was not OBJECT_PATH).",
__FILE__, __LINE__, __func__); __FILE__, __LINE__, __func__);
goto out; goto out;
} }
dbus_message_iter_get_basic (&iter, &dev_path); dbus_message_iter_get_basic (&iter, &dev_path);
dev = nm_dbus_get_device_from_escaped_object_path (data->data, dev_path); dev = nm_dbus_get_device_from_escaped_object_path (data, dev_path);
/* Ensure the device exists in our list and is supported */ /* Ensure the device exists in our list and is supported */
if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED)) if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED)) {
{ reply = nm_dbus_create_error_message (message,
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound", NM_DBUS_INTERFACE,
"The requested network device does not exist."); "DeviceNotFound",
nm_warning ("%s:%d (%s): Invalid device (device not found).", __FILE__, __LINE__, __func__); "The requested network device "
"does not exist.");
nm_warning ("%s:%d (%s): Invalid device (device not found).", __FILE__,
__LINE__, __func__);
goto out; goto out;
} }
if (nm_device_is_802_11_wireless (dev)) if (nm_device_is_802_11_wireless (dev)) {
{
NMAPSecurity * security = NULL; NMAPSecurity * security = NULL;
char * essid = NULL; char * essid = NULL;
gboolean fallback = FALSE; gboolean fallback = FALSE;
if (!dbus_message_iter_next (&iter) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) if ( !dbus_message_iter_next (&iter)
{ || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) {
nm_warning ("%s:%d (%s): Invalid argument type (essid).", __FILE__, __LINE__, __func__); nm_warning ("%s:%d (%s): Invalid argument type (essid).", __FILE__,
__LINE__, __func__);
goto out; goto out;
} }
/* grab ssid and ensure validity */ /* grab ssid and ensure validity */
dbus_message_iter_get_basic (&iter, &essid); dbus_message_iter_get_basic (&iter, &essid);
if (!essid || (strlen (essid) <= 0)) if (!essid || (strlen (essid) <= 0)) {
{ nm_warning ("%s:%d (%s): Invalid argument (essid).",
nm_warning ("%s:%d (%s): Invalid argument (essid).", __FILE__, __LINE__, __func__); __FILE__, __LINE__, __func__);
goto out; goto out;
} }
if (!dbus_message_iter_next (&iter) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN)) if ( !dbus_message_iter_next (&iter)
{ || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_BOOLEAN)) {
nm_warning ("Invalid argument type (fallback"); nm_warning ("Invalid argument type (fallback");
goto out; goto out;
} }
@@ -289,13 +325,12 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
/* If there's security information, we use that. If not, we /* If there's security information, we use that. If not, we
* make some up from the scan list. * make some up from the scan list.
*/ */
if (dbus_message_iter_next (&iter)) if (dbus_message_iter_next (&iter)) {
{ if (!(security = nm_ap_security_new_deserialize (&iter))) {
if (!(security = nm_ap_security_new_deserialize (&iter)))
{
/* There was security info, but it was invalid */ /* There was security info, but it was invalid */
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE); reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
nm_warning ("%s:%d (%s): Invalid argument (wireless security info).", __FILE__, __LINE__, __func__); nm_warning ("%s:%d (%s): Invalid argument (wireless security "
"info).", __FILE__, __LINE__, __func__);
goto out; goto out;
} }
} }
@@ -307,22 +342,19 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
g_object_unref (G_OBJECT (security)); g_object_unref (G_OBJECT (security));
nm_info ("User Switch: %s / %s", dev_path, essid); nm_info ("User Switch: %s / %s", dev_path, essid);
} } else if (nm_device_is_802_3_ethernet (dev)) {
else if (nm_device_is_802_3_ethernet (dev))
{
nm_info ("User Switch: %s", dev_path); nm_info ("User Switch: %s", dev_path);
} }
nm_device_deactivate (dev); nm_device_deactivate (dev);
nm_schedule_state_change_signal_broadcast (data->data); nm_schedule_state_change_signal_broadcast (data);
nm_policy_schedule_device_activation (nm_act_request_new (data->data, dev, ap, TRUE)); nm_policy_schedule_device_activation (nm_act_request_new (data, dev, ap, TRUE));
out: out:
if (dev)
g_object_unref (G_OBJECT (dev));
if (!reply) if (!reply)
{ reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE,
INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
}
return reply; return reply;
} }
@@ -333,10 +365,12 @@ out:
* Create a new wireless network and * Create a new wireless network and
* *
*/ */
static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_nm_create_wireless_network (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
const char * INVALID_ARGS_ERROR = "InvalidArguments"; NMData * data = (NMData *) user_data;
const char * INVALID_ARGS_MESSAGE = "NetworkManager::createWirelessNetwork called with invalid arguments.";
NMDevice * dev = NULL; NMDevice * dev = NULL;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
char * dev_path = NULL; char * dev_path = NULL;
@@ -344,50 +378,48 @@ static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connecti
NMAPSecurity * security = NULL; NMAPSecurity * security = NULL;
char * essid = NULL; char * essid = NULL;
DBusMessageIter iter; DBusMessageIter iter;
NMActRequest * req;
g_return_val_if_fail (connection != NULL, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL); g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (data->data != NULL, NULL);
dbus_message_iter_init (message, &iter); dbus_message_iter_init (message, &iter);
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_OBJECT_PATH) if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_OBJECT_PATH) {
{ reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
goto out; goto out;
} }
dbus_message_iter_get_basic (&iter, &dev_path); dbus_message_iter_get_basic (&iter, &dev_path);
dev = nm_dbus_get_device_from_escaped_object_path (data->data, dev_path); dev = nm_dbus_get_device_from_escaped_object_path (data, dev_path);
/* Ensure the device exists in our list and is supported */ /* Ensure the device exists in our list and is supported */
if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED)) if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED)) {
{ reply = nm_dbus_create_error_message (message,
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound", NM_DBUS_INTERFACE,
"The requested network device does not exist."); "DeviceNotFound",
"The requested network device "
"does not exist.");
goto out; goto out;
} }
if ( !nm_device_is_802_11_wireless (dev) if ( !nm_device_is_802_11_wireless (dev)
|| !dbus_message_iter_next (&iter) || !dbus_message_iter_next (&iter)
|| (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) {
{ reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
goto out; goto out;
} }
/* grab ssid and ensure validity */ /* grab ssid and ensure validity */
dbus_message_iter_get_basic (&iter, &essid); dbus_message_iter_get_basic (&iter, &essid);
if (!essid || (strlen (essid) <= 0) || !dbus_message_iter_next (&iter)) if (!essid || (strlen (essid) <= 0) || !dbus_message_iter_next (&iter)) {
{ reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
goto out; goto out;
} }
if (!(security = nm_ap_security_new_deserialize (&iter))) if (!(security = nm_ap_security_new_deserialize (&iter))) {
{ reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
goto out; goto out;
} }
@@ -400,216 +432,282 @@ static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connecti
g_object_unref (G_OBJECT (security)); g_object_unref (G_OBJECT (security));
nm_ap_set_user_created (new_ap, TRUE); nm_ap_set_user_created (new_ap, TRUE);
nm_policy_schedule_device_activation (nm_act_request_new (data->data, dev, new_ap, TRUE)); req = nm_act_request_new (data, dev, new_ap, TRUE);
nm_policy_schedule_device_activation (req);
out:
if (dev)
g_object_unref (G_OBJECT (dev));
return reply;
}
static DBusMessage *
nm_dbus_nm_create_test_device (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{
NMData * data = (NMData *) user_data;
NMDeviceType type;
DBusMessage *reply = NULL;
static int test_dev_num = 0;
NMDevice * dev;
char * iface;
char * udi;
char * dev_path;
char * escaped_dev_path;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
if (!dbus_message_get_args (message,
NULL,
DBUS_TYPE_INT32, &type,
DBUS_TYPE_INVALID)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
if ( (type != DEVICE_TYPE_802_3_ETHERNET)
&& (type == DEVICE_TYPE_802_11_WIRELESS)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
goto out;
}
iface = g_strdup_printf ("test%d", test_dev_num);
udi = g_strdup_printf ("/test-devices/%s", iface);
dev = nm_create_device_and_add_to_list (data, udi, iface, TRUE, type);
g_free (iface);
g_free (udi);
test_dev_num++;
dev_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
escaped_dev_path = nm_dbus_escape_object_path (dev_path);
g_free (dev_path);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &escaped_dev_path, DBUS_TYPE_INVALID);
g_free (escaped_dev_path);
out: out:
return reply; return reply;
} }
static DBusMessage *
static DBusMessage *nm_dbus_nm_create_test_device (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) nm_dbus_nm_remove_test_device (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
DBusError err; NMData * data = (NMData *) user_data;
NMDeviceType type;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
static int test_dev_num = 0; char * dev_path;
g_return_val_if_fail (data && data->data && connection && message, NULL);
dbus_error_init (&err);
if ( dbus_message_get_args (message, &err, DBUS_TYPE_INT32, &type, DBUS_TYPE_INVALID)
&& ((type == DEVICE_TYPE_802_3_ETHERNET) || (type == DEVICE_TYPE_802_11_WIRELESS)))
{
char *interface = g_strdup_printf ("test%d", test_dev_num);
char *udi = g_strdup_printf ("/test-devices/%s", interface);
NMDevice * dev = NULL; NMDevice * dev = NULL;
dev = nm_create_device_and_add_to_list (data->data, udi, interface, TRUE, type); g_return_val_if_fail (connection != NULL, NULL);
test_dev_num++; g_return_val_if_fail (message != NULL, NULL);
if ((reply = dbus_message_new_method_return (message))) g_return_val_if_fail (data != NULL, NULL);
{
char *dev_path, *escaped_dev_path; if (!dbus_message_get_args (message,
dev_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)); NULL,
escaped_dev_path = nm_dbus_escape_object_path (dev_path); DBUS_TYPE_STRING, &dev_path,
dbus_message_append_args (reply, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID); DBUS_TYPE_INVALID)) {
g_free (dev_path); reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
g_free (escaped_dev_path); goto out;
} }
g_free (interface);
g_free (udi); if (!(dev = nm_dbus_get_device_from_escaped_object_path (data, dev_path))) {
} reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
else goto out;
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "BadType", "The test device type was invalid."); }
return (reply); if (!nm_device_is_test_device (dev)) {
} reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
static DBusMessage *nm_dbus_nm_remove_test_device (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) "NotTestDevice",
{ "Only test devices can be removed"
DBusMessage *reply = NULL; " via the DBus interface.");
DBusError err; goto out;
char *dev_path; }
g_return_val_if_fail (data && data->data && connection && message, NULL); nm_remove_device (data, dev);
dbus_error_init (&err); out:
if (dbus_message_get_args (message, &err, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID)) if (dev)
{ g_object_unref (G_OBJECT (dev));
NMDevice *dev; return reply;
}
if ((dev = nm_dbus_get_device_from_escaped_object_path (data->data, dev_path)))
{ static DBusMessage *
if (nm_device_is_test_device (dev)) nm_dbus_nm_set_wireless_enabled (DBusConnection *connection,
nm_remove_device (data->data, dev); DBusMessage *message,
else void * user_data)
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NotTestDevice",
"Only test devices can be removed via dbus calls.");
}
else
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
"The requested network device does not exist.");
}
}
else
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceBad",
"The device ID was bad.");
}
if (dbus_error_is_set (&err))
dbus_error_free (&err);
return (reply);
}
static DBusMessage *nm_dbus_nm_set_wireless_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{ {
NMData * data = (NMData *) user_data;
gboolean enabled = FALSE; gboolean enabled = FALSE;
DBusError err; DBusMessage * reply = NULL;
NMData *app_data;
g_return_val_if_fail (data && data->data && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
dbus_error_init (&err); if (!dbus_message_get_args (message,
if (!dbus_message_get_args (message, &err, DBUS_TYPE_BOOLEAN, &enabled, DBUS_TYPE_INVALID)) NULL,
return NULL; DBUS_TYPE_BOOLEAN, &enabled,
DBUS_TYPE_INVALID)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
app_data = data->data; data->wireless_enabled = enabled;
app_data->wireless_enabled = enabled;
if (!enabled) if (!enabled) {
{
GSList * elt; GSList * elt;
/* Physically down all wireless devices */ /* Down all wireless devices */
nm_lock_mutex (app_data->dev_list_mutex, __FUNCTION__); nm_lock_mutex (data->dev_list_mutex, __FUNCTION__);
for (elt = app_data->dev_list; elt; elt = g_slist_next (elt)) for (elt = data->dev_list; elt; elt = g_slist_next (elt)) {
{
NMDevice * dev = (NMDevice *)(elt->data); NMDevice * dev = (NMDevice *)(elt->data);
if (nm_device_is_802_11_wireless (dev))
{ if (nm_device_is_802_11_wireless (dev)) {
nm_device_deactivate (dev); nm_device_deactivate (dev);
nm_device_bring_down (dev); nm_device_bring_down (dev);
} }
} }
nm_unlock_mutex (app_data->dev_list_mutex, __FUNCTION__); nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
} }
nm_policy_schedule_device_change_check (data->data); nm_policy_schedule_device_change_check (data);
return NULL; out:
return reply;
} }
static DBusMessage *nm_dbus_nm_get_wireless_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_nm_get_wireless_enabled (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
NMData * data = (NMData *) user_data;
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
g_return_val_if_fail (data && data->data && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
if ((reply = dbus_message_new_method_return (message))) if ((reply = dbus_message_new_method_return (message))) {
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &data->data->wireless_enabled, DBUS_TYPE_INVALID); dbus_message_append_args (reply,
DBUS_TYPE_BOOLEAN, &data->wireless_enabled,
DBUS_TYPE_INVALID);
}
return reply; return reply;
} }
static DBusMessage *nm_dbus_nm_sleep (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
{ nm_dbus_nm_sleep (DBusConnection *connection,
NMData *app_data; DBusMessage *message,
void * user_data)
g_return_val_if_fail (data && data->data && connection && message, NULL);
app_data = data->data;
if (app_data->asleep == FALSE)
{ {
NMData * data = (NMData *) user_data;
GSList * elt; GSList * elt;
nm_info ("Going to sleep."); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
if (data->asleep)
return NULL;
nm_info ("Going to sleep.");
data->asleep = TRUE;
app_data->asleep = TRUE;
/* Not using nm_schedule_state_change_signal_broadcast() here /* Not using nm_schedule_state_change_signal_broadcast() here
* because we want the signal to go out ASAP. * because we want the signal to go out ASAP.
*/ */
nm_dbus_signal_state_change (connection, app_data); nm_dbus_signal_state_change (connection, data);
/* Remove all devices from the device list */ /* Just deactivate and down all devices from the device list,
nm_lock_mutex (app_data->dev_list_mutex, __FUNCTION__); * we'll remove them in 'wake' for speed's sake.
for (elt = app_data->dev_list; elt; elt = g_slist_next (elt)) */
{ nm_lock_mutex (data->dev_list_mutex, __FUNCTION__);
for (elt = data->dev_list; elt; elt = g_slist_next (elt)) {
NMDevice *dev = (NMDevice *)(elt->data); NMDevice *dev = (NMDevice *)(elt->data);
nm_device_set_removed (dev, TRUE); nm_device_set_removed (dev, TRUE);
nm_device_deactivate_quickly (dev); nm_device_deactivate_quickly (dev);
nm_system_device_set_up_down (dev, FALSE); nm_system_device_set_up_down (dev, FALSE);
} }
nm_unlock_mutex (app_data->dev_list_mutex, __FUNCTION__); nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
nm_lock_mutex (app_data->dialup_list_mutex, __FUNCTION__); nm_lock_mutex (data->dialup_list_mutex, __FUNCTION__);
nm_system_deactivate_all_dialup (app_data->dialup_list); nm_system_deactivate_all_dialup (data->dialup_list);
app_data->modem_active = FALSE; data->modem_active = FALSE;
nm_unlock_mutex (app_data->dialup_list_mutex, __FUNCTION__); nm_unlock_mutex (data->dialup_list_mutex, __FUNCTION__);
}
return NULL; return NULL;
} }
static DBusMessage *nm_dbus_nm_wake (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_nm_wake (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
NMData *app_data; NMData * data = (NMData *) user_data;
g_return_val_if_fail (data && data->data && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
if (!data->asleep)
return NULL;
app_data = data->data;
if (app_data->asleep == TRUE)
{
nm_info ("Waking up from sleep."); nm_info ("Waking up from sleep.");
app_data->asleep = FALSE; data->asleep = FALSE;
/* Remove all devices from the device list */ /* Remove all devices from the device list */
nm_lock_mutex (app_data->dev_list_mutex, __FUNCTION__); nm_lock_mutex (data->dev_list_mutex, __FUNCTION__);
while (g_slist_length (app_data->dev_list)) while (g_slist_length (data->dev_list))
nm_remove_device (app_data, (NMDevice *)(app_data->dev_list->data)); nm_remove_device (data, (NMDevice *)(data->dev_list->data));
nm_unlock_mutex (app_data->dev_list_mutex, __FUNCTION__); g_slist_free (data->dev_list);
data->dev_list = NULL;
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
nm_add_initial_devices (app_data); nm_add_initial_devices (data);
nm_schedule_state_change_signal_broadcast (app_data); nm_schedule_state_change_signal_broadcast (data);
nm_policy_schedule_device_change_check (data->data); nm_policy_schedule_device_change_check (data);
}
return NULL; return NULL;
} }
static DBusMessage *nm_dbus_nm_get_state (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *
nm_dbus_nm_get_state (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{ {
NMData * data = (NMData *) user_data;
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
NMState state; NMState state;
g_return_val_if_fail (data && data->data && connection && message, NULL); g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
state = nm_get_app_state_from_data (data->data); if (!(reply = dbus_message_new_method_return (message))) {
if ((reply = dbus_message_new_method_return (message))) nm_warning ("Not enough memory to create dbus message.");
goto out;
}
state = nm_get_app_state_from_data (data);
dbus_message_append_args (reply, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID); dbus_message_append_args (reply, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);
out:
return reply; return reply;
} }
@@ -620,9 +718,13 @@ static DBusMessage *nm_dbus_nm_get_state (DBusConnection *connection, DBusMessag
* Register handlers for dbus methods on the org.freedesktop.NetworkManager object. * Register handlers for dbus methods on the org.freedesktop.NetworkManager object.
* *
*/ */
NMDbusMethodList *nm_dbus_nm_methods_setup (void) NMDbusMethodList *nm_dbus_nm_methods_setup (NMData *data)
{ {
NMDbusMethodList *list = nm_dbus_method_list_new (NULL); NMDbusMethodList * list;
g_return_val_if_fail (data != NULL, NULL);
list = nm_dbus_method_list_new (NM_DBUS_PATH, FALSE, data, NULL);
nm_dbus_method_list_add_method (list, "getDevices", nm_dbus_nm_get_devices); nm_dbus_method_list_add_method (list, "getDevices", nm_dbus_nm_get_devices);
nm_dbus_method_list_add_method (list, "getDialup", nm_dbus_nm_get_dialup); nm_dbus_method_list_add_method (list, "getDialup", nm_dbus_nm_get_dialup);
@@ -638,5 +740,5 @@ NMDbusMethodList *nm_dbus_nm_methods_setup (void)
nm_dbus_method_list_add_method (list, "createTestDevice", nm_dbus_nm_create_test_device); nm_dbus_method_list_add_method (list, "createTestDevice", nm_dbus_nm_create_test_device);
nm_dbus_method_list_add_method (list, "removeTestDevice", nm_dbus_nm_remove_test_device); nm_dbus_method_list_add_method (list, "removeTestDevice", nm_dbus_nm_remove_test_device);
return (list); return list;
} }

View File

@@ -22,9 +22,10 @@
#ifndef NM_DBUS_NM_H #ifndef NM_DBUS_NM_H
#define NM_DBUS_NM_H #define NM_DBUS_NM_H
#include "NetworkManagerMain.h"
#include "NetworkManagerDbusUtils.h" #include "NetworkManagerDbusUtils.h"
NMDbusMethodList *nm_dbus_nm_methods_setup (void); NMDbusMethodList *nm_dbus_nm_methods_setup (NMData *data);
#endif #endif

View File

@@ -27,6 +27,7 @@
#include "NetworkManagerUtils.h" #include "NetworkManagerUtils.h"
#include "nm-dbus-nmi.h" #include "nm-dbus-nmi.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-dbus-manager.h"
/* /*
@@ -36,7 +37,9 @@
* the new user key. * the new user key.
* *
*/ */
static void nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall, NMActRequest *req) static void
nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall,
NMActRequest *req)
{ {
DBusMessage * reply = NULL; DBusMessage * reply = NULL;
NMData * data; NMData * data;
@@ -64,21 +67,23 @@ static void nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall, NMActRe
if (!(reply = dbus_pending_call_steal_reply (pcall))) if (!(reply = dbus_pending_call_steal_reply (pcall)))
goto out; goto out;
if (message_is_error (reply)) if (message_is_error (reply)) {
{
DBusError err; DBusError err;
dbus_error_init (&err); dbus_error_init (&err);
dbus_set_error_from_message (&err, reply); dbus_set_error_from_message (&err, reply);
/* Check for cancelled error */ /* Check for cancelled error */
if (strcmp (err.name, NMI_DBUS_USER_KEY_CANCELED_ERROR) == 0) if (strcmp (err.name, NMI_DBUS_USER_KEY_CANCELED_ERROR) == 0) {
{ nm_info ("Activation (%s) New wireless user key request for network"
nm_info ("Activation (%s) New wireless user key request for network '%s' was canceled.", " '%s' was canceled.",
nm_device_get_iface (dev), nm_ap_get_essid (ap)); nm_device_get_iface (dev),
nm_ap_get_essid (ap));
} else {
nm_warning ("dbus returned an error.\n (%s) %s\n",
err.name,
err.message);
} }
else
nm_warning ("nm_dbus_get_user_key_for_network_cb(): dbus returned an error.\n (%s) %s\n", err.name, err.message);
dbus_error_free (&err); dbus_error_free (&err);
@@ -94,11 +99,12 @@ static void nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall, NMActRe
goto out; goto out;
} }
nm_info ("Activation (%s) New wireless user key for network '%s' received.", nm_device_get_iface (dev), nm_ap_get_essid (ap)); nm_info ("Activation (%s) New wireless user key for network '%s' received.",
nm_device_get_iface (dev),
nm_ap_get_essid (ap));
dbus_message_iter_init (reply, &iter); dbus_message_iter_init (reply, &iter);
if ((security = nm_ap_security_new_deserialize (&iter))) if ((security = nm_ap_security_new_deserialize (&iter))) {
{
nm_ap_set_security (ap, security); nm_ap_set_security (ap, security);
nm_device_activate_schedule_stage1_device_prepare (req); nm_device_activate_schedule_stage1_device_prepare (req);
} }
@@ -118,11 +124,14 @@ out:
* Asks the info-daemon for a user-entered WEP key. * Asks the info-daemon for a user-entered WEP key.
* *
*/ */
void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest *req, const gboolean new_key) void
nm_dbus_get_user_key_for_network (NMActRequest *req,
const gboolean new_key)
{ {
NMDBusManager * dbus_mgr = NULL;
DBusConnection *dbus_connection;
DBusMessage * message; DBusMessage * message;
DBusPendingCall * pcall; DBusPendingCall * pcall;
NMData * data;
NMDevice * dev; NMDevice * dev;
NMAccessPoint * ap; NMAccessPoint * ap;
gint32 attempt = 1; gint32 attempt = 1;
@@ -130,11 +139,14 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest
char * net_path; char * net_path;
const char * essid; const char * essid;
g_return_if_fail (connection != NULL);
g_return_if_fail (req != NULL); g_return_if_fail (req != NULL);
data = nm_act_request_get_data (req); dbus_mgr = nm_dbus_manager_get (NULL);
g_assert (data); dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
dev = nm_act_request_get_dev (req); dev = nm_act_request_get_dev (req);
g_assert (dev); g_assert (dev);
@@ -143,35 +155,42 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest
g_assert (ap); g_assert (ap);
essid = nm_ap_get_essid (ap); essid = nm_ap_get_essid (ap);
nm_info ("Activation (%s) New wireless user key requested for network '%s'.", nm_device_get_iface (dev), essid); nm_info ("Activation (%s) New wireless user key requested for network '%s'.",
nm_device_get_iface (dev),
essid);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getKeyForNetwork"))) message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
{ NMI_DBUS_PATH,
nm_warning ("nm_dbus_get_user_key_for_network(): Couldn't allocate the dbus message"); NMI_DBUS_INTERFACE,
return; "getKeyForNetwork");
if (!message) {
nm_warning ("couldn't allocate the dbus message");
goto out;
} }
dev_path = nm_dbus_get_object_path_for_device (dev); dev_path = nm_dbus_get_object_path_for_device (dev);
net_path = nm_dbus_get_object_path_for_network (dev, ap); net_path = nm_dbus_get_object_path_for_network (dev, ap);
if (dev_path && strlen (dev_path) && net_path && strlen (net_path)) if (dev_path && strlen (dev_path) && net_path && strlen (net_path)) {
{
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path,
DBUS_TYPE_OBJECT_PATH, &net_path, DBUS_TYPE_OBJECT_PATH, &net_path,
DBUS_TYPE_STRING, &essid, DBUS_TYPE_STRING, &essid,
DBUS_TYPE_INT32, &attempt, DBUS_TYPE_INT32, &attempt,
DBUS_TYPE_BOOLEAN, &new_key, DBUS_TYPE_BOOLEAN, &new_key,
DBUS_TYPE_INVALID); DBUS_TYPE_INVALID);
if ((pcall = nm_dbus_send_with_callback (connection, message, pcall = nm_dbus_send_with_callback (dbus_connection,
message,
(DBusPendingCallNotifyFunction) nm_dbus_get_user_key_for_network_cb, (DBusPendingCallNotifyFunction) nm_dbus_get_user_key_for_network_cb,
req, NULL, __func__))) req,
{ NULL,
__func__);
if (pcall) {
nm_act_request_ref (req); nm_act_request_ref (req);
nm_act_request_set_stage (req, NM_ACT_STAGE_NEED_USER_KEY); nm_act_request_set_stage (req, NM_ACT_STAGE_NEED_USER_KEY);
nm_act_request_set_user_key_pending_call (req, pcall); nm_act_request_set_user_key_pending_call (req, pcall);
} }
else } else {
nm_warning ("nm_dbus_get_user_key_for_network(): could not send dbus message"); nm_warning ("bad object path data");
} else nm_warning ("nm_dbus_get_user_key_for_network(): bad object path data"); }
g_free (net_path); g_free (net_path);
g_free (dev_path); g_free (dev_path);
@@ -181,6 +200,9 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest
*/ */
dbus_message_unref (message); dbus_message_unref (message);
out:
g_object_unref (dbus_mgr);
} }
@@ -190,27 +212,40 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest
* Sends a user-key cancellation message to NetworkManagerInfo * Sends a user-key cancellation message to NetworkManagerInfo
* *
*/ */
void nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection, NMActRequest *req) void
nm_dbus_cancel_get_user_key_for_network (NMActRequest *req)
{ {
DBusMessage * message; DBusMessage * message;
DBusPendingCall * pcall; DBusPendingCall * pcall;
NMDBusManager * dbus_mgr;
DBusConnection * dbus_connection;
g_return_if_fail (connection != NULL);
g_return_if_fail (req != NULL); g_return_if_fail (req != NULL);
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
if ((pcall = nm_act_request_get_user_key_pending_call (req))) if ((pcall = nm_act_request_get_user_key_pending_call (req)))
dbus_pending_call_cancel (pcall); dbus_pending_call_cancel (pcall);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "cancelGetKeyForNetwork"))) message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
{ NMI_DBUS_PATH,
nm_warning ("nm_dbus_cancel_get_user_key_for_network(): Couldn't allocate the dbus message"); NMI_DBUS_INTERFACE,
return; "cancelGetKeyForNetwork");
if (!message) {
nm_warning ("couldn't allocate the dbus message");
goto out;
} }
if (!dbus_connection_send (connection, message, NULL)) dbus_connection_send (dbus_connection, message, NULL);
nm_warning ("nm_dbus_cancel_get_user_key_for_network(): could not send dbus message");
dbus_message_unref (message); dbus_message_unref (message);
out:
g_object_unref (dbus_mgr);
} }
@@ -220,10 +255,13 @@ void nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection, NMActR
* Tell NetworkManagerInfo the updated info of the AP * Tell NetworkManagerInfo the updated info of the AP
* *
*/ */
gboolean nm_dbus_update_network_info (DBusConnection *connection, NMAccessPoint *ap, const gboolean automatic) void
nm_dbus_update_network_info (NMAccessPoint *ap,
const gboolean automatic)
{ {
NMDBusManager * dbus_mgr = NULL;
DBusConnection * dbus_connection;
DBusMessage * message; DBusMessage * message;
gboolean success = FALSE;
gboolean fallback; gboolean fallback;
const char * essid; const char * essid;
gchar * char_bssid; gchar * char_bssid;
@@ -231,14 +269,23 @@ gboolean nm_dbus_update_network_info (DBusConnection *connection, NMAccessPoint
const struct ether_addr *addr; const struct ether_addr *addr;
DBusMessageIter iter; DBusMessageIter iter;
g_return_val_if_fail (connection != NULL, FALSE); g_return_if_fail (ap != NULL);
g_return_val_if_fail (ap != NULL, FALSE);
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
essid = nm_ap_get_essid (ap); essid = nm_ap_get_essid (ap);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "updateNetworkInfo"))) message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
{ NMI_DBUS_PATH,
nm_warning ("nm_dbus_update_network_info(): Couldn't allocate the dbus message"); NMI_DBUS_INTERFACE,
"updateNetworkInfo");
if (!message) {
nm_warning ("couldn't allocate the dbus message");
goto out; goto out;
} }
@@ -276,19 +323,13 @@ gboolean nm_dbus_update_network_info (DBusConnection *connection, NMAccessPoint
/* Serialize the AP's security info into the message */ /* Serialize the AP's security info into the message */
security = nm_ap_get_security (ap); security = nm_ap_get_security (ap);
g_assert (security); g_assert (security);
if (nm_ap_security_serialize (security, &iter) != 0) if (nm_ap_security_serialize (security, &iter) == 0)
goto unref; dbus_connection_send (dbus_connection, message, NULL);
if (dbus_connection_send (connection, message, NULL))
success = TRUE;
else
nm_warning ("nm_dbus_update_network_info(): failed to send dbus message.");
unref:
dbus_message_unref (message); dbus_message_unref (message);
out: out:
return success; g_object_unref (dbus_mgr);
return;
} }
@@ -487,11 +528,15 @@ out:
* Async callback from nm_dbus_get_networks * Async callback from nm_dbus_get_networks
* *
*/ */
static void nm_dbus_get_networks_cb (DBusPendingCall *pcall, void *user_data) static void
nm_dbus_get_networks_cb (DBusPendingCall *pcall,
void *user_data)
{ {
DBusMessage * reply; DBusMessage * reply;
DBusMessageIter iter, array_iter; DBusMessageIter iter, array_iter;
GetNetworksCBData * cb_data = (GetNetworksCBData *)user_data; GetNetworksCBData * cb_data = (GetNetworksCBData *)user_data;
NMDBusManager * dbus_mgr = NULL;
DBusConnection *dbus_connection;
g_return_if_fail (pcall); g_return_if_fail (pcall);
g_return_if_fail (cb_data != NULL); g_return_if_fail (cb_data != NULL);
@@ -505,8 +550,7 @@ static void nm_dbus_get_networks_cb (DBusPendingCall *pcall, void *user_data)
if (!(reply = dbus_pending_call_steal_reply (pcall))) if (!(reply = dbus_pending_call_steal_reply (pcall)))
goto out; goto out;
if (message_is_error (reply)) if (message_is_error (reply)) {
{
DBusError err; DBusError err;
dbus_error_init (&err); dbus_error_init (&err);
@@ -515,18 +559,27 @@ static void nm_dbus_get_networks_cb (DBusPendingCall *pcall, void *user_data)
goto out; goto out;
} }
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_warning ("couldn't get dbus connection.");
goto out;
}
dbus_message_iter_init (reply, &iter); dbus_message_iter_init (reply, &iter);
dbus_message_iter_recurse (&iter, &array_iter); dbus_message_iter_recurse (&iter, &array_iter);
while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
{
const char * value; const char * value;
DBusMessage * message; DBusMessage * message;
dbus_message_iter_get_basic (&array_iter, &value); dbus_message_iter_get_basic (&array_iter, &value);
/* Get properties on each network */ /* Get properties on each network */
if ((message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getNetworkProperties"))) message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
{ NMI_DBUS_PATH,
NMI_DBUS_INTERFACE,
"getNetworkProperties");
if (message) {
dbus_int32_t type_as_int32 = nm_ap_list_get_type (cb_data->list); dbus_int32_t type_as_int32 = nm_ap_list_get_type (cb_data->list);
GetOneNetworkCBData * net_cb_data = g_slice_new0 (GetOneNetworkCBData); GetOneNetworkCBData * net_cb_data = g_slice_new0 (GetOneNetworkCBData);
@@ -535,10 +588,16 @@ static void nm_dbus_get_networks_cb (DBusPendingCall *pcall, void *user_data)
nm_ap_list_ref (cb_data->list); nm_ap_list_ref (cb_data->list);
net_cb_data->list = cb_data->list; net_cb_data->list = cb_data->list;
dbus_message_append_args (message, DBUS_TYPE_STRING, &value, DBUS_TYPE_INT32, &type_as_int32, DBUS_TYPE_INVALID); dbus_message_append_args (message,
nm_dbus_send_with_callback (cb_data->data->dbus_connection, message, DBUS_TYPE_STRING, &value,
(DBusPendingCallNotifyFunction) nm_dbus_get_network_data_cb, net_cb_data, DBUS_TYPE_INT32, &type_as_int32,
(DBusFreeFunction) free_get_one_network_cb_data, __func__); DBUS_TYPE_INVALID);
nm_dbus_send_with_callback (dbus_connection,
message,
(DBusPendingCallNotifyFunction) nm_dbus_get_network_data_cb,
net_cb_data,
(DBusFreeFunction) free_get_one_network_cb_data,
__func__);
dbus_message_unref (message); dbus_message_unref (message);
} }
dbus_message_iter_next(&array_iter); dbus_message_iter_next(&array_iter);
@@ -546,6 +605,8 @@ static void nm_dbus_get_networks_cb (DBusPendingCall *pcall, void *user_data)
dbus_message_unref (reply); dbus_message_unref (reply);
out: out:
if (dbus_mgr)
g_object_unref (dbus_mgr);
dbus_pending_call_unref (pcall); dbus_pending_call_unref (pcall);
} }
@@ -556,29 +617,54 @@ out:
* Update all allowed networks from NetworkManagerInfo * Update all allowed networks from NetworkManagerInfo
* *
*/ */
void nm_dbus_update_allowed_networks (DBusConnection *connection, NMAccessPointList *list, NMData *data) void
nm_dbus_update_allowed_networks (NMAccessPointList *list,
NMData *data)
{ {
NMDBusManager * dbus_mgr = NULL;
DBusConnection * dbus_connection;
DBusMessage * message; DBusMessage * message;
dbus_int32_t type_as_int32 = nm_ap_list_get_type (list); dbus_int32_t type_as_int32 = nm_ap_list_get_type (list);
GetNetworksCBData * cb_data; GetNetworksCBData * cb_data;
g_return_if_fail (connection != NULL);
g_return_if_fail (list != NULL); g_return_if_fail (list != NULL);
g_return_if_fail (data != NULL); g_return_if_fail (data != NULL);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getNetworks"))) dbus_mgr = nm_dbus_manager_get (NULL);
return; dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
dbus_message_append_args (message, DBUS_TYPE_INT32, &type_as_int32, DBUS_TYPE_INVALID); if (!dbus_connection) {
nm_warning ("could not get the dbus connection.");
goto out;
}
message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
NMI_DBUS_PATH,
NMI_DBUS_INTERFACE,
"getNetworks");
if (!message) {
nm_warning ("could not allocate the dbus message.");
goto out;
}
dbus_message_append_args (message,
DBUS_TYPE_INT32, &type_as_int32,
DBUS_TYPE_INVALID);
cb_data = g_slice_new0 (GetNetworksCBData); cb_data = g_slice_new0 (GetNetworksCBData);
cb_data->data = data; cb_data->data = data;
nm_ap_list_ref (list); nm_ap_list_ref (list);
cb_data->list = list; cb_data->list = list;
nm_dbus_send_with_callback (cb_data->data->dbus_connection, message, nm_dbus_send_with_callback (dbus_connection,
(DBusPendingCallNotifyFunction) nm_dbus_get_networks_cb, cb_data, message,
(DBusFreeFunction) free_get_networks_cb_data, __func__); (DBusPendingCallNotifyFunction) nm_dbus_get_networks_cb,
cb_data,
(DBusFreeFunction) free_get_networks_cb_data,
__func__);
dbus_message_unref (message); dbus_message_unref (message);
out:
g_object_unref (dbus_mgr);
} }
@@ -588,31 +674,53 @@ void nm_dbus_update_allowed_networks (DBusConnection *connection, NMAccessPointL
* Update all networks of a specific type from NetworkManagerInfo * Update all networks of a specific type from NetworkManagerInfo
* *
*/ */
void nm_dbus_update_one_allowed_network (DBusConnection *connection, const char *network, NMData *data) void
nm_dbus_update_one_allowed_network (const char *network,
NMData *data)
{ {
NMDBusManager * dbus_mgr = NULL;
DBusConnection * dbus_connection;
DBusMessage * message; DBusMessage * message;
dbus_int32_t type_as_int32 = NETWORK_TYPE_ALLOWED; dbus_int32_t type_as_int32 = NETWORK_TYPE_ALLOWED;
GetOneNetworkCBData * cb_data = NULL; GetOneNetworkCBData * cb_data = NULL;
g_return_if_fail (connection != NULL);
g_return_if_fail (data != NULL); g_return_if_fail (data != NULL);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getNetworkProperties"))) dbus_mgr = nm_dbus_manager_get (NULL);
{ dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
nm_warning ("nm_dbus_update_one_allowed_network(): Couldn't allocate the dbus message"); if (!dbus_connection) {
return; nm_warning ("could not get the dbus connection.");
goto out;
}
message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
NMI_DBUS_PATH,
NMI_DBUS_INTERFACE,
"getNetworkProperties");
if (!message) {
nm_warning ("couldn't allocate the dbus message.");
goto out;
} }
dbus_message_append_args (message, DBUS_TYPE_STRING, &network, DBUS_TYPE_INT32, &type_as_int32, DBUS_TYPE_INVALID);
cb_data = g_slice_new0 (GetOneNetworkCBData); cb_data = g_slice_new0 (GetOneNetworkCBData);
cb_data->data = data; cb_data->data = data;
cb_data->network = g_strdup (network); cb_data->network = g_strdup (network);
cb_data->list = data->allowed_ap_list; cb_data->list = data->allowed_ap_list;
nm_dbus_send_with_callback (cb_data->data->dbus_connection, message, dbus_message_append_args (message,
(DBusPendingCallNotifyFunction) nm_dbus_get_network_data_cb, cb_data, DBUS_TYPE_STRING, &network,
(DBusFreeFunction) free_get_one_network_cb_data, __func__); DBUS_TYPE_INT32, &type_as_int32,
DBUS_TYPE_INVALID);
nm_dbus_send_with_callback (dbus_connection,
message,
(DBusPendingCallNotifyFunction) nm_dbus_get_network_data_cb,
cb_data,
(DBusFreeFunction) free_get_one_network_cb_data,
__func__);
dbus_message_unref (message); dbus_message_unref (message);
out:
g_object_unref (dbus_mgr);
} }

View File

@@ -25,17 +25,15 @@
#include "NetworkManager.h" #include "NetworkManager.h"
#include "NetworkManagerAP.h" #include "NetworkManagerAP.h"
void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest *req, const gboolean new_key); void nm_dbus_get_user_key_for_network (NMActRequest *req, const gboolean new_key);
void nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection, NMActRequest *req); void nm_dbus_cancel_get_user_key_for_network (NMActRequest *req);
NMAccessPoint *nm_dbus_get_network_object (DBusConnection *connection, NMNetworkType type, const char *network); void nm_dbus_update_network_info (NMAccessPoint *ap, const gboolean user_requested);
gboolean nm_dbus_update_network_info (DBusConnection *connection, NMAccessPoint *ap, const gboolean user_requested); void nm_dbus_update_one_allowed_network (const char *network, NMData *data);
void nm_dbus_update_one_allowed_network (DBusConnection *connection, const char *network, NMData *data); void nm_dbus_update_allowed_networks (NMAccessPointList *list, NMData *data);
void nm_dbus_update_allowed_networks (DBusConnection *connection, NMAccessPointList *list, NMData *data);
#endif /* NM_DBUS_NMI_H */ #endif /* NM_DBUS_NMI_H */

View File

@@ -198,7 +198,7 @@ nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self)
automatic = !nm_act_request_get_user_requested (req); automatic = !nm_act_request_get_user_requested (req);
app_data = nm_device_get_app_data (NM_DEVICE (self)); app_data = nm_device_get_app_data (NM_DEVICE (self));
g_assert (app_data); g_assert (app_data);
nm_dbus_update_network_info (app_data->dbus_connection, ap, automatic); nm_dbus_update_network_info (ap, automatic);
} }
} }
@@ -213,7 +213,6 @@ nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self)
static void static void
nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self) nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self)
{ {
NMData * app_data;
gboolean has_range = FALSE; gboolean has_range = FALSE;
NMSock * sk; NMSock * sk;
iwrange range; iwrange range;
@@ -226,14 +225,10 @@ nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self)
if (self->priv->scanning) if (self->priv->scanning)
return; return;
app_data = nm_device_get_app_data (NM_DEVICE (self));
g_assert (app_data);
/* If we aren't the active device, we don't really have a signal strength /* If we aren't the active device, we don't really have a signal strength
* that would mean anything. * that would mean anything.
*/ */
if (!nm_device_get_act_request (NM_DEVICE (self))) if (!nm_device_get_act_request (NM_DEVICE (self))) {
{
self->priv->strength = -1; self->priv->strength = -1;
return; return;
} }
@@ -266,7 +261,7 @@ nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self)
self->priv->invalid_strength_counter = 0; self->priv->invalid_strength_counter = 0;
if (percent != self->priv->strength) if (percent != self->priv->strength)
nm_dbus_signal_device_strength_change (app_data->dbus_connection, self, percent); nm_dbus_signal_device_strength_change (self, percent);
self->priv->strength = percent; self->priv->strength = percent;
} }
@@ -1902,7 +1897,7 @@ convert_scan_results (gpointer user_data)
{ {
if ((outdated_ap = (NMAccessPoint *)(elt->data))) if ((outdated_ap = (NMAccessPoint *)(elt->data)))
{ {
nm_dbus_signal_wireless_network_change (app_data->dbus_connection, self, outdated_ap, NETWORK_STATUS_DISAPPEARED, -1); nm_dbus_signal_wireless_network_change (self, outdated_ap, NETWORK_STATUS_DISAPPEARED, -1);
nm_ap_list_remove_ap (nm_device_802_11_wireless_ap_list_get (self), outdated_ap); nm_ap_list_remove_ap (nm_device_802_11_wireless_ap_list_get (self), outdated_ap);
} }
} }
@@ -2528,7 +2523,6 @@ link_timeout_cb (gpointer user_data)
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data); NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
NMActRequest * req = nm_device_get_act_request (dev); NMActRequest * req = nm_device_get_act_request (dev);
NMAccessPoint * ap = nm_act_request_get_ap (req); NMAccessPoint * ap = nm_act_request_get_ap (req);
NMData * data = nm_device_get_app_data (dev);
gboolean has_key; gboolean has_key;
g_assert (dev); g_assert (dev);
@@ -2544,7 +2538,7 @@ link_timeout_cb (gpointer user_data)
nm_info ("Activation (%s/wireless): disconnected during association," nm_info ("Activation (%s/wireless): disconnected during association,"
" asking for new key.", nm_device_get_iface (dev)); " asking for new key.", nm_device_get_iface (dev));
supplicant_remove_timeout(self); supplicant_remove_timeout(self);
nm_dbus_get_user_key_for_network (data->dbus_connection, req, TRUE); nm_dbus_get_user_key_for_network (req, TRUE);
} }
else else
{ {
@@ -2657,7 +2651,6 @@ supplicant_timeout_cb (gpointer user_data)
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data); NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
NMActRequest * req = nm_device_get_act_request (dev); NMActRequest * req = nm_device_get_act_request (dev);
NMAccessPoint * ap = nm_act_request_get_ap (req); NMAccessPoint * ap = nm_act_request_get_ap (req);
NMData * data = nm_device_get_app_data (dev);
gboolean has_key; gboolean has_key;
g_assert (self); g_assert (self);
@@ -2672,7 +2665,7 @@ supplicant_timeout_cb (gpointer user_data)
/* Activation failed, we must have bad encryption key */ /* Activation failed, we must have bad encryption key */
nm_info ("Activation (%s/wireless): association took too long (>%us), asking for new key.", nm_info ("Activation (%s/wireless): association took too long (>%us), asking for new key.",
nm_device_get_iface (dev), get_supplicant_timeout (self)); nm_device_get_iface (dev), get_supplicant_timeout (self));
nm_dbus_get_user_key_for_network (data->dbus_connection, req, TRUE); nm_dbus_get_user_key_for_network (req, TRUE);
} }
else else
{ {
@@ -3015,7 +3008,6 @@ real_act_stage2_config (NMDevice *dev,
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev); NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev);
NMAccessPoint * ap = nm_act_request_get_ap (req); NMAccessPoint * ap = nm_act_request_get_ap (req);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
NMData * data = nm_act_request_get_data (req);
const char * iface; const char * iface;
gboolean ask_user = FALSE; gboolean ask_user = FALSE;
@@ -3026,7 +3018,7 @@ real_act_stage2_config (NMDevice *dev,
/* If we need an encryption key, get one */ /* If we need an encryption key, get one */
if (ap_need_key (self, ap, &ask_user)) if (ap_need_key (self, ap, &ask_user))
{ {
nm_dbus_get_user_key_for_network (data->dbus_connection, req, ask_user); nm_dbus_get_user_key_for_network (req, ask_user);
return NM_ACT_STAGE_RETURN_POSTPONE; return NM_ACT_STAGE_RETURN_POSTPONE;
} }
@@ -3162,7 +3154,7 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
/* Activation failed, we must have bad encryption key */ /* Activation failed, we must have bad encryption key */
nm_debug ("Activation (%s/wireless): could not get IP configuration info for '%s', asking for new key.", nm_debug ("Activation (%s/wireless): could not get IP configuration info for '%s', asking for new key.",
nm_device_get_iface (dev), nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)"); nm_device_get_iface (dev), nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)");
nm_dbus_get_user_key_for_network (data->dbus_connection, req, TRUE); nm_dbus_get_user_key_for_network (req, TRUE);
ret = NM_ACT_STAGE_RETURN_POSTPONE; ret = NM_ACT_STAGE_RETURN_POSTPONE;
} }
else if (nm_ap_get_mode (ap) == IW_MODE_ADHOC) else if (nm_ap_get_mode (ap) == IW_MODE_ADHOC)
@@ -3215,7 +3207,7 @@ real_activation_success_handler (NMDevice *dev,
if (!nm_ap_get_address (ap) || !nm_ethernet_address_is_valid (nm_ap_get_address (ap))) if (!nm_ap_get_address (ap) || !nm_ethernet_address_is_valid (nm_ap_get_address (ap)))
nm_ap_set_address (ap, &addr); nm_ap_set_address (ap, &addr);
nm_dbus_update_network_info (app_data->dbus_connection, ap, automatic); nm_dbus_update_network_info (ap, automatic);
} }
@@ -3271,10 +3263,7 @@ real_activation_cancel_handler (NMDevice *dev,
parent_class->activation_cancel_handler (dev, req); parent_class->activation_cancel_handler (dev, req);
if (nm_act_request_get_stage (req) == NM_ACT_STAGE_NEED_USER_KEY) if (nm_act_request_get_stage (req) == NM_ACT_STAGE_NEED_USER_KEY)
{ nm_dbus_cancel_get_user_key_for_network (req);
NMData *data = nm_device_get_app_data (dev);
nm_dbus_cancel_get_user_key_for_network (data->dbus_connection, req);
}
} }
@@ -3476,13 +3465,12 @@ add_new_ap_to_device_list (NMDevice80211Wireless *dev,
/* If the AP is not broadcasting its ESSID, try to fill it in here from our /* If the AP is not broadcasting its ESSID, try to fill it in here from our
* allowed list where we cache known MAC->ESSID associations. * allowed list where we cache known MAC->ESSID associations.
*/ */
if (!nm_ap_get_essid (ap)) if (!nm_ap_get_essid (ap)) {
{
NMData * app_data; NMData * app_data;
nm_ap_set_broadcast (ap, FALSE); nm_ap_set_broadcast (ap, FALSE);
app_data = nm_device_get_app_data (NM_DEVICE (dev)); app_data = nm_device_get_app_data (NM_DEVICE (dev));
nm_ap_list_copy_one_essid_by_address (app_data, dev, ap, app_data->allowed_ap_list); nm_ap_list_copy_one_essid_by_address (dev, ap, app_data->allowed_ap_list);
} }
/* Add the AP to the device's AP list */ /* Add the AP to the device's AP list */

View File

@@ -23,6 +23,14 @@
#define NM_DEVICE_PRIVATE_H #define NM_DEVICE_PRIVATE_H
#include "nm-device.h" #include "nm-device.h"
#include "NetworkManagerMain.h"
typedef struct NMDbusCBData {
NMDevice * dev;
NMAccessPoint * ap;
NMData * data;
} NMDbusCBData;
gboolean nm_device_is_activated (NMDevice *dev); gboolean nm_device_is_activated (NMDevice *dev);

View File

@@ -1,3 +1,4 @@
VOID:OBJECT VOID:OBJECT
VOID:OBJECT,POINTER,INT VOID:OBJECT,POINTER,INT
VOID:POINTER VOID:POINTER
VOID:POINTER,STRING,STRING,STRING

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,6 @@ void nm_dbus_vpn_signal_vpn_connection_state_change (DBusConnection *con, NMV
char ** nm_dbus_vpn_get_routes (DBusConnection *connection, NMVPNConnection *vpn, int *num_items); char ** nm_dbus_vpn_get_routes (DBusConnection *connection, NMVPNConnection *vpn, int *num_items);
NMDbusMethodList * nm_dbus_vpn_methods_setup (void); NMDbusMethodList * nm_dbus_vpn_methods_setup (NMVPNManager *mgr);
#endif #endif

View File

@@ -24,6 +24,8 @@
#include <string.h> #include <string.h>
#include "nm-vpn-act-request.h" #include "nm-vpn-act-request.h"
#include "nm-dbus-vpn.h" #include "nm-dbus-vpn.h"
#include "nm-dbus-manager.h"
#include "nm-utils.h"
struct NMVPNActRequest struct NMVPNActRequest
@@ -233,10 +235,20 @@ void nm_vpn_act_request_set_stage (NMVPNActRequest *req, NMVPNActStage stage)
old_stage = req->stage; old_stage = req->stage;
if (old_stage != stage) if (old_stage != stage)
{ {
DBusConnection *dbus_connection = nm_vpn_service_get_dbus_connection (req->service); NMDBusManager *dbus_mgr;
DBusConnection *dbus_connection;
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (dbus_connection) {
req->stage = stage; req->stage = stage;
nm_dbus_vpn_signal_vpn_connection_state_change (dbus_connection, req->vpn, req->stage); nm_dbus_vpn_signal_vpn_connection_state_change (dbus_connection,
req->vpn,
req->stage);
} else {
nm_warning ("could not get dbus connection.");
}
g_object_unref (dbus_mgr);
} }
} }

View File

@@ -23,6 +23,8 @@
#include <string.h> #include <string.h>
#include "nm-vpn-connection.h" #include "nm-vpn-connection.h"
#include "nm-dbus-vpn.h" #include "nm-dbus-vpn.h"
#include "nm-dbus-manager.h"
#include "nm-utils.h"
#include "NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
@@ -36,7 +38,6 @@ struct NMVPNConnection
char * service_name; char * service_name;
NMNamedManager *named_manager; NMNamedManager *named_manager;
DBusConnection *dbus_connection;
/* Change when connection is activated/deactivated */ /* Change when connection is activated/deactivated */
NMDevice * parent_dev; NMDevice * parent_dev;
@@ -50,8 +51,11 @@ static void nm_vpn_connection_set_ip4_config (NMVPNConnection *con, NMIP4Config
static void nm_vpn_connection_set_parent_device(NMVPNConnection *con, NMDevice *parent_dev); static void nm_vpn_connection_set_parent_device(NMVPNConnection *con, NMDevice *parent_dev);
NMVPNConnection *nm_vpn_connection_new (const char *name, const char *user_name, const char *service_name, NMVPNConnection *
NMNamedManager *named_manager, DBusConnection *dbus_connection) nm_vpn_connection_new (const char *name,
const char *user_name,
const char *service_name,
NMNamedManager *named_manager)
{ {
NMVPNConnection *connection; NMVPNConnection *connection;
@@ -59,7 +63,6 @@ NMVPNConnection *nm_vpn_connection_new (const char *name, const char *user_name,
g_return_val_if_fail (user_name != NULL, NULL); g_return_val_if_fail (user_name != NULL, NULL);
g_return_val_if_fail (service_name != NULL, NULL); g_return_val_if_fail (service_name != NULL, NULL);
g_return_val_if_fail (named_manager != NULL, NULL); g_return_val_if_fail (named_manager != NULL, NULL);
g_return_val_if_fail (dbus_connection != NULL, NULL);
connection = g_malloc0 (sizeof (NMVPNConnection)); connection = g_malloc0 (sizeof (NMVPNConnection));
connection->refcount = 1; connection->refcount = 1;
@@ -71,8 +74,6 @@ NMVPNConnection *nm_vpn_connection_new (const char *name, const char *user_name,
g_object_ref (named_manager); g_object_ref (named_manager);
connection->named_manager = named_manager; connection->named_manager = named_manager;
connection->dbus_connection = dbus_connection;
return connection; return connection;
} }
@@ -117,28 +118,46 @@ void nm_vpn_connection_activate (NMVPNConnection *connection)
} }
gboolean nm_vpn_connection_set_config (NMVPNConnection *connection, const char *vpn_iface, NMDevice *dev, NMIP4Config *ip4_config) gboolean
nm_vpn_connection_set_config (NMVPNConnection *connection,
const char *vpn_iface,
NMDevice *dev,
NMIP4Config *ip4_config)
{ {
gboolean success = FALSE; gboolean success = FALSE;
int num_routes = -1; int num_routes = -1;
char ** routes; char ** routes;
DBusConnection *dbus_connection;
NMDBusManager * dbus_mgr = NULL;
g_return_val_if_fail (connection != NULL, FALSE); g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (ip4_config != NULL, FALSE); g_return_val_if_fail (ip4_config != NULL, FALSE);
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_warning ("couldn't get dbus connection.");
goto out;
}
/* IPsec VPNs will not have tunnel device */ /* IPsec VPNs will not have tunnel device */
if (vpn_iface != NULL && strlen (vpn_iface)) if (vpn_iface != NULL && strlen (vpn_iface))
nm_vpn_connection_set_vpn_iface (connection, vpn_iface); nm_vpn_connection_set_vpn_iface (connection, vpn_iface);
nm_vpn_connection_set_parent_device (connection, dev); nm_vpn_connection_set_parent_device (connection, dev);
nm_vpn_connection_set_ip4_config (connection, ip4_config); nm_vpn_connection_set_ip4_config (connection, ip4_config);
routes = nm_dbus_vpn_get_routes (connection->dbus_connection, connection, &num_routes); routes = nm_dbus_vpn_get_routes (dbus_connection, connection, &num_routes);
nm_system_vpn_device_set_from_ip4_config (connection->named_manager, connection->parent_dev, nm_system_vpn_device_set_from_ip4_config (connection->named_manager,
connection->vpn_iface, connection->ip4_config, routes, num_routes); connection->parent_dev,
connection->vpn_iface,
connection->ip4_config,
routes,
num_routes);
g_strfreev(routes); g_strfreev(routes);
success = TRUE; success = TRUE;
out:
return success; return success;
} }

View File

@@ -27,7 +27,7 @@ typedef struct NMVPNConnection NMVPNConnection;
NMVPNConnection * nm_vpn_connection_new (const char *name, const char *user_name, const char *service_name, NMVPNConnection * nm_vpn_connection_new (const char *name, const char *user_name, const char *service_name,
NMNamedManager *named_manager, DBusConnection *dbus_connection); NMNamedManager *named_manager);
void nm_vpn_connection_ref (NMVPNConnection *con); void nm_vpn_connection_ref (NMVPNConnection *con);
void nm_vpn_connection_unref (NMVPNConnection *con); void nm_vpn_connection_unref (NMVPNConnection *con);

View File

@@ -32,6 +32,7 @@
#include "nm-vpn-service.h" #include "nm-vpn-service.h"
#include "nm-dbus-vpn.h" #include "nm-dbus-vpn.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-dbus-manager.h"
#define VPN_SERVICE_FILE_PATH SYSCONFDIR"/NetworkManager/VPN" #define VPN_SERVICE_FILE_PATH SYSCONFDIR"/NetworkManager/VPN"
@@ -42,6 +43,7 @@ struct NMVPNManager
GSList * connections; GSList * connections;
NMVPNActRequest * act_req; NMVPNActRequest * act_req;
NMDbusMethodList * dbus_methods;
}; };
static void load_services (NMVPNManager *manager, GHashTable *table); static void load_services (NMVPNManager *manager, GHashTable *table);
@@ -55,15 +57,24 @@ static void load_services (NMVPNManager *manager, GHashTable *table);
NMVPNManager *nm_vpn_manager_new (NMData *app_data) NMVPNManager *nm_vpn_manager_new (NMData *app_data)
{ {
NMVPNManager * manager; NMVPNManager * manager;
NMDBusManager * dbus_mgr;
g_return_val_if_fail (app_data != NULL, NULL); g_return_val_if_fail (app_data != NULL, NULL);
manager = g_malloc0 (sizeof (NMVPNManager)); manager = g_slice_new0 (NMVPNManager);
manager->app_data = app_data; manager->app_data = app_data;
manager->service_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) nm_vpn_service_unref); manager->service_table = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL,
(GDestroyNotify) nm_vpn_service_unref);
load_services (manager, manager->service_table); load_services (manager, manager->service_table);
manager->dbus_methods = nm_dbus_vpn_methods_setup (manager);
dbus_mgr = nm_dbus_manager_get (NULL);
nm_dbus_manager_register_method_list (dbus_mgr, manager->dbus_methods);
g_object_unref (dbus_mgr);
return manager; return manager;
} }
@@ -86,8 +97,10 @@ void nm_vpn_manager_dispose (NMVPNManager *manager)
g_hash_table_destroy (manager->service_table); g_hash_table_destroy (manager->service_table);
nm_dbus_method_list_unref (manager->dbus_methods);
memset (manager, 0, sizeof (NMVPNManager)); memset (manager, 0, sizeof (NMVPNManager));
g_free (manager); g_slice_free (NMVPNManager, manager);
} }
@@ -157,10 +170,17 @@ GSList *nm_vpn_manager_vpn_connection_list_copy (NMVPNManager *manager)
* Add a new VPN connection if none already exits, otherwise update the existing one. * Add a new VPN connection if none already exits, otherwise update the existing one.
* *
*/ */
NMVPNConnection *nm_vpn_manager_add_connection (NMVPNManager *manager, const char *name, const char *service_name, const char *user_name) NMVPNConnection *
nm_vpn_manager_add_connection (NMVPNManager *manager,
const char *name,
const char *service_name,
const char *user_name)
{ {
NMVPNConnection * connection = NULL; NMVPNConnection * connection = NULL;
NMVPNService * service; NMVPNService * service;
DBusConnection * dbus_connection;
NMDBusManager * dbus_mgr = NULL;
GSList * elt;
g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL); g_return_val_if_fail (name != NULL, NULL);
@@ -171,28 +191,44 @@ NMVPNConnection *nm_vpn_manager_add_connection (NMVPNManager *manager, const cha
if (!(service = nm_vpn_manager_find_service_by_name (manager, service_name))) if (!(service = nm_vpn_manager_find_service_by_name (manager, service_name)))
return NULL; return NULL;
if ((connection = nm_vpn_connection_new (name, user_name, service_name, manager->app_data->named_manager, dbus_mgr = nm_dbus_manager_get (NULL);
manager->app_data->dbus_connection))) dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
{ if (!dbus_connection) {
GSList *elt; nm_warning ("couldn't get dbus connection.");
goto out;
}
connection = nm_vpn_connection_new (name,
user_name,
service_name,
manager->app_data->named_manager);
if (!connection) {
nm_warning ("couldn't create VPN connecton for '%s (%s).",
name,
service_name);
goto out;
}
/* Remove the existing connection if found */ /* Remove the existing connection if found */
for (elt = manager->connections; elt; elt = g_slist_next (elt)) for (elt = manager->connections; elt; elt = g_slist_next (elt)) {
{
NMVPNConnection *con = (NMVPNConnection *)(elt->data); NMVPNConnection *con = (NMVPNConnection *)(elt->data);
if (con && nm_vpn_connection_get_name (con) && (strcmp (nm_vpn_connection_get_name (con), name) == 0))
{ if (!con || !nm_vpn_connection_get_name (con))
continue;
if (strcmp (nm_vpn_connection_get_name (con), name) != 0)
continue;
manager->connections = g_slist_remove_link (manager->connections, elt); manager->connections = g_slist_remove_link (manager->connections, elt);
nm_vpn_connection_unref (con); nm_vpn_connection_unref (con);
g_slist_free (elt); g_slist_free (elt);
} }
}
/* Add in the updated connection */ /* Add in the updated connection */
manager->connections = g_slist_append (manager->connections, connection); manager->connections = g_slist_append (manager->connections, connection);
}
out:
g_object_unref (dbus_mgr);
return connection; return connection;
} }
@@ -267,66 +303,6 @@ NMVPNActRequest *nm_vpn_manager_get_vpn_act_request (NMVPNManager *manager)
} }
static inline gboolean same_service_name (NMVPNService *service, NMVPNConnection *vpn)
{
g_return_val_if_fail (service != NULL, FALSE);
g_return_val_if_fail (vpn != NULL, FALSE);
return (!strcmp (nm_vpn_service_get_service_name (service), nm_vpn_connection_get_service_name (vpn)));
}
/*
* nm_vpn_manager_process_signal
*
* Possibly process a signal from the bus, if it comes from the currently
* active VPN daemon, if any. Return TRUE if processed, FALSE if not.
*
*/
gboolean nm_vpn_manager_process_signal (NMVPNManager *manager, DBusMessage *message)
{
const char * service_name;
NMVPNService * service;
gboolean handled = FALSE;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (message != NULL, FALSE);
service_name = dbus_message_get_interface (message);
if ((service = nm_vpn_manager_find_service_by_name (manager, service_name)))
{
nm_vpn_service_process_signal (service, manager->act_req, message);
handled = TRUE;
}
return handled;
}
/*
* nm_vpn_manager_process_name_owner_changed
*
* Respond to "service created"/"service deleted" signals from dbus for our active VPN daemon.
*
*/
gboolean nm_vpn_manager_process_name_owner_changed (NMVPNManager *manager, const char *changed_service_name, const char *old_owner, const char *new_owner)
{
NMVPNService * service;
gboolean handled = FALSE;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (changed_service_name != NULL, FALSE);
if ((service = nm_vpn_manager_find_service_by_name (manager, changed_service_name)))
{
nm_vpn_service_name_owner_changed (service, manager->act_req, old_owner, new_owner);
handled = TRUE;
}
return handled;
}
/* /*
* nm_vpn_manager_activate_vpn_connection * nm_vpn_manager_activate_vpn_connection
* *

View File

@@ -44,9 +44,6 @@ void nm_vpn_manager_deactivate_vpn_connection (NMVPNManager *manager, NMDevic
NMVPNConnection * nm_vpn_manager_find_connection_by_name (NMVPNManager *manager, const char *con_name); NMVPNConnection * nm_vpn_manager_find_connection_by_name (NMVPNManager *manager, const char *con_name);
NMVPNService * nm_vpn_manager_find_service_by_name (NMVPNManager *manager, const char *service_name); NMVPNService * nm_vpn_manager_find_service_by_name (NMVPNManager *manager, const char *service_name);
gboolean nm_vpn_manager_process_signal (NMVPNManager *manager, DBusMessage *signal);
gboolean nm_vpn_manager_process_name_owner_changed (NMVPNManager *manager, const char *service, const char *old_owner, const char *new_owner);
void nm_vpn_manager_schedule_vpn_activation_failed(NMVPNManager *manager, NMVPNActRequest *req); void nm_vpn_manager_schedule_vpn_activation_failed(NMVPNManager *manager, NMVPNActRequest *req);
void nm_vpn_manager_schedule_vpn_connection_died (NMVPNManager *manager, NMVPNActRequest *req); void nm_vpn_manager_schedule_vpn_connection_died (NMVPNManager *manager, NMVPNActRequest *req);

View File

@@ -25,12 +25,16 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <dbus/dbus.h> #include <dbus/dbus.h>
#include <sys/types.h>
#include <signal.h>
#include "NetworkManagerDbus.h" #include "NetworkManagerDbus.h"
#include "nm-dbus-vpn.h" #include "nm-dbus-vpn.h"
#include "nm-vpn-service.h" #include "nm-vpn-service.h"
#include "nm-vpn-act-request.h" #include "nm-vpn-act-request.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "dbus-dict-helpers.h" #include "dbus-dict-helpers.h"
#include "nm-dbus-manager.h"
/* define this for getting VPN debug messages */ /* define this for getting VPN debug messages */
#undef NM_DEBUG_VPN_CONFIG #undef NM_DEBUG_VPN_CONFIG
@@ -40,7 +44,10 @@ struct NMVPNService
int refcount; int refcount;
NMVPNManager * manager; NMVPNManager * manager;
NMData * app_data; NMData * app_data;
gboolean watch_active; GPid pid;
gulong watch_id;
gulong dbus_con_watch_id;
NMDBusManager * dbus_mgr;
char * name; char * name;
char * service; char * service;
@@ -59,6 +66,21 @@ static void nm_vpn_service_schedule_stage2_daemon_wait (NMVPNService *service, N
static void nm_vpn_service_schedule_stage4_ip_config_get_timeout (NMVPNService *service, NMVPNActRequest *req); static void nm_vpn_service_schedule_stage4_ip_config_get_timeout (NMVPNService *service, NMVPNActRequest *req);
static void nm_vpn_service_cancel_callback (NMVPNService *service, NMVPNActRequest *req); static void nm_vpn_service_cancel_callback (NMVPNService *service, NMVPNActRequest *req);
static gboolean nm_vpn_service_process_signal (DBusConnection *connection,
DBusMessage *message,
gpointer user_data);
static void nm_vpn_service_name_owner_changed (NMDBusManager *mgr,
DBusConnection *connection,
const char *name,
const char *old,
const char *new,
gpointer user_data);
static void nm_vpn_service_dbus_connection_changed (NMDBusManager *mgr,
DBusConnection *connection,
gpointer user_data);
#ifdef NM_DEBUG_VPN_CONFIG #ifdef NM_DEBUG_VPN_CONFIG
static void print_vpn_config (NMIP4Config *config, static void print_vpn_config (NMIP4Config *config,
const char *tundev, const char *tundev,
@@ -80,6 +102,7 @@ NMVPNService *nm_vpn_service_new (NMVPNManager *manager, NMData *app_data)
service->state = NM_VPN_STATE_SHUTDOWN; service->state = NM_VPN_STATE_SHUTDOWN;
service->app_data = app_data; service->app_data = app_data;
service->manager = manager; service->manager = manager;
service->dbus_mgr = nm_dbus_manager_get (NULL);
return service; return service;
} }
@@ -99,9 +122,11 @@ void nm_vpn_service_unref (NMVPNService *service)
service->refcount--; service->refcount--;
if (service->refcount <= 0) if (service->refcount <= 0)
{ {
nm_vpn_service_remove_watch (service);
g_free (service->name); g_free (service->name);
g_free (service->service); g_free (service->service);
g_free (service->program); g_free (service->program);
g_object_unref (service->dbus_mgr);
memset (service, 0, sizeof (NMVPNService)); memset (service, 0, sizeof (NMVPNService));
g_free (service); g_free (service);
} }
@@ -143,7 +168,7 @@ void nm_vpn_service_set_service_name (NMVPNService *service, const char *name)
service->service = g_strdup (name); service->service = g_strdup (name);
/* If the VPN daemon is currently running, tell it to stop */ /* If the VPN daemon is currently running, tell it to stop */
if (!dbus_bus_name_has_owner (service->app_data->dbus_connection, service->service, NULL)) if (nm_dbus_manager_name_has_owner (service->dbus_mgr, service->service))
nm_vpn_service_stop_connection_internal (service); nm_vpn_service_stop_connection_internal (service);
} }
@@ -182,14 +207,6 @@ static void nm_vpn_service_set_state (NMVPNService *service, const NMVPNState st
} }
DBusConnection *nm_vpn_service_get_dbus_connection (NMVPNService *service)
{
g_return_val_if_fail (service != NULL, NULL);
return service->app_data->dbus_connection;
}
/* /*
* construct_op_from_service_name * construct_op_from_service_name
* *
@@ -283,7 +300,7 @@ void nm_vpn_service_start_connection (NMVPNService *service, NMVPNActRequest *re
/* Start the daemon if it's not already running */ /* Start the daemon if it's not already running */
nm_vpn_act_request_ref (req); nm_vpn_act_request_ref (req);
if (!dbus_bus_name_has_owner (service->app_data->dbus_connection, service->service, NULL)) if (!nm_dbus_manager_name_has_owner (service->dbus_mgr, service->service))
nm_vpn_service_schedule_stage1_daemon_exec (service, req); nm_vpn_service_schedule_stage1_daemon_exec (service, req);
else else
nm_vpn_service_schedule_stage2_daemon_wait (service, req); nm_vpn_service_schedule_stage2_daemon_wait (service, req);
@@ -303,7 +320,7 @@ static gboolean nm_vpn_service_stage1_daemon_exec (gpointer user_data)
NMVPNConnection * vpn = NULL; NMVPNConnection * vpn = NULL;
GPtrArray * vpn_argv; GPtrArray * vpn_argv;
GError * error = NULL; GError * error = NULL;
GPid pid; gboolean launched = FALSE;
g_assert (req != NULL); g_assert (req != NULL);
@@ -320,17 +337,30 @@ static gboolean nm_vpn_service_stage1_daemon_exec (gpointer user_data)
g_ptr_array_add (vpn_argv, service->program); g_ptr_array_add (vpn_argv, service->program);
g_ptr_array_add (vpn_argv, NULL); g_ptr_array_add (vpn_argv, NULL);
if (!g_spawn_async (NULL, (char **) vpn_argv->pdata, NULL, 0, NULL, NULL, &pid, &error)) launched = g_spawn_async (NULL,
{ (char **) vpn_argv->pdata,
NULL,
0,
NULL,
NULL,
&service->pid,
&error);
if (!launched) {
g_ptr_array_free (vpn_argv, TRUE); g_ptr_array_free (vpn_argv, TRUE);
nm_warning ("(VPN Service %s): could not launch the VPN service. error: '%s'.", service->service, error->message); nm_warning ("(VPN Service %s): could not launch the VPN service. "
"error: '%s'.",
service->service,
error->message);
g_error_free (error); g_error_free (error);
nm_vpn_service_act_request_failed (service, req); nm_vpn_service_act_request_failed (service, req);
goto out; goto out;
} }
g_ptr_array_free (vpn_argv, TRUE); g_ptr_array_free (vpn_argv, TRUE);
nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) ran VPN service daemon %s (PID %d)", nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) ran VPN "
nm_vpn_connection_get_name (vpn), service->service, pid); "service daemon %s (PID %d)",
nm_vpn_connection_get_name (vpn),
service->service,
service->pid);
nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) complete.", nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) complete.",
nm_vpn_connection_get_name (vpn)); nm_vpn_connection_get_name (vpn));
@@ -391,8 +421,8 @@ static gboolean nm_vpn_service_stage2_daemon_wait (gpointer user_data)
nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) " nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) "
"waiting...", nm_vpn_connection_get_name (vpn)); "waiting...", nm_vpn_connection_get_name (vpn));
service_exists = dbus_bus_name_has_owner (service->app_data->dbus_connection, service_exists = nm_dbus_manager_name_has_owner (service->dbus_mgr,
service->service, NULL); service->service);
if (service_exists && (service->state == NM_VPN_STATE_STOPPED)) if (service_exists && (service->state == NM_VPN_STATE_STOPPED))
{ {
nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) " nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) "
@@ -525,6 +555,8 @@ static gboolean nm_vpn_service_stage3_connect (gpointer user_data)
dbus_uint32_t user_routes_count = 0; dbus_uint32_t user_routes_count = 0;
DBusMessage * message; DBusMessage * message;
DBusPendingCall * pcall = NULL; DBusPendingCall * pcall = NULL;
DBusConnection * dbus_connection;
gboolean success = FALSE;
g_assert (req != NULL); g_assert (req != NULL);
@@ -534,17 +566,28 @@ static gboolean nm_vpn_service_stage3_connect (gpointer user_data)
vpn = nm_vpn_act_request_get_connection (req); vpn = nm_vpn_act_request_get_connection (req);
g_assert (vpn != NULL); g_assert (vpn != NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
if (!dbus_connection) {
nm_warning ("VPN Activation (%s) Stage 3 of 4 (Connect) could not get "
"the DBus connection.",
nm_vpn_connection_get_name (vpn));
goto out;
}
nm_vpn_act_request_set_callback_id (req, 0); nm_vpn_act_request_set_callback_id (req, 0);
/* Send the start vpn request to the daemon */ /* Send the start vpn request to the daemon */
op = construct_op_from_service_name (service->service); op = construct_op_from_service_name (service->service);
message = dbus_message_new_method_call (service->service, op, service->service, "startConnection"); message = dbus_message_new_method_call (service->service,
op,
service->service,
"startConnection");
g_free (op); g_free (op);
if (!message) if (!message) {
{ nm_warning ("VPN Activation (%s) Stage 3 of 4 (Connect): couldn't "
nm_warning ("(VPN Service %s): couldn't allocate dbus message.", service->service); " allocate dbus message.",
nm_vpn_service_act_request_failed (service, req); service->service);
return FALSE; goto out;
} }
name = nm_vpn_connection_get_name (vpn); name = nm_vpn_connection_get_name (vpn);
@@ -566,17 +609,23 @@ static gboolean nm_vpn_service_stage3_connect (gpointer user_data)
DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &user_routes, user_routes_count, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &user_routes, user_routes_count,
DBUS_TYPE_INVALID); DBUS_TYPE_INVALID);
dbus_connection_send_with_reply (service->app_data->dbus_connection, message, &pcall, -1); dbus_connection_send_with_reply (dbus_connection, message, &pcall, -1);
if (pcall) if (pcall) {
{ dbus_pending_call_set_notify (pcall,
dbus_pending_call_set_notify (pcall, nm_vpn_service_stage3_connect_cb, req, NULL); nm_vpn_service_stage3_connect_cb,
req,
NULL);
nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) request sent," nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) request sent,"
" waiting for reply...", nm_vpn_connection_get_name (vpn)); " waiting for reply...",
nm_vpn_connection_get_name (vpn));
success = TRUE;
} }
else
nm_vpn_service_act_request_failed (service, req);
dbus_message_unref (message); dbus_message_unref (message);
out:
if (!success)
nm_vpn_service_act_request_failed (service, req);
return FALSE; return FALSE;
} }
@@ -712,6 +761,7 @@ get_dbus_string_helper (DBusMessageIter *iter,
static void static void
nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service, nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
NMVPNActRequest *req, NMVPNActRequest *req,
DBusConnection *dbus_connection,
DBusMessage *message) DBusMessage *message)
{ {
NMVPNConnection * vpn; NMVPNConnection * vpn;
@@ -722,7 +772,7 @@ nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
gboolean success = FALSE; gboolean success = FALSE;
DBusMessageIter iter; DBusMessageIter iter;
DBusMessageIter subiter; DBusMessageIter subiter;
NMIP4Config * config; NMIP4Config * config = NULL;
NMDevice * parent_dev; NMDevice * parent_dev;
g_return_if_fail (service != NULL); g_return_if_fail (service != NULL);
@@ -741,8 +791,7 @@ nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
dbus_message_iter_init (message, &iter); dbus_message_iter_init (message, &iter);
/* First arg: IP4 VPN Gateway address (UINT32) */ /* First arg: IP4 VPN Gateway address (UINT32) */
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) {
{
nm_warning ("Error: couldn't get IP4 VPN Gateway Address" nm_warning ("Error: couldn't get IP4 VPN Gateway Address"
" from VPN IP Config message."); " from VPN IP Config message.");
goto out; goto out;
@@ -772,15 +821,13 @@ nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
/* Sixth arg: IP4 DNS Server Addresses (ARRAY, UINT32) */ /* Sixth arg: IP4 DNS Server Addresses (ARRAY, UINT32) */
if ( !dbus_message_iter_next (&iter) if ( !dbus_message_iter_next (&iter)
|| (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)) {
{
nm_warning ("Error: couldn't get IP4 DNS Server Addresses" nm_warning ("Error: couldn't get IP4 DNS Server Addresses"
" from VPN IP Config message."); " from VPN IP Config message.");
goto out; goto out;
} }
dbus_message_iter_recurse (&iter, &subiter); dbus_message_iter_recurse (&iter, &subiter);
while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_UINT32) while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_UINT32) {
{
dbus_message_iter_get_basic (&subiter, &num); dbus_message_iter_get_basic (&subiter, &num);
if (num) if (num)
nm_ip4_config_add_nameserver (config, num); nm_ip4_config_add_nameserver (config, num);
@@ -789,15 +836,13 @@ nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
/* Seventh arg: IP4 NBNS Server Addresses (ARRAY, UINT32) */ /* Seventh arg: IP4 NBNS Server Addresses (ARRAY, UINT32) */
if ( !dbus_message_iter_next (&iter) if ( !dbus_message_iter_next (&iter)
|| (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)) {
{
nm_warning ("Error: couldn't get IP4 NBNS Server Addresses" nm_warning ("Error: couldn't get IP4 NBNS Server Addresses"
" from VPN IP Config message."); " from VPN IP Config message.");
goto out; goto out;
} }
dbus_message_iter_recurse (&iter, &subiter); dbus_message_iter_recurse (&iter, &subiter);
while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_UINT32) while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_UINT32) {
{
dbus_message_iter_get_basic (&subiter, &num); dbus_message_iter_get_basic (&subiter, &num);
/* We don't do anything with these yet */ /* We don't do anything with these yet */
dbus_message_iter_next (&subiter); dbus_message_iter_next (&subiter);
@@ -825,21 +870,24 @@ nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
if (!(parent_dev = nm_vpn_act_request_get_parent_dev (req))) if (!(parent_dev = nm_vpn_act_request_get_parent_dev (req)))
goto out; goto out;
if (nm_vpn_connection_set_config (vpn, tundev, parent_dev, config)) if (nm_vpn_connection_set_config (vpn, tundev, parent_dev, config)) {
{
nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) complete.", nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) complete.",
nm_vpn_connection_get_name (vpn)); nm_vpn_connection_get_name (vpn));
if (login_banner && strlen (login_banner)) if (login_banner && strlen (login_banner)) {
nm_dbus_vpn_signal_vpn_login_banner (service->app_data->dbus_connection, vpn, login_banner); nm_dbus_vpn_signal_vpn_login_banner (dbus_connection,
vpn,
login_banner);
}
success = TRUE; success = TRUE;
nm_vpn_service_activation_success (service, req); nm_vpn_service_activation_success (service, req);
} }
out: out:
if (!success) if (!success) {
{
nm_ip4_config_unref (config); nm_ip4_config_unref (config);
nm_warning ("(VPN Service %s): did not receive valid IP config information.", service->service); nm_warning ("(VPN Service %s): did not receive valid IP config "
"information.",
service->service);
nm_vpn_service_act_request_failed (service, req); nm_vpn_service_act_request_failed (service, req);
} }
} }
@@ -876,6 +924,7 @@ nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
NMIP4Config * config = NULL; NMIP4Config * config = NULL;
NMDevice * parent_dev; NMDevice * parent_dev;
NMUDictEntry entry = { .type = DBUS_TYPE_STRING }; NMUDictEntry entry = { .type = DBUS_TYPE_STRING };
DBusConnection *dbus_connection;
g_return_if_fail (service != NULL); g_return_if_fail (service != NULL);
g_return_if_fail (message != NULL); g_return_if_fail (message != NULL);
@@ -887,18 +936,27 @@ nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) reply received.", nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) reply received.",
nm_vpn_connection_get_name (vpn)); nm_vpn_connection_get_name (vpn));
dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
if (!dbus_connection) {
nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) could not "
"get the DBus connection.",
nm_vpn_connection_get_name (vpn));
goto out;
}
dbus_message_iter_init (message, &iter); dbus_message_iter_init (message, &iter);
/* If first arg is (UINT32) then this is an old type message */ /* If first arg is (UINT32) then this is an old type message */
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32) if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32) {
{
nm_warning ("Warning: VPN plugin is using the old IP4Config message type"); nm_warning ("Warning: VPN plugin is using the old IP4Config message type");
nm_vpn_service_stage4_ip4_config_get_old (service, req, message); nm_vpn_service_stage4_ip4_config_get_old (service,
req,
dbus_connection,
message);
return; return;
} }
if (!nmu_dbus_dict_open_read (&iter, &iter_dict)) if (!nmu_dbus_dict_open_read (&iter, &iter_dict)) {
{
nm_warning ("Warning: couldn't get config dictionary" nm_warning ("Warning: couldn't get config dictionary"
" from VPN IP Config message."); " from VPN IP Config message.");
goto out; goto out;
@@ -908,17 +966,14 @@ nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
nm_ip4_config_set_secondary (config, TRUE); nm_ip4_config_set_secondary (config, TRUE);
/* First arg: Dict Type */ /* First arg: Dict Type */
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
{
nm_warning ("Error: couldn't get configuration dict" nm_warning ("Error: couldn't get configuration dict"
" from VPN IP Config message."); " from VPN IP Config message.");
goto out; goto out;
} }
while (nmu_dbus_dict_has_dict_entry (&iter_dict)) while (nmu_dbus_dict_has_dict_entry (&iter_dict)) {
{ if (!nmu_dbus_dict_get_entry (&iter_dict, &entry)) {
if (!nmu_dbus_dict_get_entry (&iter_dict, &entry))
{
nm_warning ("Error: couldn't read dict entry" nm_warning ("Error: couldn't read dict entry"
" from VPN IP Config message."); " from VPN IP Config message.");
goto out; goto out;
@@ -964,12 +1019,14 @@ nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
if (!(parent_dev = nm_vpn_act_request_get_parent_dev (req))) if (!(parent_dev = nm_vpn_act_request_get_parent_dev (req)))
goto out; goto out;
if (nm_vpn_connection_set_config (vpn, tundev, parent_dev, config)) if (nm_vpn_connection_set_config (vpn, tundev, parent_dev, config)) {
{
nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) complete.", nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) complete.",
nm_vpn_connection_get_name (vpn)); nm_vpn_connection_get_name (vpn));
if (login_banner && strlen (login_banner)) if (login_banner && strlen (login_banner)) {
nm_dbus_vpn_signal_vpn_login_banner (service->app_data->dbus_connection, vpn, login_banner); nm_dbus_vpn_signal_vpn_login_banner (dbus_connection,
vpn,
login_banner);
}
success = TRUE; success = TRUE;
nm_vpn_service_activation_success (service, req); nm_vpn_service_activation_success (service, req);
} }
@@ -977,33 +1034,54 @@ nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
out: out:
if (tundev) g_free (tundev); if (tundev) g_free (tundev);
if (login_banner) g_free (login_banner); if (login_banner) g_free (login_banner);
if (!success) if (!success) {
{ if (config)
nm_ip4_config_unref (config); nm_ip4_config_unref (config);
nm_warning ("(VPN Service %s): did not receive valid IP config information.", service->service); nm_warning ("(VPN Service %s): did not receive valid IP config "
"information.",
service->service);
nm_vpn_service_act_request_failed (service, req); nm_vpn_service_act_request_failed (service, req);
} }
} }
static void nm_vpn_service_stop_connection_internal (NMVPNService *service) static void
nm_vpn_service_stop_connection_internal (NMVPNService *service)
{ {
DBusMessage * message; DBusConnection * dbus_connection;
char * op;
g_return_if_fail (service != NULL); g_return_if_fail (service != NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
if (dbus_connection) {
DBusMessage * message;
char * op;
/* Construct a new method call with the correct service and object path */ /* Construct a new method call with the correct service and object path */
op = construct_op_from_service_name (service->service); op = construct_op_from_service_name (service->service);
if ((message = dbus_message_new_method_call (service->service, op, service->service, "stopConnection"))) message = dbus_message_new_method_call (service->service,
{ op,
dbus_connection_send (service->app_data->dbus_connection, message, NULL); service->service,
"stopConnection");
g_free (op);
if (!message) {
nm_warning ("(VPN Service %s): couldn't allocate dbus message.",
service->service);
} else {
dbus_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message); dbus_message_unref (message);
} }
else } else {
nm_warning ("(VPN Service %s): couldn't allocate dbus message.", service->service); /* If we have the PID of the VPN service daemon, send it a TERM */
if (service->pid) {
g_free (op); kill (service->pid, SIGTERM);
service->pid = 0;
} else {
nm_warning ("(VPN Service %s): stop called, but did not have PID "
"for VPN service daemon.",
service->service);
}
}
} }
@@ -1033,42 +1111,46 @@ void nm_vpn_service_stop_connection (NMVPNService *service, NMVPNActRequest *req
} }
static void nm_vpn_service_add_watch (NMVPNService *service) static void
nm_vpn_service_add_watch (NMVPNService *service)
{ {
char * match_string = NULL;
g_return_if_fail (service != NULL); g_return_if_fail (service != NULL);
if (service->watch_active) if (service->watch_id)
return; return;
/* Add a dbus filter for this connection's service name so its signals /* Add a dbus filter for this connection's service name so its signals
* get delivered to us. * get delivered to us.
*/ */
match_string = g_strdup_printf ("type='signal'," nm_dbus_manager_register_signal_handler (service->dbus_mgr,
"interface='%s'," service->service,
"sender='%s'", service->service, service->service); NULL,
dbus_bus_add_match (service->app_data->dbus_connection, match_string, NULL); nm_vpn_service_process_signal,
g_free (match_string); service);
service->watch_active = TRUE; service->watch_id = g_signal_connect (service->dbus_mgr,
"name-owner-changed",
G_CALLBACK (nm_vpn_service_name_owner_changed),
service);
service->dbus_con_watch_id = g_signal_connect (service->dbus_mgr,
"dbus-connection-changed",
G_CALLBACK (nm_vpn_service_dbus_connection_changed),
service);
} }
static void nm_vpn_service_remove_watch (NMVPNService *service) static void
nm_vpn_service_remove_watch (NMVPNService *service)
{ {
char * match_string = NULL;
g_return_if_fail (service != NULL); g_return_if_fail (service != NULL);
if (!service->watch_active) if (!service->watch_id)
return; return;
match_string = g_strdup_printf ("type='signal'," nm_dbus_manager_remove_signal_handler (service->dbus_mgr, service->service);
"interface='%s'," g_signal_handler_disconnect (service->dbus_mgr, service->watch_id);
"sender='%s'", service->service, service->service); service->watch_id = 0;
dbus_bus_remove_match (service->app_data->dbus_connection, match_string, NULL); g_signal_handler_disconnect (service->dbus_mgr, service->dbus_con_watch_id);
g_free (match_string); service->dbus_con_watch_id = 0;
service->watch_active = FALSE;
} }
@@ -1080,50 +1162,91 @@ static inline gboolean same_service_name (NMVPNService *service, NMVPNConnection
return (!strcmp (nm_vpn_service_get_service_name (service), nm_vpn_connection_get_service_name (vpn))); return (!strcmp (nm_vpn_service_get_service_name (service), nm_vpn_connection_get_service_name (vpn)));
} }
static void
gboolean nm_vpn_service_name_owner_changed (NMVPNService *service, NMVPNActRequest *req, const char *old, const char *new) nm_vpn_service_dbus_connection_changed (NMDBusManager *mgr,
DBusConnection *dbus_connection,
gpointer user_data)
{ {
NMVPNService * service = (NMVPNService *) user_data;
g_return_if_fail (service != NULL);
if (!dbus_connection) {
NMVPNActRequest * req;
NMVPNConnection * vpn;
gboolean valid_vpn = FALSE;
/* Kill the VPN service since we can't talk to it anymore anyway */
nm_vpn_service_set_state (service, NM_VPN_STATE_SHUTDOWN);
nm_vpn_service_remove_watch (service);
req = nm_vpn_manager_get_vpn_act_request (service->manager);
if (req && (vpn = nm_vpn_act_request_get_connection (req)))
valid_vpn = same_service_name (service, vpn);
if (valid_vpn) {
nm_vpn_act_request_unref (req);
nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
}
}
}
static void
nm_vpn_service_name_owner_changed (NMDBusManager *mgr,
DBusConnection *connection,
const char *name,
const char *old,
const char *new,
gpointer user_data)
{
NMVPNService * service = (NMVPNService *) user_data;
NMVPNActRequest * req;
NMVPNConnection * vpn; NMVPNConnection * vpn;
gboolean valid_vpn = FALSE; gboolean valid_vpn = FALSE;
gboolean old_owner_good = (old && strlen (old)); gboolean old_owner_good = (old && strlen (old));
gboolean new_owner_good = (new && strlen (new)); gboolean new_owner_good = (new && strlen (new));
g_return_val_if_fail (service != NULL, FALSE); g_return_if_fail (service != NULL);
if (strcmp (name, service->service) != 0)
return;
req = nm_vpn_manager_get_vpn_act_request (service->manager);
if (req && (vpn = nm_vpn_act_request_get_connection (req))) if (req && (vpn = nm_vpn_act_request_get_connection (req)))
valid_vpn = same_service_name (service, vpn); valid_vpn = same_service_name (service, vpn);
if (!old_owner_good && new_owner_good) if (!old_owner_good && new_owner_good) {
{
/* VPN service started. */ /* VPN service started. */
nm_vpn_service_add_watch (service); nm_vpn_service_add_watch (service);
nm_vpn_service_set_state (service, NM_VPN_STATE_INIT); nm_vpn_service_set_state (service, NM_VPN_STATE_INIT);
} } else if (old_owner_good && !new_owner_good) {
else if (old_owner_good && !new_owner_good)
{
/* VPN service went away. */ /* VPN service went away. */
nm_vpn_service_set_state (service, NM_VPN_STATE_SHUTDOWN); nm_vpn_service_set_state (service, NM_VPN_STATE_SHUTDOWN);
nm_vpn_service_remove_watch (service); nm_vpn_service_remove_watch (service);
if (valid_vpn) if (valid_vpn) {
{
nm_vpn_act_request_unref (req); nm_vpn_act_request_unref (req);
nm_vpn_manager_schedule_vpn_connection_died (service->manager, req); nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
} }
} }
return TRUE;
} }
gboolean nm_vpn_service_process_signal (NMVPNService *service, NMVPNActRequest *req, DBusMessage *message) static gboolean
nm_vpn_service_process_signal (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{ {
NMVPNService * service = (NMVPNService *) user_data;
NMVPNConnection * vpn = NULL; NMVPNConnection * vpn = NULL;
NMVPNActRequest * req;
gboolean valid_vpn = FALSE; gboolean valid_vpn = FALSE;
g_return_val_if_fail (service != NULL, FALSE); g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (message != NULL, FALSE); g_return_val_if_fail (message != NULL, FALSE);
g_return_val_if_fail (service != NULL, FALSE);
req = nm_vpn_manager_get_vpn_act_request (service->manager);
if (req && (vpn = nm_vpn_act_request_get_connection (req))) if (req && (vpn = nm_vpn_act_request_get_connection (req)))
valid_vpn = same_service_name (service, vpn); valid_vpn = same_service_name (service, vpn);
@@ -1136,40 +1259,61 @@ gboolean nm_vpn_service_process_signal (NMVPNService *service, NMVPNActRequest *
const char * member = dbus_message_get_member (message); const char * member = dbus_message_get_member (message);
char * error_msg; char * error_msg;
if (valid_vpn) if (valid_vpn) {
{ if (!dbus_message_get_args (message,
if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &error_msg, DBUS_TYPE_INVALID)) NULL,
DBUS_TYPE_STRING, &error_msg,
DBUS_TYPE_INVALID)) {
error_msg = (char *) ""; error_msg = (char *) "";
nm_warning ("VPN failed for service '%s', signal '%s', with message '%s'.", service->service, member, error_msg);
nm_dbus_vpn_signal_vpn_failed (service->app_data->dbus_connection, member, vpn, error_msg);
/* Don't deal with VPN Connection stopping here, we'll do that when we get the STOPPED or STOPPING signal below */
} }
nm_warning ("VPN failed for service '%s', signal '%s', with "
" message '%s'.",
service->service,
member,
error_msg);
nm_dbus_vpn_signal_vpn_failed (connection, member, vpn, error_msg);
/* Don't deal with VPN Connection stopping here, we'll do that
* when we get the STOPPED or STOPPING signal below.
*/
} }
else if (dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_STATE_CHANGE)) } else if (dbus_message_is_signal (message, service->service,
{ NM_DBUS_VPN_SIGNAL_STATE_CHANGE)) {
dbus_uint32_t old_state_int; dbus_uint32_t old_state_int;
dbus_uint32_t new_state_int; dbus_uint32_t new_state_int;
if (dbus_message_get_args (message, NULL, DBUS_TYPE_UINT32, &old_state_int, DBUS_TYPE_UINT32, &new_state_int, DBUS_TYPE_INVALID)) if (dbus_message_get_args (message,
{ NULL,
DBUS_TYPE_UINT32, &old_state_int,
DBUS_TYPE_UINT32, &new_state_int,
DBUS_TYPE_INVALID)) {
NMVPNState old_state = (NMVPNState) old_state_int; NMVPNState old_state = (NMVPNState) old_state_int;
NMVPNState new_state = (NMVPNState) new_state_int; NMVPNState new_state = (NMVPNState) new_state_int;
nm_info ("VPN service '%s' signaled state change %d -> %d.", service->service, old_state, new_state); nm_info ("VPN service '%s' signaled state change %d -> %d.",
service->service,
old_state,
new_state);
nm_vpn_service_set_state (service, new_state); nm_vpn_service_set_state (service, new_state);
/* If the VPN daemon state is now stopped and it was starting, clear the active connection */ /* If the VPN daemon state is now stopped and it was starting,
if (((new_state == NM_VPN_STATE_STOPPED) || (new_state == NM_VPN_STATE_SHUTDOWN) || (new_state == NM_VPN_STATE_STOPPING)) * clear the active connection.
&& ((old_state == NM_VPN_STATE_STARTED) || (old_state == NM_VPN_STATE_STARTING)) */
&& valid_vpn) if ( ( (new_state == NM_VPN_STATE_STOPPED)
{ || (new_state == NM_VPN_STATE_SHUTDOWN)
|| (new_state == NM_VPN_STATE_STOPPING))
&& ( (old_state == NM_VPN_STATE_STARTED)
|| (old_state == NM_VPN_STATE_STARTING))
&& valid_vpn) {
nm_vpn_act_request_unref (req); nm_vpn_act_request_unref (req);
nm_vpn_manager_schedule_vpn_connection_died (service->manager, req); nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
} }
} }
} } else if ( valid_vpn
else if (valid_vpn && dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_IP4_CONFIG)) && dbus_message_is_signal (message, service->service,
NM_DBUS_VPN_SIGNAL_IP4_CONFIG)) {
nm_vpn_service_stage4_ip4_config_get (service, req, message); nm_vpn_service_stage4_ip4_config_get (service, req, message);
}
return TRUE; return TRUE;
} }

View File

@@ -46,13 +46,8 @@ void nm_vpn_service_set_service_name (NMVPNService *service, const char *name)
const char * nm_vpn_service_get_program (NMVPNService *service); const char * nm_vpn_service_get_program (NMVPNService *service);
void nm_vpn_service_set_program (NMVPNService *service, const char *program); void nm_vpn_service_set_program (NMVPNService *service, const char *program);
DBusConnection* nm_vpn_service_get_dbus_connection (NMVPNService *service);
NMVPNState nm_vpn_service_get_state (NMVPNService *service); NMVPNState nm_vpn_service_get_state (NMVPNService *service);
gboolean nm_vpn_service_name_owner_changed (NMVPNService *service, NMVPNActRequest *req, const char *old, const char *new);
gboolean nm_vpn_service_process_signal (NMVPNService *service, NMVPNActRequest *req, DBusMessage *message);
void nm_vpn_service_start_connection (NMVPNService *service, NMVPNActRequest *req); void nm_vpn_service_start_connection (NMVPNService *service, NMVPNActRequest *req);
void nm_vpn_service_stop_connection (NMVPNService *service, NMVPNActRequest *req); void nm_vpn_service_stop_connection (NMVPNService *service, NMVPNActRequest *req);