commit dfa447091272de6d1a7d8cd99bf7b9c0d714d299
Author: Tambet Ingo <tambet@gmail.com>
Date:   Tue Jan 13 16:12:50 2009 +0200

    Implement sending system hostname with DHCP client.

diff --git a/libnm-util/nm-setting-ip4-config.h b/libnm-util/nm-setting-ip4-config.h
index f02afb6..8626f3d 100644
--- a/libnm-util/nm-setting-ip4-config.h
+++ b/libnm-util/nm-setting-ip4-config.h
@@ -68,6 +68,7 @@ GQuark nm_setting_ip4_config_error_quark (void);
 #define NM_SETTING_IP4_CONFIG_METHOD_MANUAL     "manual"
 #define NM_SETTING_IP4_CONFIG_METHOD_SHARED     "shared"
 
+#define NM_SETTING_IP4_CONFIG_DHCP_USE_SYSTEM_HOSTNAME "system-hostname"
 
 typedef struct NMIP4Address NMIP4Address;
 
diff --git a/src/NetworkManager.c b/src/NetworkManager.c
index 5ac2e95..eb3c082 100644
--- a/src/NetworkManager.c
+++ b/src/NetworkManager.c
@@ -376,6 +376,8 @@ main (int argc, char *argv[])
 		goto done;
 	}
 
+	nm_dhcp_manager_set_hostname_provider (dhcp_mgr, G_OBJECT (manager));
+
 	/* Start our DBus service */
 	if (!nm_dbus_manager_start_service (dbus_mgr)) {
 		nm_warning ("Failed to start the dbus manager.");
diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c
index be9c9c2..675c95e 100644
--- a/src/dhcp-manager/nm-dhcp-manager.c
+++ b/src/dhcp-manager/nm-dhcp-manager.c
@@ -50,6 +50,7 @@ typedef struct {
 	NMDBusManager * dbus_mgr;
 	GHashTable *	devices;
 	DBusGProxy *	proxy;
+	GObject *       hostname_provider;
 } NMDHCPManagerPrivate;
 
 
@@ -69,6 +70,8 @@ static NMDHCPManager *nm_dhcp_manager_new (void);
 
 static void nm_dhcp_manager_cancel_transaction_real (NMDHCPDevice *device);
 
+static void hostname_provider_destroyed (gpointer data, GObject *destroyed_object);
+
 NMDHCPManager *
 nm_dhcp_manager_get (void)
 {
@@ -93,6 +96,11 @@ finalize (GObject *object)
 {
 	NMDHCPManagerPrivate *priv = NM_DHCP_MANAGER_GET_PRIVATE (object);
 
+	if (priv->hostname_provider) {
+		g_object_weak_unref (priv->hostname_provider, hostname_provider_destroyed, object);
+		priv->hostname_provider = NULL;
+	}
+
 	g_hash_table_destroy (priv->devices);
 	g_object_unref (priv->proxy);
 	g_object_unref (priv->dbus_mgr);
@@ -581,6 +589,7 @@ nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
 {
 	NMDHCPManagerPrivate *priv;
 	NMDHCPDevice *device;
+	gboolean hostname_modified = FALSE;
 
 	g_return_val_if_fail (NM_IS_DHCP_MANAGER (manager), FALSE);
 	g_return_val_if_fail (iface != NULL, FALSE);
@@ -606,7 +615,32 @@ nm_dhcp_manager_begin_transaction (NMDHCPManager *manager,
 	                                    nm_dhcp_manager_handle_timeout,
 	                                    device);
 
+	if (s_ip4 && priv->hostname_provider) {
+		const char *dhcp_hostname;
+
+		dhcp_hostname = nm_setting_ip4_config_get_dhcp_hostname (s_ip4);
+		if (dhcp_hostname && !strcmp (dhcp_hostname, NM_SETTING_IP4_CONFIG_DHCP_USE_SYSTEM_HOSTNAME)) {
+			char *system_hostname;
+
+			g_object_get (priv->hostname_provider, "hostname", &system_hostname, NULL);
+			if (system_hostname) {
+				hostname_modified = TRUE;
+				g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, system_hostname, NULL);
+				g_free (system_hostname);
+			}
+		}
+	}
+
 	nm_dhcp_client_start (device, s_ip4);
+
+	if (hostname_modified) {
+		/* Restore the saved hostname */
+		g_object_set (G_OBJECT (s_ip4),
+					  NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME,
+					  NM_SETTING_IP4_CONFIG_DHCP_USE_SYSTEM_HOSTNAME,
+					  NULL);
+	}
+
 	device->watch_id = g_child_watch_add (device->pid,
 					      (GChildWatchFunc) dhcp_watch_cb,
 					      device);
@@ -976,3 +1010,28 @@ nm_dhcp_manager_set_dhcp4_config (NMDHCPManager *self,
 	return TRUE;
 }
 
+static void
+hostname_provider_destroyed (gpointer data, GObject *destroyed_object)
+{
+	NM_DHCP_MANAGER_GET_PRIVATE (data)->hostname_provider = NULL;
+}
+
+void
+nm_dhcp_manager_set_hostname_provider (NMDHCPManager *manager, GObject *provider)
+{
+	NMDHCPManagerPrivate *priv;
+
+	g_return_if_fail (NM_IS_DHCP_MANAGER (manager));
+
+	priv = NM_DHCP_MANAGER_GET_PRIVATE (manager);
+
+	if (priv->hostname_provider) {
+		g_object_weak_unref (priv->hostname_provider, hostname_provider_destroyed, manager);
+		priv->hostname_provider = NULL;
+	}
+
+	if (G_IS_OBJECT (provider)) {
+		priv->hostname_provider = provider;
+		g_object_weak_ref (provider, hostname_provider_destroyed, manager);
+	}
+}
diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h
index 291e1b0..67cea30 100644
--- a/src/dhcp-manager/nm-dhcp-manager.h
+++ b/src/dhcp-manager/nm-dhcp-manager.h
@@ -105,4 +105,6 @@ gboolean       nm_dhcp_manager_process_signal       (NMDHCPManager *manager, DBu
 gboolean       nm_dhcp_client_start                 (NMDHCPDevice *device, NMSettingIP4Config *s_ip4);
 void           nm_dhcp_client_stop                  (const char *iface, pid_t pid);
 
+void           nm_dhcp_manager_set_hostname_provider (NMDHCPManager *manager, GObject *provider);
+
 #endif /* NM_DHCP_MANAGER_H */
