summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-10-01 17:48:36 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-10-01 17:48:36 +0200
commit873e806df047de8ac59a90d850698d7b7c80e58f (patch)
treecccc23109028290c77d7752ddfb11df7f1ce4539 /grammar
parent819c8167414a5056fb6a87b4b38ce656c78d5897 (diff)
downloadrsyslog-873e806df047de8ac59a90d850698d7b7c80e58f.tar.gz
rsyslog-873e806df047de8ac59a90d850698d7b7c80e58f.tar.xz
rsyslog-873e806df047de8ac59a90d850698d7b7c80e58f.zip
implement RainerScript "call" statement
Diffstat (limited to 'grammar')
-rw-r--r--grammar/grammar.y2
-rw-r--r--grammar/lexer.l8
-rw-r--r--grammar/rainerscript.c49
-rw-r--r--grammar/rainerscript.h9
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);