📄 namedconf.c
字号:
};static cfg_clausedef_t *logging_clausesets[] = { logging_clauses, NULL};static cfg_type_t cfg_type_logging = { "logging", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, logging_clausesets };static isc_result_tparse_unitstring(char *str, isc_resourcevalue_t *valuep) { char *endp; unsigned int len; isc_uint64_t value; isc_uint64_t unit; value = isc_string_touint64(str, &endp, 10); if (*endp == 0) { *valuep = value; return (ISC_R_SUCCESS); } len = strlen(str); if (len < 2 || endp[1] != '\0') return (ISC_R_FAILURE); switch (str[len - 1]) { case 'k': case 'K': unit = 1024; break; case 'm': case 'M': unit = 1024 * 1024; break; case 'g': case 'G': unit = 1024 * 1024 * 1024; break; default: return (ISC_R_FAILURE); } if (value > ISC_UINT64_MAX / unit) return (ISC_R_FAILURE); *valuep = value * unit; return (ISC_R_SUCCESS);}static isc_result_tparse_sizeval(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; isc_uint64_t val; UNUSED(type); CHECK(cfg_gettoken(pctx, 0)); if (pctx->token.type != isc_tokentype_string) { result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } CHECK(parse_unitstring(TOKEN_STRING(pctx), &val)); CHECK(cfg_create_obj(pctx, &cfg_type_uint64, &obj)); obj->value.uint64 = val; *ret = obj; return (ISC_R_SUCCESS); cleanup: cfg_parser_error(pctx, CFG_LOG_NEAR, "expected integer and optional unit"); return (result);}/* * A size value (number + optional unit). */static cfg_type_t cfg_type_sizeval = { "sizeval", parse_sizeval, cfg_print_uint64, cfg_doc_terminal, &cfg_rep_uint64, NULL };/* * A size, "unlimited", or "default". */static isc_result_tparse_size(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_sizeval, ret));}static const char *size_enums[] = { "unlimited", "default", NULL };static cfg_type_t cfg_type_size = { "size", parse_size, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, size_enums};/* * A size or "unlimited", but not "default". */static const char *sizenodefault_enums[] = { "unlimited", NULL };static cfg_type_t cfg_type_sizenodefault = { "size_no_default", parse_size, cfg_print_ustring, cfg_doc_terminal, &cfg_rep_string, sizenodefault_enums};/* * optional_keyvalue */static isc_result_tparse_maybe_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, isc_boolean_t optional, cfg_obj_t **ret){ isc_result_t result; cfg_obj_t *obj = NULL; const keyword_type_t *kw = type->of; CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string && strcasecmp(TOKEN_STRING(pctx), kw->name) == 0) { CHECK(cfg_gettoken(pctx, 0)); CHECK(kw->type->parse(pctx, kw->type, &obj)); obj->type = type; /* XXX kludge */ } else { if (optional) { CHECK(cfg_parse_void(pctx, NULL, &obj)); } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected '%s'", kw->name); result = ISC_R_UNEXPECTEDTOKEN; goto cleanup; } } *ret = obj; cleanup: return (result);}static isc_result_tparse_enum_or_other(cfg_parser_t *pctx, const cfg_type_t *enumtype, const cfg_type_t *othertype, cfg_obj_t **ret){ isc_result_t result; CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string && cfg_is_enum(TOKEN_STRING(pctx), enumtype->of)) { CHECK(cfg_parse_enum(pctx, enumtype, ret)); } else { CHECK(cfg_parse_obj(pctx, othertype, ret)); } cleanup: return (result);}static voiddoc_enum_or_other(cfg_printer_t *pctx, const cfg_type_t *type) { cfg_doc_terminal(pctx, type);#if 0 /* XXX */ cfg_print_chars(pctx, "( ", 2);...#endif}static isc_result_tparse_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_maybe_optional_keyvalue(pctx, type, ISC_FALSE, ret));}static isc_result_tparse_optional_keyvalue(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_maybe_optional_keyvalue(pctx, type, ISC_TRUE, ret));}static voidprint_keyvalue(cfg_printer_t *pctx, cfg_obj_t *obj) { const keyword_type_t *kw = obj->type->of; cfg_print_cstr(pctx, kw->name); cfg_print_chars(pctx, " ", 1); kw->type->print(pctx, obj);}static voiddoc_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) { const keyword_type_t *kw = type->of; cfg_print_cstr(pctx, kw->name); cfg_print_chars(pctx, " ", 1); cfg_doc_obj(pctx, kw->type);}static voiddoc_optional_keyvalue(cfg_printer_t *pctx, const cfg_type_t *type) { const keyword_type_t *kw = type->of; cfg_print_chars(pctx, "[ ", 2); cfg_print_cstr(pctx, kw->name); cfg_print_chars(pctx, " ", 1); cfg_doc_obj(pctx, kw->type); cfg_print_chars(pctx, " ]", 2);}static const char *dialup_enums[] = { "notify", "notify-passive", "refresh", "passive", NULL };static isc_result_tparse_dialup_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));}static cfg_type_t cfg_type_dialuptype = { "dialuptype", parse_dialup_type, cfg_print_ustring, doc_enum_or_other, &cfg_rep_string, dialup_enums};static const char *notify_enums[] = { "explicit", NULL };static isc_result_tparse_notify_type(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { return (parse_enum_or_other(pctx, type, &cfg_type_boolean, ret));}static cfg_type_t cfg_type_notifytype = { "notifytype", parse_notify_type, cfg_print_ustring, doc_enum_or_other, &cfg_rep_string, notify_enums,};static keyword_type_t key_kw = { "key", &cfg_type_astring };LIBISCCFG_EXTERNAL_DATA cfg_type_t cfg_type_keyref = { "keyref", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_string, &key_kw};static cfg_type_t cfg_type_optional_keyref = { "optional_keyref", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_string, &key_kw};/* * A "controls" statement is represented as a map with the multivalued * "inet" and "unix" clauses. Inet controls are tuples; unix controls * are cfg_unsupported_t objects. */static keyword_type_t controls_allow_kw = { "allow", &cfg_type_bracketed_aml };static cfg_type_t cfg_type_controls_allow = { "controls_allow", parse_keyvalue, print_keyvalue, doc_keyvalue, &cfg_rep_list, &controls_allow_kw};static keyword_type_t controls_keys_kw = { "keys", &cfg_type_keylist };static cfg_type_t cfg_type_controls_keys = { "controls_keys", parse_optional_keyvalue, print_keyvalue, doc_optional_keyvalue, &cfg_rep_list, &controls_keys_kw};static cfg_tuplefielddef_t inetcontrol_fields[] = { { "address", &cfg_type_controls_sockaddr, 0 }, { "allow", &cfg_type_controls_allow, 0 }, { "keys", &cfg_type_controls_keys, 0 }, { NULL, NULL, 0 }};static cfg_type_t cfg_type_inetcontrol = { "inetcontrol", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple, inetcontrol_fields};static cfg_clausedef_tcontrols_clauses[] = { { "inet", &cfg_type_inetcontrol, CFG_CLAUSEFLAG_MULTI }, { "unix", &cfg_type_unsupported, CFG_CLAUSEFLAG_MULTI|CFG_CLAUSEFLAG_NOTIMP }, { NULL, NULL, 0 }};static cfg_clausedef_t *controls_clausesets[] = { controls_clauses, NULL};static cfg_type_t cfg_type_controls = { "controls", cfg_parse_map, cfg_print_map, cfg_doc_map, &cfg_rep_map, &controls_clausesets};/* * An optional class, as used in view and zone statements. */static isc_result_tparse_optional_class(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) CHECK(cfg_parse_obj(pctx, &cfg_type_ustring, ret)); else CHECK(cfg_parse_obj(pctx, &cfg_type_void, ret)); cleanup: return (result);}static cfg_type_t cfg_type_optional_class = { "optional_class", parse_optional_class, NULL, cfg_doc_terminal, NULL, NULL};static isc_result_tparse_querysource(cfg_parser_t *pctx, int flags, cfg_obj_t **ret) { isc_result_t result; cfg_obj_t *obj = NULL; isc_netaddr_t netaddr; in_port_t port; unsigned int have_address = 0; unsigned int have_port = 0; if ((flags & CFG_ADDR_V4OK) != 0) isc_netaddr_any(&netaddr); else if ((flags & CFG_ADDR_V6OK) != 0) isc_netaddr_any6(&netaddr); else INSIST(0); port = 0; CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj)); for (;;) { CHECK(cfg_peektoken(pctx, 0)); if (pctx->token.type == isc_tokentype_string) { if (strcasecmp(TOKEN_STRING(pctx), "address") == 0) { /* read "address" */ CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_rawaddr(pctx, flags | CFG_ADDR_WILDOK, &netaddr)); have_address++; } else if (strcasecmp(TOKEN_STRING(pctx), "port") == 0) { /* read "port" */ CHECK(cfg_gettoken(pctx, 0)); CHECK(cfg_parse_rawport(pctx, CFG_ADDR_WILDOK, &port)); have_port++; } else { cfg_parser_error(pctx, CFG_LOG_NEAR, "expected 'address' or 'port'"); return (ISC_R_UNEXPECTEDTOKEN); } } else break; } if (have_address > 1 || have_port > 1 || have_address + have_port == 0) { cfg_parser_error(pctx, 0, "expected one address and/or port"); return (ISC_R_UNEXPECTEDTOKEN); } isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port); *ret = obj; return (ISC_R_SUCCESS); cleanup: cfg_parser_error(pctx, CFG_LOG_NEAR, "invalid query source"); CLEANUP_OBJ(obj); return (result);}static isc_result_tparse_querysource4(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { UNUSED(type); return (parse_querysource(pctx, CFG_ADDR_V4OK, ret));}static isc_result_tparse_querysource6(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { UNUSED(type); return (parse_querysource(pctx, CFG_ADDR_V6OK, ret));}static voidprint_querysource(cfg_printer_t *pctx, cfg_obj_t *obj) { isc_netaddr_t na; isc_netaddr_fromsockaddr(&na, &obj->value.sockaddr); cfg_print_chars(pctx, "address ", 8); cfg_print_rawaddr(pctx, &na); cfg_print_chars(pctx, " port ", 6); cfg_print_rawuint(pctx, isc_sockaddr_getport(&obj->value.sockaddr));}static cfg_type_t cfg_type_querysource4 = { "querysource4", parse_querysource4, NULL, cfg_doc_terminal, NULL, NULL};static cfg_type_t cfg_type_querysource6 = { "querysource6", parse_querysource6, NULL, cfg_doc_terminal, NULL, NULL};static cfg_type_t cfg_type_querysource = { "querysource", NULL, print_querysource, NULL, &cfg_rep_sockaddr, NULL };/* addrmatchelt */static isc_result_tparse_addrmatchelt(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) { if (pctx->token.type == isc_tokentype_string && (strcasecmp(TOKEN_STRING(pctx), "key") == 0)) { CHECK(cfg_parse_obj(pctx, &cfg_type_keyref, ret)); } else { if (cfg_lookingat_netaddr(pctx, CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK | CFG_ADDR_V6OK)) { CHECK(cfg_parse_netprefix(pctx, NULL, ret)); } else { CHECK(cfg_parse_astring(pctx, NULL, ret)); } } } else if (pctx->token.type == isc_tokentype_special) { if (pctx->token.value.as_char == '{') { /* Nested match list. */ CHECK(cfg_parse_obj(pctx, &cfg_type_bracketed_aml, ret)); } else if (pctx->token.value.as_char == '!') { CHECK(cfg_gettoken(pctx, 0)); /* read "!" */ CHECK(cfg_parse_obj(pctx, &cfg_type_negated, ret)); } else { goto bad; } } else { bad: cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IP match list element"); return (ISC_R_UNEXPECTEDTOKEN); } cleanup: return (result);}/* * A negated address match list element (like "! 10.0.0.1"). * Somewhat sneakily, the caller is expected to parse the * "!", but not to print it. */static cfg_tuplefielddef_t negated_fields[] = { { "value", &cfg_type_addrmatchelt, 0 }, { NULL, NULL, 0 }};static voidprint_negated(cfg_printer_t *pctx, cfg_obj_t *obj) { cfg_print_chars(pctx, "!", 1); cfg_print_tuple(pctx, obj);}static cfg_type_t cfg_type_negated = { "negated", cfg_parse_tuple, print_negated, NULL, &cfg_rep_tuple, &negated_fields};/* An address match list element */static cfg_type_t cfg_type_addrmatchelt = { "address_match_element", parse_addrmatchelt, NULL, cfg_doc_terminal, NULL, NULL};/* A bracketed address match list */static cfg_type_t cfg_type_bracketed_aml = { "bracketed_aml", cfg_parse_bracketed_list, cfg_print_bracketed_list, cfg_doc_bracketed_list, &cfg_rep_list, &cfg_type_addrmatchelt};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -