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>
* src/supplicant-manager/Makefile.am

View file

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

View file

@ -52,6 +52,10 @@
#include "nm-named-manager.h"
#include "nm-vpn-act-request.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-dhcp-manager.h"
#include "nm-logging.h"
@ -60,6 +64,8 @@
#define NM_DEFAULT_PID_FILE LOCALSTATEDIR"/run/NetworkManager.pid"
#define NO_HAL_MSG "Could not initialize connection to the HAL daemon."
/*
* Globals
*/
@ -67,6 +73,7 @@ static NMData *nm_data = NULL;
static gboolean sigterm_pipe_handler (GIOChannel *src, GIOCondition condition, gpointer data);
static void nm_data_free (NMData *data);
static void nm_hal_deinit (NMData *data);
/*
* 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
*
@ -348,10 +340,16 @@ void nm_add_initial_devices (NMData *data)
static gboolean nm_state_change_signal_broadcast (gpointer user_data)
{
NMData *data = (NMData *)user_data;
NMDBusManager *dbus_mgr = NULL;
DBusConnection *dbus_connection = NULL;
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;
}
@ -413,6 +411,87 @@ nm_monitor_setup (NMData *data)
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
@ -524,6 +603,9 @@ static void nm_data_free (NMData *data)
nm_ap_list_unref (data->allowed_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_dhcp_manager_dispose (data->dhcp_manager);
g_object_unref (data->named_manager);
@ -552,81 +634,55 @@ static gboolean sigterm_pipe_handler (GIOChannel *src, GIOCondition condition, g
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;
DBusError error;
NMData * data = (NMData *) user_data;
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 ((ctx = libhal_ctx_new()) == NULL)
{
nm_error ("libhal_ctx_new() failed, exiting...");
return NULL;
}
nm_hal_mainloop_integration (ctx, data->dbus_connection);
libhal_ctx_set_dbus_connection (ctx, data->dbus_connection);
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);
if (!old_owner_good && new_owner_good) {
/* HAL just appeared */
if (!nm_hal_init (data, connection)) {
nm_error (NO_HAL_MSG);
exit (EXIT_FAILURE);
}
libhal_ctx_free (data->hal_ctx);
data->hal_ctx = NULL;
} else if (old_owner_good && !new_owner_good) {
/* HAL went away. Bad HAL. */
nm_hal_deinit (data);
}
}
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
write_pidfile (const char *pidfile)
@ -669,19 +725,30 @@ static void nm_print_usage (void)
* main
*
*/
int main( int argc, char *argv[] )
int
main (int argc, char *argv[])
{
GOptionContext *opt_ctx = NULL;
gboolean become_daemon = FALSE;
gboolean enable_test_devices = FALSE;
gboolean show_usage = FALSE;
char * owner;
char * pidfile = NULL;
char * user_pidfile = NULL;
if (getuid () != 0)
{
NMDBusManager * dbus_mgr;
DBusConnection *dbus_connection;
int exit_status = EXIT_FAILURE;
GOptionEntry options[] = {
{"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},
{"enable-test-devices", 0, 0, G_OPTION_ARG_NONE, &enable_test_devices, "Allow dummy devices to be created via DBUS methods [DEBUG]", NULL},
{"info", 0, 0, G_OPTION_ARG_NONE, &show_usage, "Show application information", NULL},
{NULL}
};
if (getuid () != 0) {
g_printerr ("You must be root to run NetworkManager!\n");
return (EXIT_FAILURE);
goto exit;
}
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
@ -689,43 +756,33 @@ int main( int argc, char *argv[] )
textdomain (GETTEXT_PACKAGE);
/* Parse options */
{
GOptionContext *opt_ctx = NULL;
GOptionEntry options[] = {
{"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},
{"enable-test-devices", 0, 0, G_OPTION_ARG_NONE, &enable_test_devices, "Allow dummy devices to be created via DBUS methods [DEBUG]", NULL},
{"info", 0, 0, G_OPTION_ARG_NONE, &show_usage, "Show application information", NULL},
{NULL}
};
opt_ctx = g_option_context_new("");
g_option_context_add_main_entries(opt_ctx, options, NULL);
g_option_context_parse(opt_ctx, &argc, &argv, NULL);
g_option_context_free(opt_ctx);
}
opt_ctx = g_option_context_new("");
g_option_context_add_main_entries(opt_ctx, options, NULL);
g_option_context_parse(opt_ctx, &argc, &argv, NULL);
g_option_context_free(opt_ctx);
/* 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 (show_usage == TRUE)
{
if (show_usage == TRUE) {
nm_print_usage();
exit (EXIT_SUCCESS);
exit_status = EXIT_SUCCESS;
goto exit;
}
if (become_daemon)
{
if (daemon (0, 0) < 0)
{
pidfile = g_strdup (user_pidfile ? user_pidfile : NM_DEFAULT_PID_FILE);
/* 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;
saved_errno = errno;
nm_error ("NetworkManager could not daemonize: %s [error %u]",
g_strerror (saved_errno), saved_errno);
exit (EXIT_FAILURE);
nm_error ("Could not daemonize: %s [error %u]",
g_strerror (saved_errno),
saved_errno);
goto exit;
}
pidfile = user_pidfile ? user_pidfile : NM_DEFAULT_PID_FILE;
write_pidfile (pidfile);
}
@ -748,46 +805,76 @@ int main( int argc, char *argv[] )
/* Initialize our instance data */
nm_data = nm_data_new (enable_test_devices);
if (!nm_data)
{
nm_error ("nm_data_new() failed... Not enough memory?");
exit (EXIT_FAILURE);
if (!nm_data) {
nm_error ("Failed to initialize.");
goto pidfile;
}
/* Create our dbus service */
nm_data->dbus_connection = nm_dbus_init (nm_data);
if (!nm_data->dbus_connection)
{
nm_error ("nm_dbus_init() failed, exiting. "
"Either dbus is not running, or the "
"NetworkManager dbus security policy "
"was not loaded.");
exit (EXIT_FAILURE);
/* Initialize our DBus service & connection */
dbus_mgr = nm_dbus_manager_get (nm_data->main_context);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (!dbus_connection) {
nm_error ("Failed to initialize. "
"Either dbus is not running, or the "
"NetworkManager dbus security policy "
"was not loaded.");
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);
/* Need to happen after DBUS is initialized */
nm_data->vpn_manager = nm_vpn_manager_new (nm_data);
nm_data->dhcp_manager = nm_dhcp_manager_new (nm_data);
nm_data->named_manager = nm_named_manager_new (nm_data->dbus_connection);
if (!nm_data->vpn_manager) {
nm_warning ("Failed to start the VPN manager.");
goto done;
}
nm_data->dhcp_manager = nm_dhcp_manager_new (nm_data, nm_data->main_context);
if (!nm_data->dhcp_manager) {
nm_warning ("Failed to start the DHCP manager.");
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 (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_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
* lying around upon launch.
*/
@ -802,16 +889,23 @@ int main( int argc, char *argv[] )
/* Run the main loop */
nm_policy_schedule_device_change_check (nm_data);
nm_schedule_state_change_signal_broadcast (nm_data);
exit_status = EXIT_SUCCESS;
g_main_loop_run (nm_data->main_loop);
done:
nm_print_open_socks ();
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 ();
/* Clean up pidfile */
pidfile:
if (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 "NetworkManagerDbus.h"
#include "nm-utils.h"
#include "nm-dbus-manager.h"
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
*
*/
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;
gboolean strength_changed = FALSE;
gboolean new = FALSE;
NMData * app_data;
const struct ether_addr * merge_bssid;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (list != 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);
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? */
if (!devlist_essid || !merge_essid || nm_null_safe_strcmp (devlist_essid, merge_essid))
{
nm_dbus_signal_wireless_network_change (app_data->dbus_connection,
dev, list_ap, NETWORK_STATUS_DISAPPEARED, -1);
nm_dbus_signal_wireless_network_change (dev, list_ap,
NETWORK_STATUS_DISAPPEARED, -1);
new = TRUE;
}
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));
strength_changed = TRUE;
}
@ -518,26 +517,22 @@ gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointL
* artificial, since it clearly exists somewhere.
*/
nm_ap_set_artificial (list_ap, FALSE);
}
else
{
} else {
/* Add the merge AP to the list. */
nm_ap_list_append_ap (list, merge_ap);
list_ap = merge_ap;
new = TRUE;
}
if (list_ap && strength_changed && !new)
{
if (list_ap && strength_changed && !new) {
const int new_strength = nm_ap_get_strength (list_ap);
nm_dbus_signal_wireless_network_change (app_data->dbus_connection,
dev, list_ap, NETWORK_STATUS_STRENGTH_CHANGED, new_strength);
nm_dbus_signal_wireless_network_change (dev, list_ap,
NETWORK_STATUS_STRENGTH_CHANGED, new_strength);
}
if (list_ap && new)
{
nm_dbus_signal_wireless_network_change (app_data->dbus_connection,
dev, list_ap, NETWORK_STATUS_APPEARED, -1);
if (list_ap && new) {
nm_dbus_signal_wireless_network_change (dev, list_ap,
NETWORK_STATUS_APPEARED, -1);
}
return TRUE;
@ -560,21 +555,21 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
if (!dest || !source)
return;
if ((iter = nm_ap_list_iter_new (dest)))
{
while ((dest_ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *src_ap = NULL;
if (!(iter = nm_ap_list_iter_new (dest)))
return;
if ((src_ap = nm_ap_list_get_ap_by_essid (source, nm_ap_get_essid (dest_ap))))
{
nm_ap_set_invalid (dest_ap, nm_ap_get_invalid (src_ap));
nm_ap_set_security (dest_ap, nm_ap_get_security (src_ap));
nm_ap_set_timestamp_via_timestamp (dest_ap, nm_ap_get_timestamp (src_ap));
}
while ((dest_ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *src_ap = NULL;
if ((src_ap = nm_ap_list_get_ap_by_essid (source, nm_ap_get_essid (dest_ap))))
{
nm_ap_set_invalid (dest_ap, nm_ap_get_invalid (src_ap));
nm_ap_set_security (dest_ap, nm_ap_get_security (src_ap));
nm_ap_set_timestamp_via_timestamp (dest_ap, nm_ap_get_timestamp (src_ap));
}
nm_ap_list_iter_free (iter);
}
nm_ap_list_iter_free (iter);
}
@ -586,23 +581,26 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
* 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,
NMDevice80211Wireless *dev,
NMAccessPoint *ap,
NMAccessPointList *search_list)
void
nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev,
NMAccessPoint *ap,
NMAccessPointList *search_list)
{
NMAccessPoint *found_ap;
NMAccessPoint * found_ap;
if (!ap || !search_list)
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 (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);
}
if (!nm_ap_get_essid (ap))
return;
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_dbus_signal_wireless_network_change (dev, ap, NETWORK_STATUS_APPEARED, 0);
}
}
@ -615,10 +613,10 @@ 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.
*
*/
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)
{
NMAPListIter *iter;
NMAccessPoint *dest_ap;
@ -626,13 +624,12 @@ void nm_ap_list_copy_essids_by_address (NMData *app_data,
if (!dest || !source)
return;
if ((iter = nm_ap_list_iter_new (dest)))
{
while ((dest_ap = nm_ap_list_iter_next (iter)))
nm_ap_list_copy_one_essid_by_address (app_data, dev, dest_ap, source);
if (!(iter = nm_ap_list_iter_new (dest)))
return;
nm_ap_list_iter_free (iter);
}
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);
}

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);
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_one_essid_by_address (NMData *app_data, NMDevice80211Wireless *dev, NMAccessPoint *ap, NMAccessPointList *search_list);
void nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev, NMAccessPointList *dest, NMAccessPointList *source);
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);

View file

@ -43,10 +43,13 @@
#include "nm-dbus-nmi.h"
#include "nm-utils.h"
#include "nm-dhcp-manager.h"
#include "nm-dbus-manager.h"
#if 0
static char *get_nmi_match_string (const char *owner);
static gpointer nm_dbus_reinit (gpointer user_data);
#endif
/*
* nm_dbus_create_error_message
@ -54,8 +57,12 @@ static gpointer nm_dbus_reinit (gpointer user_data);
* Make a DBus error message
*
*/
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,
...)
{
char *exception_text;
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
*
@ -155,6 +173,7 @@ NMDevice *nm_dbus_get_device_from_escaped_object_path (NMData *data, const char
&& ((path[len] == '\0' || path[len] == '/')))
{
g_free (escaped_compare_path);
g_object_ref (G_OBJECT (dev));
break;
}
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
*
*/
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;
DBusMessage * message;
char * dev_path;
char * dev_path = NULL;
const char * sig = NULL;
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->dbus_connection, 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))
i++;
if (!(sig = dev_status_signals[i].signal))
return FALSE;
goto out;
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!");
g_free (dev_path);
return FALSE;
goto out;
}
/* 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);
if (essid)
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID);
nm_ap_unref (cb_data->ap);
}
else
} else {
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INVALID);
}
g_free (dev_path);
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_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message);
g_object_unref (G_OBJECT (cb_data->dev));
g_slice_free (NMStatusChangeData, cb_data);
out:
g_object_unref (dbus_mgr);
g_free (dev_path);
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
*
*/
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;
char * dev_path = NULL;
char * net_path = NULL;
const char * sig = NULL;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != 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))))
goto out;
if (!(net_path = nm_dbus_get_object_path_for_network (NM_DEVICE (dev), ap)))
goto out;
switch (status)
{
switch (status) {
case NETWORK_STATUS_DISAPPEARED:
sig = "WirelessNetworkDisappeared";
break;
@ -377,483 +413,129 @@ void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevic
break;
}
if (!sig)
{
nm_warning ("nm_dbus_signal_wireless_network_change(): tried to broadcast unknown signal.");
if (!sig) {
nm_warning ("tried to broadcast unknown signal.");
goto out;
}
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, sig)))
{
nm_warning ("nm_dbus_signal_wireless_network_change(): Not enough memory for new dbus message!");
message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, sig);
if (!message) {
nm_warning ("could not allocate the dbus message.");
goto out;
}
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_OBJECT_PATH, &net_path, DBUS_TYPE_INVALID);
if (status == NETWORK_STATUS_STRENGTH_CHANGED)
dbus_message_append_args (message, DBUS_TYPE_INT32, &strength, DBUS_TYPE_INVALID);
if (!dbus_connection_send (connection, message, NULL))
nm_warning ("nm_dbus_signal_wireless_network_change(): Could not raise the WirelessNetwork* signal!");
dbus_message_append_args (message,
DBUS_TYPE_OBJECT_PATH, &dev_path,
DBUS_TYPE_OBJECT_PATH, &net_path,
DBUS_TYPE_INVALID);
if (status == NETWORK_STATUS_STRENGTH_CHANGED) {
dbus_message_append_args (message,
DBUS_TYPE_INT32, &strength,
DBUS_TYPE_INVALID);
}
dbus_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message);
out:
g_free (net_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;
char * dev_path = NULL;
g_return_if_fail (connection != 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))))
goto out;
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceStrengthChanged")))
{
nm_warning ("nm_dbus_signal_device_strength_change(): Not enough memory for new dbus message!");
message = dbus_message_new_signal (NM_DBUS_PATH,
NM_DBUS_INTERFACE,
"DeviceStrengthChanged");
if (!message) {
nm_warning ("could not allocate the dbus message.");
goto out;
}
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INT32, &strength, DBUS_TYPE_INVALID);
if (!dbus_connection_send (connection, message, NULL))
nm_warning ("nm_dbus_signal_device_strength_change(): Could not raise the DeviceStrengthChanged signal!");
dbus_message_append_args (message,
DBUS_TYPE_OBJECT_PATH, &dev_path,
DBUS_TYPE_INT32, &strength,
DBUS_TYPE_INVALID);
dbus_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message);
out:
g_free (dev_path);
g_object_unref (dbus_mgr);
}
/*
* nm_dbus_signal_filter
*
* Respond to NetworkManagerInfo signals about changing Allowed Networks
*
*/
static DBusHandlerResult nm_dbus_signal_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
gboolean
nm_dbus_nmi_signal_handler (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{
NMData * data = (NMData *)user_data;
const char * object_path;
const char * method;
gboolean handled = FALSE;
DBusError error;
NMData * data = (NMData *) user_data;
const char * object_path;
gboolean handled = FALSE;
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);
g_return_val_if_fail (data != NULL, FALSE);
method = dbus_message_get_member (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)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (strcmp (object_path, NMI_DBUS_PATH) != 0)
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")) {
char *network = NULL;
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;
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID))
{
/* Update a single wireless network's data */
nm_debug ("NetworkManagerInfo triggered update of wireless network '%s'", network);
nm_dbus_update_one_allowed_network (connection, network, data);
handled = TRUE;
}
}
else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "VPNConnectionUpdate"))
{
char *name = NULL;
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
{
nm_debug ("NetworkManagerInfo triggered update of VPN connection '%s'", name);
nm_dbus_vpn_update_one_vpn_connection (data->dbus_connection, name, data);
handled = TRUE;
}
}
else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "UserInterfaceActivated"))
{
nm_device_802_11_wireless_set_scan_interval (data, NULL, NM_WIRELESS_SCAN_INTERVAL_ACTIVE);
if (dbus_message_get_args (message,
NULL,
DBUS_TYPE_STRING, &network,
DBUS_TYPE_INVALID)) {
/* Update a single wireless network's data */
nm_debug ("NetworkManagerInfo triggered update of wireless network "
"'%s'",
network);
nm_dbus_update_one_allowed_network (network, data);
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;
} else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "VPNConnectionUpdate")) {
char *name = NULL;
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;
if (dbus_message_get_args (message,
NULL,
DBUS_TYPE_STRING, &name,
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;
}
}
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);
} else if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "UserInterfaceActivated")) {
nm_device_802_11_wireless_set_scan_interval (data,
NULL,
NM_WIRELESS_SCAN_INTERVAL_ACTIVE);
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);
}
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_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_wireless_network_change (DBusConnection *connection, 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_wireless_network_change (NMDevice80211Wireless *dev, NMAccessPoint *ap, NMNetworkStatus status, 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);
@ -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_new_invalid_args_error (DBusMessage *replyto, const char *namespace);
gboolean nm_dbus_nmi_signal_handler (DBusConnection *connection,
DBusMessage *message,
gpointer user_data);
#endif

View file

@ -20,28 +20,108 @@
*/
#include <syslog.h>
#include <string.h>
#include "NetworkManagerDbusUtils.h"
struct NMDbusMethodList
{
NMDbusMethod validate_method;
GHashTable *methods;
guint32 refcount;
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);
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->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;
const char *method;
DBusMessage *temp_reply = NULL;
if (reply)
*reply = NULL;
NMDBusHandleMessageFunc callback = NULL;
const char * method;
g_return_val_if_fail (list != NULL, FALSE);
g_return_val_if_fail (list->methods != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (message != NULL, FALSE);
if (reply)
*reply = NULL;
if (!(method = dbus_message_get_member (message)))
return FALSE;
if (!(callback = g_hash_table_lookup (list->methods, method)))
return FALSE;
/* Call the optional validate method first, if it returns NULL then we
* actually dispatch the call.
*/
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);
/* Dispatch the method call */
*reply = (*callback) (connection, message, user_data);
if (reply)
*reply = temp_reply;
return (TRUE);
return TRUE;
}
void nm_dbus_method_list_free (NMDbusMethodList *list)
gboolean
nm_dbus_method_list_get_is_fallback (NMDbusMethodList *list)
{
if (list)
{
g_hash_table_destroy (list->methods);
g_slice_free (NMDbusMethodList, list);
}
g_return_val_if_fail (list != NULL, FALSE);
return list->is_fallback;
}
const char *
nm_dbus_method_list_get_path (NMDbusMethodList *list)
{
g_return_val_if_fail (list != NULL, NULL);
return list->path;
}

