lwconfig.c 13.3 KB
Newer Older
James Brister's avatar
James Brister committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Copyright (C) 2000  Internet Software Consortium.
 * 
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */

/***
 *** Module for parsing resolv.conf files.
 ***
 *** entry points are:
22
 ***	lwres_conf_init(lwres_context_t *ctx, lwres_conf_t *confdata)
James Brister's avatar
James Brister committed
23
24
 ***		intializes data structure for subsequent parsing.
 ***
25
 ***	lwres_conf_parse(const char *filename, lwres_conf_t *confdata)
James Brister's avatar
James Brister committed
26
27
28
29
30
 ***		parses a file and fills in the data structure.
 ***
 ***	lwres_conf_print(FILE *fp, lwres_conf_t *confdata)
 ***		prints the data structure to the FILE.
 ***
31
 ***	lwres_conf_clear(lwres_conf_t *confdata)
James Brister's avatar
James Brister committed
32
 ***		frees up all the internal memory used by the data
33
 ***		 structure, returning it to the lwres_context_t.
James Brister's avatar
James Brister committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 ***
 ***/

#include <config.h>

#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>

#include <lwres/lwbuffer.h>
#include <lwres/lwres.h>
#include <lwres/result.h>

#include "assert_p.h"
#include "context_p.h"


#if ! defined(NS_INADDRSZ)
#define NS_INADDRSZ	 4
#endif

#if ! defined(NS_IN6ADDRSZ)
#define NS_IN6ADDRSZ	16
#endif

extern int lwres_net_pton(int af, const char *src, void *dst);
extern const char *lwres_net_ntop(int af, const void *src, char *dst,
				  size_t size);

Michael Graff's avatar
Michael Graff committed
72
static lwres_result_t
73
lwres_conf_parsenameserver(lwres_context_t *ctx,  FILE *fp);
Michael Graff's avatar
Michael Graff committed
74
75

static lwres_result_t
76
lwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp);
Michael Graff's avatar
Michael Graff committed
77
78

static lwres_result_t
79
lwres_conf_parsesearch(lwres_context_t *ctx,  FILE *fp);
Michael Graff's avatar
Michael Graff committed
80
81

static lwres_result_t
82
lwres_conf_parsesortlist(lwres_context_t *ctx,  FILE *fp);
Michael Graff's avatar
Michael Graff committed
83
84

static lwres_result_t
85
lwres_conf_parseoption(lwres_context_t *ctx,  FILE *fp);
Michael Graff's avatar
Michael Graff committed
86
87

static void
88
lwres_resetaddr(lwres_addr_t *addr);
Michael Graff's avatar
Michael Graff committed
89
90

static lwres_result_t
91
lwres_create_addr(const char *buff, lwres_addr_t *addr);
James Brister's avatar
James Brister committed
92
93
94
95
96
97
98

/*
 * Skip over any leading whitespace and then read in the next sequence of
 * non-whitespace characters. Returnss EOF on end-of-file, or the character
 * that caused the reading to stop.
 */
static int
99
getword(FILE *fp, char *buffer, size_t size) {
James Brister's avatar
James Brister committed
100
101
102
103
104
105
106
	int ch;
	char *p = buffer;

	REQUIRE(buffer != NULL);
	REQUIRE(size > 0);

	*p = '\0';
107

James Brister's avatar
James Brister committed
108
	ch = fgetc(fp);
109
	while (ch != '\n' && ch != EOF && isspace((unsigned char)ch))
James Brister's avatar
James Brister committed
110
111
		ch = fgetc(fp);

112
	if (ch == EOF)
James Brister's avatar
James Brister committed
113
114
115
116
		return (EOF);

	do {
		*p = '\0';
117

118
		if (ch == EOF || isspace((unsigned char)ch))
James Brister's avatar
James Brister committed
119
			break;
120
		else if ((size_t) (p - buffer) == size - 1)
121
			return (EOF);	/* Not enough space. */
James Brister's avatar
James Brister committed
122
123
124
125
126
127
128
129
130

		*p++ = (char)ch;
		ch = fgetc(fp);
	} while (1);

	return (ch);
}

