lwconfig.c revision 69fe9aaafdd6a141610e86a777d325db75422070
/*
* Copyright (C) 2004, 2005 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.41 2005/04/29 00:24:06 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 "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
static lwres_result_t
static lwres_result_t
static lwres_result_t
static lwres_result_t
static lwres_result_t
static lwres_result_t
static void
static lwres_result_t
static int lwresaddr2af(int lwresaddrtype);
static int
{
int af = 0;
switch (lwresaddrtype) {
case LWRES_ADDRTYPE_V4:
break;
case LWRES_ADDRTYPE_V6:
break;
}
return (af);
}
/*!
* Eat characters from FP until EOL or EOF. Returns EOF or '\n'
*/
static int
int ch;
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 int
int ch;
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 int
int ch;
char *p = buffer;
*p = '\0';
return (EOF);
do {
*p = '\0';
break;
return (EOF); /* Not enough space. */
*p++ = (char)ch;
} while (1);
return (ch);
}
static void
}
static char *
char *p;
if (p != NULL)
return (p);
}
/*% intializes data structure for subsequent config parsing. */
void
int i;
confdata->sortlistnxt = 0;
confdata->no_tld_query = 0;
for (i = 0; i < LWRES_CONFMAXNAMESERVERS; i++)
for (i = 0; i < LWRES_CONFMAXSEARCH; i++)
for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
}
}
/*% Frees up all the internal memory used by the config data structure, returning it to the lwres_context_t. */
void
int i;
}
}
}
for (i = 0; i < LWRES_CONFMAXSORTLIST; i++) {
}
confdata->sortlistnxt = 0;
confdata->no_tld_query = 0;
}
static lwres_result_t
char word[LWRES_CONFMAXLINELEN];
int res;
return (LWRES_R_SUCCESS);
return (LWRES_R_FAILURE); /* Nothing on line. */
return (LWRES_R_FAILURE); /* Extra junk on line. */
if (res != LWRES_R_SUCCESS)
return (res);
return (LWRES_R_SUCCESS);
}
static lwres_result_t
char word[LWRES_CONFMAXLINELEN];
int res;
return (LWRES_R_SUCCESS);
return (LWRES_R_FAILURE); /* Nothing on line. */
return (LWRES_R_FAILURE); /* Extra junk on line. */
if (res != LWRES_R_SUCCESS)
return (res);
return (LWRES_R_SUCCESS);
}
static lwres_result_t
char word[LWRES_CONFMAXLINELEN];
int res, i;
return (LWRES_R_FAILURE); /* Nothing else on line. */
return (LWRES_R_FAILURE); /* Extra junk on line. */
/*
* Search and domain are mutually exclusive.
*/
for (i = 0; i < LWRES_CONFMAXSEARCH; i++) {
}
}
return (LWRES_R_FAILURE);
return (LWRES_R_SUCCESS);
}
static lwres_result_t
char word[LWRES_CONFMAXLINELEN];
/*
* Search and domain are mutually exclusive.
*/
}
/*
* Remove any previous search definitions.
*/
}
}
return (LWRES_R_FAILURE); /* Nothing else on line. */
idx = 0;
goto ignore; /* Too many domains. */
return (LWRES_R_FAILURE);
idx++;
break;
else
}
return (LWRES_R_SUCCESS);
}
static lwres_result_t
if (convert_zero) {
unsigned char zeroaddress[] = {0, 0, 0, 0};
}
} else {
return (LWRES_R_FAILURE); /* Unrecognised format. */
}
return (LWRES_R_SUCCESS);
}
static lwres_result_t
char word[LWRES_CONFMAXLINELEN];
char *p;
return (LWRES_R_FAILURE); /* Empty line after keyword. */
return (LWRES_R_FAILURE); /* Too many values. */
if (p != NULL)
*p++ = '\0';
if (res != LWRES_R_SUCCESS)
return (res);
if (p != NULL) {
res = lwres_create_addr(p,
0);
if (res != LWRES_R_SUCCESS)
return (res);
} else {
/*
* Make up a mask.
*/
}
confdata->sortlistnxt++;
break;
else
}
return (LWRES_R_SUCCESS);
}
static lwres_result_t
int delim;
long ndots;
char *p;
char word[LWRES_CONFMAXLINELEN];
return (LWRES_R_FAILURE); /* Empty line after keyword. */
if (*p != '\0') /* Bad string. */
return (LWRES_R_FAILURE);
return (LWRES_R_FAILURE);
}
break;
else
}
return (LWRES_R_SUCCESS);
}
/*% parses a file and fills in the data structure. */
char word[256];
int stopchar;
errno = 0;
return (LWRES_R_FAILURE);
do {
break;
}
else {
/* unrecognised word. Ignore entire line */
break;
}
}
} while (1);
return (ret);
}
/*% Prints the config data structure to the FILE. */
int i;
int af;
char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
const char *p;
if (p != tmp)
return (LWRES_R_FAILURE);
}
if (p != tmp)
return (LWRES_R_FAILURE);
}
}
if (confdata->sortlistnxt > 0) {
for (i = 0; i < confdata->sortlistnxt; i++) {
p = lwres_net_ntop(af,
if (p != tmp)
return (LWRES_R_FAILURE);
af = lwresaddr2af(
p = lwres_net_ntop
(af,
if (p != tmp)
return (LWRES_R_FAILURE);
}
}
}
if (confdata->no_tld_query)
return (LWRES_R_SUCCESS);
}
/*% Returns a pointer to the current config structure. */
}