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
}
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 == '.') {
else if (*p != '\0' && !isspace (*p) && *p != '#') {
return false;
}
- *p = '\0';
+
if (has_obrace) {
p ++;
if (*p == ':') {
}
}
- 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;
}
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];
}
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;
}
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)
{