static void
131
lwres_resetaddr(lwres_addr_t *addr) {
James Brister's avatar
James Brister committed
132
133
	REQUIRE(addr != NULL);

134
	memset(addr->address, 0, LWRES_ADDR_MAXLEN);
James Brister's avatar
James Brister committed
135
136
137
138
139
	addr->family = 0;
	addr->length = 0;
}

static char *
140
lwres_strdup(lwres_context_t *ctx, const char *str) {
James Brister's avatar
James Brister committed
141
142
	char *p;

Bob Halley's avatar
lint    
Bob Halley committed
143
	REQUIRE(str != NULL);
James Brister's avatar
James Brister committed
144
145
146
	REQUIRE(strlen(str) > 0);

	p = CTXMALLOC(strlen(str) + 1);
147
	if (p != NULL)
James Brister's avatar
James Brister committed
148
149
150
151
152
153
		strcpy(p, str);

	return (p);
}

void
154
lwres_conf_init(lwres_context_t *ctx) {
James Brister's avatar
James Brister committed
155
	int i;
156
	lwres_conf_t *confdata;
157
158

	REQUIRE(ctx != NULL);
159
	confdata = &ctx->confdata;
160

James Brister's avatar
James Brister committed
161
162
163
164
165
	confdata->nsnext = 0;
	confdata->domainname = NULL;
	confdata->searchnxt = 0;
	confdata->sortlistnxt = 0;
	confdata->resdebug = 0;
166
	confdata->ndots = 1;
James Brister's avatar
James Brister committed
167
168
	confdata->no_tld_query = 0;

169
	for (i = 0 ; i < LWRES_CONFMAXNAMESERVERS ; i++)
170
		lwres_resetaddr(&confdata->nameservers[i]);
James Brister's avatar
James Brister committed
171

172
	for (i = 0 ; i < LWRES_CONFMAXSEARCH ; i++)
James Brister's avatar
James Brister committed
173
174
175
		confdata->search[i] = NULL;

	for (i = 0 ; i < LWRES_CONFMAXSORTLIST ; i++) {
176
177
		lwres_resetaddr(&confdata->sortlist[i].addr);
		lwres_resetaddr(&confdata->sortlist[i].mask);
James Brister's avatar
James Brister committed
178
179
180
181
	}
}

void
182
lwres_conf_clear(lwres_context_t *ctx) {
James Brister's avatar
James Brister committed
183
	int i;
184
	lwres_conf_t *confdata;
185

186
187
	REQUIRE(ctx != NULL);
	confdata = &ctx->confdata;
188
189

	for (i = 0 ; i < confdata->nsnext ; i++)
190
		lwres_resetaddr(&confdata->nameservers[i]);
James Brister's avatar
James Brister committed
191
192
193
194
195
196

	if (confdata->domainname != NULL) {
		CTXFREE(confdata->domainname,
			strlen(confdata->domainname) + 1);
		confdata->domainname = NULL;
	}
197

James Brister's avatar
James Brister committed
198
199
200
201
202
203
204
205
206
	for (i = 0 ; i < confdata->searchnxt ; i++) {
		if (confdata->search[i] != NULL) {
			CTXFREE(confdata->search[i],
				strlen(confdata->search[i]) + 1);
			confdata->search[i] = NULL;
		}
	}

	for (i = 0 ; i < LWRES_CONFMAXSORTLIST ; i++) {
207
208
		lwres_resetaddr(&confdata->sortlist[i].addr);
		lwres_resetaddr(&confdata->sortlist[i].mask);
James Brister's avatar
James Brister committed
209
210
211
212
213
214
215
	}

	confdata->nsnext = 0;
	confdata->domainname = NULL;
	confdata->searchnxt = 0;
	confdata->sortlistnxt = 0;
	confdata->resdebug = 0;
216
	confdata->ndots = 1;
James Brister's avatar
James Brister committed
217
218
219
	confdata->no_tld_query = 0;
}

Michael Graff's avatar
Michael Graff committed
220
static lwres_result_t
221
lwres_conf_parsenameserver(lwres_context_t *ctx,  FILE *fp) {
James Brister's avatar
James Brister committed
222
223
	char word[LWRES_CONFMAXLINELEN];
	int res;
224
225
226
	lwres_conf_t *confdata;

	confdata = &ctx->confdata;
227
228

	if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS)
James Brister's avatar
James Brister committed
229
		return (LWRES_R_FAILURE);
230

James Brister's avatar
James Brister committed
231
	res = getword(fp, word, sizeof(word));
232
	if (strlen(word) == 0)
233
		return (LWRES_R_FAILURE); /* Nothing on line. */
234
	else if (res != EOF && res != '\n')
235
		return (LWRES_R_FAILURE); /* Extra junk on line. */
236

237
	res = lwres_create_addr(word,
James Brister's avatar
James Brister committed
238
				&confdata->nameservers[confdata->nsnext++]);
239
	if (res != LWRES_R_SUCCESS)
James Brister's avatar
James Brister committed
240
241
242
243
244
		return (res);

	return (LWRES_R_SUCCESS);
}

Michael Graff's avatar
Michael Graff committed
245
static lwres_result_t
246
lwres_conf_parsedomain(lwres_context_t *ctx,  FILE *fp) {
James Brister's avatar
James Brister committed
247
248
	char word[LWRES_CONFMAXLINELEN];
	int res, i;
249
250
251
	lwres_conf_t *confdata;

	confdata = &ctx->confdata;
252

James Brister's avatar
James Brister committed
253
	res = getword(fp, word, sizeof(word));
254
	if (strlen(word) == 0)
255
		return (LWRES_R_FAILURE); /* Nothing else on line. */
256
	else if (res != EOF && res != '\n')
257
		return (LWRES_R_FAILURE); /* Extra junk on line. */
James Brister's avatar
James Brister committed
258

259
	if (confdata->domainname != NULL)
James Brister's avatar
James Brister committed
260
261
262
		CTXFREE(confdata->domainname,
			strlen(confdata->domainname) + 1); /*  */

263
264
265
	/*
	 * Search and domain are mutually exclusive.
	 */
James Brister's avatar
James Brister committed
266
267
268
269
270
271
272
273
	for (i = 0 ; i < LWRES_CONFMAXSEARCH ; i++) {
		if (confdata->search[i] != NULL) {
			CTXFREE(confdata->search[i],
				strlen(confdata->search[i])+1);
			confdata->search[i] = NULL;
		}
	}
	confdata->searchnxt = 0;
274

James Brister's avatar
James Brister committed
275
276
	confdata->domainname = lwres_strdup(ctx, word);

277
	if (confdata->domainname == NULL)
James Brister's avatar
James Brister committed
278
279
		return (LWRES_R_FAILURE);

280
281
	return (LWRES_R_SUCCESS);
}
James Brister's avatar
James Brister committed
282

Michael Graff's avatar
Michael Graff committed
283
static lwres_result_t
284
lwres_conf_parsesearch(lwres_context_t *ctx,  FILE *fp) {
James Brister's avatar
James Brister committed
285
286
	int idx, delim;
	char word[LWRES_CONFMAXLINELEN];
287
288
289
	lwres_conf_t *confdata;

	confdata = &ctx->confdata;
290

James Brister's avatar
James Brister committed
291
	if (confdata->domainname != NULL) {
292
293
294
		/*
		 * Search and domain are mutually exclusive.
		 */
James Brister's avatar
James Brister committed
295
296
297
298
299
		CTXFREE(confdata->domainname,
			strlen(confdata->domainname) + 1);
		confdata->domainname = NULL;
	}

300
301
302
	/*
	 * Remove any previous search definitions.
	 */
James Brister's avatar
James Brister committed
303
304
305
306
307
308
309
310
	for (idx = 0 ; idx < LWRES_CONFMAXSEARCH ; idx++) {
		if (confdata->search[idx] != NULL) {
			CTXFREE(confdata->search[idx],
				strlen(confdata->search[idx])+1);
			confdata->search[idx] = NULL;
		}
	}
	confdata->searchnxt = 0;
311

James Brister's avatar
James Brister committed
312
	delim = getword(fp, word, sizeof(word));
313
	if (strlen(word) == 0)
314
		return (LWRES_R_FAILURE); /* Nothing else on line. */
James Brister's avatar
James Brister committed
315
316
317

	idx = 0;
	while (strlen(word) > 0) {
318
		if (confdata->searchnxt == LWRES_CONFMAXSEARCH)
319
			return (LWRES_R_FAILURE); /* Too many domains. */
James Brister's avatar
James Brister committed
320
321

		confdata->search[idx] = lwres_strdup(ctx, word);
322
		if (confdata->search[idx] == NULL)
James Brister's avatar
James Brister committed
323
			return (LWRES_R_FAILURE);
324
325
326
327
		idx++;
		confdata->searchnxt++;

		if (delim == EOF || delim == '\n')
James Brister's avatar
James Brister committed
328
			break;
329
		else
James Brister's avatar
James Brister committed
330
331
332
333
334
335
			delim = getword(fp, word, sizeof(word));
	}

	return (LWRES_R_SUCCESS);
}

Michael Graff's avatar
Michael Graff committed
336
static lwres_result_t
337
lwres_create_addr(const char *buffer, lwres_addr_t *addr) {
James Brister's avatar
James Brister committed
338
	unsigned char addrbuff[NS_IN6ADDRSZ];
339
	unsigned int len;
James Brister's avatar
James Brister committed
340
341

	if (lwres_net_pton(AF_INET, buffer, &addrbuff) == 1) {
342
		addr->family = LWRES_ADDRTYPE_V4;
James Brister's avatar
James Brister committed
343
		addr->length = NS_INADDRSZ;
344
		len = 4;
James Brister's avatar
James Brister committed
345
346
#if defined(AF_INET6)
	} else if (lwres_net_pton(AF_INET6, buffer, &addrbuff) == 1) {
347
		addr->family = LWRES_ADDRTYPE_V6;
James Brister's avatar
James Brister committed
348
		addr->length = NS_IN6ADDRSZ;
349
		len = 16;
James Brister's avatar
James Brister committed
350
351
#endif
	} else {
352
		return (LWRES_R_FAILURE); /* Unrecongnised format. */
James Brister's avatar
James Brister committed
353
354
	}

355
	memcpy((void *)addr->address, addrbuff, len);
James Brister's avatar
James Brister committed
356
357
358
359

	return (LWRES_R_SUCCESS);
}

Michael Graff's avatar
Michael Graff committed
360
static lwres_result_t
361
lwres_conf_parsesortlist(lwres_context_t *ctx,  FILE *fp) {
James Brister's avatar
James Brister committed
362
363
364
	int delim, res, idx;
	char word[LWRES_CONFMAXLINELEN];
	char *p;
365
366
367
	lwres_conf_t *confdata;

	confdata = &ctx->confdata;
James Brister's avatar
James Brister committed
368
369

	delim = getword(fp, word, sizeof(word));
370
	if (strlen(word) == 0)
371
		return (LWRES_R_FAILURE); /* Empty line after keyword. */
James Brister's avatar
James Brister committed
372
373

	while (strlen(word) > 0) {
374
		if (confdata->sortlistnxt == LWRES_CONFMAXSORTLIST)
375
			return (LWRES_R_FAILURE); /* Too many values. */
376

James Brister's avatar
James Brister committed
377
		p = strchr(word, '/');
378
		if (p != NULL)
James Brister's avatar
James Brister committed
379
380
381
			*p++ = '\0';

		idx = confdata->sortlistnxt;
382
		res = lwres_create_addr(word, &confdata->sortlist[idx].addr);
383
		if (res != LWRES_R_SUCCESS)
James Brister's avatar
James Brister committed
384
			return (res);
385

James Brister's avatar
James Brister committed
386
		if (p != NULL) {
387
			res = lwres_create_addr(p,
James Brister's avatar
James Brister committed
388
						&confdata->sortlist[idx].mask);
389
			if (res != LWRES_R_SUCCESS)
James Brister's avatar
James Brister committed
390
				return (res);
391
		} else {
392
393
394
			/*
			 * Make up a mask.
			 */
395
396
397
398
399
			confdata->sortlist[idx].mask =
				confdata->sortlist[idx].addr;

			memset(&confdata->sortlist[idx].mask, 0xff,
			       confdata->sortlist[idx].addr.length);
James Brister's avatar
James Brister committed
400
401
402
		}

		confdata->sortlistnxt++;
403
404

		if (delim == EOF || delim == '\n')
James Brister's avatar
James Brister committed
405
			break;
406
		else
James Brister's avatar
James Brister committed
407
408
409
410
411
412
			delim = getword(fp, word, sizeof(word));
	}

	return (LWRES_R_SUCCESS);
}

Michael Graff's avatar
Michael Graff committed
413
static lwres_result_t
414
lwres_conf_parseoption(lwres_context_t *ctx,  FILE *fp) {
James Brister's avatar
James Brister committed
415
416
417
418
	int delim;
	long ndots;
	char *p;
	char word[LWRES_CONFMAXLINELEN];
419
	lwres_conf_t *confdata;
James Brister's avatar
James Brister committed
420

421
422
	REQUIRE(ctx != NULL);
	confdata = &ctx->confdata;
James Brister's avatar
James Brister committed
423
424

	delim = getword(fp, word, sizeof(word));
425
	if (strlen(word) == 0)
426
		return (LWRES_R_FAILURE); /* Empty line after keyword. */
James Brister's avatar
James Brister committed
427
428
429
430
431
432
433
434

	while (strlen(word) > 0) {
		if (strcmp("debug", word) == 0) {
			confdata->resdebug = 1;
		} else if (strcmp("no_tld_query", word) == 0) {
			confdata->no_tld_query = 1;
		} else if (strncmp("ndots:", word, 6) == 0) {
			ndots = strtol(word + 6, &p, 10);
435
			if (*p != '\0') /* Bad string. */
James Brister's avatar
James Brister committed
436
				return (LWRES_R_FAILURE);
437
438
			if (ndots < 0 || ndots > 0xff) /* Out of range. */
				return (LWRES_R_FAILURE);
James Brister's avatar
James Brister committed
439
440
441
			confdata->ndots = ndots;
		}

442
		if (delim == EOF || delim == '\n')
James Brister's avatar
James Brister committed
443
			break;
444
		else
James Brister's avatar
James Brister committed
445
446
447
448
449
450
			delim = getword(fp, word, sizeof(word));
	}

	return (LWRES_R_SUCCESS);
}

Michael Graff's avatar
Michael Graff committed
451
lwres_result_t
452
lwres_conf_parse(lwres_context_t *ctx, const char *filename) {
James Brister's avatar
James Brister committed
453
454
	FILE *fp = NULL;
	char word[256];
Michael Graff's avatar
Michael Graff committed
455
	lwres_result_t rval;
456
457
458
459
	lwres_conf_t *confdata;

	REQUIRE(ctx != NULL);
	confdata = &ctx->confdata;
460

James Brister's avatar
James Brister committed
461
462
463
464
	REQUIRE(filename != NULL);
	REQUIRE(strlen(filename) > 0);
	REQUIRE(confdata != NULL);

Bob Halley's avatar
lint    
Bob Halley committed
465
	rval = LWRES_R_FAILURE;		/* Make compiler happy. */
James Brister's avatar
James Brister committed
466
467
468
469
470
	errno = 0;
	if ((fp = fopen(filename, "r")) == NULL)
		return (LWRES_R_FAILURE);

	do {
471
		(void)getword(fp, word, sizeof(word));
James Brister's avatar
James Brister committed
472
473
474
475
		if (strlen(word) == 0) {
			rval = LWRES_R_SUCCESS;
			break;
		}
476
477

		if (strcmp(word, "nameserver") == 0)
478
			rval = lwres_conf_parsenameserver(ctx, fp);
479
		else if (strcmp(word, "domain") == 0)
480
			rval = lwres_conf_parsedomain(ctx, fp);
481
		else if (strcmp(word, "search") == 0)
482
			rval = lwres_conf_parsesearch(ctx, fp);
483
		else if (strcmp(word, "sortlist") == 0)
484
			rval = lwres_conf_parsesortlist(ctx, fp);
485
		else if (strcmp(word, "option") == 0)
486
			rval = lwres_conf_parseoption(ctx, fp);
James Brister's avatar
James Brister committed
487
	} while (rval == LWRES_R_SUCCESS);
488

James Brister's avatar
James Brister committed
489
490
491
492
493
	fclose(fp);

	return (rval);
}

Michael Graff's avatar
Michael Graff committed
494
lwres_result_t
495
lwres_conf_print(lwres_context_t *ctx, FILE *fp) {
James Brister's avatar
James Brister committed
496
497
498
	int i;
	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"];
	const char *p;
499
500
501
502
	lwres_conf_t *confdata;

	REQUIRE(ctx != NULL);
	confdata = &ctx->confdata;
James Brister's avatar
James Brister committed
503
504

	REQUIRE(confdata->nsnext <= LWRES_CONFMAXNAMESERVERS);
Michael Graff's avatar
Michael Graff committed
505

James Brister's avatar
James Brister committed
506
507
508
509
	for (i = 0 ; i < confdata->nsnext ; i++) {
		p = lwres_net_ntop(confdata->nameservers[i].family,
				     confdata->nameservers[i].address,
				     tmp, sizeof(tmp));
510
		if (p != tmp)
James Brister's avatar
James Brister committed
511
512
513
514
515
516
517
518
519
520
521
			return (LWRES_R_FAILURE);

		fprintf(fp, "nameserver %s\n", tmp);
	}

	if (confdata->domainname != NULL) {
		fprintf(fp, "domain %s\n", confdata->domainname);
	} else if (confdata->searchnxt > 0) {
		REQUIRE(confdata->searchnxt <= LWRES_CONFMAXSEARCH);

		fprintf(fp, "search");
522
523
		for (i = 0 ; i < confdata->searchnxt ; i++)
			fprintf(fp, " %s", confdata->search[i]);
James Brister's avatar
James Brister committed
524
525
526
527
528
529
530
531
532
533
534
		fputc('\n', fp);
	}

	REQUIRE(confdata->sortlistnxt <= LWRES_CONFMAXSORTLIST);

	if (confdata->sortlistnxt > 0) {
		fputs("sortlist", fp);
		for (i = 0 ; i < confdata->sortlistnxt ; i++) {
			p = lwres_net_ntop(confdata->sortlist[i].addr.family,
					   confdata->sortlist[i].addr.address,
					   tmp, sizeof(tmp));
535
			if (p != tmp)
James Brister's avatar
James Brister committed
536
537
538
539
540
541
542
543
544
				return (LWRES_R_FAILURE);

			fprintf(fp, " %s", tmp);

			if (confdata->sortlist[i].mask.length > 0) {
				p = lwres_net_ntop
					(confdata->sortlist[i].mask.family,
					 confdata->sortlist[i].mask.address,
					 tmp, sizeof(tmp));
545
				if (p != tmp)
James Brister's avatar
James Brister committed
546
547
548
549
550
551
552
553
					return (LWRES_R_FAILURE);

				fprintf(fp, "/%s", tmp);
			}
		}
		fputc('\n', fp);
	}

554
	if (confdata->resdebug)
James Brister's avatar
James Brister committed
555
556
		fprintf(fp, "options debug\n");

557
	if (confdata->ndots > 0)
James Brister's avatar
James Brister committed
558
559
		fprintf(fp, "options ndots:%d\n", confdata->ndots);

560
	if (confdata->no_tld_query)
James Brister's avatar
James Brister committed
561
562
563
564
		fprintf(fp, "options no_tld_query\n");

	return (LWRES_R_SUCCESS);
}
565
566

lwres_conf_t *
567
lwres_conf_get(lwres_context_t *ctx) {
568
569
570
571
	REQUIRE(ctx != NULL);

	return (&ctx->confdata);
}