2008-05-11 Dan Williams <dcbw@redhat.com>

Update Fedora system-settings plugin to support latest API and use
	GFileMonitor rather than home-rolled inotify code.

	* system-settings/plugins/ifcfg-fedora/Makefile.am
	  system-settings/plugins/ifcfg-fedora/common.h
	  system-settings/plugins/ifcfg-fedora/plugin.c
		- Update to latest system settings plugin API; use GIO instead of
			custom inotify code; use NMIfcfgConnection objects instead of
			ConnectionData structures tacked onto NMConnection objects

	* system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.c
	  system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.h
		- Implement an NMExportedConnection subclass mapping ifcfg files to
			connections

	* system-settings/plugins/ifcfg-fedora/reader.c
	  system-settings/plugins/ifcfg-fedora/reader.h
		- Move ifcfg parsing bits here from parser.c

	* system-settings/plugins/ifcfg-fedora/parser.c
	  system-settings/plugins/ifcfg-fedora/parser.h
		- Remove; most code moved to reader.c



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3656 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2008-05-11 20:20:52 +00:00
parent e7e5141860
commit ff0468d23b
9 changed files with 899 additions and 996 deletions

View file

@ -1,3 +1,28 @@
2008-05-11 Dan Williams <dcbw@redhat.com>
Update Fedora system-settings plugin to support latest API and use
GFileMonitor rather than home-rolled inotify code.
* system-settings/plugins/ifcfg-fedora/Makefile.am
system-settings/plugins/ifcfg-fedora/common.h
system-settings/plugins/ifcfg-fedora/plugin.c
- Update to latest system settings plugin API; use GIO instead of
custom inotify code; use NMIfcfgConnection objects instead of
ConnectionData structures tacked onto NMConnection objects
* system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.c
system-settings/plugins/ifcfg-fedora/nm-ifcfg-connection.h
- Implement an NMExportedConnection subclass mapping ifcfg files to
connections
* system-settings/plugins/ifcfg-fedora/reader.c
system-settings/plugins/ifcfg-fedora/reader.h
- Move ifcfg parsing bits here from parser.c
* system-settings/plugins/ifcfg-fedora/parser.c
system-settings/plugins/ifcfg-fedora/parser.h
- Remove; most code moved to reader.c
2008-05-11 Dan Williams <dcbw@redhat.com>
* configure.in

View file

@ -4,10 +4,13 @@ pkglib_LTLIBRARIES = libnm-settings-plugin-ifcfg-fedora.la
libnm_settings_plugin_ifcfg_fedora_la_SOURCES = \
shvar.c \
shvar.h \
parser.c \
parser.h \
plugin.c \
plugin.h
plugin.h \
nm-ifcfg-connection.c \
nm-ifcfg-connection.h \
reader.c \
reader.h \
common.h
libnm_settings_plugin_ifcfg_fedora_la_CPPFLAGS = \
$(GLIB_CFLAGS) \
@ -16,6 +19,7 @@ libnm_settings_plugin_ifcfg_fedora_la_CPPFLAGS = \
-DG_DISABLE_DEPRECATED \
-I${top_srcdir}/system-settings/src \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-glib \
-I$(top_srcdir)/libnm-util \
-DSYSCONFDIR=\"$(sysconfdir)\"
@ -23,5 +27,14 @@ libnm_settings_plugin_ifcfg_fedora_la_LDFLAGS = -module -avoid-version
libnm_settings_plugin_ifcfg_fedora_la_LIBADD = \
$(GLIB_LIBS) \
$(GMODULE_LIBS) \
$(top_builddir)/libnm-util/libnm-util.la
$(top_builddir)/libnm-util/libnm-util.la \
$(top_builddir)/libnm-glib/libnm_glib.la
if NO_GIO
libnm_settings_plugin_ifcfg_fedora_la_LIBADD += \
$(top_builddir)/gfilemonitor/libgfilemonitor.la
else
libnm_settings_plugin_ifcfg_fedora_la_LIBADD += \
$(GIO_LIBS)
endif

View file

