Commit 060273ad authored by Daniel Salzman's avatar Daniel Salzman

conf: add template.file support

parent d3639ef1
......@@ -488,6 +488,7 @@ tests/acl.c
tests/base32hex.c
tests/base64.c
tests/changeset.c
tests/conf.c
tests/descriptor.c
tests/dname.c
tests/dthreads.c
......@@ -497,6 +498,7 @@ tests/fake_server.h
tests/fdset.c
tests/hattrie.c
tests/hhash.c
tests/internal_mem.c
tests/journal.c
tests/namedb.c
tests/net_shortwrite.c
......
......@@ -41,6 +41,7 @@
#include "libknot/internal/mempool.h"
#include "libknot/internal/namedb/namedb_lmdb.h"
#include "libknot/internal/sockaddr.h"
#include "libknot/internal/strlcat.h"
#include "libknot/yparser/ypformat.h"
#include "libknot/yparser/yptrafo.h"
......@@ -1218,91 +1219,114 @@ void conf_data(
}
}
static char* dname_to_filename(
const knot_dname_t *name,
const char *suffix)
static char* get_filename(
conf_t *conf,
const knot_dname_t *zone,
const char *name)
{
char *str = knot_dname_to_str_alloc(name);
if (str == NULL) {
return NULL;
}
const char *end = name + strlen(name);
char out[1024] = "";
// Replace possible slashes with underscores.
for (char *ch = str; *ch != '\0'; ch++) {
if (*ch == '/') {
*ch = '_';
do {
// Search for a formatter.
const char *pos = strchr(name, '%');
// If no formatter, copy the rest of the name.
if (pos == NULL) {
if (strlcat(out, name, sizeof(out)) >= sizeof(out)) {
return NULL;
}
break;
}
}
char *out = sprintf_alloc("%s%s", str, suffix);
free(str);
// Copy constant block.
char *block = strndup(name, pos - name);
if (block == NULL ||
strlcat(out, block, sizeof(out)) >= sizeof(out)) {
return NULL;
}
free(block);
return out;
// Move name pointer behind the formatter.
name = pos + 2;
char buff[512] = "";
const char type = *(pos + 1);
switch (type) {
case '%':
strlcat(buff, "%", sizeof(buff));
break;
case 's':
if (knot_dname_to_str(buff, zone, sizeof(buff)) == NULL) {
return NULL;
}
// Replace possible slashes with underscores.
for (char *ch = buff; *ch != '\0'; ch++) {
if (*ch == '/') {
*ch = '_';
}
}
break;
case '\0':
log_zone_warning(zone, "ignoring missing trailing "
"zonefile formatter");
continue;
default:
log_zone_warning(zone, "ignoring zonefile formatter '%c'",
type);
continue;
}
if (strlcat(out, buff, sizeof(out)) >= sizeof(out)) {
return NULL;
}
} while (name < end);
// Use storage prefix if not absolute path.
if (out[0] == '/') {
return strdup(out);
} else {
conf_val_t val = conf_zone_get(conf, C_STORAGE, zone);
char *storage = conf_abs_path(&val, NULL);
if (storage == NULL) {
return NULL;
}
char *abs = sprintf_alloc("%s/%s", storage, out);
free(storage);
return abs;
}
}
char* conf_zonefile(
conf_t *conf,
const knot_dname_t *zone)
{
assert(conf != NULL && zone != NULL);
// Item 'file' is not template item (cannot use conf_zone_get)! */
const char *file = NULL;
conf_val_t file_val = { NULL };
file_val.code = conf_db_get(conf, &conf->read_txn, C_ZONE, C_FILE,
zone, knot_dname_size(zone), &file_val);
if (file_val.code == KNOT_EOK) {
file = conf_str(&file_val);
if (file != NULL && file[0] == '/') {
return strdup(file);
}
}
char *abs_storage = NULL;
conf_val_t storage_val = conf_zone_get(conf, C_STORAGE, zone);
if (storage_val.code == KNOT_EOK) {
abs_storage = conf_abs_path(&storage_val, NULL);
if (abs_storage == NULL) {
return NULL;
}
if (conf == NULL || zone == NULL) {
return NULL;
}
char *out = NULL;
conf_val_t val = conf_zone_get(conf, C_FILE, zone);
const char *file = conf_str(&val);
// Use default zonefile name pattern if not specified.
if (file == NULL) {
char *file = dname_to_filename(zone, "zone");
out = sprintf_alloc("%s/%s", abs_storage, file);
free(file);
} else {
out = sprintf_alloc("%s/%s", abs_storage, file);
file = "%szone";
}
free(abs_storage);
return out;
return get_filename(conf, zone, file);
}
char* conf_journalfile(
conf_t *conf,
const knot_dname_t *zone)
{
assert(conf != NULL && zone != NULL);
char *abs_storage = NULL;
conf_val_t storage_val = conf_zone_get(conf, C_STORAGE, zone);
if (storage_val.code == KNOT_EOK) {
abs_storage = conf_abs_path(&storage_val, NULL);
if (abs_storage == NULL) {
return NULL;
}
if (conf == NULL || zone == NULL) {
return NULL;
}
char *name = dname_to_filename(zone, "diff.db");
char *out = sprintf_alloc("%s/%s", abs_storage, name);
free(name);
free(abs_storage);
return out;
return get_filename(conf, zone, "%sdb");
}
size_t conf_udp_threads(
......
......@@ -133,6 +133,7 @@ static const yp_item_t desc_remote[] = {
};
#define ZONE_ITEMS \
{ C_FILE, YP_TSTR, YP_VNONE }, \
{ C_STORAGE, YP_TSTR, YP_VSTR = { STORAGE_DIR } }, \
{ C_MASTER, YP_TREF, YP_VREF = { C_RMT }, YP_FMULTI, { check_ref } }, \
{ C_NOTIFY, YP_TREF, YP_VREF = { C_RMT }, YP_FMULTI, { check_ref } }, \
......@@ -157,7 +158,6 @@ static const yp_item_t desc_template[] = {
static const yp_item_t desc_zone[] = {
{ C_DOMAIN, YP_TDNAME, YP_VNONE },
{ C_FILE, YP_TSTR, YP_VNONE },
{ C_TPL, YP_TREF, YP_VREF = { C_TPL }, YP_FNONE, { check_ref } },
ZONE_ITEMS
{ NULL }
......
......@@ -7,6 +7,7 @@ acl
base32hex
base64
changeset
conf
descriptor
dname
dnssec_keys
......
......@@ -15,6 +15,7 @@ check_PROGRAMS = \
base32hex \
base64 \
changeset \
conf \
descriptor \
dname \
dthreads \
......@@ -64,6 +65,7 @@ check-local: $(check_PROGRAMS)
$(check_PROGRAMS)
acl_SOURCES = acl.c test_conf.h
conf_SOURCES = conf.c test_conf.h
process_query_SOURCES = process_query.c fake_server.h test_conf.h
process_answer_SOURCES = process_answer.c fake_server.h test_conf.h
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 <tap/basic.h>
#include "test_conf.h"
#define ZONE1 "0/25.2.0.192.in-addr.arpa."
#define ZONE2 "."
static void test_conf_zonefile(void)
{
int ret;
char *file;
knot_dname_t *zone1 = knot_dname_from_str_alloc(ZONE1);
ok(zone1 != NULL, "create dname "ZONE1);
knot_dname_t *zone2 = knot_dname_from_str_alloc(ZONE2);
ok(zone2 != NULL, "create dname "ZONE2);
const char *conf_str =
"template:\n"
" - id: default\n"
" storage: /tmp\n"
"\n"
"zone:\n"
" - domain: "ZONE1"\n"
" file: dir/a%%b/%ssuffix/%a\n"
"zone:\n"
" - domain: "ZONE2"\n"
" file: /%s\n";
ret = test_conf(conf_str, NULL);
ok(ret == KNOT_EOK, "Prepare configuration");
// Relative path with formatters.
file = conf_zonefile(conf(), zone1);
ok(file != NULL, "Get zonefile path for "ZONE1);
ok(strcmp(file, "/tmp/dir/a%b/0_25.2.0.192.in-addr.arpa.suffix/") == 0,
"Zonefile path compare for "ZONE1);
free(file);
// Absolute path without formatters.
file = conf_zonefile(conf(), zone2);
ok(file != NULL, "Get zonefile path for "ZONE2);
ok(strcmp(file, "/.") == 0,
"Zonefile path compare for "ZONE2);
free(file);
conf_free(conf(), false);
knot_dname_free(&zone1, NULL);
knot_dname_free(&zone2, NULL);
}
int main(int argc, char *argv[])
{
plan_lazy();
test_conf_zonefile();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment