mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
Heaps of changes for dealing with the main config file data structure.
This commit is contained in:
@@ -18,20 +18,152 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
|
||||
#include "configctx.h"
|
||||
|
||||
|
||||
static void freeoptions(isc_cfgoptions_t *opts, isc_mem_t *mem);
|
||||
static isc_result_t setdirectory(isc_cfgoptions_t *opts, char *directory,
|
||||
isc_mem_t *mem);
|
||||
/* these are the bit definitions for the flag set 1 */
|
||||
#define NCACHE_TTL_BIT (1 << 1)
|
||||
#define TRANSFERS_IN_BIT (1 << 2)
|
||||
#define TRANSFERS_PER_NS_BIT (1 << 3)
|
||||
#define TRANSFERS_OUT_BIT (1 << 4)
|
||||
#define MAX_LOG_BIT (1 << 5)
|
||||
#define CLEAN_INT_BIT (1 << 6)
|
||||
#define INTERFACE_INT_BIT (1 << 7)
|
||||
#define STATS_INT_BIT (1 << 8)
|
||||
#define HEARDBEAT_INT_BIT (1 << 9)
|
||||
#define MAX_TRANS_TIME_BIT (1 << 10)
|
||||
#define DATA_SIZE_BIT (1 << 11)
|
||||
#define STACK_SIZE_BIT (1 << 12)
|
||||
#define CORE_SIZE_BIT (1 << 13)
|
||||
#define FILES_BIT (1 << 14)
|
||||
#define QUERY_SOURCE_BIT (1 << 15)
|
||||
#define QUERY_ACL_BIT (1 << 16)
|
||||
#define TRANSFER_ACL_BIT (1 << 17)
|
||||
#define BLOCKHOLE_ACL_BIT (1 << 18)
|
||||
#define TOPOLOGY_BIT (1 << 19)
|
||||
#define TRANSFER_FORMAT_BIT (1 << 20)
|
||||
#define FAKE_IQUERY_BIT (1 << 21)
|
||||
#define RECURSION_BIT (1 << 22)
|
||||
#define FETCH_GLUE_BIT (1 << 23)
|
||||
#define NOTIFY_BIT (1 << 24)
|
||||
#define HOSTSTATS_BIT (1 << 25)
|
||||
#define DEALLOC_ON_EXIT_BIT (1 << 26)
|
||||
#define USE_IXFR_BIT (1 << 27)
|
||||
#define MAINTAIN_IXFR_BASE_BIT (1 << 28)
|
||||
#define HAS_OLD_CLIENTS_BIT (1 << 29)
|
||||
#define AUTH_NX_DOMAIN_BIT (1 << 30)
|
||||
#define MULTIPLE_CNAMES_BIT (1 << 0)
|
||||
|
||||
/* these are the bit definitions for the flag set 2 */
|
||||
#define CHECK_NAMES_BIT (1 << 1)
|
||||
#define USE_ID_POOL_BIT (1 << 2)
|
||||
#define DIALUP_BIT (1 << 3)
|
||||
|
||||
|
||||
|
||||
#define CHECKBIT(bit,flags) (((flags) & (bit)) == (bit))
|
||||
#define SETBIT(bit, flags) ((flags) |= (bit))
|
||||
#define CLEARBIT(bit, flags) ((flags) &= ~(bit))
|
||||
|
||||
#define CHECKREGION(r) \
|
||||
INSIST(((r)->base == NULL && (r)->length == 0) || \
|
||||
((r)->base != NULL && (r)->length > 0))
|
||||
|
||||
#define FREE_TEXT_REGION(r,m) \
|
||||
do { CHECKREGION(r) ; \
|
||||
if ((r)->base != NULL) { \
|
||||
isc_mem_put(m,(r)->base,(r)->length); \
|
||||
(r)->base = NULL; (r)->length = 0; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
/* I don't much like this, but there's a huge amount of code duplication
|
||||
* that these macros eliminate
|
||||
*/
|
||||
|
||||
#define FUNC_SET_FIELD(field, bit, bitset, type) \
|
||||
isc_result_t \
|
||||
isc_cfg_set_ ## field (isc_cfgctx_t *ctx, type value) \
|
||||
{ \
|
||||
INSIST(ctx != NULL); \
|
||||
INSIST(ctx->options != NULL); \
|
||||
\
|
||||
ctx->options->field = value; \
|
||||
\
|
||||
SETBIT(bit, ctx->options->bitset); \
|
||||
\
|
||||
return (ISC_R_SUCCESS); \
|
||||
}
|
||||
|
||||
#define FUNC_GET_FIELD(field, bit, bitset, type) \
|
||||
isc_result_t \
|
||||
isc_cfg_get_ ## field (isc_cfgctx_t *ctx, type *result) \
|
||||
{ \
|
||||
INSIST(ctx != NULL); \
|
||||
INSIST(ctx->options != NULL); \
|
||||
INSIST(result != NULL); \
|
||||
\
|
||||
if (CHECKBIT(bit,ctx->options->bitset)) { \
|
||||
*result = ctx->options->field; \
|
||||
return (ISC_R_SUCCESS); \
|
||||
} else { \
|
||||
return (ISC_R_NOTFOUND); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define FUNC_SET_TEXTFIELD(field) \
|
||||
isc_result_t \
|
||||
isc_cfg_set_ ## field(isc_cfgctx_t *ctx, const char *value) \
|
||||
{ \
|
||||
isc_result_t res; \
|
||||
\
|
||||
INSIST(ctx != NULL); \
|
||||
\
|
||||
res = set_text_region(ctx->mem, &ctx->options->field, value); \
|
||||
\
|
||||
return (res); \
|
||||
}
|
||||
|
||||
|
||||
#define FUNC_GET_TEXTFIELD(field) \
|
||||
isc_result_t \
|
||||
isc_cfg_get_ ## field(isc_cfgctx_t *ctx, const char **result) \
|
||||
{ \
|
||||
INSIST(ctx != NULL); \
|
||||
INSIST(ctx->options != NULL); \
|
||||
INSIST(result != NULL); \
|
||||
\
|
||||
if (ctx->options->field.base != NULL) { \
|
||||
*result = ctx->options->field.base; \
|
||||
return (ISC_R_SUCCESS); \
|
||||
} else { \
|
||||
return (ISC_R_NOTFOUND); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void freeoptions(isc_cfgoptions_t *opts, isc_mem_t *mem);
|
||||
static isc_result_t set_text_region(isc_mem_t *mem,
|
||||
isc_textregion_t *region,
|
||||
const char *value);
|
||||
static void opt_print_textregion(FILE *fp, const char *name,
|
||||
isc_textregion_t r);
|
||||
|
||||
|
||||
/***
|
||||
*** PUBLIC
|
||||
***/
|
||||
|
||||
isc_result_t
|
||||
isc_cfg_newctx(isc_mem_t *mem, isc_cfgctx_t **ctx)
|
||||
{
|
||||
@@ -98,51 +230,305 @@ isc_cfg_freectx(isc_cfgctx_t **ctx)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
isc_result_t
|
||||
isc_cfg_setdirectory(isc_cfgctx_t *ctx, char *directory)
|
||||
isc_cfg_erase_options(isc_cfgctx_t *ctx)
|
||||
{
|
||||
INSIST(ctx != NULL);
|
||||
INSIST(ctx->mem != NULL);
|
||||
INSIST(directory != NULL);
|
||||
INSIST(strlen(directory) > 0);
|
||||
INSIST(ctx->options != NULL);
|
||||
|
||||
freeoptions(ctx->options, ctx->mem);
|
||||
ctx->options = isc_mem_get(ctx->mem, sizeof *ctx->options);
|
||||
if (ctx->options == NULL) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
memset (ctx->options, 0x0, sizeof *ctx->options);
|
||||
|
||||
return (setdirectory(ctx->options, directory, ctx->mem));
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
isc_cfg_dump_config(FILE *fp, isc_cfgctx_t *cfg)
|
||||
{
|
||||
INSIST(cfg != NULL);
|
||||
INSIST(fp != NULL);
|
||||
|
||||
isc_cfg_dump_options(fp, cfg->options);
|
||||
if (cfg->zonecontext != NULL) {
|
||||
isc_zonectx_dump(fp, cfg->zonecontext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_in_units(FILE *fp, unsigned long val)
|
||||
{
|
||||
unsigned long one_gig = (1024 * 1024 * 1024);
|
||||
unsigned long one_meg = (1024 * 1024);
|
||||
unsigned long one_k = 1024;
|
||||
|
||||
if ((val % one_gig) == 0)
|
||||
fprintf(fp, "%luG", val / one_gig);
|
||||
else if ((val % one_meg) == 0)
|
||||
fprintf(fp, "%luM", val / one_meg);
|
||||
else if ((val % one_k) == 0)
|
||||
fprintf(fp, "%luK", val / one_k);
|
||||
else if (val == ULONG_MAX)
|
||||
fprintf(fp, "unlimited");
|
||||
else
|
||||
fprintf(fp, "%lu", val);
|
||||
}
|
||||
|
||||
void
|
||||
isc_cfg_dump_options(FILE *fp, isc_cfgoptions_t *options)
|
||||
{
|
||||
INSIST(options != NULL);
|
||||
INSIST(fp != NULL);
|
||||
|
||||
#define PRINT_AS_MINUTES(field, bit, name, bitfield) \
|
||||
if (CHECKBIT(bit, options->bitfield)) { \
|
||||
fprintf(fp, "\t%s %lu;\n",name, \
|
||||
(unsigned long)options->field / 60); \
|
||||
}
|
||||
|
||||
#define PRINT_AS_BOOLEAN(field, bit, name, bitfield) \
|
||||
if (CHECKBIT(bit, options->bitfield)) { \
|
||||
fprintf(fp, "\t%s %s;\n",name, \
|
||||
(options->field ? "true" : "false")); \
|
||||
}
|
||||
|
||||
#define PRINT_AS_SIZE_CLAUSE(field, bit, name, bitfield) \
|
||||
if (CHECKBIT(bit,options->bitfield)) { \
|
||||
fprintf(fp, "\t%s ",name); \
|
||||
if (options->field == 0) { \
|
||||
fprintf(fp, "default"); \
|
||||
} else { \
|
||||
print_in_units(fp,options->data_size); \
|
||||
} \
|
||||
fprintf(fp, ";\n"); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
fprintf (fp, "options {\n");
|
||||
opt_print_textregion(fp, "version", options->version);
|
||||
opt_print_textregion(fp, "directory", options->directory);
|
||||
opt_print_textregion(fp, "named-xfer", options->named_xfer);
|
||||
opt_print_textregion(fp, "pid-file", options->pid_filename);
|
||||
opt_print_textregion(fp, "statistics-file", options->stats_filename);
|
||||
opt_print_textregion(fp, "memstatistics-file",
|
||||
options->memstats_filename);
|
||||
opt_print_textregion(fp, "dump-file", options->dump_filename);
|
||||
|
||||
PRINT_AS_BOOLEAN(fake_iquery, FAKE_IQUERY_BIT,
|
||||
"fake-iquery", set_flags1);
|
||||
PRINT_AS_BOOLEAN(recursion, RECURSION_BIT,
|
||||
"recursion", set_flags1);
|
||||
PRINT_AS_BOOLEAN(fetch_glue, FETCH_GLUE_BIT,
|
||||
"fetch-glue", set_flags1);
|
||||
PRINT_AS_BOOLEAN(notify, NOTIFY_BIT,
|
||||
"notify", set_flags1);
|
||||
PRINT_AS_BOOLEAN(hoststats, HOSTSTATS_BIT,
|
||||
"hoststats", set_flags1);
|
||||
PRINT_AS_BOOLEAN(dealloc_on_exit, DEALLOC_ON_EXIT_BIT,
|
||||
"deallocate-on-exit", set_flags1);
|
||||
PRINT_AS_BOOLEAN(use_ixfr, USE_IXFR_BIT,
|
||||
"use_ixfr", set_flags1);
|
||||
PRINT_AS_BOOLEAN(maintain_ixfr_base, MAINTAIN_IXFR_BASE_BIT,
|
||||
"maintain-ixfr-base", set_flags1);
|
||||
PRINT_AS_BOOLEAN(has_old_clients, HAS_OLD_CLIENTS_BIT,
|
||||
"has-old-clients", set_flags1);
|
||||
PRINT_AS_BOOLEAN(auth_nx_domain, AUTH_NX_DOMAIN_BIT,
|
||||
"auth-nxdomain", set_flags1);
|
||||
PRINT_AS_BOOLEAN(multiple_cnames, MULTIPLE_CNAMES_BIT,
|
||||
"multiple-cnames", set_flags1);
|
||||
PRINT_AS_BOOLEAN(use_id_pool, USE_ID_POOL_BIT,
|
||||
"use-id-pool", set_flags2);
|
||||
PRINT_AS_BOOLEAN(dialup, DIALUP_BIT,
|
||||
"dialup", set_flags2);
|
||||
|
||||
PRINT_AS_SIZE_CLAUSE(data_size, DATA_SIZE_BIT, "datasize",
|
||||
set_flags1);
|
||||
PRINT_AS_SIZE_CLAUSE(stack_size, STACK_SIZE_BIT, "stacksize",
|
||||
set_flags1);
|
||||
PRINT_AS_SIZE_CLAUSE(core_size, CORE_SIZE_BIT, "coresize",
|
||||
set_flags1);
|
||||
PRINT_AS_SIZE_CLAUSE(files, FILES_BIT, "files",
|
||||
set_flags1);
|
||||
|
||||
PRINT_AS_MINUTES(max_transfer_time_in, MAX_TRANS_TIME_BIT,
|
||||
"max-transfer-time-in", set_flags1);
|
||||
PRINT_AS_MINUTES(clean_interval, CLEAN_INT_BIT,
|
||||
"cleaning-interval", set_flags1);
|
||||
PRINT_AS_MINUTES(interface_interval, INTERFACE_INT_BIT,
|
||||
"interface-interval", set_flags1);
|
||||
PRINT_AS_MINUTES(stats_interval, STATS_INT_BIT,
|
||||
"statistics-interval", set_flags1);
|
||||
|
||||
fprintf(fp,"};\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****
|
||||
**** ACCESSORS/MODIFIERS
|
||||
****/
|
||||
|
||||
/* This is seriously ugly, but we have nothing like C++ templates here.... */
|
||||
|
||||
FUNC_SET_TEXTFIELD(directory)
|
||||
FUNC_GET_TEXTFIELD(directory)
|
||||
|
||||
FUNC_SET_TEXTFIELD(version)
|
||||
FUNC_GET_TEXTFIELD(version)
|
||||
|
||||
FUNC_SET_TEXTFIELD(dump_filename)
|
||||
FUNC_GET_TEXTFIELD(dump_filename)
|
||||
|
||||
FUNC_SET_TEXTFIELD(pid_filename)
|
||||
FUNC_GET_TEXTFIELD(pid_filename)
|
||||
|
||||
FUNC_SET_TEXTFIELD(stats_filename)
|
||||
FUNC_GET_TEXTFIELD(stats_filename)
|
||||
|
||||
FUNC_SET_TEXTFIELD(memstats_filename)
|
||||
FUNC_GET_TEXTFIELD(memstats_filename)
|
||||
|
||||
FUNC_SET_TEXTFIELD(named_xfer)
|
||||
FUNC_GET_TEXTFIELD(named_xfer)
|
||||
|
||||
FUNC_SET_FIELD(max_ncache_ttl, NCACHE_TTL_BIT, set_flags1, unsigned int)
|
||||
FUNC_GET_FIELD(max_ncache_ttl, NCACHE_TTL_BIT, set_flags1, unsigned int)
|
||||
|
||||
FUNC_SET_FIELD(transfers_in, TRANSFERS_IN_BIT, set_flags1, int)
|
||||
FUNC_GET_FIELD(transfers_in, TRANSFERS_IN_BIT, set_flags1, int)
|
||||
|
||||
FUNC_SET_FIELD(transfers_per_ns, TRANSFERS_PER_NS_BIT, set_flags1, int)
|
||||
FUNC_GET_FIELD(transfers_per_ns, TRANSFERS_PER_NS_BIT, set_flags1, int)
|
||||
|
||||
FUNC_SET_FIELD(transfers_out, TRANSFERS_OUT_BIT, set_flags1, int)
|
||||
FUNC_GET_FIELD(transfers_out, TRANSFERS_OUT_BIT, set_flags1, int)
|
||||
|
||||
FUNC_SET_FIELD(max_log_size_ixfr, MAX_LOG_BIT, set_flags1, int)
|
||||
FUNC_GET_FIELD(max_log_size_ixfr, MAX_LOG_BIT, set_flags1, int)
|
||||
|
||||
FUNC_SET_FIELD(clean_interval, CLEAN_INT_BIT, set_flags1, int)
|
||||
FUNC_GET_FIELD(clean_interval, CLEAN_INT_BIT, set_flags1, int)
|
||||
|
||||
FUNC_SET_FIELD(interface_interval, INTERFACE_INT_BIT, set_flags1, int)
|
||||
FUNC_GET_FIELD(interface_interval, INTERFACE_INT_BIT, set_flags1, int)
|
||||
|
||||
FUNC_SET_FIELD(stats_interval, STATS_INT_BIT, set_flags1, int)
|
||||
FUNC_GET_FIELD(stats_interval, STATS_INT_BIT, set_flags1, int)
|
||||
|
||||
FUNC_SET_FIELD(heartbeat_interval, HEARDBEAT_INT_BIT, set_flags1, int)
|
||||
FUNC_GET_FIELD(heartbeat_interval, HEARDBEAT_INT_BIT, set_flags1, int)
|
||||
|
||||
FUNC_SET_FIELD(max_transfer_time_in,MAX_TRANS_TIME_BIT, set_flags1, long)
|
||||
FUNC_GET_FIELD(max_transfer_time_in,MAX_TRANS_TIME_BIT, set_flags1, long)
|
||||
|
||||
FUNC_SET_FIELD(data_size, DATA_SIZE_BIT, set_flags1, unsigned long)
|
||||
FUNC_GET_FIELD(data_size, DATA_SIZE_BIT, set_flags1, unsigned long)
|
||||
|
||||
FUNC_SET_FIELD(stack_size, STACK_SIZE_BIT, set_flags1, unsigned long)
|
||||
FUNC_GET_FIELD(stack_size, STACK_SIZE_BIT, set_flags1, unsigned long)
|
||||
|
||||
FUNC_SET_FIELD(core_size, CORE_SIZE_BIT, set_flags1, unsigned long)
|
||||
FUNC_GET_FIELD(core_size, CORE_SIZE_BIT, set_flags1, unsigned long)
|
||||
|
||||
FUNC_SET_FIELD(files, FILES_BIT, set_flags1, unsigned long)
|
||||
FUNC_GET_FIELD(files, FILES_BIT, set_flags1, unsigned long)
|
||||
|
||||
FUNC_SET_FIELD(fake_iquery, FAKE_IQUERY_BIT, set_flags1, isc_boolean_t)
|
||||
FUNC_GET_FIELD(fake_iquery, FAKE_IQUERY_BIT, set_flags1, isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(recursion, RECURSION_BIT, set_flags1, isc_boolean_t)
|
||||
FUNC_GET_FIELD(recursion, RECURSION_BIT, set_flags1, isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(fetch_glue, FETCH_GLUE_BIT, set_flags1, isc_boolean_t)
|
||||
FUNC_GET_FIELD(fetch_glue, FETCH_GLUE_BIT, set_flags1, isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(notify, NOTIFY_BIT, set_flags1, isc_boolean_t)
|
||||
FUNC_GET_FIELD(notify, NOTIFY_BIT, set_flags1, isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(hoststats, HOSTSTATS_BIT, set_flags1, isc_boolean_t)
|
||||
FUNC_GET_FIELD(hoststats, HOSTSTATS_BIT, set_flags1, isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(dealloc_on_exit, DEALLOC_ON_EXIT_BIT, set_flags1,
|
||||
isc_boolean_t)
|
||||
FUNC_GET_FIELD(dealloc_on_exit, DEALLOC_ON_EXIT_BIT, set_flags1,
|
||||
isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(use_ixfr, USE_IXFR_BIT, set_flags1, isc_boolean_t)
|
||||
FUNC_GET_FIELD(use_ixfr, USE_IXFR_BIT, set_flags1, isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(maintain_ixfr_base, MAINTAIN_IXFR_BASE_BIT, set_flags1,
|
||||
isc_boolean_t)
|
||||
FUNC_GET_FIELD(maintain_ixfr_base, MAINTAIN_IXFR_BASE_BIT, set_flags1,
|
||||
isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(has_old_clients, HAS_OLD_CLIENTS_BIT, set_flags1,
|
||||
isc_boolean_t)
|
||||
FUNC_GET_FIELD(has_old_clients, HAS_OLD_CLIENTS_BIT, set_flags1,
|
||||
isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(auth_nx_domain, AUTH_NX_DOMAIN_BIT, set_flags1, isc_boolean_t)
|
||||
FUNC_GET_FIELD(auth_nx_domain, AUTH_NX_DOMAIN_BIT, set_flags1, isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(multiple_cnames, MULTIPLE_CNAMES_BIT, set_flags1,
|
||||
isc_boolean_t)
|
||||
FUNC_GET_FIELD(multiple_cnames, MULTIPLE_CNAMES_BIT, set_flags1,
|
||||
isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(use_id_pool, USE_ID_POOL_BIT, set_flags2, isc_boolean_t)
|
||||
FUNC_GET_FIELD(use_id_pool, USE_ID_POOL_BIT, set_flags2, isc_boolean_t)
|
||||
|
||||
FUNC_SET_FIELD(dialup, DIALUP_BIT, set_flags2, isc_boolean_t)
|
||||
FUNC_GET_FIELD(dialup, DIALUP_BIT, set_flags2, isc_boolean_t)
|
||||
|
||||
|
||||
|
||||
|
||||
/***
|
||||
*** PRIVATE
|
||||
***/
|
||||
|
||||
|
||||
static isc_result_t
|
||||
setdirectory(isc_cfgoptions_t *opts, char *directory, isc_mem_t *mem)
|
||||
set_text_region(isc_mem_t *mem, isc_textregion_t *region, const char *value)
|
||||
{
|
||||
if (opts->directory != NULL && opts->dirlen <= strlen(directory)) {
|
||||
isc_mem_put(mem, opts->directory, opts->dirlen);
|
||||
opts->directory = NULL;
|
||||
opts->dirlen = 0;
|
||||
size_t len;
|
||||
|
||||
INSIST(mem != NULL);
|
||||
INSIST(value != NULL);
|
||||
INSIST(region != NULL);
|
||||
|
||||
len = strlen(value) + 1;
|
||||
|
||||
INSIST(len > 1);
|
||||
CHECKREGION(region);
|
||||
|
||||
if (region->base != NULL && region->length < len) {
|
||||
isc_mem_put(mem, region->base, region->length);
|
||||
region->base = NULL;
|
||||
region->length = 0;
|
||||
}
|
||||
|
||||
if (opts->dirlen == 0) {
|
||||
int need = strlen(directory) + 1;
|
||||
|
||||
opts->directory = isc_mem_get(mem, need);
|
||||
if (opts->directory == NULL) {
|
||||
if (region->base == NULL) {
|
||||
region->base = isc_mem_get(mem, len);
|
||||
if (region->base == NULL) {
|
||||
return (ISC_R_NOMEMORY);
|
||||
}
|
||||
opts->dirlen = need;
|
||||
region->length = len;
|
||||
}
|
||||
|
||||
strcpy(opts->directory, directory);
|
||||
strcpy(region->base, value);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
@@ -150,14 +536,24 @@ freeoptions(isc_cfgoptions_t *opts, isc_mem_t *mem)
|
||||
{
|
||||
INSIST(opts != NULL);
|
||||
|
||||
if (opts->directory != NULL) {
|
||||
INSIST(opts->dirlen > 0);
|
||||
} else {
|
||||
INSIST(opts->dirlen == 0);
|
||||
}
|
||||
|
||||
isc_mem_put(mem, opts->directory, opts->dirlen);
|
||||
FREE_TEXT_REGION(&opts->directory, mem);
|
||||
FREE_TEXT_REGION(&opts->version, mem);
|
||||
FREE_TEXT_REGION(&opts->dump_filename, mem);
|
||||
FREE_TEXT_REGION(&opts->pid_filename, mem);
|
||||
FREE_TEXT_REGION(&opts->stats_filename, mem);
|
||||
FREE_TEXT_REGION(&opts->memstats_filename, mem);
|
||||
FREE_TEXT_REGION(&opts->named_xfer, mem);
|
||||
|
||||
isc_mem_put(mem, opts, sizeof *opts);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
opt_print_textregion(FILE *fp, const char *name, isc_textregion_t r)
|
||||
{
|
||||
CHECKREGION(&r);
|
||||
|
||||
if (r.length > 0) {
|
||||
fprintf(fp,"\t%s \"%s\";\n", name, r.base);
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,31 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/****
|
||||
**** MODULE INFO
|
||||
****/
|
||||
|
||||
/*
|
||||
* Top level Data structure and accessors for the data defined in the
|
||||
* config file.
|
||||
*
|
||||
* MP:
|
||||
*
|
||||
* Caller must do necessary locking.
|
||||
*
|
||||
* Reliability:
|
||||
*
|
||||
*
|
||||
* Resources:
|
||||
*
|
||||
*
|
||||
* Security:
|
||||
*
|
||||
*
|
||||
* Standards:
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(CONFIGCTX_H)
|
||||
#define CONFIGCTX_H 1
|
||||
|
||||
@@ -22,19 +47,87 @@
|
||||
|
||||
#include "zone.h"
|
||||
|
||||
/* Data from an 'options' config file statement */
|
||||
typedef struct isc_cfgoptions
|
||||
{
|
||||
size_t dirlen; /* XXX no counted strings? */
|
||||
char *directory;
|
||||
isc_textregion_t directory;
|
||||
isc_textregion_t version;
|
||||
isc_textregion_t dump_filename;
|
||||
isc_textregion_t pid_filename;
|
||||
isc_textregion_t stats_filename;
|
||||
isc_textregion_t memstats_filename;
|
||||
isc_textregion_t named_xfer;
|
||||
|
||||
unsigned int flags;
|
||||
unsigned int max_ncache_ttl;
|
||||
|
||||
int transfers_in;
|
||||
int transfers_per_ns;
|
||||
int transfers_out;
|
||||
int max_log_size_ixfr;
|
||||
int clean_interval;
|
||||
int interface_interval;
|
||||
int stats_interval;
|
||||
int heartbeat_interval;
|
||||
|
||||
isc_boolean_t fake_iquery;
|
||||
isc_boolean_t recursion;
|
||||
isc_boolean_t fetch_glue;
|
||||
isc_boolean_t notify;
|
||||
isc_boolean_t hoststats;
|
||||
isc_boolean_t dealloc_on_exit;
|
||||
isc_boolean_t use_ixfr;
|
||||
isc_boolean_t maintain_ixfr_base;
|
||||
isc_boolean_t has_old_clients;
|
||||
isc_boolean_t auth_nx_domain;
|
||||
isc_boolean_t multiple_cnames;
|
||||
isc_boolean_t use_id_pool;
|
||||
isc_boolean_t dialup;
|
||||
|
||||
long max_transfer_time_in;
|
||||
|
||||
unsigned long data_size;
|
||||
unsigned long stack_size;
|
||||
unsigned long core_size;
|
||||
unsigned long files;
|
||||
|
||||
#if 0
|
||||
struct sockaddr_in query_source;
|
||||
ip_match_list query_acl;
|
||||
ip_match_list transfer_acl;
|
||||
ip_match_list blackhole_acl;
|
||||
ip_match_list topology;
|
||||
#ifdef SORT_RESPONSE
|
||||
ip_match_list sortlist;
|
||||
#endif /* SORT_RESPONSE */
|
||||
|
||||
enum axfr_format transfer_format;
|
||||
|
||||
enum severity check_names[num_trans];
|
||||
listen_info_list listen_list;
|
||||
struct fwdinfo *fwdtab;
|
||||
|
||||
rrset_order_list ordering;
|
||||
#endif
|
||||
|
||||
/* For the non-pointer members of the struct a bit will be set in
|
||||
* this field if a value was explicitly set.
|
||||
*/
|
||||
isc_uint64_t set_flags1;
|
||||
isc_uint64_t set_flags2;
|
||||
} isc_cfgoptions_t;
|
||||
|
||||
|
||||
/* Master config structure. All the information defined in a config file is
|
||||
* reachable through here.
|
||||
*/
|
||||
typedef struct isc_cfgctx
|
||||
{
|
||||
int warnings;
|
||||
int errors;
|
||||
int warnings; /* number of parse warnings */
|
||||
int errors; /* number of parse semantic errors */
|
||||
|
||||
isc_mem_t *mem;
|
||||
isc_mem_t *mem; /* where we get our memory from */
|
||||
|
||||
isc_cfgoptions_t *options;
|
||||
isc_zonectx_t *zonecontext;
|
||||
|
||||
@@ -44,7 +137,110 @@ typedef struct isc_cfgctx
|
||||
|
||||
isc_result_t isc_cfg_newctx(isc_mem_t *mem, isc_cfgctx_t **ctx);
|
||||
isc_result_t isc_cfg_freectx(isc_cfgctx_t **ctx);
|
||||
isc_result_t isc_cfg_setdirectory(isc_cfgctx_t *ctx, char *directory);
|
||||
|
||||
/* Reset the options back to virgin state. */
|
||||
isc_result_t isc_cfg_erase_options(isc_cfgctx_t *ctx);
|
||||
|
||||
/* Send a properly formatted context to the given stream */
|
||||
void isc_cfg_dump_config(FILE *fp, isc_cfgctx_t *ctx);
|
||||
void isc_cfg_dump_options(FILE *fp, isc_cfgoptions_t *options);
|
||||
|
||||
|
||||
/* Set functions for all the options fields. */
|
||||
|
||||
isc_result_t isc_cfg_set_directory(isc_cfgctx_t *ctx, const char *directory);
|
||||
isc_result_t isc_cfg_set_version(isc_cfgctx_t *ctx, const char *directory);
|
||||
isc_result_t isc_cfg_set_dump_filename(isc_cfgctx_t *ctx,
|
||||
const char *directory);
|
||||
isc_result_t isc_cfg_set_pid_filename(isc_cfgctx_t *ctx,
|
||||
const char *directory);
|
||||
isc_result_t isc_cfg_set_stats_filename(isc_cfgctx_t *ctx,
|
||||
const char *directory);
|
||||
isc_result_t isc_cfg_set_memstats_filename(isc_cfgctx_t *ctx,
|
||||
const char *directory);
|
||||
isc_result_t isc_cfg_set_named_xfer(isc_cfgctx_t *ctx, const char *directory);
|
||||
isc_result_t isc_cfg_set_max_ncache_ttl(isc_cfgctx_t*ctx, unsigned int value);
|
||||
isc_result_t isc_cfg_set_transfers_in(isc_cfgctx_t*ctx, int value);
|
||||
isc_result_t isc_cfg_set_transfers_per_ns(isc_cfgctx_t*ctx, int value);
|
||||
isc_result_t isc_cfg_set_transfers_out(isc_cfgctx_t*ctx, int value);
|
||||
isc_result_t isc_cfg_set_max_log_size_ixfr(isc_cfgctx_t*ctx, int value);
|
||||
isc_result_t isc_cfg_set_clean_interval(isc_cfgctx_t*ctx, int value);
|
||||
isc_result_t isc_cfg_set_interface_interval(isc_cfgctx_t*ctx, int value);
|
||||
isc_result_t isc_cfg_set_stats_interval(isc_cfgctx_t*ctx, int value);
|
||||
isc_result_t isc_cfg_set_heartbeat_interval(isc_cfgctx_t*ctx, int value);
|
||||
isc_result_t isc_cfg_set_max_transfer_time_in(isc_cfgctx_t*ctx, long value);
|
||||
isc_result_t isc_cfg_set_data_size(isc_cfgctx_t *ctx, unsigned long value);
|
||||
isc_result_t isc_cfg_set_stack_size(isc_cfgctx_t *ctx, unsigned long value);
|
||||
isc_result_t isc_cfg_set_core_size(isc_cfgctx_t *ctx, unsigned long value);
|
||||
isc_result_t isc_cfg_set_files(isc_cfgctx_t *ctx, unsigned long value);
|
||||
|
||||
isc_result_t isc_cfg_set_fake_iquery(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_recursion(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_fetch_glue(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_notify(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_hoststats(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_dealloc_on_exit(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_use_ixfr(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_maintain_ixfr_base(isc_cfgctx_t *ctx,
|
||||
isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_has_old_clients(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_auth_nx_domain(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_multiple_cnames(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_use_id_pool(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
isc_result_t isc_cfg_set_dialup(isc_cfgctx_t *ctx, isc_boolean_t bv);
|
||||
|
||||
|
||||
/* Get functions for all the option fields. Caller must not modify the
|
||||
* results. If the fields was not set, the ISC_R_NOTFOUND is returned,
|
||||
* otherwise ISC_R_SUCCESS
|
||||
*/
|
||||
isc_result_t isc_cfg_get_named_xfer(isc_cfgctx_t *ctx, const char **result);
|
||||
isc_result_t isc_cfg_get_directory(isc_cfgctx_t *ctx, const char **result);
|
||||
isc_result_t isc_cfg_get_version(isc_cfgctx_t *ctx, const char **result);
|
||||
isc_result_t isc_cfg_get_dump_filename(isc_cfgctx_t *ctx,
|
||||
const char **result);
|
||||
isc_result_t isc_cfg_get_pid_filename(isc_cfgctx_t *ctx,
|
||||
const char **result);
|
||||
isc_result_t isc_cfg_get_stats_filename(isc_cfgctx_t *ctx,
|
||||
const char **result);
|
||||
isc_result_t isc_cfg_get_memstats_filename(isc_cfgctx_t *ctx,
|
||||
const char **result);
|
||||
isc_result_t isc_cfg_get_max_ncache_ttl(isc_cfgctx_t *ctx,
|
||||
unsigned int *result);
|
||||
isc_result_t isc_cfg_get_transfers_in(isc_cfgctx_t *ctx, int *result);
|
||||
isc_result_t isc_cfg_get_transfers_per_ns(isc_cfgctx_t *ctx, int *result);
|
||||
isc_result_t isc_cfg_get_transfers_out(isc_cfgctx_t *ctx, int *result);
|
||||
isc_result_t isc_cfg_get_max_log_size_ixfr(isc_cfgctx_t *ctx, int *result);
|
||||
isc_result_t isc_cfg_get_clean_interval(isc_cfgctx_t *ctx, int *result);
|
||||
isc_result_t isc_cfg_get_interface_interval(isc_cfgctx_t *ctx, int *result);
|
||||
isc_result_t isc_cfg_get_stats_interval(isc_cfgctx_t *ctx, int *result);
|
||||
isc_result_t isc_cfg_get_heartbeat_interval(isc_cfgctx_t *ctx, int *result);
|
||||
isc_result_t isc_cfg_get_max_transfer_time_in(isc_cfgctx_t *ctx, long *result);
|
||||
isc_result_t isc_cfg_get_data_size(isc_cfgctx_t *ctx, unsigned long *result);
|
||||
isc_result_t isc_cfg_get_stack_size(isc_cfgctx_t *ctx, unsigned long *result);
|
||||
isc_result_t isc_cfg_get_core_size(isc_cfgctx_t *ctx, unsigned long *result);
|
||||
isc_result_t isc_cfg_get_files(isc_cfgctx_t *ctx, unsigned long *result);
|
||||
|
||||
isc_result_t isc_cfg_get_fake_iquery(isc_cfgctx_t *ctx, isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_recursion(isc_cfgctx_t *ctx, isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_fetch_glue(isc_cfgctx_t *ctx, isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_notify(isc_cfgctx_t *ctx, isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_hoststats(isc_cfgctx_t *ctx, isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_dealloc_on_exit(isc_cfgctx_t *ctx,
|
||||
isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_use_ixfr(isc_cfgctx_t *ctx, isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_maintain_ixfr_base(isc_cfgctx_t *ctx,
|
||||
isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_has_old_clients(isc_cfgctx_t *ctx,
|
||||
isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_auth_nx_domain(isc_cfgctx_t *ctx,
|
||||
isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_multiple_cnames(isc_cfgctx_t *ctx,
|
||||
isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_use_id_pool(isc_cfgctx_t *ctx, isc_boolean_t *result);
|
||||
isc_result_t isc_cfg_get_dialup(isc_cfgctx_t *ctx, isc_boolean_t *result);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user