📄 parse.c
字号:
parse_warn (cfile, "more than one secondary."); skip_to_semi (cfile); return 0; } if (!option_cache_allocate (&zone -> secondary, MDL)) log_fatal ("can't allocate secondary."); oc = zone -> secondary; consemup: token = next_token (&val, (unsigned *)0, cfile); do { struct expression *expr = (struct expression *)0; if (!parse_ip_addr_or_hostname (&expr, cfile, 0)) { parse_warn (cfile, "expecting IP addr or hostname."); skip_to_semi (cfile); return 0; } if (oc -> expression) { struct expression *old = (struct expression *)0; expression_reference (&old, oc -> expression, MDL); expression_dereference (&oc -> expression, MDL); if (!make_concat (&oc -> expression, old, expr)) log_fatal ("no memory for concat."); expression_dereference (&expr, MDL); expression_dereference (&old, MDL); } else { expression_reference (&oc -> expression, expr, MDL); expression_dereference (&expr, MDL); } token = next_token (&val, (unsigned *)0, cfile); } while (token == COMMA); if (token != SEMI) { parse_warn (cfile, "expecting semicolon."); skip_to_semi (cfile); return 0; } break; case KEY: token = next_token (&val, (unsigned *)0, cfile); token = peek_token (&val, (unsigned *)0, cfile); if (token == STRING) { token = next_token (&val, (unsigned *)0, cfile); key_name = (char *)0; } else { key_name = parse_host_name (cfile); if (!key_name) { parse_warn (cfile, "expecting key name."); skip_to_semi (cfile); return 0; } val = key_name; } if (omapi_auth_key_lookup_name (&zone -> key, val) != ISC_R_SUCCESS) parse_warn (cfile, "unknown key %s", val); if (key_name) dfree (key_name, MDL); if (!parse_semi (cfile)) return 0; break; default: done = 1; break; } } while (!done); token = next_token (&val, (unsigned *)0, cfile); if (token != RBRACE) { parse_warn (cfile, "expecting right brace."); return 0; } return 1;}/* key-statements :== key-statement | key-statement key-statements key-statement :== ALGORITHM host-name SEMI | secret-definition SEMI secret-definition :== SECRET base64val | SECRET STRING */int parse_key (struct parse *cfile){ int token; const char *val; int done = 0; struct auth_key *key; struct data_string ds; isc_result_t status; char *s; key = (struct auth_key *)0; if (omapi_auth_key_new (&key, MDL) != ISC_R_SUCCESS) log_fatal ("no memory for key"); token = peek_token (&val, (unsigned *)0, cfile); if (token == STRING) { token = next_token (&val, (unsigned *)0, cfile); key -> name = dmalloc (strlen (val) + 1, MDL); if (!key -> name) log_fatal ("no memory for key name."); strcpy (key -> name, val); } else { key -> name = parse_host_name (cfile); if (!key -> name) { parse_warn (cfile, "expecting key name."); skip_to_semi (cfile); goto bad; } } token = next_token (&val, (unsigned *)0, cfile); if (token != LBRACE) { parse_warn (cfile, "expecting left brace"); goto bad; } do { token = next_token (&val, (unsigned *)0, cfile); switch (token) { case ALGORITHM: if (key -> algorithm) { parse_warn (cfile, "key %s: too many algorithms", key -> name); goto rbad; } key -> algorithm = parse_host_name (cfile); if (!key -> algorithm) { parse_warn (cfile, "expecting key algorithm name."); goto rbad; } if (!parse_semi (cfile)) goto rbad; /* If the algorithm name isn't an FQDN, tack on the .SIG-ALG.REG.NET. domain. */ s = strrchr (key -> algorithm, '.'); if (!s) { static char add [] = ".SIG-ALG.REG.INT."; s = dmalloc (strlen (key -> algorithm) + sizeof (add), MDL); if (!s) { log_error ("no memory for key %s.", "algorithm"); goto rbad; } strcpy (s, key -> algorithm); strcat (s, add); dfree (key -> algorithm, MDL); key -> algorithm = s; } else if (s [1]) { /* If there is no trailing '.', hack one in. */ s = dmalloc (strlen (key -> algorithm) + 2, MDL); if (!s) { log_error ("no memory for key %s.", key -> algorithm); goto rbad; } strcpy (s, key -> algorithm); strcat (s, "."); dfree (key -> algorithm, MDL); key -> algorithm = s; } break; case SECRET: if (key -> key) { parse_warn (cfile, "key %s: too many secrets", key -> name); goto rbad; } memset (&ds, 0, sizeof(ds)); if (!parse_base64 (&ds, cfile)) goto rbad; status = omapi_data_string_new (&key -> key, ds.len, MDL); if (status != ISC_R_SUCCESS) goto rbad; memcpy (key -> key -> value, ds.buffer -> data, ds.len); data_string_forget (&ds, MDL); if (!parse_semi (cfile)) goto rbad; break; default: done = 1; break; } } while (!done); if (token != RBRACE) { parse_warn (cfile, "expecting right brace."); goto rbad; } /* Allow the BIND 8 syntax, which has a semicolon after each closing brace. */ token = peek_token (&val, (unsigned *)0, cfile); if (token == SEMI) token = next_token (&val, (unsigned *)0, cfile); /* Remember the key. */ status = omapi_auth_key_enter (key); if (status != ISC_R_SUCCESS) { parse_warn (cfile, "tsig key %s: %s", key -> name, isc_result_totext (status)); goto bad; } omapi_auth_key_dereference (&key, MDL); return 1; rbad: skip_to_rbrace (cfile, 1); bad: omapi_auth_key_dereference (&key, MDL); return 0;}/* * on-statement :== event-types LBRACE executable-statements RBRACE * event-types :== event-type OR event-types | * event-type * event-type :== EXPIRY | COMMIT | RELEASE */int parse_on_statement (result, cfile, lose) struct executable_statement **result; struct parse *cfile; int *lose;{ enum dhcp_token token; const char *val; if (!executable_statement_allocate (result, MDL)) log_fatal ("no memory for new statement."); (*result) -> op = on_statement; do { token = next_token (&val, (unsigned *)0, cfile); switch (token) { case EXPIRY: (*result) -> data.on.evtypes |= ON_EXPIRY; break; case COMMIT: (*result) -> data.on.evtypes |= ON_COMMIT; break; case RELEASE: (*result) -> data.on.evtypes |= ON_RELEASE; break; case TRANSMISSION: (*result) -> data.on.evtypes |= ON_TRANSMISSION; break; default: parse_warn (cfile, "expecting a lease event type"); skip_to_semi (cfile); *lose = 1; executable_statement_dereference (result, MDL); return 0; } token = next_token (&val, (unsigned *)0, cfile); } while (token == OR); /* Semicolon means no statements. */ if (token == SEMI) return 1; if (token != LBRACE) { parse_warn (cfile, "left brace expected."); skip_to_semi (cfile); *lose = 1; executable_statement_dereference (result, MDL); return 0; } if (!parse_executable_statements (&(*result) -> data.on.statements, cfile, lose, context_any)) { if (*lose) { /* Try to even things up. */ do { token = next_token (&val, (unsigned *)0, cfile); } while (token != END_OF_FILE && token != RBRACE); executable_statement_dereference (result, MDL); return 0; } } token = next_token (&val, (unsigned *)0, cfile); if (token != RBRACE) { parse_warn (cfile, "right brace expected."); skip_to_semi (cfile); *lose = 1; executable_statement_dereference (result, MDL); return 0; } return 1;}/* * switch-statement :== LPAREN expr RPAREN LBRACE executable-statements RBRACE * */int parse_switch_statement (result, cfile, lose) struct executable_statement **result; struct parse *cfile; int *lose;{ enum dhcp_token token; const char *val; if (!executable_statement_allocate (result, MDL)) log_fatal ("no memory for new statement."); (*result) -> op = switch_statement; token = next_token (&val, (unsigned *)0, cfile); if (token != LPAREN) { parse_warn (cfile, "expecting left brace."); pfui: *lose = 1; skip_to_semi (cfile); gnorf: executable_statement_dereference (result, MDL); return 0; } if (!parse_expression (&(*result) -> data.s_switch.expr, cfile, lose, context_data_or_numeric, (struct expression **)0, expr_none)) { if (!*lose) { parse_warn (cfile, "expecting data or numeric expression."); goto pfui; } goto gnorf; } token = next_token (&val, (unsigned *)0, cfile); if (token != RPAREN) { parse_warn (cfile, "right paren expected."); goto pfui; } token = next_token (&val, (unsigned *)0, cfile); if (token != LBRACE) { parse_warn (cfile, "left brace expected."); goto pfui; } if (!(parse_executable_statements (&(*result) -> data.s_switch.statements, cfile, lose, (is_data_expression ((*result) -> data.s_switch.expr) ? context_data : context_numeric)))) { if (*lose) { skip_to_rbrace (cfile, 1); executable_statement_dereference (result, MDL); return 0; } } token = next_token (&val, (unsigned *)0, cfile); if (token != RBRACE) { parse_warn (cfile, "right brace expected."); goto pfui; } return 1;}/* * case-statement :== CASE expr COLON * */int parse_case_statement (result, cfile, lose, case_context) struct executable_statement **result; struct parse *cfile; int *lose; enum expression_context case_context;{ enum dhcp_token token; const char *val; if (!executable_statement_allocate (result, MDL)) log_fatal ("no memory for new statement."); (*result) -> op = case_statement; if (!parse_expression (&(*result) -> data.c_case, cfile, lose, case_context, (struct expression **)0, expr_none)) { if (!*lose) { parse_warn (cfile, "expecting %s expression.", (case_context == context_data ? "data" : "numeric")); } pfui: *lose = 1; skip_to_semi (cfile); executable_statement_dereference (result, MDL); return 0; } token = next_token (&val, (unsigned *)0, cfile); if (token != COLON) { parse_warn (cfile, "colon expected."); goto pfui; } return 1;}/* * if-statement :== boolean-expression LBRACE executable-statements RBRACE * else-statement * * else-statement :== <null> | * ELSE LBRACE executable-statements RBRACE | * ELSE IF if-statement | * ELSIF if-statement */int parse_if_statement (result, cfile, lose) struct executable_statement **result; struct parse *cfile; int *lose;{ enum dhcp_token token; const char *val; int parenp; if (!executable_statement_allocate (result, MDL)) log_fatal ("no memory for if statement."); (*result) -> op = if_statement; token = peek_token (&val, (unsigned *)0, cfile); if (token == LPAREN) { parenp = 1; next_token (&val, (unsigned *)0, cfile); } else parenp = 0; if (!parse_boolean_expression (&(*result) -> data.ie.expr, cfile, lose)) { if (!*lose) parse_warn (cfile, "boolean expression expected."); executable_statement_dereference (result, MDL); *lose = 1; return 0; }#if defined (DEBUG_EXPRESSION_PARSE) print_expression ("if condition", (*result) -> data.ie.expr);#endif if (parenp) { token = next_token (&val, (unsigned *)0, cfile); if (token != RPAREN) { parse_warn (cfile, "expecting right paren."); *lose = 1; executable_statement_dereference (result, MDL); return 0; } } token = next_token (&val, (unsigned *)0, cfile); if (token != LBRACE) { parse_warn (cfile, "left brace expected."); skip_to_semi (cfile); *lose = 1; executable_statement_dereference (result, MDL); return 0; } if (!parse_executable_statements (&(*result) -> data.ie.tc, cfile, lose, context_any)) { if (*lose) { /* Try to even things up. */ do { token = next_token (&val, (unsigned *)0, cfile); } while (token != END_OF_FILE && token != RBRACE); executable_statement_dereference (result, MDL); return 0; } } token = next_token (&val, (unsigned *)0, cfile); if (token != RBRACE) { parse_warn (cfile, "right brace expected."); skip_to_semi (cfile); *lose = 1; executable_statement_dereference (result, MDL); return 0; } token = peek_token (&val, (unsigned *)0, cfile); if (token == ELSE) { token = next_token (&val, (unsigned *)0, cfile); token = peek_token (&val, (unsigned *)0, cfile); if (token == IF) { token = next_token (&val, (unsigned *)0, cfile); if (!parse_if_statement (&(*result) -> data.ie.fc, cfile, lose)) { if (!*lose) parse_warn (cfile, "expecting if statement"); executable_statement_dereference (result, MDL); *lose = 1; return 0; } } else if (token != LBRACE) { parse_warn (cfile, "left brac
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -