📄 parse.c
字号:
*/static int policy_lex_push_token(policy_lex_file_t *lexer, policy_lex_t token){ if (lexer->token != POLICY_LEX_BAD) { rad_assert(0 == 1); return 0; } lexer->token = token; return 1;}/* * Forward declarations. */static int parse_block(policy_lex_file_t *lexer, policy_item_t **tail);/* * Map reserved words to tokens, and vice versa. */const FR_NAME_NUMBER policy_reserved_words[] = { { "if", POLICY_RESERVED_IF }, { "else", POLICY_RESERVED_ELSE }, { "debug", POLICY_RESERVED_DEBUG }, { "print", POLICY_RESERVED_PRINT }, { "policy", POLICY_RESERVED_POLICY }, { "control", POLICY_RESERVED_CONTROL }, { "request", POLICY_RESERVED_REQUEST }, { "reply", POLICY_RESERVED_REPLY }, { "proxy-request", POLICY_RESERVED_PROXY_REQUEST }, { "proxy-reply", POLICY_RESERVED_PROXY_REPLY }, { "include", POLICY_RESERVED_INCLUDE }, { "return", POLICY_RESERVED_RETURN }, { "module", POLICY_RESERVED_MODULE }, { NULL, POLICY_RESERVED_UNKNOWN }};/* * Simplifies some later coding */static int policy_lex_str2int(policy_lex_file_t *lexer, const FR_NAME_NUMBER *table, int default_value){ policy_lex_t token; char buffer[256]; token = policy_lex_file(lexer, 0, buffer, sizeof(buffer)); if (token != POLICY_LEX_BARE_WORD) { fprintf(stderr, "%s[%d]: Unexpected token\n", lexer->filename, lexer->lineno); return default_value; } return fr_str2int(table, buffer, default_value);}/* * print foo * print "foo" */static int parse_print(policy_lex_file_t *lexer, policy_item_t **tail){ policy_lex_t token; char mystring[1024]; policy_print_t *this; debug_tokens("[PRINT] "); this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_PRINT; this->item.lineno = lexer->lineno; token = policy_lex_file(lexer, 0, mystring, sizeof(mystring)); if ((token != POLICY_LEX_BARE_WORD) && (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) { fprintf(stderr, "%s[%d]: Bad print command\n", lexer->filename, lexer->lineno); rlm_policy_free_item((policy_item_t *) this); return 0; } this->rhs_type = token; this->rhs = strdup(mystring); *tail = (policy_item_t *) this; return 1;}/* * (foo == bar), with nested conditionals. */static int parse_condition(policy_lex_file_t *lexer, policy_item_t **tail){ int rcode, seen_not = FALSE; policy_lex_t token, compare; char lhs[256], rhs[256]; policy_condition_t *this; token = policy_lex_file(lexer, 0, lhs, sizeof(lhs)); if (token != POLICY_LEX_L_BRACKET) { fprintf(stderr, "%s[%d]: Expected '(', got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, lhs)); return 0; } this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_CONDITIONAL; this->item.lineno = lexer->lineno; redo: token = policy_lex_file(lexer, 0, lhs, sizeof(lhs)); switch (token) { case POLICY_LEX_L_BRACKET: if (!policy_lex_push_token(lexer, token)) { rlm_policy_free_item((policy_item_t *) this); return 0; } this->compare = POLICY_LEX_L_BRACKET; this->child_condition = POLICY_LEX_L_BRACKET; rcode = parse_condition(lexer, &(this->child)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } break; case POLICY_LEX_L_NOT: if (seen_not) { fprintf(stderr, "%s[%d]: Syntax error at \"!!\"\n", lexer->filename, lexer->lineno); rlm_policy_free_item((policy_item_t *) this); return 0; } debug_tokens("[NOT] "); token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0); if (token != POLICY_LEX_L_BRACKET) { seen_not = this->sense = 1; goto redo; } this->compare = POLICY_LEX_L_NOT; rcode = parse_condition(lexer, &(this->child)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } break; case POLICY_LEX_BARE_WORD: this->lhs_type = token; token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0); if (token == POLICY_LEX_L_BRACKET) { debug_tokens("[IF-CALL %s] ", lhs); /* * Function call. */ if (rlm_policy_find(lexer->policies, lhs) == NULL) { fprintf(stderr, "%s[%d]: Undefined function \"%s\"\n", lexer->filename, lexer->lineno, lhs); rlm_policy_free_item((policy_item_t *) this); return 0; } /* * this->lhs set up below, after "check" */ this->lhs_type = POLICY_LEX_FUNCTION; /* * Copied from parse_call */ token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_L_BRACKET) { fprintf(stderr, "%s[%d]: Expected left bracket, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); rlm_policy_free_item((policy_item_t *) this); return 0; } token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_R_BRACKET) { fprintf(stderr, "%s[%d]: Expected right bracket, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); rlm_policy_free_item((policy_item_t *) this); return 0; } } /* else it's a comparison? */ goto check; case POLICY_LEX_DOUBLE_QUOTED_STRING: this->lhs_type = token; /* * Got word. May just be test for existence. */ check: token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0); if (token == POLICY_LEX_R_BRACKET) { debug_tokens("[TEST %s] ", lhs); this->lhs = strdup(lhs); this->compare = POLICY_LEX_CMP_TRUE; break; } compare = policy_lex_file(lexer, 0, rhs, sizeof(rhs)); switch (compare) { case POLICY_LEX_CMP_EQUALS: case POLICY_LEX_CMP_NOT_EQUALS: case POLICY_LEX_RX_EQUALS: case POLICY_LEX_RX_NOT_EQUALS: case POLICY_LEX_CMP_TRUE: case POLICY_LEX_CMP_FALSE: case POLICY_LEX_LT: case POLICY_LEX_GT: case POLICY_LEX_LE: case POLICY_LEX_GE: break; default: fprintf(stderr, "%s[%d]: Invalid operator \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, compare, rhs)); rlm_policy_free_item((policy_item_t *) this); return 0; } token = policy_lex_file(lexer, 0, rhs, sizeof(rhs)); if ((token != POLICY_LEX_BARE_WORD) && (token != POLICY_LEX_DOUBLE_QUOTED_STRING)) { fprintf(stderr, "%s[%d]: Unexpected rhs token\n", lexer->filename, lexer->lineno); rlm_policy_free_item((policy_item_t *) this); return 0; } debug_tokens("[COMPARE (%s %s %s)] ", lhs, fr_int2str(rlm_policy_tokens, compare, "?"), rhs); this->lhs = strdup(lhs); this->compare = compare; this->rhs_type = token; this->rhs = strdup(rhs); break; default: fprintf(stderr, "%s[%d]: Unexpected lhs token\n", lexer->filename, lexer->lineno); rlm_policy_free_item((policy_item_t *) this); return 0; } token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_R_BRACKET) { fprintf(stderr, "%s[%d]: Expected ')', got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); rlm_policy_free_item((policy_item_t *) this); return 0; } /* * After the end of condition, we MAY have && or || */ token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, 0); if ((token == POLICY_LEX_L_AND) || (token == POLICY_LEX_L_OR)) { token = policy_lex_file(lexer, 0, NULL, 0); /* skip over it */ debug_tokens("[%s] ", fr_int2str(rlm_policy_tokens, token, "?")); this->child_condition = token; rcode = parse_condition(lexer, &(this->child)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return 0; } } *tail = (policy_item_t *) this; return 1;}/* * if (...) {...} * if (...) {...} else {...} * if (...) {...} else if ... */static int parse_if(policy_lex_file_t *lexer, policy_item_t **tail){ int rcode; policy_lex_t token; char mystring[256]; policy_if_t *this; debug_tokens("[IF] "); this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_IF; this->item.lineno = lexer->lineno; rcode = parse_condition(lexer, &(this->condition)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } rcode = parse_block(lexer, &(this->if_true)); if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, mystring, sizeof(mystring)); if ((token == POLICY_LEX_BARE_WORD) && (fr_str2int(policy_reserved_words, mystring, POLICY_RESERVED_UNKNOWN) == POLICY_RESERVED_ELSE)) { debug_tokens("[ELSE] "); token = policy_lex_file(lexer, 0, mystring, sizeof(mystring)); token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, mystring, sizeof(mystring)); if ((token == POLICY_LEX_BARE_WORD) && (fr_str2int(policy_reserved_words, mystring, POLICY_RESERVED_UNKNOWN) == POLICY_RESERVED_IF)) { token = policy_lex_file(lexer, 0, mystring, sizeof(mystring)); rcode = parse_if(lexer, &(this->if_false)); } else { rcode = parse_block(lexer, &(this->if_false)); } if (!rcode) { rlm_policy_free_item((policy_item_t *) this); return rcode; } } debug_tokens("\n"); /* * Empty "if" condition, don't even bother remembering * it. */ if (!this->if_true && !this->if_false) { debug_tokens("Discarding empty \"if\" statement at line %d\n", this->item.lineno); rlm_policy_free_item((policy_item_t *) this); return 1; } *tail = (policy_item_t *) this; return 1;}/* * Parse a reference to a named policy "foo()" */static int parse_call(policy_lex_file_t *lexer, policy_item_t **tail, const char *name){ policy_lex_t token; policy_call_t *this; debug_tokens("[CALL] "); token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_L_BRACKET) { fprintf(stderr, "%s[%d]: Expected left bracket, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); return 0; } token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_R_BRACKET) { fprintf(stderr, "%s[%d]: Expected right bracket, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); return 0; } this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_CALL; this->item.lineno = lexer->lineno; this->name = strdup(name); *tail = (policy_item_t *) this; return 1;}/* * Edit/update/replace an attribute list */static int parse_attribute_block(policy_lex_file_t *lexer, policy_item_t **tail, policy_reserved_word_t where){ policy_lex_t token; policy_attributes_t *this; char buffer[32]; this = rad_malloc(sizeof(*this)); if (!this) { return 0; } memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_ATTRIBUTE_LIST; token = policy_lex_file(lexer, 0, buffer, sizeof(buffer)); switch (token) { case POLICY_LEX_BEFORE_WHERE_EQUALS: case POLICY_LEX_AFTER_WHERE_EQUALS: case POLICY_LEX_BEFORE_WHERE_ASSIGN: case POLICY_LEX_AFTER_WHERE_ASSIGN: if (!parse_condition(lexer, &(this->where_loc))) { rlm_policy_free_item((policy_item_t *)this); return 0; } break; case POLICY_LEX_BEFORE_HEAD_EQUALS: case POLICY_LEX_AFTER_TAIL_EQUALS: case POLICY_LEX_BEFORE_HEAD_ASSIGN: case POLICY_LEX_AFTER_TAIL_ASSIGN: case POLICY_LEX_ASSIGN: case POLICY_LEX_SET_EQUALS: case POLICY_LEX_CONCAT_EQUALS: break; default: fprintf(stderr, "%s[%d]: Unexpected token %s\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); return 0; /* unknown */ } this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_ATTRIBUTE_LIST; this->item.lineno = lexer->lineno; this->where = where; this->how = token; if (!parse_block(lexer, &(this->attributes))) { rlm_policy_free_item((policy_item_t *) this); return 0; } *tail = (policy_item_t *) this; return 1;}/* * Parse a return statement. */static int parse_return(policy_lex_file_t *lexer, policy_item_t **tail){ int rcode; policy_lex_t token; policy_return_t *this; rcode = policy_lex_str2int(lexer, policy_return_codes, RLM_MODULE_NUMCODES); if (rcode == RLM_MODULE_NUMCODES) { fprintf(stderr, "%s[%d]: Invalid return code\n", lexer->filename, lexer->lineno); return 0; } /* * Look for more sutff */ token = policy_lex_file(lexer, POLICY_LEX_FLAG_PEEK, NULL, sizeof(0)); if (token != POLICY_LEX_RC_BRACKET) { fprintf(stderr, "%s[%d]: return statement must be the last statement in a policy.\n", lexer->filename, lexer->lineno); return 0; } this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_RETURN; this->item.lineno = lexer->lineno; this->rcode = rcode; *tail = (policy_item_t *) this; return 1;}const FR_NAME_NUMBER policy_component_names[] = { { "authenticate", RLM_COMPONENT_AUTH }, { "authorize", RLM_COMPONENT_AUTZ }, { "preacct", RLM_COMPONENT_PREACCT }, { "accounting", RLM_COMPONENT_ACCT }, { "session", RLM_COMPONENT_SESS }, { "pre-proxy", RLM_COMPONENT_PRE_PROXY }, { "post-proxy", RLM_COMPONENT_POST_PROXY }, { "post-auth", RLM_COMPONENT_POST_AUTH }, { NULL, RLM_COMPONENT_COUNT }};/* * Parse a module statement. */static int parse_module(policy_lex_file_t *lexer, policy_item_t **tail){ int component; policy_lex_t token; policy_module_t *this; char *p; const char *section_name; char filename[1024]; char buffer[2048]; CONF_SECTION *cs, *subcs; modcallable *mc; /* * And the filename */ token = policy_lex_file(lexer, 0, filename, sizeof(filename)); if (token != POLICY_LEX_DOUBLE_QUOTED_STRING) { fprintf(stderr, "%s[%d]: Expected filename, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); return 0; } /* * See if we're including all of the files in a subdirectory. */ strlcpy(buffer, lexer->filename, sizeof(buffer)); p = strrchr(buffer, '/'); if (p) { strlcpy(p + 1, filename, sizeof(buffer) - 1 - (p - buffer)); } else { snprintf(buffer, sizeof(buffer), "%s/%s", radius_dir, filename); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -