about summary refs log tree commit diff
path: root/src/settings/plugins/ifupdown/interface_parser.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2014-07-06 02:16:10 +0200
committerMichael Biebl <biebl@debian.org>2014-07-06 02:16:10 +0200
commit33491bc4279481db8ae47213e34a6d695a0e8830 (patch)
tree097d2b0fdff3fae6885381ae5e57a182cd8cbbba /src/settings/plugins/ifupdown/interface_parser.c
parent59c3714a494c3b3765657c0551ad82842d98a7d2 (diff)
Imported Upstream version 0.9.10.0 upstream/0.9.10.0
Diffstat (limited to 'src/settings/plugins/ifupdown/interface_parser.c')
-rw-r--r--src/settings/plugins/ifupdown/interface_parser.c96
1 files changed, 83 insertions, 13 deletions
diff --git a/src/settings/plugins/ifupdown/interface_parser.c b/src/settings/plugins/ifupdown/interface_parser.c
index 38ed1479..ee233c93 100644
--- a/src/settings/plugins/ifupdown/interface_parser.c
+++ b/src/settings/plugins/ifupdown/interface_parser.c
@@ -25,7 +25,10 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <wordexp.h>
+#include <libgen.h>
 #include "nm-utils.h"
+#include "nm-logging.h"
 
 if_block* first;
 if_block* last;
@@ -96,21 +99,33 @@ static char *join_values_with_spaces(char *dst, char **src)
 	return(dst);
 }
 
-void ifparser_init (const char *eni_file, int quiet)
+static void _ifparser_source (const char *path, const char *en_dir, int quiet);
+
+static void
+_recursive_ifparser (const char *eni_file, int quiet)
 {
-	FILE *inp = fopen (eni_file, "r");
+	FILE *inp;
 	char line[255];
 	int skip_to_block = 1;
 	int skip_long_line = 0;
 	int offs = 0;
 
+	// Check if interfaces file exists and open it
+	if (!g_file_test (eni_file, G_FILE_TEST_EXISTS)) {
+		if (!quiet)
+			nm_log_warn (LOGD_SETTINGS, "interfaces file %s doesn't exist\n", eni_file);
+		return;
+	}
+	inp = fopen (eni_file, "r");
 	if (inp == NULL) {
 		if (!quiet)
-			g_warning ("Error: Can't open %s\n", eni_file);
+			nm_log_warn (LOGD_SETTINGS, "Can't open %s\n", eni_file);
 		return;
 	}
+	if (!quiet)
+		nm_log_info (LOGD_SETTINGS, "      interface-parser: parsing file %s\n", eni_file);
+
 
-	first = last = NULL;
 	while (!feof(inp))
 	{
 		char *token[128];	// 255 chars can only be split into 127 tokens
@@ -128,7 +143,7 @@ void ifparser_init (const char *eni_file, int quiet)
 		if (!feof(inp) && len > 0 &&  line[len-1] != '\n') {
 			if (!skip_long_line) {
 				if (!quiet)
-					g_message ("Error: Skipping over-long-line '%s...'\n", line);
+					nm_log_warn (LOGD_SETTINGS, "Skipping over-long-line '%s...'\n", line);
 			}
 			skip_long_line = 1;
 			continue;
@@ -168,22 +183,23 @@ void ifparser_init (const char *eni_file, int quiet)
 
 		if (toknum < 2) {
 			if (!quiet) {
-				g_message ("Error: Can't parse interface line '%s'\n",
-						join_values_with_spaces(value, token));
+				nm_log_warn (LOGD_SETTINGS, "Can't parse interface line '%s'\n",
+				             join_values_with_spaces(value, token));
 			}
 			skip_to_block = 1;
 			continue;
 		}
 
-		// There are four different stanzas:
-		// iface, mapping, auto and allow-*. Create a block for each of them.
+		// There are five different stanzas:
+		// iface, mapping, auto, allow-* and source.
+		// Create a block for each of them except source.
 
 		// iface stanza takes at least 3 parameters
 		if (strcmp(token[0], "iface") == 0) {
 			if (toknum < 4) {
 				if (!quiet) {
-					g_message ("Error: Can't parse iface line '%s'\n",
-							join_values_with_spaces(value, token));
+					nm_log_warn (LOGD_SETTINGS, "Can't parse iface line '%s'\n",
+					             join_values_with_spaces(value, token));
 				}
 				continue;
 			}
@@ -211,17 +227,71 @@ void ifparser_init (const char *eni_file, int quiet)
 				add_block(token[0], token[i]);
 			skip_to_block = 0;
 		}
+		// source stanza takes one or more filepaths as parameters
+		else if (strcmp(token[0], "source") == 0) {
+			int i;
+			char *en_dir;
+
+			skip_to_block = 0;
+
+			if (toknum == 1) {
+				if (!quiet)
+					nm_log_warn (LOGD_SETTINGS, "Invalid source line without parameters\n");
+				continue;
+			}
+
+			en_dir = g_path_get_dirname (eni_file);
+			for (i = 1; i < toknum; ++i)
+				_ifparser_source (token[i], en_dir, quiet);
+			g_free (en_dir);
+		}
 		else {
 			if (skip_to_block) {
 				if (!quiet) {
-					g_message ("Error: ignoring out-of-block data '%s'\n",
-							join_values_with_spaces(value, token));
+					nm_log_warn (LOGD_SETTINGS, "ignoring out-of-block data '%s'\n",
+					             join_values_with_spaces(value, token));
 				}
 			} else
 				add_data(token[0], join_values_with_spaces(value, token + 1));
 		}
 	}
 	fclose(inp);
+
+	if (!quiet)
+		nm_log_info (LOGD_SETTINGS, "      interface-parser: finished parsing file %s\n", eni_file);
+}
+
+static void
+_ifparser_source (const char *path, const char *en_dir, int quiet)
+{
+	char *abs_path;
+	wordexp_t we;
+	uint i;
+
+	if (g_path_is_absolute (path))
+		abs_path = g_strdup (path);
+	else
+		abs_path = g_build_filename (en_dir, path, NULL);
+
+	if (!quiet)
+		nm_log_info (LOGD_SETTINGS, "      interface-parser: source line includes interfaces file(s) %s\n", abs_path);
+
+	/* ifupdown uses WRDE_NOCMD for wordexp. */
+	if (wordexp (abs_path, &we, WRDE_NOCMD)) {
+		if (!quiet)
+			nm_log_warn (LOGD_SETTINGS, "word expansion for %s failed\n", abs_path);
+	} else {
+		for (i = 0; i < we.we_wordc; i++)
+			_recursive_ifparser (we.we_wordv[i], quiet);
+		wordfree (&we);
+	}
+	g_free (abs_path);
+}
+
+void ifparser_init (const char *eni_file, int quiet)
+{
+	first = last = NULL;
+	_recursive_ifparser (eni_file, quiet);
 }
 
 void _destroy_data(if_data *ifd)