diff options
| author | Michael Biebl <biebl@debian.org> | 2014-07-06 02:16:10 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2014-07-06 02:16:10 +0200 |
| commit | 33491bc4279481db8ae47213e34a6d695a0e8830 (patch) | |
| tree | 097d2b0fdff3fae6885381ae5e57a182cd8cbbba /src/settings/plugins/ifupdown/interface_parser.c | |
| parent | 59c3714a494c3b3765657c0551ad82842d98a7d2 (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.c | 96 |
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) |