2008-04-07 Dan Williams <dcbw@redhat.com>

* introspection/nm-settings-system.xml
	  introspection/Makefile.am
		- Define the unmanaged devices interface for the system settings service

	* system-settings/src/nm-system-config-hal-manager.c
	  system-settings/src/nm-system-config-hal-manager.h
	  system-settings/src/nm-system-config-hal-manager-private.h
	  system-settings/src/Makefile.am
		- Add a lightweight HAL manager object for tracking network devices for
			the purpose of determining unmanaged devices and which devices need
			the default DHCP connections

	* system-settings/src/nm-system-config-interface.c
	  system-settings/src/nm-system-config-interface.h
		- (nm_system_config_interface_init): add the HAL manager as an argument
		- (nm_system_config_interface_get_unmanaged_devices): implement
		- Define 'unmanaged-devices-changed' signal

	* system-settings/src/dbus-settings.c
	  system-settings/src/dbus-settings.h
		- Implement the unmanaged devices interface; some cleanups

	* system-settings/plugins/ifcfg-suse/plugin.c
		- Fixup for plugin interface changes

	* system-settings/plugins/ifcfg-fedora/plugin.c
		- (get_ether_device_udi): new function; find the device that has
			a specified MAC address and return its UDI
		- (get_udi_for_connection): new function; try to find the specific
			device a connection is locked to, if any
		- (device_added_cb, device_removed_cb): update unmanaged device list in
			response to HAL events
		- (get_unmanaged_devices): new function; return unmanaged device list
		- (build_one_connection): set the connection's locked device, if any
		- (write_auto_wired_connection): remove
		- (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found
		- (handle_connection_changed): alert listeners that the unmanaged device
			list has changed
		- (init): fixup for plugin interface changes, implement unmanaged devices

	* system-settings/plugins/ifcfg-fedora/parser.c
	  system-settings/plugins/ifcfg-fedora/parser.h
		- (connection_data_free): clean up connection UDI



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3537 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2008-04-08 01:36:39 +00:00
parent dcbfae2c1e
commit 67149b36f4
15 changed files with 1090 additions and 91 deletions

View file

@ -1,3 +1,49 @@
2008-04-07 Dan Williams <dcbw@redhat.com>
* introspection/nm-settings-system.xml
introspection/Makefile.am
- Define the unmanaged devices interface for the system settings service
* system-settings/src/nm-system-config-hal-manager.c
system-settings/src/nm-system-config-hal-manager.h
system-settings/src/nm-system-config-hal-manager-private.h
system-settings/src/Makefile.am
- Add a lightweight HAL manager object for tracking network devices for
the purpose of determining unmanaged devices and which devices need
the default DHCP connections
* system-settings/src/nm-system-config-interface.c
system-settings/src/nm-system-config-interface.h
- (nm_system_config_interface_init): add the HAL manager as an argument
- (nm_system_config_interface_get_unmanaged_devices): implement
- Define 'unmanaged-devices-changed' signal
* system-settings/src/dbus-settings.c
system-settings/src/dbus-settings.h
- Implement the unmanaged devices interface; some cleanups
* system-settings/plugins/ifcfg-suse/plugin.c
- Fixup for plugin interface changes
* system-settings/plugins/ifcfg-fedora/plugin.c
- (get_ether_device_udi): new function; find the device that has
a specified MAC address and return its UDI
- (get_udi_for_connection): new function; try to find the specific
device a connection is locked to, if any
- (device_added_cb, device_removed_cb): update unmanaged device list in
response to HAL events
- (get_unmanaged_devices): new function; return unmanaged device list
- (build_one_connection): set the connection's locked device, if any
- (write_auto_wired_connection): remove
- (kill_old_auto_wired_file): remove the ifcfg-Auto Wired file if found
- (handle_connection_changed): alert listeners that the unmanaged device
list has changed
- (init): fixup for plugin interface changes, implement unmanaged devices
* system-settings/plugins/ifcfg-fedora/parser.c
system-settings/plugins/ifcfg-fedora/parser.h
- (connection_data_free): clean up connection UDI
2008-04-07 Dan Williams <dcbw@redhat.com>
* system-settings/plugins/ifcfg-fedora/parser.c

View file

@ -9,6 +9,7 @@ EXTRA_DIST = \
nm-manager.xml \
nm-manager-client.xml \
nm-settings.xml \
nm-settings-system.xml \
nm-exported-connection.xml \
nm-vpn-plugin.xml \
nm-vpn-connection.xml \

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManagerSettings.System">
<tp:docstring>
Implemented by the system settings service to provide additional settings to NetworkManager.
</tp:docstring>
<property name="UnmanagedDevices" type="ao" access="read">
<tp:docstring>
The list of HAL UDIs of devices that should not be managed by NetworkManager.
</tp:docstring>
</property>
<signal name="PropertiesChanged">
<arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
<tp:docstring>
A dictionary mapping property names to variant boxed values
</tp:docstring>
</arg>
</signal>
</interface>
</node>

View file

@ -112,6 +112,8 @@ connection_data_free (gpointer userdata)
g_hash_table_destroy (cdata->ppp_secrets);
g_free (cdata->ifcfg_path);
g_free (cdata->udi);
memset (cdata, 0, sizeof (ConnectionData));
g_free (cdata);
}

View file

