Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / lib / lwres / lwconfig.c
blob3dff9000f281364da1fc055f7678b1cae55052ff
1 /* $NetBSD: lwconfig.c,v 1.6 2014/12/10 04:38:02 christos Exp $ */
3 /*
4 * Copyright (C) 2004-2008, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2000-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /*! \file */
22 /**
23 * Module for parsing resolv.conf files.
25 * lwres_conf_init() creates an empty lwres_conf_t structure for
26 * lightweight resolver context ctx.
28 * lwres_conf_clear() frees up all the internal memory used by that
29 * lwres_conf_t structure in resolver context ctx.
31 * lwres_conf_parse() opens the file filename and parses it to initialise
32 * the resolver context ctx's lwres_conf_t structure.
34 * lwres_conf_print() prints the lwres_conf_t structure for resolver
35 * context ctx to the FILE fp.
37 * \section lwconfig_return Return Values
39 * lwres_conf_parse() returns #LWRES_R_SUCCESS if it successfully read and
40 * parsed filename. It returns #LWRES_R_FAILURE if filename could not be
41 * opened or contained incorrect resolver statements.
43 * lwres_conf_print() returns #LWRES_R_SUCCESS unless an error occurred
44 * when converting the network addresses to a numeric host address
45 * string. If this happens, the function returns #LWRES_R_FAILURE.
47 * \section lwconfig_see See Also
49 * stdio(3), \link resolver resolver \endlink
51 * \section files Files
53 * /etc/resolv.conf
56 #include <config.h>
58 #include <assert.h>
59 #include <ctype.h>
60 #include <errno.h>
61 #include <stdlib.h>
62 #include <stdio.h>
63 #include <string.h>
64 #include <unistd.h>
66 #include <lwres/lwbuffer.h>
67 #include <lwres/lwres.h>
68 #include <lwres/net.h>
69 #include <lwres/result.h>
70 #include <lwres/stdlib.h>
71 #include <lwres/string.h>
73 #include "assert_p.h"
74 #include "context_p.h"
75 #include "print_p.h"
78 #if ! defined(NS_INADDRSZ)
79 #define NS_INADDRSZ 4
80 #endif
82 #if ! defined(NS_IN6ADDRSZ)
83 #define NS_IN6ADDRSZ 16
84 #endif
86 static lwres_result_t
87 lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp);
89 static lwres_result_t
90 lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp);
92 static lwres_result_t
93 lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp);
95 static lwres_result_t
96 lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp);
98 static lwres_result_t
99 lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp);
101 static lwres_result_t
102 lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp);
104 static void
105 lwres_resetaddr(lwres_addr_t *addr);
107 static lwres_result_t
108 lwres_create_addr(const char *buff, lwres_addr_t *addr, int convert_zero);
110 static int lwresaddr2af(int lwresaddrtype);
113 static int
114 lwresaddr2af(int lwresaddrtype)
116 int af = 0;
118 switch (lwresaddrtype) {
119 case LWRES_ADDRTYPE_V4:
120 af = AF_INET;
121 break;
123 case LWRES_ADDRTYPE_V6:
124 af = AF_INET6;
125 break;
128 return (af);
133 * Eat characters from FP until EOL or EOF. Returns EOF or '\n'
135 static int
136 eatline(FILE *fp) {
137 int ch;
139 ch = fgetc(fp);
140 while (ch != '\n' && ch != EOF)
141 ch = fgetc(fp);
143 return (ch);
148 * Eats white space up to next newline or non-whitespace character (of
149 * EOF). Returns the last character read. Comments are considered white
150 * space.
152 static int
153 eatwhite(FILE *fp) {
154 int ch;
156 ch = fgetc(fp);
157 while (ch != '\n' && ch != EOF && isspace((unsigned char)ch))
158 ch = fgetc(fp);
160 if (ch == ';' || ch == '#')
161 ch = eatline(fp);
163 return (ch);
168 * Skip over any leading whitespace and then read in the next sequence of
169 * non-whitespace characters. In this context newline is not considered
170 * whitespace. Returns EOF on end-of-file, or the character
171 * that caused the reading to stop.
173 static int
174 getword(FILE *fp, char *buffer, size_t size) {
175 int ch;
176 char *p = buffer;
178 REQUIRE(buffer != NULL);
179 REQUIRE(size > 0U);
181 *p = '\0';
183 ch = eatwhite(fp);
185 if (ch == EOF)
186 return (EOF);
188 for (;;) {
189 *p = '\0';
191 if (ch == EOF || isspace((unsigned char)ch))
192 break;
193 else if ((size_t) (p - buffer) == size - 1)
194 return (EOF); /* Not enough space. */
196 *p++ = (char)ch;
197 ch = fgetc(fp);
200 return (ch);
203 static void
204 lwres_resetaddr(lwres_addr_t *addr) {
205 REQUIRE(addr != NULL);
207 memset(addr->address, 0, LWRES_ADDR_MAXLEN);
208 addr->family = 0;
209 addr->length = 0;
210 addr->zone = 0;
213 static char *
214 lwres_strdup(lwres_context_t *ctx, const char *str) {
215 char *p;
217 REQUIRE(str != NULL);
218 REQUIRE(strlen(str) > 0U);
220 p = CTXMALLOC(strlen(str) + 1);
221 if (p != NULL)
222 strcpy(p, str);
224 return (p);
227 /*% intializes data structure for subsequent config parsing. */
228 void
229 lwres_conf_init(lwres_context_t *ctx) {
230 int i;
231 lwres_conf_t *confdata;
233 REQUIRE(ctx != NULL);
234 confdata = &ctx->confdata;
236 confdata->nsnext = 0;
237 confdata->lwnext = 0;
238 confdata->domainname = NULL;
239 confdata->searchnxt = 0;
240 confdata->sortlistnxt = 0;
241 confdata->resdebug = 0;
242 confdata->ndots = 1;
243 confdata->no_tld_query = 0;
245 for (i = 0; i < LWRES_CONFMAXNAMESERVERS; i++)
246 lwres_resetaddr(&confdata->nameservers[i]);
248 for (i = 0; i < LWRES_CONFMAXSEARCH; i++)
249 confdata->search[i] = NULL;
251 for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
252 lwres_resetaddr(&confdata->sortlist[i].addr);
253 lwres_resetaddr(&confdata->sortlist[i].mask);
257 /*% Frees up all the internal memory used by the config data structure, returning it to the lwres_context_t. */
258 void
259 lwres_conf_clear(lwres_context_t *ctx) {
260 int i;
261 lwres_conf_t *confdata;
263 REQUIRE(ctx != NULL);
264 confdata = &ctx->confdata;
266 for (i = 0; i < confdata->nsnext; i++)
267 lwres_resetaddr(&confdata->nameservers[i]);
269 if (confdata->domainname != NULL) {
270 CTXFREE(confdata->domainname,
271 strlen(confdata->domainname) + 1);
272 confdata->domainname = NULL;
275 for (i = 0; i < confdata->searchnxt; i++) {
276 if (confdata->search[i] != NULL) {
277 CTXFREE(confdata->search[i],
278 strlen(confdata->search[i]) + 1);
279 confdata->search[i] = NULL;
283 for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
284 lwres_resetaddr(&confdata->sortlist[i].addr);
285 lwres_resetaddr(&confdata->sortlist[i].mask);
288 confdata->nsnext = 0;
289 confdata->lwnext = 0;
290 confdata->domainname = NULL;
291 confdata->searchnxt = 0;
292 confdata->sortlistnxt = 0;
293 confdata->resdebug = 0;
294 confdata->ndots = 1;
295 confdata->no_tld_query = 0;
298 static lwres_result_t
299 lwres_conf_parsenameserver(lwres_context_t *ctx, FILE *fp) {
300 char word[LWRES_CONFMAXLINELEN];
301 int res;
302 lwres_conf_t *confdata;
303 lwres_addr_t address;
305 confdata = &ctx->confdata;
307 if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS)
308 return (LWRES_R_SUCCESS);
310 res = getword(fp, word, sizeof(word));
311 if (strlen(word) == 0U)
312 return (LWRES_R_FAILURE); /* Nothing on line. */
313 else if (res == ' ' || res == '\t')
314 res = eatwhite(fp);
316 if (res != EOF && res != '\n')
317 return (LWRES_R_FAILURE); /* Extra junk on line. */
319 res = lwres_create_addr(word, &address, 1);
320 if (res == LWRES_R_SUCCESS &&
321 ((address.family == LWRES_ADDRTYPE_V4 && ctx->use_ipv4 == 1) ||
322 (address.family == LWRES_ADDRTYPE_V6 && ctx->use_ipv6 == 1))) {
323 confdata->nameservers[confdata->nsnext++] = address;
326 return (LWRES_R_SUCCESS);
329 static lwres_result_t
330 lwres_conf_parselwserver(lwres_context_t *ctx, FILE *fp) {
331 char word[LWRES_CONFMAXLINELEN];
332 int res;
333 lwres_conf_t *confdata;
335 confdata = &ctx->confdata;
337 if (confdata->lwnext == LWRES_CONFMAXLWSERVERS)
338 return (LWRES_R_SUCCESS);
340 res = getword(fp, word, sizeof(word));
341 if (strlen(word) == 0U)
342 return (LWRES_R_FAILURE); /* Nothing on line. */
343 else if (res == ' ' || res == '\t')
344 res = eatwhite(fp);
346 if (res != EOF && res != '\n')
347 return (LWRES_R_FAILURE); /* Extra junk on line. */
349 res = lwres_create_addr(word,
350 &confdata->lwservers[confdata->lwnext++], 1);
351 if (res != LWRES_R_SUCCESS)
352 return (res);
354 return (LWRES_R_SUCCESS);
357 static lwres_result_t
358 lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp) {
359 char word[LWRES_CONFMAXLINELEN];
360 int res, i;
361 lwres_conf_t *confdata;
363 confdata = &ctx->confdata;
365 res = getword(fp, word, sizeof(word));
366 if (strlen(word) == 0U)
367 return (LWRES_R_FAILURE); /* Nothing else on line. */
368 else if (res == ' ' || res == '\t')
369 res = eatwhite(fp);
371 if (res != EOF && res != '\n')
372 return (LWRES_R_FAILURE); /* Extra junk on line. */
374 if (confdata->domainname != NULL)
375 CTXFREE(confdata->domainname,
376 strlen(confdata->domainname) + 1); /* */
379 * Search and domain are mutually exclusive.
381 for (i = 0; i < LWRES_CONFMAXSEARCH; i++) {
382 if (confdata->search[i] != NULL) {
383 CTXFREE(confdata->search[i],
384 strlen(confdata->search[i])+1);
385 confdata->search[i] = NULL;
388 confdata->searchnxt = 0;
390 confdata->domainname = lwres_strdup(ctx, word);
392 if (confdata->domainname == NULL)
393 return (LWRES_R_FAILURE);
395 return (LWRES_R_SUCCESS);
398 static lwres_result_t
399 lwres_conf_parsesearch(lwres_context_t *ctx, FILE *fp) {
400 int idx, delim;
401 char word[LWRES_CONFMAXLINELEN];
402 lwres_conf_t *confdata;
404 confdata = &ctx->confdata;
406 if (confdata->domainname != NULL) {
408 * Search and domain are mutually exclusive.
410 CTXFREE(confdata->domainname,
411 strlen(confdata->domainname) + 1);
412 confdata->domainname = NULL;
416 * Remove any previous search definitions.
418 for (idx = 0; idx < LWRES_CONFMAXSEARCH; idx++) {
419 if (confdata->search[idx] != NULL) {
420 CTXFREE(confdata->search[idx],
421 strlen(confdata->search[idx])+1);
422 confdata->search[idx] = NULL;
425 confdata->searchnxt = 0;
427 delim = getword(fp, word, sizeof(word));
428 if (strlen(word) == 0U)
429 return (LWRES_R_FAILURE); /* Nothing else on line. */
431 idx = 0;
432 while (strlen(word) > 0U) {
433 if (confdata->searchnxt == LWRES_CONFMAXSEARCH)
434 goto ignore; /* Too many domains. */
436 confdata->search[idx] = lwres_strdup(ctx, word);
437 if (confdata->search[idx] == NULL)
438 return (LWRES_R_FAILURE);
439 idx++;
440 confdata->searchnxt++;
442 ignore:
443 if (delim == EOF || delim == '\n')
444 break;
445 else
446 delim = getword(fp, word, sizeof(word));
449 return (LWRES_R_SUCCESS);
452 static lwres_result_t
453 lwres_create_addr(const char *buffer, lwres_addr_t *addr, int convert_zero) {
454 struct in_addr v4;
455 struct in6_addr v6;
456 char buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") +
457 sizeof("%4294967295")];
458 char *percent;
459 size_t n;
461 n = strlcpy(buf, buffer, sizeof(buf));
462 if (n >= sizeof(buf))
463 return (LWRES_R_FAILURE);
465 percent = strchr(buf, '%');
466 if (percent != NULL)
467 *percent = 0;
469 if (lwres_net_aton(buffer, &v4) == 1) {
470 if (convert_zero) {
471 unsigned char zeroaddress[] = {0, 0, 0, 0};
472 unsigned char loopaddress[] = {127, 0, 0, 1};
473 if (memcmp(&v4, zeroaddress, 4) == 0)
474 memmove(&v4, loopaddress, 4);
476 addr->family = LWRES_ADDRTYPE_V4;
477 addr->length = NS_INADDRSZ;
478 addr->zone = 0;
479 memmove((void *)addr->address, &v4, NS_INADDRSZ);
481 } else if (lwres_net_pton(AF_INET6, buf, &v6) == 1) {
482 addr->family = LWRES_ADDRTYPE_V6;
483 addr->length = NS_IN6ADDRSZ;
484 memmove((void *)addr->address, &v6, NS_IN6ADDRSZ);
485 if (percent != NULL) {
486 unsigned long zone;
487 char *ep;
489 percent++;
491 #ifdef HAVE_IF_NAMETOINDEX
492 zone = if_nametoindex(percent);
493 if (zone != 0U) {
494 addr->zone = zone;
495 return (LWRES_R_SUCCESS);
497 #endif
498 zone = strtoul(percent, &ep, 10);
499 if (ep != percent && *ep == 0)
500 addr->zone = zone;
501 else
502 return (LWRES_R_FAILURE);
503 } else
504 addr->zone = 0;
505 } else
506 return (LWRES_R_FAILURE); /* Unrecognised format. */
508 return (LWRES_R_SUCCESS);
511 static lwres_result_t
512 lwres_conf_parsesortlist(lwres_context_t *ctx, FILE *fp) {
513 int delim, res, idx;
514 char word[LWRES_CONFMAXLINELEN];
515 char *p;
516 lwres_conf_t *confdata;
518 confdata = &ctx->confdata;
520 delim = getword(fp, word, sizeof(word));
521 if (strlen(word) == 0U)
522 return (LWRES_R_FAILURE); /* Empty line after keyword. */
524 while (strlen(word) > 0U) {
525 if (confdata->sortlistnxt == LWRES_CONFMAXSORTLIST)
526 return (LWRES_R_FAILURE); /* Too many values. */
528 p = strchr(word, '/');
529 if (p != NULL)
530 *p++ = '\0';
532 idx = confdata->sortlistnxt;
533 res = lwres_create_addr(word, &confdata->sortlist[idx].addr, 1);
534 if (res != LWRES_R_SUCCESS)
535 return (res);
537 if (p != NULL) {
538 res = lwres_create_addr(p,
539 &confdata->sortlist[idx].mask,
541 if (res != LWRES_R_SUCCESS)
542 return (res);
543 } else {
545 * Make up a mask.
547 confdata->sortlist[idx].mask =
548 confdata->sortlist[idx].addr;
550 memset(&confdata->sortlist[idx].mask.address, 0xff,
551 confdata->sortlist[idx].addr.length);
554 confdata->sortlistnxt++;
556 if (delim == EOF || delim == '\n')
557 break;
558 else
559 delim = getword(fp, word, sizeof(word));
562 return (LWRES_R_SUCCESS);
565 static lwres_result_t
566 lwres_conf_parseoption(lwres_context_t *ctx, FILE *fp) {
567 int delim;
568 long ndots;
569 char *p;
570 char word[LWRES_CONFMAXLINELEN];
571 lwres_conf_t *confdata;
573 REQUIRE(ctx != NULL);
574 confdata = &ctx->confdata;
576 delim = getword(fp, word, sizeof(word));
577 if (strlen(word) == 0U)
578 return (LWRES_R_FAILURE); /* Empty line after keyword. */
580 while (strlen(word) > 0U) {
581 if (strcmp("debug", word) == 0) {
582 confdata->resdebug = 1;
583 } else if (strcmp("no_tld_query", word) == 0) {
584 confdata->no_tld_query = 1;
585 } else if (strncmp("ndots:", word, 6) == 0) {
586 ndots = strtol(word + 6, &p, 10);
587 if (*p != '\0') /* Bad string. */
588 return (LWRES_R_FAILURE);
589 if (ndots < 0 || ndots > 0xff) /* Out of range. */
590 return (LWRES_R_FAILURE);
591 confdata->ndots = (lwres_uint8_t)ndots;
594 if (delim == EOF || delim == '\n')
595 break;
596 else
597 delim = getword(fp, word, sizeof(word));
600 return (LWRES_R_SUCCESS);
603 /*% parses a file and fills in the data structure. */
604 lwres_result_t
605 lwres_conf_parse(lwres_context_t *ctx, const char *filename) {
606 FILE *fp = NULL;
607 char word[256];
608 lwres_result_t rval, ret;
609 #if !defined(NDEBUG) && defined(__minix)
610 lwres_conf_t *confdata;
611 #endif /* !defined(NDEBUG) && defined(__minix) */
612 int stopchar;
614 REQUIRE(ctx != NULL);
615 #if !defined(NDEBUG) && defined(__minix)
616 confdata = &ctx->confdata;
617 #endif /* !defined(NDEBUG) && defined(__minix) */
619 REQUIRE(filename != NULL);
620 REQUIRE(strlen(filename) > 0U);
621 #if !defined(NDEBUG) && defined(__minix)
622 REQUIRE(confdata != NULL);
623 #endif /* !defined(NDEBUG) && defined(__minix) */
625 errno = 0;
626 if ((fp = fopen(filename, "r")) == NULL)
627 return (LWRES_R_NOTFOUND);
629 ret = LWRES_R_SUCCESS;
630 for (;;) {
631 stopchar = getword(fp, word, sizeof(word));
632 if (stopchar == EOF) {
633 rval = LWRES_R_SUCCESS;
634 POST(rval);
635 break;
638 if (strlen(word) == 0U)
639 rval = LWRES_R_SUCCESS;
640 else if (strcmp(word, "nameserver") == 0)
641 rval = lwres_conf_parsenameserver(ctx, fp);
642 else if (strcmp(word, "lwserver") == 0)
643 rval = lwres_conf_parselwserver(ctx, fp);
644 else if (strcmp(word, "domain") == 0)
645 rval = lwres_conf_parsedomain(ctx, fp);
646 else if (strcmp(word, "search") == 0)
647 rval = lwres_conf_parsesearch(ctx, fp);
648 else if (strcmp(word, "sortlist") == 0)
649 rval = lwres_conf_parsesortlist(ctx, fp);
650 else if (strcmp(word, "options") == 0)
651 rval = lwres_conf_parseoption(ctx, fp);
652 else {
653 /* unrecognised word. Ignore entire line */
654 rval = LWRES_R_SUCCESS;
655 stopchar = eatline(fp);
656 if (stopchar == EOF) {
657 break;
660 if (ret == LWRES_R_SUCCESS && rval != LWRES_R_SUCCESS)
661 ret = rval;
664 fclose(fp);
666 return (ret);
669 /*% Prints the config data structure to the FILE. */
670 lwres_result_t
671 lwres_conf_print(lwres_context_t *ctx, FILE *fp) {
672 int i;
673 int af;
674 char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
675 char buf[sizeof("%4000000000")];
676 const char *p;
677 lwres_conf_t *confdata;
678 lwres_addr_t tmpaddr;
680 REQUIRE(ctx != NULL);
681 confdata = &ctx->confdata;
683 REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS);
685 for (i = 0; i < confdata->nsnext; i++) {
686 af = lwresaddr2af(confdata->nameservers[i].family);
688 p = lwres_net_ntop(af, confdata->nameservers[i].address,
689 tmp, sizeof(tmp));
690 if (p != tmp)
691 return (LWRES_R_FAILURE);
693 if (af == AF_INET6 && confdata->lwservers[i].zone != 0) {
694 snprintf(buf, sizeof(buf), "%%%u",
695 confdata->nameservers[i].zone);
696 } else
697 buf[0] = 0;
699 fprintf(fp, "nameserver %s%s\n", tmp, buf);
702 for (i = 0; i < confdata->lwnext; i++) {
703 af = lwresaddr2af(confdata->lwservers[i].family);
705 p = lwres_net_ntop(af, confdata->lwservers[i].address,
706 tmp, sizeof(tmp));
707 if (p != tmp)
708 return (LWRES_R_FAILURE);
710 if (af == AF_INET6 && confdata->lwservers[i].zone != 0) {
711 snprintf(buf, sizeof(buf), "%%%u",
712 confdata->nameservers[i].zone);
713 } else
714 buf[0] = 0;
716 fprintf(fp, "lwserver %s%s\n", tmp, buf);
719 if (confdata->domainname != NULL) {
720 fprintf(fp, "domain %s\n", confdata->domainname);
721 } else if (confdata->searchnxt > 0) {
722 REQUIRE(confdata->searchnxt <= LWRES_CONFMAXSEARCH);
724 fprintf(fp, "search");
725 for (i = 0; i < confdata->searchnxt; i++)
726 fprintf(fp, " %s", confdata->search[i]);
727 fputc('\n', fp);
730 REQUIRE(confdata->sortlistnxt <= LWRES_CONFMAXSORTLIST);
732 if (confdata->sortlistnxt > 0) {
733 fputs("sortlist", fp);
734 for (i = 0; i < confdata->sortlistnxt; i++) {
735 af = lwresaddr2af(confdata->sortlist[i].addr.family);
737 p = lwres_net_ntop(af,
738 confdata->sortlist[i].addr.address,
739 tmp, sizeof(tmp));
740 if (p != tmp)
741 return (LWRES_R_FAILURE);
743 fprintf(fp, " %s", tmp);
745 tmpaddr = confdata->sortlist[i].mask;
746 memset(&tmpaddr.address, 0xff, tmpaddr.length);
748 if (memcmp(&tmpaddr.address,
749 confdata->sortlist[i].mask.address,
750 confdata->sortlist[i].mask.length) != 0) {
751 af = lwresaddr2af(
752 confdata->sortlist[i].mask.family);
753 p = lwres_net_ntop
754 (af,
755 confdata->sortlist[i].mask.address,
756 tmp, sizeof(tmp));
757 if (p != tmp)
758 return (LWRES_R_FAILURE);
760 fprintf(fp, "/%s", tmp);
763 fputc('\n', fp);
766 if (confdata->resdebug)
767 fprintf(fp, "options debug\n");
769 if (confdata->ndots > 0)
770 fprintf(fp, "options ndots:%d\n", confdata->ndots);
772 if (confdata->no_tld_query)
773 fprintf(fp, "options no_tld_query\n");
775 return (LWRES_R_SUCCESS);
778 /*% Returns a pointer to the current config structure. */
779 lwres_conf_t *
780 lwres_conf_get(lwres_context_t *ctx) {
781 REQUIRE(ctx != NULL);
783 return (&ctx->confdata);