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  <[EMAIL PROTECTED]>
+
+       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  <[EMAIL PROTECTED]>
 
        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

_______________________________________________
NetworkManager-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/networkmanager-list

Reply via email to