📄 parse.c
字号:
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 + -