⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 4 页
字号:
	for (;;) {		cfg_listelt_t *elt;	redo:		/*		 * Parse the option name and see if it is known.		 */		CHECK(cfg_gettoken(pctx, 0));		if (pctx->token.type != isc_tokentype_string) {			cfg_ungettoken(pctx);			break;		}		/*		 * We accept "include" statements wherever a map body		 * clause can occur.		 */		if (strcasecmp(TOKEN_STRING(pctx), "include") == 0) {			/*			 * Turn the file name into a temporary configuration			 * object just so that it is not overwritten by the			 * semicolon token.			 */			CHECK(cfg_parse_obj(pctx, &cfg_type_qstring, &includename));			CHECK(parse_semicolon(pctx));			CHECK(parser_openfile(pctx, includename->					      value.string.base));			 cfg_obj_destroy(pctx, &includename);			 goto redo;		}		clause = NULL;		for (clauseset = clausesets; *clauseset != NULL; clauseset++) {			for (clause = *clauseset;			     clause->name != NULL;			     clause++) {				if (strcasecmp(TOKEN_STRING(pctx),					   clause->name) == 0)					goto done;			}		}	done:		if (clause == NULL || clause->name == NULL) {			cfg_parser_error(pctx, CFG_LOG_NOPREP, "unknown option");			/*			 * Try to recover by parsing this option as an unknown			 * option and discarding it.			 */			CHECK(cfg_parse_obj(pctx, &cfg_type_unsupported, &eltobj));			cfg_obj_destroy(pctx, &eltobj);			CHECK(parse_semicolon(pctx));			continue;		}		/* Clause is known. */		/* Issue warnings if appropriate */		if ((clause->flags & CFG_CLAUSEFLAG_OBSOLETE) != 0)			cfg_parser_warning(pctx, 0, "option '%s' is obsolete",				       clause->name);		if ((clause->flags & CFG_CLAUSEFLAG_NOTIMP) != 0)			cfg_parser_warning(pctx, 0, "option '%s' is "				       "not implemented", clause->name);		if ((clause->flags & CFG_CLAUSEFLAG_NYI) != 0)			cfg_parser_warning(pctx, 0, "option '%s' is "				       "not implemented", clause->name);		/*		 * Don't log options with CFG_CLAUSEFLAG_NEWDEFAULT		 * set here - we need to log the *lack* of such an option,		 * not its presence.		 */		/* See if the clause already has a value; if not create one. */		result = isc_symtab_lookup(obj->value.map.symtab,					   clause->name, 0, &symval);		if ((clause->flags & CFG_CLAUSEFLAG_MULTI) != 0) {			/* Multivalued clause */			cfg_obj_t *listobj = NULL;			if (result == ISC_R_NOTFOUND) {				CHECK(cfg_create_list(pctx,						  &cfg_type_implicitlist,						  &listobj));				symval.as_pointer = listobj;				result = isc_symtab_define(obj->value.						   map.symtab,						   clause->name,						   1, symval,						   isc_symexists_reject);				if (result != ISC_R_SUCCESS) {					cfg_parser_error(pctx, CFG_LOG_NEAR,						     "isc_symtab_define(%s) "						     "failed", clause->name);					isc_mem_put(pctx->mctx, list,						    sizeof(cfg_list_t));					goto cleanup;				}			} else {				INSIST(result == ISC_R_SUCCESS);				listobj = symval.as_pointer;			}			elt = NULL;			CHECK(cfg_parse_listelt(pctx, clause->type, &elt));			CHECK(parse_semicolon(pctx));			ISC_LIST_APPEND(listobj->value.list, elt, link);		} else {			/* Single-valued clause */			if (result == ISC_R_NOTFOUND) {				isc_boolean_t callback =					ISC_TF((clause->flags &						CFG_CLAUSEFLAG_CALLBACK) != 0);				CHECK(parse_symtab_elt(pctx, clause->name,						       clause->type,						       obj->value.map.symtab,						       callback));				CHECK(parse_semicolon(pctx));			} else if (result == ISC_R_SUCCESS) {				cfg_parser_error(pctx, CFG_LOG_NEAR, "'%s' redefined",					     clause->name);				result = ISC_R_EXISTS;				goto cleanup;			} else {				cfg_parser_error(pctx, CFG_LOG_NEAR,					     "isc_symtab_define() failed");				goto cleanup;			}		}	}	*ret = obj;	return (ISC_R_SUCCESS); cleanup:	CLEANUP_OBJ(value);	CLEANUP_OBJ(obj);	CLEANUP_OBJ(eltobj);	CLEANUP_OBJ(includename);	return (result);}static isc_result_tparse_symtab_elt(cfg_parser_t *pctx, const char *name,		 cfg_type_t *elttype, isc_symtab_t *symtab,		 isc_boolean_t callback){	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));		symval.as_pointer = obj;	CHECK(isc_symtab_define(symtab, name,				1, symval,				isc_symexists_reject));	return (ISC_R_SUCCESS); cleanup:	CLEANUP_OBJ(obj);	return (result);}/* * Parse a map; e.g., "{ foo 1; bar { glub; }; zap true; zap false; }" */isc_result_tcfg_parse_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {	isc_result_t result;	CHECK(cfg_parse_special(pctx, '{'));	CHECK(cfg_parse_mapbody(pctx, type, ret));	CHECK(cfg_parse_special(pctx, '}')); cleanup:	return (result);}/* * Subroutine for cfg_parse_named_map() and cfg_parse_addressed_map(). */static isc_result_tparse_any_named_map(cfg_parser_t *pctx, cfg_type_t *nametype, const cfg_type_t *type,		    cfg_obj_t **ret){	isc_result_t result;	cfg_obj_t *idobj = NULL;	cfg_obj_t *mapobj = NULL;	CHECK(cfg_parse_obj(pctx, nametype, &idobj));	CHECK(cfg_parse_map(pctx, type, &mapobj));	mapobj->value.map.id = idobj;	idobj = NULL;	*ret = mapobj; cleanup:	CLEANUP_OBJ(idobj);	return (result);}/* * Parse a map identified by a string name.  E.g., "name { foo 1; }".   * Used for the "key" and "channel" statements. */isc_result_tcfg_parse_named_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {	return (parse_any_named_map(pctx, &cfg_type_astring, type, ret));}/* * Parse a map identified by a network address. * Used for the "server" statement. */isc_result_tcfg_parse_addressed_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {	return (parse_any_named_map(pctx, &cfg_type_netaddr, type, ret));}voidcfg_print_mapbody(cfg_printer_t *pctx, cfg_obj_t *obj) {	isc_result_t result = ISC_R_SUCCESS;	const cfg_clausedef_t * const *clauseset;	for (clauseset = obj->value.map.clausesets;	     *clauseset != NULL;	     clauseset++)	{		isc_symvalue_t symval;		const cfg_clausedef_t *clause;		for (clause = *clauseset;		     clause->name != NULL;		     clause++) {			result = isc_symtab_lookup(obj->value.map.symtab,						   clause->name, 0, &symval);			if (result == ISC_R_SUCCESS) {				cfg_obj_t *obj = symval.as_pointer;				if (obj->type == &cfg_type_implicitlist) {					/* Multivalued. */					cfg_list_t *list = &obj->value.list;					cfg_listelt_t *elt;					for (elt = ISC_LIST_HEAD(*list);					     elt != NULL;					     elt = ISC_LIST_NEXT(elt, link)) {						print_indent(pctx);						cfg_print_cstr(pctx, clause->name);						cfg_print_chars(pctx, " ", 1);						cfg_print_obj(pctx, elt->obj);						cfg_print_chars(pctx, ";\n", 2);					}				} else {					/* Single-valued. */					print_indent(pctx);					cfg_print_cstr(pctx, clause->name);					cfg_print_chars(pctx, " ", 1);					cfg_print_obj(pctx, obj);					cfg_print_chars(pctx, ";\n", 2);				}			} else if (result == ISC_R_NOTFOUND) {				; /* do nothing */			} else {				INSIST(0);			}		}	}}voidcfg_doc_mapbody(cfg_printer_t *pctx, const cfg_type_t *type) {	const cfg_clausedef_t * const *clauseset;	const cfg_clausedef_t *clause;		for (clauseset = type->of; *clauseset != NULL; clauseset++) {		for (clause = *clauseset;		     clause->name != NULL;		     clause++) {			cfg_print_cstr(pctx, clause->name);			cfg_print_chars(pctx, " ", 1);			cfg_doc_obj(pctx, clause->type);			cfg_print_chars(pctx, ";", 1);			/* XXX print flags here? */			cfg_print_chars(pctx, "\n\n", 2);		}	}}static struct flagtext {	unsigned int flag;	const char *text;} flagtexts[] = {	{ CFG_CLAUSEFLAG_NOTIMP, "not implemented" },	{ CFG_CLAUSEFLAG_NYI, "not yet implemented" },	{ CFG_CLAUSEFLAG_OBSOLETE, "obsolete" },	{ CFG_CLAUSEFLAG_NEWDEFAULT, "default changed" },	{ 0, NULL }};voidcfg_print_map(cfg_printer_t *pctx, cfg_obj_t *obj) {	if (obj->value.map.id != NULL) {		cfg_print_obj(pctx, obj->value.map.id);		cfg_print_chars(pctx, " ", 1);	}	print_open(pctx);	cfg_print_mapbody(pctx, obj);	print_close(pctx);}static voidprint_clause_flags(cfg_printer_t *pctx, unsigned int flags) {	struct flagtext *p;	isc_boolean_t first = ISC_TRUE;	for (p = flagtexts; p->flag != 0; p++) {		if ((flags & p->flag) != 0) {			if (first)				cfg_print_chars(pctx, " // ", 4);			else				cfg_print_chars(pctx, ", ", 2);			cfg_print_cstr(pctx, p->text);			first = ISC_FALSE;		}	}}voidcfg_doc_map(cfg_printer_t *pctx, const cfg_type_t *type) {	const cfg_clausedef_t * const *clauseset;	const cfg_clausedef_t *clause;		if (type->parse == cfg_parse_named_map) {		cfg_doc_obj(pctx, &cfg_type_astring);		cfg_print_chars(pctx, " ", 1);	} else if (type->parse == cfg_parse_addressed_map) {		cfg_doc_obj(pctx, &cfg_type_netaddr);		cfg_print_chars(pctx, " ", 1);	}		print_open(pctx);		for (clauseset = type->of; *clauseset != NULL; clauseset++) {		for (clause = *clauseset;		     clause->name != NULL;		     clause++) {			print_indent(pctx);			cfg_print_cstr(pctx, clause->name);			if (clause->type->print != cfg_print_void)				cfg_print_chars(pctx, " ", 1);			cfg_doc_obj(pctx, clause->type);			cfg_print_chars(pctx, ";", 1);			print_clause_flags(pctx, clause->flags);			cfg_print_chars(pctx, "\n", 1);		}	}	print_close(pctx);}isc_boolean_tcfg_obj_ismap(cfg_obj_t *obj) {	REQUIRE(obj != NULL);	return (ISC_TF(obj->type->rep == &cfg_rep_map));}isc_result_tcfg_map_get(cfg_obj_t *mapobj, const char* name, cfg_obj_t **obj) {	isc_result_t result;	isc_symvalue_t val;	cfg_map_t *map;		REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map);	REQUIRE(name != NULL);	REQUIRE(obj != NULL && *obj == NULL);	map = &mapobj->value.map;		result = isc_symtab_lookup(map->symtab, name, MAP_SYM, &val);	if (result != ISC_R_SUCCESS)		return (result);	*obj = val.as_pointer;	return (ISC_R_SUCCESS);}cfg_obj_t *cfg_map_getname(cfg_obj_t *mapobj) {	REQUIRE(mapobj != NULL && mapobj->type->rep == &cfg_rep_map);	return (mapobj->value.map.id);}/* Parse an arbitrary token, storing its raw text representation. */static isc_result_tparse_token(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {	cfg_obj_t *obj = NULL;        isc_result_t result;	isc_region_t r;	UNUSED(type);	CHECK(cfg_create_obj(pctx, &cfg_type_token, &obj));	CHECK(cfg_gettoken(pctx, CFG_LEXOPT_QSTRING));	if (pctx->token.type == isc_tokentype_eof) {		cfg_ungettoken(pctx);		result = ISC_R_EOF;		goto cleanup;	}	isc_lex_getlasttokentext(pctx->lexer, &pctx->token, &r);	obj->value.string.base = isc_mem_get(pctx->mctx, r.length + 1);	obj->value.string.length = r.length;	memcpy(obj->value.string.base, r.base, r.length);	obj->value.string.base[r.length] = '\0';	*ret = obj; cleanup:	return (result);}cfg_type_t cfg_type_token = {	"token", parse_token, cfg_print_ustring, cfg_doc_terminal,	&cfg_rep_string, NULL};/* * An unsupported option.  This is just a list of tokens with balanced braces * ending in a semicolon. */static isc_result_tparse_unsupported(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {	cfg_obj_t *listobj = NULL;	isc_result_t result;	int braces = 0;	CHECK(cfg_create_list(pctx, type, &listobj));	for (;;) {		cfg_listelt_t *elt = NULL;		CHECK(cfg_peektoken(pctx, 0));		if (pctx->token.type == isc_tokentype_special) {			if (pctx->token.value.as_char == '{')				braces++;			else if (pctx->token.value.as_char == '}')				braces--;			else if (pctx->token.value.as_char == ';')				if (braces == 0)					break;		}		if (pctx->token.type == isc_tokentype_eof || braces < 0) {			cfg_parser_error(pctx, CFG_LOG_NEAR, "unexpected token");			result = ISC_R_UNEXPECTEDTOKEN;			goto cleanup;		}		CHECK(cfg_parse_listelt(pctx, &cfg_type_token, &elt));		ISC_LIST_APPEND(listobj->value.list, elt, link);	}	INSIST(braces == 0);	*ret = listobj;	return (ISC_R_SUCCESS); cleanup:	CLEANUP_OBJ(listobj);	return (result);}cfg_type_t cfg_type_unsupported = {	"unsupported", parse_unsupported, cfg_print_spacelist, cfg_doc_terminal,	&cfg_rep_list, NULL};/* * Try interpreting the current token as a network address. * * If CFG_ADDR_WILDOK is set in flags, "*" can be used as a wildcard * and at least one of CFG_ADDR_V4OK and CFG_ADDR_V6OK must also be set.  The * "*" is interpreted as the IPv4 wildcard address if CFG_ADDR_V4OK is  * set (including the case where CFG_ADDR_V4OK and CFG_ADDR_V6OK are both set), * and the IPv6 wildcard address otherwise. */static isc_result_ttoken_addr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) {	char *s;	struct in_addr in4a;	struct in6_addr in6a;	if (pctx->token.type != isc_tokentype_string)		return (ISC_R_UNEXPECTEDTOKEN);	s = TOKEN_STRING(pctx);	if ((flags & CFG_ADDR_WILDOK) != 0 && strcmp(s, "*") == 0) {		if ((flags & CFG_ADDR_V4OK) != 0) {			isc_netaddr_any(na);			return (ISC_R_SUCCESS);		} else if ((flags & CFG_ADDR_V6OK) != 0) {			isc_netaddr_any6(na);			return (ISC_R_SUCCESS);		} else {			INSIST(0);		}	} else {		if ((flags & (CFG_ADDR_V4OK | CFG_ADDR_V4PREFIXOK)) != 0) {			if (inet_pton(AF_INET, s, &in4a) == 1) {				isc_netaddr_fromin(na, &in4a);				return (ISC_R_SUCCESS);			}		}		if ((flags & CFG_ADDR_V4PREFIXOK) != 0 &&		    strlen(s) <= 15U) {			char buf[64];			int i;			strcpy(buf, s);			for (i = 0; i < 3; i++) {				strcat(buf, ".0");				if (inet_pton(AF_INET, buf, &in4a) == 1) {					isc_netaddr_fromin(na, &in4a);					return (ISC_R_SUCCESS);				}			}		}		if ((flags & CFG_ADDR_V6OK) != 0 &&		    strlen(s) <= 127U) {			char buf[128]; /* see lib/bind9/getaddresses.c */			char *d; /* zone delimiter */			isc_uint32_t zone = 0; /* scope zone ID */			strcpy(buf, s);			d = strchr(buf, '%');			if (d != NULL)				*d = '\0';			if (inet_pton(AF_INET6, buf, &in6a) == 1) {				if (d != NULL) {#ifdef ISC_PLATFORM_HAVESCOPEID					isc_result_t result;					result = isc_netscope_pton(AF_INET6,								   d + 1,								   &in6a,								   &zone);					if (result != ISC_R_SUCCESS)						return (result);#else				return (ISC_R_BADADDRESSFORM);#endif				}				isc_netaddr_fromin6(na, &in6a);				isc_netaddr_setzone(na, zone);				return (ISC_R_SUCCESS);			}		}	}	return (ISC_R_UNEXPECTEDTOKEN);}isc_result_tcfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na) {	isc_result_t result;	CHECK(cfg_gettoken(pctx, 0));	result = token_addr(pctx, flags, na);	if (result == ISC_R_UNEXPECTEDTOKEN)		cfg_parser_error(pctx, CFG_LOG_NEAR, "expected IP address"); cleanup:	return (result);}isc_boolean_t

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -