Commit 528b2232 authored by Daniel Salzman's avatar Daniel Salzman

Remove flex/bison based configuration

parent d822f302
......@@ -56,9 +56,6 @@
/m4/ltsugar.m4
/m4/ltversion.m4
/m4/lt~obsolete.m4
/src/knot/conf/libknotd_la-cf-lex.c
/src/knot/conf/libknotd_la-cf-parse.c
/src/knot/conf/libknotd_la-cf-parse.h
/src/dnssec/libdnssec.pc
/src/libknot-int.pc
/src/libknot.pc
......
......@@ -4,11 +4,11 @@ compiler:
before_install:
- sudo add-apt-repository --yes ppa:cz.nic-labs/knot-dns
- sudo apt-get update -qq
- sudo apt-get install -qq autotools-dev autoconf automake libtool libssl-dev liburcu-dev flex bison ragel pkg-config texinfo texlive lcov liblmdb-dev
- sudo apt-get install -qq autotools-dev autoconf automake libtool libssl-dev liburcu-dev pkg-config texinfo texlive lcov liblmdb-dev
- sudo pip install cpp-coveralls --use-mirrors
before_script:
- autoreconf -fi
script:
- ./configure --disable-fastparser --disable-shared --enable-static --enable-code-coverage && make && make -k check
after_success:
- coveralls --exclude tests/ --exclude src/cf-lex.l --exclude src/cf-parse.y --exclude ./src/utils/ --exclude ./src/libtap --exclude ./src/zscanner --build-root ./src/
- coveralls --exclude tests/ --exclude ./src/utils/ --exclude ./src/libtap --exclude ./src/zscanner --build-root ./src/
......@@ -57,14 +57,12 @@ endif
code-coverage-html:
if CODE_COVERAGE_ENABLED
@echo "Generating code coverage HTML report (this might take a while)"
@cp src/knot/conf/cf-lex.l src/knot/conf/cf-parse.y src/
LANG=C $(GENHTML) $(code_coverage_quiet) \
--output-directory $(CODE_COVERAGE_HTML) \
--title "Knot DNS $(PACKAGE_VERSION) Code Coverage" \
--legend --show-details \
--ignore-errors source \
$(CODE_COVERAGE_INFO)
-@rm src/cf-lex.l src/cf-parse.y
else
@echo "You need to run configure with --enable-code-coverage to enable code coverage"
endif
......
......@@ -4,8 +4,6 @@ Dependencies
Knot DNS has several dependencies:
* libtool
* autoconf > 2.65
* flex >= 2.5.31
* bison >= 2.3
* liburcu >= 0.5.4
* gnutls >= 3.0
* jansson >= 2.3
......@@ -41,7 +39,7 @@ $ sudo apt-get upgrade
Install prerequisites:
$ sudo apt-get install \
libtool autoconf flex bison liburcu-dev libgnutls28-dev libjansson-dev
libtool autoconf liburcu-dev libgnutls28-dev libjansson-dev
Install optional packages to override embedded libraries:
$ sudo apt-get install liblmdb-dev
......@@ -59,7 +57,7 @@ Install basic development tools:
Install prerequisites:
# yum install \
libtool autoconf flex bison userspace-rcu-devel gnutls-devel jansson-devel
libtool autoconf userspace-rcu-devel gnutls-devel jansson-devel
Install optional packages to override embedded libraries:
# yum install lmdb-devel
......
......@@ -168,38 +168,6 @@ AC_SUBST(config_dir)
# Dependencies needed for Knot DNS daemon
#########################################
AS_IF([test "$enable_daemon" = "yes"],[
AC_CACHE_CHECK([for reentrant lex], [ac_cv_path_LEX],
[AC_PATH_PROGS_FEATURE_CHECK([LEX], [$LEX flex gflex],
[cat >conftest.l <<_ACEOF
%{
%}
%option reentrant
%option bison-bridge
%option noinput
%option nounput
%option noreject
BLANK [ \t\n]
%%
<<EOF>> return 0;
%%
_ACEOF
_AC_DO_VAR(ac_path_LEX conftest.l)
test $ac_status -eq 0 && ac_cv_path_LEX=$ac_path_LEX ac_path_LEX_found=true
rm -f conftest.l lexyy.c lex.yy.c
],
[AC_MSG_ERROR([could not find lex that supports reentrant parsers])])])
AC_SUBST([LEX], [$ac_cv_path_LEX])
AM_PROG_LEX
AC_PROG_YACC
YACC_BISON=`bison --version | awk '{print $1;exit}'`
AS_IF([test "x$YACC_BISON" != "xbison"],
[AC_MSG_ERROR([GNU bison needed for reentrant parsers, set the \$YACC variable before running configure])])
])
# Systemd integration
......
......@@ -25,8 +25,6 @@ Knot DNS build system relies on these standard tools:
* make
* libtool
* autoconf >= 2.65
* flex >= 2.5.31
* bison >= 2.3
.. _Required libraries:
......
......@@ -7,7 +7,6 @@ lib_LTLIBRARIES = \
libknot-yparser.la
noinst_LTLIBRARIES =
# $(YACC) will generate header file
AM_CPPFLAGS = \
-include $(top_builddir)/src/config.h \
-DCONFIG_DIR='"${config_dir}"' \
......@@ -17,9 +16,6 @@ AM_CPPFLAGS = \
AM_CFLAGS = $(CODE_COVERAGE_CFLAGS)
AM_LDFLAGS = $(CODE_COVERAGE_LDFLAGS)
AM_YFLAGS = -d
libknotd_la_YFLAGS = -pcf_ -d
libknotd_la_LFLAGS = # TODO: reentrant parser, prefix
######################
# Knot DNS Libraries #
......@@ -190,16 +186,6 @@ if HAVE_DAEMON
sbin_PROGRAMS = knotc knotd
noinst_LTLIBRARIES += libknotd.la
BUILT_SOURCES = \
knot/conf/libknotd_la-cf-lex.c \
knot/conf/libknotd_la-cf-parse.c \
knot/conf/libknotd_la-cf-parse.h
CLEANFILES = \
knot/conf/libknotd_la-cf-lex.c \
knot/conf/libknotd_la-cf-parse.c \
knot/conf/libknotd_la-cf-parse.h
knotc_SOURCES = \
knot/ctl/knotc_main.c
......@@ -208,14 +194,6 @@ knotd_SOURCES = \
# static: server shared
libknotd_la_SOURCES = \
knot/conf/cf-lex.l \
knot/conf/cf-parse.y \
knot/conf/conf.c \
knot/conf/conf.h \
knot/conf/extra.c \
knot/conf/extra.h \
knot/conf/includes.c \
knot/conf/includes.h \
knot/ctl/estimator.c \
knot/ctl/estimator.h \
knot/ctl/process.c \
......
......@@ -43,8 +43,6 @@
#include "libknot/dname.h"
struct conf;
/*! \brief Log facility types. */
typedef enum {
LOGT_SYSLOG = 0, /*!< Logging to syslog(3) facility. */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include "knot/conf/includes.h"
#include "knot/conf/extra.h"
/*!
* \brief Init structure with custom data for config parser.
*/
conf_extra_t *conf_extra_init(const char *file)
{
conf_extra_t *extra = calloc(1, sizeof(conf_extra_t));
if (!extra) {
return NULL;
}
conf_includes_t *includes = conf_includes_init();
if (!includes) {
free(extra);
return NULL;
}
if (!conf_includes_push(includes, file)) {
conf_includes_free(includes);
free(extra);
return NULL;
}
extra->error = false;
extra->includes = includes;
return extra;
}
/*!
* \brief Free structure with custom data for config parser.
*/
void conf_extra_free(conf_extra_t *extra)
{
if (!extra)
return;
conf_includes_free(extra->includes);
free(extra);
}
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file extra.h
*
* \author Jan Vcelak <jan.vcelak@nic.cz>
*
* \brief API for managing custom data in the configuration parser.
*
* \addtogroup config
* @{
*/
#pragma once
#include <stdbool.h>
#include "knot/conf/includes.h"
/*!
* \brief Custom data held within the parser context.
*/
typedef struct {
bool error; //!< Indicates that error was set.
conf_includes_t *includes; //!< Used to handle filenames in includes.
} conf_extra_t;
/*!
* \brief Init structure with custom data for config parser.
*
* \param file Name of the main configuration file.
*
* \return Initialized stucture or NULL.
*/
conf_extra_t *conf_extra_init(const char *file);
/*!
* \brief Free structure with custom data for config parser.
*
* \param extra Structure to be freed.
*/
void conf_extra_free(conf_extra_t *extra);
/*! @} */
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "knot/conf/includes.h"
#define INCLUDES_CAPACITY_BLOCK 128 // Size of included files block.
/*!
* \brief Structure to store names of files included into the config.
*/
struct conf_includes {
int free_index; //!< First free index in 'names'.
int capacity; //!< Maximal capacity.
conf_include_t *files; //!< Stored includes.
};
/*!
* \brief Initialize structure for storing names of included files.
*/
conf_includes_t *conf_includes_init()
{
conf_includes_t *includes = calloc(1, sizeof(conf_includes_t));
if (!includes) {
return NULL;
}
conf_include_t *files = calloc(INCLUDES_CAPACITY_BLOCK,
sizeof(conf_include_t));
if (!files) {
free(includes);
return NULL;
}
includes->capacity = INCLUDES_CAPACITY_BLOCK;
includes->files = files;
return includes;
}
/*!
* \brief Free structure for storing the names of included files.
*/
void conf_includes_free(conf_includes_t *includes)
{
if (!includes) {
return;
}
while (conf_includes_remove(includes));
free(includes->files);
free(includes);
}
/**
* \brief Constructs a path relative to a reference file.
*
* e.g. path_relative_to("b.conf", "samples/a.conf") == "samples/b.conf"
*
* \param filename File name of the target file.
* \param reference Referece file name (just path is used).
*
* \return Relative path to a reference file.
*/
static char *path_relative_to(const char *filename, const char *reference)
{
char *path_end = strrchr(reference, '/');
if (!path_end) {
return strdup(filename);
}
int path_len = (int)(path_end - reference);
size_t result_len = path_len + 1 + strlen(filename) + 1;
char *result = malloc(result_len * sizeof(char));
if (!result) {
return NULL;
}
int w;
w = snprintf(result, result_len, "%.*s/%s", path_len, reference, filename);
assert(w + 1 == (int)result_len);
return result;
}
/**
* \brief Pushes a file name onto the stack of files.
*/
bool conf_includes_push(conf_includes_t *includes, const char *filename)
{
if (!includes || !filename) {
return false;
}
char *store = NULL;
if (includes->free_index == 0 || filename[0] == '/') {
store = strdup(filename);
} else {
conf_include_t *previous = &includes->files[includes->free_index - 1];
store = path_relative_to(filename, previous->filename);
}
for (int i = 0; i < includes->free_index; i++) {
// Check for include loop.
if (strcmp(includes->files[i].filename, store) == 0) {
free(store);
return false;
}
}
// Extend the stack if full.
if (includes->free_index >= includes->capacity) {
size_t new_size = (includes->capacity + INCLUDES_CAPACITY_BLOCK) *
sizeof(conf_include_t);
conf_include_t *new_files = realloc(includes->files, new_size);
if (new_files == NULL) {
free(store);
return false;
}
includes->capacity = new_size;
includes->files = new_files;
}
conf_include_t new_include = {
.filename = store,
.handle = NULL
};
includes->files[includes->free_index++] = new_include;
return store != NULL;
}
/**
* \brief Returns an include on the top of the stack.
*/
conf_include_t *conf_includes_top(conf_includes_t *includes)
{
if (!includes || includes->free_index == 0) {
return NULL;
}
return includes->files + includes->free_index - 1;
}
/**
* \brief Returns an include on the top of the stack and removes it.
*/
conf_include_t *conf_includes_pop(conf_includes_t *includes)
{
conf_include_t *result = conf_includes_top(includes);
if (result) {
includes->free_index -= 1;
}
return result;
}
/**
* \brief Returns an include on the top of the stack and removes it.
*/
bool conf_includes_remove(conf_includes_t *includes)
{
conf_include_t *top = conf_includes_pop(includes);
if (top) {
if (top->filename) {
free(top->filename);
top->filename = NULL;
}
if (top->handle) {
fclose(top->handle);
top->handle = NULL;
}
return true;
}
return false;
}
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*!
* \file includes.h
*
* \author Jan Vcelak <jan.vcelak@nic.cz>
*
* \brief Handing of includes in configuration file.
*
* \addtogroup config
* @{
*/
#pragma once
#include <stdbool.h>
#include <stdio.h>
/*!
* \brief Structure to hold data for one include in configuration file.
*/
typedef struct {
char *filename;
FILE *handle;
} conf_include_t;
/*!
* \brief Structure to keep config file includes stack.
*/
struct conf_includes;
typedef struct conf_includes conf_includes_t;
/*!
* \brief Initialize structure for storing names of included files.
*/
conf_includes_t *conf_includes_init();
/*!
* \brief Free structure for storing the names of included files.
*/
void conf_includes_free(conf_includes_t *includes);
/**
* \brief Pushes a file name onto the stack of files.
*
* If the file name is not absolute (or first inserted), the name is changed
* to be relative to previously inserted file name.
*
* \param filename File name to be stored (and processed). It is copied.
*
* \return Success.
*/
bool conf_includes_push(conf_includes_t *includes, const char *filename);
/**
* \brief Returns an include on the top of the stack.
*
* \return File name on the top of the stack. Do not free it.
*/
conf_include_t *conf_includes_top(conf_includes_t *includes);
/**
* \brief Returns an include on the top of the stack and removes it.
*
* \return File name on the top of the stack. Caller should free the result.
*/
conf_include_t *conf_includes_pop(conf_includes_t *includes);
/**
* \brief Remove the include on the top.
*
* \return True if the include was removed.
*/
bool conf_includes_remove(conf_includes_t *includes);
/*! @} */
Makefile
Makefile.in
sample_conf.c
runtests.log
# Test binaries:
......@@ -8,7 +7,6 @@ acl
base32hex
base64
changeset
conf
descriptor
dname
dnssec_keys
......
......@@ -19,7 +19,6 @@ check_PROGRAMS = \
base64 \
changeset \
changeset \
conf \
descriptor \
dname \
dthreads \
......@@ -65,13 +64,6 @@ check-local: $(check_PROGRAMS)
-L $(top_builddir)/tests/runtests.log \
$(check_PROGRAMS)
EXTRA_DIST = data
dist_check_SCRIPTS = resource.sh
conf_SOURCES = conf.c sample_conf.h
process_query_SOURCES = process_query.c fake_server.h
process_answer_SOURCES = process_answer.c fake_server.h
nodist_conf_SOURCES = sample_conf.c
CLEANFILES = sample_conf.c runtests.log
sample_conf.c: data/sample_conf
$(abs_srcdir)/resource.sh $(abs_srcdir)/data/sample_conf >$@
CLEANFILES = runtests.log
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <tap/basic.h>
#include "knot/conf/conf.h"
/* Resources. */
#include "sample_conf.h"
/*! Run all scheduled tests for given parameters.
*/
int main(int argc, char *argv[])
{
plan(19);
// Test 1: Allocate new config
const char *config_fn = "rc:/sample_conf";
conf_t *conf = conf_new(strdup(config_fn));
ok(conf != 0, "config_new()");
// Test 2: Parse config
int ret = conf_parse_str(conf, sample_conf_rc);
is_int(0, ret, "parsing configuration file %s", config_fn);
if (ret != 0) {
skip_block(19, "Parse err");
goto skip_all;
}
// Test 3: Test server version (0-level depth)
is_string("Infinitesimal", conf->version, "server version loaded ok");
// Test 4: Test interfaces (1-level depth)
ok(!EMPTY_LIST(conf->ifaces), "configured interfaces exist");
// Test 5,6: Interfaces content (2-level depth)
struct node *n = HEAD(conf->ifaces);
conf_iface_t *iface = (conf_iface_t*)n;
struct sockaddr_storage addr_ref;
sockaddr_set(&addr_ref, AF_INET, "10.10.1.1", 53531);
is_int(0, sockaddr_cmp(&iface->addr, &addr_ref), "interface0 address check");
n = n->next;
iface = (conf_iface_t*)n;
sockaddr_set(&addr_ref, AF_INET6, "::0", 53);
is_int(0, sockaddr_cmp(&iface->addr, &addr_ref), "interface1 address check");
// Test 9,10: Check server key
if (EMPTY_LIST(conf->keys)) {
ok(0, "TSIG key algorithm check - NO KEY FOUND");
ok(0, "TSIG key secret check - NO KEY FOUND");
} else {
knot_tsig_key_t *k = &((conf_key_t *)HEAD(conf->keys))->k;
uint8_t decoded_secret[] = { 0x5a };
ok(k->algorithm == DNSSEC_TSIG_HMAC_MD5,
"TSIG key algorithm check");
ok(k->secret.size == sizeof(decoded_secret)
&& memcmp(k->secret.data, decoded_secret,
sizeof(decoded_secret)) == 0,
"TSIG key secret check");
}
// Test 11,12,13,14,15,16,17,18: Check logging facilities
ok(list_size(&conf->logs) == 4, "log facilites count check");
n = HEAD(conf->logs);
ok(!EMPTY_LIST(conf->logs), "log facilities not empty");
conf_log_t *log = (conf_log_t*)n;
node_t *nm = HEAD(log->map);
conf_log_map_t *m = (conf_log_map_t*)nm;
ok(log->type == LOGT_SYSLOG, "log0 is syslog");
if (EMPTY_LIST(log->map)) {
skip_block(5, "Empty list");
} else {
ok(m->source == LOG_ANY, "syslog first rule is ANY");
int mask = LOG_UPTO(LOG_NOTICE);
ok(m->prios == mask, "syslog mask is equal");
nm = nm->next;
m = (conf_log_map_t*)nm;
ok(m != 0, "syslog has more than 1 rule");
if (m == 0) {
skip_block(2, "No mapping");
} else {
ok(m->source == LOG_ZONE, "syslog next rule is for zone");
ok(m->prios == LOG_UPTO(LOG_INFO), "rule for zone is: info level");
}
}
// Test 19,20: File facility checks
n = n->next;
log = (conf_log_t*)n;
ok(n != 0, "log has next facility");
if (n == 0) {
skip("No mapping");
} else {
is_string("/var/log/knot/server.err", log->file, "log file matches");
}
// Test 21: Load key dname
const char *sample_str = "key0.example.net";
knot_dname_t *sample = knot_dname_from_str_alloc(sample_str);
if (list_size(&conf->keys) > 0) {
knot_tsig_key_t *k = &((conf_key_t *)HEAD(conf->keys))->k;
ok(knot_dname_cmp(sample, k->name) == 0,
"TSIG key dname check");
} else {
ok(0, "TSIG key dname check - NO KEY FOUND");
}
knot_dname_free(&sample, NULL);
skip_all:
// Deallocating config
conf_free(conf);
return 0;