lwconfig.c revision 0c27b3fe77ac1d5094ba3521e8142d9e7973133f
/*
* Copyright (C) 2000-2008, 2011, 2012, 2014, 2016 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
/*! \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"
#include "print_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 (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
char buf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") +
sizeof("%4294967295")];
char *percent;
size_t n;
if (n >= sizeof(buf))
return (LWRES_R_FAILURE);
*percent = 0;
if (convert_zero) {
unsigned char zeroaddress[] = {0, 0, 0, 0};
}
unsigned long zone;
char *ep;
percent++;
#ifdef HAVE_IF_NAMETOINDEX
if (zone != 0U) {
return (LWRES_R_SUCCESS);
}
#endif
else
return (LWRES_R_FAILURE);
} else
} 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;
long attempts;
long timeout;
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);
if (*p != '\0') /* Bad string. */
return (LWRES_R_FAILURE);
if (*p != '\0') /* Bad string. */
return (LWRES_R_FAILURE);
if (attempts < 0) /* Out of range. */
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_NOTFOUND);
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")];
char buf[sizeof("%4000000000")];
const char *p;
if (p != tmp)
return (LWRES_R_FAILURE);
} else
buf[0] = 0;
}
if (p != tmp)
return (LWRES_R_FAILURE);
} else
buf[0] = 0;
}
}
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. */
}