Commit 03b64bb3 authored by Daniel Salzman's avatar Daniel Salzman

utils: add config conversion utility (knot1to2)

parent 710a2271
......@@ -76,6 +76,7 @@
# Binaries
/src/knotc
/src/knotd
/src/knot1to2
/src/kdig
/src/khost
/src/knsupdate
......
......@@ -439,6 +439,17 @@ src/utils/kdig/kdig_params.h
src/utils/khost/khost_main.c
src/utils/khost/khost_params.c
src/utils/khost/khost_params.h
src/utils/knot1to2/cf-lex.c
src/utils/knot1to2/cf-lex.l
src/utils/knot1to2/cf-parse.tab.c
src/utils/knot1to2/cf-parse.tab.h
src/utils/knot1to2/cf-parse.y
src/utils/knot1to2/extra.c
src/utils/knot1to2/extra.h
src/utils/knot1to2/includes.c
src/utils/knot1to2/includes.h
src/utils/knot1to2/main.c
src/utils/knot1to2/scheme.h
src/utils/knsupdate/knsupdate_exec.c
src/utils/knsupdate/knsupdate_exec.h
src/utils/knsupdate/knsupdate_main.c
......
......@@ -416,6 +416,7 @@ AC_CONFIG_FILES([Makefile
man/kdig.1
man/knsupdate.1
man/knot.conf.5
man/knot1to2.1
])
AC_OUTPUT
......
......@@ -5,7 +5,7 @@ MANPAGES += knot.conf.5 knotc.8 knotd.8
endif # HAVE_DAEMON
if HAVE_UTILS
MANPAGES += kdig.1 khost.1 knsupdate.1
MANPAGES += kdig.1 khost.1 knsupdate.1 knot1to2.1
endif # HAVE_UTILS
dist_man_MANS = $(MANPAGES)
......
.TH "knot1to2" "1" "@RELEASE_DATE@" "CZ.NIC Labs" "Knot DNS, version @VERSION@"
.SH NAME
.TP 6
.B knot1to2
\- Simple Knot DNS configuration conversion utility
.SH SYNOPSIS
.B knot1to2
-i \fIfile\fR -o \fIfile\fR
.SH DESCRIPTION
This utility converts Knot DNS configuration file from version 1.x to version 2.x.
.TP 4
.BR \-i ,\ \-\-in
Input configuration file (Knot version 1.x).
.TP
.BR \-o ,\ \-\-out
Output configuration file (Knot version 2.x)
.TP
.BR \-h ,\ \-\-help
Print help.
.TP
.BR \-V ,\ \-\-version
Print package version.
.SH AUTHOR
Daniel Salzman (\fBwww.knot\-dns.cz\fR)
.TP
Please send any bug reports or comments to \fBknot\-dns@labs.nic.cz\fR
.SH SEE ALSO
.BR kdig (1),
.BR khost (1),
.BR knsupdate (1).
......@@ -50,3 +50,12 @@ sed -i '/static\ const\ int\ yparser_/d' $OUT_Y
sed -i 's/\s*$//g' $OUT_Y
popd
### KNOT1TO2 ###
pushd ../src/utils/knot1to2/
flex cf-lex.l
bison -d -b cf-parse cf-parse.y
popd
......@@ -365,7 +365,7 @@ endif # HAVE_DAEMON
if HAVE_UTILS
bin_PROGRAMS = kdig khost knsupdate
bin_PROGRAMS = kdig khost knsupdate knot1to2
noinst_LTLIBRARIES += libknotus.la
kdig_SOURCES = \
......@@ -391,6 +391,17 @@ knsupdate_SOURCES = \
utils/knsupdate/knsupdate_params.c \
utils/knsupdate/knsupdate_params.h
knot1to2_SOURCES = \
utils/knot1to2/cf-lex.c \
utils/knot1to2/cf-parse.tab.c \
utils/knot1to2/cf-parse.tab.h \
utils/knot1to2/extra.c \
utils/knot1to2/extra.h \
utils/knot1to2/includes.c \
utils/knot1to2/includes.h \
utils/knot1to2/main.c \
utils/knot1to2/scheme.h
# static: utilities shared
libknotus_la_SOURCES = \
utils/common/exec.c \
......@@ -417,6 +428,7 @@ libknotus_la_LIBADD = libknot-int.la libknot.la
kdig_LDADD = $(libidn_LIBS) libknotus.la
khost_LDADD = $(libidn_LIBS) libknotus.la
knsupdate_LDADD = zscanner/libzscanner.la libknotus.la
knot1to2_LDADD = libknot-int.la
#######################################
# Optional Knot DNS Utilities modules #
......
......@@ -141,9 +141,7 @@ static const char _yparser_eof_actions[] = {
int _yp_start_state =
25
;
int _yp_start_state = 25;
int _yp_parse(
yp_parser_t *parser)
......@@ -403,9 +401,7 @@ _again:
}
// Check for general parser error.
if (parser->cs ==
0
) {
if (parser->cs == 0) {
return KNOT_EPARSEFAIL;
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* A Bison parser, made by GNU Bison 3.0.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
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/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_CF_CF_PARSE_TAB_H_INCLUDED
# define YY_CF_CF_PARSE_TAB_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int cf_debug;
#endif
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
enum yytokentype
{
END = 258,
INVALID_TOKEN = 259,
TEXT = 260,
NUM = 261,
INTERVAL = 262,
SIZE = 263,
BOOL = 264,
SYSTEM = 265,
IDENTITY = 266,
HOSTNAME = 267,
SVERSION = 268,
NSID = 269,
KEY = 270,
KEYS = 271,
MAX_UDP_PAYLOAD = 272,
TSIG_ALGO_NAME = 273,
WORKERS = 274,
BACKGROUND_WORKERS = 275,
ASYNC_START = 276,
USER = 277,
RUNDIR = 278,
PIDFILE = 279,
REMOTES = 280,
GROUPS = 281,
ZONES = 282,
FILENAME = 283,
DISABLE_ANY = 284,
SEMANTIC_CHECKS = 285,
NOTIFY_RETRIES = 286,
NOTIFY_TIMEOUT = 287,
DBSYNC_TIMEOUT = 288,
IXFR_FSLIMIT = 289,
XFR_IN = 290,
XFR_OUT = 291,
UPDATE_IN = 292,
NOTIFY_IN = 293,
NOTIFY_OUT = 294,
BUILD_DIFFS = 295,
MAX_CONN_IDLE = 296,
MAX_CONN_HS = 297,
MAX_CONN_REPLY = 298,
MAX_TCP_CLIENTS = 299,
RATE_LIMIT = 300,
RATE_LIMIT_SIZE = 301,
RATE_LIMIT_SLIP = 302,
TRANSFERS = 303,
STORAGE = 304,
DNSSEC_ENABLE = 305,
DNSSEC_KEYDIR = 306,
SIGNATURE_LIFETIME = 307,
SERIAL_POLICY = 308,
SERIAL_POLICY_VAL = 309,
QUERY_MODULE = 310,
INTERFACES = 311,
ADDRESS = 312,
PORT = 313,
IPA = 314,
IPA6 = 315,
VIA = 316,
CONTROL = 317,
ALLOW = 318,
LISTEN_ON = 319,
LOG = 320,
LOG_DEST = 321,
LOG_SRC = 322,
LOG_LEVEL = 323
};
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE YYSTYPE;
union YYSTYPE
{
#line 302 "cf-parse.y" /* yacc.c:1909 */
struct {
char *t;
long i;
size_t l;
} tok;
#line 131 "cf-parse.tab.h" /* yacc.c:1909 */
};
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
int cf_parse (void *scanner);
#endif /* !YY_CF_CF_PARSE_TAB_H_INCLUDED */
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 <string.h>
#include "utils/knot1to2/includes.h"
#include "utils/knot1to2/extra.h"
/*!
* \brief Init structure with custom data for config parser.
*/
conf_extra_t *conf_extra_init(const char *file, int run, share_t *share)
{
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;
extra->run = run;
extra->share = share;
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/>.
*/
#pragma once
#include <stdbool.h>
#include "utils/knot1to2/includes.h"
#include "utils/knot1to2/scheme.h"
#include "libknot/internal/trie/hat-trie.h"
typedef struct {
FILE *out;
bool have_sections[S_LAST - S_FIRST + 1];
hattrie_t *groups;
hattrie_t *remotes;
hattrie_t *acl_xfer;
hattrie_t *acl_notify;
hattrie_t *acl_update;
hattrie_t *acl_control;
} share_t;
/*!
* \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.
int run; // Current run number.
share_t *share; // Variables shared among all runs.
hattrie_t *current_trie;
const char *current_key;
} 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, int run, share_t *share);
/*!
* \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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utils/knot1to2/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/>.
*/
#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);
/* Copyright (C) 2015 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 <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "utils/knot1to2/extra.h"
#include "utils/knot1to2/scheme.h"
#include "libknot/internal/trie/hat-trie.h"
static int run_parser(const char *file_in, int run, share_t *share)
{
extern int cf_parse(void *scanner);
extern int cf_lex_init_extra(void *, void *scanner);
extern void cf_set_in(FILE *f, void *scanner);
extern void cf_lex_destroy(void *scanner);
extern volatile int parser_ret;
FILE *in = fopen(file_in, "r");
if (in == NULL) {
printf("Failed to open input file '%s'\n", file_in);
return -1;
}
void *sc = NULL;
conf_extra_t *extra = conf_extra_init(file_in, run, share);
cf_lex_init_extra(extra, &sc);
cf_set_in(in, sc);
cf_parse(sc);
cf_lex_destroy(sc);
conf_extra_free(extra);
fclose(in);
return parser_ret;
}
static int convert(const char *file_out, const char *file_in)
{
FILE *out = fopen(file_out, "w");