View file

@ -27,27 +27,42 @@
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include "nm-device.h"
#include "NetworkManagerMain.h"
typedef struct NMDbusCBData
{
NMData *data;
NMDevice *dev;
NMAccessPoint *ap;
} NMDbusCBData;
typedef DBusMessage* (*NMDbusMethod) (DBusConnection *, DBusMessage *, NMDbusCBData *);
typedef struct NMDbusMethodList NMDbusMethodList;
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,
gpointer user_data, DBusMessage **reply);
NMDbusMethodList * nm_dbus_method_list_new (const char *path,
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

View file

@ -31,6 +31,7 @@
#include "nm-netlink-monitor.h"
#include "nm-named-manager.h"
#include "nm-device.h"
#include "NetworkManagerDbusUtils.h"
typedef enum NMIntState
@ -45,7 +46,6 @@ typedef enum NMIntState
} NMIntState;
typedef struct NMDbusMethodList NMDbusMethodList;
typedef struct NMActRequest NMActRequest;
typedef struct NMVPNActRequest NMVPNActRequest;
typedef struct NMVPNManager NMVPNManager;
@ -67,11 +67,9 @@ typedef struct NMData
NMVPNManager * vpn_manager;
NMDHCPManager * dhcp_manager;
DBusConnection * dbus_connection;
NMDbusMethodList * nm_methods;
NMDbusMethodList * device_methods;
NMDbusMethodList * net_methods;
NMDbusMethodList * vpn_methods;
GMainContext * main_context;
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_hal_init (NMData *data);
void nm_hal_deinit (NMData *data);
int nm_get_sigterm_pipe (void);
#endif

View file

