commit cdad254f778996437500ff813f91cabab717ed3e
Author: Pavel Šimerda <psimerda@redhat.com>
Date:   Tue Nov 18 18:12:16 2014 +0100

    dns-manager: make /etc/resolv.conf a symlink to /run/NetworkManager/resolv.conf

diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c
index 0d93d8b..eda80ad 100644
--- a/src/dns-manager/nm-dns-manager.c
+++ b/src/dns-manager/nm-dns-manager.c
@@ -441,48 +441,20 @@ update_resolv_conf (char **searches,
                     char **nameservers,
                     GError **error)
 {
-	char *tmp_resolv_conf;
-	char *tmp_resolv_conf_realpath;
-	char *resolv_conf_realpath;
+	char *my_resolv_conf = "/run/NetworkManager/resolv.conf";
+	char *my_resolv_conf_tmp = "/run/NetworkManager/resolv.conf.tmp";
 	FILE *f;
-	int do_rename = 1;
-	int old_errno = 0;
 
 	g_return_val_if_fail (error != NULL, FALSE);
 
-	/* Find the real path of resolv.conf; it could be a symlink to something */
-	resolv_conf_realpath = realpath (_PATH_RESCONF, NULL);
-	if (!resolv_conf_realpath)
-		resolv_conf_realpath = strdup (_PATH_RESCONF);
-
-	/* Build up the real path for the temp resolv.conf that we're about to
-	 * write out.
-	 */
-	tmp_resolv_conf = g_strdup_printf ("%s.tmp", resolv_conf_realpath);
-	tmp_resolv_conf_realpath = realpath (tmp_resolv_conf, NULL);
-	if (!tmp_resolv_conf_realpath)
-		tmp_resolv_conf_realpath = strdup (tmp_resolv_conf);
-	g_free (tmp_resolv_conf);
-	tmp_resolv_conf = NULL;
-
-	if ((f = fopen (tmp_resolv_conf_realpath, "w")) == NULL) {
-		do_rename = 0;
-		old_errno = errno;
-		if ((f = fopen (_PATH_RESCONF, "w")) == NULL) {
-			g_set_error (error,
-			             NM_MANAGER_ERROR,
-			             NM_MANAGER_ERROR_FAILED,
-			             "Could not open %s: %s\nCould not open %s: %s\n",
-			             tmp_resolv_conf_realpath,
-			             g_strerror (old_errno),
-			             _PATH_RESCONF,
-			             g_strerror (errno));
-			goto out;
-		}
-		/* Update tmp_resolv_conf_realpath so the error message on fclose()
-		 * failure will be correct.
-		 */
-		strcpy (tmp_resolv_conf_realpath, _PATH_RESCONF);
+	if ((f = fopen (my_resolv_conf_tmp, "w")) == NULL) {
+		g_set_error (error,
+		             NM_MANAGER_ERROR,
+		             NM_MANAGER_ERROR_FAILED,
+		             "Could not open %s: %s\n",
+		             my_resolv_conf_tmp,
+		             g_strerror (errno));
+		return FALSE;
 	}
 
 	write_resolv_conf (f, searches, nameservers, error);
@@ -496,28 +468,46 @@ update_resolv_conf (char **searches,
 			             NM_MANAGER_ERROR,
 			             NM_MANAGER_ERROR_FAILED,
 			             "Could not close %s: %s\n",
-			             tmp_resolv_conf_realpath,
+			             my_resolv_conf_tmp,
 			             g_strerror (errno));
 		}
 	}
 
-	/* Don't rename the tempfile over top of the existing resolv.conf if there
-	 * was an error writing it out.
-	 */
-	if (*error == NULL && do_rename) {
-		if (rename (tmp_resolv_conf_realpath, resolv_conf_realpath) < 0) {
-			g_set_error (error,
-			             NM_MANAGER_ERROR,
-			             NM_MANAGER_ERROR_FAILED,
-			             "Could not replace " _PATH_RESCONF ": %s\n",
-			             g_strerror (errno));
-		}
+	if (*error)
+		return FALSE;
+
+	if (rename (my_resolv_conf_tmp, my_resolv_conf) < 0) {
+		g_set_error (error,
+		             NM_MANAGER_ERROR,
+		             NM_MANAGER_ERROR_FAILED,
+		             "Could not replace %s: %s\n",
+		             my_resolv_conf,
+		             g_strerror (errno));
+		return FALSE;
+	}
+
+	if (unlink (_PATH_RESCONF) == -1 && errno != ENOENT) {
+		g_set_error (error,
+		             NM_MANAGER_ERROR,
+		             NM_MANAGER_ERROR_FAILED,
+		             "Could not unlink %s: %s\n",
+		             _PATH_RESCONF,
+		             g_strerror (errno));
+		return FALSE;
+	}
+
+	if (symlink (my_resolv_conf, _PATH_RESCONF)) {
+		g_set_error (error,
+		             NM_MANAGER_ERROR,
+		             NM_MANAGER_ERROR_FAILED,
+		             "Could not create symlink %s pointing to %s: %s\n",
+		             _PATH_RESCONF,
+		             my_resolv_conf,
+		             g_strerror (errno));
+		return FALSE;
 	}
 
-out:
-	free (tmp_resolv_conf_realpath);
-	free (resolv_conf_realpath);
-	return *error ? FALSE : TRUE;
+	return TRUE;
 }
 
 static void
