summary refs log tree commit diff
path: root/src/settings/plugins/ifcfg-rh/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/settings/plugins/ifcfg-rh/utils.c')
-rw-r--r--src/settings/plugins/ifcfg-rh/utils.c144
1 files changed, 83 insertions, 61 deletions
diff --git a/src/settings/plugins/ifcfg-rh/utils.c b/src/settings/plugins/ifcfg-rh/utils.c
index 4b7cb43d..a793288d 100644
--- a/src/settings/plugins/ifcfg-rh/utils.c
+++ b/src/settings/plugins/ifcfg-rh/utils.c
@@ -25,6 +25,9 @@
 #include <string.h>
 
 #include "nm-core-internal.h"
+#include "nm-macros-internal.h"
+#include "NetworkManagerUtils.h"
+#include "gsystem-local-alloc.h"
 
 #include "utils.h"
 #include "shvar.h"
@@ -149,41 +152,34 @@ check_suffix (const char *base, const char *tag)
 gboolean
 utils_should_ignore_file (const char *filename, gboolean only_ifcfg)
 {
-	char *base;
-	gboolean ignore = TRUE;
-	gboolean is_ifcfg = FALSE;
-	gboolean is_other = FALSE;
+	gs_free char *base = NULL;
 
 	g_return_val_if_fail (filename != NULL, TRUE);
 
 	base = g_path_get_basename (filename);
-	g_return_val_if_fail (base != NULL, TRUE);
 
 	/* Only handle ifcfg, keys, and routes files */
-	if (!strncmp (base, IFCFG_TAG, strlen (IFCFG_TAG)))
-		is_ifcfg = TRUE;
-
-	if (only_ifcfg == FALSE) {
-		if (   !strncmp (base, KEYS_TAG, strlen (KEYS_TAG))
-		    || !strncmp (base, ROUTE_TAG, strlen (ROUTE_TAG))
-		    || !strncmp (base, ROUTE6_TAG, strlen (ROUTE6_TAG)))
-				is_other = TRUE;
+	if (strncmp (base, IFCFG_TAG, strlen (IFCFG_TAG)) != 0) {
+		if (only_ifcfg)
+			return TRUE;
+		else if (   strncmp (base, KEYS_TAG, strlen (KEYS_TAG)) != 0
+		         && strncmp (base, ROUTE_TAG, strlen (ROUTE_TAG)) != 0
+		         && strncmp (base, ROUTE6_TAG, strlen (ROUTE6_TAG)) != 0)
+			return TRUE;
 	}
 
 	/* But not those that have certain suffixes */
-	if (   (is_ifcfg || is_other)
-	    && !check_suffix (base, BAK_TAG)
-	    && !check_suffix (base, TILDE_TAG)
-	    && !check_suffix (base, ORIG_TAG)
-	    && !check_suffix (base, REJ_TAG)
-	    && !check_suffix (base, RPMNEW_TAG)
-	    && !check_suffix (base, AUGNEW_TAG)
-	    && !check_suffix (base, AUGTMP_TAG)
-	    && !check_rpm_temp_suffix (base))
-		ignore = FALSE;
-
-	g_free (base);
-	return ignore;
+	if (   check_suffix (base, BAK_TAG)
+	    || check_suffix (base, TILDE_TAG)
+	    || check_suffix (base, ORIG_TAG)
+	    || check_suffix (base, REJ_TAG)
+	    || check_suffix (base, RPMNEW_TAG)
+	    || check_suffix (base, AUGNEW_TAG)
+	    || check_suffix (base, AUGTMP_TAG)
+	    || check_rpm_temp_suffix (base))
+		return TRUE;
+
+	return FALSE;
 }
 
 char *
@@ -205,34 +201,43 @@ utils_cert_path (const char *parent, const char *suffix)
 const char *
 utils_get_ifcfg_name (const char *file, gboolean only_ifcfg)
 {
-	const char *name = NULL, *start = NULL;
-	char *base;
+	const char *name;
 
 	g_return_val_if_fail (file != NULL, NULL);
 
-	base = g_path_get_basename (file);
-	if (!base)
+	name = strrchr (file, '/');
+	if (!name)
+		name = file;
+	else
+		name++;
+	if (!*name)
 		return NULL;
 
-	/* Find the point in 'file' where 'base' starts.  We use 'file' since it's
-	 * const and thus will survive after we free 'base'.
-	 */
-	start = file + strlen (file) - strlen (base);
-	g_assert (strcmp (start, base) == 0);
-	g_free (base);
-
-	if (!strncmp (start, IFCFG_TAG, strlen (IFCFG_TAG)))
-		name = start + strlen (IFCFG_TAG);
-	else if (only_ifcfg == FALSE)  {
-		if (!strncmp (start, KEYS_TAG, strlen (KEYS_TAG)))
-			name = start + strlen (KEYS_TAG);
-		else if (!strncmp (start, ROUTE_TAG, strlen (ROUTE_TAG)))
-			name = start + strlen (ROUTE_TAG);
-		else if (!strncmp (start, ROUTE6_TAG, strlen (ROUTE6_TAG)))
-			name = start + strlen (ROUTE6_TAG);
+#define MATCH_TAG_AND_RETURN(name, TAG) \
+	G_STMT_START { \
+		if (strncmp (name, TAG, STRLEN (TAG)) == 0) { \
+			name += STRLEN (TAG); \
+			if (name[0] == '\0') \
+				return NULL; \
+			else \
+				return name; \
+		} \
+	} G_STMT_END
+
+	/* Do not detect alias files and return 'eth0:0' instead of 'eth0'.
+	 * Unfortunately, we cannot be sure that our files don't contain colons,
+	 * so we cannot reject files with colons.
+	 *
+	 * Instead, you must not call utils_get_ifcfg_name() with an alias file
+	 * or files that are ignored. */
+	MATCH_TAG_AND_RETURN (name, IFCFG_TAG);
+	if (!only_ifcfg) {
+		MATCH_TAG_AND_RETURN (name, KEYS_TAG);
+		MATCH_TAG_AND_RETURN (name, ROUTE_TAG);
+		MATCH_TAG_AND_RETURN (name, ROUTE6_TAG);
 	}
 
-	return name;
+	return NULL;
 }
 
 /* Used to get any ifcfg/extra file path from any other ifcfg/extra path
@@ -420,26 +425,43 @@ utils_is_ifcfg_alias_file (const char *alias, const char *ifcfg)
 }
 
 char *
-utils_get_ifcfg_from_alias (const char *alias)
+utils_detect_ifcfg_path (const char *path, gboolean only_ifcfg)
 {
-	char *base, *ptr, *ifcfg = NULL;
+	gs_free char *base = NULL;
+	char *ptr, *ifcfg = NULL;
 
-	g_return_val_if_fail (alias != NULL, NULL);
+	g_return_val_if_fail (path != NULL, NULL);
 
-	base = g_path_get_basename (alias);
-	g_return_val_if_fail (base != NULL, NULL);
+	if (utils_should_ignore_file (path, only_ifcfg))
+		return NULL;
 
-	if (utils_is_ifcfg_alias_file (base, NULL)) {
-		ifcfg = g_strdup (alias);
-		ptr = strrchr (ifcfg, ':');
-		if (ptr)
-			*ptr = '\0';
-		else {
+	base = g_path_get_basename (path);
+
+	if (strncmp (base, IFCFG_TAG, STRLEN (IFCFG_TAG)) == 0) {
+		if (base[STRLEN (IFCFG_TAG)] == '\0')
+			return NULL;
+		if (utils_is_ifcfg_alias_file (base, NULL)) {
+			ifcfg = g_strdup (path);
+			ptr = strrchr (ifcfg, ':');
+			if (ptr && ptr > ifcfg) {
+				*ptr = '\0';
+				if (g_file_test (ifcfg, G_FILE_TEST_EXISTS)) {
+					/* the file has a colon, so it is probably an alias.
+					 * To be ~more~ certain that this is an alias file,
+					 * check whether a corresponding base file exists. */
+					if (only_ifcfg) {
+						g_free (ifcfg);
+						return NULL;
+					}
+					return ifcfg;
+				}
+			}
 			g_free (ifcfg);
-			ifcfg = NULL;
 		}
+		return g_strdup (path);
 	}
 
-	g_free (base);
-	return ifcfg;
+	if (only_ifcfg)
+		return NULL;
+	return utils_get_ifcfg_path (path);
 }