summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--grammar/grammar.y9
-rw-r--r--grammar/rainerscript.c147
-rw-r--r--grammar/rainerscript.h11
-rw-r--r--plugins/imudp/imudp.c53
-rw-r--r--runtime/typedefs.h1
5 files changed, 170 insertions, 51 deletions
diff --git a/grammar/grammar.y b/grammar/grammar.y
index 89fd2289..10d832c3 100644
--- a/grammar/grammar.y
+++ b/grammar/grammar.y
@@ -94,8 +94,7 @@ extern int yyerror(char*);
%token CMP_STARTSWITH
%token CMP_STARTSWITHI
-%type <estr> value
-%type <nvlst> nv nvlst
+%type <nvlst> nv nvlst value
%type <obj> obj property constant
%type <objlst> propconst
%type <expr> expr
@@ -141,9 +140,9 @@ property: BEGIN_PROPERTY nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_PROPERTY, $2); }
constant: BEGIN_CONSTANT nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_CONSTANT, $2); }
nvlst: { $$ = NULL; }
| nvlst nv { $2->next = $1; $$ = $2; }
-nv: NAME '=' value { $$ = nvlstNew($1, $3); }
-value: STRING { $$ = $1; }
- | array { dbgprintf("DDDD: value array\n"); }
+nv: NAME '=' value { $$ = nvlstSetName($3, $1); }
+value: STRING { $$ = nvlstNewStr($1); }
+ | array { $$ = nvlstNewArray($1); }
script: stmt { $$ = $1; }
| script stmt { $$ = scriptAddStmt($1, $2); }
stmt: actlst { $$ = $1; }
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index d77721b8..6f9310db 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -51,6 +51,9 @@ DEFobjCurrIf(regexp)
void cnfexprOptimize(struct cnfexpr *expr);
static void cnfstmtOptimizePRIFilt(struct cnfstmt *stmt);
+static void cnfarrayPrint(struct cnfarray *ar, int indent);
+static void cnfarrayContentDestruct(struct cnfarray *ar);
+static struct cnfarray* cnfarrayDup(struct cnfarray *old);
char*
getFIOPName(unsigned iFIOP)
@@ -206,13 +209,12 @@ objlstPrint(struct objlst *lst)
}
struct nvlst*
-nvlstNew(es_str_t *name, es_str_t *value)
+nvlstNewStr(es_str_t *value)
{
struct nvlst *lst;
if((lst = malloc(sizeof(struct nvlst))) != NULL) {
lst->next = NULL;
- lst->name = name;
lst->val.datatype = 'S';
lst->val.d.estr = value;
lst->bUsed = 0;
@@ -221,6 +223,28 @@ nvlstNew(es_str_t *name, es_str_t *value)
return lst;
}
+struct nvlst*
+nvlstNewArray(struct cnfarray *ar)
+{
+ struct nvlst *lst;
+
+ if((lst = malloc(sizeof(struct nvlst))) != NULL) {
+ lst->next = NULL;
+ lst->val.datatype = 'A';
+ lst->val.d.ar = ar;
+ lst->bUsed = 0;
+ }
+
+ return lst;
+}
+
+struct nvlst*
+nvlstSetName(struct nvlst *lst, es_str_t *name)
+{
+ lst->name = name;
+ return lst;
+}
+
void
nvlstDestruct(struct nvlst *lst)
{
@@ -230,8 +254,7 @@ nvlstDestruct(struct nvlst *lst)
toDel = lst;
lst = lst->next;
es_deleteStr(toDel->name);
- if(toDel->val.datatype == 'S')
- es_deleteStr(toDel->val.d.estr);
+ varDelete(&toDel->val);
free(toDel);
}
}
@@ -243,11 +266,21 @@ nvlstPrint(struct nvlst *lst)
dbgprintf("nvlst %p:\n", lst);
while(lst != NULL) {
name = es_str2cstr(lst->name, NULL);
- // TODO: support for non-string types
- value = es_str2cstr(lst->val.d.estr, NULL);
- dbgprintf("\tname: '%s', value '%s'\n", name, value);
+ switch(lst->val.datatype) {
+ case 'A':
+ dbgprintf("\tname: '%s':\n", name);
+ cnfarrayPrint(lst->val.d.ar, 5);
+ break;
+ case 'S':
+ value = es_str2cstr(lst->val.d.estr, NULL);
+ dbgprintf("\tname: '%s', value '%s'\n", name, value);
+ free(value);
+ break;
+ default:dbgprintf("nvlstPrint: unknown type '%c' [%d]\n",
+ lst->val.datatype, lst->val.datatype);
+ break;
+ }
free(name);
- free(value);
lst = lst->next;
}
}
@@ -566,6 +599,7 @@ doGetWord(struct nvlst *valnode, struct cnfparamdescr *param,
es_size_t i;
int r = 1;
unsigned char *c;
+
val->val.datatype = 'S';
val->val.d.estr = es_newStr(32);
c = es_getBufAddr(valnode->val.d.estr);
@@ -574,7 +608,7 @@ doGetWord(struct nvlst *valnode, struct cnfparamdescr *param,
}
if(i != es_strlen(valnode->val.d.estr)) {
parser_errmsg("parameter '%s' contains whitespace, which is not "
- "permitted - data after first whitespace ignored",
+ "permitted",
param->name);
r = 0;
}
@@ -582,6 +616,30 @@ doGetWord(struct nvlst *valnode, struct cnfparamdescr *param,
}
static inline int
+doGetArray(struct nvlst *valnode, struct cnfparamdescr *param,
+ struct cnfparamvals *val)
+{
+ int r = 1;
+
+ switch(valnode->val.datatype) {
+ case 'S':
+ /* a constant string is assumed to be a single-element array */
+ val->val.datatype = 'A';
+ val->val.d.ar = cnfarrayNew(es_strdup(valnode->val.d.estr));
+ break;
+ case 'A':
+ val->val.datatype = 'A';
+ val->val.d.ar = cnfarrayDup(valnode->val.d.ar);
+ break;
+ default:parser_errmsg("parameter '%s' must be an array, but is a "
+ "different datatype", param->name);
+ r = 0;
+ break;
+ }
+ return r;
+}
+
+static inline int
doGetChar(struct nvlst *valnode, struct cnfparamdescr *param,
struct cnfparamvals *val)
{
@@ -607,8 +665,15 @@ nvlstGetParam(struct nvlst *valnode, struct cnfparamdescr *param,
uchar *cstr;
int r;
- dbgprintf("XXXX: in nvlstGetParam, name '%s', type %d, valnode->bUsed %d\n",
+ DBGPRINTF("nvlstGetParam: name '%s', type %d, valnode->bUsed %d\n",
param->name, (int) param->type, valnode->bUsed);
+ if(valnode->val.datatype != 'S' && param->type != eCmdHdlrArray) {
+ parser_errmsg("parameter '%s' is not a string, which is not "
+ "permitted",
+ param->name);
+ r = 0;
+ goto done;
+ }
valnode->bUsed = 1;
val->bUsed = 1;
switch(param->type) {
@@ -664,6 +729,9 @@ nvlstGetParam(struct nvlst *valnode, struct cnfparamdescr *param,
val->val.d.estr = es_strdup(valnode->val.d.estr);
r = 1;
break;
+ case eCmdHdlrArray:
+ r = doGetArray(valnode, param, val);
+ break;
case eCmdHdlrGoneAway:
parser_errmsg("parameter '%s' is no longer supported",
param->name);
@@ -674,7 +742,7 @@ nvlstGetParam(struct nvlst *valnode, struct cnfparamdescr *param,
r = 0;
break;
}
- return r;
+done: return r;
}
@@ -751,6 +819,9 @@ cnfparamsPrint(struct cnfparamblk *params, struct cnfparamvals *vals)
dbgprintf(" '%s'", cstr);
free(cstr);
break;
+ case 'A':
+ cnfarrayPrint(vals[i].val.d.ar, 0);
+ break;
case 'N':
dbgprintf("%lld", vals[i].val.d.n);
break;
@@ -1544,11 +1615,10 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
//---------------------------------------------------------
-static inline void
-cnfarrayDestruct(struct cnfarray *ar)
+static void
+cnfarrayContentDestruct(struct cnfarray *ar)
{
unsigned short i;
-
for(i = 0 ; i < ar->nmemb ; ++i) {
es_deleteStr(ar->arr[i]);
}
@@ -1620,7 +1690,7 @@ cnfexprDestruct(struct cnfexpr *expr)
cnffuncDestruct((struct cnffunc*)expr);
break;
case S_ARRAY:
- cnfarrayDestruct((struct cnfarray*)expr);
+ cnfarrayContentDestruct((struct cnfarray*)expr);
break;
default:break;
}
@@ -1665,6 +1735,17 @@ pmaskPrint(uchar *pmask, int indent)
dbgprintf("\n");
}
+static void
+cnfarrayPrint(struct cnfarray *ar, int indent)
+{
+ int i;
+ doIndent(indent); dbgprintf("ARRAY:\n");
+ for(i = 0 ; i < ar->nmemb ; ++i) {
+ doIndent(indent+1);
+ cstrPrint("string '", ar->arr[i]);
+ dbgprintf("'\n");
+ }
+}
void
cnfexprPrint(struct cnfexpr *expr, int indent)
@@ -1757,13 +1838,7 @@ cnfexprPrint(struct cnfexpr *expr, int indent)
dbgprintf("'\n");
break;
case S_ARRAY:
-dbgprintf("DDDD: %d members\n", ((struct cnfarray*)expr)->nmemb);
- doIndent(indent); dbgprintf("ARRAY:\n");
- for(i = 0 ; i < ((struct cnfarray*)expr)->nmemb ; ++i) {
- doIndent(indent+1);
- cstrPrint("string '", ((struct cnfarray*)expr)->arr[i]);
- dbgprintf("'\n");
- }
+ cnfarrayPrint((struct cnfarray*)expr, indent);
break;
case 'N':
doIndent(indent);
@@ -1924,7 +1999,6 @@ cnfarrayNew(es_str_t *val)
done: return ar;
}
-/* creates array AND adds first element to it */
struct cnfarray*
cnfarrayAdd(struct cnfarray *ar, es_str_t *val)
{
@@ -1940,6 +2014,19 @@ cnfarrayAdd(struct cnfarray *ar, es_str_t *val)
done: return ar;
}
+/* duplicate an array (deep copy) */
+static struct cnfarray*
+cnfarrayDup(struct cnfarray *old)
+{
+ int i;
+ struct cnfarray *ar;
+ ar = cnfarrayNew(es_strdup(old->arr[0]));
+ for(i = 1 ; i < old->nmemb ; ++i) {
+ cnfarrayAdd(ar, es_strdup(old->arr[i]));
+ }
+ return ar;
+}
+
struct cnfvar*
cnfvarNew(char *name)
{
@@ -2647,8 +2734,16 @@ cnfDoInclude(char *name)
void
varDelete(struct var *v)
{
- if(v->datatype == 'S')
+ switch(v->datatype) {
+ case 'S':
es_deleteStr(v->d.estr);
+ break;
+ case 'A':
+ cnfarrayContentDestruct(v->d.ar);
+ free(v->d.ar);
+ break;
+ default:break;
+ }
}
void
@@ -2656,7 +2751,9 @@ cnfparamvalsDestruct(struct cnfparamvals *paramvals, struct cnfparamblk *blk)
{
int i;
for(i = 0 ; i < blk->nParams ; ++i) {
- varDelete(&paramvals[i].val);
+ if(paramvals[i].bUsed) {
+ varDelete(&paramvals[i].val);
+ }
}
free(paramvals);
}
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
index 974f2160..314f8434 100644
--- a/grammar/rainerscript.h
+++ b/grammar/rainerscript.h
@@ -74,11 +74,13 @@ enum cnfactType { CNFACT_V2, CNFACT_LEGACY };
struct var {
union {
es_str_t *estr;
- struct cnfexpr *expr;
+ struct cnfarray *ar;
long long n;
struct json_object *json;
} d;
- char datatype; /* 'N' number, 'S' string, 'E' expression, 'J' JSON */
+ char datatype; /* 'N' number, 'S' string, 'J' JSON, 'A' array
+ * Note: 'A' is only supported during config phase
+ */
};
struct cnfobj {
@@ -284,7 +286,9 @@ void readConfFile(FILE *fp, es_str_t **str);
struct objlst* objlstNew(struct cnfobj *obj);
void objlstDestruct(struct objlst *lst);
void objlstPrint(struct objlst *lst);
-struct nvlst* nvlstNew(es_str_t *name, es_str_t *value);
+struct nvlst* nvlstNewArray(struct cnfarray *ar);
+struct nvlst* nvlstNewStr(es_str_t *value);
+struct nvlst* nvlstSetName(struct nvlst *lst, es_str_t *name);
void nvlstDestruct(struct nvlst *lst);
void nvlstPrint(struct nvlst *lst);
void nvlstChkUnused(struct nvlst *lst);
@@ -323,6 +327,7 @@ struct cnfstmt * cnfstmtNewUnset(char *var);
void cnfstmtDestruct(struct cnfstmt *root);
void cnfstmtOptimize(struct cnfstmt *root);
struct cnfarray* cnfarrayNew(es_str_t *val);
+//struct cnfarray* cnfarrayDup(struct cnfarray *old);
struct cnfarray* cnfarrayAdd(struct cnfarray *ar, es_str_t *val);
char* getFIOPName(unsigned iFIOP);
rsRetVal initRainerscript(void);
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 158d30b8..0dda30ec 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -138,7 +138,7 @@ static struct cnfparamblk modpblk =
/* input instance parameters */
static struct cnfparamdescr inppdescr[] = {
- { "port", eCmdHdlrString, CNFPARAM_REQUIRED }, /* legacy: InputTCPServerRun */
+ { "port", eCmdHdlrArray, CNFPARAM_REQUIRED }, /* legacy: InputTCPServerRun */
{ "address", eCmdHdlrString, 0 },
{ "ruleset", eCmdHdlrString, 0 }
};
@@ -664,10 +664,38 @@ rsRetVal rcvMainLoop(thrdInfo_t *pThrd)
#endif /* #if HAVE_EPOLL_CREATE1 */
+static inline rsRetVal
+createListner(es_str_t *port, struct cnfparamvals *pvals)
+{
+ instanceConf_t *inst;
+ int i;
+ DEFiRet;
+
+ CHKiRet(createInstance(&inst));
+ inst->pszBindPort = (uchar*)es_str2cstr(port, NULL);
+ for(i = 0 ; i < inppblk.nParams ; ++i) {
+ if(!pvals[i].bUsed)
+ continue;
+ if(!strcmp(inppblk.descr[i].name, "port")) {
+ continue; /* array, handled by caller */
+ } else if(!strcmp(inppblk.descr[i].name, "address")) {
+ inst->pszBindAddr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else if(!strcmp(inppblk.descr[i].name, "ruleset")) {
+ inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else {
+ dbgprintf("imudp: program error, non-handled "
+ "param '%s'\n", inppblk.descr[i].name);
+ }
+ }
+finalize_it:
+ RETiRet;
+}
+
+
BEGINnewInpInst
struct cnfparamvals *pvals;
- instanceConf_t *inst;
int i;
+ int portIdx;
CODESTARTnewInpInst
DBGPRINTF("newInpInst (imudp)\n");
@@ -677,28 +705,17 @@ CODESTARTnewInpInst
"imudp: required parameter are missing\n");
ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
}
-
if(Debug) {
dbgprintf("input param blk in imudp:\n");
cnfparamsPrint(&inppblk, pvals);
}
- CHKiRet(createInstance(&inst));
-
- for(i = 0 ; i < inppblk.nParams ; ++i) {
- if(!pvals[i].bUsed)
- continue;
- if(!strcmp(inppblk.descr[i].name, "port")) {
- inst->pszBindPort = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
- } else if(!strcmp(inppblk.descr[i].name, "address")) {
- inst->pszBindAddr = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
- } else if(!strcmp(inppblk.descr[i].name, "ruleset")) {
- inst->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
- } else {
- dbgprintf("imudp: program error, non-handled "
- "param '%s'\n", inppblk.descr[i].name);
- }
+ portIdx = cnfparamGetIdx(&inppblk, "port");
+ assert(portIdx != -1);
+ for(i = 0 ; i < pvals[portIdx].val.d.ar->nmemb ; ++i) {
+ createListner(pvals[portIdx].val.d.ar->arr[i], pvals);
}
+
finalize_it:
CODE_STD_FINALIZERnewInpInst
cnfparamvalsDestruct(pvals, &inppblk);
diff --git a/runtime/typedefs.h b/runtime/typedefs.h
index b99daed7..ccae08b2 100644
--- a/runtime/typedefs.h
+++ b/runtime/typedefs.h
@@ -164,6 +164,7 @@ typedef enum cslCmdHdlrType {
eCmdHdlrSeverity,
eCmdHdlrGetWord,
eCmdHdlrString,
+ eCmdHdlrArray,
eCmdHdlrQueueType,
eCmdHdlrGoneAway /* statment existed, but is no longer supported */
} ecslCmdHdrlType;