@ -38,6 +38,7 @@
#include "nm-dbus-nmi.h"
#include "nm-device-802-11-wireless.h"
#include "nm-device-802-3-ethernet.h"
#include "nm-dbus-manager.h"
/*
@ -537,9 +538,10 @@ static gboolean allowed_list_update_pending = FALSE;
* 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;
allowed_list_update_pending = FALSE;
@ -551,9 +553,8 @@ static gboolean nm_policy_allowed_ap_list_update (gpointer user_data)
if (data->allowed_ap_list)
nm_ap_list_unref (data->allowed_ap_list);
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);
return (FALSE);
nm_dbus_update_allowed_networks (data->allowed_ap_list, data);
return FALSE;
}
@ -597,7 +598,8 @@ static gboolean device_list_update_pending = FALSE;
* 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;
@ -605,27 +607,30 @@ static gboolean nm_policy_device_list_update_from_allowed_list (NMData *data)
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);
if (nm_device_is_802_11_wireless (dev))
{
NMDevice80211Wireless * wdev = NM_DEVICE_802_11_WIRELESS (dev);
NMDevice80211Wireless * wdev;
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_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);
if (!nm_device_is_802_11_wireless (dev))
continue;
nm_ap_list_remove_duplicate_essids (nm_device_802_11_wireless_ap_list_get (wdev));
wdev = NM_DEVICE_802_11_WIRELESS (dev);
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 (wdev,
nm_device_802_11_wireless_ap_list_get (wdev),
data->allowed_ap_list);
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_ap_list_remove_duplicate_essids (nm_device_802_11_wireless_ap_list_get (wdev));
}
nm_policy_schedule_device_change_check (data);

View file

@ -32,32 +32,42 @@
#include "NetworkManagerSystem.h"
#include "nm-activation-request.h"
#include "nm-utils.h"
#include "nm-dbus-manager.h"
#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
{
NMData * data;
GMainContext * main_ctx;
gboolean running;
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)
{
if ( (state == 2) /* BOUND */
|| (state == 3) /* RENEW */
|| (state == 4) /* REBOOT */
|| (state == 5)) /* REBIND */
if ( (state == DHCDBD_BOUND)
|| (state == DHCDBD_RENEW)
|| (state == DHCDBD_REBOOT)
|| (state == DHCDBD_REBIND))
return TRUE;
return FALSE;
@ -66,36 +76,46 @@ static gboolean state_is_bound (guint8 state)
static gboolean state_is_down (guint8 state)
{
if ( (state == 0) /* NBI */
|| (state == 11) /* RELEASE */
|| (state == 13) /* ABEND */
|| (state == 14)) /* END */
if ( (state == DHCDBD_NBI)
|| (state == DHCDBD_RELEASE)
|| (state == DHCDBD_ABEND)
|| (state == DHCDBD_END))
return TRUE;
return FALSE;
}
NMDHCPManager * nm_dhcp_manager_new (NMData *data)
NMDHCPManager *
nm_dhcp_manager_new (NMData *data,
GMainContext *main_ctx)
{
NMDHCPManager * manager;
char * owner;
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->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);
if (manager->running && (owner = get_name_owner (data->dbus_connection, DHCP_SERVICE_NAME)))
{
char *match = get_dhcp_match_string (owner);
dbus_bus_add_match (data->dbus_connection, match, NULL);
g_free (match);
g_free (owner);
}
nm_dbus_manager_register_signal_handler (manager->dbus_mgr,
DHCP_SERVICE_NAME ".state",
DHCP_SERVICE_NAME,
nm_dhcp_manager_process_signal,
manager);
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;
}
@ -105,53 +125,71 @@ void nm_dhcp_manager_dispose (NMDHCPManager *manager)
{
g_return_if_fail (manager != NULL);
g_object_unref (manager->dbus_mgr);
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 * reply;
char * path;
guint32 state = 0;
DBusError error;
DBusConnection *dbus_connection;
g_return_val_if_fail (manager != NULL, 0);
g_return_val_if_fail (dev != NULL, 0);
if (!manager->running)
{
if (!manager->running) {
nm_warning ("dhcdbd not running!");
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));
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);
if (message == NULL)
{
nm_warning ("nm_dhcp_manager_get_state_for_device(): Couldn't allocate the dbus message");
return 0;
if (message == NULL) {
nm_warning ("couldn't allocate the dbus message.");
goto out;
}
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);
if (dbus_error_is_set (&error))
{
if (strcmp (error.name, "org.freedesktop.DBus.Error.UnknownMethod") != 0)
nm_info ("Error from dhcdbd on 'reason' request because: name '%s', message '%s'.", error.name, error.message);
if (dbus_error_is_set (&error)) {
if (strcmp (error.name, "org.freedesktop.DBus.Error.UnknownMethod") != 0) {
nm_info ("Error from dhcdbd on 'reason' request because: name '%s',"
" message '%s'.",
error.name,
error.message);
}
dbus_error_free (&error);
}
else if (reply)
{
if (reply) {
if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
state = 0;
dbus_message_unref (reply);
}
out:
return state;
}
@ -189,65 +227,86 @@ 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;
DBusMessage * message;
DBusMessage * reply;
NMDevice * dev;
char * path;
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 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 */
GSource * source;
DBusConnection * dbus_connection;
gboolean success = FALSE;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (req != NULL, FALSE);
if (!manager->running)
{
if (!manager->running) {
nm_warning ("dhcdbd not running!");
return FALSE;
}
else
{
/* Cancel any DHCP transaction already in progress */
nm_dhcp_manager_cancel_transaction (manager, req);
/* FIXME don't sleep */
sleep (1);
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 */
nm_dhcp_manager_cancel_transaction (manager, req);
/* FIXME don't sleep */
sleep (1);
dev = nm_act_request_get_dev (req);
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));
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);
if (message == NULL)
{
nm_warning ("nm_dhcp_manager_begin_transaction(): Couldn't allocate the dbus message");
return FALSE;
if (message == NULL) {
nm_warning ("couldn't allocate dbus message");
goto out;
}
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);
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 (message);
if (dbus_error_is_set (&error))
{
nm_info ("Couldn't send DHCP 'up' message because: name '%s', message '%s'.", error.name, error.message);
if (dbus_error_is_set (&error)) {
nm_info ("Couldn't send DHCP 'up' message because: name '%s', message "
" '%s'.",
error.name,
error.message);
dbus_error_free (&error);
return FALSE;
goto out;
}
/* Set up a timeout on the transaction to kill it after NM_DHCP_TIMEOUT seconds */
source = g_timeout_source_new (NM_DHCP_TIMEOUT * 1000);
g_source_set_callback (source, (GSourceFunc) nm_dhcp_manager_handle_timeout, req, NULL);
nm_act_request_set_dhcp_timeout (req, g_source_attach (source, manager->data->main_context));
g_source_set_callback (source,
(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);
success = TRUE;
out:
return TRUE;
}
@ -262,7 +321,7 @@ static void remove_timeout (NMDHCPManager *manager, NMActRequest *req)
/* Remove any pending timeouts on the request */
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);
g_source_destroy (source);
}
@ -274,166 +333,236 @@ static void remove_timeout (NMDHCPManager *manager, NMActRequest *req)
* 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;
DBusMessage *message = NULL;
char *path;
DBusConnection *dbus_connection;
g_return_if_fail (manager != 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);
g_assert (dev);
if (manager->running && !state_is_down (nm_act_request_get_dhcp_state (req)))
{
DBusMessage * message;
char * 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, "down")))
{
dbus_connection_send (manager->data->dbus_connection, message, NULL);
dbus_message_unref (message);
/* Give dhcdbd/dhclient some time to send out a RELEASE if they like */
/* FIXME: we should really monitor the interface's DHCP state by waiting
* for dhcdbd to tell us the device is "down" rather than sleeping here.
*/
if (!manager->data->asleep)
sleep (1);
}
g_free (path);
remove_timeout (manager, req);
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));
message = dbus_message_new_method_call (DHCP_SERVICE_NAME,
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);
/* Give dhcdbd/dhclient some time to send out a RELEASE if they like */
/* FIXME: we should really monitor the interface's DHCP state by waiting
* for dhcdbd to tell us the device is "down" rather than sleeping here.
*/
if (!manager->data->asleep)
sleep (1);
remove_timeout (manager, req);
out:
return;
}
static gboolean get_ip4_uint32s (NMDHCPManager *manager, NMDevice *dev, const char *item,
guint32 **ip4_uint32, guint32 *num_items, gboolean ignore_error)
static gboolean
get_ip4_uint32s (NMDHCPManager *manager,
NMDevice *dev,
const char *item,
guint32 **ip4_uint32,
guint32 *num_items,
gboolean ignore_error)
{
DBusMessage * message = NULL;
DBusMessage * reply = NULL;
char * path;
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 (dev != NULL, FALSE);
g_return_val_if_fail (ip4_uint32 != 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;
*num_items = 0;
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)))
{
DBusError error;
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (manager->data->dbus_connection, message, -1, &error);
if (reply)
{
GArray *buffer;
DBusMessageIter iter;
dbus_message_iter_init (reply, &iter);
buffer = g_array_new (TRUE, TRUE, sizeof (guint32));
while (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32)
{
guint32 value;
dbus_message_iter_get_basic (&iter, &value);
g_array_append_val (buffer, value);
dbus_message_iter_next (&iter);
success = TRUE;
}
if (success)
{
*ip4_uint32 = (guint32 *)(buffer->data);
*num_items = buffer->len;
}
g_array_free (buffer, FALSE);
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);
}
message = dbus_message_new_method_call (DHCP_SERVICE_NAME,
path,
DHCP_SERVICE_NAME".dbus.get",
item);
g_free (path);
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (dbus_connection,
message,
-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);
goto out;
}
if (!reply) {
nm_warning ("error calling '%s', DHCP daemon did not respond.", item);
goto out;
}
dbus_message_iter_init (reply, &iter);
buffer = g_array_new (TRUE, TRUE, sizeof (guint32));
while (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32) {
guint32 uint32_value;
dbus_message_iter_get_basic (&iter, &uint32_value);
g_array_append_val (buffer, uint32_value);
dbus_message_iter_next (&iter);
success = TRUE;
}
if (success) {
*ip4_uint32 = (guint32 *)(buffer->data);
*num_items = buffer->len;
}
g_array_free (buffer, FALSE);
dbus_message_unref (reply);
out:
return success;
}
static gboolean get_ip4_string (NMDHCPManager *manager, NMDevice *dev, const char *item,
char **string, gboolean ignore_error)
static gboolean
get_ip4_string (NMDHCPManager *manager,
NMDevice *dev,
const char *item,
char **string,
gboolean ignore_error)
{
DBusMessage * message = NULL;
DBusMessage * reply = NULL;
char * path;
gboolean success = FALSE;
DBusError error;
DBusConnection *dbus_connection;
DBusMessageIter iter;
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (dev != 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;
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)))
{
DBusError error;
message = dbus_message_new_method_call (DHCP_SERVICE_NAME,
path,
DHCP_SERVICE_NAME".dbus.get",
item);
g_free (path);
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
dbus_error_init (&error);
reply = dbus_connection_send_with_reply_and_block (dbus_connection,
message,
-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);
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) {
char *dbus_string;
dbus_error_init (&error);
if ((reply = dbus_connection_send_with_reply_and_block (manager->data->dbus_connection, message, -1, &error)))
{
DBusMessageIter iter;
dbus_message_iter_init (reply, &iter);
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
{
char *dbus_string;
dbus_error_init (&error);
if (dbus_message_get_args (reply, &error, DBUS_TYPE_STRING, &dbus_string, DBUS_TYPE_INVALID))
{
*string = g_strdup (dbus_string);
success = TRUE;
}
}
else if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY)
{
char *byte_array = NULL;
int len = 0;
dbus_error_init (&error);
if (dbus_message_get_args (reply, &error, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &byte_array, &len, DBUS_TYPE_INVALID))
{
byte_array[len] = '\0';
*string = g_strdup (byte_array);
success = TRUE;
}
}
if (dbus_message_get_args (reply,
&error,
DBUS_TYPE_STRING, &dbus_string,
DBUS_TYPE_INVALID)) {
*string = g_strdup (dbus_string);
success = TRUE;
}
} else if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY) {
char *byte_array = NULL;
int len = 0;
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_error_init (&error);
if (dbus_message_get_args (reply,
&error,
DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &byte_array, &len,
DBUS_TYPE_INVALID)) {
byte_array[len] = '\0';
*string = g_strdup (byte_array);
success = TRUE;
}
dbus_message_unref (message);
}
g_free (path);
out:
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.
*
*/
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 * member;
const char * interface;
@ -648,6 +781,7 @@ gboolean nm_dhcp_manager_process_signal (NMDHCPManager *manager, DBusMessage *me
return FALSE;
if (!(interface = dbus_message_get_interface (message)))
return FALSE;
/* Ignore non-DHCP related messages */
if (strncmp (interface, DHCP_SERVICE_NAME, manager->dhcp_sn_len))
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_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)
{
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.
*
*/
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;
gboolean old_owner_good = (old_owner && strlen (old_owner));
gboolean new_owner_good = (new_owner && strlen (new_owner));
NMDHCPManager * self = (NMDHCPManager *) user_data;
gboolean old_owner_good = (old && strlen (old));
gboolean new_owner_good = (new && strlen (new));
g_return_val_if_fail (manager != NULL, FALSE);
g_return_val_if_fail (changed_service_name != NULL, FALSE);
g_return_if_fail (self != NULL);
g_return_if_fail (name != NULL);
/* Can't handle the signal if its not from the DHCP service */
if (strcmp (DHCP_SERVICE_NAME, changed_service_name) != 0)
return FALSE;
if (strcmp (DHCP_SERVICE_NAME, name) != 0)
return;
if (!old_owner_good && new_owner_good)
{
char *match = get_dhcp_match_string (new_owner);
/* DHCP service got created */
dbus_bus_add_match (manager->data->dbus_connection, match, NULL);
g_free (match);
manager->running = TRUE;
handled = TRUE;
if (!old_owner_good && new_owner_good) {
self->running = TRUE;
} else if (old_owner_good && !new_owner_good) {
self->running = FALSE;
}
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;
}
static void
nm_dhcp_manager_dbus_connection_changed (NMDBusManager *dbus_mgr,
DBusConnection *dbus_connection,
gpointer user_data)
{
NMDHCPManager * self = (NMDHCPManager *) user_data;
if (dbus_connection) {
if (nm_dbus_manager_name_has_owner (dbus_mgr, DHCP_SERVICE_NAME))
self->running = TRUE;
} else {
self->running = FALSE;
}
}

View file

@ -49,9 +49,7 @@ enum dhcdbd_state
DHCDBD_END_OPTIONS, /* last option in subscription sent */
};
char * get_dhcp_match_string (const char *owner);
NMDHCPManager * nm_dhcp_manager_new (NMData *data);
NMDHCPManager * nm_dhcp_manager_new (NMData *data, GMainContext *main_ctx);
void nm_dhcp_manager_dispose (NMDHCPManager *manager);
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);
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);
#endif

View file

