📄 namedconf.c
字号:
/* * The socket address syntax in the "controls" statement is silly. * It allows both socket address families, but also allows "*", * whis is gratuitously interpreted as the IPv4 wildcard address. */static unsigned int controls_sockaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK | CFG_ADDR_WILDOK;static cfg_type_t cfg_type_controls_sockaddr = { "controls_sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, &cfg_rep_sockaddr, &controls_sockaddr_flags};/* * Handle the special kludge syntax of the "keys" clause in the "server" * statement, which takes a single key with or without braces and semicolon. */static isc_result_tparse_server_key_kludge(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret){ isc_result_t result; isc_boolean_t braces = ISC_FALSE; UNUSED(type); /* Allow opening brace. */ CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == '{') { result = cfg_gettoken(pctx, 0); braces = ISC_TRUE; } CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret)); if (braces) { /* Skip semicolon if present. */ CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_special && pctx->token.value.as_char == ';') CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_special(pctx, '}')); } cleanup: return (result);}static cfg_type_t cfg_type_server_key_kludge = { "server_key", parse_server_key_kludge, NULL, cfg_doc_terminal, NULL, NULL};/* * An optional logging facility. */static isc_result_tparse_optional_facility(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret){ isc_result_t result; UNUSED(type); CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string || pctx->token.type == isc_tokentype_qstring) { CHECK(cfg_parse_obj(pctx, &cfg_type_astring, ret)); } else { CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret)); } cleanup: return (result);}static cfg_type_t cfg_type_optional_facility = { "optional_facility", parse_optional_facility, NULL, cfg_doc_terminal, NULL, NULL };/* * A log severity. Return as a string, except "debug N", * which is returned as a keyword object. */static keyword_type_t debug_kw = { "debug", &cfg_type_uint32 };static cfg_type_t cfg_type_debuglevel = { "debuglevel", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_uint32, &debug_kw};static isc_result_tparse_logseverity(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; UNUSED(type); CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), "debug") == 0) { CHECK(cfg_gettoken(pctx, 0)); /* read "debug" */ CHECK(cfg_peektoken(pctx, ISC_LEXOPT_NUMBER)); if (pctx->token.type == isc_tokentype_number) { CHECK(cfg_parse_uint32(pctx, NULL, ret)); } else { /* * The debug level is optional and defaults to 1. * This makes little sense, but we support it for * compatibility with BIND 8. */ CHECK(cfg_create_obj(pctx, &cfg_type_uint32, ret)); (*ret)->value.uint32 = 1; } (*ret)->type = &cfg_type_debuglevel; /* XXX kludge */ } else { CHECK(cfg_parse_obj(pctx, &cfg_type_loglevel, ret)); } cleanup: return (result);}static cfg_type_t cfg_type_logseverity = { "log_severity", parse_logseverity, NULL, cfg_doc_terminal, NULL, NULL };/* * The "file" clause of the "channel" statement. * This is yet another special case. */static const char *logversions_enums[] = { "unlimited", NULL };static isc_result_tparse_logversions(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_uint32, ret));}static cfg_type_t cfg_type_logversions = { "logversions", parse_logversions, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, logversions_enums};static cfg_tuplefielddef_t logfile_fields[] = { { "file", &cfg_type_qstring, 0 }, { "versions", &cfg_type_logversions, 0 }, { "size", &cfg_type_size, 0 }, { NULL, NULL, 0 }};static isc_result_tparse_logfile(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; const cfg_tuplefielddef_t *fields = type->of; CHECK(cfg_create_tuple(pctx, type, &obj)); /* Parse the mandatory "file" field */ CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); /* Parse "versions" and "size" fields in any order. */ for (;;) { CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string) { CHECK(cfg_gettoken(pctx, 0)); if (strcasecmp(TOKEN_STRING(pctx), "versions") == 0 && obj->value.tuple[1] == NULL) { CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1])); } else if (strcasecmp(TOKEN_STRING(pctx), "size") == 0 && obj->value.tuple[2] == NULL) { CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2])); } else { break; } } else { break; } } /* Create void objects for missing optional values. */ if (obj->value.tuple[1] == NULL) CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1])); if (obj->value.tuple[2] == NULL) CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2])); *ret = obj; return (ISC_R_SUCCESS); cleanup: CLEANUP_OBJ(obj); return (result);}static voidprint_logfile(cfg_printer_t *pctx, cfg_obj_t *obj) { cfg_print_obj(pctx, obj->value.tuple[0]); /* file */ if (obj->value.tuple[1]->type->print != cfg_print_void) { cfg_print_chars(pctx, " versions ", 10); cfg_print_obj(pctx, obj->value.tuple[1]); } if (obj->value.tuple[2]->type->print != cfg_print_void) { cfg_print_chars(pctx, " size ", 6); cfg_print_obj(pctx, obj->value.tuple[2]); }}static cfg_type_t cfg_type_logfile = { "log_file", parse_logfile, print_logfile, cfg_doc_terminal, &cfg_rep_tuple, logfile_fields};/* An IPv4/IPv6 address with optional port, "*" accepted as wildcard. */static unsigned int sockaddr4wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V4OK;static cfg_type_t cfg_type_sockaddr4wild = { "sockaddr4wild", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr4wild_flags};static unsigned int sockaddr6wild_flags = CFG_ADDR_WILDOK | CFG_ADDR_V6OK;static cfg_type_t cfg_type_sockaddr6wild = { "v6addrportwild", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr, &cfg_rep_sockaddr, &sockaddr6wild_flags};/* * lwres */static cfg_tuplefielddef_t lwres_view_fields[] = { { "name", &cfg_type_astring, 0 }, { "class", &cfg_type_optional_class, 0 }, { NULL, NULL, 0 }};static cfg_type_t cfg_type_lwres_view = { "lwres_view", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, lwres_view_fields};static cfg_type_t cfg_type_lwres_searchlist = { "lwres_searchlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_astring };static cfg_clausedef_tlwres_clauses[] = { { "listen-on", &cfg_type_portiplist, 0 }, { "view", &cfg_type_lwres_view, 0 }, { "search", &cfg_type_lwres_searchlist, 0 }, { "ndots", &cfg_type_uint32, 0 }, { NULL, NULL, 0 }};static cfg_clausedef_t *lwres_clausesets[] = { lwres_clauses, NULL};static cfg_type_t cfg_type_lwres = { "lwres", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, lwres_clausesets };/* * rndc */static cfg_clausedef_trndcconf_options_clauses[] = { { "default-server", &cfg_type_astring, 0 }, { "default-key", &cfg_type_astring, 0 }, { "default-port", &cfg_type_uint32, 0 }, { NULL, NULL, 0 }};static cfg_clausedef_t *rndcconf_options_clausesets[] = { rndcconf_options_clauses, NULL};static cfg_type_t cfg_type_rndcconf_options = { "rndcconf_options", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, rndcconf_options_clausesets};static cfg_clausedef_trndcconf_server_clauses[] = { { "key", &cfg_type_astring, 0 }, { "port", &cfg_type_uint32, 0 }, { NULL, NULL, 0 }};static cfg_clausedef_t *rndcconf_server_clausesets[] = { rndcconf_server_clauses, NULL};static cfg_type_t cfg_type_rndcconf_server = { "rndcconf_server", cfg_parse_named_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, rndcconf_server_clausesets};static cfg_clausedef_trndcconf_clauses[] = { { "key", &cfg_type_key, CFG_CLAUSEFLAG_MULTI }, { "server", &cfg_type_rndcconf_server, CFG_CLAUSEFLAG_MULTI }, { "options", &cfg_type_rndcconf_options, 0 }, { NULL, NULL, 0 }};static cfg_clausedef_t *rndcconf_clausesets[] = { rndcconf_clauses, NULL};LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndcconf = { "rndcconf", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, rndcconf_clausesets};static cfg_clausedef_trndckey_clauses[] = { { "key", &cfg_type_key, 0 }, { NULL, NULL, 0 }};static cfg_clausedef_t *rndckey_clausesets[] = { rndckey_clauses, NULL};LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_rndckey = { "rndckey", cfg_parse_mapbody, cfg_print_mapbody, cfg_doc_mapbody, &cfg_rep_map, rndckey_clausesets};static cfg_tuplefielddef_t nameport_fields[] = { { "name", &cfg_type_astring, 0 }, { "port", &cfg_type_optional_port, 0 }, { NULL, NULL, 0 }};static cfg_type_t cfg_type_nameport = { "nameport", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, nameport_fields};static voiddoc_sockaddrnameport(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_chars(pctx, "( ", 2); cfg_print_cstr(pctx, "<quoted_string>"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[port <integer>]"); cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, "<ipv4_address>"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[port <integer>]"); cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, "<ipv6_address>"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[port <integer>]"); cfg_print_chars(pctx, " )", 2);}static isc_result_tparse_sockaddrnameport(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret){ isc_result_t result; cfg_obj_t *obj = NULL; UNUSED(type); CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string || pctx->token.type == isc_tokentype_qstring) { if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK)) CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr, ret)); else { const cfg_tuplefielddef_t *fields = cfg_type_nameport.of; CHECK(cfg_create_tuple(pctx, &cfg_type_nameport, &obj)); CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0])); CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1])); *ret = obj; obj = NULL; } } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IP address or hostname"); return (ISC_R_UNEXPECTEDTOKEN); } cleanup: CLEANUP_OBJ(obj); return (result);}static cfg_type_t cfg_type_sockaddrnameport = { "sockaddrnameport_element", parse_sockaddrnameport, NULL, doc_sockaddrnameport, NULL, NULL};static cfg_type_t cfg_type_bracketed_sockaddrnameportlist = { "bracketed_sockaddrnameportlist", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_sockaddrnameport};/* * A list of socket addresses or name with an optional default port, * as used in the dual-stack-servers option. E.g., * "port 1234 { dual-stack-servers.net; 10.0.0.1; 1::2 port 69; }" */static cfg_tuplefielddef_t nameportiplist_fields[] = { { "port", &cfg_type_optional_port, 0 }, { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 }, { NULL, NULL, 0 }};static cfg_type_t cfg_type_nameportiplist = { "nameportiplist", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, nameportiplist_fields};/* * masters element. */static voiddoc_masterselement(cfg_printer_t *pctx, const cfg_type_t *type) { UNUSED(type); cfg_print_chars(pctx, "( ", 2); cfg_print_cstr(pctx, "<masters>"); cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, "<ipv4_address>"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[port <integer>]"); cfg_print_chars(pctx, " | ", 3); cfg_print_cstr(pctx, "<ipv6_address>"); cfg_print_chars(pctx, " ", 1); cfg_print_cstr(pctx, "[port <integer>]"); cfg_print_chars(pctx, " )", 2);}static isc_result_tparse_masterselement(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret){ isc_result_t result; cfg_obj_t *obj = NULL; UNUSED(type); CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING)); if (pctx->token.type == isc_tokentype_string || pctx->token.type == isc_tokentype_qstring) { if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V6OK)) CHECK(cfg_parse_sockaddr(pctx, &cfg_type_sockaddr, ret)); else CHECK(cfg_parse_astring(pctx, &cfg_type_astring, ret)); } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IP address or masters name"); return (ISC_R_UNEXPECTEDTOKEN); } cleanup: CLEANUP_OBJ(obj); return (result);}static cfg_type_t cfg_type_masterselement = { "masters_element", parse_masterselement, NULL, doc_masterselement, NULL, NULL};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -