lwconfig.c

来自「非常好的dns解析软件」· C语言 代码 · 共 726 行 · 第 1/2 页

C
726
字号
/* * Copyright (C) 2004-2006  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003  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 ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC 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. *//* $Id: lwconfig.c,v 1.38.18.5 2006/10/03 23:50:51 marka Exp $ *//*! \file *//** * Module for parsing resolv.conf files. * *    lwres_conf_init() creates an empty lwres_conf_t structure for *    lightweight resolver context ctx. *  *    lwres_conf_clear() frees up all the internal memory used by that *    lwres_conf_t structure in resolver context ctx. *  *    lwres_conf_parse() opens the file filename and parses it to initialise *    the resolver context ctx's lwres_conf_t structure. *  *    lwres_conf_print() prints the lwres_conf_t structure for resolver *    context ctx to the FILE fp. *  * \section lwconfig_return Return Values *  *    lwres_conf_parse() returns #LWRES_R_SUCCESS if it successfully read and *    parsed filename. It returns #LWRES_R_FAILURE if filename could not be *    opened or contained incorrect resolver statements. *  *    lwres_conf_print() returns #LWRES_R_SUCCESS unless an error occurred *    when converting the network addresses to a numeric host address *    string. If this happens, the function returns #LWRES_R_FAILURE. *  * \section lwconfig_see See Also *  *    stdio(3), \link resolver resolver \endlink *  * \section files Files *  *    /etc/resolv.conf */#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 <lwres/lwbuffer.h>#include <lwres/lwres.h>#include <lwres/net.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#endifstatic lwres_result_tlwres_conf_parsenameserver(lwres_context_t *ctx,  FILE *fp);static lwres_result_tlwres_conf_parselwserver(lwres_context_t *ctx,  FILE *fp);static lwres_result_tlwres_conf_parsedomain(lwres_context_t *ctx, FILE *fp);static lwres_result_tlwres_conf_parsesearch(lwres_context_t *ctx,  FILE *fp);static lwres_result_tlwres_conf_parsesortlist(lwres_context_t *ctx,  FILE *fp);static lwres_result_tlwres_conf_parseoption(lwres_context_t *ctx,  FILE *fp);static voidlwres_resetaddr(lwres_addr_t *addr);static lwres_result_tlwres_create_addr(const char *buff, lwres_addr_t *addr, int convert_zero);static int lwresaddr2af(int lwresaddrtype);static intlwresaddr2af(int lwresaddrtype){	int af = 0;	switch (lwresaddrtype) {	case LWRES_ADDRTYPE_V4:		af = AF_INET;		break;	case LWRES_ADDRTYPE_V6:		af = AF_INET6;		break;	}	return (af);}/*! * Eat characters from FP until EOL or EOF. Returns EOF or '\n' */static inteatline(FILE *fp) {	int ch;	ch = fgetc(fp);	while (ch != '\n' && ch != EOF)		ch = fgetc(fp);	return (ch);}/*! * Eats white space up to next newline or non-whitespace character (of * EOF). Returns the last character read. Comments are considered white * space. */static inteatwhite(FILE *fp) {	int ch;	ch = fgetc(fp);	while (ch != '\n' && ch != EOF && isspace((unsigned char)ch))		ch = fgetc(fp);	if (ch == ';' || ch == '#')		ch = eatline(fp);	return (ch);}/*! * Skip over any leading whitespace and then read in the next sequence of * non-whitespace characters. In this context newline is not considered * whitespace. Returns EOF on end-of-file, or the character * that caused the reading to stop. */static intgetword(FILE *fp, char *buffer, size_t size) {	int ch;	char *p = buffer;	REQUIRE(buffer != NULL);	REQUIRE(size > 0U);	*p = '\0';	ch = eatwhite(fp);	if (ch == EOF)		return (EOF);	do {		*p = '\0';		if (ch == EOF || isspace((unsigned char)ch))			break;		else if ((size_t) (p - buffer) == size - 1)			return (EOF);	/* Not enough space. */		*p++ = (char)ch;		ch = fgetc(fp);	} while (1);	return (ch);}static voidlwres_resetaddr(lwres_addr_t *addr) {	REQUIRE(addr != NULL);	memset(addr->address, 0, LWRES_ADDR_MAXLEN);	addr->family = 0;	addr->length = 0;}static char *lwres_strdup(lwres_context_t *ctx, const char *str) {	char *p;	REQUIRE(str != NULL);	REQUIRE(strlen(str) > 0U);	p = CTXMALLOC(strlen(str) + 1);	if (p != NULL)		strcpy(p, str);	return (p);}/*% intializes data structure for subsequent config parsing. */voidlwres_conf_init(lwres_context_t *ctx) {	int i;	lwres_conf_t *confdata;	REQUIRE(ctx != NULL);	confdata = &ctx->confdata;	confdata->nsnext = 0;	confdata->lwnext = 0;	confdata->domainname = NULL;	confdata->searchnxt = 0;	confdata->sortlistnxt = 0;	confdata->resdebug = 0;	confdata->ndots = 1;	confdata->no_tld_query = 0;	for (i = 0; i < LWRES_CONFMAXNAMESERVERS; i++)		lwres_resetaddr(&confdata->nameservers[i]);	for (i = 0; i < LWRES_CONFMAXSEARCH; i++)		confdata->search[i] = NULL;	for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {		lwres_resetaddr(&confdata->sortlist[i].addr);		lwres_resetaddr(&confdata->sortlist[i].mask);	}}/*% Frees up all the internal memory used by the config data structure, returning it to the lwres_context_t. */voidlwres_conf_clear(lwres_context_t *ctx) {	int i;	lwres_conf_t *confdata;	REQUIRE(ctx != NULL);	confdata = &ctx->confdata;	for (i = 0; i < confdata->nsnext; i++)		lwres_resetaddr(&confdata->nameservers[i]);	if (confdata->domainname != NULL) {		CTXFREE(confdata->domainname,			strlen(confdata->domainname) + 1);		confdata->domainname = NULL;	}	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++) {		lwres_resetaddr(&confdata->sortlist[i].addr);		lwres_resetaddr(&confdata->sortlist[i].mask);	}	confdata->nsnext = 0;	confdata->lwnext = 0;	confdata->domainname = NULL;	confdata->searchnxt = 0;	confdata->sortlistnxt = 0;	confdata->resdebug = 0;	confdata->ndots = 1;	confdata->no_tld_query = 0;}static lwres_result_tlwres_conf_parsenameserver(lwres_context_t *ctx,  FILE *fp) {	char word[LWRES_CONFMAXLINELEN];	int res;	lwres_conf_t *confdata;	lwres_addr_t address;	confdata = &ctx->confdata;	if (confdata->nsnext == LWRES_CONFMAXNAMESERVERS)		return (LWRES_R_SUCCESS);	res = getword(fp, word, sizeof(word));	if (strlen(word) == 0U)		return (LWRES_R_FAILURE); /* Nothing on line. */	else if (res == ' ' || res == '\t')		res = eatwhite(fp);	if (res != EOF && res != '\n')		return (LWRES_R_FAILURE); /* Extra junk on line. */	res = lwres_create_addr(word, &address, 1);	if (res == LWRES_R_SUCCESS)		confdata->nameservers[confdata->nsnext++] = address;	return (LWRES_R_SUCCESS);}static lwres_result_tlwres_conf_parselwserver(lwres_context_t *ctx,  FILE *fp) {	char word[LWRES_CONFMAXLINELEN];	int res;	lwres_conf_t *confdata;	confdata = &ctx->confdata;	if (confdata->lwnext == LWRES_CONFMAXLWSERVERS)		return (LWRES_R_SUCCESS);	res = getword(fp, word, sizeof(word));	if (strlen(word) == 0U)		return (LWRES_R_FAILURE); /* Nothing on line. */	else if (res == ' ' || res == '\t')		res = eatwhite(fp);	if (res != EOF && res != '\n')		return (LWRES_R_FAILURE); /* Extra junk on line. */	res = lwres_create_addr(word,				&confdata->lwservers[confdata->lwnext++], 1);	if (res != LWRES_R_SUCCESS)		return (res);	return (LWRES_R_SUCCESS);}static lwres_result_tlwres_conf_parsedomain(lwres_context_t *ctx,  FILE *fp) {	char word[LWRES_CONFMAXLINELEN];	int res, i;	lwres_conf_t *confdata;	confdata = &ctx->confdata;	res = getword(fp, word, sizeof(word));	if (strlen(word) == 0U)		return (LWRES_R_FAILURE); /* Nothing else on line. */	else if (res == ' ' || res == '\t')		res = eatwhite(fp);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?