cfg_parse_ functions internally handle the parser

Instead of (1) allocating a parser, (2) parsing a file/buffer then (3)
freeing the parser, the parser is now internally created/destroyed from
within the `cfg_parse_*` functions. This simplifies a lot the use cases,
especially around the error cases where the parser needs to be freed in
a cleanup goto.

The only trick was the parser callback mechanism, which would previously
have been set up between steps 1 and 2.  Since it's never been used for
any purpose other than the "directory" option, the chdir call has now
been moved inside the parser and the generic callback mechanism has been
removed, replacing CFG_CLAUSEFLAG_CALLBACK with CFG_CLAUSEFLAG_CHDIR.
This commit is contained in:
Colin Vidal 2025-10-22 11:49:09 +02:00 committed by Evan Hunt
parent 0191ba5540
commit d03f6e6fd4
25 changed files with 250 additions and 425 deletions

View file

@ -63,32 +63,6 @@ usage(void) {
exit(EXIT_SUCCESS);
}
/*% directory callback */
static isc_result_t
directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
isc_result_t result;
const char *directory;
REQUIRE(strcasecmp("directory", clausename) == 0);
UNUSED(arg);
UNUSED(clausename);
/*
* Change directory.
*/
directory = cfg_obj_asstring(obj);
result = isc_dir_chdir(directory);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"change directory to '%s' failed: %s\n", directory,
isc_result_totext(result));
return result;
}
return ISC_R_SUCCESS;
}
static bool
get_maps(const cfg_obj_t **maps, const char *name, const cfg_obj_t **obj) {
int i;
@ -574,16 +548,14 @@ output(void *closure, const char *text, int textlen) {
int
main(int argc, char **argv) {
int c;
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL;
const char *conffile = NULL;
isc_result_t result = ISC_R_SUCCESS;
bool load_zones = false;
bool list_zones = false;
bool print = false;
bool nodeprecate = false;
bool allconfigs = false;
unsigned int flags = 0;
unsigned int parserflags = 0;
unsigned int checkflags = BIND_CHECK_PLUGINS | BIND_CHECK_ALGORITHMS;
isc_commandline_init(argc, argv);
@ -631,7 +603,7 @@ main(int argc, char **argv) {
break;
case 'i':
nodeprecate = true;
parserflags |= CFG_PCTX_NODEPRECATED;
break;
case 'j':
@ -650,7 +622,7 @@ main(int argc, char **argv) {
break;
case 'n':
allconfigs = true;
parserflags |= CFG_PCTX_ALLCONFIGS;
break;
case 't':
@ -722,18 +694,8 @@ main(int argc, char **argv) {
}
CHECK(setup_logging(stdout));
CHECK(cfg_parser_create(isc_g_mctx, &parser));
if (nodeprecate) {
cfg_parser_setflags(parser, CFG_PCTX_NODEPRECATED, true);
}
if (allconfigs) {
cfg_parser_setflags(parser, CFG_PCTX_ALLCONFIGS, true);
}
cfg_parser_setcallback(parser, directory_callback, NULL);
CHECK(cfg_parse_file(parser, conffile, &cfg_type_namedconf, &config));
CHECK(cfg_parse_file(isc_g_mctx, conffile, &cfg_type_namedconf,
parserflags, &config));
CHECK(isccfg_check_namedconf(config, checkflags, isc_g_mctx));
if (load_zones || list_zones) {
CHECK(load_zones_fromconfig(config, list_zones));
@ -748,9 +710,5 @@ cleanup:
cfg_obj_detach(&config);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
return result == ISC_R_SUCCESS ? 0 : 1;
}

View file

@ -808,7 +808,6 @@ cleanup:
static isc_result_t
setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) {
isc_result_t result;
cfg_parser_t *parser = NULL;
const cfg_obj_t *trust_anchors = NULL;
cfg_obj_t *bindkeys = NULL;
@ -824,15 +823,13 @@ setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) {
CHECK(convert_name(&afn, &anchor_name, trust_anchor));
}
CHECK(cfg_parser_create(isc_g_mctx, &parser));
if (anchorfile != NULL) {
if (access(anchorfile, R_OK) != 0) {
fatal("Unable to read key file '%s'", anchorfile);
}
result = cfg_parse_file(parser, anchorfile, &cfg_type_bindkeys,
&bindkeys);
result = cfg_parse_file(isc_g_mctx, anchorfile,
&cfg_type_bindkeys, 0, &bindkeys);
if (result != ISC_R_SUCCESS) {
fatal("Unable to load keys from '%s'", anchorfile);
}
@ -841,8 +838,7 @@ setup_dnsseckeys(dns_client_t *client, dns_view_t *toview) {
isc_buffer_init(&b, anchortext, sizeof(anchortext) - 1);
isc_buffer_add(&b, sizeof(anchortext) - 1);
cfg_parser_reset(parser);
result = cfg_parse_buffer(parser, &b, NULL, 0,
result = cfg_parse_buffer(isc_g_mctx, &b, NULL, 0,
&cfg_type_bindkeys, 0, &bindkeys);
if (result != ISC_R_SUCCESS) {
fatal("Unable to parse built-in keys");
@ -864,9 +860,6 @@ cleanup:
if (bindkeys != NULL) {
cfg_obj_detach(&bindkeys);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
if (result != ISC_R_SUCCESS) {
delv_log(ISC_LOG_ERROR, "setup_dnsseckeys: %s",
isc_result_totext(result));

View file

@ -1072,7 +1072,6 @@ parse_hmac(const char *algname) {
*/
static isc_result_t
read_confkey(void) {
cfg_parser_t *pctx = NULL;
cfg_obj_t *file = NULL;
const cfg_obj_t *keyobj = NULL;
const cfg_obj_t *secretobj = NULL;
@ -1086,12 +1085,8 @@ read_confkey(void) {
return ISC_R_FILENOTFOUND;
}
result = cfg_parser_create(isc_g_mctx, &pctx);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey, &file);
result = cfg_parse_file(isc_g_mctx, keyfile, &cfg_type_sessionkey, 0,
&file);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
@ -1117,11 +1112,8 @@ read_confkey(void) {
setup_text_key();
cleanup:
if (pctx != NULL) {
if (file != NULL) {
cfg_obj_detach(&file);
}
cfg_parser_destroy(&pctx);
if (file != NULL) {
cfg_obj_detach(&file);
}
return result;

View file

@ -1147,14 +1147,11 @@ main(int argc, char **argv) {
keygen(&ctx, argc, argv);
} else {
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL;
dns_kasp_t *kasp = NULL;
RUNTIME_CHECK(cfg_parser_create(isc_g_mctx, &parser) ==
ISC_R_SUCCESS);
if (cfg_parse_file(parser, ctx.configfile,
&cfg_type_namedconf,
if (cfg_parse_file(isc_g_mctx, ctx.configfile,
&cfg_type_namedconf, 0,
&config) != ISC_R_SUCCESS)
{
fatal("unable to load dnssec-policy '%s' from "
@ -1200,7 +1197,6 @@ main(int argc, char **argv) {
dns_kasp_detach(&kasp);
cfg_obj_detach(&config);
cfg_parser_destroy(&parser);
}
} else {
keygen(&ctx, argc, argv);

View file

@ -170,11 +170,9 @@ checkparams(ksr_ctx_t *ksr, const char *command) {
static void
getkasp(ksr_ctx_t *ksr, dns_kasp_t **kasp) {
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL;
RUNTIME_CHECK(cfg_parser_create(isc_g_mctx, &parser) == ISC_R_SUCCESS);
if (cfg_parse_file(parser, ksr->configfile, &cfg_type_namedconf,
if (cfg_parse_file(isc_g_mctx, ksr->configfile, &cfg_type_namedconf, 0,
&config) != ISC_R_SUCCESS)
{
fatal("unable to load dnssec-policy '%s' from '%s'",
@ -188,7 +186,6 @@ getkasp(ksr_ctx_t *ksr, dns_kasp_t **kasp) {
fatal("dnssec-policy '%s' has no keys configured", ksr->policy);
}
cfg_obj_detach(&config);
cfg_parser_destroy(&parser);
}
static int

View file

@ -363,89 +363,28 @@ remote-servers " DEFAULT_IANA_ROOT_ZONE_PRIMARIES " {\n\
isc_result_t
named_config_parsedefaults(cfg_obj_t **conf) {
isc_buffer_t b;
cfg_parser_t *parser = NULL;
isc_result_t result;
result = cfg_parser_create(isc_g_mctx, &parser);
if (result != ISC_R_SUCCESS) {
return result;
}
isc_buffer_init(&b, defaultconf, sizeof(defaultconf) - 1);
isc_buffer_add(&b, sizeof(defaultconf) - 1);
result = cfg_parse_buffer(parser, &b, __FILE__, 0, &cfg_type_namedconf,
CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE |
CFG_PCTX_NOEXPERIMENTAL,
conf);
cfg_parser_destroy(&parser);
return result;
}
/*
* This function is called as soon as the 'directory' statement has been
* parsed. This can be extended to support other options if necessary.
*/
static isc_result_t
directory_callback(const char *clausename, const cfg_obj_t *obj, void *arg) {
isc_result_t result;
const char *directory;
REQUIRE(strcasecmp("directory", clausename) == 0);
UNUSED(arg);
UNUSED(clausename);
/*
* Change directory.
*/
directory = cfg_obj_asstring(obj);
if (!isc_file_ischdiridempotent(directory)) {
cfg_obj_log(obj, ISC_LOG_WARNING,
"option 'directory' contains relative path '%s'",
directory);
}
if (!isc_file_isdirwritable(directory)) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_ERROR, "directory '%s' is not writable",
directory);
return ISC_R_NOPERM;
}
result = isc_dir_chdir(directory);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"change directory to '%s' failed: %s", directory,
isc_result_totext(result));
return result;
}
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) == cwd) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_INFO, "the working directory is now '%s'",
cwd);
}
return ISC_R_SUCCESS;
return cfg_parse_buffer(isc_g_mctx, &b, __FILE__, 0,
&cfg_type_namedconf,
CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE |
CFG_PCTX_NOEXPERIMENTAL,
conf);
}
isc_result_t
named_config_parsefile(cfg_parser_t *parser, cfg_obj_t **conf) {
named_config_parsefile(cfg_obj_t **conf) {
isc_result_t result;
REQUIRE(parser);
REQUIRE(conf && *conf == NULL);
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_INFO, "parsing user configuration from '%s'",
named_g_conffile);
cfg_parser_setcallback(parser, directory_callback, NULL);
result = cfg_parse_file(parser, named_g_conffile, &cfg_type_namedconf,
conf);
result = cfg_parse_file(isc_g_mctx, named_g_conffile,
&cfg_type_namedconf, 0, conf);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}

View file

@ -787,7 +787,6 @@ register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist,
static isc_result_t
get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
isc_result_t result;
cfg_parser_t *pctx = NULL;
cfg_obj_t *config = NULL;
const cfg_obj_t *key = NULL;
const cfg_obj_t *algobj = NULL;
@ -806,8 +805,7 @@ get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
return ISC_R_FILENOTFOUND;
}
CHECK(cfg_parser_create(mctx, &pctx));
CHECK(cfg_parse_file(pctx, named_g_keyfile, &cfg_type_rndckey,
CHECK(cfg_parse_file(mctx, named_g_keyfile, &cfg_type_rndckey, 0,
&config));
CHECK(cfg_map_get(config, "key", &key));
@ -863,9 +861,6 @@ cleanup:
if (config != NULL) {
cfg_obj_detach(&config);
}
if (pctx != NULL) {
cfg_parser_destroy(&pctx);
}
return result;
}

View file

@ -28,7 +28,7 @@ isc_result_t
named_config_parsedefaults(cfg_obj_t **conf);
isc_result_t
named_config_parsefile(cfg_parser_t *parser, cfg_obj_t **conf);
named_config_parsefile(cfg_obj_t **conf);
const char *
named_config_getdefault(void);

View file

@ -2349,7 +2349,6 @@ catz_addmodzone_cb(void *arg) {
cfg_obj_t *zoneobj = NULL;
ns_cfgctx_t *cfg = NULL;
dns_zone_t *zone = NULL;
cfg_parser_t *parser = NULL;
if (isc_loop_shuttingdown(isc_loop_get(isc_tid()))) {
goto cleanup;
@ -2464,10 +2463,8 @@ catz_addmodzone_cb(void *arg) {
confbuf = NULL;
result = dns_catz_generate_zonecfg(cz->origin, cz->entry, &confbuf);
if (result == ISC_R_SUCCESS) {
CHECK(cfg_parser_create(cfg->mctx, &parser));
result = cfg_parse_buffer(parser, confbuf, "catz", 0,
result = cfg_parse_buffer(cfg->mctx, confbuf, "catz", 0,
&cfg_type_addzoneconf, 0, &zoneconf);
cfg_parser_destroy(&parser);
isc_buffer_free(&confbuf);
}
/*
@ -2721,7 +2718,6 @@ catz_reconfigure(dns_catz_entry_t *entry, void *arg1, void *arg2) {
ns_cfgctx_t *cfg = NULL;
dns_zone_t *zone = NULL;
isc_result_t result;
cfg_parser_t *parser = NULL;
isc_buffer_init(&namebuf, nameb, DNS_NAME_FORMATSIZE);
dns_name_totext(dns_catz_entry_getname(entry), DNS_NAME_OMITFINALDOT,
@ -2745,10 +2741,8 @@ catz_reconfigure(dns_catz_entry_t *entry, void *arg1, void *arg2) {
result = dns_catz_generate_zonecfg(data->catz, entry, &confbuf);
if (result == ISC_R_SUCCESS) {
CHECK(cfg_parser_create(cfg->mctx, &parser));
result = cfg_parse_buffer(parser, confbuf, "catz", 0,
result = cfg_parse_buffer(cfg->mctx, confbuf, "catz", 0,
&cfg_type_addzoneconf, 0, &zoneconf);
cfg_parser_destroy(&parser);
isc_buffer_free(&confbuf);
}
/*
@ -7558,7 +7552,6 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, isc_buffer_t **text,
size_t zone_config_len;
cfg_obj_t *zoneconf = NULL;
char bufname[DNS_NAME_FORMATSIZE];
cfg_parser_t *parser = NULL;
REQUIRE(view != NULL);
REQUIRE(key != NULL);
@ -7596,10 +7589,8 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, isc_buffer_t **text,
snprintf(bufname, sizeof(bufname), "%.*s", (int)zone_name_len,
zone_name);
CHECK(cfg_parser_create(view->mctx, &parser));
result = cfg_parse_buffer(parser, *text, bufname, 0,
result = cfg_parse_buffer(view->mctx, *text, bufname, 0,
&cfg_type_addzoneconf, 0, &zoneconf);
cfg_parser_destroy(&parser);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_ERROR,
@ -9232,14 +9223,12 @@ cleanup_aclctx:
static isc_result_t
load_configuration(named_server_t *server, bool first_time) {
isc_result_t result;
cfg_parser_t *parser = NULL;
cfg_obj_t *config = NULL, *bindkeys = NULL;
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_DEBUG(1), "load_configuration");
CHECK(cfg_parser_create(isc_g_mctx, &parser));
CHECK(named_config_parsefile(parser, &config));
CHECK(named_config_parsefile(&config));
if (named_g_bindkeysfile != NULL) {
/*
@ -9255,9 +9244,9 @@ load_configuration(named_server_t *server, bool first_time) {
"keys instead",
named_g_bindkeysfile);
} else {
cfg_parser_reset(parser);
result = cfg_parse_file(parser, named_g_bindkeysfile,
&cfg_type_bindkeys, &bindkeys);
result = cfg_parse_file(
isc_g_mctx, named_g_bindkeysfile,
&cfg_type_bindkeys, 0, &bindkeys);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER,
@ -9274,9 +9263,6 @@ load_configuration(named_server_t *server, bool first_time) {
result = apply_configuration(config, bindkeys, server, first_time);
cleanup:
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
if (bindkeys != NULL) {
cfg_obj_detach(&bindkeys);
}
@ -12466,9 +12452,8 @@ load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg) {
* Parse the configuration in the NZF file. This may be called in
* multiple views, so we reset the parser each time.
*/
cfg_parser_reset(named_g_addparser);
result = cfg_parse_file(named_g_addparser, view->new_zone_file,
&cfg_type_addzoneconf, &nzcfg->nzf_config);
result = cfg_parse_file(nzcfg->mctx, view->new_zone_file,
&cfg_type_addzoneconf, 0, &nzcfg->nzf_config);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_ERROR, "Error parsing NZF file '%s': %s",
@ -12816,7 +12801,6 @@ load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg) {
MDB_dbi dbi;
MDB_val key, data;
ns_dzarg_t dzarg;
cfg_parser_t *parser = NULL;
UNUSED(nzcfg);
@ -12840,10 +12824,8 @@ load_nzf(dns_view_t *view, ns_cfgctx_t *nzcfg) {
* config type, giving us a guarantee that valid configuration
* will be written to DB.
*/
CHECK(cfg_parser_create(nzcfg->mctx, &parser));
result = cfg_parse_file(parser, view->new_zone_file,
&cfg_type_addzoneconf, &nzf_config);
cfg_parser_destroy(&parser);
result = cfg_parse_file(nzcfg->mctx, view->new_zone_file,
&cfg_type_addzoneconf, 0, &nzf_config);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL, NAMED_LOGMODULE_SERVER,
ISC_LOG_ERROR, "Error parsing NZF file '%s': %s",
@ -12973,7 +12955,6 @@ newzone_parse(named_server_t *server, char *command, dns_view_t **viewp,
dns_rdataclass_t rdclass;
dns_view_t *view = NULL;
const char *bn = NULL;
cfg_parser_t *parser = NULL;
REQUIRE(viewp != NULL && *viewp == NULL);
REQUIRE(zoneobjp != NULL && *zoneobjp == NULL);
@ -12998,10 +12979,8 @@ newzone_parse(named_server_t *server, char *command, dns_view_t **viewp,
*/
isc_buffer_forward(&argbuf, 3);
CHECK(cfg_parser_create(server->mctx, &parser));
CHECK(cfg_parse_buffer(parser, &argbuf, bn, 0, &cfg_type_addzoneconf, 0,
&zoneconf));
cfg_parser_destroy(&parser);
CHECK(cfg_parse_buffer(server->mctx, &argbuf, bn, 0,
&cfg_type_addzoneconf, 0, &zoneconf));
CHECK(cfg_map_get(zoneconf, "zone", &zlist));
if (!cfg_obj_islist(zlist)) {
@ -13076,10 +13055,6 @@ newzone_parse(named_server_t *server, char *command, dns_view_t **viewp,
return ISC_R_SUCCESS;
cleanup:
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
if (zoneconf != NULL) {
cfg_obj_detach(&zoneconf);
}
@ -13091,13 +13066,12 @@ cleanup:
}
static isc_result_t
delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, const cfg_obj_t *config,
delete_zoneconf(dns_view_t *view, const cfg_obj_t *config,
const dns_name_t *zname, nzfwriter_t nzfwriter) {
isc_result_t result = ISC_R_NOTFOUND;
const cfg_obj_t *zl = NULL;
REQUIRE(view != NULL);
REQUIRE(pctx != NULL);
REQUIRE(config != NULL);
REQUIRE(zname != NULL);
@ -13126,7 +13100,6 @@ delete_zoneconf(dns_view_t *view, cfg_parser_t *pctx, const cfg_obj_t *config,
e = UNCONST(elt);
ISC_LIST_UNLINK(*list, e, link);
cfg_obj_detach(&e->obj);
isc_mem_put(pctx->mctx, e, sizeof(*e));
result = ISC_R_SUCCESS;
break;
}
@ -13263,8 +13236,7 @@ do_addzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
cfg_obj_attach(zoneconf, &cfg->nzf_config);
} else {
cfg_obj_t *z = UNCONST(zoneobj);
CHECK(cfg_parser_mapadd(cfg->add_parser, cfg->nzf_config, z,
"zone"));
CHECK(cfg_parser_mapadd(cfg->nzf_config, z, "zone"));
}
cleanup_config = true;
#endif /* HAVE_LMDB */
@ -13313,8 +13285,7 @@ cleanup:
(void)isc_stdio_close(fp);
}
if (result != ISC_R_SUCCESS && cleanup_config) {
tresult = delete_zoneconf(view, cfg->add_parser,
cfg->nzf_config, name, NULL);
tresult = delete_zoneconf(view, cfg->nzf_config, name, NULL);
RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
}
#else /* HAVE_LMDB */
@ -13341,7 +13312,6 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
dns_zone_t *zone = NULL;
const cfg_obj_t *voptions = NULL;
bool added;
cfg_parser_t *parser = NULL;
#ifndef HAVE_LMDB
FILE *fp = NULL;
cfg_obj_t *z;
@ -13448,7 +13418,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
#ifndef HAVE_LMDB
/* Remove old zone from configuration (and NZF file if applicable) */
if (added) {
result = delete_zoneconf(view, cfg->add_parser, cfg->nzf_config,
result = delete_zoneconf(view, cfg->nzf_config,
dns_zone_getorigin(zone),
nzf_writeconf);
if (result != ISC_R_SUCCESS) {
@ -13461,18 +13431,15 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
#endif /* HAVE_LMDB */
if (!added) {
TCHECK(cfg_parser_create(cfg->mctx, &parser));
if (cfg->vconfig == NULL) {
result = delete_zoneconf(view, parser, cfg->config,
result = delete_zoneconf(view, cfg->config,
dns_zone_getorigin(zone),
NULL);
} else {
voptions = cfg_tuple_get(cfg->vconfig, "options");
result = delete_zoneconf(view, parser, voptions,
dns_zone_getorigin(zone),
NULL);
result = delete_zoneconf(
view, voptions, dns_zone_getorigin(zone), NULL);
}
cfg_parser_destroy(&parser);
if (result != ISC_R_SUCCESS) {
TCHECK(putstr(text, "former zone configuration "
@ -13520,7 +13487,7 @@ do_modzone(named_server_t *server, ns_cfgctx_t *cfg, dns_view_t *view,
#ifndef HAVE_LMDB
/* Store the new zone configuration; also in NZF if applicable */
z = UNCONST(zoneobj);
CHECK(cfg_parser_mapadd(cfg->add_parser, cfg->nzf_config, z, "zone"));
CHECK(cfg_parser_mapadd(cfg->nzf_config, z, "zone"));
#endif /* HAVE_LMDB */
if (added) {
@ -13695,7 +13662,6 @@ rmzone(void *arg) {
dns_db_t *dbp = NULL;
bool added;
isc_result_t result;
cfg_parser_t *parser = NULL;
#ifdef HAVE_LMDB
MDB_txn *txn = NULL;
MDB_dbi dbi;
@ -13746,7 +13712,7 @@ rmzone(void *arg) {
}
UNLOCK(&view->new_zone_lock);
#else /* ifdef HAVE_LMDB */
result = delete_zoneconf(view, cfg->add_parser, cfg->nzf_config,
result = delete_zoneconf(view, cfg->nzf_config,
dns_zone_getorigin(zone),
nzf_writeconf);
if (result != ISC_R_SUCCESS) {
@ -13759,24 +13725,17 @@ rmzone(void *arg) {
}
if (!added && cfg != NULL) {
result = cfg_parser_create(cfg->mctx, &parser);
INSIST(result == ISC_R_SUCCESS); /* colin: this is just a
shortcut until the
initialization function of
the parser can't fails */
if (cfg->vconfig != NULL) {
const cfg_obj_t *voptions = cfg_tuple_get(cfg->vconfig,
"options");
result = delete_zoneconf(view, parser, voptions,
dns_zone_getorigin(zone),
NULL);
result = delete_zoneconf(
view, voptions, dns_zone_getorigin(zone), NULL);
} else {
result = delete_zoneconf(view, parser, cfg->config,
result = delete_zoneconf(view, cfg->config,
dns_zone_getorigin(zone),
NULL);
}
cfg_parser_destroy(&parser);
if (result != ISC_R_SUCCESS) {
isc_log_write(NAMED_LOGCATEGORY_GENERAL,
NAMED_LOGMODULE_SERVER, ISC_LOG_ERROR,

View file

@ -555,7 +555,6 @@ failure:
*/
static isc_result_t
read_sessionkey(isc_mem_t *mctx) {
cfg_parser_t *pctx = NULL;
cfg_obj_t *sessionkey = NULL;
const cfg_obj_t *key = NULL;
const cfg_obj_t *secretobj = NULL;
@ -570,12 +569,7 @@ read_sessionkey(isc_mem_t *mctx) {
return ISC_R_FILENOTFOUND;
}
result = cfg_parser_create(mctx, &pctx);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
result = cfg_parse_file(pctx, keyfile, &cfg_type_sessionkey,
result = cfg_parse_file(mctx, keyfile, &cfg_type_sessionkey, 0,
&sessionkey);
if (result != ISC_R_SUCCESS) {
goto cleanup;
@ -602,11 +596,8 @@ read_sessionkey(isc_mem_t *mctx) {
setup_keystr();
cleanup:
if (pctx != NULL) {
if (sessionkey != NULL) {
cfg_obj_detach(&sessionkey);
}
cfg_parser_destroy(&pctx);
if (sessionkey != NULL) {
cfg_obj_detach(&sessionkey);
}
if (keystr != NULL) {

View file

@ -274,16 +274,13 @@ parse_parameters(filter_instance_t *inst, const char *parameters,
const void *cfg, const char *cfg_file, unsigned long cfg_line,
isc_mem_t *mctx, void *aclctx) {
isc_result_t result = ISC_R_SUCCESS;
cfg_parser_t *parser = NULL;
cfg_obj_t *param_obj = NULL;
const cfg_obj_t *obj = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(parse_filter_a_on(param_obj, "filter-a-on-v6", &inst->v6_a));
@ -302,9 +299,6 @@ cleanup:
if (param_obj != NULL) {
cfg_obj_detach(&param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
return result;
}
@ -368,15 +362,12 @@ plugin_check(const char *parameters, const void *cfg, const char *cfg_file,
unsigned long cfg_line, isc_mem_t *mctx, void *aclctx,
const ns_pluginctx_t *ctx ISC_ATTR_UNUSED) {
isc_result_t result = ISC_R_SUCCESS;
cfg_parser_t *parser = NULL;
cfg_obj_t *param_obj = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(check_syntax(param_obj, cfg, mctx, aclctx));
@ -385,9 +376,6 @@ cleanup:
if (param_obj != NULL) {
cfg_obj_detach(&param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
return result;
}

View file

@ -275,16 +275,13 @@ parse_parameters(filter_instance_t *inst, const char *parameters,
const void *cfg, const char *cfg_file, unsigned long cfg_line,
isc_mem_t *mctx, void *aclctx) {
isc_result_t result = ISC_R_SUCCESS;
cfg_parser_t *parser = NULL;
cfg_obj_t *param_obj = NULL;
const cfg_obj_t *obj = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(parse_filter_aaaa_on(param_obj, "filter-aaaa-on-v4",
@ -305,9 +302,6 @@ cleanup:
if (param_obj != NULL) {
cfg_obj_detach(&param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
return result;
}
@ -372,15 +366,12 @@ plugin_check(const char *parameters, const void *cfg, const char *cfg_file,
unsigned long cfg_line, isc_mem_t *mctx, void *aclctx,
const ns_pluginctx_t *ctx ISC_ATTR_UNUSED) {
isc_result_t result = ISC_R_SUCCESS;
cfg_parser_t *parser = NULL;
cfg_obj_t *param_obj = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfg_file, cfg_line,
CHECK(cfg_parse_buffer(mctx, &b, cfg_file, cfg_line,
&cfg_type_parameters, 0, &param_obj));
CHECK(check_syntax(param_obj, cfg, mctx, aclctx));
@ -389,9 +380,6 @@ cleanup:
if (param_obj != NULL) {
cfg_obj_detach(&param_obj);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
return result;
}

View file

@ -573,16 +573,13 @@ synthrecord_parseconfig(synthrecord_t *inst, const char *parameters,
const dns_name_t *zname) {
isc_result_t result;
isc_mem_t *mctx = inst->mctx;
cfg_parser_t *parser = NULL;
cfg_obj_t *synthrecordcfg = NULL;
isc_buffer_t b;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfgfile, cfgline,
CHECK(cfg_parse_buffer(mctx, &b, cfgfile, cfgline,
&synthrecord_cfgparams, 0, &synthrecordcfg));
synthrecord_setconfigmode(inst, zname);
@ -596,10 +593,6 @@ cleanup:
cfg_obj_detach(&synthrecordcfg);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
return result;
}

View file

@ -535,8 +535,7 @@ rndc_start(void *arg) {
}
static void
parse_config(isc_mem_t *mctx, const char *keyname, cfg_parser_t **pctxp,
cfg_obj_t **configp) {
parse_config(isc_mem_t *mctx, const char *keyname, cfg_obj_t **configp) {
isc_result_t result;
const char *conffile = admin_conffile;
const cfg_obj_t *addresses = NULL;
@ -577,12 +576,10 @@ parse_config(isc_mem_t *mctx, const char *keyname, cfg_parser_t **pctxp,
admin_keyfile, admin_conffile);
}
DO("create parser", cfg_parser_create(mctx, pctxp));
/*
* The parser will output its own errors, so DO() is not used.
*/
result = cfg_parse_file(*pctxp, conffile, conftype, &config);
result = cfg_parse_file(mctx, conffile, conftype, 0, &config);
if (result != ISC_R_SUCCESS) {
fatal("could not load rndc configuration");
}
@ -809,7 +806,6 @@ int
main(int argc, char **argv) {
bool show_final_mem = false;
isc_logconfig_t *logconfig = NULL;
cfg_parser_t *pctx = NULL;
cfg_obj_t *config = NULL;
const char *keyname = NULL;
struct in_addr in;
@ -963,7 +959,7 @@ main(int argc, char **argv) {
ISC_LOG_PRINTTAG | ISC_LOG_PRINTLEVEL, ISC_LOGCATEGORY_DEFAULT,
ISC_LOGMODULE_DEFAULT);
parse_config(isc_g_mctx, keyname, &pctx, &config);
parse_config(isc_g_mctx, keyname, &config);
isc_buffer_allocate(isc_g_mctx, &databuf, 2048);
@ -1000,7 +996,6 @@ main(int argc, char **argv) {
isccc_ccmsg_invalidate(&rndc_ccmsg);
cfg_obj_detach(&config);
cfg_parser_destroy(&pctx);
isc_mem_put(isc_g_mctx, args, argslen);

View file

@ -522,6 +522,7 @@ n=$((n + 1))
echo_i "check that named-checkconf -l prints out the zone list ($n)"
ret=0
$CHECKCONF -l good.conf \
| grep -v "working directory is" \
| grep -v "is deprecated" \
| grep -v "is not implemented" \
| grep -v "is not recommended" \

View file

@ -116,7 +116,6 @@ plugin_register(const char *parameters, const void *cfg, const char *cfgfile,
ns_hooktable_t *hooktable, const ns_pluginctx_t *ctx,
void **instp) {
isc_result_t result;
cfg_parser_t *parser = NULL;
cfg_obj_t *syncplugincfg = NULL;
const cfg_obj_t *obj = NULL;
isc_buffer_t b;
@ -135,12 +134,10 @@ plugin_register(const char *parameters, const void *cfg, const char *cfgfile,
*inst = (syncplugin_t){ .mctx = mctx };
*instp = inst;
CHECK(cfg_parser_create(mctx, &parser));
isc_buffer_constinit(&b, parameters, strlen(parameters));
isc_buffer_add(&b, strlen(parameters));
CHECK(cfg_parse_buffer(parser, &b, cfgfile, cfgline,
CHECK(cfg_parse_buffer(mctx, &b, cfgfile, cfgline,
&syncplugin__cfgparams, 0, &syncplugincfg));
CHECK(syncplugin__parse_rcode(syncplugincfg, &inst->rcode));
@ -220,10 +217,6 @@ cleanup:
cfg_obj_detach(&syncplugincfg);
}
if (parser != NULL) {
cfg_parser_destroy(&parser);
}
return result;
}

View file

@ -52,7 +52,6 @@ int
main(int argc, char **argv) {
isc_result_t result;
isc_mem_t *mctx = NULL;
cfg_parser_t *pctx = NULL;
cfg_obj_t *cfg = NULL;
cfg_type_t *type = NULL;
bool grammar = false;
@ -134,9 +133,7 @@ main(int argc, char **argv) {
if (type == NULL || filename == NULL) {
usage();
}
RUNTIME_CHECK(cfg_parser_create(mctx, &pctx) == ISC_R_SUCCESS);
result = cfg_parse_file(pctx, filename, type, &cfg);
result = cfg_parse_file(mctx, filename, type, 0, &cfg);
fprintf(stderr, "read config: %s\n", isc_result_totext(result));
@ -147,8 +144,6 @@ main(int argc, char **argv) {
cfg_print(cfg, output, NULL);
cfg_obj_detach(&cfg);
cfg_parser_destroy(&pctx);
}
if (memstats) {

View file

@ -113,25 +113,12 @@ cfg_parser_setflags(cfg_parser_t *pctx, unsigned int flags, bool turn_on);
*\li "pctx" is not NULL.
*/
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(isc_mem_t *mctx, const char *file, const cfg_type_t *type,
unsigned int flags, cfg_obj_t **ret);
isc_result_t
cfg_parse_file(cfg_parser_t *pctx, const char *file, const cfg_type_t *type,
cfg_obj_t **ret);
isc_result_t
cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
cfg_parse_buffer(isc_mem_t *mctx, isc_buffer_t *buffer, const char *file,
unsigned int line, const cfg_type_t *type, unsigned int flags,
cfg_obj_t **ret);
/*%<
@ -152,8 +139,9 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
* Returns an error if the file or buffer does not parse correctly.
*
* Requires:
*\li "filename" is valid.
*\li "mem" is valid.
*\li "file" is valid.
*\li "buffer" is valid.
*\li "mctx" is valid.
*\li "type" is valid.
*\li "cfg" is non-NULL and "*cfg" is NULL.
*\li "flags" be one or more of CFG_PCTX_NODEPRECATED or zero.
@ -165,8 +153,7 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
*/
isc_result_t
cfg_parser_mapadd(cfg_parser_t *pctx, cfg_obj_t *mapobj, cfg_obj_t *obj,
const char *clause);
cfg_parser_mapadd(cfg_obj_t *mapobj, cfg_obj_t *obj, const char *clause);
/*%<
* Add the object 'obj' to the specified clause in mapbody 'mapobj'.
* Used for adding new zones.
@ -174,7 +161,6 @@ cfg_parser_mapadd(cfg_parser_t *pctx, cfg_obj_t *mapobj, cfg_obj_t *obj,
* Require:
* \li 'obj' is a valid cfg_obj_t.
* \li 'mapobj' is a valid cfg_obj_t of type map.
* \li 'pctx' is a valid cfg_parser_t.
*/
void

View file

@ -47,11 +47,8 @@ enum {
/*% Clause is obsolete (logs a warning, but is not a fatal error) */
CFG_CLAUSEFLAG_OBSOLETE = 1 << 3,
/*%
* Clause needs to be interpreted during parsing by calling a
* callback function, like the "directory" option.
*/
CFG_CLAUSEFLAG_CALLBACK = 1 << 4,
/*% Clause indicates it must change the current directory */
CFG_CLAUSEFLAG_CHDIR = 1 << 4,
/*% Clause that is only used in testing. */
CFG_CLAUSEFLAG_TESTONLY = 1 << 5,
@ -266,9 +263,6 @@ struct cfg_parser {
/*%< Reference counter */
isc_refcount_t references;
cfg_parsecallback_t callback;
void *callbackarg;
};
/* Parser context flags */
@ -438,7 +432,8 @@ 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);
cfg_create_list(isc_mem_t *mctx, cfg_obj_t *file, size_t line,
const cfg_type_t *type, cfg_obj_t **objp);
isc_result_t
cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,

View file

@ -1232,7 +1232,7 @@ static cfg_clausedef_t options_clauses[] = {
{ "coresize", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "datasize", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "deallocate-on-exit", NULL, CFG_CLAUSEFLAG_ANCIENT },
{ "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CALLBACK },
{ "directory", &cfg_type_qstring, CFG_CLAUSEFLAG_CHDIR },
{ "dnsrps-library", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE },
#ifdef HAVE_DNSTAP
{ "dnstap-output", &cfg_type_dnstapoutput, CFG_CLAUSEFLAG_OPTIONAL },

View file

@ -50,6 +50,7 @@
#include <isc/buffer.h>
#include <isc/dir.h>
#include <isc/errno.h>
#include <isc/file.h>
#include <isc/formatcheck.h>
#include <isc/lex.h>
#include <isc/log.h>
@ -114,7 +115,7 @@ static void
free_list(cfg_obj_t *obj);
static isc_result_t
create_listelt(cfg_parser_t *pctx, cfg_listelt_t **eltp);
create_listelt(isc_mem_t *mctx, cfg_listelt_t **eltp);
static isc_result_t
create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type,
@ -542,8 +543,6 @@ cfg_parser_create(isc_mem_t *mctx, cfg_parser_t **ret) {
pctx->open_files = NULL;
pctx->closed_files = NULL;
pctx->line = 0;
pctx->callback = NULL;
pctx->callbackarg = NULL;
pctx->token.type = isc_tokentype_unknown;
pctx->flags = 0;
pctx->buf_name = NULL;
@ -563,8 +562,12 @@ cfg_parser_create(isc_mem_t *mctx, cfg_parser_t **ret) {
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));
CHECK(cfg_create_list(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_filelist,
&pctx->open_files));
CHECK(cfg_create_list(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_filelist,
&pctx->closed_files));
*ret = pctx;
return ISC_R_SUCCESS;
@ -604,7 +607,7 @@ parser_openfile(cfg_parser_t *pctx, const char *filename) {
}
CHECK(create_string(pctx, filename, &cfg_type_qstring, &stringobj));
CHECK(create_listelt(pctx, &elt));
CHECK(create_listelt(pctx->mctx, &elt));
elt->obj = stringobj;
ISC_LIST_APPEND(pctx->open_files->value.list, elt, link);
@ -614,15 +617,6 @@ cleanup:
return result;
}
void
cfg_parser_setcallback(cfg_parser_t *pctx, cfg_parsecallback_t callback,
void *arg) {
REQUIRE(pctx != NULL);
pctx->callback = callback;
pctx->callbackarg = arg;
}
void
cfg_parser_reset(cfg_parser_t *pctx) {
REQUIRE(pctx != NULL);
@ -674,16 +668,25 @@ cleanup:
return result;
}
#define REQUIRE_PCTX_FLAGS(flags) \
REQUIRE((flags & ~(CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE | \
CFG_PCTX_NOEXPERIMENTAL)) == 0)
isc_result_t
cfg_parse_file(cfg_parser_t *pctx, const char *filename, const cfg_type_t *type,
cfg_obj_t **ret) {
cfg_parse_file(isc_mem_t *mctx, const char *filename, const cfg_type_t *type,
unsigned int flags, cfg_obj_t **ret) {
isc_result_t result;
cfg_listelt_t *elt;
cfg_parser_t *pctx = NULL;
REQUIRE(pctx != NULL);
REQUIRE(mctx != NULL);
REQUIRE(filename != NULL);
REQUIRE(type != NULL);
REQUIRE(ret != NULL && *ret == NULL);
REQUIRE_PCTX_FLAGS(flags);
CHECK(cfg_parser_create(mctx, &pctx));
pctx->flags = flags;
CHECK(parser_openfile(pctx, filename));
@ -696,22 +699,27 @@ cfg_parse_file(cfg_parser_t *pctx, const char *filename, const cfg_type_t *type,
ISC_LIST_APPEND(pctx->closed_files->value.list, elt, link);
cleanup:
if (pctx != NULL) {
cfg_parser_destroy(&pctx);
}
return result;
}
isc_result_t
cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
cfg_parse_buffer(isc_mem_t *mctx, isc_buffer_t *buffer, const char *file,
unsigned int line, const cfg_type_t *type, unsigned int flags,
cfg_obj_t **ret) {
isc_result_t result;
cfg_parser_t *pctx = NULL;
REQUIRE(pctx != NULL);
REQUIRE(mctx != NULL);
REQUIRE(type != NULL);
REQUIRE(buffer != NULL);
REQUIRE(ret != NULL && *ret == NULL);
REQUIRE((flags & ~(CFG_PCTX_NODEPRECATED | CFG_PCTX_NOOBSOLETE |
CFG_PCTX_NOEXPERIMENTAL)) == 0);
REQUIRE_PCTX_FLAGS(flags);
CHECK(cfg_parser_create(mctx, &pctx));
CHECK(isc_lex_openbuffer(pctx->lexer, buffer));
pctx->buf_name = file;
@ -725,6 +733,10 @@ cfg_parse_buffer(cfg_parser_t *pctx, isc_buffer_t *buffer, const char *file,
pctx->buf_name = NULL;
cleanup:
if (pctx != NULL) {
cfg_parser_destroy(&pctx);
}
return result;
}
@ -1945,25 +1957,25 @@ cfg_type_t cfg_type_boolean = { "boolean", cfg_parse_boolean,
*/
isc_result_t
cfg_create_list(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **obj) {
cfg_create_list(isc_mem_t *mctx, cfg_obj_t *file, size_t line,
const cfg_type_t *type, cfg_obj_t **obj) {
isc_result_t result;
REQUIRE(pctx != NULL);
REQUIRE(mctx != NULL);
REQUIRE(type != NULL);
REQUIRE(obj != NULL && *obj == NULL);
CHECK(cfg_create_obj(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, type, obj));
CHECK(cfg_create_obj(mctx, file, line, 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) {
create_listelt(isc_mem_t *mctx, cfg_listelt_t **eltp) {
cfg_listelt_t *elt;
elt = isc_mem_get(pctx->mctx, sizeof(*elt));
elt = isc_mem_get(mctx, sizeof(*elt));
elt->obj = NULL;
ISC_LINK_INIT(elt, link);
*eltp = elt;
@ -1996,7 +2008,7 @@ cfg_parse_listelt(cfg_parser_t *pctx, const cfg_type_t *elttype,
REQUIRE(elttype != NULL);
REQUIRE(ret != NULL && *ret == NULL);
CHECK(create_listelt(pctx, &elt));
CHECK(create_listelt(pctx->mctx, &elt));
result = cfg_parse_obj(pctx, elttype, &value);
if (result != ISC_R_SUCCESS) {
@ -2024,7 +2036,8 @@ parse_list(cfg_parser_t *pctx, const cfg_type_t *listtype, cfg_obj_t **ret) {
isc_result_t result;
cfg_listelt_t *elt = NULL;
CHECK(cfg_create_list(pctx, listtype, &listobj));
CHECK(cfg_create_list(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, listtype, &listobj));
for (;;) {
CHECK(cfg_peektoken(pctx, 0));
@ -2119,7 +2132,8 @@ cfg_parse_spacelist(cfg_parser_t *pctx, const cfg_type_t *listtype,
listof = listtype->of;
CHECK(cfg_create_list(pctx, listtype, &listobj));
CHECK(cfg_create_list(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, listtype, &listobj));
for (;;) {
cfg_listelt_t *elt = NULL;
@ -2386,8 +2400,9 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
/* Multivalued clause */
cfg_obj_t *listobj = NULL;
CHECK(cfg_create_list(pctx, &cfg_type_implicitlist,
&listobj));
CHECK(cfg_create_list(
pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, &cfg_type_implicitlist, &listobj));
symval.as_pointer = listobj;
result = isc_symtab_define_and_return(
obj->value.map.symtab, clause->name,
@ -2406,12 +2421,12 @@ cfg_parse_mapbody(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
ISC_LIST_APPEND(listobj->value.list, elt, link);
} else {
/* Single-valued clause */
bool callback = ((clause->flags &
CFG_CLAUSEFLAG_CALLBACK) != 0);
bool chdir = ((clause->flags & CFG_CLAUSEFLAG_CHDIR) !=
0);
result = parse_symtab_elt(
pctx, clause->name, clause->type,
obj->value.map.symtab, callback);
result = parse_symtab_elt(pctx, clause->name,
clause->type,
obj->value.map.symtab, chdir);
if (result == ISC_R_EXISTS) {
cfg_parser_error(pctx, CFG_LOG_NEAR,
"'%s' redefined",
@ -2437,17 +2452,60 @@ cleanup:
return result;
}
static isc_result_t
change_directory(const char *clausename, const cfg_obj_t *obj) {
isc_result_t result;
const char *directory;
REQUIRE(strcasecmp("directory", clausename) == 0);
UNUSED(clausename);
/*
* Change directory.
*/
directory = cfg_obj_asstring(obj);
if (!isc_file_ischdiridempotent(directory)) {
cfg_obj_log(obj, ISC_LOG_WARNING,
"option 'directory' contains relative path '%s'",
directory);
}
if (!isc_file_isdirwritable(directory)) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"directory '%s' is not writable", directory);
return ISC_R_NOPERM;
}
result = isc_dir_chdir(directory);
if (result != ISC_R_SUCCESS) {
cfg_obj_log(obj, ISC_LOG_ERROR,
"change directory to '%s' failed: %s", directory,
isc_result_totext(result));
return result;
}
char cwd[PATH_MAX];
if (getcwd(cwd, sizeof(cwd)) == cwd) {
cfg_obj_log(obj, ISC_LOG_INFO,
"the working directory is now '%s'", cwd);
}
return ISC_R_SUCCESS;
}
static isc_result_t
parse_symtab_elt(cfg_parser_t *pctx, const char *name, cfg_type_t *elttype,
isc_symtab_t *symtab, bool callback) {
isc_symtab_t *symtab, bool chdir) {
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));
if (chdir) {
CHECK(change_directory(name, obj));
}
symval.as_pointer = obj;
@ -2857,7 +2915,8 @@ parse_unsupported(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
isc_result_t result;
int braces = 0;
CHECK(cfg_create_list(pctx, type, &listobj));
CHECK(cfg_create_list(pctx->mctx, cfg_parser_currentfile(pctx),
pctx->line, type, &listobj));
for (;;) {
cfg_listelt_t *elt = NULL;
@ -3868,17 +3927,15 @@ cfg_print_grammar(const cfg_type_t *type, unsigned int flags,
}
isc_result_t
cfg_parser_mapadd(cfg_parser_t *pctx, cfg_obj_t *mapobj, cfg_obj_t *obj,
const char *clausename) {
cfg_parser_mapadd(cfg_obj_t *mapobj, cfg_obj_t *obj, const char *clausename) {
isc_result_t result = ISC_R_SUCCESS;
const cfg_map_t *map;
const cfg_map_t *map = NULL;
isc_symvalue_t symval;
cfg_obj_t *destobj = NULL;
cfg_listelt_t *elt = NULL;
const cfg_clausedef_t *const *clauseset;
const cfg_clausedef_t *clause;
const cfg_clausedef_t *const *clauseset = NULL;
const cfg_clausedef_t *clause = NULL;
REQUIRE(pctx != NULL);
REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map);
REQUIRE(obj != NULL);
REQUIRE(clausename != NULL);
@ -3903,9 +3960,10 @@ breakout:
&symval);
if (result == ISC_R_NOTFOUND) {
if ((clause->flags & CFG_CLAUSEFLAG_MULTI) != 0) {
CHECK(cfg_create_list(pctx, &cfg_type_implicitlist,
CHECK(cfg_create_list(mapobj->mctx, obj->file,
obj->line, &cfg_type_implicitlist,
&destobj));
CHECK(create_listelt(pctx, &elt));
CHECK(create_listelt(mapobj->mctx, &elt));
cfg_obj_attach(obj, &elt->obj);
ISC_LIST_APPEND(destobj->value.list, elt, link);
symval.as_pointer = destobj;
@ -3923,7 +3981,7 @@ breakout:
INSIST(result == ISC_R_SUCCESS);
if (destobj2->type == &cfg_type_implicitlist) {
CHECK(create_listelt(pctx, &elt));
CHECK(create_listelt(mapobj->mctx, &elt));
cfg_obj_attach(obj, &elt->obj);
ISC_LIST_APPEND(destobj2->value.list, elt, link);
} else {
@ -3936,7 +3994,7 @@ breakout:
cleanup:
if (elt != NULL) {
free_listelt(pctx->mctx, elt);
free_listelt(mapobj->mctx, elt);
}
CLEANUP_OBJ(destobj);

View file

@ -120,7 +120,6 @@ ISC_RUN_TEST_IMPL(duration) {
"T99999999999H99999999999M99999999999S" },
};
isc_buffer_t buf1;
cfg_parser_t *p1 = NULL;
cfg_obj_t *c1 = NULL;
bool must_fail = false;
@ -144,14 +143,10 @@ ISC_RUN_TEST_IMPL(duration) {
isc_buffer_add(&buf1, strlen(conf) - 1);
/* Parse with default line numbering */
result = cfg_parser_create(isc_g_mctx, &p1);
assert_int_equal(result, ISC_R_SUCCESS);
result = cfg_parse_buffer(p1, &buf1, "text1", 0,
result = cfg_parse_buffer(isc_g_mctx, &buf1, "text1", 0,
&cfg_type_namedconf, 0, &c1);
if (must_fail) {
assert_int_equal(result, DNS_R_BADTTL);
cfg_parser_destroy(&p1);
continue;
}
assert_int_equal(result, ISC_R_SUCCESS);
@ -193,7 +188,6 @@ ISC_RUN_TEST_IMPL(duration) {
}
cfg_obj_detach(&c1);
cfg_parser_destroy(&p1);
}
}

View file

@ -124,16 +124,12 @@ static void
test__query_source_print(const char *config, const char *expected) {
isc_result_t result;
isc_buffer_t buffer;
cfg_parser_t *parser = NULL;
cfg_obj_t *output_conf = NULL;
result = cfg_parser_create(mctx, &parser);
assert_int_equal(result, ISC_R_SUCCESS);
isc_buffer_constinit(&buffer, config, strlen(config));
isc_buffer_add(&buffer, strlen(config));
result = cfg_parse_buffer(parser, &buffer, "text1", 0,
result = cfg_parse_buffer(isc_g_mctx, &buffer, "text1", 0,
&cfg_type_namedconf, 0, &output_conf);
assert_int_equal(result, ISC_R_SUCCESS);
assert_non_null(output_conf);
@ -144,9 +140,7 @@ test__query_source_print(const char *config, const char *expected) {
output_conf->type->print(&pctx, output_conf);
assert_text(expected);
cfg_obj_detach(parser, &output_conf);
cfg_parser_reset(parser);
cfg_parser_destroy(&parser);
cfg_obj_detach(&output_conf);
}
ISC_RUN_TEST_IMPL(query_source_print_none) {

View file

@ -11,6 +11,7 @@
foreach unit : [
'duration',
'grammar',
'parser',
]
test_bin = executable(

View file

@ -60,7 +60,6 @@ append(void *arg, const char *str, int len) {
ISC_RUN_TEST_IMPL(addzoneconf) {
isc_result_t result;
isc_buffer_t b;
cfg_parser_t *p = NULL;
const char *tests[] = {
"zone \"test4.baz\" { type primary; file \"e.db\"; };",
"zone \"test/.baz\" { type primary; file \"e.db\"; };",
@ -73,9 +72,6 @@ ISC_RUN_TEST_IMPL(addzoneconf) {
char buf[1024];
/* Parse with default line numbering */
result = cfg_parser_create(isc_g_mctx, &p);
assert_int_equal(result, ISC_R_SUCCESS);
for (size_t i = 0; i < ARRAY_SIZE(tests); i++) {
cfg_obj_t *conf = NULL;
const cfg_obj_t *obj = NULL, *zlist = NULL;
@ -83,7 +79,7 @@ ISC_RUN_TEST_IMPL(addzoneconf) {
isc_buffer_constinit(&b, tests[i], strlen(tests[i]));
isc_buffer_add(&b, strlen(tests[i]));
result = cfg_parse_buffer(p, &b, "text1", 0,
result = cfg_parse_buffer(isc_g_mctx, &b, "text1", 0,
&cfg_type_namedconf, 0, &conf);
assert_int_equal(result, ISC_R_SUCCESS);
@ -103,49 +99,77 @@ ISC_RUN_TEST_IMPL(addzoneconf) {
assert_string_equal(tests[i], buf);
cfg_obj_detach(&conf);
cfg_parser_reset(p);
}
cfg_parser_destroy(&p);
}
/* test cfg_parse_buffer() */
ISC_RUN_TEST_IMPL(parse_buffer) {
isc_result_t result;
unsigned char text[] = "options\n{\nrecursion yes;\n};\n";
isc_buffer_t buf1, buf2;
cfg_parser_t *p1 = NULL, *p2 = NULL;
cfg_obj_t *c1 = NULL, *c2 = NULL;
int fresult;
unsigned char text[] = "options\n{\nidonotexists yes;\n};\n";
char logfilebuf[512];
size_t logfilelen;
isc_buffer_t buf;
cfg_obj_t *c = NULL;
isc_buffer_init(&buf1, &text[0], sizeof(text) - 1);
isc_buffer_add(&buf1, sizeof(text) - 1);
/*
* Redirect parser errors into a specific file for checking the output
* later.
*/
constexpr char logfilename[] = "./cfglog.out";
FILE *logfile = fopen(logfilename, "w+");
assert_non_null(logfile);
/* Parse with default line numbering */
result = cfg_parser_create(isc_g_mctx, &p1);
assert_int_equal(result, ISC_R_SUCCESS);
isc_logdestination_t *logdest = ISC_LOGDESTINATION_FILE(logfile);
isc_logconfig_t *logconfig = isc_logconfig_get();
isc_log_createandusechannel(logconfig, "default_stderr",
ISC_LOG_TOFILEDESC, ISC_LOG_DYNAMIC,
logdest, 0, ISC_LOGCATEGORY_DEFAULT,
ISC_LOGMODULE_DEFAULT);
result = cfg_parse_buffer(p1, &buf1, "text1", 0, &cfg_type_namedconf, 0,
&c1);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(p1->line, 5);
/* Parse with default line numbering. */
isc_buffer_init(&buf, &text[0], sizeof(text) - 1);
isc_buffer_add(&buf, sizeof(text) - 1);
result = cfg_parse_buffer(isc_g_mctx, &buf, "text1", 0,
&cfg_type_namedconf, 0, &c);
assert_int_equal(result, ISC_R_FAILURE);
assert_null(c);
isc_buffer_init(&buf2, &text[0], sizeof(text) - 1);
isc_buffer_add(&buf2, sizeof(text) - 1);
/* Parse with changed line number. */
isc_buffer_first(&buf);
result = cfg_parse_buffer(isc_g_mctx, &buf, "text2", 100,
&cfg_type_namedconf, 0, &c);
assert_int_equal(result, ISC_R_FAILURE);
assert_null(c);
/* Parse with changed line number */
result = cfg_parser_create(isc_g_mctx, &p2);
assert_int_equal(result, ISC_R_SUCCESS);
/* Parse with changed line number and no name. */
isc_buffer_first(&buf);
result = cfg_parse_buffer(isc_g_mctx, &buf, NULL, 100,
&cfg_type_namedconf, 0, &c);
assert_int_equal(result, ISC_R_FAILURE);
assert_null(c);
result = cfg_parse_buffer(p2, &buf2, "text2", 100, &cfg_type_namedconf,
0, &c2);
assert_int_equal(result, ISC_R_SUCCESS);
assert_int_equal(p2->line, 104);
/* Check log values (and, specifically, line numbers). */
logfilelen = ftell(logfile);
assert_in_range(logfilelen, 0, sizeof(logfilebuf));
cfg_obj_detach(&c1);
cfg_obj_detach(&c2);
fresult = fseek(logfile, 0, SEEK_SET);
assert_int_equal(fresult, 0);
cfg_parser_destroy(&p1);
cfg_parser_destroy(&p2);
fresult = fread(logfilebuf, 1, logfilelen, logfile);
assert_int_equal(fresult, logfilelen);
logfilebuf[logfilelen] = 0;
assert_non_null(
strstr(logfilebuf, "text1:3: unknown option 'idonotexists'"));
assert_non_null(
strstr(logfilebuf, "text2:102: unknown option 'idonotexists'"));
assert_non_null(
strstr(logfilebuf, "none:102: unknown option 'idonotexists'"));
fclose(logfile);
remove(logfilename);
}
/* test cfg_map_firstclause() */