@ -39,6 +39,7 @@
#include "nm-ip4-config.h"
#include "nm-utils.h"
#include "NetworkManagerSystem.h"
#include "nm-dbus-manager.h"
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
@ -54,26 +55,11 @@
#define NAMED_DBUS_PATH "/com/redhat/named"
#endif
enum
{
PROP_0,
PROP_DBUS_CONNECTION
};
G_DEFINE_TYPE(NMNamedManager, nm_named_manager, G_TYPE_OBJECT)
static void nm_named_manager_finalize (GObject *object);
static void nm_named_manager_dispose (GObject *object);
static GObject *nm_named_manager_constructor (GType type, guint n_construct_properties,
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);
#define NM_NAMED_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_NAMED_MANAGER, \
NMNamedManagerPrivate))
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);
struct NMNamedManagerPrivate
{
gboolean use_named;
DBusConnection *connection;
struct NMNamedManagerPrivate {
gboolean use_named;
NMDBusManager * dbus_mgr;
GSList * configs;
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
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.
*
*/
gboolean
nm_named_manager_process_name_owner_changed (NMNamedManager *mgr,
const char *changed_service_name,
const char *old_owner, const char *new_owner)
static void
nm_named_manager_name_owner_changed (NMDBusManager *dbus_mgr,
DBusConnection *connection,
const char *name,
const char *old,
const char *new,
gpointer user_data)
{
NMNamedManager *mgr = (NMNamedManager *) user_data;
gboolean handled = FALSE;
gboolean old_owner_good = (old_owner && strlen (old_owner));
gboolean new_owner_good = (new_owner && strlen (new_owner));
gboolean old_owner_good = (old && strlen (old));
gboolean new_owner_good = (new && strlen (new));
g_return_val_if_fail (mgr != NULL, FALSE);
g_return_val_if_fail (changed_service_name != NULL, FALSE);
g_return_if_fail (mgr != NULL);
g_return_if_fail (name != NULL);
/* Ensure signal is for named's service */
if (strcmp (NAMED_DBUS_SERVICE, changed_service_name) != 0)
return FALSE;
if (strcmp (NAMED_DBUS_SERVICE, name) != 0)
return;
if (!old_owner_good && new_owner_good)
{
if (!old_owner_good && new_owner_good) {
mgr->priv->use_named = TRUE;
if (!add_all_ip4_configs_to_named (mgr))
nm_warning ("Could not set fowarders in named.");
handled = TRUE;
}
else if (old_owner_good && !new_owner_good)
{
} else if (old_owner_good && !new_owner_good) {
mgr->priv->use_named = FALSE;
/* FIXME: change resolv.conf */
handled = TRUE;
}
if (handled)
{
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)");
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);
}
}
}
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 *
@ -439,64 +330,88 @@ add_ip4_config_to_named (NMNamedManager *mgr, NMIP4Config *config)
{
const char *domain;
int i, num_nameservers;
gboolean success = FALSE;
DBusMessage * message;
DBusMessage * reply;
DBusMessage * reply = NULL;
DBusError error;
gboolean dflt = FALSE;
DBusConnection *dbus_connection;
g_return_val_if_fail (mgr != 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)))
return FALSE;
goto out;
if (!(message = dbus_message_new_method_call (NAMED_DBUS_SERVICE, NAMED_DBUS_PATH, NAMED_DBUS_INTERFACE, "SetForwarders")))
return FALSE;
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, &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);
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_uint16_t port = htons (53); /* default DNS port */
char fwd_policy = dflt ? 1 : 2; /* 'first' : 'only' */
dbus_message_append_args (message, DBUS_TYPE_UINT32, &server,
DBUS_TYPE_UINT16, &port,
DBUS_TYPE_BYTE, &fwd_policy,
DBUS_TYPE_INVALID);
dbus_message_append_args (message,
DBUS_TYPE_UINT32, &server,
DBUS_TYPE_UINT16, &port,
DBUS_TYPE_BYTE, &fwd_policy,
DBUS_TYPE_INVALID);
}
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);
if (dbus_error_is_set (&error))
{
nm_warning ("Could not set forwarders for zone '%s'. Error: '%s'.", domain, error.message);
dbus_error_free (&error);
return FALSE;
if (dbus_error_is_set (&error)) {
nm_warning ("Could not set forwarders for zone '%s'. Error: '%s'.",
domain,
error.message);
goto out;
}
if (!reply)
{
nm_warning ("Could not set forwarders for zone '%s', did not receive a reply from named.", domain);
dbus_error_free (&error);
return FALSE;
if (!reply) {
nm_warning ("Could not set forwarders for zone '%s', did not receive "
"a reply from named.",
domain);
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;
dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID);
nm_warning ("Could not set forwarders for zone '%s'. Named replied: '%s'", domain, err_msg);
dbus_message_unref (reply);
return FALSE;
dbus_message_get_args (reply,
NULL,
DBUS_TYPE_STRING, &err_msg,
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
@ -515,47 +430,76 @@ add_all_ip4_configs_to_named (NMNamedManager *mgr)
static gboolean
remove_one_zone_from_named (NMNamedManager *mgr, const char *zone)
{
DBusMessage * message;
DBusMessage * reply;
gboolean success = FALSE;
DBusMessage * message = NULL;
DBusMessage * reply = NULL;
DBusError error;
DBusConnection *dbus_connection;
g_return_val_if_fail (mgr != 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);
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);
if (dbus_error_is_set (&error))
{
nm_warning ("Could not remove forwarders for zone '%s'. Error: '%s'.", zone, error.message);
dbus_error_free (&error);
return FALSE;
if (dbus_error_is_set (&error)) {
nm_warning ("Could not remove forwarders for zone '%s'. "
"Error: '%s'.",
zone,
error.message);
goto out;
}
if (!reply)
{
nm_warning ("Could not remove forwarders for zone '%s', did not receive a reply from named.", zone);
dbus_error_free (&error);
return FALSE;
if (!reply) {
nm_warning ("Could not remove forwarders for zone '%s', did not "
" receive a reply from named.",
zone);
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;
dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID);
nm_warning ("Could not remove forwarders for zone '%s'. Named replied: '%s'", zone, err_msg);
dbus_message_unref (reply);
return FALSE;
dbus_message_get_args (reply,
NULL,
DBUS_TYPE_STRING, &err_msg,
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
@ -576,59 +520,75 @@ static void
remove_all_zones_from_named (NMNamedManager *mgr)
{
DBusMessage * message;
DBusMessage * reply;
DBusMessage * reply = NULL;
DBusError error;
DBusMessageIter iter;
GSList * zones = NULL;
GSList * elt = NULL;
DBusConnection * dbus_connection;
g_return_if_fail (mgr != NULL);
if (!mgr->priv->use_named)
return;
if (!(message = dbus_message_new_method_call (NAMED_DBUS_SERVICE, NAMED_DBUS_PATH, NAMED_DBUS_INTERFACE, "GetForwarders")))
return;
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,
"GetForwarders");
if (!message) {
nm_warning ("could not allocate dbus message.");
goto out;
}
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);
if (dbus_error_is_set (&error))
{
nm_warning ("Could not get forwarder list from named. Error: '%s'.", error.message);
dbus_error_free (&error);
return;
if (dbus_error_is_set (&error)) {
nm_warning ("Could not get forwarder list from named. Error: '%s'.",
error.message);
goto out;
}
if (!reply)
{
nm_warning ("Could not get forarder list from named, did not receive a reply from named.");
dbus_error_free (&error);
return;
if (!reply) {
nm_warning ("Could not get forarder list from named, did not receive "
" a reply from named.");
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;
dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID);
nm_warning ("Could not get forwarder list from named. Named replied: '%s'", err_msg);
dbus_message_unref (reply);
return;
dbus_message_get_args (reply,
NULL,
DBUS_TYPE_STRING, &err_msg,
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);
do
{
/* We depend on zones being the only strings in what named returns obviously */
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
{
do {
/* We depend on zones being the only strings in what
* named returns (obviously)
*/
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING) {
char *zone = NULL;
dbus_message_iter_get_basic (&iter, &zone);
zones = g_slist_append (zones, g_strdup (zone));
}
} while (dbus_message_iter_next (&iter));
dbus_message_unref (reply);
/* Remove all the zones from named */
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_free (zones);
out:
if (dbus_error_is_set (&error))
dbus_error_free (&error);
dbus_message_unref (reply);
}
gboolean
@ -735,3 +700,66 @@ nm_named_manager_remove_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
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
{
typedef struct {
GObject parent;
NMNamedManagerPrivate *priv;
} NMNamedManager;
typedef struct
{
typedef struct {
GObjectClass parent;
} NMNamedManagerClass;
GType nm_named_manager_get_type (void);
NMNamedManager * nm_named_manager_new (DBusConnection *connection);
gboolean nm_named_manager_process_name_owner_changed (NMNamedManager *mgr,
const char *changed_service_name,
const char *old_owner, const char *new_owner);
NMNamedManager * nm_named_manager_new (void);
gboolean nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config);

View file

@ -27,6 +27,7 @@
#include "nm-device.h"
#include "NetworkManagerDbus.h"
#include "nm-dhcp-manager.h"
#include "nm-dbus-manager.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)
{
DBusMessage * message;
char * dev_path;
char * dev_path = NULL;
NMDBusManager * dbus_mgr = NULL;
DBusConnection *dbus_connection;
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->dev);
if (!(dev_path = nm_dbus_get_object_path_for_device (req->dev)))
return;
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, "DeviceActivationStage")))
{
nm_warning ("nm_act_request_set_stage(): Not enough memory for new dbus message!");
g_free (dev_path);
return;
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 the dbus connection.");
goto out;
}
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_UINT32, &stage, DBUS_TYPE_INVALID);
g_free (dev_path);
if (!(dev_path = nm_dbus_get_object_path_for_device (req->dev)))
goto out;
if (!dbus_connection_send (req->data->dbus_connection, message, NULL))
nm_warning ("nm_act_request_set_stage(): Could not raise the signal!");
message = dbus_message_new_signal (NM_DBUS_PATH,
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);
out:
g_free (dev_path);
g_object_unref (dbus_mgr);
}
DBusPendingCall * nm_act_request_get_user_key_pending_call (NMActRequest *req)

File diff suppressed because it is too large Load diff

View file

@ -23,7 +23,7 @@
#define NM_DBUS_DEVICE_H
NMDbusMethodList *nm_dbus_device_methods_setup (void);
NMDbusMethodList *nm_dbus_device_methods_setup (NMData *data);
#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 "nm-dbus-net.h"
#include "nm-utils.h"
#include "nm-device-private.h"
/*
* nm_dbus_get_ap_from_object_path
@ -34,25 +36,27 @@
* 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;
NMAccessPointList *ap_list;
NMAPListIter *iter;
char compare_path[100], *escaped_compare_path;
NMAccessPoint * ap = NULL;
NMAccessPointList * ap_list;
NMAPListIter * iter;
char compare_path[100];
char * escaped_compare_path;
g_return_val_if_fail (path != 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));
if (!ap_list)
return (NULL);
return NULL;
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;
snprintf (compare_path, 100, "%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES,
@ -60,214 +64,316 @@ static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevic
escaped_compare_path = nm_dbus_escape_object_path (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' */
if (path[len] == '\0' || path[len] == '/')
{
if (path[len] == '\0' || path[len] == '/') {
g_free (escaped_compare_path);
break;
}
}
g_free (escaped_compare_path);
}
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;
NMAccessPoint *ap;
const char *path;
const char *essid;
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 ((ap = nm_dbus_get_ap_from_object_path (path, data->dev)))
data->ap = ap;
else
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NetworkNotFound",
"The requested network does not exist for this device.");
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
essid = nm_ap_get_essid (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID);
return reply;
}
static DBusMessage *nm_dbus_net_get_name (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
static DBusMessage *
nm_dbus_net_get_address (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{
DBusMessage *reply = NULL;
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL;
char buf[20];
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)))
{
const char *essid = nm_ap_get_essid (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &essid, DBUS_TYPE_INVALID);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
memset (&buf[0], 0, 20);
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);
return reply;
}
static DBusMessage *nm_dbus_net_get_address (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
static DBusMessage *
nm_dbus_net_get_strength (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{
DBusMessage *reply = NULL;
NMDbusCBData * data = (NMDbusCBData *) user_data;
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)))
{
char buf[20];
memset (&buf[0], 0, 20);
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);
if (!(reply = dbus_message_new_method_return (message))) {
nm_warning ("Not enough memory to create dbus message.");
return NULL;
}
return reply;
}
static DBusMessage *nm_dbus_net_get_strength (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
g_return_val_if_fail (data && data->data && data->dev && data->ap && connection && message, NULL);
/* We iterate over the device list and return the best strength for all
* APs with the given ESSID.
*/
if ((reply = dbus_message_new_method_return (message)))
{
NMAccessPoint *tmp_ap = NULL;
NMAccessPointList *ap_list;
NMAPListIter *iter;
int best_strength = nm_ap_get_strength (data->ap);
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))))
goto append;
if (!(ap_list = nm_device_802_11_wireless_ap_list_get (NM_DEVICE_802_11_WIRELESS (data->dev))))
goto append;
if (!(iter = nm_ap_list_iter_new (ap_list)))
goto append;
if (!(iter = nm_ap_list_iter_new (ap_list)))
goto append;
/* Find best strength # among all APs that share this essid */
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_ap_get_strength (tmp_ap) > best_strength)
best_strength = nm_ap_get_strength (tmp_ap);
}
nm_ap_list_iter_free (iter);
/* Find best strength # among all APs that share this essid */
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_ap_get_strength (tmp_ap) > best_strength)
best_strength = nm_ap_get_strength (tmp_ap);
}
nm_ap_list_iter_free (iter);
append:
dbus_message_append_args (reply, DBUS_TYPE_INT32, &best_strength, DBUS_TYPE_INVALID);
append:
dbus_message_append_args (reply, DBUS_TYPE_INT32, &best_strength, DBUS_TYPE_INVALID);
return reply;
}
static DBusMessage *
nm_dbus_net_get_frequency (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL;
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;
}
return reply;
}
static DBusMessage *nm_dbus_net_get_frequency (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))) {
double freq;
freq = nm_ap_get_freq (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_DOUBLE, &freq, DBUS_TYPE_INVALID);
}
freq = nm_ap_get_freq (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_DOUBLE, &freq, DBUS_TYPE_INVALID);
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)
{
DBusMessage *reply = NULL;
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL;
dbus_int32_t rate;
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))) {
dbus_int32_t rate;
rate = nm_ap_get_rate (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_INT32, &rate, DBUS_TYPE_INVALID);
}
return reply;
}
static DBusMessage *nm_dbus_net_get_encrypted (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))) {
dbus_bool_t is_encrypted;
is_encrypted = nm_ap_get_encrypted (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_encrypted, DBUS_TYPE_INVALID);
}
return reply;
}
static DBusMessage *nm_dbus_net_get_mode (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)))
{
dbus_int32_t mode = (dbus_int32_t) nm_ap_get_mode (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID);
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);
dbus_message_append_args (reply, DBUS_TYPE_INT32, &rate, DBUS_TYPE_INVALID);
return reply;
}
static DBusMessage *nm_dbus_net_get_properties (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
static DBusMessage *
nm_dbus_net_get_encrypted (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{
DBusMessage *reply = NULL;
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL;
dbus_bool_t is_encrypted;
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)))
{
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_ptr = &hw_addr_buf[0];
dbus_int32_t strength = nm_ap_get_strength (data->ap);
double freq = nm_ap_get_freq (data->ap);
dbus_int32_t rate = nm_ap_get_rate (data->ap);
dbus_int32_t mode = (dbus_int32_t) nm_ap_get_mode (data->ap);
dbus_int32_t capabilities = (dbus_int32_t) nm_ap_get_capabilities (data->ap);
dbus_bool_t broadcast = (dbus_bool_t) nm_ap_get_broadcast (data->ap);
memset (&hw_addr_buf[0], 0, 20);
if (nm_ap_get_address (data->ap))
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_TYPE_STRING, &essid,
DBUS_TYPE_STRING, &hw_addr_buf_ptr,
DBUS_TYPE_INT32, &strength,
DBUS_TYPE_DOUBLE, &freq,
DBUS_TYPE_INT32, &rate,
DBUS_TYPE_INT32, &mode,
DBUS_TYPE_INT32, &capabilities,
DBUS_TYPE_BOOLEAN, &broadcast,
DBUS_TYPE_INVALID);
g_free (op);
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);
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_encrypted, DBUS_TYPE_INVALID);
return reply;
}
static DBusMessage *
nm_dbus_net_get_mode (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL;
dbus_int32_t mode;
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;
}
mode = (dbus_int32_t) nm_ap_get_mode (data->ap);
dbus_message_append_args (reply, DBUS_TYPE_INT32, &mode, DBUS_TYPE_INVALID);
return reply;
}
static DBusMessage *
nm_dbus_net_get_properties (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
{
NMDbusCBData * data = (NMDbusCBData *) user_data;
DBusMessage * reply = NULL;
char * op;
const char * essid;
char hw_addr_buf[20];
char * hw_addr_buf_ptr = &hw_addr_buf[0];
dbus_int32_t strength;
double freq;
dbus_int32_t rate;
dbus_int32_t mode;
dbus_int32_t capabilities;
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);
if (nm_ap_get_address (data->ap))
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_TYPE_STRING, &essid,
DBUS_TYPE_STRING, &hw_addr_buf_ptr,
DBUS_TYPE_INT32, &strength,
DBUS_TYPE_DOUBLE, &freq,
DBUS_TYPE_INT32, &rate,
DBUS_TYPE_INT32, &mode,
DBUS_TYPE_INT32, &capabilities,
DBUS_TYPE_BOOLEAN, &broadcast,
DBUS_TYPE_INVALID);
g_free (op);
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
@ -276,18 +382,22 @@ static DBusMessage *nm_dbus_net_get_properties (DBusConnection *connection, DBus
* 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;
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);
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, "getName", nm_dbus_net_get_name);
nm_dbus_method_list_add_method (list, "getAddress", nm_dbus_net_get_address);
nm_dbus_method_list_add_method (list, "getStrength", nm_dbus_net_get_strength);
nm_dbus_method_list_add_method (list, "getFrequency", nm_dbus_net_get_frequency);
nm_dbus_method_list_add_method (list, "getRate", nm_dbus_net_get_rate);
nm_dbus_method_list_add_method (list, "getEncrypted", nm_dbus_net_get_encrypted);
nm_dbus_method_list_add_method (list, "getMode", nm_dbus_net_get_mode);
nm_dbus_method_list_add_method (list, "getStrength", nm_dbus_net_get_strength);
nm_dbus_method_list_add_method (list, "getFrequency", nm_dbus_net_get_frequency);
nm_dbus_method_list_add_method (list, "getRate", nm_dbus_net_get_rate);
nm_dbus_method_list_add_method (list, "getEncrypted", nm_dbus_net_get_encrypted);
nm_dbus_method_list_add_method (list, "getMode", nm_dbus_net_get_mode);
return (list);
}

