From: Zbigniew Jędrzejewski-Szmek Date: Tue, 9 Dec 2025 10:30:17 +0000 (+0100) Subject: resolvectl: split out helper to parse stdin X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=097f130731513bd934ed74975ac34070197614af;p=thirdparty%2Fsystemd.git resolvectl: split out helper to parse stdin No functional change, just splitting up of a lengthy function. --- diff --git a/src/resolve/resolvconf-compat.c b/src/resolve/resolvconf-compat.c index 47abdc900f8..d8e68d524a0 100644 --- a/src/resolve/resolvconf-compat.c +++ b/src/resolve/resolvconf-compat.c @@ -14,6 +14,12 @@ #include "string-util.h" #include "strv.h" +typedef enum LookupType { + LOOKUP_TYPE_REGULAR, + LOOKUP_TYPE_PRIVATE, + LOOKUP_TYPE_EXCLUSIVE, /* -x */ +} LookupType; + static int resolvconf_help(void) { _cleanup_free_ char *link = NULL; int r; @@ -94,6 +100,75 @@ static int parse_search_domain(const char *string) { return 0; } +static int parse_stdin(LookupType lookup_type) { + int r; + + for (unsigned n = 0;;) { + _cleanup_free_ char *line = NULL; + const char *a; + + r = read_stripped_line(stdin, LONG_LINE_MAX, &line); + if (r < 0) + return log_error_errno(r, "Failed to read from stdin: %m"); + if (r == 0) + break; + n++; + + if (IN_SET(*line, '#', ';', 0)) + continue; + + a = first_word(line, "nameserver"); + if (a) { + (void) parse_nameserver(a); + continue; + } + + a = first_word(line, "domain"); + if (!a) + a = first_word(line, "search"); + if (a) { + (void) parse_search_domain(a); + continue; + } + + log_syntax(NULL, LOG_DEBUG, "stdin", n, 0, "Ignoring resolv.conf line: %s", line); + } + + switch (lookup_type) { + case LOOKUP_TYPE_REGULAR: + break; + + case LOOKUP_TYPE_PRIVATE: + arg_disable_default_route = true; + break; + + case LOOKUP_TYPE_EXCLUSIVE: + /* If -x mode is selected, let's preferably route non-suffixed lookups to this interface. + * This somewhat matches the original -x behaviour */ + + r = strv_extend(&arg_set_domain, "~."); + if (r < 0) + return log_oom(); + break; + + default: + assert_not_reached(); + } + + if (strv_isempty(arg_set_dns)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "No DNS servers specified, refusing operation."); + + if (strv_isempty(arg_set_domain)) { + /* When no domain/search is set, clear the current domains. */ + r = strv_extend(&arg_set_domain, ""); + if (r < 0) + return log_oom(); + } + + return 0; +} + int resolvconf_parse_argv(int argc, char *argv[]) { enum { @@ -114,22 +189,18 @@ int resolvconf_parse_argv(int argc, char *argv[]) { {} }; - enum { - TYPE_REGULAR, - TYPE_PRIVATE, - TYPE_EXCLUSIVE, /* -x */ - } type = TYPE_REGULAR; - int c, r; assert(argc >= 0); assert(argv); /* openresolv checks these environment variables */ + LookupType lookup_type = LOOKUP_TYPE_REGULAR; + if (getenv("IF_EXCLUSIVE")) - type = TYPE_EXCLUSIVE; + lookup_type = LOOKUP_TYPE_EXCLUSIVE; if (getenv("IF_PRIVATE")) - type = TYPE_PRIVATE; + lookup_type = LOOKUP_TYPE_PRIVATE; arg_mode = _MODE_INVALID; @@ -153,11 +224,11 @@ int resolvconf_parse_argv(int argc, char *argv[]) { /* The exclusive/private/force stuff is an openresolv invention, we support in some skewed way */ case 'x': - type = TYPE_EXCLUSIVE; + lookup_type = LOOKUP_TYPE_EXCLUSIVE; break; case 'p': - type = TYPE_PRIVATE; + lookup_type = LOOKUP_TYPE_PRIVATE; break; case 'f': @@ -215,75 +286,12 @@ int resolvconf_parse_argv(int argc, char *argv[]) { r = ifname_resolvconf_mangle(argv[optind]); if (r <= 0) return r; - optind++; if (arg_mode == MODE_SET_LINK) { - unsigned n = 0; - - for (;;) { - _cleanup_free_ char *line = NULL; - const char *a; - - r = read_stripped_line(stdin, LONG_LINE_MAX, &line); - if (r < 0) - return log_error_errno(r, "Failed to read from stdin: %m"); - if (r == 0) - break; - - n++; - - if (IN_SET(*line, '#', ';', 0)) - continue; - - a = first_word(line, "nameserver"); - if (a) { - (void) parse_nameserver(a); - continue; - } - - a = first_word(line, "domain"); - if (!a) - a = first_word(line, "search"); - if (a) { - (void) parse_search_domain(a); - continue; - } - - log_syntax(NULL, LOG_DEBUG, "stdin", n, 0, "Ignoring resolv.conf line: %s", line); - } - - switch (type) { - case TYPE_REGULAR: - break; - - case TYPE_PRIVATE: - arg_disable_default_route = true; - break; - - case TYPE_EXCLUSIVE: - /* If -x mode is selected, let's preferably route non-suffixed lookups to this interface. This - * somewhat matches the original -x behaviour */ - - r = strv_extend(&arg_set_domain, "~."); - if (r < 0) - return log_oom(); - break; - - default: - assert_not_reached(); - } - - if (strv_isempty(arg_set_dns)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "No DNS servers specified, refusing operation."); - - if (strv_isempty(arg_set_domain)) { - /* When no domain/search is set, clear the current domains. */ - r = strv_extend(&arg_set_domain, ""); - if (r < 0) - return log_oom(); - } + r = parse_stdin(lookup_type); + if (r < 0) + return r; } return 1; /* work to do */