@ -35,6 +35,7 @@
typedef struct {
char *ifcfg_path;
char *udi;
gboolean ignored;
gboolean exported;

View file

@ -26,12 +26,21 @@
#include <sys/inotify.h>
#include <unistd.h>
#include <errno.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <dbus/dbus-glib.h>
#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
#include <nm-setting-wireless.h>
#include <nm-setting-gsm.h>
#include <nm-setting-cdma.h>
#include <nm-setting-pppoe.h>
#include <nm-setting-wireless-security.h>
#include <nm-setting-8021x.h>
#include "nm-dbus-glib-types.h"
#include "plugin.h"
#include "parser.h"
#include "shvar.h"
@ -53,6 +62,10 @@ G_DEFINE_TYPE_EXTENDED (SCPluginIfcfg, sc_plugin_ifcfg, G_TYPE_OBJECT, 0,
typedef struct {
gboolean initialized;
DBusGConnection *g_connection;
NMSystemConfigHalManager *hal_mgr;
GSList *connections;
int ifd;
@ -72,31 +85,186 @@ ifcfg_plugin_error_quark (void)
return error_quark;
}
#define AUTO_WIRED_STAMP_FILE SYSCONFDIR"/NetworkManager/auto-wired-stamp"
#define AUTO_WIRED_FILE_NAME _("Auto Wired")
static char *
get_ether_device_udi (SCPluginIfcfg *plugin, GByteArray *mac, GSList *devices)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GError *error = NULL;
GSList *iter;
char *udi = NULL;
if (!priv->g_connection || !mac)
return NULL;
for (iter = devices; !udi && iter; iter = g_slist_next (iter)) {
DBusGProxy *dev_proxy;
char *address = NULL;
dev_proxy = dbus_g_proxy_new_for_name (priv->g_connection,
"org.freedesktop.Hal",
iter->data,
"org.freedesktop.Hal.Device");
if (!dev_proxy)
continue;
if (dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyString", 10000, &error,
G_TYPE_STRING, "net.address", G_TYPE_INVALID,
G_TYPE_STRING, &address, G_TYPE_INVALID)) {
struct ether_addr *dev_mac;
if (address && strlen (address)) {
dev_mac = ether_aton (address);
if (!memcmp (dev_mac->ether_addr_octet, mac->data, ETH_ALEN))
udi = g_strdup (iter->data);
}
} else {
g_error_free (error);
error = NULL;
}
g_free (address);
g_object_unref (dev_proxy);
}
return udi;
}
static NMDeviceType
get_device_type_for_connection (NMConnection *connection)
{
NMDeviceType devtype = DEVICE_TYPE_UNKNOWN;
NMSettingConnection *s_con;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
if (!s_con)
return DEVICE_TYPE_UNKNOWN;
if ( !strcmp (s_con->type, NM_SETTING_WIRED_SETTING_NAME)
|| !strcmp (s_con->type, NM_SETTING_PPPOE_SETTING_NAME)) {
if (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED))
devtype = DEVICE_TYPE_802_3_ETHERNET;
} else if (!strcmp (s_con->type, NM_SETTING_WIRELESS_SETTING_NAME)) {
if (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS))
devtype = DEVICE_TYPE_802_11_WIRELESS;
} else if (!strcmp (s_con->type, NM_SETTING_GSM_SETTING_NAME)) {
if (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM))
devtype = DEVICE_TYPE_GSM;
} else if (!strcmp (s_con->type, NM_SETTING_CDMA_SETTING_NAME)) {
if (nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA))
devtype = DEVICE_TYPE_CDMA;
}
return devtype;
}
static char *
get_udi_for_connection (SCPluginIfcfg *plugin, NMConnection *connection, NMDeviceType devtype)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
NMSettingWired *s_wired;
NMSettingWireless *s_wireless;
char *udi = NULL;
GSList *devices = NULL;
if (devtype == DEVICE_TYPE_UNKNOWN)
devtype = get_device_type_for_connection (connection);
switch (devtype) {
case DEVICE_TYPE_802_3_ETHERNET:
s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED);
if (s_wired) {
devices = nm_system_config_hal_manager_get_devices_of_type (priv->hal_mgr, DEVICE_TYPE_802_3_ETHERNET);
udi = get_ether_device_udi (plugin, s_wired->mac_address, devices);
}
break;
case DEVICE_TYPE_802_11_WIRELESS:
s_wireless = (NMSettingWireless *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS);
if (s_wireless) {
devices = nm_system_config_hal_manager_get_devices_of_type (priv->hal_mgr, DEVICE_TYPE_802_11_WIRELESS);
udi = get_ether_device_udi (plugin, s_wireless->mac_address, devices);
}
break;
default:
break;
}
g_slist_foreach (devices, (GFunc) g_free, NULL);
g_slist_free (devices);
return udi;
}
static void
write_auto_wired_connection (const char *profile_path)
device_added_cb (NMSystemConfigHalManager *hal_mgr,
const char *udi,
NMDeviceType devtype,
gpointer user_data)
{
GError *error = NULL;
char *path;
const char *contents = "# Written by nm-system-settings\nTYPE=Ethernet\nBOOTPROTO=dhcp\nONBOOT=yes\nUSERCTL=yes\nPEERDNS=yes\n";
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GSList *iter;
gboolean changed = FALSE;
/* Write out a default autoconnect ethernet connection */
if (g_file_test (AUTO_WIRED_STAMP_FILE, G_FILE_TEST_EXISTS) || !profile_path)
return;
/* Try to get the UDI for all connections that don't have a UDI yet */
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
NMConnection *connection = NM_CONNECTION (iter->data);
ConnectionData *cdata = connection_data_get (connection);
path = g_strdup_printf ("%s/ifcfg-%s", profile_path, AUTO_WIRED_FILE_NAME);
if (g_file_test (path, G_FILE_TEST_EXISTS))
return;
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "writing default Auto Wired connection");
if (!g_file_set_contents (path, contents, -1, &error)) {
PLUGIN_WARN (IFCFG_PLUGIN_NAME, "could not write default wired connection: %s (%d).", error->message, error->code);
g_error_free (error);
} else {
g_file_set_contents (AUTO_WIRED_STAMP_FILE, "", -1, NULL);
if (!cdata->udi) {
cdata->udi = get_udi_for_connection (plugin, connection, devtype);
if (cdata->udi && cdata->ignored)
changed = TRUE;
}
}
if (changed)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
}
static void
device_removed_cb (NMSystemConfigHalManager *hal_mgr,
const char *udi,
NMDeviceType devtype,
gpointer user_data)
{
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (user_data);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GSList *iter;
gboolean changed = FALSE;
/* Try to get the UDI for all connections that don't have a UDI yet */
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
NMConnection *connection = NM_CONNECTION (iter->data);
ConnectionData *cdata = connection_data_get (connection);
if (cdata->udi && !strcmp (cdata->udi, udi)) {
g_free (cdata->udi);
cdata->udi = NULL;
if (cdata->ignored)
changed = TRUE;
}
}
if (changed)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
}
static GSList *
get_unmanaged_devices (NMSystemConfigInterface *config)
{
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GSList *copy = NULL, *iter;
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
ConnectionData *cdata = connection_data_get (NM_CONNECTION (iter->data));
if (cdata->ignored && cdata->udi)
copy = g_slist_append (copy, g_strdup (cdata->udi));
}
return copy;
}
struct FindInfo {
@ -143,7 +311,7 @@ watch_path (const char *path, const int inotify_fd, GHashTable *table)
}
static NMConnection *
build_one_connection (const char *path)
build_one_connection (SCPluginIfcfg *plugin, const char *path)
{
NMConnection *connection;
GError *error = NULL;
@ -155,6 +323,9 @@ build_one_connection (const char *path)
connection = parser_parse_file (path, &error);
if (connection) {
NMSettingConnection *s_con;
ConnectionData *cdata = connection_data_get (connection);
cdata->udi = get_udi_for_connection (plugin, connection, DEVICE_TYPE_UNKNOWN);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
@ -169,7 +340,8 @@ build_one_connection (const char *path)
}
static NMConnection *
handle_new_ifcfg (const char *basename,
handle_new_ifcfg (SCPluginIfcfg *plugin,
const char *basename,
const int inotify_fd,
GHashTable *watch_table)
{
@ -187,7 +359,7 @@ handle_new_ifcfg (const char *basename,
return NULL;
}
connection = build_one_connection (path);
connection = build_one_connection (plugin, path);
if (!connection)
goto out;
@ -204,8 +376,8 @@ handle_new_ifcfg (const char *basename,
cdata = connection_data_get (connection);
if (cdata->ignored) {
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' because "
"NM_CONTROLLED was false.", basename);
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its "
"device because NM_CONTROLLED was false.", basename);
}
out:
@ -252,14 +424,47 @@ clear_all_connections (SCPluginIfcfg *plugin)
}
}
static void
kill_old_auto_wired_file (void)
{
char *path;
const char *match = "# Written by nm-system-settings\nTYPE=Ethernet\nBOOTPROTO=dhcp\nONBOOT=yes\nUSERCTL=yes\nPEERDNS=yes\n";
char *contents = NULL;
gsize length = 0;
path = g_strdup_printf (IFCFG_DIR "/ifcfg-Auto Wired");
if (!g_file_test (path, G_FILE_TEST_EXISTS)) {
g_free (path);
return;
}
if (!g_file_get_contents (path, &contents, &length, NULL))
goto out;
if (!length && !contents)
goto out;
if ( (length != strlen (match))
&& (length != (strlen (match) - 1))
&& (length != (strlen (match) + 1)))
goto out;
if (strncmp (contents, match, MIN (length, strlen (match))))
goto out;
unlink (path);
out:
g_free (contents);
g_free (path);
}
static void
read_all_connections (SCPluginIfcfg *plugin)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GDir *dir;
const char *item;
GSList *iter;
gboolean have_wired = FALSE;
clear_all_connections (plugin);
@ -269,31 +474,25 @@ read_all_connections (SCPluginIfcfg *plugin)
if (dir) {
while ((item = g_dir_read_name (dir))) {
NMConnection *connection;
ConnectionData *cdata;
if (strncmp (item, IFCFG_TAG, strlen (IFCFG_TAG)))
continue;
connection = handle_new_ifcfg (item, priv->ifd, priv->watch_table);
if (connection)
connection = handle_new_ifcfg (plugin, item, priv->ifd, priv->watch_table);
if (connection) {
priv->connections = g_slist_append (priv->connections, connection);
cdata = connection_data_get (connection);
if (cdata->ignored && cdata->udi)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
}
}
g_dir_close (dir);
} else {
PLUGIN_WARN (IFCFG_PLUGIN_NAME, "couldn't access network config directory '" IFCFG_DIR "'.");
}
/* Check if we need to write out the auto wired connection */
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
NMConnection *connection = NM_CONNECTION (iter->data);
NMSettingConnection *s_con;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
if (!strcmp (s_con->type, NM_SETTING_WIRED_SETTING_NAME))
have_wired = TRUE;
}
if (!have_wired)
write_auto_wired_connection (IFCFG_DIR);
kill_old_auto_wired_file ();
}
static GSList *
@ -427,7 +626,7 @@ handle_connection_changed (SCPluginIfcfg *plugin,
}
/* Could return NULL if the connection got deleted */
new_connection = build_one_connection (filename);
new_connection = build_one_connection (plugin, filename);
existing = find_connection_by_path (priv->connections, filename);
if (!existing) {
@ -440,6 +639,11 @@ handle_connection_changed (SCPluginIfcfg *plugin,
if (!new_cdata->ignored) {
new_cdata->exported = TRUE;
g_signal_emit_by_name (plugin, "connection-added", new_connection);
} else {
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its "
"device because NM_CONTROLLED was false.", basename);
if (new_cdata->udi)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
}
}
g_free (filename);
@ -466,24 +670,34 @@ handle_connection_changed (SCPluginIfcfg *plugin,
g_assert (new_cdata);
connection_data_copy_secrets (new_cdata, existing_cdata);
g_free (existing_cdata->udi);
existing_cdata->udi = new_cdata->udi ? g_strdup (new_cdata->udi) : NULL;
if (new_cdata->ignored && !existing_cdata->ignored) {
/* connection now ignored */
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its "
"device because NM_CONTROLLED was false.", basename);
existing_cdata->ignored = TRUE;
g_signal_emit_by_name (plugin, "connection-removed", existing);
existing_cdata->exported = FALSE;
if (existing_cdata->udi)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
} else if (!new_cdata->ignored && existing_cdata->ignored) {
/* connection no longer ignored, let the system settings
* service know about it now.
*/
existing_cdata->ignored = FALSE;
existing_cdata->exported = TRUE;
if (existing_cdata->udi)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
g_signal_emit_by_name (plugin, "connection-added", existing);
} else if (!new_cdata->ignored && !existing_cdata->ignored) {
/* connection updated and not ignored */
g_signal_emit_by_name (plugin, "connection-updated", existing);
} else if (new_cdata->ignored && existing_cdata->ignored) {
/* do nothing */
if (existing_cdata->udi)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
}
}
g_object_unref (new_connection);
@ -495,6 +709,10 @@ handle_connection_changed (SCPluginIfcfg *plugin,
priv->connections = g_slist_remove (priv->connections, existing);
if (!existing_cdata->ignored)
g_signal_emit_by_name (plugin, "connection-removed", existing);
else {
if (existing_cdata->udi)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
}
g_object_unref (existing);
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " removed connection");
}
@ -521,7 +739,7 @@ handle_new_item (SCPluginIfcfg *plugin, const char *basename)
return;
/* New connection */
connection = handle_new_ifcfg (basename, priv->ifd, priv->watch_table);
connection = handle_new_ifcfg (plugin, basename, priv->ifd, priv->watch_table);
if (!connection)
return;
@ -533,6 +751,9 @@ handle_new_item (SCPluginIfcfg *plugin, const char *basename)
if (!cdata->ignored) {
cdata->exported = TRUE;
g_signal_emit_by_name (plugin, "connection-added", connection);
} else {
if (cdata->udi)
g_signal_emit_by_name (plugin, "unmanaged-devices-changed");
}
}
@ -665,9 +886,10 @@ sc_plugin_inotify_init (SCPluginIfcfg *plugin, GError **error)
}
static void
init (NMSystemConfigInterface *config)
init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager)
{
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (config);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GError *error = NULL;
if (!sc_plugin_inotify_init (plugin, &error)) {
@ -675,17 +897,38 @@ init (NMSystemConfigInterface *config)
error->message ? error->message : "(unknown)");
g_error_free (error);
}
priv->hal_mgr = g_object_ref (hal_manager);
g_signal_connect (priv->hal_mgr, "device-added", G_CALLBACK (device_added_cb), config);
g_signal_connect (priv->hal_mgr, "device-removed", G_CALLBACK (device_removed_cb), config);
}
static void
sc_plugin_ifcfg_init (SCPluginIfcfg *plugin)
{
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
GError *error = NULL;
priv->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (!priv->g_connection) {
PLUGIN_PRINT (IFCFG_PLUGIN_NAME, " dbus-glib error: %s",
error->message ? error->message : "(unknown)");
g_free (error);
}
}
static void
dispose (GObject *object)
{
clear_all_connections (SC_PLUGIN_IFCFG (object));
SCPluginIfcfg *plugin = SC_PLUGIN_IFCFG (object);
SCPluginIfcfgPrivate *priv = SC_PLUGIN_IFCFG_GET_PRIVATE (plugin);
clear_all_connections (plugin);
g_object_unref (priv->hal_mgr);
if (priv->g_connection)
g_object_unref (priv->g_connection);
G_OBJECT_CLASS (sc_plugin_ifcfg_parent_class)->dispose (object);
}
@ -739,6 +982,7 @@ system_config_interface_init (NMSystemConfigInterface *system_config_interface_c
/* interface implementation */
system_config_interface_class->get_connections = get_connections;
system_config_interface_class->get_secrets = get_secrets;
system_config_interface_class->get_unmanaged_devices = get_unmanaged_devices;
system_config_interface_class->init = init;
}

