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

📄 parse.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		token = next_token (&val, (unsigned *)0, cfile);		known = 0;		option = parse_option_name (cfile, 0, &known);		if (!option) {			*lose = 1;			return 0;		}		return parse_option_statement (result, cfile, 1, option,					       send_option_statement);	      case SUPERSEDE:	      case OPTION:		token = next_token (&val, (unsigned *)0, cfile);		known = 0;		option = parse_option_name (cfile, 0, &known);		if (!option) {			*lose = 1;			return 0;		}		return parse_option_statement (result, cfile, 1, option,					       supersede_option_statement);	      case ALLOW:		flag = 1;		goto pad;	      case DENY:		flag = 0;		goto pad;	      case IGNORE:		flag = 2;	      pad:		token = next_token (&val, (unsigned *)0, cfile);		cache = (struct option_cache *)0;		if (!parse_allow_deny (&cache, cfile, flag))			return 0;		if (!executable_statement_allocate (result, MDL))			log_fatal ("no memory for new statement.");		(*result) -> op = supersede_option_statement;		(*result) -> data.option = cache;		break;	      case DEFAULT:		token = next_token (&val, (unsigned *)0, cfile);		token = peek_token (&val, (unsigned *)0, cfile);		if (token == COLON)			goto switch_default;		known = 0;		option = parse_option_name (cfile, 0, &known);		if (!option) {			*lose = 1;			return 0;		}		return parse_option_statement (result, cfile, 1, option,					       default_option_statement);	      case PREPEND:		token = next_token (&val, (unsigned *)0, cfile);		known = 0;		option = parse_option_name (cfile, 0, &known);		if (!option) {			*lose = 1;			return 0;		}		return parse_option_statement (result, cfile, 1, option,					       prepend_option_statement);	      case APPEND:		token = next_token (&val, (unsigned *)0, cfile);		known = 0;		option = parse_option_name (cfile, 0, &known);		if (!option) {			*lose = 1;			return 0;		}		return parse_option_statement (result, cfile, 1, option,					       append_option_statement);	      case ON:		token = next_token (&val, (unsigned *)0, cfile);		return parse_on_statement (result, cfile, lose);				      case SWITCH:		token = next_token (&val, (unsigned *)0, cfile);		return parse_switch_statement (result, cfile, lose);	      case CASE:		token = next_token (&val, (unsigned *)0, cfile);		if (case_context == context_any) {			parse_warn (cfile,				    "case statement in inappropriate scope.");			*lose = 1;			skip_to_semi (cfile);			return 0;		}		return parse_case_statement (result,					     cfile, lose, case_context);	      switch_default:		token = next_token (&val, (unsigned *)0, cfile);		if (case_context == context_any) {			parse_warn (cfile, "switch default statement in %s",				    "inappropriate scope.");					*lose = 1;			return 0;		} else {			if (!executable_statement_allocate (result, MDL))				log_fatal ("no memory for default statement.");			(*result) -> op = default_statement;			return 1;		}				      case DEFINE:	      case TOKEN_SET:		token = next_token (&val, (unsigned *)0, cfile);		if (token == DEFINE)			flag = 1;		else			flag = 0;		token = next_token (&val, (unsigned *)0, cfile);		if (token != NAME && token != NUMBER_OR_NAME) {			parse_warn (cfile,				    "%s can't be a variable name", val);		      badset:			skip_to_semi (cfile);			*lose = 1;			return 0;		}		if (!executable_statement_allocate (result, MDL))			log_fatal ("no memory for set statement.");		(*result) -> op = flag ? define_statement : set_statement;		(*result) -> data.set.name = dmalloc (strlen (val) + 1, MDL);		if (!(*result)->data.set.name)			log_fatal ("can't allocate variable name");		strcpy ((*result) -> data.set.name, val);		token = next_token (&val, (unsigned *)0, cfile);		if (token == LPAREN) {			struct string_list *head, *cur, *new;			struct expression *expr;			head = cur = (struct string_list *)0;			do {				token = next_token (&val,						    (unsigned *)0, cfile);				if (token == RPAREN)					break;				if (token != NAME && token != NUMBER_OR_NAME) {					parse_warn (cfile,						    "expecting argument name");					skip_to_rbrace (cfile, 0);					*lose = 1;					executable_statement_dereference						(result, MDL);					return 0;				}				new = ((struct string_list *)				       dmalloc (sizeof (struct string_list) +						strlen (val), MDL));				if (!new)					log_fatal ("can't allocate string.");				memset (new, 0, sizeof *new);				strcpy (new -> string, val);				if (cur) {					cur -> next = new;					cur = new;				} else {					head = cur = new;				}				token = next_token (&val,						    (unsigned *)0, cfile);			} while (token == COMMA);			if (token != RPAREN) {				parse_warn (cfile, "expecting right paren.");			      badx:				skip_to_semi (cfile);				*lose = 1;				executable_statement_dereference (result, MDL);				return 0;			}			token = next_token (&val, (unsigned *)0, cfile);			if (token != LBRACE) {				parse_warn (cfile, "expecting left brace.");				goto badx;			}			expr = (struct expression *)0;			if (!(expression_allocate (&expr, MDL)))				log_fatal ("can't allocate expression.");			expr -> op = expr_function;			if (!fundef_allocate (&expr -> data.func, MDL))				log_fatal ("can't allocate fundef.");			expr -> data.func -> args = head;			(*result) -> data.set.expr = expr;			if (!(parse_executable_statements			      (&expr -> data.func -> statements, cfile, lose,			       case_context))) {				if (*lose)					goto badx;			}			token = next_token (&val, (unsigned *)0, cfile);			if (token != RBRACE) {				parse_warn (cfile, "expecting rigt brace.");				goto badx;			}		} else {			if (token != EQUAL) {				parse_warn (cfile,					    "expecting '=' in %s statement.",					    flag ? "define" : "set");				goto badset;			}			if (!parse_expression (&(*result) -> data.set.expr,					       cfile, lose, context_any,					       (struct expression **)0,					       expr_none)) {				if (!*lose)					parse_warn (cfile,						    "expecting expression.");				else					*lose = 1;				skip_to_semi (cfile);				executable_statement_dereference (result, MDL);				return 0;			}			if (!parse_semi (cfile)) {				*lose = 1;				executable_statement_dereference (result, MDL);				return 0;			}		}		break;	      case UNSET:		token = next_token (&val, (unsigned *)0, cfile);		token = next_token (&val, (unsigned *)0, cfile);		if (token != NAME && token != NUMBER_OR_NAME) {			parse_warn (cfile,				    "%s can't be a variable name", val);		      badunset:			skip_to_semi (cfile);			*lose = 1;			return 0;		}		if (!executable_statement_allocate (result, MDL))			log_fatal ("no memory for set statement.");		(*result) -> op = unset_statement;		(*result) -> data.unset = dmalloc (strlen (val) + 1, MDL);		if (!(*result)->data.unset)			log_fatal ("can't allocate variable name");		strcpy ((*result) -> data.unset, val);		if (!parse_semi (cfile)) {			*lose = 1;			executable_statement_dereference (result, MDL);			return 0;		}		break;	      case EVAL:		token = next_token (&val, (unsigned *)0, cfile);		if (!executable_statement_allocate (result, MDL))			log_fatal ("no memory for eval statement.");		(*result) -> op = eval_statement;		if (!parse_expression (&(*result) -> data.eval,				       cfile, lose, context_data, /* XXX */				       (struct expression **)0, expr_none)) {			if (!*lose)				parse_warn (cfile,					    "expecting data expression.");			else				*lose = 1;			skip_to_semi (cfile);			executable_statement_dereference (result, MDL);			return 0;		}		if (!parse_semi (cfile)) {			*lose = 1;			executable_statement_dereference (result, MDL);		}		break;	      case RETURN:		token = next_token (&val, (unsigned *)0, cfile);		if (!executable_statement_allocate (result, MDL))			log_fatal ("no memory for return statement.");		(*result) -> op = return_statement;		if (!parse_expression (&(*result) -> data.retval,				       cfile, lose, context_data,				       (struct expression **)0, expr_none)) {			if (!*lose)				parse_warn (cfile,					    "expecting data expression.");			else				*lose = 1;			skip_to_semi (cfile);			executable_statement_dereference (result, MDL);			return 0;		}		if (!parse_semi (cfile)) {			*lose = 1;			executable_statement_dereference (result, MDL);			return 0;		}		break;	      case LOG:		token = next_token (&val, (unsigned *)0, cfile);		if (!executable_statement_allocate (result, MDL))			log_fatal ("no memory for log statement.");		(*result) -> op = log_statement;		token = next_token (&val, (unsigned *)0, cfile);		if (token != LPAREN) {			parse_warn (cfile, "left parenthesis expected.");			skip_to_semi (cfile);			*lose = 1;			return 0;		}		token = peek_token (&val, (unsigned *)0, cfile);		i = 1;		if (token == FATAL) {			(*result) -> data.log.priority = log_priority_fatal;		} else if (token == ERROR) {			(*result) -> data.log.priority = log_priority_error;		} else if (token == TOKEN_DEBUG) {			(*result) -> data.log.priority = log_priority_debug;		} else if (token == INFO) {			(*result) -> data.log.priority = log_priority_info;		} else {			(*result) -> data.log.priority = log_priority_debug;			i = 0;		}		if (i) {			token = next_token (&val, (unsigned *)0, cfile);			token = next_token (&val, (unsigned *)0, cfile);			if (token != COMMA) {				parse_warn (cfile, "comma expected.");				skip_to_semi (cfile);				*lose = 1;				return 0;			}		}		if (!(parse_data_expression		      (&(*result) -> data.log.expr, cfile, lose))) {			skip_to_semi (cfile);			*lose = 1;			return 0;		}		token = next_token (&val, (unsigned *)0, cfile);		if (token != RPAREN) {			parse_warn (cfile, "right parenthesis expected.");			skip_to_semi (cfile);			*lose = 1;			return 0;		}		token = next_token (&val, (unsigned *)0, cfile);		if (token != SEMI) {			parse_warn (cfile, "semicolon expected.");			skip_to_semi (cfile);			*lose = 1;			return 0;		}		break;					/* Not really a statement, but we parse it here anyway		   because it's appropriate for all DHCP agents with		   parsers. */	      case ZONE:		token = next_token (&val, (unsigned *)0, cfile);		zone = (struct dns_zone *)0;		if (!dns_zone_allocate (&zone, MDL))			log_fatal ("no memory for new zone.");		zone -> name = parse_host_name (cfile);		if (!zone -> name) {			parse_warn (cfile, "expecting hostname.");		      badzone:			*lose = 1;			skip_to_semi (cfile);			dns_zone_dereference (&zone, MDL);			return 0;		}		i = strlen (zone -> name);		if (zone -> name [i - 1] != '.') {			s = dmalloc ((unsigned)i + 2, MDL);			if (!s) {				parse_warn (cfile, "no trailing '.' on zone");				goto badzone;			}			strcpy (s, zone -> name);			s [i] = '.';			s [i + 1] = 0;			dfree (zone -> name, MDL);			zone -> name = s;		}		if (!parse_zone (zone, cfile))			goto badzone;		status = enter_dns_zone (zone);		if (status != ISC_R_SUCCESS) {			parse_warn (cfile, "dns zone key %s: %s",				    zone -> name, isc_result_totext (status));			dns_zone_dereference (&zone, MDL);			return 0;		}		dns_zone_dereference (&zone, MDL);		return 1;				/* Also not really a statement, but same idea as above. */	      case KEY:		token = next_token (&val, (unsigned *)0, cfile);		if (!parse_key (cfile)) {			*lose = 1;			return 0;		}		return 1;	      default:		if (config_universe && is_identifier (token)) {			option = (struct option *)0;			option_hash_lookup (&option, config_universe -> hash,					    val, 0, MDL);			if (option) {				token = next_token (&val,						    (unsigned *)0, cfile);				return parse_option_statement					(result, cfile, 1, option,					 supersede_option_statement);			}		}		if (token == NUMBER_OR_NAME || token == NAME) {			/* This is rather ugly.  Since function calls are			   data expressions, fake up an eval statement. */			if (!executable_statement_allocate (result, MDL))				log_fatal ("no memory for eval statement.");			(*result) -> op = eval_statement;			if (!parse_expression (&(*result) -> data.eval,					       cfile, lose, context_data,					       (struct expression **)0,					       expr_none)) {				if (!*lose)					parse_warn (cfile, "expecting "						    "function call.");				else					*lose = 1;				skip_to_semi (cfile);				executable_statement_dereference (result, MDL);				return 0;			}			if (!parse_semi (cfile)) {				*lose = 1;				executable_statement_dereference (result, MDL);				return 0;			}			break;		}		*lose = 0;		return 0;	}	return 1;}/* zone-statements :== zone-statement |		       zone-statement zone-statements   zone-statement :==	PRIMARY ip-addresses SEMI |	SECONDARY ip-addresses SEMI |	key-reference SEMI   ip-addresses :== ip-addr-or-hostname |		  ip-addr-or-hostname COMMA ip-addresses   key-reference :== KEY STRING |		    KEY identifier */int parse_zone (struct dns_zone *zone, struct parse *cfile){	int token;	const char *val;	char *key_name;	struct option_cache *oc;	int done = 0;	token = next_token (&val, (unsigned *)0, cfile);	if (token != LBRACE) {		parse_warn (cfile, "expecting left brace");		return 0;	}	do {	    token = peek_token (&val, (unsigned *)0, cfile);	    switch (token) {		  case PRIMARY:		    if (zone -> primary) {			    parse_warn (cfile,					"more than one primary.");			    skip_to_semi (cfile);			    return 0;		    }		    if (!option_cache_allocate (&zone -> primary, MDL))			    log_fatal ("can't allocate primary option cache.");		    oc = zone -> primary;		    goto consemup;		    		  case SECONDARY:		    if (zone -> secondary) {

⌨️ 快捷键说明

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