diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c index 0c217efd92..169fd66ef7 100644 --- a/bin/check/named-checkconf.c +++ b/bin/check/named-checkconf.c @@ -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; } diff --git a/bin/delv/delv.c b/bin/delv/delv.c index dd53c825fa..b05e05f2d2 100644 --- a/bin/delv/delv.c +++ b/bin/delv/delv.c @@ -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)); diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 51949c2cc9..5928c265bd 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -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; diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index ab53148b44..6c6e82f097 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -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); diff --git a/bin/dnssec/dnssec-ksr.c b/bin/dnssec/dnssec-ksr.c index 0a43fd889a..a4ef81b82e 100644 --- a/bin/dnssec/dnssec-ksr.c +++ b/bin/dnssec/dnssec-ksr.c @@ -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 diff --git a/bin/named/config.c b/bin/named/config.c index d7022be01b..00006a8522 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -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; } diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 0ae02c8891..0376d2b770 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -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; } diff --git a/bin/named/include/named/config.h b/bin/named/include/named/config.h index 6b275727d4..3de19d73f8 100644 --- a/bin/named/include/named/config.h +++ b/bin/named/include/named/config.h @@ -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); diff --git a/bin/named/server.c b/bin/named/server.c index 5fdfedd082..989bcee49c 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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, diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 585dc80b91..4ceff56466 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -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) { diff --git a/bin/plugins/filter-a.c b/bin/plugins/filter-a.c index 5d1cf06e52..2d98b70692 100644 --- a/bin/plugins/filter-a.c +++ b/bin/plugins/filter-a.c @@ -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, ¶m_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(¶m_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, ¶m_obj)); CHECK(check_syntax(param_obj, cfg, mctx, aclctx)); @@ -385,9 +376,6 @@ cleanup: if (param_obj != NULL) { cfg_obj_detach(¶m_obj); } - if (parser != NULL) { - cfg_parser_destroy(&parser); - } return result; } diff --git a/bin/plugins/filter-aaaa.c b/bin/plugins/filter-aaaa.c index ad2ef52f3a..dad917464c 100644 --- a/bin/plugins/filter-aaaa.c +++ b/bin/plugins/filter-aaaa.c @@ -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, ¶m_obj)); CHECK(parse_filter_aaaa_on(param_obj, "filter-aaaa-on-v4", @@ -305,9 +302,6 @@ cleanup: if (param_obj != NULL) { cfg_obj_detach(¶m_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, ¶m_obj)); CHECK(check_syntax(param_obj, cfg, mctx, aclctx)); @@ -389,9 +380,6 @@ cleanup: if (param_obj != NULL) { cfg_obj_detach(¶m_obj); } - if (parser != NULL) { - cfg_parser_destroy(&parser); - } return result; } diff --git a/bin/plugins/synthrecord.c b/bin/plugins/synthrecord.c index 5c5f34bf89..1fab2a3a37 100644 --- a/bin/plugins/synthrecord.c +++ b/bin/plugins/synthrecord.c @@ -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; } diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index 3204e30a63..46d0aa0c97 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -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); diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index efb781188b..aec7b13639 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -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" \ diff --git a/bin/tests/system/hooks/driver/test-syncplugin.c b/bin/tests/system/hooks/driver/test-syncplugin.c index 09856fd2cc..620829c8cc 100644 --- a/bin/tests/system/hooks/driver/test-syncplugin.c +++ b/bin/tests/system/hooks/driver/test-syncplugin.c @@ -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; } diff --git a/doc/misc/cfg_test.c b/doc/misc/cfg_test.c index 60b28bc159..f29600c2aa 100644 --- a/doc/misc/cfg_test.c +++ b/doc/misc/cfg_test.c @@ -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) { diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index 8e861655a5..b403fa7b28 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -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 diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index c06fedefb2..8e84e31a37 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -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, diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index ce30d4b948..d13fd830f8 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -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 }, diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 822ccc83a2..b2667a2629 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/tests/isccfg/duration_test.c b/tests/isccfg/duration_test.c index 4454933a1c..a9cb1fd021 100644 --- a/tests/isccfg/duration_test.c +++ b/tests/isccfg/duration_test.c @@ -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); } } diff --git a/tests/isccfg/grammar_test.c b/tests/isccfg/grammar_test.c index ac06a7e49a..88e4f00160 100644 --- a/tests/isccfg/grammar_test.c +++ b/tests/isccfg/grammar_test.c @@ -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) { diff --git a/tests/isccfg/meson.build b/tests/isccfg/meson.build index 16ca023f86..419986f595 100644 --- a/tests/isccfg/meson.build +++ b/tests/isccfg/meson.build @@ -11,6 +11,7 @@ foreach unit : [ 'duration', + 'grammar', 'parser', ] test_bin = executable( diff --git a/tests/isccfg/parser_test.c b/tests/isccfg/parser_test.c index 8ace4ea4f4..a08bf2abe6 100644 --- a/tests/isccfg/parser_test.c +++ b/tests/isccfg/parser_test.c @@ -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() */