diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2012-10-01 17:48:36 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2012-10-01 17:48:36 +0200 |
commit | 873e806df047de8ac59a90d850698d7b7c80e58f (patch) | |
tree | cccc23109028290c77d7752ddfb11df7f1ce4539 /grammar | |
parent | 819c8167414a5056fb6a87b4b38ce656c78d5897 (diff) | |
download | rsyslog-873e806df047de8ac59a90d850698d7b7c80e58f.tar.gz rsyslog-873e806df047de8ac59a90d850698d7b7c80e58f.tar.xz rsyslog-873e806df047de8ac59a90d850698d7b7c80e58f.zip |
implement RainerScript "call" statement
Diffstat (limited to 'grammar')
-rw-r--r-- | grammar/grammar.y | 2 | ||||
-rw-r--r-- | grammar/lexer.l | 8 | ||||
-rw-r--r-- | grammar/rainerscript.c | 49 | ||||
-rw-r--r-- | grammar/rainerscript.h | 9 |
4 files changed, 64 insertions, 4 deletions
diff --git a/grammar/grammar.y b/grammar/grammar.y index 10d832c3..61878554 100644 --- a/grammar/grammar.y +++ b/grammar/grammar.y @@ -68,6 +68,7 @@ extern int yyerror(char*); %token STOP %token SET %token UNSET +%token <cnfstmt> CALL %token <s> LEGACY_ACTION %token <s> LEGACY_RULESET %token <s> PRIFILT @@ -159,6 +160,7 @@ stmt: actlst { $$ = $1; } | UNSET VAR ';' { $$ = cnfstmtNewUnset($2); } | PRIFILT block { $$ = cnfstmtNewPRIFILT($1, $2); } | PROPFILT block { $$ = cnfstmtNewPROPFILT($1, $2); } + | CALL NAME { $$ = cnfstmtNewCall($2); } block: stmt { $$ = $1; } | '{' script '}' { $$ = $2; } actlst: s_act { $$ = $1; } diff --git a/grammar/lexer.l b/grammar/lexer.l index bc56d4e5..f45dbc2a 100644 --- a/grammar/lexer.l +++ b/grammar/lexer.l @@ -45,6 +45,8 @@ /* INCL is in $IncludeConfig processing (skip to include file) */ %x LINENO /* LINENO: support for setting the linenumber */ +%x INCALL + /* INCALL: support for the call statement */ %x EXPR /* EXPR is a bit ugly, but we need it to support pre v6-syntax. The problem * is that cfsysline statement start with $..., the same like variables in @@ -141,11 +143,17 @@ int fileno(FILE *stream); <EXPR>[a-z][a-z0-9_]* { yylval.estr = es_newStrFromCStr(yytext, yyleng); return FUNC; } <EXPR>. { dbgprintf("invalid char in expr: %s\n", yytext); } +<INCALL>[ \t\n] +<INCALL>. { dbgprintf("invalid char in CALL stmt: %s\n", yytext); } +<INCALL>[a-zA-Z][a-zA-Z0-9_\.]* { yylval.estr = es_newStrFromCStr(yytext, yyleng); + BEGIN INITIAL; + return NAME; } "&" { return '&'; } "{" { return '{'; } "}" { return '}'; } "stop" { return STOP; } "else" { return ELSE; } +"call" { BEGIN INCALL; return CALL; } "set" { BEGIN EXPR; return SET; } "unset" { BEGIN EXPR; return UNSET; } /* line number support because the "preprocessor" combines lines and so needs diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c index 17b482ab..2e5381f4 100644 --- a/grammar/rainerscript.c +++ b/grammar/rainerscript.c @@ -45,6 +45,7 @@ #include "regexp.h" #include "obj.h" #include "modules.h" +#include "ruleset.h" DEFobjCurrIf(obj) DEFobjCurrIf(regexp) @@ -1887,6 +1888,7 @@ void cnfstmtPrint(struct cnfstmt *root, int indent) { struct cnfstmt *stmt; + char *cstr; //dbgprintf("stmt %p, indent %d, type '%c'\n", expr, indent, expr->nodetype); for(stmt = root ; stmt != NULL ; stmt = stmt->next) { switch(stmt->nodetype) { @@ -1896,6 +1898,11 @@ cnfstmtPrint(struct cnfstmt *root, int indent) case S_STOP: doIndent(indent); dbgprintf("STOP\n"); break; + case S_CALL: + cstr = es_str2cstr(stmt->d.s_call.name, NULL); + doIndent(indent); dbgprintf("CALL [%s]\n", cstr); + free(cstr); + break; case S_ACT: doIndent(indent); dbgprintf("ACTION %p [%s]\n", stmt->d.act, stmt->printable); break; @@ -1935,7 +1942,6 @@ cnfstmtPrint(struct cnfstmt *root, int indent) doIndent(indent); dbgprintf("\tProperty.: '%s'\n", propIDToName(stmt->d.s_propfilt.propID)); if(stmt->d.s_propfilt.propName != NULL) { - char *cstr; cstr = es_str2cstr(stmt->d.s_propfilt.propName, NULL); doIndent(indent); dbgprintf("\tCEE-Prop.: '%s'\n", cstr); @@ -2061,6 +2067,9 @@ cnfstmtDestruct(struct cnfstmt *root) case S_NOP: case S_STOP: break; + case S_CALL: + es_deleteStr(stmt->d.s_call.name); + break; case S_ACT: actionDestruct(stmt->d.act); break; @@ -2117,6 +2126,16 @@ cnfstmtNewSet(char *var, struct cnfexpr *expr) } struct cnfstmt * +cnfstmtNewCall(es_str_t *name) +{ + struct cnfstmt* cnfstmt; + if((cnfstmt = cnfstmtNew(S_CALL)) != NULL) { + cnfstmt->d.s_call.name = name; + } + return cnfstmt; +} + +struct cnfstmt * cnfstmtNewUnset(char *var) { struct cnfstmt* cnfstmt; @@ -2461,6 +2480,31 @@ cnfstmtOptimizePRIFilt(struct cnfstmt *stmt) done: return; } +/* we abuse "optimize" a bit. Actually, we obtain a ruleset pointer, as + * all rulesets are only known later in the process (now!). + */ +static void +cnfstmtOptimizeCall(struct cnfstmt *stmt) +{ + ruleset_t *pRuleset; + rsRetVal localRet; + uchar *rsName; + + rsName = (uchar*) es_str2cstr(stmt->d.s_call.name, NULL); + localRet = rulesetGetRuleset(loadConf, &pRuleset, rsName); + if(localRet != RS_RET_OK) { + /* in that case, we accept that a NOP will "survive" */ + parser_errmsg("ruleset '%s' cannot be found\n", rsName); + es_deleteStr(stmt->d.s_call.name); + stmt->nodetype = S_NOP; + goto done; + } + DBGPRINTF("CALL obtained ruleset ptr %p for ruleset %s\n", pRuleset, rsName); + stmt->d.s_call.stmt = pRuleset->root; +done: + free(rsName); + return; +} /* (recursively) optimize a statement */ void cnfstmtOptimize(struct cnfstmt *root) @@ -2486,6 +2530,9 @@ dbgprintf("RRRR: stmtOptimize: stmt %p, nodetype %u\n", stmt, stmt->nodetype); case S_ACT: cnfstmtOptimizeAct(stmt); break; + case S_CALL: + cnfstmtOptimizeCall(stmt); + break; case S_STOP: if(stmt->next != NULL) parser_errmsg("STOP is followed by unreachable statements!\n"); diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h index 7d4961ab..8ff0d702 100644 --- a/grammar/rainerscript.h +++ b/grammar/rainerscript.h @@ -5,9 +5,6 @@ #include <typedefs.h> #include <sys/types.h> #include <regex.h> -//#include "stringbuf.h" - -/* TODO: make this hack cleaner... we have circular definitions, so we need: */ #define LOG_NFACILITIES 24 /* current number of syslog facilities */ @@ -127,6 +124,7 @@ struct nvlst { #define S_NOP 4005 /* usually used to disable some statement */ #define S_SET 4006 #define S_UNSET 4007 +#define S_CALL 4008 enum cnfFiltType { CNFFILT_NONE, CNFFILT_PRI, CNFFILT_PROP, CNFFILT_SCRIPT }; static inline char* @@ -164,6 +162,10 @@ struct cnfstmt { uchar *varname; } s_unset; struct { + es_str_t *name; + struct cnfstmt *stmt; + } s_call; + struct { uchar pmask[LOG_NFACILITIES+1]; /* priority mask */ struct cnfstmt *t_then; struct cnfstmt *t_else; @@ -324,6 +326,7 @@ struct cnfstmt * cnfstmtNewAct(struct nvlst *lst); struct cnfstmt * cnfstmtNewLegaAct(char *actline); struct cnfstmt * cnfstmtNewSet(char *var, struct cnfexpr *expr); struct cnfstmt * cnfstmtNewUnset(char *var); +struct cnfstmt * cnfstmtNewCall(es_str_t *name); void cnfstmtDestruct(struct cnfstmt *root); void cnfstmtOptimize(struct cnfstmt *root); struct cnfarray* cnfarrayNew(es_str_t *val); |