View file

@ -23,7 +23,15 @@
#define NM_DBUS_NET_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

View file

@ -46,168 +46,201 @@
* 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)
{
DBusMessage *reply = NULL;
DBusMessageIter iter;
DBusMessageIter iter_array;
NMData * data = (NMData *) user_data;
DBusMessage * reply = NULL;
DBusMessageIter iter;
DBusMessageIter iter_array;
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 devices */
if (!data->data->dev_list)
return (nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoDevices",
"There are no available network devices."));
if (!data->dev_list) {
return nm_dbus_create_error_message (message,
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;
}
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;
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter_array);
for (elt = data->data->dev_list; elt; elt = g_slist_next (elt))
{
NMDevice *dev = (NMDevice *)(elt->data);
dbus_message_iter_open_container (&iter,
DBUS_TYPE_ARRAY,
DBUS_TYPE_OBJECT_PATH_AS_STRING,
&iter_array);
if (dev)
{
char *op = nm_dbus_get_object_path_for_device (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);
dbus_message_iter_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &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_append_basic (&iter_array, DBUS_TYPE_OBJECT_PATH, &op);
g_free (op);
}
dbus_message_iter_close_container (&iter, &iter_array);
nm_unlock_mutex (data->data->dialup_list_mutex, __FUNCTION__);
}
else
{
nm_unlock_mutex (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 dialup list, try again.");
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_activate_dialup (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
static DBusMessage *
nm_dbus_nm_get_dialup (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{
DBusMessage *reply = NULL;
NMData *nm_data = (NMData *) data->data;
const char *dialup;
NMData * data = (NMData *) user_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);
reply = dbus_message_new_method_return (message);
if (!reply)
/* Check for no dialup devices */
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;
}
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))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments",
"NetworkManager::activateDialup called with invalid arguments.");
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
nm_lock_mutex (nm_data->dialup_list_mutex, __FUNCTION__);
if (!nm_system_activate_dialup (nm_data->dialup_list, dialup))
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "ActivationFailed",
"Failed to activate the dialup device.");
else
nm_data->modem_active = TRUE;
nm_unlock_mutex (nm_data->dialup_list_mutex, __FUNCTION__);
nm_lock_mutex (data->dialup_list_mutex, __FUNCTION__);
if (!nm_system_activate_dialup (data->dialup_list, dialup)) {
reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"ActivationFailed",
"Failed to activate the dialup "
"device.");
} else {
data->modem_active = TRUE;
}
nm_unlock_mutex (data->dialup_list_mutex, __FUNCTION__);
out:
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;
NMData *nm_data = (NMData *) data->data;
const char *dialup;
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);
reply = dbus_message_new_method_return (message);
if (!reply)
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))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments",
"NetworkManager::deactivateDialup called with invalid arguments.");
if (!dbus_message_get_args (message,
NULL,
DBUS_TYPE_STRING, &dialup,
DBUS_TYPE_INVALID)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
nm_lock_mutex (nm_data->dialup_list_mutex, __FUNCTION__);
if (!nm_system_deactivate_dialup (nm_data->dialup_list, dialup))
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeactivationFailed",
"Failed to deactivate the dialup device.");
else
nm_data->modem_active = FALSE;
nm_unlock_mutex (nm_data->dialup_list_mutex, __FUNCTION__);
nm_lock_mutex (data->dialup_list_mutex, __FUNCTION__);
if (!nm_system_deactivate_dialup (data->dialup_list, dialup)) {
reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"DeactivationFailed",
"Failed to deactivate the dialup "
" device.");
} else {
data->modem_active = FALSE;
}
nm_unlock_mutex (data->dialup_list_mutex, __FUNCTION__);
out:
return reply;
@ -221,10 +254,12 @@ out:
* 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";
const char * INVALID_ARGS_MESSAGE = "NetworkManager::setActiveDevice called with invalid arguments.";
NMData * data = (NMData *) user_data;
NMDevice * dev = NULL;
DBusMessage * reply = NULL;
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 (message != 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);
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).",
__FILE__, __LINE__, __func__);
goto out;
}
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 */
if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
"The requested network device does not exist.");
nm_warning ("%s:%d (%s): Invalid device (device not found).", __FILE__, __LINE__, __func__);
if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED)) {
reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"DeviceNotFound",
"The requested network device "
"does not exist.");
nm_warning ("%s:%d (%s): Invalid device (device not found).", __FILE__,
__LINE__, __func__);
goto out;
}
if (nm_device_is_802_11_wireless (dev))
{
if (nm_device_is_802_11_wireless (dev)) {
NMAPSecurity * security = NULL;
char * essid = NULL;
gboolean fallback = FALSE;
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__);
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__);
goto out;
}
/* grab ssid and ensure validity */
dbus_message_iter_get_basic (&iter, &essid);
if (!essid || (strlen (essid) <= 0))
{
nm_warning ("%s:%d (%s): Invalid argument (essid).", __FILE__, __LINE__, __func__);
if (!essid || (strlen (essid) <= 0)) {
nm_warning ("%s:%d (%s): Invalid argument (essid).",
__FILE__, __LINE__, __func__);
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");
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
* make some up from the scan list.
*/
if (dbus_message_iter_next (&iter))
{
if (!(security = nm_ap_security_new_deserialize (&iter)))
{
if (dbus_message_iter_next (&iter)) {
if (!(security = nm_ap_security_new_deserialize (&iter))) {
/* There was security info, but it was invalid */
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
nm_warning ("%s:%d (%s): Invalid argument (wireless security info).", __FILE__, __LINE__, __func__);
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
nm_warning ("%s:%d (%s): Invalid argument (wireless security "
"info).", __FILE__, __LINE__, __func__);
goto out;
}
}
@ -307,22 +342,19 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
g_object_unref (G_OBJECT (security));
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_device_deactivate (dev);
nm_schedule_state_change_signal_broadcast (data->data);
nm_policy_schedule_device_activation (nm_act_request_new (data->data, dev, ap, TRUE));
nm_schedule_state_change_signal_broadcast (data);
nm_policy_schedule_device_activation (nm_act_request_new (data, dev, ap, TRUE));
out:
if (dev)
g_object_unref (G_OBJECT (dev));
if (!reply)
{
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);
return reply;
}
@ -333,10 +365,12 @@ out:
* 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";
const char * INVALID_ARGS_MESSAGE = "NetworkManager::createWirelessNetwork called with invalid arguments.";
NMData * data = (NMData *) user_data;
NMDevice * dev = NULL;
DBusMessage * reply = NULL;
char * dev_path = NULL;
@ -344,50 +378,48 @@ static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connecti
NMAPSecurity * security = NULL;
char * essid = NULL;
DBusMessageIter iter;
NMActRequest * req;
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->data != NULL, NULL);
dbus_message_iter_init (message, &iter);
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_OBJECT_PATH)
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_OBJECT_PATH) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
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 */
if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
"The requested network device does not exist.");
if (!dev || !(nm_device_get_capabilities (dev) & NM_DEVICE_CAP_NM_SUPPORTED)) {
reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"DeviceNotFound",
"The requested network device "
"does not exist.");
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_get_arg_type (&iter) != DBUS_TYPE_STRING))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
|| (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
/* grab ssid and ensure validity */
dbus_message_iter_get_basic (&iter, &essid);
if (!essid || (strlen (essid) <= 0) || !dbus_message_iter_next (&iter))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
if (!essid || (strlen (essid) <= 0) || !dbus_message_iter_next (&iter)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
if (!(security = nm_ap_security_new_deserialize (&iter)))
{
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, INVALID_ARGS_ERROR, INVALID_ARGS_MESSAGE);
if (!(security = nm_ap_security_new_deserialize (&iter))) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
@ -400,216 +432,282 @@ static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connecti
g_object_unref (G_OBJECT (security));
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:
return reply;
}
static DBusMessage *nm_dbus_nm_create_test_device (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
static DBusMessage *
nm_dbus_nm_remove_test_device (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{
DBusError err;
NMDeviceType type;
NMData * data = (NMData *) user_data;
DBusMessage *reply = NULL;
static int test_dev_num = 0;
char * dev_path;
NMDevice * dev = 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);
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;
dev = nm_create_device_and_add_to_list (data->data, udi, interface, TRUE, type);
test_dev_num++;
if ((reply = dbus_message_new_method_return (message)))
{
char *dev_path, *escaped_dev_path;
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);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID);
g_free (dev_path);
g_free (escaped_dev_path);
}
g_free (interface);
g_free (udi);
if (!dbus_message_get_args (message,
NULL,
DBUS_TYPE_STRING, &dev_path,
DBUS_TYPE_INVALID)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
else
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "BadType", "The test device type was invalid.");
return (reply);
if (!(dev = nm_dbus_get_device_from_escaped_object_path (data, dev_path))) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
if (!nm_device_is_test_device (dev)) {
reply = nm_dbus_create_error_message (message,
NM_DBUS_INTERFACE,
"NotTestDevice",
"Only test devices can be removed"
" via the DBus interface.");
goto out;
}
nm_remove_device (data, dev);
out:
if (dev)
g_object_unref (G_OBJECT (dev));
return reply;
}
static DBusMessage *nm_dbus_nm_remove_test_device (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
static DBusMessage *
nm_dbus_nm_set_wireless_enabled (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{
DBusMessage *reply = NULL;
DBusError err;
char *dev_path;
NMData * data = (NMData *) user_data;
gboolean enabled = FALSE;
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);
dbus_error_init (&err);
if (dbus_message_get_args (message, &err, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID))
{
NMDevice *dev;
if ((dev = nm_dbus_get_device_from_escaped_object_path (data->data, dev_path)))
{
if (nm_device_is_test_device (dev))
nm_remove_device (data->data, dev);
else
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_message_get_args (message,
NULL,
DBUS_TYPE_BOOLEAN, &enabled,
DBUS_TYPE_INVALID)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE);
goto out;
}
if (dbus_error_is_set (&err))
dbus_error_free (&err);
data->wireless_enabled = enabled;
return (reply);
}
if (!enabled) {
GSList * elt;
static DBusMessage *nm_dbus_nm_set_wireless_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
gboolean enabled = FALSE;
DBusError err;
NMData *app_data;
/* Down all wireless devices */
nm_lock_mutex (data->dev_list_mutex, __FUNCTION__);
for (elt = data->dev_list; elt; elt = g_slist_next (elt)) {
NMDevice * dev = (NMDevice *)(elt->data);
g_return_val_if_fail (data && data->data && connection && message, NULL);
dbus_error_init (&err);
if (!dbus_message_get_args (message, &err, DBUS_TYPE_BOOLEAN, &enabled, DBUS_TYPE_INVALID))
return NULL;
app_data = data->data;
app_data->wireless_enabled = enabled;
if (!enabled)
{
GSList *elt;
/* Physically down all wireless devices */
nm_lock_mutex (app_data->dev_list_mutex, __FUNCTION__);
for (elt = app_data->dev_list; elt; elt = g_slist_next (elt))
{
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_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;
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)))
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &data->data->wireless_enabled, DBUS_TYPE_INVALID);
if ((reply = dbus_message_new_method_return (message))) {
dbus_message_append_args (reply,
DBUS_TYPE_BOOLEAN, &data->wireless_enabled,
DBUS_TYPE_INVALID);
}
return reply;
}
static DBusMessage *nm_dbus_nm_sleep (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
static DBusMessage *
nm_dbus_nm_sleep (DBusConnection *connection,
DBusMessage *message,
void * user_data)
{
NMData *app_data;
NMData * data = (NMData *) user_data;
GSList * elt;
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);
app_data = data->data;
if (app_data->asleep == FALSE)
{
GSList *elt;
if (data->asleep)
return NULL;
nm_info ("Going to sleep.");
nm_info ("Going to sleep.");
data->asleep = TRUE;
app_data->asleep = TRUE;
/* Not using nm_schedule_state_change_signal_broadcast() here
* because we want the signal to go out ASAP.
*/
nm_dbus_signal_state_change (connection, app_data);
/* Not using nm_schedule_state_change_signal_broadcast() here
* because we want the signal to go out ASAP.
*/
nm_dbus_signal_state_change (connection, data);
/* Remove all devices from the device list */
nm_lock_mutex (app_data->dev_list_mutex, __FUNCTION__);
for (elt = app_data->dev_list; elt; elt = g_slist_next (elt))
{
NMDevice *dev = (NMDevice *)(elt->data);
nm_device_set_removed (dev, TRUE);
nm_device_deactivate_quickly (dev);
nm_system_device_set_up_down (dev, FALSE);
}
nm_unlock_mutex (app_data->dev_list_mutex, __FUNCTION__);
nm_lock_mutex (app_data->dialup_list_mutex, __FUNCTION__);
nm_system_deactivate_all_dialup (app_data->dialup_list);
app_data->modem_active = FALSE;
nm_unlock_mutex (app_data->dialup_list_mutex, __FUNCTION__);
/* Just deactivate and down all devices from the device list,
* we'll remove them in 'wake' for speed's sake.
*/
nm_lock_mutex (data->dev_list_mutex, __FUNCTION__);
for (elt = data->dev_list; elt; elt = g_slist_next (elt)) {
NMDevice *dev = (NMDevice *)(elt->data);
nm_device_set_removed (dev, TRUE);
nm_device_deactivate_quickly (dev);
nm_system_device_set_up_down (dev, FALSE);
}
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
nm_lock_mutex (data->dialup_list_mutex, __FUNCTION__);
nm_system_deactivate_all_dialup (data->dialup_list);
data->modem_active = FALSE;
nm_unlock_mutex (data->dialup_list_mutex, __FUNCTION__);
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);
app_data = data->data;
if (app_data->asleep == TRUE)
{
nm_info ("Waking up from sleep.");
app_data->asleep = FALSE;
if (!data->asleep)
return NULL;
/* Remove all devices from the device list */
nm_lock_mutex (app_data->dev_list_mutex, __FUNCTION__);
while (g_slist_length (app_data->dev_list))
nm_remove_device (app_data, (NMDevice *)(app_data->dev_list->data));
nm_unlock_mutex (app_data->dev_list_mutex, __FUNCTION__);
nm_info ("Waking up from sleep.");
data->asleep = FALSE;
nm_add_initial_devices (app_data);
/* Remove all devices from the device list */
nm_lock_mutex (data->dev_list_mutex, __FUNCTION__);
while (g_slist_length (data->dev_list))
nm_remove_device (data, (NMDevice *)(data->dev_list->data));
g_slist_free (data->dev_list);
data->dev_list = NULL;
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
nm_schedule_state_change_signal_broadcast (app_data);
nm_policy_schedule_device_change_check (data->data);
}
nm_add_initial_devices (data);
nm_schedule_state_change_signal_broadcast (data);
nm_policy_schedule_device_change_check (data);
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;
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)))
dbus_message_append_args (reply, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);
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);
out:
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.
*
*/
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, "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, "removeTestDevice", nm_dbus_nm_remove_test_device);
return (list);
return list;
}