@ -1,6 +1,5 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* Søren Sandmann <sandmann@daimi.au.dk>
*
* 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
@ -16,15 +15,11 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2007 Red Hat, Inc.
* (C) Copyright 2008 Red Hat, Inc.
*/
#ifndef _PARSER_H_
#define _PARSER_H_
#include <glib.h>
#include <nm-connection.h>
#include <nm-setting-ip4-config.h>
#ifndef __COMMON_H__
#define __COMMON_H__
#define IFCFG_TAG "ifcfg-"
#define KEYS_TAG "keys-"
@ -33,21 +28,10 @@
#define ORIG_TAG ".orig"
#define REJ_TAG ".rej"
typedef struct {
char *ifcfg_path;
char *udi;
gboolean ignored;
gboolean exported;
#include <glib.h>
GHashTable *wifi_secrets;
GHashTable *onex_secrets;
GHashTable *ppp_secrets;
} ConnectionData;
GQuark ifcfg_plugin_error_quark (void);
NMConnection * parser_parse_file (const char *file, GError **error);
ConnectionData *connection_data_get (NMConnection *connection);
ConnectionData *connection_data_add (NMConnection *connection, const char *ifcfg_path);
void connection_data_copy_secrets (ConnectionData *from, ConnectionData *to);
#endif /* __COMMON_H__ */
#endif /* _PARSER_H_ */

View file