View file

@ -326,7 +326,7 @@ ifcfg_dir_changed (GFileMonitor *monitor,
}
static void
init (NMSystemConfigInterface *config)
init (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager)
{
GFile *file;
GFileMonitor *monitor;

View file

@ -1,16 +1,23 @@
INCLUDES = -I${top_srcdir} \
-I${top_srcdir}/include \
-I${top_srcdir}/libnm-util \
-I${top_srcdir}/libnm-glib
-I${top_srcdir}/libnm-glib \
-I${top_builddir}/marshallers
sbin_PROGRAMS = nm-system-settings
BUILT_SOURCES = \
nm-settings-system-glue.h
nm_system_settings_SOURCES = \
dbus-settings.c \
dbus-settings.h \
main.c \
nm-system-config-interface.c \
nm-system-config-interface.h
nm-system-config-interface.h \
nm-system-config-hal-manager.c \
nm-system-config-hal-manager.h \
nm-system-config-hal-manager-private.h
nm_system_settings_CPPFLAGS = \
$(DBUS_CFLAGS) \
@ -32,10 +39,15 @@ nm_system_settings_LDADD = \
$(GTHREAD_LIBS) \
$(GMODULE_LIBS) \
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/libnm-glib/libnm_glib.la
$(top_builddir)/libnm-glib/libnm_glib.la \
$(top_builddir)/marshallers/libmarshallers.la
nm_system_settings_LDFLAGS = -rdynamic
nm-settings-system-glue.h: $(top_srcdir)/introspection/nm-settings-system.xml
dbus-binding-tool --prefix=nm_settings_system --mode=glib-server --output=nm-settings-system-glue.h $(top_srcdir)/introspection/nm-settings-system.xml
dbusservicedir = $(DBUS_SYS_DIR)
dbusservice_DATA = nm-system-settings.conf
@ -46,4 +58,6 @@ EXTRA_DIST = \
$(dbusservice_DATA) \
$(dbusactivation_DATA)
CLEANFILES = \
$(BUILT_SOURCES)

View file

@ -26,6 +26,7 @@
#include <nm-setting-connection.h>
#include "nm-dbus-glib-types.h"
#include "dbus-settings.h"
#include "nm-system-config-interface.h"
#include "nm-utils.h"
@ -150,7 +151,6 @@ nm_sysconfig_exported_connection_class_init (NMSysconfigExportedConnectionClass
static void
nm_sysconfig_exported_connection_init (NMSysconfigExportedConnection *sysconfig_exported_connection)
{
}
NMSysconfigExportedConnection *
@ -174,21 +174,42 @@ nm_sysconfig_exported_connection_new (NMConnection *connection,
* NMSettings
*/
#include "nm-settings-system-glue.h"
typedef struct {
GSList *connections;
GHashTable *unmanaged_devices;
} NMSysconfigSettingsPrivate;
G_DEFINE_TYPE (NMSysconfigSettings, nm_sysconfig_settings, NM_TYPE_SETTINGS);
#define NM_SYSCONFIG_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsPrivate))
enum {
PROPERTIES_CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
PROP_UNMANAGED_DEVICES,
LAST_PROP
};
static GPtrArray *
nm_sysconfig_settings_list_connections (NMSettings *settings)
list_connections (NMSettings *settings)
{
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (settings);
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GPtrArray *connections;
NMSysconfigSettings *sysconfig_settings;
GSList *iter;
g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings), NULL);
sysconfig_settings = NM_SYSCONFIG_SETTINGS (settings);
connections = g_ptr_array_new ();
for (iter = sysconfig_settings->connections; iter; iter = g_slist_next (iter)) {
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
NMExportedConnection *exported = NM_EXPORTED_CONNECTION (iter->data);
NMConnection *connection;
char *path;
@ -204,33 +225,145 @@ nm_sysconfig_settings_list_connections (NMSettings *settings)
}
static void
nm_sysconfig_settings_finalize (GObject *object)
settings_finalize (GObject *object)
{
NMSysconfigSettings *settings = NM_SYSCONFIG_SETTINGS (object);
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
if (settings->connections) {
g_slist_foreach (settings->connections, (GFunc) g_object_unref, NULL);
g_slist_free (settings->connections);
settings->connections = NULL;
if (priv->connections) {
g_slist_foreach (priv->connections, (GFunc) g_object_unref, NULL);
g_slist_free (priv->connections);
priv->connections = NULL;
}
g_hash_table_destroy (priv->unmanaged_devices);
G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object);
}
static void
add_one_unmanaged_device (gpointer key, gpointer data, gpointer user_data)
{
GPtrArray *devices = (GPtrArray *) user_data;
g_ptr_array_add (devices, g_strdup (key));
}
static char*
uscore_to_wincaps (const char *uscore)
{
const char *p;
GString *str;
gboolean last_was_uscore;
last_was_uscore = TRUE;
str = g_string_new (NULL);
p = uscore;
while (p && *p) {
if (*p == '-' || *p == '_')
last_was_uscore = TRUE;
else {
if (last_was_uscore) {
g_string_append_c (str, g_ascii_toupper (*p));
last_was_uscore = FALSE;
} else
g_string_append_c (str, *p);
}
++p;
}
return g_string_free (str, FALSE);
}
static void
notify (GObject *object, GParamSpec *pspec)
{
GValue *value;
GHashTable *hash;
value = g_slice_new0 (GValue);
hash = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, NULL);
g_value_init (value, pspec->value_type);
g_object_get_property (object, pspec->name, value);
g_hash_table_insert (hash, uscore_to_wincaps (pspec->name), value);
g_signal_emit (object, signals[PROPERTIES_CHANGED], 0, hash);
g_hash_table_destroy (hash);
g_value_unset (value);
g_slice_free (GValue, value);
}
static GPtrArray *
get_unmanaged_devices (NMSysconfigSettings *self)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GPtrArray *devices;
devices = g_ptr_array_sized_new (3);
g_hash_table_foreach (priv->unmanaged_devices, (GHFunc) add_one_unmanaged_device, devices);
return devices;
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMSysconfigSettings *self = NM_SYSCONFIG_SETTINGS (object);
switch (prop_id) {
case PROP_UNMANAGED_DEVICES:
g_value_take_boxed (value, get_unmanaged_devices (self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_sysconfig_settings_class_init (NMSysconfigSettingsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
NMSettingsClass *settings_class = NM_SETTINGS_CLASS (class);
object_class->finalize = nm_sysconfig_settings_finalize;
settings_class->list_connections = nm_sysconfig_settings_list_connections;
g_type_class_add_private (settings_class, sizeof (NMSysconfigSettingsPrivate));
/* virtual methods */
object_class->notify = notify;
object_class->get_property = get_property;
object_class->finalize = settings_finalize;
settings_class->list_connections = list_connections;
/* properties */
g_object_class_install_property
(object_class, PROP_UNMANAGED_DEVICES,
g_param_spec_boxed (NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES,
"Unamanged devices",
"Unmanaged devices",
DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH,
G_PARAM_READABLE));
/* signals */
signals[PROPERTIES_CHANGED] =
g_signal_new ("properties-changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSysconfigSettingsClass, properties_changed),
NULL, NULL,
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE, 1, DBUS_TYPE_G_MAP_OF_VARIANT);
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (settings_class),
&dbus_glib_nm_settings_system_object_info);
}
static void
nm_sysconfig_settings_init (NMSysconfigSettings *sysconfig_settings)
nm_sysconfig_settings_init (NMSysconfigSettings *self)
{
sysconfig_settings->connections = NULL;
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
priv->unmanaged_devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
NMSysconfigSettings *
@ -244,37 +377,41 @@ nm_sysconfig_settings_new (DBusGConnection *g_conn)
}
void
nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings,
nm_sysconfig_settings_add_connection (NMSysconfigSettings *self,
NMConnection *connection,
DBusGConnection *g_connection)
{
NMSysconfigSettingsPrivate *priv;
NMSysconfigExportedConnection *exported;
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings));
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
g_return_if_fail (NM_IS_CONNECTION (connection));
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
exported = nm_sysconfig_exported_connection_new (connection, g_connection);
if (!exported) {
g_warning ("%s: couldn't export the connection!", __func__);
return;
}
settings->connections = g_slist_append (settings->connections, exported);
priv->connections = g_slist_append (priv->connections, exported);
nm_settings_signal_new_connection (NM_SETTINGS (settings),
nm_settings_signal_new_connection (NM_SETTINGS (self),
NM_EXPORTED_CONNECTION (exported));
}
static void
remove_connection (NMSysconfigSettings *settings,
remove_connection (NMSysconfigSettings *self,
NMConnection *connection)
{
NMSysconfigSettingsPrivate *priv;
GSList *iter;
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings));
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
g_return_if_fail (NM_IS_CONNECTION (connection));
for (iter = settings->connections; iter; iter = g_slist_next (iter)) {
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
NMSysconfigExportedConnection *item = NM_SYSCONFIG_EXPORTED_CONNECTION (iter->data);
NMExportedConnection *exported = NM_EXPORTED_CONNECTION (item);
NMConnection *wrapped;
@ -282,7 +419,7 @@ remove_connection (NMSysconfigSettings *settings,
wrapped = nm_exported_connection_get_connection (exported);
if (wrapped == connection) {
settings->connections = g_slist_remove (settings->connections, iter);
priv->connections = g_slist_remove_link (priv->connections, iter);
nm_exported_connection_signal_removed (exported);
g_object_unref (item);
g_slist_free (iter);
@ -299,22 +436,23 @@ nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings,
}
void
nm_sysconfig_settings_update_connection (NMSysconfigSettings *settings,
nm_sysconfig_settings_update_connection (NMSysconfigSettings *self,
NMConnection *connection)
{
NMSysconfigSettingsPrivate *priv;
GHashTable *hash;
GSList *iter;
NMSysconfigExportedConnection *found = NULL;
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (settings));
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
g_return_if_fail (NM_IS_CONNECTION (connection));
for (iter = settings->connections; iter; iter = g_slist_next (iter)) {
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
for (iter = priv->connections; iter; iter = g_slist_next (iter)) {
NMSysconfigExportedConnection *item = NM_SYSCONFIG_EXPORTED_CONNECTION (iter->data);
NMConnection *wrapped;
wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (item));
if (wrapped == connection) {
found = item;
break;
@ -328,7 +466,7 @@ nm_sysconfig_settings_update_connection (NMSysconfigSettings *settings,
/* If the connection is no longer valid, it gets removed */
if (!nm_connection_verify (connection)) {
remove_connection (settings, connection);
remove_connection (self, connection);
return;
}
@ -337,3 +475,25 @@ nm_sysconfig_settings_update_connection (NMSysconfigSettings *settings,
g_hash_table_destroy (hash);
}
void
nm_sysconfig_settings_update_unamanged_devices (NMSysconfigSettings *self,
GSList *new_list)
{
NMSysconfigSettingsPrivate *priv;
GSList *iter;
g_return_if_fail (NM_IS_SYSCONFIG_SETTINGS (self));
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
g_hash_table_remove_all (priv->unmanaged_devices);
for (iter = new_list; iter; iter = g_slist_next (iter)) {
if (!g_hash_table_lookup (priv->unmanaged_devices, iter->data)) {
g_hash_table_insert (priv->unmanaged_devices,
g_strdup (iter->data),
GUINT_TO_POINTER (1));
}
}
g_object_notify (G_OBJECT (self), NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES);
}

View file

@ -43,12 +43,12 @@ typedef struct _NMSysconfigExportedConnectionClass NMSysconfigExportedConnection
struct _NMSysconfigExportedConnection
{
NMExportedConnection parent_instance;
NMExportedConnection parent_instance;
};
struct _NMSysconfigExportedConnectionClass
{
NMExportedConnectionClass parent_class;
NMExportedConnectionClass parent_class;
};
GType nm_sysconfig_exported_connection_get_type (void);
@ -68,16 +68,19 @@ typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass;
#define NM_IS_SYSCONFIG_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SYSCONFIG_SETTINGS))
#define NM_SYSCONFIG_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSCONFIG_SETTINGS, NMSysconfigSettingsClass))
#define NM_SYSCONFIG_SETTINGS_UNMANAGED_DEVICES "unmanaged-devices"
struct _NMSysconfigSettings
{
NMSettings parent_instance;
GSList *connections;
NMSettings parent_instance;
};
struct _NMSysconfigSettingsClass
{
NMSettingsClass parent_class;
NMSettingsClass parent_class;
/* Signals */
void (*properties_changed) (NMSysconfigSettings *settings, GHashTable *properties);
};
GType nm_sysconfig_settings_get_type (void);
@ -94,4 +97,7 @@ void nm_sysconfig_settings_remove_connection (NMSysconfigSettings *settings,
void nm_sysconfig_settings_update_connection (NMSysconfigSettings *settings,
NMConnection *connection);
void nm_sysconfig_settings_update_unamanged_devices (NMSysconfigSettings *settings,
GSList *new_list);
#endif /* __DBUS_SETTINGS_H__ */

View file

@ -0,0 +1,34 @@
/*
* Copyright (C) 2008 Dan Williams
*
* 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, 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.
*/
/* *** Not to be used by system settings service plugins *** */
#ifndef NM_SYSTEM_CONFIG_HAL_MANAGER_PRIVATE_H
#define NM_SYSTEM_CONFIG_HAL_MANAGER_PRIVATE_H
#include "nm-system-config-hal-manager.h"
NMSystemConfigHalManager *nm_system_config_hal_manager_get (DBusGConnection *g_connection);
void nm_system_config_hal_manager_reinit_dbus (NMSystemConfigHalManager *manager,
DBusGConnection *g_connection);
void nm_system_config_hal_manager_deinit_dbus (NMSystemConfigHalManager *manager);
#endif /* NM_SYSTEM_CONFIG_HAL_MANAGER_PRIVATE_H */

View file

@ -0,0 +1,379 @@
/*
* Copyright (C) 2008 Dan Williams
*
* 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, 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 <string.h>
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "nm-marshal.h"
#include "nm-dbus-glib-types.h"
#include "nm-system-config-hal-manager.h"
#include "nm-system-config-hal-manager-private.h"
#define NUM_DEVICE_TYPES DEVICE_TYPE_CDMA
typedef struct {
DBusGConnection *g_connection;
DBusGProxy *proxy;
GHashTable *devices;
} NMSystemConfigHalManagerPrivate;
#define NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, \
NMSystemConfigHalManagerPrivate))
G_DEFINE_TYPE (NMSystemConfigHalManager, nm_system_config_hal_manager, G_TYPE_OBJECT)
enum {
DEVICE_ADDED,
DEVICE_REMOVED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static NMDeviceType
get_type_for_udi (NMSystemConfigHalManager *manager, const char *udi)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
NMDeviceType devtype = DEVICE_TYPE_UNKNOWN;
DBusGProxy *dev_proxy;
GError *error = NULL;
GSList *capabilities = NULL, *iter;
dev_proxy = dbus_g_proxy_new_for_name (priv->g_connection,
"org.freedesktop.Hal",
udi,
"org.freedesktop.Hal.Device");
if (!dev_proxy)
return DEVICE_TYPE_UNKNOWN;
if (!dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyStringList", 10000, &error,
G_TYPE_STRING, "info.capabilities", G_TYPE_INVALID,
DBUS_TYPE_G_LIST_OF_STRING, &capabilities, G_TYPE_INVALID)) {
g_error_free (error);
goto out;
}
if (!g_slist_length (capabilities))
goto out;
for (iter = capabilities; iter && (devtype == DEVICE_TYPE_UNKNOWN); iter = g_slist_next (iter)) {
if (!strcmp (iter->data, "net.80203"))
devtype = DEVICE_TYPE_802_3_ETHERNET;
else if (!strcmp (iter->data, "net.80211"))
devtype = DEVICE_TYPE_802_11_WIRELESS;
else if (!strcmp (iter->data, "modem")) {
GSList *csets = NULL, *elt;
if (dbus_g_proxy_call_with_timeout (dev_proxy,
"GetPropertyStringList", 10000, &error,
G_TYPE_STRING, "modem.command_sets", G_TYPE_INVALID,
DBUS_TYPE_G_LIST_OF_STRING, &csets, G_TYPE_INVALID)) {
for (elt = csets; elt && (devtype == DEVICE_TYPE_UNKNOWN); elt = g_slist_next (elt)) {
if (!strcmp (elt->data, "GSM-07.07"))
devtype = DEVICE_TYPE_GSM;
else if (!strcmp (elt->data, "IS-707-A"))
devtype = DEVICE_TYPE_CDMA;
}
}
}
}
g_boxed_free (DBUS_TYPE_G_LIST_OF_STRING, capabilities);
out:
g_object_unref (dev_proxy);
return devtype;
}
static void
device_added_cb (DBusGProxy *proxy, const char *udi, gpointer user_data)
{
NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data);
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
NMDeviceType devtype;
if (!g_hash_table_lookup (priv->devices, udi)) {
devtype = get_type_for_udi (manager, udi);
if (devtype != DEVICE_TYPE_UNKNOWN) {
g_hash_table_insert (priv->devices, g_strdup (udi), GUINT_TO_POINTER (devtype));
g_signal_emit (manager, signals[DEVICE_ADDED], 0, udi, devtype);
}
}
}
static void
device_removed_cb (DBusGProxy *proxy, const char *udi, gpointer user_data)
{
NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data);
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
NMDeviceType devtype;
devtype = GPOINTER_TO_UINT (g_hash_table_lookup (priv->devices, udi));
if (devtype != DEVICE_TYPE_UNKNOWN) {
g_signal_emit (manager, signals[DEVICE_REMOVED], 0, udi, devtype);
g_hash_table_remove (priv->devices, udi);
}
}
static void
device_new_capability_cb (DBusGProxy *proxy,
const char *udi,
const char *capability,
gpointer user_data)
{
NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data);
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
NMDeviceType devtype;
if (!g_hash_table_lookup (priv->devices, udi)) {
devtype = get_type_for_udi (manager, udi);
if (devtype != DEVICE_TYPE_UNKNOWN) {
g_hash_table_insert (priv->devices, g_strdup (udi), GUINT_TO_POINTER (devtype));
g_signal_emit (manager, signals[DEVICE_ADDED], 0, udi, devtype);
}
}
}
static void
initial_add_devices_of_type (NMSystemConfigHalManager *manager, const char *capability)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
GSList *devices = NULL, *iter;
GError *error = NULL;
if (!dbus_g_proxy_call_with_timeout (priv->proxy,
"FindDeviceByCapability", 10000, &error,
G_TYPE_STRING, capability, G_TYPE_INVALID,
DBUS_TYPE_G_LIST_OF_STRING, &devices, G_TYPE_INVALID)) {
g_warning ("%s: could not get device from HAL: %s (%d).",
__func__, error->message, error->code);
g_error_free (error);
return;
}
for (iter = devices; iter; iter = g_slist_next (iter))
device_added_cb (priv->proxy, (const char *) iter->data, manager);
if (devices)
g_boxed_free (DBUS_TYPE_G_LIST_OF_STRING, devices);
}
static gboolean
init_dbus (NMSystemConfigHalManager *manager, DBusGConnection *g_connection)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
priv->g_connection = g_connection;
priv->proxy = dbus_g_proxy_new_for_name (priv->g_connection,
"org.freedesktop.Hal",
"/org/freedesktop/Hal/Manager",
"org.freedesktop.Hal.Manager");
if (!priv->proxy) {
g_warning ("Could not get the HAL object!");
priv->g_connection = NULL;
return FALSE;
}
dbus_g_proxy_add_signal (priv->proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "DeviceAdded", G_CALLBACK (device_added_cb), manager, NULL);
dbus_g_proxy_add_signal (priv->proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "DeviceRemoved", G_CALLBACK (device_removed_cb), manager, NULL);
dbus_g_object_register_marshaller (nm_marshal_VOID__STRING_STRING,
G_TYPE_NONE,
G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_INVALID);
dbus_g_proxy_add_signal (priv->proxy, "NewCapability", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "NewCapability", G_CALLBACK (device_new_capability_cb), manager, NULL);
initial_add_devices_of_type (manager, "net.80203");
initial_add_devices_of_type (manager, "net.80211");
initial_add_devices_of_type (manager, "modem");
return TRUE;
}
static void
remove_all_devices (gpointer key, gpointer data, gpointer user_data)
{
NMSystemConfigHalManager *manager = NM_SYSTEM_CONFIG_HAL_MANAGER (user_data);
g_signal_emit (manager, signals[DEVICE_REMOVED], 0, key, GPOINTER_TO_UINT (data));
}
static void
cleanup_dbus (NMSystemConfigHalManager *manager)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
g_hash_table_foreach (priv->devices, (GHFunc) remove_all_devices, manager);
g_hash_table_remove_all (priv->devices);
if (priv->proxy) {
g_object_unref (priv->proxy);
priv->proxy = NULL;
}
priv->g_connection = NULL;
}
static NMSystemConfigHalManager *
nm_system_config_hal_manager_new (DBusGConnection *g_connection)
{
NMSystemConfigHalManager *manager;
g_return_val_if_fail (g_connection != NULL, NULL);
manager = g_object_new (NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NULL);
if (!init_dbus (manager, g_connection)) {
g_object_unref (manager);
return NULL;
}
return manager;
}
NMSystemConfigHalManager *
nm_system_config_hal_manager_get (DBusGConnection *g_connection)
{
static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
static NMSystemConfigHalManager *singleton = NULL;
g_static_mutex_lock (&mutex);
if (!singleton)
singleton = nm_system_config_hal_manager_new (g_connection);
else
g_object_ref (singleton);
g_static_mutex_unlock (&mutex);
return singleton;
}
static void
nm_system_config_hal_manager_init (NMSystemConfigHalManager *manager)
{
NMSystemConfigHalManagerPrivate *priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
}
static void
dispose (GObject *object)
{
cleanup_dbus (NM_SYSTEM_CONFIG_HAL_MANAGER (object));
G_OBJECT_CLASS (nm_system_config_hal_manager_parent_class)->dispose (object);
}
static void
nm_system_config_hal_manager_class_init (NMSystemConfigHalManagerClass *manager_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
g_type_class_add_private (manager_class, sizeof (NMSystemConfigHalManagerPrivate));
/* virtual methods */
object_class->dispose = dispose;
/* signals */
signals[DEVICE_ADDED] =
g_signal_new ("device-added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSystemConfigHalManagerClass, device_added),
NULL, NULL,
nm_marshal_VOID__STRING_UINT,
G_TYPE_NONE, 2,
G_TYPE_STRING,
G_TYPE_UINT);
signals[DEVICE_REMOVED] =
g_signal_new ("device-removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSystemConfigHalManagerClass, device_removed),
NULL, NULL,
nm_marshal_VOID__STRING_UINT,
G_TYPE_NONE, 2,
G_TYPE_STRING,
G_TYPE_UINT);
}
void
nm_system_config_hal_manager_reinit_dbus (NMSystemConfigHalManager *manager,
DBusGConnection *g_connection)
{
init_dbus (manager, g_connection);
}
void
nm_system_config_hal_manager_deinit_dbus (NMSystemConfigHalManager *manager)
{
cleanup_dbus (manager);
}
typedef struct {
NMDeviceType devtype;
GSList **list;
} GetDeviceInfo;
static void
add_devices_of_type (gpointer key, gpointer data, gpointer user_data)
{
GetDeviceInfo *info = (GetDeviceInfo *) user_data;
if (GPOINTER_TO_UINT (data) == info->devtype)
*(info->list) = g_slist_append (*(info->list), g_strdup (key));
}
GSList *
nm_system_config_hal_manager_get_devices_of_type (NMSystemConfigHalManager *manager,
NMDeviceType devtype)
{
NMSystemConfigHalManagerPrivate *priv;
GetDeviceInfo info;
GSList *list = NULL;
g_return_val_if_fail (NM_IS_SYSTEM_CONFIG_HAL_MANAGER (manager), NULL);
g_return_val_if_fail (devtype <= NUM_DEVICE_TYPES, NULL);
priv = NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager);
info.devtype = devtype;
info.list = &list;
g_hash_table_foreach (priv->devices, (GHFunc) add_devices_of_type, &info);
return list;
}
DBusGProxy *
nm_system_config_hal_manager_get_hal_proxy (NMSystemConfigHalManager *manager)
{
g_return_val_if_fail (NM_IS_SYSTEM_CONFIG_HAL_MANAGER (manager), NULL);
return NM_SYSTEM_CONFIG_HAL_MANAGER_GET_PRIVATE (manager)->proxy;
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2008 Dan Williams
*
* 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, 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_SYSTEM_CONFIG_HAL_MANAGER_H
#define NM_SYSTEM_CONFIG_HAL_MANAGER_H
#include <glib/gtypes.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "NetworkManager.h"
#define NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER (nm_system_config_hal_manager_get_type ())
#define NM_SYSTEM_CONFIG_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManager))
#define NM_SYSTEM_CONFIG_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManagerClass))
#define NM_IS_SYSTEM_CONFIG_HAL_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER))
#define NM_IS_SYSTEM_CONFIG_HAL_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER))
#define NM_SYSTEM_CONFIG_HAL_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SYSTEM_CONFIG_HAL_MANAGER, NMSystemConfigHalManagerClass))
typedef struct {
GObject parent;
} NMSystemConfigHalManager;
typedef struct {
GObjectClass parent;
/* Signals */
void (*device_added) (NMSystemConfigHalManager *manager, const char *udi, NMDeviceType type);
void (*device_removed) (NMSystemConfigHalManager *manager, const char *udi, NMDeviceType type);
} NMSystemConfigHalManagerClass;
GType nm_system_config_hal_manager_get_type (void);
/* Returned list is allocated and must be freed by caller */
GSList *nm_system_config_hal_manager_get_devices_of_type (NMSystemConfigHalManager *manager, NMDeviceType devtype);
DBusGProxy *nm_system_config_hal_manager_get_hal_proxy (NMSystemConfigHalManager *manager);
#endif /* NM_SYSTEM_CONFIG_HAL_MANAGER_H */

View file

@ -76,6 +76,14 @@ interface_init (gpointer g_iface)
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
g_signal_new ("unmanaged-devices-changed",
iface_type,
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMSystemConfigInterface, unmanaged_devices_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
initialized = TRUE;
}
@ -110,12 +118,13 @@ nm_system_config_interface_get_type (void)
}
void
nm_system_config_interface_init (NMSystemConfigInterface *config)
nm_system_config_interface_init (NMSystemConfigInterface *config,
NMSystemConfigHalManager *hal_manager)
{
g_return_if_fail (config != NULL);
if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init)
NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init (config);
NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->init (config, hal_manager);
}
GSList *
@ -142,3 +151,13 @@ nm_system_config_interface_get_secrets (NMSystemConfigInterface *config,
return NULL;
}
GSList *
nm_system_config_interface_get_unmanaged_devices (NMSystemConfigInterface *config)
{
g_return_val_if_fail (config != NULL, NULL);
if (NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_devices)
return NM_SYSTEM_CONFIG_INTERFACE_GET_INTERFACE (config)->get_unmanaged_devices (config);
return NULL;
}

View file

@ -26,10 +26,12 @@
#include <glib-object.h>
#include <nm-connection.h>
#include "nm-system-config-hal-manager.h"
G_BEGIN_DECLS
#define PLUGIN_PRINT(pname, fmt, args...) \
{ g_print (" " pname ": " fmt "\n", ##args); }
{ g_message (" " pname ": " fmt, ##args); }
#define PLUGIN_WARN(pname, fmt, args...) \
{ g_warning (" " pname ": " fmt, ##args); }
@ -72,7 +74,7 @@ struct _NMSystemConfigInterface {
GTypeInterface g_iface;
/* Called when the plugin is loaded to initialize it */
void (*init) (NMSystemConfigInterface *config);
void (*init) (NMSystemConfigInterface *config, NMSystemConfigHalManager *hal_manager);
/* Returns the plugins currently known list of connections. The returned
* list is freed by the system settings service.
@ -90,6 +92,13 @@ struct _NMSystemConfigInterface {
*/
GHashTable * (*get_secrets) (NMSystemConfigInterface *config, NMConnection *connection, NMSetting *setting);
/*
* Return a list of HAL UDIs of devices which NetworkManager should not
* manage. Returned list will be freed by the system settings service, and
* each element must be allocated using g_malloc() or its variants.
*/
GSList * (*get_unmanaged_devices) (NMSystemConfigInterface *config);
/* Signals */
/* Emitted when a new connection has been found by the plugin */
@ -100,11 +109,15 @@ struct _NMSystemConfigInterface {
/* Emitted when any non-secret settings of the connection change */
void (*connection_updated) (NMSystemConfigInterface *config, NMConnection *connection);
/* Emitted when the list of unmanaged devices changes */
void (*unmanaged_devices_changed) (NMSystemConfigInterface *config);
};
GType nm_system_config_interface_get_type (void);
void nm_system_config_interface_init (NMSystemConfigInterface *config);
void nm_system_config_interface_init (NMSystemConfigInterface *config,
NMSystemConfigHalManager *hal_manager);
GSList * nm_system_config_interface_get_connections (NMSystemConfigInterface *config);
@ -112,6 +125,8 @@ GHashTable *nm_system_config_interface_get_secrets (NMSystemConfigInterface *con
NMConnection *connection,
NMSetting *setting);
GSList *nm_system_config_interface_get_unmanaged_devices (NMSystemConfigInterface *config);
G_END_DECLS
#endif /* NM_SYSTEM_CONFIG_INTERFACE_H */