View file

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

View file

@ -27,6 +27,7 @@
#include "NetworkManagerUtils.h"
#include "nm-dbus-nmi.h"
#include "nm-utils.h"
#include "nm-dbus-manager.h"
/*
@ -36,7 +37,9 @@
* 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;
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)))
goto out;
if (message_is_error (reply))
{
if (message_is_error (reply)) {
DBusError err;
dbus_error_init (&err);
dbus_set_error_from_message (&err, reply);
/* Check for cancelled error */
if (strcmp (err.name, NMI_DBUS_USER_KEY_CANCELED_ERROR) == 0)
{
nm_info ("Activation (%s) New wireless user key request for network '%s' was canceled.",
nm_device_get_iface (dev), nm_ap_get_essid (ap));
if (strcmp (err.name, NMI_DBUS_USER_KEY_CANCELED_ERROR) == 0) {
nm_info ("Activation (%s) New wireless user key request for network"
" '%s' was canceled.",
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);
@ -94,11 +99,12 @@ static void nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall, NMActRe
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);
if ((security = nm_ap_security_new_deserialize (&iter)))
{
if ((security = nm_ap_security_new_deserialize (&iter))) {
nm_ap_set_security (ap, security);
nm_device_activate_schedule_stage1_device_prepare (req);
}
@ -118,11 +124,14 @@ out:
* 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;
DBusPendingCall * pcall;
NMData * data;
NMDevice * dev;
NMAccessPoint * ap;
gint32 attempt = 1;
@ -130,11 +139,14 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest
char * net_path;
const char * essid;
g_return_if_fail (connection != NULL);
g_return_if_fail (req != NULL);
data = nm_act_request_get_data (req);
g_assert (data);
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;
}
dev = nm_act_request_get_dev (req);
g_assert (dev);
@ -143,35 +155,42 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest
g_assert (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")))
{
nm_warning ("nm_dbus_get_user_key_for_network(): Couldn't allocate the dbus message");
return;
message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
NMI_DBUS_PATH,
NMI_DBUS_INTERFACE,
"getKeyForNetwork");
if (!message) {
nm_warning ("couldn't allocate the dbus message");
goto out;
}
dev_path = nm_dbus_get_object_path_for_device (dev);
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_TYPE_OBJECT_PATH, &net_path,
DBUS_TYPE_STRING, &essid,
DBUS_TYPE_INT32, &attempt,
DBUS_TYPE_BOOLEAN, &new_key,
DBUS_TYPE_INVALID);
if ((pcall = nm_dbus_send_with_callback (connection, message,
(DBusPendingCallNotifyFunction) nm_dbus_get_user_key_for_network_cb,
req, NULL, __func__)))
{
pcall = nm_dbus_send_with_callback (dbus_connection,
message,
(DBusPendingCallNotifyFunction) nm_dbus_get_user_key_for_network_cb,
req,
NULL,
__func__);
if (pcall) {
nm_act_request_ref (req);
nm_act_request_set_stage (req, NM_ACT_STAGE_NEED_USER_KEY);
nm_act_request_set_user_key_pending_call (req, pcall);
}
else
nm_warning ("nm_dbus_get_user_key_for_network(): could not send dbus message");
} else nm_warning ("nm_dbus_get_user_key_for_network(): bad object path data");
} else {
nm_warning ("bad object path data");
}
g_free (net_path);
g_free (dev_path);
@ -181,6 +200,9 @@ void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMActRequest
*/
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
*
*/
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;
DBusPendingCall * pcall;
NMDBusManager * dbus_mgr;
DBusConnection * dbus_connection;
g_return_if_fail (connection != 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)))
dbus_pending_call_cancel (pcall);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "cancelGetKeyForNetwork")))
{
nm_warning ("nm_dbus_cancel_get_user_key_for_network(): Couldn't allocate the dbus message");
return;
message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
NMI_DBUS_PATH,
NMI_DBUS_INTERFACE,
"cancelGetKeyForNetwork");
if (!message) {
nm_warning ("couldn't allocate the dbus message");
goto out;
}
if (!dbus_connection_send (connection, message, NULL))
nm_warning ("nm_dbus_cancel_get_user_key_for_network(): could not send dbus message");
dbus_connection_send (dbus_connection, message, NULL);
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
*
*/
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;
gboolean success = FALSE;
gboolean fallback;
const char * essid;
gchar * char_bssid;
@ -231,14 +269,23 @@ gboolean nm_dbus_update_network_info (DBusConnection *connection, NMAccessPoint
const struct ether_addr *addr;
DBusMessageIter iter;
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (ap != NULL, FALSE);
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;
}
essid = nm_ap_get_essid (ap);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "updateNetworkInfo")))
{
nm_warning ("nm_dbus_update_network_info(): Couldn't allocate the dbus message");
message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
NMI_DBUS_PATH,
NMI_DBUS_INTERFACE,
"updateNetworkInfo");
if (!message) {
nm_warning ("couldn't allocate the dbus message");
goto out;
}
@ -276,19 +323,13 @@ gboolean nm_dbus_update_network_info (DBusConnection *connection, NMAccessPoint
/* Serialize the AP's security info into the message */
security = nm_ap_get_security (ap);
g_assert (security);
if (nm_ap_security_serialize (security, &iter) != 0)
goto unref;
if (dbus_connection_send (connection, message, NULL))
success = TRUE;
else
nm_warning ("nm_dbus_update_network_info(): failed to send dbus message.");
unref:
if (nm_ap_security_serialize (security, &iter) == 0)
dbus_connection_send (dbus_connection, message, NULL);
dbus_message_unref (message);
out:
return success;
g_object_unref (dbus_mgr);
return;
}
@ -487,11 +528,15 @@ out:
* 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;
DBusMessageIter iter, array_iter;
GetNetworksCBData * cb_data = (GetNetworksCBData *)user_data;
NMDBusManager * dbus_mgr = NULL;
DBusConnection *dbus_connection;
g_return_if_fail (pcall);
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)))
goto out;
if (message_is_error (reply))
{
if (message_is_error (reply)) {
DBusError err;
dbus_error_init (&err);
@ -515,18 +559,27 @@ static void nm_dbus_get_networks_cb (DBusPendingCall *pcall, void *user_data)
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_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;
DBusMessage * message;
dbus_message_iter_get_basic (&array_iter, &value);
/* 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);
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);
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);
nm_dbus_send_with_callback (cb_data->data->dbus_connection, message,
(DBusPendingCallNotifyFunction) nm_dbus_get_network_data_cb, net_cb_data,
(DBusFreeFunction) free_get_one_network_cb_data, __func__);
dbus_message_append_args (message,
DBUS_TYPE_STRING, &value,
DBUS_TYPE_INT32, &type_as_int32,
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_iter_next(&array_iter);
@ -546,6 +605,8 @@ static void nm_dbus_get_networks_cb (DBusPendingCall *pcall, void *user_data)
dbus_message_unref (reply);
out:
if (dbus_mgr)
g_object_unref (dbus_mgr);
dbus_pending_call_unref (pcall);
}
@ -556,29 +617,54 @@ out:
* 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;
dbus_int32_t type_as_int32 = nm_ap_list_get_type (list);
GetNetworksCBData * cb_data;
g_return_if_fail (connection != NULL);
g_return_if_fail (list != NULL);
g_return_if_fail (data != NULL);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getNetworks")))
return;
dbus_message_append_args (message, DBUS_TYPE_INT32, &type_as_int32, DBUS_TYPE_INVALID);
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;
}
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->data = data;
nm_ap_list_ref (list);
cb_data->list = list;
nm_dbus_send_with_callback (cb_data->data->dbus_connection, message,
(DBusPendingCallNotifyFunction) nm_dbus_get_networks_cb, cb_data,
(DBusFreeFunction) free_get_networks_cb_data, __func__);
nm_dbus_send_with_callback (dbus_connection,
message,
(DBusPendingCallNotifyFunction) nm_dbus_get_networks_cb,
cb_data,
(DBusFreeFunction) free_get_networks_cb_data,
__func__);
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
*
*/
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;
dbus_int32_t type_as_int32 = NETWORK_TYPE_ALLOWED;
GetOneNetworkCBData * cb_data = NULL;
g_return_if_fail (connection != NULL);
g_return_if_fail (data != NULL);
if (!(message = dbus_message_new_method_call (NMI_DBUS_SERVICE, NMI_DBUS_PATH, NMI_DBUS_INTERFACE, "getNetworkProperties")))
{
nm_warning ("nm_dbus_update_one_allowed_network(): Couldn't allocate the dbus message");
return;
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;
}
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->data = data;
cb_data->network = g_strdup (network);
cb_data->list = data->allowed_ap_list;
nm_dbus_send_with_callback (cb_data->data->dbus_connection, message,
(DBusPendingCallNotifyFunction) nm_dbus_get_network_data_cb, cb_data,
(DBusFreeFunction) free_get_one_network_cb_data, __func__);
dbus_message_append_args (message,
DBUS_TYPE_STRING, &network,
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);
out:
g_object_unref (dbus_mgr);
}

View file

@ -25,17 +25,15 @@
#include "NetworkManager.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 (DBusConnection *connection, NMAccessPointList *list, NMData *data);
void nm_dbus_update_allowed_networks (NMAccessPointList *list, NMData *data);
#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);
app_data = nm_device_get_app_data (NM_DEVICE (self));
g_assert (app_data);
nm_dbus_update_network_info (app_data->dbus_connection, ap, automatic);
nm_dbus_update_network_info (ap, automatic);
}
}
@ -213,9 +213,8 @@ nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self)
static void
nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self)
{
NMData * app_data;
gboolean has_range = FALSE;
NMSock * sk;
gboolean has_range = FALSE;
NMSock * sk;
iwrange range;
iwstats stats;
int percent = -1;
@ -226,14 +225,10 @@ nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self)
if (self->priv->scanning)
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
* 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;
return;
}
@ -266,7 +261,7 @@ nm_device_802_11_wireless_update_signal_strength (NMDevice80211Wireless *self)
self->priv->invalid_strength_counter = 0;
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;
}
@ -1902,7 +1897,7 @@ convert_scan_results (gpointer user_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);
}
}
@ -2528,7 +2523,6 @@ link_timeout_cb (gpointer user_data)
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
NMActRequest * req = nm_device_get_act_request (dev);
NMAccessPoint * ap = nm_act_request_get_ap (req);
NMData * data = nm_device_get_app_data (dev);
gboolean has_key;
g_assert (dev);
@ -2544,7 +2538,7 @@ link_timeout_cb (gpointer user_data)
nm_info ("Activation (%s/wireless): disconnected during association,"
" asking for new key.", nm_device_get_iface (dev));
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
{
@ -2657,7 +2651,6 @@ supplicant_timeout_cb (gpointer user_data)
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data);
NMActRequest * req = nm_device_get_act_request (dev);
NMAccessPoint * ap = nm_act_request_get_ap (req);
NMData * data = nm_device_get_app_data (dev);
gboolean has_key;
g_assert (self);
@ -2672,7 +2665,7 @@ supplicant_timeout_cb (gpointer user_data)
/* Activation failed, we must have bad encryption 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_dbus_get_user_key_for_network (data->dbus_connection, req, TRUE);
nm_dbus_get_user_key_for_network (req, TRUE);
}
else
{
@ -3015,7 +3008,6 @@ real_act_stage2_config (NMDevice *dev,
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev);
NMAccessPoint * ap = nm_act_request_get_ap (req);
NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
NMData * data = nm_act_request_get_data (req);
const char * iface;
gboolean ask_user = FALSE;
@ -3026,7 +3018,7 @@ real_act_stage2_config (NMDevice *dev,
/* If we need an encryption key, get one */
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;
}
@ -3162,7 +3154,7 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
/* 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_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;
}
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)))
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);
if (nm_act_request_get_stage (req) == NM_ACT_STAGE_NEED_USER_KEY)
{
NMData *data = nm_device_get_app_data (dev);
nm_dbus_cancel_get_user_key_for_network (data->dbus_connection, req);
}
nm_dbus_cancel_get_user_key_for_network (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
* allowed list where we cache known MAC->ESSID associations.
*/
if (!nm_ap_get_essid (ap))
{
if (!nm_ap_get_essid (ap)) {
NMData * app_data;
nm_ap_set_broadcast (ap, FALSE);
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 */

View file

@ -23,6 +23,14 @@
#define NM_DEVICE_PRIVATE_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);

View file

@ -1,3 +1,4 @@
VOID:OBJECT
VOID:OBJECT,POINTER,INT
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);
NMDbusMethodList * nm_dbus_vpn_methods_setup (void);
NMDbusMethodList * nm_dbus_vpn_methods_setup (NMVPNManager *mgr);
#endif

View file

@ -24,6 +24,8 @@
#include <string.h>
#include "nm-vpn-act-request.h"
#include "nm-dbus-vpn.h"
#include "nm-dbus-manager.h"
#include "nm-utils.h"
struct NMVPNActRequest
@ -233,10 +235,20 @@ void nm_vpn_act_request_set_stage (NMVPNActRequest *req, NMVPNActStage stage)
old_stage = req->stage;
if (old_stage != stage)
{
DBusConnection *dbus_connection = nm_vpn_service_get_dbus_connection (req->service);
NMDBusManager *dbus_mgr;
DBusConnection *dbus_connection;
req->stage = stage;
nm_dbus_vpn_signal_vpn_connection_state_change (dbus_connection, req->vpn, req->stage);
dbus_mgr = nm_dbus_manager_get (NULL);
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (dbus_connection) {
req->stage = 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 "nm-vpn-connection.h"
#include "nm-dbus-vpn.h"
#include "nm-dbus-manager.h"
#include "nm-utils.h"
#include "NetworkManagerSystem.h"
@ -36,7 +38,6 @@ struct NMVPNConnection
char * service_name;
NMNamedManager *named_manager;
DBusConnection *dbus_connection;
/* Change when connection is activated/deactivated */
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);
NMVPNConnection *nm_vpn_connection_new (const char *name, const char *user_name, const char *service_name,
NMNamedManager *named_manager, DBusConnection *dbus_connection)
NMVPNConnection *
nm_vpn_connection_new (const char *name,
const char *user_name,
const char *service_name,
NMNamedManager *named_manager)
{
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 (service_name != 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->refcount = 1;
@ -71,8 +74,6 @@ NMVPNConnection *nm_vpn_connection_new (const char *name, const char *user_name,
g_object_ref (named_manager);
connection->named_manager = named_manager;
connection->dbus_connection = dbus_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;
int num_routes = -1;
char ** routes;
DBusConnection *dbus_connection;
NMDBusManager * dbus_mgr = NULL;
g_return_val_if_fail (connection != NULL, FALSE);
g_return_val_if_fail (dev != 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 */
if (vpn_iface != NULL && strlen (vpn_iface))
nm_vpn_connection_set_vpn_iface (connection, vpn_iface);
nm_vpn_connection_set_parent_device (connection, dev);
nm_vpn_connection_set_ip4_config (connection, ip4_config);
routes = nm_dbus_vpn_get_routes (connection->dbus_connection, connection, &num_routes);
nm_system_vpn_device_set_from_ip4_config (connection->named_manager, connection->parent_dev,
connection->vpn_iface, connection->ip4_config, routes, 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,
connection->vpn_iface,
connection->ip4_config,
routes,
num_routes);
g_strfreev(routes);
success = TRUE;
out:
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,
NMNamedManager *named_manager, DBusConnection *dbus_connection);
NMNamedManager *named_manager);
void nm_vpn_connection_ref (NMVPNConnection *con);
void nm_vpn_connection_unref (NMVPNConnection *con);

View file

@ -32,6 +32,7 @@
#include "nm-vpn-service.h"
#include "nm-dbus-vpn.h"
#include "nm-utils.h"
#include "nm-dbus-manager.h"
#define VPN_SERVICE_FILE_PATH SYSCONFDIR"/NetworkManager/VPN"
@ -42,6 +43,7 @@ struct NMVPNManager
GSList * connections;
NMVPNActRequest * act_req;
NMDbusMethodList * dbus_methods;
};
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 * manager;
NMDBusManager * dbus_mgr;
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->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);
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;
}
@ -86,8 +97,10 @@ void nm_vpn_manager_dispose (NMVPNManager *manager)
g_hash_table_destroy (manager->service_table);
nm_dbus_method_list_unref (manager->dbus_methods);
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.
*
*/
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;
NMVPNService * service;
DBusConnection * dbus_connection;
NMDBusManager * dbus_mgr = NULL;
GSList * elt;
g_return_val_if_fail (manager != 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)))
return NULL;
if ((connection = nm_vpn_connection_new (name, user_name, service_name, manager->app_data->named_manager,
manager->app_data->dbus_connection)))
{
GSList *elt;
/* Remove the existing connection if found */
for (elt = manager->connections; elt; elt = g_slist_next (elt))
{
NMVPNConnection *con = (NMVPNConnection *)(elt->data);
if (con && nm_vpn_connection_get_name (con) && (strcmp (nm_vpn_connection_get_name (con), name) == 0))
{
manager->connections = g_slist_remove_link (manager->connections, elt);
nm_vpn_connection_unref (con);
g_slist_free (elt);
}
}
/* Add in the updated connection */
manager->connections = g_slist_append (manager->connections, connection);
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;
}
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 */
for (elt = manager->connections; elt; elt = g_slist_next (elt)) {
NMVPNConnection *con = (NMVPNConnection *)(elt->data);
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);
nm_vpn_connection_unref (con);
g_slist_free (elt);
}
/* Add in the updated connection */
manager->connections = g_slist_append (manager->connections, connection);
out:
g_object_unref (dbus_mgr);
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
*

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);
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_connection_died (NMVPNManager *manager, NMVPNActRequest *req);