@ -0,0 +1,422 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* 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.
*
* (C) Copyright 2008 Red Hat, Inc.
*/
#include <string.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <glib/gstdio.h>
#include <NetworkManager.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 "common.h"
#include "nm-ifcfg-connection.h"
#include "nm-system-config-hal-manager.h"
#include "reader.h"
G_DEFINE_TYPE (NMIfcfgConnection, nm_ifcfg_connection, NM_TYPE_EXPORTED_CONNECTION)
#define NM_IFCFG_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionPrivate))
typedef struct {
char *filename;
char *keyfile;
char *udi;
gboolean unmanaged;
NMSystemConfigHalManager *hal_mgr;
DBusGConnection *g_connection;
gulong daid;
} NMIfcfgConnectionPrivate;
enum {
PROP_0,
PROP_FILENAME,
PROP_UNMANAGED,
PROP_UDI,
LAST_PROP
};
static char *
get_ether_device_udi (DBusGConnection *g_connection, GByteArray *mac, GSList *devices)
{
GError *error = NULL;
GSList *iter;
char *udi = NULL;
if (!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 (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 (NMConnection *connection,
DBusGConnection *g_connection,
NMSystemConfigHalManager *hal_mgr,
NMDeviceType devtype)
{
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 (hal_mgr, DEVICE_TYPE_802_3_ETHERNET);
udi = get_ether_device_udi (g_connection, 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 (hal_mgr, DEVICE_TYPE_802_11_WIRELESS);
udi = get_ether_device_udi (g_connection, s_wireless->mac_address, devices);
}
break;
default:
break;
}
g_slist_foreach (devices, (GFunc) g_free, NULL);
g_slist_free (devices);
return udi;
}
static void
device_added_cb (NMSystemConfigHalManager *hal_mgr,
const char *udi,
NMDeviceType devtype,
gpointer user_data)
{
NMIfcfgConnection *connection = NM_IFCFG_CONNECTION (user_data);
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (connection);
NMConnection *wrapped;
/* Should only be called when udi is NULL */
g_return_if_fail (priv->udi == NULL);
wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection));
if (devtype != get_device_type_for_connection (wrapped))
return;
priv->udi = get_udi_for_connection (wrapped, priv->g_connection, priv->hal_mgr, devtype);
if (!priv->udi)
return;
/* If the connection is unmanaged we have to tell the plugin */
if (priv->unmanaged)
g_object_notify (G_OBJECT (connection), NM_IFCFG_CONNECTION_UNMANAGED);
g_signal_handler_disconnect (G_OBJECT (hal_mgr), priv->daid);
priv->daid = 0;
}
NMIfcfgConnection *
nm_ifcfg_connection_new (const char *filename,
DBusGConnection *g_connection,
NMSystemConfigHalManager *hal_mgr,
GError **error)
{
GObject *object;
NMConnection *wrapped;
gboolean unmanaged = FALSE;
char *udi;
g_return_val_if_fail (filename != NULL, NULL);
wrapped = connection_from_file (filename, &unmanaged, error);
if (!wrapped)
return NULL;
udi = get_udi_for_connection (wrapped, g_connection, hal_mgr, DEVICE_TYPE_UNKNOWN);
object = (GObject *) g_object_new (NM_TYPE_IFCFG_CONNECTION,
NM_IFCFG_CONNECTION_FILENAME, filename,
NM_IFCFG_CONNECTION_UNMANAGED, unmanaged,
NM_IFCFG_CONNECTION_UDI, udi,
NM_EXPORTED_CONNECTION_CONNECTION, wrapped,
NULL);
if (object && !udi) {
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
priv->hal_mgr = g_object_ref (hal_mgr);
priv->g_connection = dbus_g_connection_ref (g_connection);
priv->daid = g_signal_connect (priv->hal_mgr, "device-added", G_CALLBACK (device_added_cb), object);
}
g_object_unref (wrapped);
g_free (udi);
return (NMIfcfgConnection *) object;
}
const char *
nm_ifcfg_connection_get_filename (NMIfcfgConnection *self)
{
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->filename;
}
const char *
nm_ifcfg_connection_get_udi (NMIfcfgConnection *self)
{
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), NULL);
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->udi;
}
gboolean
nm_ifcfg_connection_get_unmanaged (NMIfcfgConnection *self)
{
g_return_val_if_fail (NM_IS_IFCFG_CONNECTION (self), FALSE);
return NM_IFCFG_CONNECTION_GET_PRIVATE (self)->unmanaged;
}
static GHashTable *
get_settings (NMExportedConnection *exported)
{
return nm_connection_to_hash (nm_exported_connection_get_connection (exported));
}
static const char *
get_id (NMExportedConnection *exported)
{
return NM_IFCFG_CONNECTION_GET_PRIVATE (exported)->filename;
}
static gboolean
update (NMExportedConnection *exported, GHashTable *new_settings, GError **error)
{
// write_connection (NM_IFCFG_CONNECTION (exported));
return TRUE;
}
static gboolean
delete (NMExportedConnection *exported, GError **error)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (exported);
g_unlink (priv->filename);
if (priv->keyfile)
g_unlink (priv->keyfile);
return TRUE;
}
/* GObject */
static void
nm_ifcfg_connection_init (NMIfcfgConnection *connection)
{
}
static void
finalize (GObject *object)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
NMConnection *wrapped;
wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (object));
if (wrapped)
nm_connection_clear_secrets (wrapped);
g_free (priv->filename);
g_free (priv->udi);
if (priv->hal_mgr) {
if (priv->daid)
g_signal_handler_disconnect (G_OBJECT (priv->hal_mgr), priv->daid);
g_object_unref (priv->hal_mgr);
}
if (priv->g_connection)
dbus_g_connection_unref (priv->g_connection);
G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object);
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
switch (prop_id) {
case PROP_FILENAME:
/* Construct only */
priv->filename = g_value_dup_string (value);
break;
case PROP_UNMANAGED:
priv->unmanaged = g_value_get_boolean (value);
break;
case PROP_UDI:
/* Construct only */
priv->udi = g_value_dup_string (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (object);
switch (prop_id) {
case PROP_FILENAME:
g_value_set_string (value, priv->filename);
break;
case PROP_UNMANAGED:
g_value_set_boolean (value, priv->unmanaged);
break;
case PROP_UDI:
g_value_set_string (value, priv->udi);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_ifcfg_connection_class_init (NMIfcfgConnectionClass *ifcfg_connection_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (ifcfg_connection_class);
NMExportedConnectionClass *connection_class = NM_EXPORTED_CONNECTION_CLASS (ifcfg_connection_class);
g_type_class_add_private (ifcfg_connection_class, sizeof (NMIfcfgConnectionPrivate));
/* Virtual methods */
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->finalize = finalize;
connection_class->get_settings = get_settings;
connection_class->get_id = get_id;
connection_class->update = update;
connection_class->delete = delete;
/* Properties */
g_object_class_install_property
(object_class, PROP_FILENAME,
g_param_spec_string (NM_IFCFG_CONNECTION_FILENAME,
"FileName",
"File name",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
(object_class, PROP_UNMANAGED,
g_param_spec_boolean (NM_IFCFG_CONNECTION_UNMANAGED,
"Unmanaged",
"Unmanaged",
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_UDI,
g_param_spec_string (NM_IFCFG_CONNECTION_UDI,
"UDI",
"UDI",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}

View file

@ -0,0 +1,63 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* 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.
*
* (C) Copyright 2008 Red Hat, Inc.
*/
#ifndef NM_IFCFG_CONNECTION_H
#define NM_IFCFG_CONNECTION_H
G_BEGIN_DECLS
#include <nm-settings.h>
#include "nm-system-config-hal-manager.h"
#define NM_TYPE_IFCFG_CONNECTION (nm_ifcfg_connection_get_type ())
#define NM_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnection))
#define NM_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass))
#define NM_IS_IFCFG_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION))
#define NM_IS_IFCFG_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_IFCFG_CONNECTION))
#define NM_IFCFG_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_IFCFG_CONNECTION, NMIfcfgConnectionClass))
#define NM_IFCFG_CONNECTION_FILENAME "filename"
#define NM_IFCFG_CONNECTION_UNMANAGED "unmanaged"
#define NM_IFCFG_CONNECTION_UDI "udi"
typedef struct {
NMExportedConnection parent;
} NMIfcfgConnection;
typedef struct {
NMExportedConnectionClass parent;
} NMIfcfgConnectionClass;
GType nm_ifcfg_connection_get_type (void);
NMIfcfgConnection *nm_ifcfg_connection_new (const char *filename,
DBusGConnection *g_connection,
NMSystemConfigHalManager *hal_mgr,
GError **error);
const char *nm_ifcfg_connection_get_filename (NMIfcfgConnection *self);
const char *nm_ifcfg_connection_get_udi (NMIfcfgConnection *self);
gboolean nm_ifcfg_connection_get_unmanaged (NMIfcfgConnection *self);
G_END_DECLS
#endif /* NM_IFCFG_CONNECTION_H */

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,5 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* Søren Sandmann <sandmann@daimi.au.dk>
*
* 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
@ -16,7 +15,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2007 Red Hat, Inc.
* (C) Copyright 2008 Red Hat, Inc.
*/
#include <stdlib.h>
@ -40,7 +39,6 @@
#undef __user
#include <glib.h>
#include <nm-connection.h>
#include <NetworkManager.h>
#include <nm-setting-connection.h>
@ -49,91 +47,27 @@
#include <nm-setting-wireless.h>
#include <nm-utils.h>
#include "common.h"
#include "shvar.h"
#include "parser.h"
#include "plugin.h"
#define CONNECTION_DATA_TAG "plugin-data"
#include "reader.h"
ConnectionData *
connection_data_get (NMConnection *connection)
#define TYPE_ETHERNET "Ethernet"
#define TYPE_WIRELESS "Wireless"
static char *
get_ifcfg_name (const char *file)
{
return (ConnectionData *) g_object_get_data (G_OBJECT (connection), CONNECTION_DATA_TAG);
}
char *ifcfg_name;
char *basename;
static void
copy_one_cdata_secret (gpointer key, gpointer data, gpointer user_data)
{
GHashTable *to = (GHashTable *) user_data;
basename = g_path_get_basename (file);
if (!basename)
return NULL;
g_hash_table_insert (to, key, g_strdup (data));
}
static void
clear_one_cdata_secret (gpointer key, gpointer data, gpointer user_data)
{
guint32 len = strlen (data);
memset (data, 0, len);
}
void
connection_data_copy_secrets (ConnectionData *from, ConnectionData *to)
{
g_return_if_fail (from != NULL);
g_return_if_fail (to != NULL);
g_hash_table_foreach (to->wifi_secrets, clear_one_cdata_secret, NULL);
g_hash_table_remove_all (to->wifi_secrets);
g_hash_table_foreach (from->wifi_secrets, copy_one_cdata_secret, to->wifi_secrets);
g_hash_table_foreach (to->onex_secrets, clear_one_cdata_secret, NULL);
g_hash_table_remove_all (to->onex_secrets);
g_hash_table_foreach (from->onex_secrets, copy_one_cdata_secret, to->onex_secrets);
g_hash_table_foreach (to->ppp_secrets, clear_one_cdata_secret, NULL);
g_hash_table_remove_all (to->ppp_secrets);
g_hash_table_foreach (from->ppp_secrets, copy_one_cdata_secret, to->ppp_secrets);
}
static void
connection_data_free (gpointer userdata)
{
ConnectionData *cdata = (ConnectionData *) userdata;
g_return_if_fail (cdata != NULL);
g_hash_table_foreach (cdata->wifi_secrets, clear_one_cdata_secret, NULL);
g_hash_table_destroy (cdata->wifi_secrets);
g_hash_table_foreach (cdata->onex_secrets, clear_one_cdata_secret, NULL);
g_hash_table_destroy (cdata->onex_secrets);
g_hash_table_foreach (cdata->ppp_secrets, clear_one_cdata_secret, NULL);
g_hash_table_destroy (cdata->ppp_secrets);
g_free (cdata->ifcfg_path);
g_free (cdata->udi);
memset (cdata, 0, sizeof (ConnectionData));
g_free (cdata);
}
ConnectionData *
connection_data_add (NMConnection *connection, const char *ifcfg_path)
{
ConnectionData *cdata;
cdata = g_malloc0 (sizeof (ConnectionData));
cdata->ifcfg_path = g_strdup (ifcfg_path);
cdata->wifi_secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
cdata->onex_secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
cdata->ppp_secrets = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
g_object_set_data_full (G_OBJECT (connection),
CONNECTION_DATA_TAG, cdata,
connection_data_free);
return cdata;
ifcfg_name = g_strdup (basename + strlen (IFCFG_TAG));
g_free (basename);
return ifcfg_name;
}
static gboolean
@ -148,56 +82,6 @@ get_int (const char *str, int *value)
return TRUE;
}
static gboolean
should_ignore_file (const char *basename, const char *tag)
{
int len, tag_len;
g_return_val_if_fail (basename != NULL, TRUE);
g_return_val_if_fail (tag != NULL, TRUE);
len = strlen (basename);
tag_len = strlen (tag);
if ((len > tag_len) && !strcasecmp (basename + len - tag_len, tag))
return TRUE;
return FALSE;
}
static char *
get_ifcfg_name (const char *file)
{
char *ifcfg_name = NULL;
char *basename;
int len;
basename = g_path_get_basename (file);
if (!basename)
goto error;
len = strlen (basename);
if (len < strlen (IFCFG_TAG) + 1)
goto error;
if (strncmp (basename, IFCFG_TAG, strlen (IFCFG_TAG)))
goto error;
/* ignore some files */
if (should_ignore_file (basename, BAK_TAG))
goto error;
if (should_ignore_file (basename, TILDE_TAG))
goto error;
if (should_ignore_file (basename, ORIG_TAG))
goto error;
if (should_ignore_file (basename, REJ_TAG))
goto error;
ifcfg_name = g_strdup (basename + strlen (IFCFG_TAG));
error:
g_free (basename);
return ifcfg_name;
}
static NMSetting *
make_connection_setting (const char *file,
shvarFile *ifcfg,
@ -426,7 +310,7 @@ static gboolean
add_one_wep_key (shvarFile *ifcfg,
const char *shvar_key,
guint8 key_idx,
GHashTable *secrets,
NMSettingWirelessSecurity *s_wsec,
GError **error)
{
char *key = NULL;
@ -436,7 +320,7 @@ add_one_wep_key (shvarFile *ifcfg,
g_return_val_if_fail (ifcfg != NULL, FALSE);
g_return_val_if_fail (shvar_key != NULL, FALSE);
g_return_val_if_fail (key_idx <= 3, FALSE);
g_return_val_if_fail (secrets != NULL, FALSE);
g_return_val_if_fail (s_wsec != NULL, FALSE);
value = svGetValue (ifcfg, shvar_key);
if (!value || !strlen (value)) {
@ -478,13 +362,13 @@ add_one_wep_key (shvarFile *ifcfg,
if (key) {
if (key_idx == 0)
g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0, key);
s_wsec->wep_key0 = key;
else if (key_idx == 1)
g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1, key);
s_wsec->wep_key1 = key;
else if (key_idx == 2)
g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2, key);
s_wsec->wep_key2 = key;
else if (key_idx == 3)
g_hash_table_insert (secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3, key);
s_wsec->wep_key3 = key;
else
g_assert_not_reached ();
success = TRUE;
@ -525,17 +409,20 @@ out:
}
static gboolean
read_wep_keys (shvarFile *ifcfg, guint8 def_idx, GHashTable *secrets, GError **error)
read_wep_keys (shvarFile *ifcfg,
guint8 def_idx,
NMSettingWirelessSecurity *s_wsec,
GError **error)
{
if (!add_one_wep_key (ifcfg, "KEY1", 0, secrets, error))
if (!add_one_wep_key (ifcfg, "KEY1", 0, s_wsec, error))
return FALSE;
if (!add_one_wep_key (ifcfg, "KEY2", 1, secrets, error))
if (!add_one_wep_key (ifcfg, "KEY2", 1, s_wsec, error))
return FALSE;
if (!add_one_wep_key (ifcfg, "KEY3", 2, secrets, error))
if (!add_one_wep_key (ifcfg, "KEY3", 2, s_wsec, error))
return FALSE;
if (!add_one_wep_key (ifcfg, "KEY4", 3, secrets, error))
if (!add_one_wep_key (ifcfg, "KEY4", 3, s_wsec, error))
return FALSE;
if (!add_one_wep_key (ifcfg, "KEY", def_idx, secrets, error))
if (!add_one_wep_key (ifcfg, "KEY", def_idx, s_wsec, error))
return FALSE;
return TRUE;
@ -544,7 +431,6 @@ read_wep_keys (shvarFile *ifcfg, guint8 def_idx, GHashTable *secrets, GError **e
static NMSetting *
make_wireless_security_setting (shvarFile *ifcfg,
const char *file,
ConnectionData *cdata,
GError **error)
{
NMSettingWirelessSecurity *s_wireless_sec;
@ -572,13 +458,13 @@ make_wireless_security_setting (shvarFile *ifcfg,
}
/* Read keys in the ifcfg file */
if (!read_wep_keys (ifcfg, default_key_idx, cdata->wifi_secrets, error))
if (!read_wep_keys (ifcfg, default_key_idx, s_wireless_sec, error))
goto error;
/* Try to get keys from the "shadow" key file */
keys_ifcfg = get_keys_ifcfg (file);
if (keys_ifcfg) {
if (!read_wep_keys (keys_ifcfg, default_key_idx, cdata->wifi_secrets, error)) {
if (!read_wep_keys (keys_ifcfg, default_key_idx, s_wireless_sec, error)) {
svCloseFile (keys_ifcfg);
goto error;
}
@ -586,18 +472,15 @@ make_wireless_security_setting (shvarFile *ifcfg,
}
/* If there's a default key, ensure that key exists */
if ( (default_key_idx == 1)
&& !g_hash_table_lookup (cdata->wifi_secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1)) {
if ((default_key_idx == 1) && !s_wireless_sec->wep_key1) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Default WEP key index was 2, but no valid KEY2 exists.");
goto error;
} else if ( (default_key_idx == 2)
&& !g_hash_table_lookup (cdata->wifi_secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2)) {
} else if ((default_key_idx == 2) && !s_wireless_sec->wep_key2) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Default WEP key index was 3, but no valid KEY3 exists.");
goto error;
} else if ( (default_key_idx == 3)
&& !g_hash_table_lookup (cdata->wifi_secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)) {
} else if ((default_key_idx == 3) && !s_wireless_sec->wep_key3) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Default WEP key index was 4, but no valid KEY4 exists.");
goto error;
@ -624,10 +507,10 @@ make_wireless_security_setting (shvarFile *ifcfg,
g_free (lcase);
}
if ( !g_hash_table_lookup (cdata->wifi_secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY0)
&& !g_hash_table_lookup (cdata->wifi_secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY1)
&& !g_hash_table_lookup (cdata->wifi_secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY2)
&& !g_hash_table_lookup (cdata->wifi_secrets, NM_SETTING_WIRELESS_SECURITY_WEP_KEY3)
if ( !s_wireless_sec->wep_key0
&& !s_wireless_sec->wep_key1
&& !s_wireless_sec->wep_key2
&& !s_wireless_sec->wep_key3
&& !s_wireless_sec->wep_tx_keyidx) {
if (s_wireless_sec->auth_alg && !strcmp (s_wireless_sec->auth_alg, "shared")) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
@ -730,7 +613,6 @@ wireless_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **err
NMSettingWireless *tmp;
NMSetting *security_setting = NULL;
char *printable_ssid = NULL;
ConnectionData *cdata;
g_return_val_if_fail (file != NULL, NULL);
g_return_val_if_fail (ifcfg != NULL, NULL);
@ -744,11 +626,8 @@ wireless_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **err
return NULL;
}
/* Add plugin specific data to connection */
cdata = connection_data_add (connection, file);
/* Wireless security */
security_setting = make_wireless_security_setting (ifcfg, file, cdata, error);
security_setting = make_wireless_security_setting (ifcfg, file, error);
if (*error)
goto error;
if (security_setting)
@ -830,7 +709,6 @@ wired_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **error)
NMConnection *connection = NULL;
NMSetting *con_setting = NULL;
NMSetting *wired_setting = NULL;
ConnectionData *cdata;
g_return_val_if_fail (file != NULL, NULL);
g_return_val_if_fail (ifcfg != NULL, NULL);
@ -850,9 +728,6 @@ wired_connection_from_ifcfg (const char *file, shvarFile *ifcfg, GError **error)
}
nm_connection_add_setting (connection, con_setting);
/* Add plugin data to connection */
cdata = connection_data_add (connection, file);
wired_setting = make_wired_setting (ifcfg, error);
if (!wired_setting)
goto error;
@ -913,11 +788,8 @@ out:
return success;
}
#define TYPE_ETHERNET "Ethernet"
#define TYPE_WIRELESS "Wireless"
NMConnection *
parser_parse_file (const char *file, GError **error)
connection_from_file (const char *filename, gboolean *ignored, GError **error)
{
NMConnection *connection = NULL;
shvarFile *parsed;
@ -925,23 +797,22 @@ parser_parse_file (const char *file, GError **error)
char *nmc = NULL;
NMSetting *s_ip4;
char *ifcfg_name = NULL;
gboolean ignored = FALSE;
ConnectionData *cdata;
g_return_val_if_fail (file != NULL, NULL);
g_return_val_if_fail (filename != NULL, NULL);
g_return_val_if_fail (ignored != NULL, NULL);
ifcfg_name = get_ifcfg_name (file);
ifcfg_name = get_ifcfg_name (filename);
if (!ifcfg_name) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Ignoring connection '%s' because it's not an ifcfg file.", file);
"Ignoring connection '%s' because it's not an ifcfg file.", filename);
return NULL;
}
g_free (ifcfg_name);
parsed = svNewFile (file);
parsed = svNewFile (filename);
if (!parsed) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Couldn't parse file '%s'", file);
"Couldn't parse file '%s'", filename);
return NULL;
}
@ -956,7 +827,7 @@ parser_parse_file (const char *file, GError **error)
device = svGetValue (parsed, "DEVICE");
if (!device) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"File '%s' had neither TYPE nor DEVICE keys.", file);
"File '%s' had neither TYPE nor DEVICE keys.", filename);
goto done;
}
@ -971,7 +842,7 @@ parser_parse_file (const char *file, GError **error)
if (!is_wireless_device (device, &is_wireless)) {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"File '%s' specified device '%s', but the device's "
"type could not be determined.", file, device);
"type could not be determined.", filename, device);
g_free (device);
goto done;
}
@ -992,14 +863,14 @@ parser_parse_file (const char *file, GError **error)
g_free (nmc);
if (!strcmp (lower, "no") || !strcmp (lower, "n") || !strcmp (lower, "false"))
ignored = TRUE;
*ignored = TRUE;
g_free (lower);
}
if (!strcmp (type, TYPE_ETHERNET))
connection = wired_connection_from_ifcfg (file, parsed, error);
connection = wired_connection_from_ifcfg (filename, parsed, error);
else if (!strcmp (type, TYPE_WIRELESS))
connection = wireless_connection_from_ifcfg (file, parsed, error);
connection = wireless_connection_from_ifcfg (filename, parsed, error);
else {
g_set_error (error, ifcfg_plugin_error_quark (), 0,
"Unknown connection type '%s'", type);
@ -1019,10 +890,6 @@ parser_parse_file (const char *file, GError **error)
nm_connection_add_setting (connection, s_ip4);
}
/* Update the ignored tag */
cdata = connection_data_get (connection);
cdata->ignored = ignored;
if (!nm_connection_verify (connection)) {
g_object_unref (connection);
connection = NULL;
@ -1035,3 +902,4 @@ done:
return connection;
}

View file

@ -0,0 +1,29 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager system settings service
*
* 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.
*
* (C) Copyright 2008 Red Hat, Inc.
*/
#ifndef __READER_H__
#define __READER_H__
#include <glib.h>
#include <nm-connection.h>
NMConnection *connection_from_file (const char *filename, gboolean *ignored, GError **error);
#endif /* __READER_H__ */

View file

@ -69,6 +69,38 @@ enum {
LAST_PROP
};
static void
load_connections (NMSysconfigSettings *self)
{
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *iter;
if (priv->connections_loaded)
return;
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
GSList *plugin_connections;
GSList *elt;
plugin_connections = nm_system_config_interface_get_connections (plugin);
// FIXME: ensure connections from plugins loaded with a lower priority
// get rejected when they conflict with connections from a higher
// priority plugin.
for (elt = plugin_connections; elt; elt = g_slist_next (elt))
nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (elt->data));
g_slist_free (plugin_connections);
}
/* FIXME: Bad hack */
unmanaged_devices_changed (NULL, self);
priv->connections_loaded = TRUE;
}
static void
hash_keys_to_slist (gpointer key, gpointer val, gpointer user_data)
{
@ -84,31 +116,7 @@ list_connections (NMSettings *settings)
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GSList *list = NULL;
if (!priv->connections_loaded) {
GSList *iter;
for (iter = priv->plugins; iter; iter = g_slist_next (iter)) {
NMSystemConfigInterface *plugin = NM_SYSTEM_CONFIG_INTERFACE (iter->data);
GSList *plugin_connections;
GSList *elt;
plugin_connections = nm_system_config_interface_get_connections (plugin);
// FIXME: ensure connections from plugins loaded with a lower priority
// get rejected when they conflict with connections from a higher
// priority plugin.
for (elt = plugin_connections; elt; elt = g_slist_next (elt))
nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (elt->data));
g_slist_free (plugin_connections);
}
/* FIXME: Bad hack */
unmanaged_devices_changed (NULL, self);
priv->connections_loaded = TRUE;
}
load_connections (self);
g_hash_table_foreach (priv->connections, hash_keys_to_slist, &list);
@ -195,6 +203,8 @@ get_unmanaged_devices (NMSysconfigSettings *self)
NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
GPtrArray *devices;
load_connections (self);
devices = g_ptr_array_sized_new (3);
g_hash_table_foreach (priv->unmanaged_devices, (GHFunc) add_one_unmanaged_device, devices);
return devices;
@ -406,6 +416,9 @@ nm_sysconfig_settings_is_device_managed (NMSysconfigSettings *self,
g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), FALSE);
priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self);
load_connections (self);
if (g_hash_table_lookup (priv->unmanaged_devices, udi))
return FALSE;
return TRUE;