File nm-fix-hosts-updating.patch of Package NetworkManager
From 41d52e582bb90710d2c02fc649505421df9e262c Mon Sep 17 00:00:00 2001
From: Tambet Ingo <tambet@gmail.com>
Date: Wed, 3 Dec 2008 12:19:43 +0200
Subject: [PATCH] nm-fix-hosts-updating
diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c
index a97103c..a31baca 100644
--- a/src/NetworkManagerPolicy.c
+++ b/src/NetworkManagerPolicy.c
@@ -250,84 +250,54 @@ get_best_device (NMManager *manager, NMActRequest **out_req)
#define FALLBACK_HOSTNAME "localhost.localdomain"
static gboolean
-update_etc_hosts (const char *hostname)
+update_etc_hosts (const char *hostname, const char *domain)
{
+ char *new_contents;
char *contents = NULL;
- char **lines = NULL, **line;
GError *error = NULL;
- gboolean initial_comments = TRUE;
- gboolean added = FALSE;
- gsize contents_len = 0;
- GString *new_contents;
+ const char *hosts = SYSCONFDIR "/hosts";
+ gsize contents_len;
gboolean success = FALSE;
- g_return_val_if_fail (hostname != NULL, FALSE);
-
- if (!g_file_get_contents (SYSCONFDIR "/hosts", &contents, &contents_len, &error)) {
- nm_warning ("%s: couldn't read " SYSCONFDIR "/hosts: (%d) %s",
- __func__, error ? error->code : 0,
- (error && error->message) ? error->message : "(unknown)");
+ if (!g_file_get_contents (hosts, &contents, &contents_len, &error)) {
+ g_warning ("%s: couldn't read %s: (%d) %s",
+ __func__, hosts, error ? error->code : 0,
+ (error && error->message) ? error->message : "(unknown)");
if (error)
g_error_free (error);
} else {
- lines = g_strsplit_set (contents, "\n\r", 0);
- g_free (contents);
- }
-
- new_contents = g_string_sized_new (contents_len ? contents_len + 100 : 200);
- if (!new_contents) {
- nm_warning ("%s: not enough memory to update " SYSCONFDIR "/hosts", __func__);
- return FALSE;
- }
-
- /* Replace any 127.0.0.1 entry that is at the beginning of the file or right
- * after initial comments. If there is no 127.0.0.1 entry at the beginning
- * or after initial comments, add one there and ignore any other 127.0.0.1
- * entries.
- */
- for (line = lines; lines && *line; line++) {
- gboolean add_line = TRUE;
-
- /* This is the first line after the initial comments */
- if (initial_comments && (*line[0] != '#')) {
- initial_comments = FALSE;
- g_string_append_printf (new_contents, "127.0.0.1\t%s", hostname);
- if (strcmp (hostname, FALLBACK_HOSTNAME))
- g_string_append_printf (new_contents, "\t" FALLBACK_HOSTNAME);
- g_string_append (new_contents, "\tlocalhost\n");
- added = TRUE;
-
- /* Don't add the entry if it's supposed to be the actual localhost reverse mapping */
- if (!strncmp (*line, "127.0.0.1", strlen ("127.0.0.1")) && strstr (*line, "localhost"))
- add_line = FALSE;
+ GRegex *regex;
+ GString *replacement;
+
+ replacement = g_string_new ("127.0.0.2\t");
+ g_string_append (replacement, hostname);
+ if (domain) {
+ g_string_append_c (replacement, '.');
+ g_string_append (replacement, domain);
+ g_string_append_c (replacement, ' ');
+ g_string_append (replacement, hostname);
}
- if (add_line) {
- g_string_append (new_contents, *line);
- /* Only append the new line if this isn't the last line in the file */
- if (*(line+1))
- g_string_append_c (new_contents, '\n');
+ regex = g_regex_new ("^127\\.0\\.0\\.2\\s+.+$", G_REGEX_MULTILINE, 0, NULL);
+ new_contents = g_regex_replace (regex, contents, contents_len, 0, replacement->str, 0, &error);
+
+ g_free (contents);
+ g_string_free (replacement, TRUE);
+ g_regex_unref (regex);
+
+ if (!error && g_file_set_contents (hosts, new_contents, -1, &error))
+ success = TRUE;
+ else {
+ nm_warning ("%s: couldn't update %s: (%d) %s",
+ __func__, hosts, error ? error->code : 0,
+ (error && error->message) ? error->message : "(unknown)");
+ if (error)
+ g_error_free (error);
}
- }
- /* Hmm, /etc/hosts was empty for some reason */
- if (!added) {
- g_string_append (new_contents, "# Do not remove the following line, or various programs");
- g_string_append (new_contents, "# that require network functionality will fail.");
- g_string_append (new_contents, "127.0.0.1\t" FALLBACK_HOSTNAME "\tlocalhost");
+ g_free (new_contents);
}
- error = NULL;
- if (!g_file_set_contents (SYSCONFDIR "/hosts", new_contents->str, -1, &error)) {
- nm_warning ("%s: couldn't update " SYSCONFDIR "/hosts: (%d) %s",
- __func__, error ? error->code : 0,
- (error && error->message) ? error->message : "(unknown)");
- if (error)
- g_error_free (error);
- } else
- success = TRUE;
-
- g_string_free (new_contents, TRUE);
return success;
}
@@ -336,7 +306,13 @@ set_system_hostname (const char *new_hostname, const char *msg)
{
char old_hostname[HOST_NAME_MAX + 1];
int ret = 0;
- const char *name = new_hostname ? new_hostname : FALLBACK_HOSTNAME;
+ char **strv;
+ const char *name;
+ const char *domain;
+
+ strv = g_strsplit (new_hostname ? new_hostname : FALLBACK_HOSTNAME, ".", 2);
+ name = strv[0];
+ domain = strv[1];
old_hostname[HOST_NAME_MAX] = '\0';
errno = 0;
@@ -346,16 +322,15 @@ set_system_hostname (const char *new_hostname, const char *msg)
__func__, errno, strerror (errno));
} else {
/* Do nothing if the hostname isn't actually changing */
- if ( (new_hostname && !strcmp (old_hostname, new_hostname))
- || (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME)))
- return;
+ if (!strcmp (old_hostname, name))
+ goto out;
}
nm_info ("Setting system hostname to '%s' (%s)", name, msg);
ret = sethostname (name, strlen (name));
if (ret == 0) {
- if (!update_etc_hosts (name)) {
+ if (!update_etc_hosts (name, domain)) {
/* error updating /etc/hosts; fallback to localhost.localdomain */
nm_info ("Setting system hostname to '" FALLBACK_HOSTNAME "' (error updating /etc/hosts)");
ret = sethostname (FALLBACK_HOSTNAME, strlen (FALLBACK_HOSTNAME));
@@ -369,6 +344,9 @@ set_system_hostname (const char *new_hostname, const char *msg)
nm_warning ("%s: couldn't set the system hostname to '%s': (%d) %s",
__func__, name, errno, strerror (errno));
}
+
+ out:
+ g_strfreev (strv);
}
static void
--
1.6.0.2