diff options
Diffstat (limited to 'contrib/bind9/lib/isccfg')
-rw-r--r-- | contrib/bind9/lib/isccfg/Makefile.in | 83 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/aclconf.c | 256 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/api | 3 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/include/Makefile.in | 25 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/include/isccfg/Makefile.in | 42 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/include/isccfg/aclconf.h | 73 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/include/isccfg/cfg.h | 417 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/include/isccfg/grammar.h | 452 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/include/isccfg/log.h | 55 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/include/isccfg/namedconf.h | 45 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/include/isccfg/version.h | 28 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/log.c | 52 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/namedconf.c | 2049 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/parser.c | 2382 | ||||
-rw-r--r-- | contrib/bind9/lib/isccfg/version.c | 29 |
15 files changed, 0 insertions, 5991 deletions
diff --git a/contrib/bind9/lib/isccfg/Makefile.in b/contrib/bind9/lib/isccfg/Makefile.in deleted file mode 100644 index 7d19123..0000000 --- a/contrib/bind9/lib/isccfg/Makefile.in +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2001-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: Makefile.in,v 1.12.18.4 2005/09/05 00:18:30 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -@LIBISCCFG_API@ - -@BIND9_MAKE_INCLUDES@ - -CINCLUDES = -I. ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} - -CDEFINES = @USE_DLZ@ -CWARNINGS = - -ISCLIBS = ../../lib/isc/libisc.@A@ -ISCCCLIBS = ../../lib/isccc/libisccc.@A@ -DNSLIBS = ../../lib/dns/libdns.@A@ -ISCCFGLIBS = ../../lib/cfg/libisccfg.@A@ - -ISCDEPLIBS = ../../lib/isc/libisc.@A@ -ISCCFGDEPLIBS = libisccfg.@A@ - -LIBS = @LIBS@ - -SUBDIRS = include - -# Alphabetically -OBJS = aclconf.@O@ log.@O@ namedconf.@O@ parser.@O@ version.@O@ - -# Alphabetically -SRCS = aclconf.c log.c namedconf.c parser.c version.c - -TARGETS = timestamp - -@BIND9_MAKE_RULES@ - -version.@O@: version.c - ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \ - -DVERSION=\"${VERSION}\" \ - -DLIBINTERFACE=${LIBINTERFACE} \ - -DLIBREVISION=${LIBREVISION} \ - -DLIBAGE=${LIBAGE} \ - -c ${srcdir}/version.c - -libisccfg.@SA@: ${OBJS} - ${AR} ${ARFLAGS} $@ ${OBJS} - ${RANLIB} $@ - -libisccfg.la: ${OBJS} - ${LIBTOOL_MODE_LINK} \ - ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg.la -rpath ${libdir} \ - -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \ - ${OBJS} ${LIBS} ${DNSLIBS} ${ISCCCLIBS} ${ISCLIBS} - -timestamp: libisccfg.@A@ - touch timestamp - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir} - -install:: timestamp installdirs - ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisccfg.@A@ ${DESTDIR}${libdir} - -clean distclean:: - rm -f libisccfg.@A@ timestamp diff --git a/contrib/bind9/lib/isccfg/aclconf.c b/contrib/bind9/lib/isccfg/aclconf.c deleted file mode 100644 index d7b41ce..0000000 --- a/contrib/bind9/lib/isccfg/aclconf.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2002 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: aclconf.c,v 1.2.2.6 2006/03/02 00:37:22 marka Exp $ */ - -#include <config.h> - -#include <isc/mem.h> -#include <isc/string.h> /* Required for HP/UX (and others?) */ -#include <isc/util.h> - -#include <isccfg/namedconf.h> -#include <isccfg/aclconf.h> - -#include <dns/acl.h> -#include <dns/fixedname.h> -#include <dns/log.h> - -#define LOOP_MAGIC ISC_MAGIC('L','O','O','P') - -void -cfg_aclconfctx_init(cfg_aclconfctx_t *ctx) { - ISC_LIST_INIT(ctx->named_acl_cache); -} - -void -cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx) { - dns_acl_t *dacl, *next; - for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache); - dacl != NULL; - dacl = next) - { - next = ISC_LIST_NEXT(dacl, nextincache); - dns_acl_detach(&dacl); - } -} - -/* - * Find the definition of the named acl whose name is "name". - */ -static isc_result_t -get_acl_def(const cfg_obj_t *cctx, const char *name, const cfg_obj_t **ret) { - isc_result_t result; - const cfg_obj_t *acls = NULL; - const cfg_listelt_t *elt; - - result = cfg_map_get(cctx, "acl", &acls); - if (result != ISC_R_SUCCESS) - return (result); - for (elt = cfg_list_first(acls); - elt != NULL; - elt = cfg_list_next(elt)) { - const cfg_obj_t *acl = cfg_listelt_value(elt); - const char *aclname = cfg_obj_asstring(cfg_tuple_get(acl, "name")); - if (strcasecmp(aclname, name) == 0) { - *ret = cfg_tuple_get(acl, "value"); - return (ISC_R_SUCCESS); - } - } - return (ISC_R_NOTFOUND); -} - -static isc_result_t -convert_named_acl(const cfg_obj_t *nameobj, const cfg_obj_t *cctx, - isc_log_t *lctx, cfg_aclconfctx_t *ctx, - isc_mem_t *mctx, dns_acl_t **target) -{ - isc_result_t result; - const cfg_obj_t *cacl = NULL; - dns_acl_t *dacl; - dns_acl_t loop; - const char *aclname = cfg_obj_asstring(nameobj); - - /* Look for an already-converted version. */ - for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache); - dacl != NULL; - dacl = ISC_LIST_NEXT(dacl, nextincache)) - { - if (strcasecmp(aclname, dacl->name) == 0) { - if (ISC_MAGIC_VALID(dacl, LOOP_MAGIC)) { - cfg_obj_log(nameobj, lctx, ISC_LOG_ERROR, - "acl loop detected: %s", aclname); - return (ISC_R_FAILURE); - } - dns_acl_attach(dacl, target); - return (ISC_R_SUCCESS); - } - } - /* Not yet converted. Convert now. */ - result = get_acl_def(cctx, aclname, &cacl); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(nameobj, lctx, ISC_LOG_WARNING, - "undefined ACL '%s'", aclname); - return (result); - } - /* - * Add a loop detection element. - */ - memset(&loop, 0, sizeof(loop)); - ISC_LINK_INIT(&loop, nextincache); - DE_CONST(aclname, loop.name); - loop.magic = LOOP_MAGIC; - ISC_LIST_APPEND(ctx->named_acl_cache, &loop, nextincache); - result = cfg_acl_fromconfig(cacl, cctx, lctx, ctx, mctx, &dacl); - ISC_LIST_UNLINK(ctx->named_acl_cache, &loop, nextincache); - loop.magic = 0; - loop.name = NULL; - if (result != ISC_R_SUCCESS) - return (result); - dacl->name = isc_mem_strdup(dacl->mctx, aclname); - if (dacl->name == NULL) - return (ISC_R_NOMEMORY); - ISC_LIST_APPEND(ctx->named_acl_cache, dacl, nextincache); - dns_acl_attach(dacl, target); - return (ISC_R_SUCCESS); -} - -static isc_result_t -convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx, - dns_name_t *dnsname) -{ - isc_result_t result; - isc_buffer_t buf; - dns_fixedname_t fixname; - unsigned int keylen; - const char *txtname = cfg_obj_asstring(keyobj); - - keylen = strlen(txtname); - isc_buffer_init(&buf, txtname, keylen); - isc_buffer_add(&buf, keylen); - dns_fixedname_init(&fixname); - result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf, - dns_rootname, ISC_FALSE, NULL); - if (result != ISC_R_SUCCESS) { - cfg_obj_log(keyobj, lctx, ISC_LOG_WARNING, - "key name '%s' is not a valid domain name", - txtname); - return (result); - } - return (dns_name_dup(dns_fixedname_name(&fixname), mctx, dnsname)); -} - -isc_result_t -cfg_acl_fromconfig(const cfg_obj_t *caml, - const cfg_obj_t *cctx, - isc_log_t *lctx, - cfg_aclconfctx_t *ctx, - isc_mem_t *mctx, - dns_acl_t **target) -{ - isc_result_t result; - unsigned int count; - dns_acl_t *dacl = NULL; - dns_aclelement_t *de; - const cfg_listelt_t *elt; - - REQUIRE(target != NULL && *target == NULL); - - count = 0; - for (elt = cfg_list_first(caml); - elt != NULL; - elt = cfg_list_next(elt)) - count++; - - result = dns_acl_create(mctx, count, &dacl); - if (result != ISC_R_SUCCESS) - return (result); - - de = dacl->elements; - for (elt = cfg_list_first(caml); - elt != NULL; - elt = cfg_list_next(elt)) - { - const cfg_obj_t *ce = cfg_listelt_value(elt); - if (cfg_obj_istuple(ce)) { - /* This must be a negated element. */ - ce = cfg_tuple_get(ce, "value"); - de->negative = ISC_TRUE; - } else { - de->negative = ISC_FALSE; - } - - if (cfg_obj_isnetprefix(ce)) { - /* Network prefix */ - de->type = dns_aclelementtype_ipprefix; - - cfg_obj_asnetprefix(ce, - &de->u.ip_prefix.address, - &de->u.ip_prefix.prefixlen); - } else if (cfg_obj_istype(ce, &cfg_type_keyref)) { - /* Key name */ - de->type = dns_aclelementtype_keyname; - dns_name_init(&de->u.keyname, NULL); - result = convert_keyname(ce, lctx, mctx, - &de->u.keyname); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else if (cfg_obj_islist(ce)) { - /* Nested ACL */ - de->type = dns_aclelementtype_nestedacl; - result = cfg_acl_fromconfig(ce, cctx, lctx, ctx, - mctx, &de->u.nestedacl); - if (result != ISC_R_SUCCESS) - goto cleanup; - } else if (cfg_obj_isstring(ce)) { - /* ACL name */ - const char *name = cfg_obj_asstring(ce); - if (strcasecmp(name, "localhost") == 0) { - de->type = dns_aclelementtype_localhost; - } else if (strcasecmp(name, "localnets") == 0) { - de->type = dns_aclelementtype_localnets; - } else if (strcasecmp(name, "any") == 0) { - de->type = dns_aclelementtype_any; - } else if (strcasecmp(name, "none") == 0) { - de->type = dns_aclelementtype_any; - de->negative = ISC_TF(! de->negative); - } else { - de->type = dns_aclelementtype_nestedacl; - result = convert_named_acl(ce, cctx, lctx, - ctx, mctx, - &de->u.nestedacl); - if (result != ISC_R_SUCCESS) - goto cleanup; - } - } else { - cfg_obj_log(ce, lctx, ISC_LOG_WARNING, - "address match list contains " - "unsupported element type"); - result = ISC_R_FAILURE; - goto cleanup; - } - de++; - dacl->length++; - } - - *target = dacl; - return (ISC_R_SUCCESS); - - cleanup: - dns_acl_detach(&dacl); - return (result); -} diff --git a/contrib/bind9/lib/isccfg/api b/contrib/bind9/lib/isccfg/api deleted file mode 100644 index aba393a..0000000 --- a/contrib/bind9/lib/isccfg/api +++ /dev/null @@ -1,3 +0,0 @@ -LIBINTERFACE = 30 -LIBREVISION = 3 -LIBAGE = 0 diff --git a/contrib/bind9/lib/isccfg/include/Makefile.in b/contrib/bind9/lib/isccfg/include/Makefile.in deleted file mode 100644 index 4eddd92..0000000 --- a/contrib/bind9/lib/isccfg/include/Makefile.in +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2001 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: Makefile.in,v 1.5 2004/03/05 05:12:24 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -SUBDIRS = isccfg -TARGETS = - -@BIND9_MAKE_RULES@ diff --git a/contrib/bind9/lib/isccfg/include/isccfg/Makefile.in b/contrib/bind9/lib/isccfg/include/isccfg/Makefile.in deleted file mode 100644 index d71d2c2..0000000 --- a/contrib/bind9/lib/isccfg/include/isccfg/Makefile.in +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") -# Copyright (C) 2001, 2002 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: Makefile.in,v 1.8.18.2 2005/01/12 01:54:57 marka Exp $ - -srcdir = @srcdir@ -VPATH = @srcdir@ -top_srcdir = @top_srcdir@ - -@BIND9_VERSION@ - -# -# Only list headers that are to be installed and are not -# machine generated. The latter are handled specially in the -# install target below. -# -HEADERS = aclconf.h cfg.h grammar.h log.h namedconf.h version.h - -SUBDIRS = -TARGETS = - -@BIND9_MAKE_RULES@ - -installdirs: - $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isccfg - -install:: installdirs - for i in ${HEADERS}; do \ - ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/isccfg ; \ - done diff --git a/contrib/bind9/lib/isccfg/include/isccfg/aclconf.h b/contrib/bind9/lib/isccfg/include/isccfg/aclconf.h deleted file mode 100644 index a13740c..0000000 --- a/contrib/bind9/lib/isccfg/include/isccfg/aclconf.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1999-2001 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: aclconf.h,v 1.2.2.5 2006/03/02 00:37:22 marka Exp $ */ - -#ifndef ISCCFG_ACLCONF_H -#define ISCCFG_ACLCONF_H 1 - -#include <isc/lang.h> - -#include <isccfg/cfg.h> - -#include <dns/types.h> - -typedef struct cfg_aclconfctx { - ISC_LIST(dns_acl_t) named_acl_cache; -} cfg_aclconfctx_t; - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -void -cfg_aclconfctx_init(cfg_aclconfctx_t *ctx); -/* - * Initialize an ACL configuration context. - */ - -void -cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx); -/* - * Destroy an ACL configuration context. - */ - -isc_result_t -cfg_acl_fromconfig(const cfg_obj_t *caml, - const cfg_obj_t *cctx, - isc_log_t *lctx, - cfg_aclconfctx_t *ctx, - isc_mem_t *mctx, - dns_acl_t **target); -/* - * Construct a new dns_acl_t from configuration data in 'caml' and - * 'cctx'. Memory is allocated through 'mctx'. - * - * Any named ACLs referred to within 'caml' will be be converted - * into nested dns_acl_t objects. Multiple references to the same - * named ACLs will be converted into shared references to a single - * nested dns_acl_t object when the referring objects were created - * passing the same ACL configuration context 'ctx'. - * - * On success, attach '*target' to the new dns_acl_t object. - */ - -ISC_LANG_ENDDECLS - -#endif /* ISCCFG_ACLCONF_H */ diff --git a/contrib/bind9/lib/isccfg/include/isccfg/cfg.h b/contrib/bind9/lib/isccfg/include/isccfg/cfg.h deleted file mode 100644 index 6a30a1c..0000000 --- a/contrib/bind9/lib/isccfg/include/isccfg/cfg.h +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2000-2002 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: cfg.h,v 1.34.18.5 2006/03/02 00:37:22 marka Exp $ */ - -#ifndef ISCCFG_CFG_H -#define ISCCFG_CFG_H 1 - -/***** - ***** Module Info - *****/ - -/*! \file - * \brief - * This is the new, table-driven, YACC-free configuration file parser. - */ - -/*** - *** Imports - ***/ - -#include <isc/formatcheck.h> -#include <isc/lang.h> -#include <isc/types.h> -#include <isc/list.h> - - -/*** - *** Types - ***/ - -/*% - * A configuration parser. - */ -typedef struct cfg_parser cfg_parser_t; - -/*% - * A configuration type definition object. There is a single - * static cfg_type_t object for each data type supported by - * the configuration parser. - */ -typedef struct cfg_type cfg_type_t; - -/*% - * A configuration object. This is the basic building block of the - * configuration parse tree. It contains a value (which may be - * of one of several types) and information identifying the file - * and line number the value came from, for printing error - * messages. - */ -typedef struct cfg_obj cfg_obj_t; - -/*% - * A configuration object list element. - */ -typedef struct cfg_listelt cfg_listelt_t; - -/*% - * A callback function to be called when parsing an option - * that needs to be interpreted at parsing time, like - * "directory". - */ -typedef isc_result_t -(*cfg_parsecallback_t)(const char *clausename, const cfg_obj_t *obj, void *arg); - -/*** - *** Functions - ***/ - -ISC_LANG_BEGINDECLS - -isc_result_t -cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret); -/*%< - * Create a configuration file parser. Any warning and error - * messages will be logged to 'lctx'. - * - * The parser object returned can be used for a single call - * to cfg_parse_file() or cfg_parse_buffer(). It must not - * be reused for parsing multiple files or buffers. - */ - -void -cfg_parser_setcallback(cfg_parser_t *pctx, - cfg_parsecallback_t callback, - void *arg); -/*%< - * Make the parser call 'callback' whenever it encounters - * a configuration clause with the callback attribute, - * passing it the clause name, the clause value, - * and 'arg' as arguments. - * - * To restore the default of not invoking callbacks, pass - * callback==NULL and arg==NULL. - */ - -isc_result_t -cfg_parse_file(cfg_parser_t *pctx, const char *filename, - const cfg_type_t *type, cfg_obj_t **ret); -isc_result_t -cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, - const cfg_type_t *type, cfg_obj_t **ret); -/*%< - * Read a configuration containing data of type 'type' - * and make '*ret' point to its parse tree. - * - * The configuration is read from the file 'filename' - * (isc_parse_file()) or the buffer 'buffer' - * (isc_parse_buffer()). - * - * Returns an error if the file does not parse correctly. - * - * Requires: - *\li "filename" is valid. - *\li "mem" is valid. - *\li "type" is valid. - *\li "cfg" is non-NULL and "*cfg" is NULL. - * - * Returns: - * \li #ISC_R_SUCCESS - success - *\li #ISC_R_NOMEMORY - no memory available - *\li #ISC_R_INVALIDFILE - file doesn't exist or is unreadable - *\li others - file contains errors - */ - -void -cfg_parser_destroy(cfg_parser_t **pctxp); -/*%< - * Destroy a configuration parser. - */ - -isc_boolean_t -cfg_obj_isvoid(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is of void type (e.g., an optional - * value not specified). - */ - -isc_boolean_t -cfg_obj_ismap(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is of a map type. - */ - -isc_result_t -cfg_map_get(const cfg_obj_t *mapobj, const char* name, const cfg_obj_t **obj); -/*%< - * Extract an element from a configuration object, which - * must be of a map type. - * - * Requires: - * \li 'mapobj' points to a valid configuration object of a map type. - * \li 'name' points to a null-terminated string. - * \li 'obj' is non-NULL and '*obj' is NULL. - * - * Returns: - * \li #ISC_R_SUCCESS - success - * \li #ISC_R_NOTFOUND - name not found in map - */ - -const cfg_obj_t * -cfg_map_getname(const cfg_obj_t *mapobj); -/*%< - * Get the name of a named map object, like a server "key" clause. - * - * Requires: - * \li 'mapobj' points to a valid configuration object of a map type. - * - * Returns: - * \li A pointer to a configuration object naming the map object, - * or NULL if the map object does not have a name. - */ - -isc_boolean_t -cfg_obj_istuple(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is of a map type. - */ - -const cfg_obj_t * -cfg_tuple_get(const cfg_obj_t *tupleobj, const char *name); -/*%< - * Extract an element from a configuration object, which - * must be of a tuple type. - * - * Requires: - * \li 'tupleobj' points to a valid configuration object of a tuple type. - * \li 'name' points to a null-terminated string naming one of the - *\li fields of said tuple type. - */ - -isc_boolean_t -cfg_obj_isuint32(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is of integer type. - */ - -isc_uint32_t -cfg_obj_asuint32(const cfg_obj_t *obj); -/*%< - * Returns the value of a configuration object of 32-bit integer type. - * - * Requires: - * \li 'obj' points to a valid configuration object of 32-bit integer type. - * - * Returns: - * \li A 32-bit unsigned integer. - */ - -isc_boolean_t -cfg_obj_isuint64(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is of integer type. - */ - -isc_uint64_t -cfg_obj_asuint64(const cfg_obj_t *obj); -/*%< - * Returns the value of a configuration object of 64-bit integer type. - * - * Requires: - * \li 'obj' points to a valid configuration object of 64-bit integer type. - * - * Returns: - * \li A 64-bit unsigned integer. - */ - -isc_boolean_t -cfg_obj_isstring(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is of string type. - */ - -const char * -cfg_obj_asstring(const cfg_obj_t *obj); -/*%< - * Returns the value of a configuration object of a string type - * as a null-terminated string. - * - * Requires: - * \li 'obj' points to a valid configuration object of a string type. - * - * Returns: - * \li A pointer to a null terminated string. - */ - -isc_boolean_t -cfg_obj_isboolean(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is of a boolean type. - */ - -isc_boolean_t -cfg_obj_asboolean(const cfg_obj_t *obj); -/*%< - * Returns the value of a configuration object of a boolean type. - * - * Requires: - * \li 'obj' points to a valid configuration object of a boolean type. - * - * Returns: - * \li A boolean value. - */ - -isc_boolean_t -cfg_obj_issockaddr(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is a socket address. - */ - -const isc_sockaddr_t * -cfg_obj_assockaddr(const cfg_obj_t *obj); -/*%< - * Returns the value of a configuration object representing a socket address. - * - * Requires: - * \li 'obj' points to a valid configuration object of a socket address type. - * - * Returns: - * \li A pointer to a sockaddr. The sockaddr must be copied by the caller - * if necessary. - */ - -isc_boolean_t -cfg_obj_isnetprefix(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is a network prefix. - */ - -void -cfg_obj_asnetprefix(const cfg_obj_t *obj, isc_netaddr_t *netaddr, - unsigned int *prefixlen); -/*%< - * Gets the value of a configuration object representing a network - * prefix. The network address is returned through 'netaddr' and the - * prefix length in bits through 'prefixlen'. - * - * Requires: - * \li 'obj' points to a valid configuration object of network prefix type. - *\li 'netaddr' and 'prefixlen' are non-NULL. - */ - -isc_boolean_t -cfg_obj_islist(const cfg_obj_t *obj); -/*%< - * Return true iff 'obj' is of list type. - */ - -const cfg_listelt_t * -cfg_list_first(const cfg_obj_t *obj); -/*%< - * Returns the first list element in a configuration object of a list type. - * - * Requires: - * \li 'obj' points to a valid configuration object of a list type or NULL. - * - * Returns: - * \li A pointer to a cfg_listelt_t representing the first list element, - * or NULL if the list is empty or nonexistent. - */ - -const cfg_listelt_t * -cfg_list_next(const cfg_listelt_t *elt); -/*%< - * Returns the next element of a list of configuration objects. - * - * Requires: - * \li 'elt' points to cfg_listelt_t obtained from cfg_list_first() or - * a previous call to cfg_list_next(). - * - * Returns: - * \li A pointer to a cfg_listelt_t representing the next element, - * or NULL if there are no more elements. - */ - -const cfg_obj_t * -cfg_listelt_value(const cfg_listelt_t *elt); -/*%< - * Returns the configuration object associated with cfg_listelt_t. - * - * Requires: - * \li 'elt' points to cfg_listelt_t obtained from cfg_list_first() or - * cfg_list_next(). - * - * Returns: - * \li A non-NULL pointer to a configuration object. - */ - -void -cfg_print(const cfg_obj_t *obj, - void (*f)(void *closure, const char *text, int textlen), - void *closure); -/*%< - * Print the configuration object 'obj' by repeatedly calling the - * function 'f', passing 'closure' and a region of text starting - * at 'text' and comprising 'textlen' characters. - */ - -void -cfg_print_grammar(const cfg_type_t *type, - void (*f)(void *closure, const char *text, int textlen), - void *closure); -/*%< - * Print a summary of the grammar of the configuration type 'type'. - */ - -isc_boolean_t -cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type); -/*%< - * Return true iff 'obj' is of type 'type'. - */ - -void cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj); -/*%< - * Destroy a configuration object. - */ - -void -cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level, - const char *fmt, ...) - ISC_FORMAT_PRINTF(4, 5); -/*%< - * Log a message concerning configuration object 'obj' to the logging - * channel of 'pctx', at log level 'level'. The message will be prefixed - * with the file name(s) and line number where 'obj' was defined. - */ - -const char * -cfg_obj_file(const cfg_obj_t *obj); -/*%< - * Return the file that defined this object. - */ - -unsigned int -cfg_obj_line(const cfg_obj_t *obj); -/*%< - * Return the line in file where this object was defined. - */ - - -ISC_LANG_ENDDECLS - -#endif /* ISCCFG_CFG_H */ diff --git a/contrib/bind9/lib/isccfg/include/isccfg/grammar.h b/contrib/bind9/lib/isccfg/include/isccfg/grammar.h deleted file mode 100644 index fa66146..0000000 --- a/contrib/bind9/lib/isccfg/include/isccfg/grammar.h +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2002, 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: grammar.h,v 1.4.18.8 2006/02/28 03:10:49 marka Exp $ */ - -#ifndef ISCCFG_GRAMMAR_H -#define ISCCFG_GRAMMAR_H 1 - -/*! \file */ - -#include <isc/lex.h> -#include <isc/netaddr.h> -#include <isc/sockaddr.h> -#include <isc/region.h> -#include <isc/types.h> - -#include <isccfg/cfg.h> - -/* - * Definitions shared between the configuration parser - * and the grammars; not visible to users of the parser. - */ - -/*% Clause may occur multiple times (e.g., "zone") */ -#define CFG_CLAUSEFLAG_MULTI 0x00000001 -/*% Clause is obsolete */ -#define CFG_CLAUSEFLAG_OBSOLETE 0x00000002 -/*% Clause is not implemented, and may never be */ -#define CFG_CLAUSEFLAG_NOTIMP 0x00000004 -/*% Clause is not implemented yet */ -#define CFG_CLAUSEFLAG_NYI 0x00000008 -/*% Default value has changed since earlier release */ -#define CFG_CLAUSEFLAG_NEWDEFAULT 0x00000010 -/*% - * Clause needs to be interpreted during parsing - * by calling a callback function, like the - * "directory" option. - */ -#define CFG_CLAUSEFLAG_CALLBACK 0x00000020 - -typedef struct cfg_clausedef cfg_clausedef_t; -typedef struct cfg_tuplefielddef cfg_tuplefielddef_t; -typedef struct cfg_printer cfg_printer_t; -typedef ISC_LIST(cfg_listelt_t) cfg_list_t; -typedef struct cfg_map cfg_map_t; -typedef struct cfg_rep cfg_rep_t; - -/* - * Function types for configuration object methods - */ - -typedef isc_result_t (*cfg_parsefunc_t)(cfg_parser_t *, const cfg_type_t *type, - cfg_obj_t **); -typedef void (*cfg_printfunc_t)(cfg_printer_t *, const cfg_obj_t *); -typedef void (*cfg_docfunc_t)(cfg_printer_t *, const cfg_type_t *); -typedef void (*cfg_freefunc_t)(cfg_parser_t *, cfg_obj_t *); - -/* - * Structure definitions - */ - -/*% - * A configuration printer object. This is an abstract - * interface to a destination to which text can be printed - * by calling the function 'f'. - */ -struct cfg_printer { - void (*f)(void *closure, const char *text, int textlen); - void *closure; - int indent; -}; - -/*% A clause definition. */ -struct cfg_clausedef { - const char *name; - cfg_type_t *type; - unsigned int flags; -}; - -/*% A tuple field definition. */ -struct cfg_tuplefielddef { - const char *name; - cfg_type_t *type; - unsigned int flags; -}; - -/*% A configuration object type definition. */ -struct cfg_type { - const char *name; /*%< For debugging purposes only */ - cfg_parsefunc_t parse; - cfg_printfunc_t print; - cfg_docfunc_t doc; /*%< Print grammar description */ - cfg_rep_t * rep; /*%< Data representation */ - const void * of; /*%< Additional data for meta-types */ -}; - -/*% A keyword-type definition, for things like "port <integer>". */ -typedef struct { - const char *name; - const cfg_type_t *type; -} keyword_type_t; - -struct cfg_map { - cfg_obj_t *id; /*%< Used for 'named maps' like keys, zones, &c */ - const cfg_clausedef_t * const *clausesets; /*%< The clauses that - can occur in this map; - used for printing */ - isc_symtab_t *symtab; -}; - -typedef struct cfg_netprefix cfg_netprefix_t; - -struct cfg_netprefix { - isc_netaddr_t address; /* IP4/IP6 */ - unsigned int prefixlen; -}; - -/*% - * A configuration data representation. - */ -struct cfg_rep { - const char * name; /*%< For debugging only */ - cfg_freefunc_t free; /*%< How to free this kind of data. */ -}; - -/*% - * A configuration object. This is the main building block - * of the configuration parse tree. - */ - -struct cfg_obj { - const cfg_type_t *type; - union { - isc_uint32_t uint32; - isc_uint64_t uint64; - isc_textregion_t string; /*%< null terminated, too */ - isc_boolean_t boolean; - cfg_map_t map; - cfg_list_t list; - cfg_obj_t ** tuple; - isc_sockaddr_t sockaddr; - cfg_netprefix_t netprefix; - } value; - const char * file; - unsigned int line; -}; - - -/*% A list element. */ -struct cfg_listelt { - cfg_obj_t *obj; - ISC_LINK(cfg_listelt_t) link; -}; - -/*% The parser object. */ -struct cfg_parser { - isc_mem_t * mctx; - isc_log_t * lctx; - isc_lex_t * lexer; - unsigned int errors; - unsigned int warnings; - isc_token_t token; - - /*% We are at the end of all input. */ - isc_boolean_t seen_eof; - - /*% The current token has been pushed back. */ - isc_boolean_t ungotten; - - /*% - * The stack of currently active files, represented - * as a configuration list of configuration strings. - * The head is the top-level file, subsequent elements - * (if any) are the nested include files, and the - * last element is the file currently being parsed. - */ - cfg_obj_t * open_files; - - /*% - * Names of files that we have parsed and closed - * and were previously on the open_file list. - * We keep these objects around after closing - * the files because the file names may still be - * referenced from other configuration objects - * for use in reporting semantic errors after - * parsing is complete. - */ - cfg_obj_t * closed_files; - - /*% - * Current line number. We maintain our own - * copy of this so that it is available even - * when a file has just been closed. - */ - unsigned int line; - - cfg_parsecallback_t callback; - void *callbackarg; -}; - - -/*@{*/ -/*% - * Flags defining whether to accept certain types of network addresses. - */ -#define CFG_ADDR_V4OK 0x00000001 -#define CFG_ADDR_V4PREFIXOK 0x00000002 -#define CFG_ADDR_V6OK 0x00000004 -#define CFG_ADDR_WILDOK 0x00000008 -#define CFG_ADDR_MASK (CFG_ADDR_V6OK|CFG_ADDR_V4OK) -/*@}*/ - -/*@{*/ -/*% - * Predefined data representation types. - */ -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint32; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_uint64; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_string; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_boolean; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_map; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_list; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_tuple; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_sockaddr; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_netprefix; -LIBISCCFG_EXTERNAL_DATA extern cfg_rep_t cfg_rep_void; -/*@}*/ - -/*@{*/ -/*% - * Predefined configuration object types. - */ -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_boolean; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint32; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4wild; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr6wild; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netprefix; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_void; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_token; -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_unsupported; -/*@}*/ - -isc_result_t -cfg_gettoken(cfg_parser_t *pctx, int options); - -isc_result_t -cfg_peektoken(cfg_parser_t *pctx, int options); - -void -cfg_ungettoken(cfg_parser_t *pctx); - -#define CFG_LEXOPT_QSTRING (ISC_LEXOPT_QSTRING | ISC_LEXOPT_QSTRINGMULTILINE) - -isc_result_t -cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); - -void -cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u); - -isc_result_t -cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj); - -void -cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj); - -isc_result_t -cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj); - -isc_result_t -cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -isc_result_t -cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na); - -void -cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na); - -isc_boolean_t -cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags); - -isc_result_t -cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port); - -isc_result_t -cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj); - -void -cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type); - -isc_result_t -cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -isc_result_t -cfg_parse_special(cfg_parser_t *pctx, int special); -/*%< Parse a required special character 'special'. */ - -isc_result_t -cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); - -isc_result_t -cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj); - -void -cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type); - -isc_result_t -cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); - -isc_result_t -cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype, - cfg_listelt_t **ret); - -isc_result_t -cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj); - -void -cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type); - -isc_result_t -cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj); - -isc_result_t -cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type); - -void -cfg_print_chars(cfg_printer_t *pctx, const char *text, int len); -/*%< Print 'len' characters at 'text' */ - -void -cfg_print_cstr(cfg_printer_t *pctx, const char *s); -/*%< Print the null-terminated string 's' */ - -isc_result_t -cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -isc_result_t -cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -isc_result_t -cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -isc_result_t -cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t ** -ret); - -void -cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj); - -void -cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type); - -isc_result_t -cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj); - -void -cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type); - -isc_result_t -cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj); - -void -cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type); - -isc_result_t -cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -void -cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj); - -void -cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type); -/*%< - * Print a description of the grammar of an arbitrary configuration - * type 'type' - */ - -void -cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type); -/*%< - * Document the type 'type' as a terminal by printing its - * name in angle brackets, e.g., <uint32>. - */ - -void -cfg_parser_error(cfg_parser_t *pctx, unsigned int flags, - const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); -/*! - * Pass one of these flags to cfg_parser_error() to include the - * token text in log message. - */ -#define CFG_LOG_NEAR 0x00000001 /*%< Say "near <token>" */ -#define CFG_LOG_BEFORE 0x00000002 /*%< Say "before <token>" */ -#define CFG_LOG_NOPREP 0x00000004 /*%< Say just "<token>" */ - -void -cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags, - const char *fmt, ...) ISC_FORMAT_PRINTF(3, 4); - -isc_boolean_t -cfg_is_enum(const char *s, const char *const *enums); -/*%< Return true iff the string 's' is one of the strings in 'enums' */ - -#endif /* ISCCFG_GRAMMAR_H */ diff --git a/contrib/bind9/lib/isccfg/include/isccfg/log.h b/contrib/bind9/lib/isccfg/include/isccfg/log.h deleted file mode 100644 index f66c37f..0000000 --- a/contrib/bind9/lib/isccfg/include/isccfg/log.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 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: log.h,v 1.6.18.2 2005/04/29 00:17:16 marka Exp $ */ - -#ifndef ISCCFG_LOG_H -#define ISCCFG_LOG_H 1 - -/*! \file */ - -#include <isc/lang.h> -#include <isc/log.h> - -LIBISCCFG_EXTERNAL_DATA extern isc_logcategory_t cfg_categories[]; -LIBISCCFG_EXTERNAL_DATA extern isc_logmodule_t cfg_modules[]; - -#define CFG_LOGCATEGORY_CONFIG (&cfg_categories[0]) - -#define CFG_LOGMODULE_PARSER (&cfg_modules[0]) - -ISC_LANG_BEGINDECLS - -void -cfg_log_init(isc_log_t *lctx); -/*%< - * Make the libisccfg categories and modules available for use with the - * ISC logging library. - * - * Requires: - *\li lctx is a valid logging context. - * - *\li cfg_log_init() is called only once. - * - * Ensures: - * \li The catgories and modules defined above are available for - * use by isc_log_usechannnel() and isc_log_write(). - */ - -ISC_LANG_ENDDECLS - -#endif /* ISCCFG_LOG_H */ diff --git a/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h b/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h deleted file mode 100644 index 6125b26..0000000 --- a/contrib/bind9/lib/isccfg/include/isccfg/namedconf.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2002 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: namedconf.h,v 1.3.18.2 2005/04/29 00:17:16 marka Exp $ */ - -#ifndef ISCCFG_NAMEDCONF_H -#define ISCCFG_NAMEDCONF_H 1 - -/*! \file - * \brief - * This module defines the named.conf, rndc.conf, and rndc.key grammars. - */ - -#include <isccfg/cfg.h> - -/* - * Configuration object types. - */ -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_namedconf; -/*%< A complete named.conf file. */ - -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndcconf; -/*%< A complete rndc.conf file. */ - -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_rndckey; -/*%< A complete rndc.key file. */ - -LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_keyref; -/*%< A key reference, used as an ACL element */ - -#endif /* ISCCFG_CFG_H */ diff --git a/contrib/bind9/lib/isccfg/include/isccfg/version.h b/contrib/bind9/lib/isccfg/include/isccfg/version.h deleted file mode 100644 index 38bb14b..0000000 --- a/contrib/bind9/lib/isccfg/include/isccfg/version.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 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: version.h,v 1.3.18.2 2005/04/29 00:17:16 marka Exp $ */ - -/*! \file */ - -#include <isc/platform.h> - -LIBISCCFG_EXTERNAL_DATA extern const char cfg_version[]; - -LIBISCCFG_EXTERNAL_DATA extern const unsigned int cfg_libinterface; -LIBISCCFG_EXTERNAL_DATA extern const unsigned int cfg_librevision; -LIBISCCFG_EXTERNAL_DATA extern const unsigned int cfg_libage; diff --git a/contrib/bind9/lib/isccfg/log.c b/contrib/bind9/lib/isccfg/log.c deleted file mode 100644 index 5d5ccb5..0000000 --- a/contrib/bind9/lib/isccfg/log.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2001 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: log.c,v 1.5.18.2 2005/04/29 00:17:15 marka Exp $ */ - -/*! \file */ - -#include <config.h> - -#include <isc/util.h> - -#include <isccfg/log.h> - -/*% - * When adding a new category, be sure to add the appropriate - * #define to <isccfg/log.h>. - */ -LIBISCCFG_EXTERNAL_DATA isc_logcategory_t cfg_categories[] = { - { "config", 0 }, - { NULL, 0 } -}; - -/*% - * When adding a new module, be sure to add the appropriate - * #define to <isccfg/log.h>. - */ -LIBISCCFG_EXTERNAL_DATA isc_logmodule_t cfg_modules[] = { - { "isccfg/parser", 0 }, - { NULL, 0 } -}; - -void -cfg_log_init(isc_log_t *lctx) { - REQUIRE(lctx != NULL); - - isc_log_registercategories(lctx, cfg_categories); - isc_log_registermodules(lctx, cfg_modules); -} diff --git a/contrib/bind9/lib/isccfg/namedconf.c b/contrib/bind9/lib/isccfg/namedconf.c deleted file mode 100644 index 65e30a2..0000000 --- a/contrib/bind9/lib/isccfg/namedconf.c +++ /dev/null @@ -1,2049 +0,0 @@ -/* - * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 2002, 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: namedconf.c,v 1.30.18.38 2006/05/03 01:46:40 marka Exp $ */ - -/*! \file */ - -#include <config.h> - -#include <string.h> - -#include <isc/lex.h> -#include <isc/result.h> -#include <isc/string.h> -#include <isc/util.h> - -#include <isccfg/cfg.h> -#include <isccfg/grammar.h> -#include <isccfg/log.h> - -#define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base) - -/*% Check a return value. */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -/*% Clean up a configuration object if non-NULL. */ -#define CLEANUP_OBJ(obj) \ - do { if ((obj) != NULL) cfg_obj_destroy(pctx, &(obj)); } while (0) - - -/*% - * Forward declarations of static functions. - */ - -static isc_result_t -parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype, - const cfg_type_t *othertype, cfg_obj_t **ret); - -static isc_result_t -parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -static isc_result_t -parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -static void -print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj); - -static void -doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type); - -static void -doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type); - -static cfg_type_t cfg_type_acl; -static cfg_type_t cfg_type_addrmatchelt; -static cfg_type_t cfg_type_bracketed_aml; -static cfg_type_t cfg_type_bracketed_namesockaddrkeylist; -static cfg_type_t cfg_type_bracketed_sockaddrlist; -static cfg_type_t cfg_type_bracketed_sockaddrnameportlist; -static cfg_type_t cfg_type_controls; -static cfg_type_t cfg_type_controls_sockaddr; -static cfg_type_t cfg_type_destinationlist; -static cfg_type_t cfg_type_dialuptype; -static cfg_type_t cfg_type_ixfrdifftype; -static cfg_type_t cfg_type_key; -static cfg_type_t cfg_type_logfile; -static cfg_type_t cfg_type_logging; -static cfg_type_t cfg_type_logseverity; -static cfg_type_t cfg_type_lwres; -static cfg_type_t cfg_type_masterselement; -static cfg_type_t cfg_type_nameportiplist; -static cfg_type_t cfg_type_negated; -static cfg_type_t cfg_type_notifytype; -static cfg_type_t cfg_type_optional_class; -static cfg_type_t cfg_type_optional_facility; -static cfg_type_t cfg_type_optional_facility; -static cfg_type_t cfg_type_optional_keyref; -static cfg_type_t cfg_type_optional_port; -static cfg_type_t cfg_type_options; -static cfg_type_t cfg_type_portiplist; -static cfg_type_t cfg_type_querysource4; -static cfg_type_t cfg_type_querysource6; -static cfg_type_t cfg_type_querysource; -static cfg_type_t cfg_type_server; -static cfg_type_t cfg_type_server_key_kludge; -static cfg_type_t cfg_type_size; -static cfg_type_t cfg_type_sizenodefault; -static cfg_type_t cfg_type_sockaddr4wild; -static cfg_type_t cfg_type_sockaddr6wild; -static cfg_type_t cfg_type_view; -static cfg_type_t cfg_type_viewopts; -static cfg_type_t cfg_type_zone; -static cfg_type_t cfg_type_zoneopts; -static cfg_type_t cfg_type_dynamically_loadable_zones; -static cfg_type_t cfg_type_dynamically_loadable_zones_opts; - -/* - * Clauses that can be found in a 'dynamically loadable zones' statement - */ -static cfg_clausedef_t -dynamically_loadable_zones_clauses[] = { - { "database", &cfg_type_astring, 0 }, - { NULL, NULL, 0 } -}; - -/* - * A dynamically loadable zones statement. - */ -static cfg_tuplefielddef_t dynamically_loadable_zones_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "options", &cfg_type_dynamically_loadable_zones_opts, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_dynamically_loadable_zones = { - "dlz", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, - &cfg_rep_tuple, - dynamically_loadable_zones_fields - }; - - -/*% tkey-dhkey */ - -static cfg_tuplefielddef_t tkey_dhkey_fields[] = { - { "name", &cfg_type_qstring, 0 }, - { "keyid", &cfg_type_uint32, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_tkey_dhkey = { - "tkey-dhkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - tkey_dhkey_fields -}; - -/*% listen-on */ - -static cfg_tuplefielddef_t listenon_fields[] = { - { "port", &cfg_type_optional_port, 0 }, - { "acl", &cfg_type_bracketed_aml, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_listenon = { - "listenon", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, listenon_fields }; - -/*% acl */ - -static cfg_tuplefielddef_t acl_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "value", &cfg_type_bracketed_aml, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_acl = { - "acl", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, acl_fields }; - -/*% masters */ -static cfg_tuplefielddef_t masters_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "port", &cfg_type_optional_port, 0 }, - { "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_masters = { - "masters", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, masters_fields }; - -/*% - * "sockaddrkeylist", a list of socket addresses with optional keys - * and an optional default port, as used in the masters option. - * E.g., - * "port 1234 { mymasters; 10.0.0.1 key foo; 1::2 port 69; }" - */ - -static cfg_tuplefielddef_t namesockaddrkey_fields[] = { - { "masterselement", &cfg_type_masterselement, 0 }, - { "key", &cfg_type_optional_keyref, 0 }, - { NULL, NULL, 0 }, -}; - -static cfg_type_t cfg_type_namesockaddrkey = { - "namesockaddrkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - namesockaddrkey_fields -}; - -static cfg_type_t cfg_type_bracketed_namesockaddrkeylist = { - "bracketed_namesockaddrkeylist", cfg_parse_bracketed_list, - cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_namesockaddrkey -}; - -static cfg_tuplefielddef_t namesockaddrkeylist_fields[] = { - { "port", &cfg_type_optional_port, 0 }, - { "addresses", &cfg_type_bracketed_namesockaddrkeylist, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_namesockaddrkeylist = { - "sockaddrkeylist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - namesockaddrkeylist_fields -}; - -/*% - * A list of socket addresses with an optional default port, - * as used in the also-notify option. E.g., - * "port 1234 { 10.0.0.1; 1::2 port 69; }" - */ -static cfg_tuplefielddef_t portiplist_fields[] = { - { "port", &cfg_type_optional_port, 0 }, - { "addresses", &cfg_type_bracketed_sockaddrlist, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_portiplist = { - "portiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - portiplist_fields -}; - -/*% - * A public key, as in the "pubkey" statement. - */ -static cfg_tuplefielddef_t pubkey_fields[] = { - { "flags", &cfg_type_uint32, 0 }, - { "protocol", &cfg_type_uint32, 0 }, - { "algorithm", &cfg_type_uint32, 0 }, - { "key", &cfg_type_qstring, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_pubkey = { - "pubkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, pubkey_fields }; - -/*% - * A list of RR types, used in grant statements. - * Note that the old parser allows quotes around the RR type names. - */ -static cfg_type_t cfg_type_rrtypelist = { - "rrtypelist", cfg_parse_spacelist, cfg_print_spacelist, cfg_doc_terminal, - &cfg_rep_list, &cfg_type_astring -}; - -static const char *mode_enums[] = { "grant", "deny", NULL }; -static cfg_type_t cfg_type_mode = { - "mode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, - &mode_enums -}; - -static const char *matchtype_enums[] = { - "name", "subdomain", "wildcard", "self", "selfsub", "selfwild", NULL }; -static cfg_type_t cfg_type_matchtype = { - "matchtype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, - &matchtype_enums -}; - -/*% - * A grant statement, used in the update policy. - */ -static cfg_tuplefielddef_t grant_fields[] = { - { "mode", &cfg_type_mode, 0 }, - { "identity", &cfg_type_astring, 0 }, /* domain name */ - { "matchtype", &cfg_type_matchtype, 0 }, - { "name", &cfg_type_astring, 0 }, /* domain name */ - { "types", &cfg_type_rrtypelist, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_grant = { - "grant", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, grant_fields }; - -static cfg_type_t cfg_type_updatepolicy = { - "update_policy", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, - &cfg_rep_list, &cfg_type_grant -}; - -/*% - * A view statement. - */ -static cfg_tuplefielddef_t view_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "class", &cfg_type_optional_class, 0 }, - { "options", &cfg_type_viewopts, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_view = { - "view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, view_fields }; - -/*% - * A zone statement. - */ -static cfg_tuplefielddef_t zone_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "class", &cfg_type_optional_class, 0 }, - { "options", &cfg_type_zoneopts, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_zone = { - "zone", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, zone_fields }; - -/*% - * A "category" clause in the "logging" statement. - */ -static cfg_tuplefielddef_t category_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "destinations", &cfg_type_destinationlist,0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_category = { - "category", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, category_fields }; - - -/*% - * A trusted key, as used in the "trusted-keys" statement. - */ -static cfg_tuplefielddef_t trustedkey_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "flags", &cfg_type_uint32, 0 }, - { "protocol", &cfg_type_uint32, 0 }, - { "algorithm", &cfg_type_uint32, 0 }, - { "key", &cfg_type_qstring, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_trustedkey = { - "trustedkey", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - trustedkey_fields -}; - -static keyword_type_t wild_class_kw = { "class", &cfg_type_ustring }; - -static cfg_type_t cfg_type_optional_wild_class = { - "optional_wild_class", parse_optional_keyvalue, print_keyvalue, - doc_optional_keyvalue, &cfg_rep_string, &wild_class_kw -}; - -static keyword_type_t wild_type_kw = { "type", &cfg_type_ustring }; - -static cfg_type_t cfg_type_optional_wild_type = { - "optional_wild_type", parse_optional_keyvalue, - print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &wild_type_kw -}; - -static keyword_type_t wild_name_kw = { "name", &cfg_type_qstring }; - -static cfg_type_t cfg_type_optional_wild_name = { - "optional_wild_name", parse_optional_keyvalue, - print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &wild_name_kw -}; - -/*% - * An rrset ordering element. - */ -static cfg_tuplefielddef_t rrsetorderingelement_fields[] = { - { "class", &cfg_type_optional_wild_class, 0 }, - { "type", &cfg_type_optional_wild_type, 0 }, - { "name", &cfg_type_optional_wild_name, 0 }, - { "order", &cfg_type_ustring, 0 }, /* must be literal "order" */ - { "ordering", &cfg_type_ustring, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_rrsetorderingelement = { - "rrsetorderingelement", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - rrsetorderingelement_fields -}; - -/*% - * A global or view "check-names" option. Note that the zone - * "check-names" option has a different syntax. - */ - -static const char *checktype_enums[] = { "master", "slave", "response", NULL }; -static cfg_type_t cfg_type_checktype = { - "checktype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, - &cfg_rep_string, &checktype_enums -}; - -static const char *checkmode_enums[] = { "fail", "warn", "ignore", NULL }; -static cfg_type_t cfg_type_checkmode = { - "checkmode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, - &cfg_rep_string, &checkmode_enums -}; - -static cfg_tuplefielddef_t checknames_fields[] = { - { "type", &cfg_type_checktype, 0 }, - { "mode", &cfg_type_checkmode, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_checknames = { - "checknames", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - checknames_fields -}; - -static cfg_type_t cfg_type_bracketed_sockaddrlist = { - "bracketed_sockaddrlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, - &cfg_rep_list, &cfg_type_sockaddr -}; - -static cfg_type_t cfg_type_rrsetorder = { - "rrsetorder", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, - &cfg_rep_list, &cfg_type_rrsetorderingelement -}; - -static keyword_type_t port_kw = { "port", &cfg_type_uint32 }; - -static cfg_type_t cfg_type_optional_port = { - "optional_port", parse_optional_keyvalue, print_keyvalue, - doc_optional_keyvalue, &cfg_rep_uint32, &port_kw -}; - -/*% A list of keys, as in the "key" clause of the controls statement. */ -static cfg_type_t cfg_type_keylist = { - "keylist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, - &cfg_type_astring -}; - -static cfg_type_t cfg_type_trustedkeys = { - "trusted-keys", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, - &cfg_type_trustedkey -}; - -static const char *forwardtype_enums[] = { "first", "only", NULL }; -static cfg_type_t cfg_type_forwardtype = { - "forwardtype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, - &forwardtype_enums -}; - -static const char *zonetype_enums[] = { - "master", "slave", "stub", "hint", "forward", "delegation-only", NULL }; -static cfg_type_t cfg_type_zonetype = { - "zonetype", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, - &cfg_rep_string, &zonetype_enums -}; - -static const char *loglevel_enums[] = { - "critical", "error", "warning", "notice", "info", "dynamic", NULL }; -static cfg_type_t cfg_type_loglevel = { - "loglevel", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, - &loglevel_enums -}; - -static const char *transferformat_enums[] = { - "many-answers", "one-answer", NULL }; -static cfg_type_t cfg_type_transferformat = { - "transferformat", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, &cfg_rep_string, - &transferformat_enums -}; - -/*% - * The special keyword "none", as used in the pid-file option. - */ - -static void -print_none(cfg_printer_t *pctx, const cfg_obj_t *obj) { - UNUSED(obj); - cfg_print_chars(pctx, "none", 4); -} - -static cfg_type_t cfg_type_none = { - "none", NULL, print_none, NULL, &cfg_rep_void, NULL -}; - -/*% - * A quoted string or the special keyword "none". Used in the pid-file option. - */ -static isc_result_t -parse_qstringornone(cfg_parser_t *pctx, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); - if (pctx->token.type == isc_tokentype_string && - strcasecmp(TOKEN_STRING(pctx), "none") == 0) - return (cfg_create_obj(pctx, &cfg_type_none, ret)); - cfg_ungettoken(pctx); - return (cfg_parse_qstring(pctx, type, ret)); - cleanup: - return (result); -} - -static void -doc_qstringornone(cfg_printer_t *pctx, const cfg_type_t *type) { - UNUSED(type); - cfg_print_chars(pctx, "( <quoted_string> | none )", 26); -} - -static cfg_type_t cfg_type_qstringornone = { - "qstringornone", parse_qstringornone, NULL, doc_qstringornone, NULL, NULL }; - -/*% - * keyword hostname - */ - -static void -print_hostname(cfg_printer_t *pctx, const cfg_obj_t *obj) { - UNUSED(obj); - cfg_print_chars(pctx, "hostname", 4); -} - -static cfg_type_t cfg_type_hostname = { - "hostname", NULL, print_hostname, NULL, &cfg_rep_boolean, NULL -}; - -/*% - * "server-id" argument. - */ - -static isc_result_t -parse_serverid(cfg_parser_t *pctx, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); - if (pctx->token.type == isc_tokentype_string && - strcasecmp(TOKEN_STRING(pctx), "none") == 0) - return (cfg_create_obj(pctx, &cfg_type_none, ret)); - if (pctx->token.type == isc_tokentype_string && - strcasecmp(TOKEN_STRING(pctx), "hostname") == 0) { - return (cfg_create_obj(pctx, &cfg_type_hostname, ret)); - } - cfg_ungettoken(pctx); - return (cfg_parse_qstring(pctx, type, ret)); - cleanup: - return (result); -} - -static void -doc_serverid(cfg_printer_t *pctx, const cfg_type_t *type) { - UNUSED(type); - cfg_print_chars(pctx, "( <quoted_string> | none | hostname )", 26); -} - -static cfg_type_t cfg_type_serverid = { - "serverid", parse_serverid, NULL, doc_serverid, NULL, NULL }; - -/*% - * Port list. - */ -static isc_result_t -parse_port(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - - UNUSED(type); - - CHECK(cfg_parse_uint32(pctx, NULL, ret)); - if ((*ret)->value.uint32 > 0xffff) { - cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid port"); - cfg_obj_destroy(pctx, ret); - result = ISC_R_RANGE; - } - cleanup: - return (result); -} - -static cfg_type_t cfg_type_port = { - "port", parse_port, NULL, cfg_doc_terminal, - NULL, NULL -}; - -static cfg_type_t cfg_type_bracketed_portlist = { - "bracketed_sockaddrlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, - &cfg_rep_list, &cfg_type_port -}; - -/*% - * Clauses that can be found within the top level of the named.conf - * file only. - */ -static cfg_clausedef_t -namedconf_clauses[] = { - { "options", &cfg_type_options, 0 }, - { "controls", &cfg_type_controls, CFG_CLAUSEFLAG_MULTI }, - { "acl", &cfg_type_acl, CFG_CLAUSEFLAG_MULTI }, - { "masters", &cfg_type_masters, CFG_CLAUSEFLAG_MULTI }, - { "logging", &cfg_type_logging, 0 }, - { "view", &cfg_type_view, CFG_CLAUSEFLAG_MULTI }, - { "lwres", &cfg_type_lwres, CFG_CLAUSEFLAG_MULTI }, - { NULL, NULL, 0 } -}; - -/*% - * Clauses that can occur at the top level or in the view - * statement, but not in the options block. - */ -static cfg_clausedef_t -namedconf_or_view_clauses[] = { - { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI }, - { "zone", &cfg_type_zone, CFG_CLAUSEFLAG_MULTI }, - /* only 1 DLZ per view allowed */ - { "dlz", &cfg_type_dynamically_loadable_zones, 0 }, - { "server", &cfg_type_server, CFG_CLAUSEFLAG_MULTI }, - { "trusted-keys", &cfg_type_trustedkeys, CFG_CLAUSEFLAG_MULTI }, - { NULL, NULL, 0 } -}; - -/*% - * Clauses that can be found within the 'options' statement. - */ -static cfg_clausedef_t -options_clauses[] = { - { "avoid-v4-udp-ports", &cfg_type_bracketed_portlist, 0 }, - { "avoid-v6-udp-ports", &cfg_type_bracketed_portlist, 0 }, - { "blackhole", &cfg_type_bracketed_aml, 0 }, - { "coresize", &cfg_type_size, 0 }, - { "datasize", &cfg_type_size, 0 }, - { "deallocate-on-exit", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK }, - { "dump-file", &cfg_type_qstring, 0 }, - { "fake-iquery", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "files", &cfg_type_size, 0 }, - { "has-old-clients", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "heartbeat-interval", &cfg_type_uint32, 0 }, - { "host-statistics", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTIMP }, - { "host-statistics-max", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, - { "hostname", &cfg_type_qstringornone, 0 }, - { "interface-interval", &cfg_type_uint32, 0 }, - { "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, - { "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, - { "match-mapped-addresses", &cfg_type_boolean, 0 }, - { "memstatistics-file", &cfg_type_qstring, 0 }, - { "multiple-cnames", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "named-xfer", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE }, - { "pid-file", &cfg_type_qstringornone, 0 }, - { "port", &cfg_type_uint32, 0 }, - { "querylog", &cfg_type_boolean, 0 }, - { "recursing-file", &cfg_type_qstring, 0 }, - { "random-device", &cfg_type_qstring, 0 }, - { "recursive-clients", &cfg_type_uint32, 0 }, - { "serial-queries", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE }, - { "serial-query-rate", &cfg_type_uint32, 0 }, - { "server-id", &cfg_type_serverid, 0 }, - { "stacksize", &cfg_type_size, 0 }, - { "statistics-file", &cfg_type_qstring, 0 }, - { "statistics-interval", &cfg_type_uint32, CFG_CLAUSEFLAG_NYI }, - { "tcp-clients", &cfg_type_uint32, 0 }, - { "tcp-listen-queue", &cfg_type_uint32, 0 }, - { "tkey-dhkey", &cfg_type_tkey_dhkey, 0 }, - { "tkey-gssapi-credential", &cfg_type_qstring, 0 }, - { "tkey-domain", &cfg_type_qstring, 0 }, - { "transfers-per-ns", &cfg_type_uint32, 0 }, - { "transfers-in", &cfg_type_uint32, 0 }, - { "transfers-out", &cfg_type_uint32, 0 }, - { "treat-cr-as-space", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "use-id-pool", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "use-ixfr", &cfg_type_boolean, 0 }, - { "version", &cfg_type_qstringornone, 0 }, - { "flush-zones-on-shutdown", &cfg_type_boolean, 0 }, - { NULL, NULL, 0 } -}; - - -static cfg_type_t cfg_type_namelist = { - "namelist", cfg_parse_bracketed_list, cfg_print_bracketed_list, - cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_qstring }; - -static keyword_type_t exclude_kw = { "exclude", &cfg_type_namelist }; - -static cfg_type_t cfg_type_optional_exclude = { - "optional_exclude", parse_optional_keyvalue, print_keyvalue, - doc_optional_keyvalue, &cfg_rep_list, &exclude_kw }; - -static cfg_type_t cfg_type_algorithmlist = { - "algorithmlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, - cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring }; - -static cfg_tuplefielddef_t disablealgorithm_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "algorithms", &cfg_type_algorithmlist, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_disablealgorithm = { - "disablealgorithm", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, - &cfg_rep_tuple, disablealgorithm_fields -}; - -static cfg_tuplefielddef_t mustbesecure_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "value", &cfg_type_boolean, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_mustbesecure = { - "mustbesecure", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, - &cfg_rep_tuple, mustbesecure_fields -}; - -static const char *masterformat_enums[] = { "text", "raw", NULL }; -static cfg_type_t cfg_type_masterformat = { - "masterformat", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum, - &cfg_rep_string, &masterformat_enums -}; - -/*% - * dnssec-lookaside - */ - -static keyword_type_t trustanchor_kw = { "trust-anchor", &cfg_type_astring }; - -static cfg_type_t cfg_type_trustanchor = { - "trust-anchor", parse_keyvalue, print_keyvalue, doc_keyvalue, - &cfg_rep_string, &trustanchor_kw -}; - -static cfg_tuplefielddef_t lookaside_fields[] = { - { "domain", &cfg_type_astring, 0 }, - { "trust-anchor", &cfg_type_trustanchor, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_lookaside = { - "lookaside", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, - &cfg_rep_tuple, lookaside_fields -}; - -/*% - * Clauses that can be found within the 'view' statement, - * with defaults in the 'options' statement. - */ - -static cfg_clausedef_t -view_clauses[] = { - { "allow-query-cache", &cfg_type_bracketed_aml, 0 }, - { "allow-recursion", &cfg_type_bracketed_aml, 0 }, - { "allow-v6-synthesis", &cfg_type_bracketed_aml, - CFG_CLAUSEFLAG_OBSOLETE }, - { "sortlist", &cfg_type_bracketed_aml, 0 }, - { "topology", &cfg_type_bracketed_aml, CFG_CLAUSEFLAG_NOTIMP }, - { "auth-nxdomain", &cfg_type_boolean, CFG_CLAUSEFLAG_NEWDEFAULT }, - { "minimal-responses", &cfg_type_boolean, 0 }, - { "recursion", &cfg_type_boolean, 0 }, - { "rrset-order", &cfg_type_rrsetorder, 0 }, - { "provide-ixfr", &cfg_type_boolean, 0 }, - { "request-ixfr", &cfg_type_boolean, 0 }, - { "fetch-glue", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "rfc2308-type1", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI }, - { "additional-from-auth", &cfg_type_boolean, 0 }, - { "additional-from-cache", &cfg_type_boolean, 0 }, - /* - * Note that the query-source option syntax is different - * from the other -source options. - */ - { "query-source", &cfg_type_querysource4, 0 }, - { "query-source-v6", &cfg_type_querysource6, 0 }, - { "cleaning-interval", &cfg_type_uint32, 0 }, - { "min-roots", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTIMP }, - { "lame-ttl", &cfg_type_uint32, 0 }, - { "max-ncache-ttl", &cfg_type_uint32, 0 }, - { "max-cache-ttl", &cfg_type_uint32, 0 }, - { "transfer-format", &cfg_type_transferformat, 0 }, - { "max-cache-size", &cfg_type_sizenodefault, 0 }, - { "check-names", &cfg_type_checknames, CFG_CLAUSEFLAG_MULTI }, - { "cache-file", &cfg_type_qstring, 0 }, - { "suppress-initial-notify", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI }, - { "preferred-glue", &cfg_type_astring, 0 }, - { "dual-stack-servers", &cfg_type_nameportiplist, 0 }, - { "edns-udp-size", &cfg_type_uint32, 0 }, - { "max-udp-size", &cfg_type_uint32, 0 }, - { "root-delegation-only", &cfg_type_optional_exclude, 0 }, - { "disable-algorithms", &cfg_type_disablealgorithm, - CFG_CLAUSEFLAG_MULTI }, - { "dnssec-enable", &cfg_type_boolean, 0 }, - { "dnssec-validation", &cfg_type_boolean, 0 }, - { "dnssec-lookaside", &cfg_type_lookaside, CFG_CLAUSEFLAG_MULTI }, - { "dnssec-must-be-secure", &cfg_type_mustbesecure, - CFG_CLAUSEFLAG_MULTI }, - { "dnssec-accept-expired", &cfg_type_boolean, 0 }, - { "ixfr-from-differences", &cfg_type_ixfrdifftype, 0 }, - { "acache-enable", &cfg_type_boolean, 0 }, - { "acache-cleaning-interval", &cfg_type_uint32, 0 }, - { "max-acache-size", &cfg_type_sizenodefault, 0 }, - { "clients-per-query", &cfg_type_uint32, 0 }, - { "max-clients-per-query", &cfg_type_uint32, 0 }, - { "empty-server", &cfg_type_astring, 0 }, - { "empty-contact", &cfg_type_astring, 0 }, - { "empty-zones-enable", &cfg_type_boolean, 0 }, - { "disable-empty-zone", &cfg_type_astring, CFG_CLAUSEFLAG_MULTI }, - { "zero-no-soa-ttl-cache", &cfg_type_boolean, 0 }, - { NULL, NULL, 0 } -}; - -/*% - * Clauses that can be found within the 'view' statement only. - */ -static cfg_clausedef_t -view_only_clauses[] = { - { "match-clients", &cfg_type_bracketed_aml, 0 }, - { "match-destinations", &cfg_type_bracketed_aml, 0 }, - { "match-recursive-only", &cfg_type_boolean, 0 }, - { NULL, NULL, 0 } -}; - -/*% - * Clauses that can be found in a 'zone' statement, - * with defaults in the 'view' or 'options' statement. - */ -static cfg_clausedef_t -zone_clauses[] = { - { "allow-query", &cfg_type_bracketed_aml, 0 }, - { "allow-transfer", &cfg_type_bracketed_aml, 0 }, - { "allow-update", &cfg_type_bracketed_aml, 0 }, - { "allow-update-forwarding", &cfg_type_bracketed_aml, 0 }, - { "allow-notify", &cfg_type_bracketed_aml, 0 }, - { "masterfile-format", &cfg_type_masterformat, 0 }, - { "notify", &cfg_type_notifytype, 0 }, - { "notify-source", &cfg_type_sockaddr4wild, 0 }, - { "notify-source-v6", &cfg_type_sockaddr6wild, 0 }, - { "also-notify", &cfg_type_portiplist, 0 }, - { "notify-delay", &cfg_type_uint32, 0 }, - { "dialup", &cfg_type_dialuptype, 0 }, - { "forward", &cfg_type_forwardtype, 0 }, - { "forwarders", &cfg_type_portiplist, 0 }, - { "maintain-ixfr-base", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "max-ixfr-log-size", &cfg_type_size, CFG_CLAUSEFLAG_OBSOLETE }, - { "max-journal-size", &cfg_type_sizenodefault, 0 }, - { "max-transfer-time-in", &cfg_type_uint32, 0 }, - { "max-transfer-time-out", &cfg_type_uint32, 0 }, - { "max-transfer-idle-in", &cfg_type_uint32, 0 }, - { "max-transfer-idle-out", &cfg_type_uint32, 0 }, - { "max-retry-time", &cfg_type_uint32, 0 }, - { "min-retry-time", &cfg_type_uint32, 0 }, - { "max-refresh-time", &cfg_type_uint32, 0 }, - { "min-refresh-time", &cfg_type_uint32, 0 }, - { "multi-master", &cfg_type_boolean, 0 }, - { "sig-validity-interval", &cfg_type_uint32, 0 }, - { "transfer-source", &cfg_type_sockaddr4wild, 0 }, - { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, - { "alt-transfer-source", &cfg_type_sockaddr4wild, 0 }, - { "alt-transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, - { "use-alt-transfer-source", &cfg_type_boolean, 0 }, - { "zone-statistics", &cfg_type_boolean, 0 }, - { "key-directory", &cfg_type_qstring, 0 }, - { "check-wildcard", &cfg_type_boolean, 0 }, - { "check-integrity", &cfg_type_boolean, 0 }, - { "check-mx", &cfg_type_checkmode, 0 }, - { "check-mx-cname", &cfg_type_checkmode, 0 }, - { "check-srv-cname", &cfg_type_checkmode, 0 }, - { "check-sibling", &cfg_type_boolean, 0 }, - { "zero-no-soa-ttl", &cfg_type_boolean, 0 }, - { "update-check-ksk", &cfg_type_boolean, 0 }, - { NULL, NULL, 0 } -}; - -/*% - * Clauses that can be found in a 'zone' statement - * only. - */ -static cfg_clausedef_t -zone_only_clauses[] = { - { "type", &cfg_type_zonetype, 0 }, - { "file", &cfg_type_qstring, 0 }, - { "journal", &cfg_type_qstring, 0 }, - { "ixfr-base", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE }, - { "ixfr-tmp-file", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE }, - { "masters", &cfg_type_namesockaddrkeylist, 0 }, - { "pubkey", &cfg_type_pubkey, - CFG_CLAUSEFLAG_MULTI | CFG_CLAUSEFLAG_OBSOLETE }, - { "update-policy", &cfg_type_updatepolicy, 0 }, - { "database", &cfg_type_astring, 0 }, - { "delegation-only", &cfg_type_boolean, 0 }, - /* - * Note that the format of the check-names option is different between - * the zone options and the global/view options. Ugh. - */ - { "check-names", &cfg_type_checkmode, 0 }, - { "ixfr-from-differences", &cfg_type_boolean, 0 }, - { NULL, NULL, 0 } -}; - - -/*% The top-level named.conf syntax. */ - -static cfg_clausedef_t * -namedconf_clausesets[] = { - namedconf_clauses, - namedconf_or_view_clauses, - NULL -}; - -LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_namedconf = { - "namedconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, - &cfg_rep_map, namedconf_clausesets -}; - -/*% The "options" statement syntax. */ - -static cfg_clausedef_t * -options_clausesets[] = { - options_clauses, - view_clauses, - zone_clauses, - NULL -}; -static cfg_type_t cfg_type_options = { - "options", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, options_clausesets }; - -/*% The "view" statement syntax. */ - -static cfg_clausedef_t * -view_clausesets[] = { - view_only_clauses, - namedconf_or_view_clauses, - view_clauses, - zone_clauses, - dynamically_loadable_zones_clauses, - NULL -}; -static cfg_type_t cfg_type_viewopts = { - "view", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, view_clausesets }; - -/*% The "zone" statement syntax. */ - -static cfg_clausedef_t * -zone_clausesets[] = { - zone_only_clauses, - zone_clauses, - NULL -}; -static cfg_type_t cfg_type_zoneopts = { - "zoneopts", cfg_parse_map, cfg_print_map, - cfg_doc_map, &cfg_rep_map, zone_clausesets }; - -/*% The "dynamically loadable zones" statement syntax. */ - -static cfg_clausedef_t * -dynamically_loadable_zones_clausesets[] = { - dynamically_loadable_zones_clauses, - NULL -}; -static cfg_type_t cfg_type_dynamically_loadable_zones_opts = { - "dynamically_loadable_zones_opts", cfg_parse_map, - cfg_print_map, cfg_doc_map, &cfg_rep_map, - dynamically_loadable_zones_clausesets -}; - -/*% - * Clauses that can be found within the 'key' statement. - */ -static cfg_clausedef_t -key_clauses[] = { - { "algorithm", &cfg_type_astring, 0 }, - { "secret", &cfg_type_astring, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_clausedef_t * -key_clausesets[] = { - key_clauses, - NULL -}; -static cfg_type_t cfg_type_key = { - "key", cfg_parse_named_map, cfg_print_map, - cfg_doc_map, &cfg_rep_map, key_clausesets -}; - - -/*% - * Clauses that can be found in a 'server' statement. - */ -static cfg_clausedef_t -server_clauses[] = { - { "bogus", &cfg_type_boolean, 0 }, - { "provide-ixfr", &cfg_type_boolean, 0 }, - { "request-ixfr", &cfg_type_boolean, 0 }, - { "support-ixfr", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE }, - { "transfers", &cfg_type_uint32, 0 }, - { "transfer-format", &cfg_type_transferformat, 0 }, - { "keys", &cfg_type_server_key_kludge, 0 }, - { "edns", &cfg_type_boolean, 0 }, - { "edns-udp-size", &cfg_type_uint32, 0 }, - { "max-udp-size", &cfg_type_uint32, 0 }, - { "notify-source", &cfg_type_sockaddr4wild, 0 }, - { "notify-source-v6", &cfg_type_sockaddr6wild, 0 }, - { "query-source", &cfg_type_querysource4, 0 }, - { "query-source-v6", &cfg_type_querysource6, 0 }, - { "transfer-source", &cfg_type_sockaddr4wild, 0 }, - { "transfer-source-v6", &cfg_type_sockaddr6wild, 0 }, - { NULL, NULL, 0 } -}; -static cfg_clausedef_t * -server_clausesets[] = { - server_clauses, - NULL -}; -static cfg_type_t cfg_type_server = { - "server", cfg_parse_netprefix_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, - server_clausesets -}; - - -/*% - * Clauses that can be found in a 'channel' clause in the - * 'logging' statement. - * - * These have some additional constraints that need to be - * checked after parsing: - * - There must exactly one of file/syslog/null/stderr - * - */ -static cfg_clausedef_t -channel_clauses[] = { - /* Destinations. We no longer require these to be first. */ - { "file", &cfg_type_logfile, 0 }, - { "syslog", &cfg_type_optional_facility, 0 }, - { "null", &cfg_type_void, 0 }, - { "stderr", &cfg_type_void, 0 }, - /* Options. We now accept these for the null channel, too. */ - { "severity", &cfg_type_logseverity, 0 }, - { "print-time", &cfg_type_boolean, 0 }, - { "print-severity", &cfg_type_boolean, 0 }, - { "print-category", &cfg_type_boolean, 0 }, - { NULL, NULL, 0 } -}; -static cfg_clausedef_t * -channel_clausesets[] = { - channel_clauses, - NULL -}; -static cfg_type_t cfg_type_channel = { - "channel", cfg_parse_named_map, cfg_print_map, cfg_doc_map, - &cfg_rep_map, channel_clausesets -}; - -/*% A list of log destination, used in the "category" clause. */ -static cfg_type_t cfg_type_destinationlist = { - "destinationlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, - &cfg_rep_list, &cfg_type_astring }; - -/*% - * Clauses that can be found in a 'logging' statement. - */ -static cfg_clausedef_t -logging_clauses[] = { - { "channel", &cfg_type_channel, CFG_CLAUSEFLAG_MULTI }, - { "category", &cfg_type_category, CFG_CLAUSEFLAG_MULTI }, - { NULL, NULL, 0 } -}; -static cfg_clausedef_t * -logging_clausesets[] = { - logging_clauses, - NULL -}; -static cfg_type_t cfg_type_logging = { - "logging", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, logging_clausesets }; - - -static isc_result_t -parse_unitstring(char *str, isc_resourcevalue_t *valuep) { - char *endp; - unsigned int len; - isc_uint64_t value; - isc_uint64_t unit; - - value = isc_string_touint64(str, &endp, 10); - if (*endp == 0) { - *valuep = value; - return (ISC_R_SUCCESS); - } - - len = strlen(str); - if (len < 2 || endp[1] != '\0') - return (ISC_R_FAILURE); - - switch (str[len - 1]) { - case 'k': - case 'K': - unit = 1024; - break; - case 'm': - case 'M': - unit = 1024 * 1024; - break; - case 'g': - case 'G': - unit = 1024 * 1024 * 1024; - break; - default: - return (ISC_R_FAILURE); - } - if (value > ISC_UINT64_MAX / unit) - return (ISC_R_FAILURE); - *valuep = value * unit; - return (ISC_R_SUCCESS); -} - -static isc_result_t -parse_sizeval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *obj = NULL; - isc_uint64_t val; - - UNUSED(type); - - CHECK(cfg_gettoken(pctx, 0)); - if (pctx->token.type != isc_tokentype_string) { - result = ISC_R_UNEXPECTEDTOKEN; - goto cleanup; - } - CHECK(parse_unitstring(TOKEN_STRING(pctx), &val)); - - CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj)); - obj->value.uint64 = val; - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer and optional unit"); - return (result); -} - -/*% - * A size value (number + optional unit). - */ -static cfg_type_t cfg_type_sizeval = { - "sizeval", parse_sizeval, cfg_print_uint64, cfg_doc_terminal, - &cfg_rep_uint64, NULL }; - -/*% - * A size, "unlimited", or "default". - */ - -static isc_result_t -parse_size(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_enum_or_other(pctx, type, &cfg_type_sizeval, ret)); -} - -static const char *size_enums[] = { "unlimited", "default", NULL }; -static cfg_type_t cfg_type_size = { - "size", parse_size, cfg_print_ustring, cfg_doc_terminal, - &cfg_rep_string, size_enums -}; - -/*% - * A size or "unlimited", but not "default". - */ -static const char *sizenodefault_enums[] = { "unlimited", NULL }; -static cfg_type_t cfg_type_sizenodefault = { - "size_no_default", parse_size, cfg_print_ustring, cfg_doc_terminal, - &cfg_rep_string, sizenodefault_enums -}; - -/*% - * optional_keyvalue - */ -static isc_result_t -parse_maybe_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, - isc_boolean_t optional, cfg_obj_t **ret) -{ - isc_result_t result; - cfg_obj_t *obj = NULL; - const keyword_type_t *kw = type->of; - - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_string && - strcasecmp(TOKEN_STRING(pctx), kw->name) == 0) { - CHECK(cfg_gettoken(pctx, 0)); - CHECK(kw->type->parse(pctx, kw->type, &obj)); - obj->type = type; /* XXX kludge */ - } else { - if (optional) { - CHECK(cfg_parse_void(pctx, NULL, &obj)); - } else { - cfg_parser_error(pctx, CFG_LOG_NEAR, "expected '%s'", - kw->name); - result = ISC_R_UNEXPECTEDTOKEN; - goto cleanup; - } - } - *ret = obj; - cleanup: - return (result); -} - -static isc_result_t -parse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype, - const cfg_type_t *othertype, cfg_obj_t **ret) -{ - isc_result_t result; - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_string && - cfg_is_enum(TOKEN_STRING(pctx), enumtype->of)) { - CHECK(cfg_parse_enum(pctx, enumtype, ret)); - } else { - CHECK(cfg_parse_obj(pctx, othertype, ret)); - } - cleanup: - return (result); -} - -static void -doc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *type) { - cfg_doc_terminal(pctx, type); -#if 0 /* XXX */ - cfg_print_chars(pctx, "( ", 2);... -#endif - -} - -static isc_result_t -parse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_maybe_optional_keyvalue(pctx, type, ISC_FALSE, ret)); -} - -static isc_result_t -parse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_maybe_optional_keyvalue(pctx, type, ISC_TRUE, ret)); -} - -static void -print_keyvalue(cfg_printer_t *pctx, const cfg_obj_t *obj) { - const keyword_type_t *kw = obj->type->of; - cfg_print_cstr(pctx, kw->name); - cfg_print_chars(pctx, " ", 1); - kw->type->print(pctx, obj); -} - -static void -doc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) { - const keyword_type_t *kw = type->of; - cfg_print_cstr(pctx, kw->name); - cfg_print_chars(pctx, " ", 1); - cfg_doc_obj(pctx, kw->type); -} - -static void -doc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) { - const keyword_type_t *kw = type->of; - cfg_print_chars(pctx, "[ ", 2); - cfg_print_cstr(pctx, kw->name); - cfg_print_chars(pctx, " ", 1); - cfg_doc_obj(pctx, kw->type); - cfg_print_chars(pctx, " ]", 2); -} - -static const char *dialup_enums[] = { - "notify", "notify-passive", "refresh", "passive", NULL }; -static isc_result_t -parse_dialup_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); -} -static cfg_type_t cfg_type_dialuptype = { - "dialuptype", parse_dialup_type, cfg_print_ustring, doc_enum_or_other, - &cfg_rep_string, dialup_enums -}; - -static const char *notify_enums[] = { "explicit", "master-only", NULL }; -static isc_result_t -parse_notify_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); -} -static cfg_type_t cfg_type_notifytype = { - "notifytype", parse_notify_type, cfg_print_ustring, doc_enum_or_other, - &cfg_rep_string, notify_enums, -}; - -static const char *ixfrdiff_enums[] = { "master", "slave", NULL }; -static isc_result_t -parse_ixfrdiff_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret)); -} -static cfg_type_t cfg_type_ixfrdifftype = { - "ixfrdiff", parse_ixfrdiff_type, cfg_print_ustring, doc_enum_or_other, - &cfg_rep_string, ixfrdiff_enums, -}; - -static keyword_type_t key_kw = { "key", &cfg_type_astring }; - -LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_keyref = { - "keyref", parse_keyvalue, print_keyvalue, doc_keyvalue, - &cfg_rep_string, &key_kw -}; - -static cfg_type_t cfg_type_optional_keyref = { - "optional_keyref", parse_optional_keyvalue, print_keyvalue, - doc_optional_keyvalue, &cfg_rep_string, &key_kw -}; - -/*% - * A "controls" statement is represented as a map with the multivalued - * "inet" and "unix" clauses. - */ - -static keyword_type_t controls_allow_kw = { - "allow", &cfg_type_bracketed_aml }; - -static cfg_type_t cfg_type_controls_allow = { - "controls_allow", parse_keyvalue, - print_keyvalue, doc_keyvalue, - &cfg_rep_list, &controls_allow_kw -}; - -static keyword_type_t controls_keys_kw = { - "keys", &cfg_type_keylist }; - -static cfg_type_t cfg_type_controls_keys = { - "controls_keys", parse_optional_keyvalue, - print_keyvalue, doc_optional_keyvalue, - &cfg_rep_list, &controls_keys_kw -}; - -static cfg_tuplefielddef_t inetcontrol_fields[] = { - { "address", &cfg_type_controls_sockaddr, 0 }, - { "allow", &cfg_type_controls_allow, 0 }, - { "keys", &cfg_type_controls_keys, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_inetcontrol = { - "inetcontrol", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - inetcontrol_fields -}; - -static keyword_type_t controls_perm_kw = { - "perm", &cfg_type_uint32 }; - -static cfg_type_t cfg_type_controls_perm = { - "controls_perm", parse_keyvalue, - print_keyvalue, doc_keyvalue, - &cfg_rep_uint32, &controls_perm_kw -}; - -static keyword_type_t controls_owner_kw = { - "owner", &cfg_type_uint32 }; - -static cfg_type_t cfg_type_controls_owner = { - "controls_owner", parse_keyvalue, - print_keyvalue, doc_keyvalue, - &cfg_rep_uint32, &controls_owner_kw -}; - -static keyword_type_t controls_group_kw = { - "group", &cfg_type_uint32 }; - -static cfg_type_t cfg_type_controls_group = { - "controls_allow", parse_keyvalue, - print_keyvalue, doc_keyvalue, - &cfg_rep_uint32, &controls_group_kw -}; - -static cfg_tuplefielddef_t unixcontrol_fields[] = { - { "path", &cfg_type_qstring, 0 }, - { "perm", &cfg_type_controls_perm, 0 }, - { "owner", &cfg_type_controls_owner, 0 }, - { "group", &cfg_type_controls_group, 0 }, - { "keys", &cfg_type_controls_keys, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_unixcontrol = { - "unixcontrol", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - unixcontrol_fields -}; - -static cfg_clausedef_t -controls_clauses[] = { - { "inet", &cfg_type_inetcontrol, CFG_CLAUSEFLAG_MULTI }, - { "unix", &cfg_type_unixcontrol, CFG_CLAUSEFLAG_MULTI }, - { NULL, NULL, 0 } -}; - -static cfg_clausedef_t * -controls_clausesets[] = { - controls_clauses, - NULL -}; -static cfg_type_t cfg_type_controls = { - "controls", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, &controls_clausesets -}; - -/*% - * An optional class, as used in view and zone statements. - */ -static isc_result_t -parse_optional_class(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - UNUSED(type); - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_string) - CHECK(cfg_parse_obj(pctx, &cfg_type_ustring, ret)); - else - CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret)); - cleanup: - return (result); -} - -static cfg_type_t cfg_type_optional_class = { - "optional_class", parse_optional_class, NULL, cfg_doc_terminal, - NULL, NULL -}; - -static isc_result_t -parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *obj = NULL; - isc_netaddr_t netaddr; - in_port_t port; - unsigned int have_address = 0; - unsigned int have_port = 0; - const unsigned int *flagp = type->of; - - if ((*flagp & CFG_ADDR_V4OK) != 0) - isc_netaddr_any(&netaddr); - else if ((*flagp & CFG_ADDR_V6OK) != 0) - isc_netaddr_any6(&netaddr); - else - INSIST(0); - - port = 0; - - for (;;) { - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_string) { - if (strcasecmp(TOKEN_STRING(pctx), - "address") == 0) - { - /* read "address" */ - CHECK(cfg_gettoken(pctx, 0)); - CHECK(cfg_parse_rawaddr(pctx, *flagp, - &netaddr)); - have_address++; - } else if (strcasecmp(TOKEN_STRING(pctx), "port") == 0) - { - /* read "port" */ - CHECK(cfg_gettoken(pctx, 0)); - CHECK(cfg_parse_rawport(pctx, - CFG_ADDR_WILDOK, - &port)); - have_port++; - } else if (have_port == 0 && have_address == 0) { - return (cfg_parse_sockaddr(pctx, type, ret)); - } else { - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected 'address' or 'port'"); - return (ISC_R_UNEXPECTEDTOKEN); - } - } else - break; - } - if (have_address > 1 || have_port > 1 || - have_address + have_port == 0) { - cfg_parser_error(pctx, 0, "expected one address and/or port"); - return (ISC_R_UNEXPECTEDTOKEN); - } - - CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj)); - isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port); - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid query source"); - CLEANUP_OBJ(obj); - return (result); -} - -static void -print_querysource(cfg_printer_t *pctx, const cfg_obj_t *obj) { - isc_netaddr_t na; - isc_netaddr_fromsockaddr(&na, &obj->value.sockaddr); - cfg_print_chars(pctx, "address ", 8); - cfg_print_rawaddr(pctx, &na); - cfg_print_chars(pctx, " port ", 6); - cfg_print_rawuint(pctx, isc_sockaddr_getport(&obj->value.sockaddr)); -} - -static unsigned int sockaddr4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK; -static unsigned int sockaddr6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK; -static cfg_type_t cfg_type_querysource4 = { - "querysource4", parse_querysource, NULL, cfg_doc_terminal, - NULL, &sockaddr4wild_flags -}; - -static cfg_type_t cfg_type_querysource6 = { - "querysource6", parse_querysource, NULL, cfg_doc_terminal, - NULL, &sockaddr6wild_flags -}; - -static cfg_type_t cfg_type_querysource = { - "querysource", NULL, print_querysource, NULL, &cfg_rep_sockaddr, NULL -}; - -/*% addrmatchelt */ - -static isc_result_t -parse_addrmatchelt(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - UNUSED(type); - - CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); - - if (pctx->token.type == isc_tokentype_string || - pctx->token.type == isc_tokentype_qstring) { - if (pctx->token.type == isc_tokentype_string && - (strcasecmp(TOKEN_STRING(pctx), "key") == 0)) { - CHECK(cfg_parse_obj(pctx, &cfg_type_keyref, ret)); - } else { - if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | - CFG_ADDR_V4PREFIXOK | - CFG_ADDR_V6OK)) - { - CHECK(cfg_parse_netprefix(pctx, NULL, ret)); - } else { - CHECK(cfg_parse_astring(pctx, NULL, ret)); - } - } - } else if (pctx->token.type == isc_tokentype_special) { - if (pctx->token.value.as_char == '{') { - /* Nested match list. */ - CHECK(cfg_parse_obj(pctx, &cfg_type_bracketed_aml, ret)); - } else if (pctx->token.value.as_char == '!') { - CHECK(cfg_gettoken(pctx, 0)); /* read "!" */ - CHECK(cfg_parse_obj(pctx, &cfg_type_negated, ret)); - } else { - goto bad; - } - } else { - bad: - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected IP match list element"); - return (ISC_R_UNEXPECTEDTOKEN); - } - cleanup: - return (result); -} - -/*% - * A negated address match list element (like "! 10.0.0.1"). - * Somewhat sneakily, the caller is expected to parse the - * "!", but not to print it. - */ - -static cfg_tuplefielddef_t negated_fields[] = { - { "value", &cfg_type_addrmatchelt, 0 }, - { NULL, NULL, 0 } -}; - -static void -print_negated(cfg_printer_t *pctx, const cfg_obj_t *obj) { - cfg_print_chars(pctx, "!", 1); - cfg_print_tuple(pctx, obj); -} - -static cfg_type_t cfg_type_negated = { - "negated", cfg_parse_tuple, print_negated, NULL, &cfg_rep_tuple, - &negated_fields -}; - -/*% An address match list element */ - -static cfg_type_t cfg_type_addrmatchelt = { - "address_match_element", parse_addrmatchelt, NULL, cfg_doc_terminal, - NULL, NULL -}; - -/*% A bracketed address match list */ - -static cfg_type_t cfg_type_bracketed_aml = { - "bracketed_aml", cfg_parse_bracketed_list, cfg_print_bracketed_list, - cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_addrmatchelt -}; - -/*% - * The socket address syntax in the "controls" statement is silly. - * It allows both socket address families, but also allows "*", - * whis is gratuitously interpreted as the IPv4 wildcard address. - */ -static unsigned int controls_sockaddr_flags = - CFG_ADDR_V4OK | CFG_ADDR_V6OK | CFG_ADDR_WILDOK; -static cfg_type_t cfg_type_controls_sockaddr = { - "controls_sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr, - cfg_doc_sockaddr, &cfg_rep_sockaddr, &controls_sockaddr_flags -}; - -/*% - * Handle the special kludge syntax of the "keys" clause in the "server" - * statement, which takes a single key with or without braces and semicolon. - */ -static isc_result_t -parse_server_key_kludge(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) -{ - isc_result_t result; - isc_boolean_t braces = ISC_FALSE; - UNUSED(type); - - /* Allow opening brace. */ - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_special && - pctx->token.value.as_char == '{') { - result = cfg_gettoken(pctx, 0); - braces = ISC_TRUE; - } - - CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret)); - - if (braces) { - /* Skip semicolon if present. */ - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_special && - pctx->token.value.as_char == ';') - CHECK(cfg_gettoken(pctx, 0)); - - CHECK(cfg_parse_special(pctx, '}')); - } - cleanup: - return (result); -} -static cfg_type_t cfg_type_server_key_kludge = { - "server_key", parse_server_key_kludge, NULL, cfg_doc_terminal, - NULL, NULL -}; - - -/*% - * An optional logging facility. - */ - -static isc_result_t -parse_optional_facility(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) -{ - isc_result_t result; - UNUSED(type); - - CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); - if (pctx->token.type == isc_tokentype_string || - pctx->token.type == isc_tokentype_qstring) { - CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret)); - } else { - CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret)); - } - cleanup: - return (result); -} - -static cfg_type_t cfg_type_optional_facility = { - "optional_facility", parse_optional_facility, NULL, cfg_doc_terminal, - NULL, NULL }; - - -/*% - * A log severity. Return as a string, except "debug N", - * which is returned as a keyword object. - */ - -static keyword_type_t debug_kw = { "debug", &cfg_type_uint32 }; -static cfg_type_t cfg_type_debuglevel = { - "debuglevel", parse_keyvalue, - print_keyvalue, doc_keyvalue, - &cfg_rep_uint32, &debug_kw -}; - -static isc_result_t -parse_logseverity(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - UNUSED(type); - - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_string && - strcasecmp(TOKEN_STRING(pctx), "debug") == 0) { - CHECK(cfg_gettoken(pctx, 0)); /* read "debug" */ - CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER)); - if (pctx->token.type == isc_tokentype_number) { - CHECK(cfg_parse_uint32(pctx, NULL, ret)); - } else { - /* - * The debug level is optional and defaults to 1. - * This makes little sense, but we support it for - * compatibility with BIND 8. - */ - CHECK(cfg_create_obj(pctx, &cfg_type_uint32, ret)); - (*ret)->value.uint32 = 1; - } - (*ret)->type = &cfg_type_debuglevel; /* XXX kludge */ - } else { - CHECK(cfg_parse_obj(pctx, &cfg_type_loglevel, ret)); - } - cleanup: - return (result); -} - -static cfg_type_t cfg_type_logseverity = { - "log_severity", parse_logseverity, NULL, cfg_doc_terminal, - NULL, NULL }; - -/*% - * The "file" clause of the "channel" statement. - * This is yet another special case. - */ - -static const char *logversions_enums[] = { "unlimited", NULL }; -static isc_result_t -parse_logversions(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_enum_or_other(pctx, type, &cfg_type_uint32, ret)); -} -static cfg_type_t cfg_type_logversions = { - "logversions", parse_logversions, cfg_print_ustring, cfg_doc_terminal, - &cfg_rep_string, logversions_enums -}; - -static cfg_tuplefielddef_t logfile_fields[] = { - { "file", &cfg_type_qstring, 0 }, - { "versions", &cfg_type_logversions, 0 }, - { "size", &cfg_type_size, 0 }, - { NULL, NULL, 0 } -}; - -static isc_result_t -parse_logfile(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *obj = NULL; - const cfg_tuplefielddef_t *fields = type->of; - - CHECK(cfg_create_tuple(pctx, type, &obj)); - - /* Parse the mandatory "file" field */ - CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); - - /* Parse "versions" and "size" fields in any order. */ - for (;;) { - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_string) { - CHECK(cfg_gettoken(pctx, 0)); - if (strcasecmp(TOKEN_STRING(pctx), - "versions") == 0 && - obj->value.tuple[1] == NULL) { - CHECK(cfg_parse_obj(pctx, fields[1].type, - &obj->value.tuple[1])); - } else if (strcasecmp(TOKEN_STRING(pctx), - "size") == 0 && - obj->value.tuple[2] == NULL) { - CHECK(cfg_parse_obj(pctx, fields[2].type, - &obj->value.tuple[2])); - } else { - break; - } - } else { - break; - } - } - - /* Create void objects for missing optional values. */ - if (obj->value.tuple[1] == NULL) - CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1])); - if (obj->value.tuple[2] == NULL) - CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2])); - - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -static void -print_logfile(cfg_printer_t *pctx, const cfg_obj_t *obj) { - cfg_print_obj(pctx, obj->value.tuple[0]); /* file */ - if (obj->value.tuple[1]->type->print != cfg_print_void) { - cfg_print_chars(pctx, " versions ", 10); - cfg_print_obj(pctx, obj->value.tuple[1]); - } - if (obj->value.tuple[2]->type->print != cfg_print_void) { - cfg_print_chars(pctx, " size ", 6); - cfg_print_obj(pctx, obj->value.tuple[2]); - } -} - -static cfg_type_t cfg_type_logfile = { - "log_file", parse_logfile, print_logfile, cfg_doc_terminal, - &cfg_rep_tuple, logfile_fields -}; - -/*% An IPv4 address with optional port, "*" accepted as wildcard. */ -static cfg_type_t cfg_type_sockaddr4wild = { - "sockaddr4wild", cfg_parse_sockaddr, cfg_print_sockaddr, - cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr4wild_flags -}; - -/*% An IPv6 address with optional port, "*" accepted as wildcard. */ -static cfg_type_t cfg_type_sockaddr6wild = { - "v6addrportwild", cfg_parse_sockaddr, cfg_print_sockaddr, - cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr6wild_flags -}; - -/*% - * lwres - */ - -static cfg_tuplefielddef_t lwres_view_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "class", &cfg_type_optional_class, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_lwres_view = { - "lwres_view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, - lwres_view_fields -}; - -static cfg_type_t cfg_type_lwres_searchlist = { - "lwres_searchlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, - &cfg_rep_list, &cfg_type_astring }; - -static cfg_clausedef_t -lwres_clauses[] = { - { "listen-on", &cfg_type_portiplist, 0 }, - { "view", &cfg_type_lwres_view, 0 }, - { "search", &cfg_type_lwres_searchlist, 0 }, - { "ndots", &cfg_type_uint32, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_clausedef_t * -lwres_clausesets[] = { - lwres_clauses, - NULL -}; -static cfg_type_t cfg_type_lwres = { - "lwres", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, - lwres_clausesets -}; - -/*% - * rndc - */ - -static cfg_clausedef_t -rndcconf_options_clauses[] = { - { "default-key", &cfg_type_astring, 0 }, - { "default-port", &cfg_type_uint32, 0 }, - { "default-server", &cfg_type_astring, 0 }, - { "default-source-address", &cfg_type_netaddr4wild, 0 }, - { "default-source-address-v6", &cfg_type_netaddr6wild, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_clausedef_t * -rndcconf_options_clausesets[] = { - rndcconf_options_clauses, - NULL -}; - -static cfg_type_t cfg_type_rndcconf_options = { - "rndcconf_options", cfg_parse_map, cfg_print_map, cfg_doc_map, - &cfg_rep_map, rndcconf_options_clausesets -}; - -static cfg_clausedef_t -rndcconf_server_clauses[] = { - { "key", &cfg_type_astring, 0 }, - { "port", &cfg_type_uint32, 0 }, - { "source-address", &cfg_type_netaddr4wild, 0 }, - { "source-address-v6", &cfg_type_netaddr6wild, 0 }, - { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_clausedef_t * -rndcconf_server_clausesets[] = { - rndcconf_server_clauses, - NULL -}; - -static cfg_type_t cfg_type_rndcconf_server = { - "rndcconf_server", cfg_parse_named_map, cfg_print_map, cfg_doc_map, - &cfg_rep_map, rndcconf_server_clausesets -}; - -static cfg_clausedef_t -rndcconf_clauses[] = { - { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI }, - { "server", &cfg_type_rndcconf_server, CFG_CLAUSEFLAG_MULTI }, - { "options", &cfg_type_rndcconf_options, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_clausedef_t * -rndcconf_clausesets[] = { - rndcconf_clauses, - NULL -}; - -LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndcconf = { - "rndcconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, - &cfg_rep_map, rndcconf_clausesets -}; - -static cfg_clausedef_t -rndckey_clauses[] = { - { "key", &cfg_type_key, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_clausedef_t * -rndckey_clausesets[] = { - rndckey_clauses, - NULL -}; - -LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndckey = { - "rndckey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, - &cfg_rep_map, rndckey_clausesets -}; - -static cfg_tuplefielddef_t nameport_fields[] = { - { "name", &cfg_type_astring, 0 }, - { "port", &cfg_type_optional_port, 0 }, - { NULL, NULL, 0 } -}; -static cfg_type_t cfg_type_nameport = { - "nameport", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, - &cfg_rep_tuple, nameport_fields -}; - -static void -doc_sockaddrnameport(cfg_printer_t *pctx, const cfg_type_t *type) { - UNUSED(type); - cfg_print_chars(pctx, "( ", 2); - cfg_print_cstr(pctx, "<quoted_string>"); - cfg_print_chars(pctx, " ", 1); - cfg_print_cstr(pctx, "[port <integer>]"); - cfg_print_chars(pctx, " | ", 3); - cfg_print_cstr(pctx, "<ipv4_address>"); - cfg_print_chars(pctx, " ", 1); - cfg_print_cstr(pctx, "[port <integer>]"); - cfg_print_chars(pctx, " | ", 3); - cfg_print_cstr(pctx, "<ipv6_address>"); - cfg_print_chars(pctx, " ", 1); - cfg_print_cstr(pctx, "[port <integer>]"); - cfg_print_chars(pctx, " )", 2); -} - -static isc_result_t -parse_sockaddrnameport(cfg_parser_t *pctx, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - cfg_obj_t *obj = NULL; - UNUSED(type); - - CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); - if (pctx->token.type == isc_tokentype_string || - pctx->token.type == isc_tokentype_qstring) { - if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK)) - CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr, ret)); - else { - const cfg_tuplefielddef_t *fields = - cfg_type_nameport.of; - CHECK(cfg_create_tuple(pctx, &cfg_type_nameport, - &obj)); - CHECK(cfg_parse_obj(pctx, fields[0].type, - &obj->value.tuple[0])); - CHECK(cfg_parse_obj(pctx, fields[1].type, - &obj->value.tuple[1])); - *ret = obj; - obj = NULL; - } - } else { - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected IP address or hostname"); - return (ISC_R_UNEXPECTEDTOKEN); - } - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -static cfg_type_t cfg_type_sockaddrnameport = { - "sockaddrnameport_element", parse_sockaddrnameport, NULL, - doc_sockaddrnameport, NULL, NULL -}; - -static cfg_type_t cfg_type_bracketed_sockaddrnameportlist = { - "bracketed_sockaddrnameportlist", cfg_parse_bracketed_list, - cfg_print_bracketed_list, cfg_doc_bracketed_list, - &cfg_rep_list, &cfg_type_sockaddrnameport -}; - -/*% - * A list of socket addresses or name with an optional default port, - * as used in the dual-stack-servers option. E.g., - * "port 1234 { dual-stack-servers.net; 10.0.0.1; 1::2 port 69; }" - */ -static cfg_tuplefielddef_t nameportiplist_fields[] = { - { "port", &cfg_type_optional_port, 0 }, - { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 }, - { NULL, NULL, 0 } -}; - -static cfg_type_t cfg_type_nameportiplist = { - "nameportiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, - &cfg_rep_tuple, nameportiplist_fields -}; - -/*% - * masters element. - */ - -static void -doc_masterselement(cfg_printer_t *pctx, const cfg_type_t *type) { - UNUSED(type); - cfg_print_chars(pctx, "( ", 2); - cfg_print_cstr(pctx, "<masters>"); - cfg_print_chars(pctx, " | ", 3); - cfg_print_cstr(pctx, "<ipv4_address>"); - cfg_print_chars(pctx, " ", 1); - cfg_print_cstr(pctx, "[port <integer>]"); - cfg_print_chars(pctx, " | ", 3); - cfg_print_cstr(pctx, "<ipv6_address>"); - cfg_print_chars(pctx, " ", 1); - cfg_print_cstr(pctx, "[port <integer>]"); - cfg_print_chars(pctx, " )", 2); -} - -static isc_result_t -parse_masterselement(cfg_parser_t *pctx, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - cfg_obj_t *obj = NULL; - UNUSED(type); - - CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); - if (pctx->token.type == isc_tokentype_string || - pctx->token.type == isc_tokentype_qstring) { - if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK)) - CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr, ret)); - else - CHECK(cfg_parse_astring(pctx, &cfg_type_astring, ret)); - } else { - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected IP address or masters name"); - return (ISC_R_UNEXPECTEDTOKEN); - } - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -static cfg_type_t cfg_type_masterselement = { - "masters_element", parse_masterselement, NULL, - doc_masterselement, NULL, NULL -}; diff --git a/contrib/bind9/lib/isccfg/parser.c b/contrib/bind9/lib/isccfg/parser.c deleted file mode 100644 index 19a51a6..0000000 --- a/contrib/bind9/lib/isccfg/parser.c +++ /dev/null @@ -1,2382 +0,0 @@ -/* - * 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: parser.c,v 1.112.18.11 2006/02/28 03:10:49 marka Exp $ */ - -/*! \file */ - -#include <config.h> - -#include <isc/buffer.h> -#include <isc/dir.h> -#include <isc/formatcheck.h> -#include <isc/lex.h> -#include <isc/log.h> -#include <isc/mem.h> -#include <isc/net.h> -#include <isc/netaddr.h> -#include <isc/print.h> -#include <isc/string.h> -#include <isc/sockaddr.h> -#include <isc/netscope.h> -#include <isc/util.h> -#include <isc/symtab.h> - -#include <isccfg/cfg.h> -#include <isccfg/grammar.h> -#include <isccfg/log.h> - -/* Shorthand */ -#define CAT CFG_LOGCATEGORY_CONFIG -#define MOD CFG_LOGMODULE_PARSER - -#define MAP_SYM 1 /* Unique type for isc_symtab */ - -#define TOKEN_STRING(pctx) (pctx->token.value.as_textregion.base) - -/* Check a return value. */ -#define CHECK(op) \ - do { result = (op); \ - if (result != ISC_R_SUCCESS) goto cleanup; \ - } while (0) - -/* Clean up a configuration object if non-NULL. */ -#define CLEANUP_OBJ(obj) \ - do { if ((obj) != NULL) cfg_obj_destroy(pctx, &(obj)); } while (0) - - -/* - * Forward declarations of static functions. - */ - -static void -free_tuple(cfg_parser_t *pctx, cfg_obj_t *obj); - -static isc_result_t -parse_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); - -static void -print_list(cfg_printer_t *pctx, const cfg_obj_t *obj); - -static void -free_list(cfg_parser_t *pctx, cfg_obj_t *obj); - -static isc_result_t -create_listelt(cfg_parser_t *pctx, cfg_listelt_t **eltp); - -static isc_result_t -create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type, - cfg_obj_t **ret); - -static void -free_string(cfg_parser_t *pctx, cfg_obj_t *obj); - -static isc_result_t -create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp); - -static void -free_map(cfg_parser_t *pctx, cfg_obj_t *obj); - -static isc_result_t -parse_symtab_elt(cfg_parser_t *pctx, const char *name, - cfg_type_t *elttype, isc_symtab_t *symtab, - isc_boolean_t callback); - -static void -free_noop(cfg_parser_t *pctx, cfg_obj_t *obj); - -static isc_result_t -cfg_getstringtoken(cfg_parser_t *pctx); - -static void -parser_complain(cfg_parser_t *pctx, isc_boolean_t is_warning, - unsigned int flags, const char *format, va_list args); - -/* - * Data representations. These correspond to members of the - * "value" union in struct cfg_obj (except "void", which does - * not need a union member). - */ - -cfg_rep_t cfg_rep_uint32 = { "uint32", free_noop }; -cfg_rep_t cfg_rep_uint64 = { "uint64", free_noop }; -cfg_rep_t cfg_rep_string = { "string", free_string }; -cfg_rep_t cfg_rep_boolean = { "boolean", free_noop }; -cfg_rep_t cfg_rep_map = { "map", free_map }; -cfg_rep_t cfg_rep_list = { "list", free_list }; -cfg_rep_t cfg_rep_tuple = { "tuple", free_tuple }; -cfg_rep_t cfg_rep_sockaddr = { "sockaddr", free_noop }; -cfg_rep_t cfg_rep_netprefix = { "netprefix", free_noop }; -cfg_rep_t cfg_rep_void = { "void", free_noop }; - -/* - * Configuration type definitions. - */ - -/*% - * An implicit list. These are formed by clauses that occur multiple times. - */ -static cfg_type_t cfg_type_implicitlist = { - "implicitlist", NULL, print_list, NULL, &cfg_rep_list, NULL }; - -/* Functions. */ - -void -cfg_print_obj(cfg_printer_t *pctx, const cfg_obj_t *obj) { - obj->type->print(pctx, obj); -} - -void -cfg_print_chars(cfg_printer_t *pctx, const char *text, int len) { - pctx->f(pctx->closure, text, len); -} - -static void -print_open(cfg_printer_t *pctx) { - cfg_print_chars(pctx, "{\n", 2); - pctx->indent++; -} - -static void -print_indent(cfg_printer_t *pctx) { - int indent = pctx->indent; - while (indent > 0) { - cfg_print_chars(pctx, "\t", 1); - indent--; - } -} - -static void -print_close(cfg_printer_t *pctx) { - pctx->indent--; - print_indent(pctx); - cfg_print_chars(pctx, "}", 1); -} - -isc_result_t -cfg_parse_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - INSIST(ret != NULL && *ret == NULL); - result = type->parse(pctx, type, ret); - if (result != ISC_R_SUCCESS) - return (result); - INSIST(*ret != NULL); - return (ISC_R_SUCCESS); -} - -void -cfg_print(const cfg_obj_t *obj, - void (*f)(void *closure, const char *text, int textlen), - void *closure) -{ - cfg_printer_t pctx; - pctx.f = f; - pctx.closure = closure; - pctx.indent = 0; - obj->type->print(&pctx, obj); -} - - -/* Tuples. */ - -isc_result_t -cfg_create_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - const cfg_tuplefielddef_t *fields = type->of; - const cfg_tuplefielddef_t *f; - cfg_obj_t *obj = NULL; - unsigned int nfields = 0; - int i; - - for (f = fields; f->name != NULL; f++) - nfields++; - - CHECK(cfg_create_obj(pctx, type, &obj)); - obj->value.tuple = isc_mem_get(pctx->mctx, - nfields * sizeof(cfg_obj_t *)); - if (obj->value.tuple == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - for (f = fields, i = 0; f->name != NULL; f++, i++) - obj->value.tuple[i] = NULL; - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - if (obj != NULL) - isc_mem_put(pctx->mctx, obj, sizeof(*obj)); - return (result); -} - -isc_result_t -cfg_parse_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) -{ - isc_result_t result; - const cfg_tuplefielddef_t *fields = type->of; - const cfg_tuplefielddef_t *f; - cfg_obj_t *obj = NULL; - unsigned int i; - - CHECK(cfg_create_tuple(pctx, type, &obj)); - for (f = fields, i = 0; f->name != NULL; f++, i++) - CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[i])); - - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -void -cfg_print_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) { - unsigned int i; - const cfg_tuplefielddef_t *fields = obj->type->of; - const cfg_tuplefielddef_t *f; - isc_boolean_t need_space = ISC_FALSE; - - for (f = fields, i = 0; f->name != NULL; f++, i++) { - const cfg_obj_t *fieldobj = obj->value.tuple[i]; - if (need_space) - cfg_print_chars(pctx, " ", 1); - cfg_print_obj(pctx, fieldobj); - need_space = ISC_TF(fieldobj->type->print != cfg_print_void); - } -} - -void -cfg_doc_tuple(cfg_printer_t *pctx, const cfg_type_t *type) { - const cfg_tuplefielddef_t *fields = type->of; - const cfg_tuplefielddef_t *f; - isc_boolean_t need_space = ISC_FALSE; - - for (f = fields; f->name != NULL; f++) { - if (need_space) - cfg_print_chars(pctx, " ", 1); - cfg_doc_obj(pctx, f->type); - need_space = ISC_TF(f->type->print != cfg_print_void); - } -} - -static void -free_tuple(cfg_parser_t *pctx, cfg_obj_t *obj) { - unsigned int i; - const cfg_tuplefielddef_t *fields = obj->type->of; - const cfg_tuplefielddef_t *f; - unsigned int nfields = 0; - - if (obj->value.tuple == NULL) - return; - - for (f = fields, i = 0; f->name != NULL; f++, i++) { - CLEANUP_OBJ(obj->value.tuple[i]); - nfields++; - } - isc_mem_put(pctx->mctx, obj->value.tuple, - nfields * sizeof(cfg_obj_t *)); -} - -isc_boolean_t -cfg_obj_istuple(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_tuple)); -} - -const cfg_obj_t * -cfg_tuple_get(const cfg_obj_t *tupleobj, const char* name) { - unsigned int i; - const cfg_tuplefielddef_t *fields; - const cfg_tuplefielddef_t *f; - - REQUIRE(tupleobj != NULL && tupleobj->type->rep == &cfg_rep_tuple); - - fields = tupleobj->type->of; - for (f = fields, i = 0; f->name != NULL; f++, i++) { - if (strcmp(f->name, name) == 0) - return (tupleobj->value.tuple[i]); - } - INSIST(0); - return (NULL); -} - -isc_result_t -cfg_parse_special(cfg_parser_t *pctx, int special) { - isc_result_t result; - CHECK(cfg_gettoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_special && - pctx->token.value.as_char == special) - return (ISC_R_SUCCESS); - - cfg_parser_error(pctx, CFG_LOG_NEAR, "'%c' expected", special); - return (ISC_R_UNEXPECTEDTOKEN); - cleanup: - return (result); -} - -/* - * Parse a required semicolon. If it is not there, log - * an error and increment the error count but continue - * parsing. Since the next token is pushed back, - * care must be taken to make sure it is eventually - * consumed or an infinite loop may result. - */ -static isc_result_t -parse_semicolon(cfg_parser_t *pctx) { - isc_result_t result; - CHECK(cfg_gettoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_special && - pctx->token.value.as_char == ';') - return (ISC_R_SUCCESS); - - cfg_parser_error(pctx, CFG_LOG_BEFORE, "missing ';'"); - cfg_ungettoken(pctx); - cleanup: - return (result); -} - -/* - * Parse EOF, logging and returning an error if not there. - */ -static isc_result_t -parse_eof(cfg_parser_t *pctx) { - isc_result_t result; - CHECK(cfg_gettoken(pctx, 0)); - - if (pctx->token.type == isc_tokentype_eof) - return (ISC_R_SUCCESS); - - cfg_parser_error(pctx, CFG_LOG_NEAR, "syntax error"); - return (ISC_R_UNEXPECTEDTOKEN); - cleanup: - return (result); -} - -/* A list of files, used internally for pctx->files. */ - -static cfg_type_t cfg_type_filelist = { - "filelist", NULL, print_list, NULL, &cfg_rep_list, - &cfg_type_qstring -}; - -isc_result_t -cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) { - isc_result_t result; - cfg_parser_t *pctx; - isc_lexspecials_t specials; - - REQUIRE(mctx != NULL); - REQUIRE(ret != NULL && *ret == NULL); - - pctx = isc_mem_get(mctx, sizeof(*pctx)); - if (pctx == NULL) - return (ISC_R_NOMEMORY); - - pctx->mctx = mctx; - pctx->lctx = lctx; - pctx->lexer = NULL; - pctx->seen_eof = ISC_FALSE; - pctx->ungotten = ISC_FALSE; - pctx->errors = 0; - pctx->warnings = 0; - pctx->open_files = NULL; - pctx->closed_files = NULL; - pctx->line = 0; - pctx->callback = NULL; - pctx->callbackarg = NULL; - pctx->token.type = isc_tokentype_unknown; - - memset(specials, 0, sizeof(specials)); - specials['{'] = 1; - specials['}'] = 1; - specials[';'] = 1; - specials['/'] = 1; - specials['"'] = 1; - specials['!'] = 1; - - CHECK(isc_lex_create(pctx->mctx, 1024, &pctx->lexer)); - - isc_lex_setspecials(pctx->lexer, specials); - isc_lex_setcomments(pctx->lexer, (ISC_LEXCOMMENT_C | - ISC_LEXCOMMENT_CPLUSPLUS | - ISC_LEXCOMMENT_SHELL)); - - CHECK(cfg_create_list(pctx, &cfg_type_filelist, &pctx->open_files)); - CHECK(cfg_create_list(pctx, &cfg_type_filelist, &pctx->closed_files)); - - *ret = pctx; - return (ISC_R_SUCCESS); - - cleanup: - if (pctx->lexer != NULL) - isc_lex_destroy(&pctx->lexer); - CLEANUP_OBJ(pctx->open_files); - CLEANUP_OBJ(pctx->closed_files); - isc_mem_put(mctx, pctx, sizeof(*pctx)); - return (result); -} - -static isc_result_t -parser_openfile(cfg_parser_t *pctx, const char *filename) { - isc_result_t result; - cfg_listelt_t *elt = NULL; - cfg_obj_t *stringobj = NULL; - - result = isc_lex_openfile(pctx->lexer, filename); - if (result != ISC_R_SUCCESS) { - cfg_parser_error(pctx, 0, "open: %s: %s", - filename, isc_result_totext(result)); - goto cleanup; - } - - CHECK(create_string(pctx, filename, &cfg_type_qstring, &stringobj)); - CHECK(create_listelt(pctx, &elt)); - elt->obj = stringobj; - ISC_LIST_APPEND(pctx->open_files->value.list, elt, link); - - return (ISC_R_SUCCESS); - cleanup: - CLEANUP_OBJ(stringobj); - return (result); -} - -void -cfg_parser_setcallback(cfg_parser_t *pctx, - cfg_parsecallback_t callback, - void *arg) -{ - pctx->callback = callback; - pctx->callbackarg = arg; -} - -/* - * Parse a configuration using a pctx where a lexer has already - * been set up with a source. - */ -static isc_result_t -parse2(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *obj = NULL; - - result = cfg_parse_obj(pctx, type, &obj); - - if (pctx->errors != 0) { - /* Errors have been logged. */ - if (result == ISC_R_SUCCESS) - result = ISC_R_FAILURE; - goto cleanup; - } - - if (result != ISC_R_SUCCESS) { - /* Parsing failed but no errors have been logged. */ - cfg_parser_error(pctx, 0, "parsing failed"); - goto cleanup; - } - - CHECK(parse_eof(pctx)); - - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -isc_result_t -cfg_parse_file(cfg_parser_t *pctx, const char *filename, - const cfg_type_t *type, cfg_obj_t **ret) -{ - isc_result_t result; - - REQUIRE(filename != NULL); - - CHECK(parser_openfile(pctx, filename)); - CHECK(parse2(pctx, type, ret)); - cleanup: - return (result); -} - - -isc_result_t -cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, - const cfg_type_t *type, cfg_obj_t **ret) -{ - isc_result_t result; - REQUIRE(buffer != NULL); - CHECK(isc_lex_openbuffer(pctx->lexer, buffer)); - CHECK(parse2(pctx, type, ret)); - cleanup: - return (result); -} - -void -cfg_parser_destroy(cfg_parser_t **pctxp) { - cfg_parser_t *pctx = *pctxp; - isc_lex_destroy(&pctx->lexer); - /* - * Cleaning up open_files does not - * close the files; that was already done - * by closing the lexer. - */ - CLEANUP_OBJ(pctx->open_files); - CLEANUP_OBJ(pctx->closed_files); - isc_mem_put(pctx->mctx, pctx, sizeof(*pctx)); - *pctxp = NULL; -} - -/* - * void - */ -isc_result_t -cfg_parse_void(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - UNUSED(type); - return (cfg_create_obj(pctx, &cfg_type_void, ret)); -} - -void -cfg_print_void(cfg_printer_t *pctx, const cfg_obj_t *obj) { - UNUSED(pctx); - UNUSED(obj); -} - -void -cfg_doc_void(cfg_printer_t *pctx, const cfg_type_t *type) { - UNUSED(pctx); - UNUSED(type); -} - -isc_boolean_t -cfg_obj_isvoid(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_void)); -} - -cfg_type_t cfg_type_void = { - "void", cfg_parse_void, cfg_print_void, cfg_doc_void, &cfg_rep_void, - NULL }; - - -/* - * uint32 - */ -isc_result_t -cfg_parse_uint32(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *obj = NULL; - UNUSED(type); - - CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER | ISC_LEXOPT_CNUMBER)); - if (pctx->token.type != isc_tokentype_number) { - cfg_parser_error(pctx, CFG_LOG_NEAR, "expected number"); - return (ISC_R_UNEXPECTEDTOKEN); - } - - CHECK(cfg_create_obj(pctx, &cfg_type_uint32, &obj)); - - obj->value.uint32 = pctx->token.value.as_ulong; - *ret = obj; - cleanup: - return (result); -} - -void -cfg_print_cstr(cfg_printer_t *pctx, const char *s) { - cfg_print_chars(pctx, s, strlen(s)); -} - -void -cfg_print_rawuint(cfg_printer_t *pctx, unsigned int u) { - char buf[32]; - snprintf(buf, sizeof(buf), "%u", u); - cfg_print_cstr(pctx, buf); -} - -void -cfg_print_uint32(cfg_printer_t *pctx, const cfg_obj_t *obj) { - cfg_print_rawuint(pctx, obj->value.uint32); -} - -isc_boolean_t -cfg_obj_isuint32(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_uint32)); -} - -isc_uint32_t -cfg_obj_asuint32(const cfg_obj_t *obj) { - REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_uint32); - return (obj->value.uint32); -} - -cfg_type_t cfg_type_uint32 = { - "integer", cfg_parse_uint32, cfg_print_uint32, cfg_doc_terminal, - &cfg_rep_uint32, NULL -}; - - -/* - * uint64 - */ -isc_boolean_t -cfg_obj_isuint64(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_uint64)); -} - -isc_uint64_t -cfg_obj_asuint64(const cfg_obj_t *obj) { - REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_uint64); - return (obj->value.uint64); -} - -void -cfg_print_uint64(cfg_printer_t *pctx, const cfg_obj_t *obj) { - char buf[32]; - snprintf(buf, sizeof(buf), "%" ISC_PRINT_QUADFORMAT "u", - obj->value.uint64); - cfg_print_cstr(pctx, buf); -} - -cfg_type_t cfg_type_uint64 = { - "64_bit_integer", NULL, cfg_print_uint64, cfg_doc_terminal, - &cfg_rep_uint64, NULL -}; - -/* - * qstring (quoted string), ustring (unquoted string), astring - * (any string) - */ - -/* Create a string object from a null-terminated C string. */ -static isc_result_t -create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - cfg_obj_t *obj = NULL; - int len; - - CHECK(cfg_create_obj(pctx, type, &obj)); - len = strlen(contents); - obj->value.string.length = len; - obj->value.string.base = isc_mem_get(pctx->mctx, len + 1); - if (obj->value.string.base == 0) { - isc_mem_put(pctx->mctx, obj, sizeof(*obj)); - return (ISC_R_NOMEMORY); - } - memcpy(obj->value.string.base, contents, len); - obj->value.string.base[len] = '\0'; - - *ret = obj; - cleanup: - return (result); -} - -isc_result_t -cfg_parse_qstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - UNUSED(type); - - CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); - if (pctx->token.type != isc_tokentype_qstring) { - cfg_parser_error(pctx, CFG_LOG_NEAR, "expected quoted string"); - return (ISC_R_UNEXPECTEDTOKEN); - } - return (create_string(pctx, - TOKEN_STRING(pctx), - &cfg_type_qstring, - ret)); - cleanup: - return (result); -} - -static isc_result_t -parse_ustring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - UNUSED(type); - - CHECK(cfg_gettoken(pctx, 0)); - if (pctx->token.type != isc_tokentype_string) { - cfg_parser_error(pctx, CFG_LOG_NEAR, "expected unquoted string"); - return (ISC_R_UNEXPECTEDTOKEN); - } - return (create_string(pctx, - TOKEN_STRING(pctx), - &cfg_type_ustring, - ret)); - cleanup: - return (result); -} - -isc_result_t -cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - UNUSED(type); - - CHECK(cfg_getstringtoken(pctx)); - return (create_string(pctx, - TOKEN_STRING(pctx), - &cfg_type_qstring, - ret)); - cleanup: - return (result); -} - -isc_boolean_t -cfg_is_enum(const char *s, const char *const *enums) { - const char * const *p; - for (p = enums; *p != NULL; p++) { - if (strcasecmp(*p, s) == 0) - return (ISC_TRUE); - } - return (ISC_FALSE); -} - -static isc_result_t -check_enum(cfg_parser_t *pctx, cfg_obj_t *obj, const char *const *enums) { - const char *s = obj->value.string.base; - if (cfg_is_enum(s, enums)) - return (ISC_R_SUCCESS); - cfg_parser_error(pctx, 0, "'%s' unexpected", s); - return (ISC_R_UNEXPECTEDTOKEN); -} - -isc_result_t -cfg_parse_enum(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *obj = NULL; - CHECK(parse_ustring(pctx, NULL, &obj)); - CHECK(check_enum(pctx, obj, type->of)); - *ret = obj; - return (ISC_R_SUCCESS); - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -void -cfg_doc_enum(cfg_printer_t *pctx, const cfg_type_t *type) { - const char * const *p; - cfg_print_chars(pctx, "( ", 2); - for (p = type->of; *p != NULL; p++) { - cfg_print_cstr(pctx, *p); - if (p[1] != NULL) - cfg_print_chars(pctx, " | ", 3); - } - cfg_print_chars(pctx, " )", 2); -} - -void -cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj) { - cfg_print_chars(pctx, obj->value.string.base, obj->value.string.length); -} - -static void -print_qstring(cfg_printer_t *pctx, const cfg_obj_t *obj) { - cfg_print_chars(pctx, "\"", 1); - cfg_print_ustring(pctx, obj); - cfg_print_chars(pctx, "\"", 1); -} - -static void -free_string(cfg_parser_t *pctx, cfg_obj_t *obj) { - isc_mem_put(pctx->mctx, obj->value.string.base, - obj->value.string.length + 1); -} - -isc_boolean_t -cfg_obj_isstring(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_string)); -} - -const char * -cfg_obj_asstring(const cfg_obj_t *obj) { - REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_string); - return (obj->value.string.base); -} - -/* Quoted string only */ -cfg_type_t cfg_type_qstring = { - "quoted_string", cfg_parse_qstring, print_qstring, cfg_doc_terminal, - &cfg_rep_string, NULL -}; - -/* Unquoted string only */ -cfg_type_t cfg_type_ustring = { - "string", parse_ustring, cfg_print_ustring, cfg_doc_terminal, - &cfg_rep_string, NULL -}; - -/* Any string (quoted or unquoted); printed with quotes */ -cfg_type_t cfg_type_astring = { - "string", cfg_parse_astring, print_qstring, cfg_doc_terminal, - &cfg_rep_string, NULL -}; - -/* - * Booleans - */ - -isc_boolean_t -cfg_obj_isboolean(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_boolean)); -} - -isc_boolean_t -cfg_obj_asboolean(const cfg_obj_t *obj) { - REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_boolean); - return (obj->value.boolean); -} - -static isc_result_t -parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) -{ - isc_result_t result; - isc_boolean_t value; - cfg_obj_t *obj = NULL; - UNUSED(type); - - result = cfg_gettoken(pctx, 0); - if (result != ISC_R_SUCCESS) - return (result); - - if (pctx->token.type != isc_tokentype_string) - goto bad_boolean; - - if ((strcasecmp(TOKEN_STRING(pctx), "true") == 0) || - (strcasecmp(TOKEN_STRING(pctx), "yes") == 0) || - (strcmp(TOKEN_STRING(pctx), "1") == 0)) { - value = ISC_TRUE; - } else if ((strcasecmp(TOKEN_STRING(pctx), "false") == 0) || - (strcasecmp(TOKEN_STRING(pctx), "no") == 0) || - (strcmp(TOKEN_STRING(pctx), "0") == 0)) { - value = ISC_FALSE; - } else { - goto bad_boolean; - } - - CHECK(cfg_create_obj(pctx, &cfg_type_boolean, &obj)); - obj->value.boolean = value; - *ret = obj; - return (result); - - bad_boolean: - cfg_parser_error(pctx, CFG_LOG_NEAR, "boolean expected"); - return (ISC_R_UNEXPECTEDTOKEN); - - cleanup: - return (result); -} - -static void -print_boolean(cfg_printer_t *pctx, const cfg_obj_t *obj) { - if (obj->value.boolean) - cfg_print_chars(pctx, "yes", 3); - else - cfg_print_chars(pctx, "no", 2); -} - -cfg_type_t cfg_type_boolean = { - "boolean", parse_boolean, print_boolean, cfg_doc_terminal, - &cfg_rep_boolean, NULL -}; - -/* - * Lists. - */ - -isc_result_t -cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **obj) { - isc_result_t result; - CHECK(cfg_create_obj(pctx, type, obj)); - ISC_LIST_INIT((*obj)->value.list); - cleanup: - return (result); -} - -static isc_result_t -create_listelt(cfg_parser_t *pctx, cfg_listelt_t **eltp) { - cfg_listelt_t *elt; - elt = isc_mem_get(pctx->mctx, sizeof(*elt)); - if (elt == NULL) - return (ISC_R_NOMEMORY); - elt->obj = NULL; - ISC_LINK_INIT(elt, link); - *eltp = elt; - return (ISC_R_SUCCESS); -} - -static void -free_list_elt(cfg_parser_t *pctx, cfg_listelt_t *elt) { - cfg_obj_destroy(pctx, &elt->obj); - isc_mem_put(pctx->mctx, elt, sizeof(*elt)); -} - -static void -free_list(cfg_parser_t *pctx, cfg_obj_t *obj) { - cfg_listelt_t *elt, *next; - for (elt = ISC_LIST_HEAD(obj->value.list); - elt != NULL; - elt = next) - { - next = ISC_LIST_NEXT(elt, link); - free_list_elt(pctx, elt); - } -} - -isc_result_t -cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype, - cfg_listelt_t **ret) -{ - isc_result_t result; - cfg_listelt_t *elt = NULL; - cfg_obj_t *value = NULL; - - CHECK(create_listelt(pctx, &elt)); - - result = cfg_parse_obj(pctx, elttype, &value); - if (result != ISC_R_SUCCESS) - goto cleanup; - - elt->obj = value; - - *ret = elt; - return (ISC_R_SUCCESS); - - cleanup: - isc_mem_put(pctx->mctx, elt, sizeof(*elt)); - return (result); -} - -/* - * Parse a homogeneous list whose elements are of type 'elttype' - * and where each element is terminated by a semicolon. - */ -static isc_result_t -parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) -{ - cfg_obj_t *listobj = NULL; - const cfg_type_t *listof = listtype->of; - isc_result_t result; - cfg_listelt_t *elt = NULL; - - CHECK(cfg_create_list(pctx, listtype, &listobj)); - - for (;;) { - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_special && - pctx->token.value.as_char == /*{*/ '}') - break; - CHECK(cfg_parse_listelt(pctx, listof, &elt)); - CHECK(parse_semicolon(pctx)); - ISC_LIST_APPEND(listobj->value.list, elt, link); - elt = NULL; - } - *ret = listobj; - return (ISC_R_SUCCESS); - - cleanup: - if (elt != NULL) - free_list_elt(pctx, elt); - CLEANUP_OBJ(listobj); - return (result); -} - -static void -print_list(cfg_printer_t *pctx, const cfg_obj_t *obj) { - const cfg_list_t *list = &obj->value.list; - const cfg_listelt_t *elt; - - for (elt = ISC_LIST_HEAD(*list); - elt != NULL; - elt = ISC_LIST_NEXT(elt, link)) { - print_indent(pctx); - cfg_print_obj(pctx, elt->obj); - cfg_print_chars(pctx, ";\n", 2); - } -} - -isc_result_t -cfg_parse_bracketed_list(cfg_parser_t *pctx, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - CHECK(cfg_parse_special(pctx, '{')); - CHECK(parse_list(pctx, type, ret)); - CHECK(cfg_parse_special(pctx, '}')); - cleanup: - return (result); -} - -void -cfg_print_bracketed_list(cfg_printer_t *pctx, const cfg_obj_t *obj) { - print_open(pctx); - print_list(pctx, obj); - print_close(pctx); -} - -void -cfg_doc_bracketed_list(cfg_printer_t *pctx, const cfg_type_t *type) { - cfg_print_chars(pctx, "{ ", 2); - cfg_doc_obj(pctx, type->of); - cfg_print_chars(pctx, "; ... }", 7); -} - -/* - * Parse a homogeneous list whose elements are of type 'elttype' - * and where elements are separated by space. The list ends - * before the first semicolon. - */ -isc_result_t -cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *listtype, - cfg_obj_t **ret) -{ - cfg_obj_t *listobj = NULL; - const cfg_type_t *listof = listtype->of; - isc_result_t result; - - CHECK(cfg_create_list(pctx, listtype, &listobj)); - - for (;;) { - cfg_listelt_t *elt = NULL; - - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_special && - pctx->token.value.as_char == ';') - break; - CHECK(cfg_parse_listelt(pctx, listof, &elt)); - ISC_LIST_APPEND(listobj->value.list, elt, link); - } - *ret = listobj; - return (ISC_R_SUCCESS); - - cleanup: - CLEANUP_OBJ(listobj); - return (result); -} - -void -cfg_print_spacelist(cfg_printer_t *pctx, const cfg_obj_t *obj) { - const cfg_list_t *list = &obj->value.list; - const cfg_listelt_t *elt; - - for (elt = ISC_LIST_HEAD(*list); - elt != NULL; - elt = ISC_LIST_NEXT(elt, link)) { - cfg_print_obj(pctx, elt->obj); - if (ISC_LIST_NEXT(elt, link) != NULL) - cfg_print_chars(pctx, " ", 1); - } -} - -isc_boolean_t -cfg_obj_islist(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_list)); -} - -const cfg_listelt_t * -cfg_list_first(const cfg_obj_t *obj) { - REQUIRE(obj == NULL || obj->type->rep == &cfg_rep_list); - if (obj == NULL) - return (NULL); - return (ISC_LIST_HEAD(obj->value.list)); -} - -const cfg_listelt_t * -cfg_list_next(const cfg_listelt_t *elt) { - REQUIRE(elt != NULL); - return (ISC_LIST_NEXT(elt, link)); -} - -const cfg_obj_t * -cfg_listelt_value(const cfg_listelt_t *elt) { - REQUIRE(elt != NULL); - return (elt->obj); -} - -/* - * Maps. - */ - -/* - * Parse a map body. That's something like - * - * "foo 1; bar { glub; }; zap true; zap false;" - * - * i.e., a sequence of option names followed by values and - * terminated by semicolons. Used for the top level of - * the named.conf syntax, as well as for the body of the - * options, view, zone, and other statements. - */ -isc_result_t -cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) -{ - const cfg_clausedef_t * const *clausesets = type->of; - isc_result_t result; - const cfg_clausedef_t * const *clauseset; - const cfg_clausedef_t *clause; - cfg_obj_t *value = NULL; - cfg_obj_t *obj = NULL; - cfg_obj_t *eltobj = NULL; - cfg_obj_t *includename = NULL; - isc_symvalue_t symval; - cfg_list_t *list = NULL; - - CHECK(create_map(pctx, type, &obj)); - - obj->value.map.clausesets = clausesets; - - for (;;) { - cfg_listelt_t *elt; - - redo: - /* - * Parse the option name and see if it is known. - */ - CHECK(cfg_gettoken(pctx, 0)); - - if (pctx->token.type != isc_tokentype_string) { - cfg_ungettoken(pctx); - break; - } - - /* - * We accept "include" statements wherever a map body - * clause can occur. - */ - if (strcasecmp(TOKEN_STRING(pctx), "include") == 0) { - /* - * Turn the file name into a temporary configuration - * object just so that it is not overwritten by the - * semicolon token. - */ - CHECK(cfg_parse_obj(pctx, &cfg_type_qstring, &includename)); - CHECK(parse_semicolon(pctx)); - CHECK(parser_openfile(pctx, includename-> - value.string.base)); - cfg_obj_destroy(pctx, &includename); - goto redo; - } - - clause = NULL; - for (clauseset = clausesets; *clauseset != NULL; clauseset++) { - for (clause = *clauseset; - clause->name != NULL; - clause++) { - if (strcasecmp(TOKEN_STRING(pctx), - clause->name) == 0) - goto done; - } - } - done: - if (clause == NULL || clause->name == NULL) { - cfg_parser_error(pctx, CFG_LOG_NOPREP, "unknown option"); - /* - * Try to recover by parsing this option as an unknown - * option and discarding it. - */ - CHECK(cfg_parse_obj(pctx, &cfg_type_unsupported, &eltobj)); - cfg_obj_destroy(pctx, &eltobj); - CHECK(parse_semicolon(pctx)); - continue; - } - - /* Clause is known. */ - - /* Issue warnings if appropriate */ - if ((clause->flags & CFG_CLAUSEFLAG_OBSOLETE) != 0) - cfg_parser_warning(pctx, 0, "option '%s' is obsolete", - clause->name); - if ((clause->flags & CFG_CLAUSEFLAG_NOTIMP) != 0) - cfg_parser_warning(pctx, 0, "option '%s' is " - "not implemented", clause->name); - if ((clause->flags & CFG_CLAUSEFLAG_NYI) != 0) - cfg_parser_warning(pctx, 0, "option '%s' is " - "not implemented", clause->name); - /* - * Don't log options with CFG_CLAUSEFLAG_NEWDEFAULT - * set here - we need to log the *lack* of such an option, - * not its presence. - */ - - /* See if the clause already has a value; if not create one. */ - result = isc_symtab_lookup(obj->value.map.symtab, - clause->name, 0, &symval); - - if ((clause->flags & CFG_CLAUSEFLAG_MULTI) != 0) { - /* Multivalued clause */ - cfg_obj_t *listobj = NULL; - if (result == ISC_R_NOTFOUND) { - CHECK(cfg_create_list(pctx, - &cfg_type_implicitlist, - &listobj)); - symval.as_pointer = listobj; - result = isc_symtab_define(obj->value. - map.symtab, - clause->name, - 1, symval, - isc_symexists_reject); - if (result != ISC_R_SUCCESS) { - cfg_parser_error(pctx, CFG_LOG_NEAR, - "isc_symtab_define(%s) " - "failed", clause->name); - isc_mem_put(pctx->mctx, list, - sizeof(cfg_list_t)); - goto cleanup; - } - } else { - INSIST(result == ISC_R_SUCCESS); - listobj = symval.as_pointer; - } - - elt = NULL; - CHECK(cfg_parse_listelt(pctx, clause->type, &elt)); - CHECK(parse_semicolon(pctx)); - - ISC_LIST_APPEND(listobj->value.list, elt, link); - } else { - /* Single-valued clause */ - if (result == ISC_R_NOTFOUND) { - isc_boolean_t callback = - ISC_TF((clause->flags & - CFG_CLAUSEFLAG_CALLBACK) != 0); - CHECK(parse_symtab_elt(pctx, clause->name, - clause->type, - obj->value.map.symtab, - callback)); - CHECK(parse_semicolon(pctx)); - } else if (result == ISC_R_SUCCESS) { - cfg_parser_error(pctx, CFG_LOG_NEAR, "'%s' redefined", - clause->name); - result = ISC_R_EXISTS; - goto cleanup; - } else { - cfg_parser_error(pctx, CFG_LOG_NEAR, - "isc_symtab_define() failed"); - goto cleanup; - } - } - } - - - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - CLEANUP_OBJ(value); - CLEANUP_OBJ(obj); - CLEANUP_OBJ(eltobj); - CLEANUP_OBJ(includename); - return (result); -} - -static isc_result_t -parse_symtab_elt(cfg_parser_t *pctx, const char *name, - cfg_type_t *elttype, isc_symtab_t *symtab, - isc_boolean_t callback) -{ - isc_result_t result; - cfg_obj_t *obj = NULL; - isc_symvalue_t symval; - - CHECK(cfg_parse_obj(pctx, elttype, &obj)); - - if (callback && pctx->callback != NULL) - CHECK(pctx->callback(name, obj, pctx->callbackarg)); - - symval.as_pointer = obj; - CHECK(isc_symtab_define(symtab, name, - 1, symval, - isc_symexists_reject)); - return (ISC_R_SUCCESS); - - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -/* - * Parse a map; e.g., "{ foo 1; bar { glub; }; zap true; zap false; }" - */ -isc_result_t -cfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - CHECK(cfg_parse_special(pctx, '{')); - CHECK(cfg_parse_mapbody(pctx, type, ret)); - CHECK(cfg_parse_special(pctx, '}')); - cleanup: - return (result); -} - -/* - * Subroutine for cfg_parse_named_map() and cfg_parse_addressed_map(). - */ -static isc_result_t -parse_any_named_map(cfg_parser_t *pctx, cfg_type_t *nametype, const cfg_type_t *type, - cfg_obj_t **ret) -{ - isc_result_t result; - cfg_obj_t *idobj = NULL; - cfg_obj_t *mapobj = NULL; - - CHECK(cfg_parse_obj(pctx, nametype, &idobj)); - CHECK(cfg_parse_map(pctx, type, &mapobj)); - mapobj->value.map.id = idobj; - idobj = NULL; - *ret = mapobj; - cleanup: - CLEANUP_OBJ(idobj); - return (result); -} - -/* - * Parse a map identified by a string name. E.g., "name { foo 1; }". - * Used for the "key" and "channel" statements. - */ -isc_result_t -cfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_any_named_map(pctx, &cfg_type_astring, type, ret)); -} - -/* - * Parse a map identified by a network address. - * Used to be used for the "server" statement. - */ -isc_result_t -cfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_any_named_map(pctx, &cfg_type_netaddr, type, ret)); -} - -/* - * Parse a map identified by a network prefix. - * Used for the "server" statement. - */ -isc_result_t -cfg_parse_netprefix_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - return (parse_any_named_map(pctx, &cfg_type_netprefix, type, ret)); -} - -void -cfg_print_mapbody(cfg_printer_t *pctx, const cfg_obj_t *obj) { - isc_result_t result = ISC_R_SUCCESS; - - const cfg_clausedef_t * const *clauseset; - - for (clauseset = obj->value.map.clausesets; - *clauseset != NULL; - clauseset++) - { - isc_symvalue_t symval; - const cfg_clausedef_t *clause; - - for (clause = *clauseset; - clause->name != NULL; - clause++) { - result = isc_symtab_lookup(obj->value.map.symtab, - clause->name, 0, &symval); - if (result == ISC_R_SUCCESS) { - cfg_obj_t *obj = symval.as_pointer; - if (obj->type == &cfg_type_implicitlist) { - /* Multivalued. */ - cfg_list_t *list = &obj->value.list; - cfg_listelt_t *elt; - for (elt = ISC_LIST_HEAD(*list); - elt != NULL; - elt = ISC_LIST_NEXT(elt, link)) { - print_indent(pctx); - cfg_print_cstr(pctx, clause->name); - cfg_print_chars(pctx, " ", 1); - cfg_print_obj(pctx, elt->obj); - cfg_print_chars(pctx, ";\n", 2); - } - } else { - /* Single-valued. */ - print_indent(pctx); - cfg_print_cstr(pctx, clause->name); - cfg_print_chars(pctx, " ", 1); - cfg_print_obj(pctx, obj); - cfg_print_chars(pctx, ";\n", 2); - } - } else if (result == ISC_R_NOTFOUND) { - ; /* do nothing */ - } else { - INSIST(0); - } - } - } -} - -void -cfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type) { - const cfg_clausedef_t * const *clauseset; - const cfg_clausedef_t *clause; - - for (clauseset = type->of; *clauseset != NULL; clauseset++) { - for (clause = *clauseset; - clause->name != NULL; - clause++) { - cfg_print_cstr(pctx, clause->name); - cfg_print_chars(pctx, " ", 1); - cfg_doc_obj(pctx, clause->type); - cfg_print_chars(pctx, ";", 1); - /* XXX print flags here? */ - cfg_print_chars(pctx, "\n\n", 2); - } - } -} - -static struct flagtext { - unsigned int flag; - const char *text; -} flagtexts[] = { - { CFG_CLAUSEFLAG_NOTIMP, "not implemented" }, - { CFG_CLAUSEFLAG_NYI, "not yet implemented" }, - { CFG_CLAUSEFLAG_OBSOLETE, "obsolete" }, - { CFG_CLAUSEFLAG_NEWDEFAULT, "default changed" }, - { 0, NULL } -}; - -void -cfg_print_map(cfg_printer_t *pctx, const cfg_obj_t *obj) { - if (obj->value.map.id != NULL) { - cfg_print_obj(pctx, obj->value.map.id); - cfg_print_chars(pctx, " ", 1); - } - print_open(pctx); - cfg_print_mapbody(pctx, obj); - print_close(pctx); -} - -static void -print_clause_flags(cfg_printer_t *pctx, unsigned int flags) { - struct flagtext *p; - isc_boolean_t first = ISC_TRUE; - for (p = flagtexts; p->flag != 0; p++) { - if ((flags & p->flag) != 0) { - if (first) - cfg_print_chars(pctx, " // ", 4); - else - cfg_print_chars(pctx, ", ", 2); - cfg_print_cstr(pctx, p->text); - first = ISC_FALSE; - } - } -} - -void -cfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type) { - const cfg_clausedef_t * const *clauseset; - const cfg_clausedef_t *clause; - - if (type->parse == cfg_parse_named_map) { - cfg_doc_obj(pctx, &cfg_type_astring); - cfg_print_chars(pctx, " ", 1); - } else if (type->parse == cfg_parse_addressed_map) { - cfg_doc_obj(pctx, &cfg_type_netaddr); - cfg_print_chars(pctx, " ", 1); - } else if (type->parse == cfg_parse_netprefix_map) { - cfg_doc_obj(pctx, &cfg_type_netprefix); - cfg_print_chars(pctx, " ", 1); - } - - print_open(pctx); - - for (clauseset = type->of; *clauseset != NULL; clauseset++) { - for (clause = *clauseset; - clause->name != NULL; - clause++) { - print_indent(pctx); - cfg_print_cstr(pctx, clause->name); - if (clause->type->print != cfg_print_void) - cfg_print_chars(pctx, " ", 1); - cfg_doc_obj(pctx, clause->type); - cfg_print_chars(pctx, ";", 1); - print_clause_flags(pctx, clause->flags); - cfg_print_chars(pctx, "\n", 1); - } - } - print_close(pctx); -} - -isc_boolean_t -cfg_obj_ismap(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_map)); -} - -isc_result_t -cfg_map_get(const cfg_obj_t *mapobj, const char* name, const cfg_obj_t **obj) { - isc_result_t result; - isc_symvalue_t val; - const cfg_map_t *map; - - REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map); - REQUIRE(name != NULL); - REQUIRE(obj != NULL && *obj == NULL); - - map = &mapobj->value.map; - - result = isc_symtab_lookup(map->symtab, name, MAP_SYM, &val); - if (result != ISC_R_SUCCESS) - return (result); - *obj = val.as_pointer; - return (ISC_R_SUCCESS); -} - -const cfg_obj_t * -cfg_map_getname(const cfg_obj_t *mapobj) { - REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map); - return (mapobj->value.map.id); -} - - -/* Parse an arbitrary token, storing its raw text representation. */ -static isc_result_t -parse_token(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - cfg_obj_t *obj = NULL; - isc_result_t result; - isc_region_t r; - - UNUSED(type); - - CHECK(cfg_create_obj(pctx, &cfg_type_token, &obj)); - CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING)); - if (pctx->token.type == isc_tokentype_eof) { - cfg_ungettoken(pctx); - result = ISC_R_EOF; - goto cleanup; - } - - isc_lex_getlasttokentext(pctx->lexer, &pctx->token, &r); - - obj->value.string.base = isc_mem_get(pctx->mctx, r.length + 1); - if (obj->value.string.base == NULL) { - result = ISC_R_NOMEMORY; - goto cleanup; - } - obj->value.string.length = r.length; - memcpy(obj->value.string.base, r.base, r.length); - obj->value.string.base[r.length] = '\0'; - *ret = obj; - return (result); - - cleanup: - if (obj != NULL) - isc_mem_put(pctx->mctx, obj, sizeof(*obj)); - return (result); -} - -cfg_type_t cfg_type_token = { - "token", parse_token, cfg_print_ustring, cfg_doc_terminal, - &cfg_rep_string, NULL -}; - -/* - * An unsupported option. This is just a list of tokens with balanced braces - * ending in a semicolon. - */ - -static isc_result_t -parse_unsupported(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - cfg_obj_t *listobj = NULL; - isc_result_t result; - int braces = 0; - - CHECK(cfg_create_list(pctx, type, &listobj)); - - for (;;) { - cfg_listelt_t *elt = NULL; - - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_special) { - if (pctx->token.value.as_char == '{') - braces++; - else if (pctx->token.value.as_char == '}') - braces--; - else if (pctx->token.value.as_char == ';') - if (braces == 0) - break; - } - if (pctx->token.type == isc_tokentype_eof || braces < 0) { - cfg_parser_error(pctx, CFG_LOG_NEAR, "unexpected token"); - result = ISC_R_UNEXPECTEDTOKEN; - goto cleanup; - } - - CHECK(cfg_parse_listelt(pctx, &cfg_type_token, &elt)); - ISC_LIST_APPEND(listobj->value.list, elt, link); - } - INSIST(braces == 0); - *ret = listobj; - return (ISC_R_SUCCESS); - - cleanup: - CLEANUP_OBJ(listobj); - return (result); -} - -cfg_type_t cfg_type_unsupported = { - "unsupported", parse_unsupported, cfg_print_spacelist, cfg_doc_terminal, - &cfg_rep_list, NULL -}; - -/* - * Try interpreting the current token as a network address. - * - * If CFG_ADDR_WILDOK is set in flags, "*" can be used as a wildcard - * and at least one of CFG_ADDR_V4OK and CFG_ADDR_V6OK must also be set. The - * "*" is interpreted as the IPv4 wildcard address if CFG_ADDR_V4OK is - * set (including the case where CFG_ADDR_V4OK and CFG_ADDR_V6OK are both set), - * and the IPv6 wildcard address otherwise. - */ -static isc_result_t -token_addr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) { - char *s; - struct in_addr in4a; - struct in6_addr in6a; - - if (pctx->token.type != isc_tokentype_string) - return (ISC_R_UNEXPECTEDTOKEN); - - s = TOKEN_STRING(pctx); - if ((flags & CFG_ADDR_WILDOK) != 0 && strcmp(s, "*") == 0) { - if ((flags & CFG_ADDR_V4OK) != 0) { - isc_netaddr_any(na); - return (ISC_R_SUCCESS); - } else if ((flags & CFG_ADDR_V6OK) != 0) { - isc_netaddr_any6(na); - return (ISC_R_SUCCESS); - } else { - INSIST(0); - } - } else { - if ((flags & (CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK)) != 0) { - if (inet_pton(AF_INET, s, &in4a) == 1) { - isc_netaddr_fromin(na, &in4a); - return (ISC_R_SUCCESS); - } - } - if ((flags & CFG_ADDR_V4PREFIXOK) != 0 && - strlen(s) <= 15U) { - char buf[64]; - int i; - - strcpy(buf, s); - for (i = 0; i < 3; i++) { - strcat(buf, ".0"); - if (inet_pton(AF_INET, buf, &in4a) == 1) { - isc_netaddr_fromin(na, &in4a); - return (ISC_R_SUCCESS); - } - } - } - if ((flags & CFG_ADDR_V6OK) != 0 && - strlen(s) <= 127U) { - char buf[128]; /* see lib/bind9/getaddresses.c */ - char *d; /* zone delimiter */ - isc_uint32_t zone = 0; /* scope zone ID */ - - strcpy(buf, s); - d = strchr(buf, '%'); - if (d != NULL) - *d = '\0'; - - if (inet_pton(AF_INET6, buf, &in6a) == 1) { - if (d != NULL) { -#ifdef ISC_PLATFORM_HAVESCOPEID - isc_result_t result; - - result = isc_netscope_pton(AF_INET6, - d + 1, - &in6a, - &zone); - if (result != ISC_R_SUCCESS) - return (result); -#else - return (ISC_R_BADADDRESSFORM); -#endif - } - - isc_netaddr_fromin6(na, &in6a); - isc_netaddr_setzone(na, zone); - return (ISC_R_SUCCESS); - } - } - } - return (ISC_R_UNEXPECTEDTOKEN); -} - -isc_result_t -cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) { - isc_result_t result; - const char *wild = ""; - const char *prefix = ""; - - CHECK(cfg_gettoken(pctx, 0)); - result = token_addr(pctx, flags, na); - if (result == ISC_R_UNEXPECTEDTOKEN) { - if ((flags & CFG_ADDR_WILDOK) != 0) - wild = " or '*'"; - if ((flags & CFG_ADDR_V4PREFIXOK) != 0) - wild = " or IPv4 prefix"; - if ((flags & CFG_ADDR_MASK) == CFG_ADDR_V4OK) - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected IPv4 address%s%s", - prefix, wild); - else if ((flags & CFG_ADDR_MASK) == CFG_ADDR_V6OK) - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected IPv6 address%s%s", - prefix, wild); - else - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected IP address%s%s", - prefix, wild); - } - cleanup: - return (result); -} - -isc_boolean_t -cfg_lookingat_netaddr(cfg_parser_t *pctx, unsigned int flags) { - isc_result_t result; - isc_netaddr_t na_dummy; - result = token_addr(pctx, flags, &na_dummy); - return (ISC_TF(result == ISC_R_SUCCESS)); -} - -isc_result_t -cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port) { - isc_result_t result; - - CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER)); - - if ((flags & CFG_ADDR_WILDOK) != 0 && - pctx->token.type == isc_tokentype_string && - strcmp(TOKEN_STRING(pctx), "*") == 0) { - *port = 0; - return (ISC_R_SUCCESS); - } - if (pctx->token.type != isc_tokentype_number) { - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected port number or '*'"); - return (ISC_R_UNEXPECTEDTOKEN); - } - if (pctx->token.value.as_ulong >= 65536U) { - cfg_parser_error(pctx, CFG_LOG_NEAR, - "port number out of range"); - return (ISC_R_UNEXPECTEDTOKEN); - } - *port = (in_port_t)(pctx->token.value.as_ulong); - return (ISC_R_SUCCESS); - cleanup: - return (result); -} - -void -cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na) { - isc_result_t result; - char text[128]; - isc_buffer_t buf; - - isc_buffer_init(&buf, text, sizeof(text)); - result = isc_netaddr_totext(na, &buf); - RUNTIME_CHECK(result == ISC_R_SUCCESS); - cfg_print_chars(pctx, isc_buffer_base(&buf), isc_buffer_usedlength(&buf)); -} - -/* netaddr */ - -static unsigned int netaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK; -static unsigned int netaddr4_flags = CFG_ADDR_V4OK; -static unsigned int netaddr4wild_flags = CFG_ADDR_V4OK | CFG_ADDR_WILDOK; -static unsigned int netaddr6_flags = CFG_ADDR_V6OK; -static unsigned int netaddr6wild_flags = CFG_ADDR_V6OK | CFG_ADDR_WILDOK; - -static isc_result_t -parse_netaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - cfg_obj_t *obj = NULL; - isc_netaddr_t netaddr; - unsigned int flags = *(const unsigned int *)type->of; - - CHECK(cfg_create_obj(pctx, type, &obj)); - CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr)); - isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, 0); - *ret = obj; - return (ISC_R_SUCCESS); - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -static void -cfg_doc_netaddr(cfg_printer_t *pctx, const cfg_type_t *type) { - const unsigned int *flagp = type->of; - int n = 0; - if (*flagp != CFG_ADDR_V4OK && *flagp != CFG_ADDR_V6OK) - cfg_print_chars(pctx, "( ", 2); - if (*flagp & CFG_ADDR_V4OK) { - cfg_print_cstr(pctx, "<ipv4_address>"); - n++; - } - if (*flagp & CFG_ADDR_V6OK) { - if (n != 0) - cfg_print_chars(pctx, " | ", 3); - cfg_print_cstr(pctx, "<ipv6_address>"); - n++; - } - if (*flagp & CFG_ADDR_WILDOK) { - if (n != 0) - cfg_print_chars(pctx, " | ", 3); - cfg_print_chars(pctx, "*", 1); - n++; - } - if (*flagp != CFG_ADDR_V4OK && *flagp != CFG_ADDR_V6OK) - cfg_print_chars(pctx, " )", 2); -} - -cfg_type_t cfg_type_netaddr = { - "netaddr", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, - &cfg_rep_sockaddr, &netaddr_flags -}; - -cfg_type_t cfg_type_netaddr4 = { - "netaddr4", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, - &cfg_rep_sockaddr, &netaddr4_flags -}; - -cfg_type_t cfg_type_netaddr4wild = { - "netaddr4wild", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, - &cfg_rep_sockaddr, &netaddr4wild_flags -}; - -cfg_type_t cfg_type_netaddr6 = { - "netaddr6", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, - &cfg_rep_sockaddr, &netaddr6_flags -}; - -cfg_type_t cfg_type_netaddr6wild = { - "netaddr6wild", parse_netaddr, cfg_print_sockaddr, cfg_doc_netaddr, - &cfg_rep_sockaddr, &netaddr6wild_flags -}; - -/* netprefix */ - -isc_result_t -cfg_parse_netprefix(cfg_parser_t *pctx, const cfg_type_t *type, - cfg_obj_t **ret) -{ - cfg_obj_t *obj = NULL; - isc_result_t result; - isc_netaddr_t netaddr; - unsigned int addrlen, prefixlen; - UNUSED(type); - - CHECK(cfg_parse_rawaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK | - CFG_ADDR_V6OK, &netaddr)); - switch (netaddr.family) { - case AF_INET: - addrlen = 32; - break; - case AF_INET6: - addrlen = 128; - break; - default: - addrlen = 0; - INSIST(0); - break; - } - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_special && - pctx->token.value.as_char == '/') { - CHECK(cfg_gettoken(pctx, 0)); /* read "/" */ - CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER)); - if (pctx->token.type != isc_tokentype_number) { - cfg_parser_error(pctx, CFG_LOG_NEAR, - "expected prefix length"); - return (ISC_R_UNEXPECTEDTOKEN); - } - prefixlen = pctx->token.value.as_ulong; - if (prefixlen > addrlen) { - cfg_parser_error(pctx, CFG_LOG_NOPREP, - "invalid prefix length"); - return (ISC_R_RANGE); - } - } else { - prefixlen = addrlen; - } - CHECK(cfg_create_obj(pctx, &cfg_type_netprefix, &obj)); - obj->value.netprefix.address = netaddr; - obj->value.netprefix.prefixlen = prefixlen; - *ret = obj; - return (ISC_R_SUCCESS); - cleanup: - cfg_parser_error(pctx, CFG_LOG_NEAR, "expected network prefix"); - return (result); -} - -static void -print_netprefix(cfg_printer_t *pctx, const cfg_obj_t *obj) { - const cfg_netprefix_t *p = &obj->value.netprefix; - - cfg_print_rawaddr(pctx, &p->address); - cfg_print_chars(pctx, "/", 1); - cfg_print_rawuint(pctx, p->prefixlen); -} - -isc_boolean_t -cfg_obj_isnetprefix(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_netprefix)); -} - -void -cfg_obj_asnetprefix(const cfg_obj_t *obj, isc_netaddr_t *netaddr, - unsigned int *prefixlen) { - REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_netprefix); - *netaddr = obj->value.netprefix.address; - *prefixlen = obj->value.netprefix.prefixlen; -} - -cfg_type_t cfg_type_netprefix = { - "netprefix", cfg_parse_netprefix, print_netprefix, cfg_doc_terminal, - &cfg_rep_netprefix, NULL -}; - -static isc_result_t -parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, - int flags, cfg_obj_t **ret) -{ - isc_result_t result; - isc_netaddr_t netaddr; - in_port_t port = 0; - cfg_obj_t *obj = NULL; - - CHECK(cfg_create_obj(pctx, type, &obj)); - CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr)); - CHECK(cfg_peektoken(pctx, 0)); - if (pctx->token.type == isc_tokentype_string && - strcasecmp(TOKEN_STRING(pctx), "port") == 0) { - CHECK(cfg_gettoken(pctx, 0)); /* read "port" */ - CHECK(cfg_parse_rawport(pctx, flags, &port)); - } - isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port); - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - CLEANUP_OBJ(obj); - return (result); -} - -static unsigned int sockaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK; -cfg_type_t cfg_type_sockaddr = { - "sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, - &cfg_rep_sockaddr, &sockaddr_flags -}; - -isc_result_t -cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - const unsigned int *flagp = type->of; - return (parse_sockaddrsub(pctx, &cfg_type_sockaddr, *flagp, ret)); -} - -void -cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj) { - isc_netaddr_t netaddr; - in_port_t port; - char buf[ISC_NETADDR_FORMATSIZE]; - - isc_netaddr_fromsockaddr(&netaddr, &obj->value.sockaddr); - isc_netaddr_format(&netaddr, buf, sizeof(buf)); - cfg_print_cstr(pctx, buf); - port = isc_sockaddr_getport(&obj->value.sockaddr); - if (port != 0) { - cfg_print_chars(pctx, " port ", 6); - cfg_print_rawuint(pctx, port); - } -} - -void -cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type) { - const unsigned int *flagp = type->of; - int n = 0; - cfg_print_chars(pctx, "( ", 2); - if (*flagp & CFG_ADDR_V4OK) { - cfg_print_cstr(pctx, "<ipv4_address>"); - n++; - } - if (*flagp & CFG_ADDR_V6OK) { - if (n != 0) - cfg_print_chars(pctx, " | ", 3); - cfg_print_cstr(pctx, "<ipv6_address>"); - n++; - } - if (*flagp & CFG_ADDR_WILDOK) { - if (n != 0) - cfg_print_chars(pctx, " | ", 3); - cfg_print_chars(pctx, "*", 1); - n++; - } - cfg_print_chars(pctx, " ) ", 3); - if (*flagp & CFG_ADDR_WILDOK) { - cfg_print_cstr(pctx, "[ port ( <integer> | * ) ]"); - } else { - cfg_print_cstr(pctx, "[ port <integer> ]"); - } -} - -isc_boolean_t -cfg_obj_issockaddr(const cfg_obj_t *obj) { - REQUIRE(obj != NULL); - return (ISC_TF(obj->type->rep == &cfg_rep_sockaddr)); -} - -const isc_sockaddr_t * -cfg_obj_assockaddr(const cfg_obj_t *obj) { - REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_sockaddr); - return (&obj->value.sockaddr); -} - -isc_result_t -cfg_gettoken(cfg_parser_t *pctx, int options) { - isc_result_t result; - - if (pctx->seen_eof) - return (ISC_R_SUCCESS); - - options |= (ISC_LEXOPT_EOF | ISC_LEXOPT_NOMORE); - - redo: - pctx->token.type = isc_tokentype_unknown; - result = isc_lex_gettoken(pctx->lexer, options, &pctx->token); - pctx->ungotten = ISC_FALSE; - pctx->line = isc_lex_getsourceline(pctx->lexer); - - switch (result) { - case ISC_R_SUCCESS: - if (pctx->token.type == isc_tokentype_eof) { - result = isc_lex_close(pctx->lexer); - INSIST(result == ISC_R_NOMORE || - result == ISC_R_SUCCESS); - - if (isc_lex_getsourcename(pctx->lexer) != NULL) { - /* - * Closed an included file, not the main file. - */ - cfg_listelt_t *elt; - elt = ISC_LIST_TAIL(pctx->open_files-> - value.list); - INSIST(elt != NULL); - ISC_LIST_UNLINK(pctx->open_files-> - value.list, elt, link); - ISC_LIST_APPEND(pctx->closed_files-> - value.list, elt, link); - goto redo; - } - pctx->seen_eof = ISC_TRUE; - } - break; - - case ISC_R_NOSPACE: - /* More understandable than "ran out of space". */ - cfg_parser_error(pctx, CFG_LOG_NEAR, "token too big"); - break; - - case ISC_R_IOERROR: - cfg_parser_error(pctx, 0, "%s", - isc_result_totext(result)); - break; - - default: - cfg_parser_error(pctx, CFG_LOG_NEAR, "%s", - isc_result_totext(result)); - break; - } - return (result); -} - -void -cfg_ungettoken(cfg_parser_t *pctx) { - if (pctx->seen_eof) - return; - isc_lex_ungettoken(pctx->lexer, &pctx->token); - pctx->ungotten = ISC_TRUE; -} - -isc_result_t -cfg_peektoken(cfg_parser_t *pctx, int options) { - isc_result_t result; - CHECK(cfg_gettoken(pctx, options)); - cfg_ungettoken(pctx); - cleanup: - return (result); -} - -/* - * Get a string token, accepting both the quoted and the unquoted form. - * Log an error if the next token is not a string. - */ -static isc_result_t -cfg_getstringtoken(cfg_parser_t *pctx) { - isc_result_t result; - - result = cfg_gettoken(pctx, CFG_LEXOPT_QSTRING); - if (result != ISC_R_SUCCESS) - return (result); - - if (pctx->token.type != isc_tokentype_string && - pctx->token.type != isc_tokentype_qstring) { - cfg_parser_error(pctx, CFG_LOG_NEAR, "expected string"); - return (ISC_R_UNEXPECTEDTOKEN); - } - return (ISC_R_SUCCESS); -} - -void -cfg_parser_error(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...) { - va_list args; - va_start(args, fmt); - parser_complain(pctx, ISC_FALSE, flags, fmt, args); - va_end(args); - pctx->errors++; -} - -void -cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...) { - va_list args; - va_start(args, fmt); - parser_complain(pctx, ISC_TRUE, flags, fmt, args); - va_end(args); - pctx->warnings++; -} - -#define MAX_LOG_TOKEN 30 /* How much of a token to quote in log messages. */ - -static char * -current_file(cfg_parser_t *pctx) { - static char none[] = "none"; - cfg_listelt_t *elt; - cfg_obj_t *fileobj; - - if (pctx->open_files == NULL) - return (none); - elt = ISC_LIST_TAIL(pctx->open_files->value.list); - if (elt == NULL) - return (none); - - fileobj = elt->obj; - INSIST(fileobj->type == &cfg_type_qstring); - return (fileobj->value.string.base); -} - -static void -parser_complain(cfg_parser_t *pctx, isc_boolean_t is_warning, - unsigned int flags, const char *format, - va_list args) -{ - char tokenbuf[MAX_LOG_TOKEN + 10]; - static char where[ISC_DIR_PATHMAX + 100]; - static char message[2048]; - int level = ISC_LOG_ERROR; - const char *prep = ""; - size_t len; - - if (is_warning) - level = ISC_LOG_WARNING; - - snprintf(where, sizeof(where), "%s:%u: ", - current_file(pctx), pctx->line); - - len = vsnprintf(message, sizeof(message), format, args); - if (len >= sizeof(message)) - FATAL_ERROR(__FILE__, __LINE__, - "error message would overflow"); - - if ((flags & (CFG_LOG_NEAR|CFG_LOG_BEFORE|CFG_LOG_NOPREP)) != 0) { - isc_region_t r; - - if (pctx->ungotten) - (void)cfg_gettoken(pctx, 0); - - if (pctx->token.type == isc_tokentype_eof) { - snprintf(tokenbuf, sizeof(tokenbuf), "end of file"); - } else if (pctx->token.type == isc_tokentype_unknown) { - flags = 0; - tokenbuf[0] = '\0'; - } else { - isc_lex_getlasttokentext(pctx->lexer, - &pctx->token, &r); - if (r.length > MAX_LOG_TOKEN) - snprintf(tokenbuf, sizeof(tokenbuf), - "'%.*s...'", MAX_LOG_TOKEN, r.base); - else - snprintf(tokenbuf, sizeof(tokenbuf), - "'%.*s'", (int)r.length, r.base); - } - - /* Choose a preposition. */ - if (flags & CFG_LOG_NEAR) - prep = " near "; - else if (flags & CFG_LOG_BEFORE) - prep = " before "; - else - prep = " "; - } else { - tokenbuf[0] = '\0'; - } - isc_log_write(pctx->lctx, CAT, MOD, level, - "%s%s%s%s", where, message, prep, tokenbuf); -} - -void -cfg_obj_log(const cfg_obj_t *obj, isc_log_t *lctx, int level, - const char *fmt, ...) { - va_list ap; - char msgbuf[2048]; - - if (! isc_log_wouldlog(lctx, level)) - return; - - va_start(ap, fmt); - - vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); - isc_log_write(lctx, CAT, MOD, level, - "%s:%u: %s", - obj->file == NULL ? "<unknown file>" : obj->file, - obj->line, msgbuf); - va_end(ap); -} - -const char * -cfg_obj_file(const cfg_obj_t *obj) { - return (obj->file); -} - -unsigned int -cfg_obj_line(const cfg_obj_t *obj) { - return (obj->line); -} - -isc_result_t -cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - cfg_obj_t *obj; - - obj = isc_mem_get(pctx->mctx, sizeof(cfg_obj_t)); - if (obj == NULL) - return (ISC_R_NOMEMORY); - obj->type = type; - obj->file = current_file(pctx); - obj->line = pctx->line; - *ret = obj; - return (ISC_R_SUCCESS); -} - -static void -map_symtabitem_destroy(char *key, unsigned int type, - isc_symvalue_t symval, void *userarg) -{ - cfg_obj_t *obj = symval.as_pointer; - cfg_parser_t *pctx = (cfg_parser_t *)userarg; - - UNUSED(key); - UNUSED(type); - - cfg_obj_destroy(pctx, &obj); -} - - -static isc_result_t -create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { - isc_result_t result; - isc_symtab_t *symtab = NULL; - cfg_obj_t *obj = NULL; - - CHECK(cfg_create_obj(pctx, type, &obj)); - CHECK(isc_symtab_create(pctx->mctx, 5, /* XXX */ - map_symtabitem_destroy, - pctx, ISC_FALSE, &symtab)); - obj->value.map.symtab = symtab; - obj->value.map.id = NULL; - - *ret = obj; - return (ISC_R_SUCCESS); - - cleanup: - if (obj != NULL) - isc_mem_put(pctx->mctx, obj, sizeof(*obj)); - return (result); -} - -static void -free_map(cfg_parser_t *pctx, cfg_obj_t *obj) { - CLEANUP_OBJ(obj->value.map.id); - isc_symtab_destroy(&obj->value.map.symtab); -} - -isc_boolean_t -cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) { - return (ISC_TF(obj->type == type)); -} - -/* - * Destroy 'obj', a configuration object created in 'pctx'. - */ -void -cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) { - cfg_obj_t *obj = *objp; - obj->type->rep->free(pctx, obj); - isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t)); - *objp = NULL; -} - -static void -free_noop(cfg_parser_t *pctx, cfg_obj_t *obj) { - UNUSED(pctx); - UNUSED(obj); -} - -void -cfg_doc_obj(cfg_printer_t *pctx, const cfg_type_t *type) { - type->doc(pctx, type); -} - -void -cfg_doc_terminal(cfg_printer_t *pctx, const cfg_type_t *type) { - cfg_print_chars(pctx, "<", 1); - cfg_print_cstr(pctx, type->name); - cfg_print_chars(pctx, ">", 1); -} - -void -cfg_print_grammar(const cfg_type_t *type, - void (*f)(void *closure, const char *text, int textlen), - void *closure) -{ - cfg_printer_t pctx; - pctx.f = f; - pctx.closure = closure; - pctx.indent = 0; - cfg_doc_obj(&pctx, type); -} diff --git a/contrib/bind9/lib/isccfg/version.c b/contrib/bind9/lib/isccfg/version.c deleted file mode 100644 index 0b7287b..0000000 --- a/contrib/bind9/lib/isccfg/version.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1998-2001 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: version.c,v 1.3.18.2 2005/04/29 00:17:15 marka Exp $ */ - -/*! \file */ - -#include <isccfg/version.h> - -const char cfg_version[] = VERSION; - -const unsigned int cfg_libinterface = LIBINTERFACE; -const unsigned int cfg_librevision = LIBREVISION; -const unsigned int cfg_libage = LIBAGE; - |