View file

@ -25,12 +25,16 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dbus/dbus.h>
#include <sys/types.h>
#include <signal.h>
#include "NetworkManagerDbus.h"
#include "nm-dbus-vpn.h"
#include "nm-vpn-service.h"
#include "nm-vpn-act-request.h"
#include "nm-utils.h"
#include "dbus-dict-helpers.h"
#include "nm-dbus-manager.h"
/* define this for getting VPN debug messages */
#undef NM_DEBUG_VPN_CONFIG
@ -38,9 +42,12 @@
struct NMVPNService
{
int refcount;
NMVPNManager * manager;
NMData * app_data;
gboolean watch_active;
NMVPNManager * manager;
NMData * app_data;
GPid pid;
gulong watch_id;
gulong dbus_con_watch_id;
NMDBusManager * dbus_mgr;
char * name;
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_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
static void print_vpn_config (NMIP4Config *config,
const char *tundev,
@ -80,6 +102,7 @@ NMVPNService *nm_vpn_service_new (NMVPNManager *manager, NMData *app_data)
service->state = NM_VPN_STATE_SHUTDOWN;
service->app_data = app_data;
service->manager = manager;
service->dbus_mgr = nm_dbus_manager_get (NULL);
return service;
}
@ -99,9 +122,11 @@ void nm_vpn_service_unref (NMVPNService *service)
service->refcount--;
if (service->refcount <= 0)
{
nm_vpn_service_remove_watch (service);
g_free (service->name);
g_free (service->service);
g_free (service->program);
g_object_unref (service->dbus_mgr);
memset (service, 0, sizeof (NMVPNService));
g_free (service);
}
@ -143,7 +168,7 @@ void nm_vpn_service_set_service_name (NMVPNService *service, const char *name)
service->service = g_strdup (name);
/* 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);
}
@ -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
*
@ -283,7 +300,7 @@ void nm_vpn_service_start_connection (NMVPNService *service, NMVPNActRequest *re
/* Start the daemon if it's not already running */
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);
else
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;
GPtrArray * vpn_argv;
GError * error = NULL;
GPid pid;
gboolean launched = FALSE;
g_assert (req != NULL);
@ -320,19 +337,32 @@ 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, 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);
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);
nm_vpn_service_act_request_failed (service, req);
goto out;
}
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_vpn_connection_get_name (vpn), service->service, pid);
nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) ran VPN "
"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_vpn_connection_get_name (vpn));
nm_vpn_connection_get_name (vpn));
nm_vpn_service_schedule_stage2_daemon_wait (service, req);
@ -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) "
"waiting...", nm_vpn_connection_get_name (vpn));
service_exists = dbus_bus_name_has_owner (service->app_data->dbus_connection,
service->service, NULL);
service_exists = nm_dbus_manager_name_has_owner (service->dbus_mgr,
service->service);
if (service_exists && (service->state == NM_VPN_STATE_STOPPED))
{
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;
DBusMessage * message;
DBusPendingCall * pcall = NULL;
DBusConnection * dbus_connection;
gboolean success = FALSE;
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);
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);
/* Send the start vpn request to the daemon */
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);
if (!message)
{
nm_warning ("(VPN Service %s): couldn't allocate dbus message.", service->service);
nm_vpn_service_act_request_failed (service, req);
return FALSE;
if (!message) {
nm_warning ("VPN Activation (%s) Stage 3 of 4 (Connect): couldn't "
" allocate dbus message.",
service->service);
goto out;
}
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_INVALID);
dbus_connection_send_with_reply (service->app_data->dbus_connection, message, &pcall, -1);
if (pcall)
{
dbus_pending_call_set_notify (pcall, nm_vpn_service_stage3_connect_cb, req, NULL);
dbus_connection_send_with_reply (dbus_connection, message, &pcall, -1);
if (pcall) {
dbus_pending_call_set_notify (pcall,
nm_vpn_service_stage3_connect_cb,
req,
NULL);
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);
out:
if (!success)
nm_vpn_service_act_request_failed (service, req);
return FALSE;
}
@ -711,8 +760,9 @@ get_dbus_string_helper (DBusMessageIter *iter,
*/
static void
nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
NMVPNActRequest *req,
DBusMessage *message)
NMVPNActRequest *req,
DBusConnection *dbus_connection,
DBusMessage *message)
{
NMVPNConnection * vpn;
guint32 num;
@ -722,7 +772,7 @@ nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
gboolean success = FALSE;
DBusMessageIter iter;
DBusMessageIter subiter;
NMIP4Config * config;
NMIP4Config * config = NULL;
NMDevice * parent_dev;
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);
/* 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"
" from VPN IP Config message.");
goto out;
@ -772,15 +821,13 @@ nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
/* Sixth arg: IP4 DNS Server Addresses (ARRAY, UINT32) */
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"
" from VPN IP Config message.");
goto out;
}
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);
if (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) */
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"
" from VPN IP Config message.");
goto out;
}
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);
/* We don't do anything with these yet */
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)))
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_vpn_connection_get_name (vpn));
if (login_banner && strlen (login_banner))
nm_dbus_vpn_signal_vpn_login_banner (service->app_data->dbus_connection, vpn, login_banner);
if (login_banner && strlen (login_banner)) {
nm_dbus_vpn_signal_vpn_login_banner (dbus_connection,
vpn,
login_banner);
}
success = TRUE;
nm_vpn_service_activation_success (service, req);
}
out:
if (!success)
{
if (!success) {
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);
}
}
@ -876,6 +924,7 @@ nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
NMIP4Config * config = NULL;
NMDevice * parent_dev;
NMUDictEntry entry = { .type = DBUS_TYPE_STRING };
DBusConnection *dbus_connection;
g_return_if_fail (service != 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_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);
/* 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_vpn_service_stage4_ip4_config_get_old (service, req, message);
nm_vpn_service_stage4_ip4_config_get_old (service,
req,
dbus_connection,
message);
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"
" from VPN IP Config message.");
goto out;
@ -908,17 +966,14 @@ nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
nm_ip4_config_set_secondary (config, TRUE);
/* 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"
" from VPN IP Config message.");
goto out;
}
while (nmu_dbus_dict_has_dict_entry (&iter_dict))
{
if (!nmu_dbus_dict_get_entry (&iter_dict, &entry))
{
while (nmu_dbus_dict_has_dict_entry (&iter_dict)) {
if (!nmu_dbus_dict_get_entry (&iter_dict, &entry)) {
nm_warning ("Error: couldn't read dict entry"
" from VPN IP Config message.");
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)))
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_vpn_connection_get_name (vpn));
if (login_banner && strlen (login_banner))
nm_dbus_vpn_signal_vpn_login_banner (service->app_data->dbus_connection, vpn, login_banner);
if (login_banner && strlen (login_banner)) {
nm_dbus_vpn_signal_vpn_login_banner (dbus_connection,
vpn,
login_banner);
}
success = TRUE;
nm_vpn_service_activation_success (service, req);
}
@ -977,33 +1034,54 @@ nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
out:
if (tundev) g_free (tundev);
if (login_banner) g_free (login_banner);
if (!success)
{
nm_ip4_config_unref (config);
nm_warning ("(VPN Service %s): did not receive valid IP config information.", service->service);
if (!success) {
if (config)
nm_ip4_config_unref (config);
nm_warning ("(VPN Service %s): did not receive valid IP config "
"information.",
service->service);
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;
char * op;
DBusConnection * dbus_connection;
g_return_if_fail (service != NULL);
/* Construct a new method call with the correct service and object path */
op = construct_op_from_service_name (service->service);
if ((message = dbus_message_new_method_call (service->service, op, service->service, "stopConnection")))
{
dbus_connection_send (service->app_data->dbus_connection, message, NULL);
dbus_message_unref (message);
}
else
nm_warning ("(VPN Service %s): couldn't allocate dbus message.", service->service);
dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
if (dbus_connection) {
DBusMessage * message;
char * op;
g_free (op);
/* Construct a new method call with the correct service and object path */
op = construct_op_from_service_name (service->service);
message = dbus_message_new_method_call (service->service,
op,
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);
}
} else {
/* If we have the PID of the VPN service daemon, send it a TERM */
if (service->pid) {
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);
if (service->watch_active)
if (service->watch_id)
return;
/* Add a dbus filter for this connection's service name so its signals
* get delivered to us.
*/
match_string = g_strdup_printf ("type='signal',"
"interface='%s',"
"sender='%s'", service->service, service->service);
dbus_bus_add_match (service->app_data->dbus_connection, match_string, NULL);
g_free (match_string);
service->watch_active = TRUE;
nm_dbus_manager_register_signal_handler (service->dbus_mgr,
service->service,
NULL,
nm_vpn_service_process_signal,
service);
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);
if (!service->watch_active)
if (!service->watch_id)
return;
match_string = g_strdup_printf ("type='signal',"
"interface='%s',"
"sender='%s'", service->service, service->service);
dbus_bus_remove_match (service->app_data->dbus_connection, match_string, NULL);
g_free (match_string);
service->watch_active = FALSE;
nm_dbus_manager_remove_signal_handler (service->dbus_mgr, service->service);
g_signal_handler_disconnect (service->dbus_mgr, service->watch_id);
service->watch_id = 0;
g_signal_handler_disconnect (service->dbus_mgr, service->dbus_con_watch_id);
service->dbus_con_watch_id = 0;
}
@ -1080,96 +1162,158 @@ 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)));
}
gboolean nm_vpn_service_name_owner_changed (NMVPNService *service, NMVPNActRequest *req, const char *old, const char *new)
static void
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;
gboolean valid_vpn = FALSE;
gboolean old_owner_good = (old && strlen (old));
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)))
valid_vpn = same_service_name (service, vpn);
if (!old_owner_good && new_owner_good)
{
if (!old_owner_good && new_owner_good) {
/* VPN service started. */
nm_vpn_service_add_watch (service);
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. */
nm_vpn_service_set_state (service, NM_VPN_STATE_SHUTDOWN);
nm_vpn_service_remove_watch (service);
if (valid_vpn)
{
if (valid_vpn) {
nm_vpn_act_request_unref (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;
NMVPNActRequest * req;
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 (service != NULL, FALSE);
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 ( dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED)
|| dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED)
|| dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED)
|| dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD)
|| dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
if ( dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED)
|| dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED)
|| dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED)
|| dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD)
|| dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
{
const char * member = dbus_message_get_member (message);
char * error_msg;
if (valid_vpn)
{
if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &error_msg, DBUS_TYPE_INVALID))
if (valid_vpn) {
if (!dbus_message_get_args (message,
NULL,
DBUS_TYPE_STRING, &error_msg,
DBUS_TYPE_INVALID)) {
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 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 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);
/* If the VPN daemon state is now stopped and it was starting, clear the active connection */
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)
{
/* If the VPN daemon state is now stopped and it was starting,
* clear the active connection.
*/
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_manager_schedule_vpn_connection_died (service->manager, req);
}
}
}
else if (valid_vpn && dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_IP4_CONFIG))
} else if ( valid_vpn
&& dbus_message_is_signal (message, service->service,
NM_DBUS_VPN_SIGNAL_IP4_CONFIG)) {
nm_vpn_service_stage4_ip4_config_get (service, req, message);
}
return TRUE;
}

View file

@ -46,12 +46,7 @@ void nm_vpn_service_set_service_name (NMVPNService *service, const char *name)
const char * nm_vpn_service_get_program (NMVPNService *service);
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);
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);
NMVPNState nm_vpn_service_get_state (NMVPNService *service);
void nm_vpn_service_start_connection (NMVPNService *service, NMVPNActRequest *req);
void nm_vpn_service_stop_connection (NMVPNService *service, NMVPNActRequest *req);