[PATCH] IFUPDOWN - hostname read/write support
- From: Alexander Sack <asac canonical com>
- To: NetworkManager List <networkmanager-list gnome org>
- Subject: [PATCH] IFUPDOWN - hostname read/write support
- Date: Mon, 6 Oct 2008 17:27:10 +0200
Implement system hostname support for debian/ubuntu
Make nm-inotify-helper from ifcfg-fedora plugin usable
for other plugins too
=== modified file 'ChangeLog'
--- a/ChangeLog 2008-10-03 21:51:57 +0000
+++ b/ChangeLog 2008-10-06 08:22:23 +0000
@@ -1,8 +1,36 @@
+2008-10-03 Alexander Sack <asac ubuntu com>
+
+ Implement system hostname support for debian/ubuntu
+
+ * system-settings/plugins/ifupdown/plugin.c
+ - (GObject__set_property, GObject__get_property, SCPluginIfupdown_init, update_system_hostname, get_hostname):
+ implement hostname property that watches and
+ parses /etc/hostname
+
+
+ Make nm-inotify-helper from ifcfg-fedora plugin usable
+ for other plugins too
+
+ * system-settings/plugins/ifcfg-fedora/nm-inotify-helper.c (deleted)
+ system-settings/plugins/ifcfg-fedora/nm-inotify-helper.h (deleted)
+ system-settings/src/nm-inotify-helper.c (NEW)
+ system-settings/src/nm-inotify-helper.h (NEW)
+ system-settings/plugins/ifcfg-fedora/Makefile.am
+ system-settings/src/Makefile.am
+ - make inotify available for all system plugins and
+ adjust ifcfg-fedora build accordingly
+
+ * system-settings/plugins/ifupdown/plugin.c
+ - (GObject__get_property): extend announced capabilities; add
+ NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME support
+ - (GObject__set_property,write_system_hostname): implement
+ NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME capability.
+
2008-10-02 Alexander Sack <asac ubuntu com>
Implement support for wep-tx-keyidx in ifupdown system
config plugin.
* system-settings/plugins/ifupdown/parser.c
- (update_wireless_security_setting_from_if_block): introduce
free_type_mapping func table; rename a few local
=== modified file 'system-settings/plugins/ifcfg-fedora/Makefile.am'
--- a/system-settings/plugins/ifcfg-fedora/Makefile.am 2008-05-13 16:53:50 +0000
+++ b/system-settings/plugins/ifcfg-fedora/Makefile.am 2008-10-02 22:32:18 +0000
@@ -5,19 +5,17 @@ libnm_settings_plugin_ifcfg_fedora_la_SO
shvar.c \
shvar.h \
plugin.c \
plugin.h \
nm-ifcfg-connection.c \
nm-ifcfg-connection.h \
reader.c \
reader.h \
- common.h \
- nm-inotify-helper.c \
- nm-inotify-helper.h
+ common.h
libnm_settings_plugin_ifcfg_fedora_la_CPPFLAGS = \
$(GLIB_CFLAGS) \
$(GMODULE_CFLAGS) \
$(DBUS_CFLAGS) \
-DG_DISABLE_DEPRECATED \
-I${top_srcdir}/system-settings/src \
-I$(top_srcdir)/include \
=== removed file 'system-settings/plugins/ifcfg-fedora/nm-inotify-helper.c'
--- a/system-settings/plugins/ifcfg-fedora/nm-inotify-helper.c 2008-08-26 09:34:31 +0000
+++ b/system-settings/plugins/ifcfg-fedora/nm-inotify-helper.c 1970-01-01 00:00:00 +0000
@@ -1,211 +0,0 @@
-/* -*- 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 Red Hat, Inc.
- */
-
-#include <unistd.h>
-#include <string.h>
-#include <sys/inotify.h>
-#include <glib.h>
-
-#include "nm-marshal.h"
-#include "nm-inotify-helper.h"
-
-G_DEFINE_TYPE (NMInotifyHelper, nm_inotify_helper, G_TYPE_OBJECT)
-
-#define NM_INOTIFY_HELPER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperPrivate))
-
-typedef struct {
- int ifd;
-
- GHashTable *wd_refs;
-} NMInotifyHelperPrivate;
-
-/* Signals */
-enum {
- EVENT,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
-int
-nm_inotify_helper_add_watch (NMInotifyHelper *self, const char *path)
-{
- NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
- int wd;
- guint32 refcount;
-
- g_return_val_if_fail (priv->ifd >= 0, -1);
-
- /* We only care about modifications since we're just trying to get change
- * notifications on hardlinks.
- */
-
- wd = inotify_add_watch (priv->ifd, path, IN_CLOSE_WRITE);
- if (wd < 0)
- return -1;
-
- refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd)));
- refcount++;
- g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount));
-
- return wd;
-}
-
-void
-nm_inotify_helper_remove_watch (NMInotifyHelper *self, int wd)
-{
- NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
- guint32 refcount;
-
- g_return_if_fail (priv->ifd >= 0);
-
- refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd)));
- if (!refcount)
- return;
-
- refcount--;
- if (!refcount) {
- g_hash_table_remove (priv->wd_refs, GINT_TO_POINTER (wd));
- inotify_rm_watch (priv->ifd, wd);
- } else
- g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount));
-}
-
-static gboolean
-inotify_event_handler (GIOChannel *channel, GIOCondition cond, gpointer user_data)
-{
- NMInotifyHelper *self = NM_INOTIFY_HELPER (user_data);
- struct inotify_event evt;
-
- /* read the notifications from the watch descriptor */
- while (g_io_channel_read_chars (channel, (gchar *) &evt, sizeof (struct inotify_event), NULL, NULL) == G_IO_STATUS_NORMAL) {
- gchar filename[PATH_MAX + 1];
-
- filename[0] = '\0';
- if (evt.len > 0) {
- g_io_channel_read_chars (channel,
- filename,
- evt.len > PATH_MAX ? PATH_MAX : evt.len,
- NULL, NULL);
- }
-
- if (!(evt.mask & IN_IGNORED))
- g_signal_emit (self, signals[EVENT], 0, &evt, &filename[0]);
- }
-
- return TRUE;
-}
-
-static gboolean
-init_inotify (NMInotifyHelper *self)
-{
- NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
- GIOChannel *channel;
- guint source_id;
-
- priv->ifd = inotify_init ();
- if (priv->ifd == -1) {
- g_warning ("%s: couldn't initialize inotify", __func__);
- return FALSE;
- }
-
- /* Watch the inotify descriptor for file/directory change events */
- channel = g_io_channel_unix_new (priv->ifd);
- if (!channel) {
- g_warning ("%s: couldn't create new GIOChannel", __func__);
- close (priv->ifd);
- priv->ifd = -1;
- return FALSE;
- }
-
- g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
- g_io_channel_set_encoding (channel, NULL, NULL);
-
- source_id = g_io_add_watch (channel,
- G_IO_IN | G_IO_ERR,
- (GIOFunc) inotify_event_handler,
- (gpointer) self);
- g_io_channel_unref (channel);
- return TRUE;
-}
-
-NMInotifyHelper *
-nm_inotify_helper_get (void)
-{
- static NMInotifyHelper *singleton = NULL;
-
- if (!singleton) {
- singleton = (NMInotifyHelper *) g_object_new (NM_TYPE_INOTIFY_HELPER, NULL);
- if (!singleton)
- return NULL;
-
- if (!init_inotify (singleton)) {
- g_object_unref (singleton);
- return NULL;
- }
- } else
- g_object_ref (singleton);
-
- g_assert (singleton);
- return singleton;
-}
-
-static void
-nm_inotify_helper_init (NMInotifyHelper *self)
-{
- NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
-
- priv->wd_refs = g_hash_table_new (g_direct_hash, g_direct_equal);
-}
-
-static void
-finalize (GObject *object)
-{
- NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (object);
-
- if (priv->ifd >= 0)
- close (priv->ifd);
-
- g_hash_table_destroy (priv->wd_refs);
-
- G_OBJECT_CLASS (nm_inotify_helper_parent_class)->finalize (object);
-}
-
-static void
-nm_inotify_helper_class_init (NMInotifyHelperClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private (klass, sizeof (NMInotifyHelperPrivate));
-
- /* Virtual methods */
- object_class->finalize = finalize;
-
- /* Signals */
- signals[EVENT] =
- g_signal_new ("event",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (NMInotifyHelperClass, event),
- NULL, NULL,
- _nm_marshal_VOID__POINTER_STRING,
- G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_STRING);
-}
-
=== removed file 'system-settings/plugins/ifcfg-fedora/nm-inotify-helper.h'
--- a/system-settings/plugins/ifcfg-fedora/nm-inotify-helper.h 2008-06-26 18:31:52 +0000
+++ b/system-settings/plugins/ifcfg-fedora/nm-inotify-helper.h 1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
-/* -*- 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * (C) Copyright 2008 Red Hat, Inc.
- */
-
-#ifndef __INOTIFY_HELPER_H__
-#define __INOTIFY_HELPER_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <sys/inotify.h>
-
-#define NM_TYPE_INOTIFY_HELPER (nm_inotify_helper_get_type ())
-#define NM_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelper))
-#define NM_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass))
-#define NM_IS_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_INOTIFY_HELPER))
-#define NM_IS_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_INOTIFY_HELPER))
-#define NM_INOTIFY_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass))
-
-typedef struct {
- GObject parent;
-} NMInotifyHelper;
-
-typedef struct {
- GObjectClass parent;
-
- /* signals */
- void (* event) (NMInotifyHelper *helper, struct inotify_event *evt, const char *filename);
-} NMInotifyHelperClass;
-
-GType nm_inotify_helper_get_type (void);
-
-NMInotifyHelper * nm_inotify_helper_get (void);
-
-int nm_inotify_helper_add_watch (NMInotifyHelper *helper, const char *path);
-
-void nm_inotify_helper_remove_watch (NMInotifyHelper *helper, int wd);
-
-#endif /* __INOTIFY_HELPER_H__ */
=== modified file 'system-settings/plugins/ifupdown/plugin.c'
--- a/system-settings/plugins/ifupdown/plugin.c 2008-09-18 15:29:59 +0000
+++ b/system-settings/plugins/ifupdown/plugin.c 2008-10-04 17:09:53 +0000
@@ -36,32 +36,37 @@
#include "nm-setting-ip4-config.h"
#include "nm-setting-wireless.h"
#include "nm-setting-wired.h"
#include "nm-setting-ppp.h"
#include "nm-ifupdown-connection.h"
#include "plugin.h"
#include "parser.h"
+#include "nm-inotify-helper.h"
#include <nm-utils.h>
#include <sha1.h>
#include <arpa/inet.h>
#define IFUPDOWN_PLUGIN_NAME "ifupdown"
#define IFUPDOWN_PLUGIN_INFO "(C) 2008 Canonical Ltd. To report bugs please use the NetworkManager mailing list."
+#define IFUPDOWN_SYSTEM_HOSTNAME_FILE "/etc/hostname"
typedef struct {
DBusGConnection *g_connection;
NMSystemConfigHalManager *hal_mgr;
GHashTable *iface_connections;
-
+ gchar* hostname;
+
+ gulong inotify_event_id;
+ int inotify_system_hostname_wd;
} SCPluginIfupdownPrivate;
static void
system_config_interface_init (NMSystemConfigInterface *system_config_interface_class);
G_DEFINE_TYPE_EXTENDED (SCPluginIfupdown, sc_plugin_ifupdown, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SYSTEM_CONFIG_INTERFACE,
system_config_interface_init))
@@ -100,21 +105,36 @@ SCPluginIfupdown_connection_added (NMSys
static void
SCPluginIfupdown_unmanaged_devices_changed (NMSystemConfigInterface *config);
static void
GObject__get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void
+GObject__set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec);
+
+static void
GObject__dispose (GObject *object);
static void
GObject__finalize (GObject *object);
+/* other helpers */
+static const char *
+get_hostname (NMSystemConfigInterface *config);
+
+
+static void
+update_system_hostname(NMInotifyHelper *inotify_helper,
+ struct inotify_event *evt,
+ const char *path,
+ NMSystemConfigInterface *config);
+
static void
system_config_interface_init (NMSystemConfigInterface *system_config_interface_class)
{
system_config_interface_class->init = SCPluginIfupdown_init;
system_config_interface_class->get_connections = SCPluginIfupdown_get_connections;
system_config_interface_class->get_unmanaged_devices = SCPluginIfupdown_get_unmanaged_devices;
system_config_interface_class->connection_added = SCPluginIfupdown_connection_added;
@@ -126,16 +146,17 @@ sc_plugin_ifupdown_class_init (SCPluginI
{
GObjectClass *object_class = G_OBJECT_CLASS (req_class);
g_type_class_add_private (req_class, sizeof (SCPluginIfupdownPrivate));
object_class->dispose = GObject__dispose;
object_class->finalize = GObject__finalize;
object_class->get_property = GObject__get_property;
+ object_class->set_property = GObject__set_property;
g_object_class_override_property (object_class,
NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME,
NM_SYSTEM_CONFIG_INTERFACE_NAME);
g_object_class_override_property (object_class,
NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO,
NM_SYSTEM_CONFIG_INTERFACE_INFO);
@@ -151,23 +172,35 @@ sc_plugin_ifupdown_class_init (SCPluginI
static void
SCPluginIfupdown_init (NMSystemConfigInterface *config,
NMSystemConfigHalManager *hal_manager)
{
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
GHashTable *auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal);
if_block *block = NULL;
+ NMInotifyHelper *inotify_helper;
if(!priv->iface_connections)
priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal);
PLUGIN_PRINT("SCPlugin-Ifupdown", "init!");
priv->hal_mgr = g_object_ref (hal_manager);
+ inotify_helper = nm_inotify_helper_get ();
+ priv->inotify_event_id = g_signal_connect (inotify_helper,
+ "event",
+ G_CALLBACK (update_system_hostname),
+ config);
+
+ priv->inotify_system_hostname_wd =
+ nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE);
+
+ update_system_hostname(inotify_helper, NULL, NULL, config);
+
ifparser_init();
block = ifparser_getfirst();
while(block) {
if(!strcmp("auto", block->type)) {
g_hash_table_insert (auto_ifaces, block->name, "auto");
} else if (!strcmp ("iface", block->type) && strcmp ("lo", block->name)) {
NMExportedConnection *connection = g_hash_table_lookup(priv->iface_connections, block->name);
@@ -260,58 +293,153 @@ static void
SCPluginIfupdown_unmanaged_devices_changed (NMSystemConfigInterface *config)
{
PLUGIN_PRINT("SCPlugin-Ifdown", "unmanaged_devices_changed ... started");
g_return_if_fail (config != NULL);
PLUGIN_PRINT("SCPlugin-Ifdown", "unmanaged_devices_changed ... ended");
}
+static const char *
+get_hostname (NMSystemConfigInterface *config)
+{
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
+ return priv->hostname;
+}
+
+static void
+update_system_hostname(NMInotifyHelper *inotify_helper,
+ struct inotify_event *evt,
+ const char *path,
+ NMSystemConfigInterface *config)
+{
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
+ gchar *hostname_file = NULL;
+ gsize hostname_file_len = 0;
+ GError *error = NULL;
+
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "update_system_hostname");
+
+ if (evt && evt->wd != priv->inotify_system_hostname_wd)
+ return;
+
+ if(!g_file_get_contents ( IFUPDOWN_SYSTEM_HOSTNAME_FILE,
+ &hostname_file,
+ &hostname_file_len,
+ &error)) {
+ nm_warning ("update_system_hostname() - couldn't read "
+ IFUPDOWN_SYSTEM_HOSTNAME_FILE " (%d/%s)",
+ error->code, error->message);
+ return;
+ }
+
+ if (priv->hostname)
+ g_free(priv->hostname);
+
+ priv->hostname = g_strstrip(hostname_file);
+
+ g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+static void
+write_system_hostname(NMSystemConfigInterface *config,
+ const char *newhostname)
+{
+ GError *error = NULL;
+ SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (config);
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", "write_system_hostname: %s", newhostname);
+
+ g_return_if_fail (newhostname);
+
+ if(!g_file_set_contents ( IFUPDOWN_SYSTEM_HOSTNAME_FILE,
+ newhostname,
+ -1,
+ &error)) {
+ nm_warning ("update_system_hostname() - couldn't write hostname (%s) to "
+ IFUPDOWN_SYSTEM_HOSTNAME_FILE " (%d/%s)",
+ newhostname, error->code, error->message);
+ } else {
+ priv->hostname = g_strdup (newhostname);
+ }
+ g_object_notify (G_OBJECT (config), NM_SYSTEM_CONFIG_INTERFACE_HOSTNAME);
+}
+
+
static void
sc_plugin_ifupdown_init (SCPluginIfupdown *plugin)
{
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin);
GError *error = NULL;
priv->g_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
if (!priv->g_connection) {
- PLUGIN_PRINT (IFUPDOWN_PLUGIN_NAME, " dbus-glib error: %s",
+ PLUGIN_PRINT ("SCPlugin-Ifupdown", " dbus-glib error: %s",
error->message ? error->message : "(unknown)");
g_error_free (error);
}
}
static void
GObject__get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
+ NMSystemConfigInterface *self = NM_SYSTEM_CONFIG_INTERFACE (object);
+
switch (prop_id) {
case NM_SYSTEM_CONFIG_INTERFACE_PROP_NAME:
g_value_set_string (value, IFUPDOWN_PLUGIN_NAME);
break;
case NM_SYSTEM_CONFIG_INTERFACE_PROP_INFO:
g_value_set_string (value, IFUPDOWN_PLUGIN_INFO);
break;
case NM_SYSTEM_CONFIG_INTERFACE_PROP_CAPABILITIES:
- g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_NONE);
+ g_value_set_uint (value, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_HOSTNAME);
break;
case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
- g_value_set_string (value, "");
+ {
+ g_value_set_string (value, get_hostname(self));
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
+ }
+}
+
+static void
+GObject__set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case NM_SYSTEM_CONFIG_INTERFACE_PROP_HOSTNAME:
+ {
+ const gchar *hostname = g_value_get_string (value);
+ if (hostname && strlen (hostname) < 1)
+ hostname = NULL;
+ write_system_hostname(NM_SYSTEM_CONFIG_INTERFACE(object),
+ hostname);
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
GObject__dispose (GObject *object)
{
SCPluginIfupdown *plugin = SC_PLUGIN_IFUPDOWN (object);
SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin);
+ NMInotifyHelper *inotify_helper = nm_inotify_helper_get ();
+
+ g_signal_handler_disconnect (inotify_helper, priv->inotify_event_id);
+
+ if (priv->inotify_system_hostname_wd >= 0)
+ nm_inotify_helper_remove_watch (inotify_helper, priv->inotify_system_hostname_wd);
g_object_unref (priv->hal_mgr);
G_OBJECT_CLASS (sc_plugin_ifupdown_parent_class)->dispose (object);
}
static void
GObject__finalize (GObject *object)
{
=== modified file 'system-settings/src/Makefile.am'
--- a/system-settings/src/Makefile.am 2008-07-16 07:37:10 +0000
+++ b/system-settings/src/Makefile.am 2008-10-02 22:32:18 +0000
@@ -8,16 +8,18 @@ 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-inotify-helper.c \
+ nm-inotify-helper.h \
nm-polkit-helpers.c \
nm-polkit-helpers.h \
nm-system-config-error.c \
nm-system-config-error.h \
nm-system-config-interface.c \
nm-system-config-interface.h \
nm-system-config-hal-manager.c \
nm-system-config-hal-manager.h \
=== added file 'system-settings/src/nm-inotify-helper.c'
--- a/system-settings/src/nm-inotify-helper.c 1970-01-01 00:00:00 +0000
+++ b/system-settings/src/nm-inotify-helper.c 2008-10-02 22:32:18 +0000
@@ -0,0 +1,211 @@
+/* -*- 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/inotify.h>
+#include <glib.h>
+
+#include "nm-marshal.h"
+#include "nm-inotify-helper.h"
+
+G_DEFINE_TYPE (NMInotifyHelper, nm_inotify_helper, G_TYPE_OBJECT)
+
+#define NM_INOTIFY_HELPER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperPrivate))
+
+typedef struct {
+ int ifd;
+
+ GHashTable *wd_refs;
+} NMInotifyHelperPrivate;
+
+/* Signals */
+enum {
+ EVENT,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+int
+nm_inotify_helper_add_watch (NMInotifyHelper *self, const char *path)
+{
+ NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
+ int wd;
+ guint32 refcount;
+
+ g_return_val_if_fail (priv->ifd >= 0, -1);
+
+ /* We only care about modifications since we're just trying to get change
+ * notifications on hardlinks.
+ */
+
+ wd = inotify_add_watch (priv->ifd, path, IN_CLOSE_WRITE);
+ if (wd < 0)
+ return -1;
+
+ refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd)));
+ refcount++;
+ g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount));
+
+ return wd;
+}
+
+void
+nm_inotify_helper_remove_watch (NMInotifyHelper *self, int wd)
+{
+ NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
+ guint32 refcount;
+
+ g_return_if_fail (priv->ifd >= 0);
+
+ refcount = GPOINTER_TO_UINT (g_hash_table_lookup (priv->wd_refs, GINT_TO_POINTER (wd)));
+ if (!refcount)
+ return;
+
+ refcount--;
+ if (!refcount) {
+ g_hash_table_remove (priv->wd_refs, GINT_TO_POINTER (wd));
+ inotify_rm_watch (priv->ifd, wd);
+ } else
+ g_hash_table_replace (priv->wd_refs, GINT_TO_POINTER (wd), GUINT_TO_POINTER (refcount));
+}
+
+static gboolean
+inotify_event_handler (GIOChannel *channel, GIOCondition cond, gpointer user_data)
+{
+ NMInotifyHelper *self = NM_INOTIFY_HELPER (user_data);
+ struct inotify_event evt;
+
+ /* read the notifications from the watch descriptor */
+ while (g_io_channel_read_chars (channel, (gchar *) &evt, sizeof (struct inotify_event), NULL, NULL) == G_IO_STATUS_NORMAL) {
+ gchar filename[PATH_MAX + 1];
+
+ filename[0] = '\0';
+ if (evt.len > 0) {
+ g_io_channel_read_chars (channel,
+ filename,
+ evt.len > PATH_MAX ? PATH_MAX : evt.len,
+ NULL, NULL);
+ }
+
+ if (!(evt.mask & IN_IGNORED))
+ g_signal_emit (self, signals[EVENT], 0, &evt, &filename[0]);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+init_inotify (NMInotifyHelper *self)
+{
+ NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
+ GIOChannel *channel;
+ guint source_id;
+
+ priv->ifd = inotify_init ();
+ if (priv->ifd == -1) {
+ g_warning ("%s: couldn't initialize inotify", __func__);
+ return FALSE;
+ }
+
+ /* Watch the inotify descriptor for file/directory change events */
+ channel = g_io_channel_unix_new (priv->ifd);
+ if (!channel) {
+ g_warning ("%s: couldn't create new GIOChannel", __func__);
+ close (priv->ifd);
+ priv->ifd = -1;
+ return FALSE;
+ }
+
+ g_io_channel_set_flags (channel, G_IO_FLAG_NONBLOCK, NULL);
+ g_io_channel_set_encoding (channel, NULL, NULL);
+
+ source_id = g_io_add_watch (channel,
+ G_IO_IN | G_IO_ERR,
+ (GIOFunc) inotify_event_handler,
+ (gpointer) self);
+ g_io_channel_unref (channel);
+ return TRUE;
+}
+
+NMInotifyHelper *
+nm_inotify_helper_get (void)
+{
+ static NMInotifyHelper *singleton = NULL;
+
+ if (!singleton) {
+ singleton = (NMInotifyHelper *) g_object_new (NM_TYPE_INOTIFY_HELPER, NULL);
+ if (!singleton)
+ return NULL;
+
+ if (!init_inotify (singleton)) {
+ g_object_unref (singleton);
+ return NULL;
+ }
+ } else
+ g_object_ref (singleton);
+
+ g_assert (singleton);
+ return singleton;
+}
+
+static void
+nm_inotify_helper_init (NMInotifyHelper *self)
+{
+ NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (self);
+
+ priv->wd_refs = g_hash_table_new (g_direct_hash, g_direct_equal);
+}
+
+static void
+finalize (GObject *object)
+{
+ NMInotifyHelperPrivate *priv = NM_INOTIFY_HELPER_GET_PRIVATE (object);
+
+ if (priv->ifd >= 0)
+ close (priv->ifd);
+
+ g_hash_table_destroy (priv->wd_refs);
+
+ G_OBJECT_CLASS (nm_inotify_helper_parent_class)->finalize (object);
+}
+
+static void
+nm_inotify_helper_class_init (NMInotifyHelperClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (NMInotifyHelperPrivate));
+
+ /* Virtual methods */
+ object_class->finalize = finalize;
+
+ /* Signals */
+ signals[EVENT] =
+ g_signal_new ("event",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NMInotifyHelperClass, event),
+ NULL, NULL,
+ _nm_marshal_VOID__POINTER_STRING,
+ G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_STRING);
+}
+
=== added file 'system-settings/src/nm-inotify-helper.h'
--- a/system-settings/src/nm-inotify-helper.h 1970-01-01 00:00:00 +0000
+++ b/system-settings/src/nm-inotify-helper.h 2008-10-02 22:32:18 +0000
@@ -0,0 +1,54 @@
+/* -*- 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
+
+#ifndef __INOTIFY_HELPER_H__
+#define __INOTIFY_HELPER_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <sys/inotify.h>
+
+#define NM_TYPE_INOTIFY_HELPER (nm_inotify_helper_get_type ())
+#define NM_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelper))
+#define NM_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass))
+#define NM_IS_INOTIFY_HELPER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_INOTIFY_HELPER))
+#define NM_IS_INOTIFY_HELPER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_INOTIFY_HELPER))
+#define NM_INOTIFY_HELPER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_INOTIFY_HELPER, NMInotifyHelperClass))
+
+typedef struct {
+ GObject parent;
+} NMInotifyHelper;
+
+typedef struct {
+ GObjectClass parent;
+
+ /* signals */
+ void (* event) (NMInotifyHelper *helper, struct inotify_event *evt, const char *filename);
+} NMInotifyHelperClass;
+
+GType nm_inotify_helper_get_type (void);
+
+NMInotifyHelper * nm_inotify_helper_get (void);
+
+int nm_inotify_helper_add_watch (NMInotifyHelper *helper, const char *path);
+
+void nm_inotify_helper_remove_watch (NMInotifyHelper *helper, int wd);
+
+#endif /* __INOTIFY_HELPER_H__ */
- Alexander
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]