From cdac77e4c351e1d3c4b04d8018ae3a9884057570 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Mon, 15 May 2017 15:21:08 +0100 Subject: [PATCH] [Feature] Allow to use custom callback when parsing resolv.conf --- contrib/librdns/rdns.h | 14 ++++++++++++++ contrib/librdns/util.c | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/contrib/librdns/rdns.h b/contrib/librdns/rdns.h index e5fc82fe4..5c44900f1 100644 --- a/contrib/librdns/rdns.h +++ b/contrib/librdns/rdns.h @@ -265,6 +265,20 @@ void* rdns_resolver_add_server (struct rdns_resolver *resolver, bool rdns_resolver_parse_resolv_conf (struct rdns_resolver *resolver, const char *path); +typedef bool (*rdns_resolv_conf_cb) (struct rdns_resolver *resolver, + const char *name, unsigned int port, + int priority, unsigned int io_cnt, void *ud); +/** + * Parse nameservers calling the specified callback for each nameserver + * @param resolve resolver object + * @param path path to resolv.conf file (/etc/resolv.conf typically) + * @param cb callback to call + * @param ud userdata for callback + * @return true if resolv.conf has been parsed + */ +bool rdns_resolver_parse_resolv_conf_cb (struct rdns_resolver *resolver, + const char *path, rdns_resolv_conf_cb cb, void *ud); + /** * Set an external logger function to log messages from the resolver * @param resolver resolver object diff --git a/contrib/librdns/util.c b/contrib/librdns/util.c index 32ba4a5d9..9ea8f5c43 100644 --- a/contrib/librdns/util.c +++ b/contrib/librdns/util.c @@ -487,22 +487,28 @@ rdns_request_release (struct rdns_request *req) } static bool -rdns_resolver_conf_process_line (struct rdns_resolver *resolver, char *line) +rdns_resolver_conf_process_line (struct rdns_resolver *resolver, + const char *line, rdns_resolv_conf_cb cb, void *ud) { - char *p, *c; + const char *p, *c, *end; bool has_obrace = false; unsigned int port = dns_port; - if (strncmp (line, "nameserver", sizeof ("nameserver") - 1) == 0) { + end = line + strlen (line); + + if (end - line > sizeof ("nameserver") - 1 && + strncmp (line, "nameserver", sizeof ("nameserver") - 1) == 0) { p = line + sizeof ("nameserver") - 1; /* Skip spaces */ while (*p == ' ' || *p == '\t') { p ++; } + if (*p == '[') { has_obrace = true; p ++; } + if (isxdigit (*p) || *p == ':') { c = p; while (isxdigit (*p) || *p == ':' || *p == '.') { @@ -514,7 +520,7 @@ rdns_resolver_conf_process_line (struct rdns_resolver *resolver, char *line) else if (*p != '\0' && !isspace (*p) && *p != '#') { return false; } - *p = '\0'; + if (has_obrace) { p ++; if (*p == ':') { @@ -526,7 +532,14 @@ rdns_resolver_conf_process_line (struct rdns_resolver *resolver, char *line) } } - return rdns_resolver_add_server (resolver, c, port, 0, default_io_cnt); + if (cb == NULL) { + return rdns_resolver_add_server (resolver, c, port, 0, + default_io_cnt) != NULL; + } + else { + return cb (resolver, c, port, 0, + default_io_cnt, ud); + } } else { return false; @@ -538,7 +551,8 @@ rdns_resolver_conf_process_line (struct rdns_resolver *resolver, char *line) } bool -rdns_resolver_parse_resolv_conf (struct rdns_resolver *resolver, const char *path) +rdns_resolver_parse_resolv_conf_cb (struct rdns_resolver *resolver, + const char *path, rdns_resolv_conf_cb cb, void *ud) { FILE *in; char buf[BUFSIZ]; @@ -550,10 +564,11 @@ rdns_resolver_parse_resolv_conf (struct rdns_resolver *resolver, const char *pat } while (!feof (in)) { - if (fgets (buf, sizeof (buf), in) == NULL) { + if (fgets (buf, sizeof (buf) - 1, in) == NULL) { break; } - if (!rdns_resolver_conf_process_line (resolver, buf)) { + + if (!rdns_resolver_conf_process_line (resolver, buf, cb, ud)) { rdns_warn ("rdns_resolver_parse_resolv_conf: cannot parse line: %s", buf); fclose (in); return false; @@ -561,9 +576,16 @@ rdns_resolver_parse_resolv_conf (struct rdns_resolver *resolver, const char *pat } fclose (in); + return true; } +bool +rdns_resolver_parse_resolv_conf (struct rdns_resolver *resolver, const char *path) +{ + return rdns_resolver_parse_resolv_conf_cb (resolver, path, NULL, NULL); +} + bool rdns_request_has_type (struct rdns_request *req, enum rdns_request_type type) { -- 2.39.5