summaryrefslogtreecommitdiffstats
path: root/grammar/rainerscript.h
blob: 329f8bd20d0c3fe114e4ff8ff6339edbda35f6eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
/* rsyslog rainerscript definitions
 *
 * Copyright 2011-2018 Rainer Gerhards
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *       -or-
 *       see COPYING.ASL20 in the source distribution
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef INC_UTILS_H
#define INC_UTILS_H
#include <stdio.h>
#include <libestr.h>
#include <typedefs.h>
#include <sys/types.h>
#include <json.h>
#include <regex.h>
#include "typedefs.h"

#define LOG_NFACILITIES 24+1 /* we copy&paste this as including rsyslog.h gets us in off64_t trouble... :-( */
#define CNFFUNC_MAX_ARGS 32
	/**< maximum number of arguments that any function can have (among
	 *   others, this is used to size data structures).
	 */

enum cnfobjType {
	CNFOBJ_ACTION,
	CNFOBJ_RULESET,
	CNFOBJ_GLOBAL,
	CNFOBJ_INPUT,
	CNFOBJ_MODULE,
	CNFOBJ_TPL,
	CNFOBJ_PROPERTY,
	CNFOBJ_CONSTANT,
	CNFOBJ_MAINQ,
	CNFOBJ_LOOKUP_TABLE,
	CNFOBJ_PARSER,
	CNFOBJ_TIMEZONE,
	CNFOBJ_DYN_STATS,
	CNFOBJ_PERCTILE_STATS,
	CNFOBJ_INVALID = 0
};

const char* cnfobjType2str(enum cnfobjType ot);

/* a variant type, for example used for expression evaluation
 * 2011-07-15/rger: note that there exists a "legacy" object var,
 * which implements the same idea, but in a suboptimal manner. I have
 * stipped this down as much as possible, but will keep it for a while
 * to avoid unnecessary complexity during development. TODO: in the long
 * term, var shall be replaced by struct svar.
 */
struct svar{
	union {
		es_str_t *estr;
		struct cnfarray *ar;
		long long n;
		struct json_object *json;
	} d;
	char datatype; /* 'N' number, 'S' string, 'J' JSON, 'A' array
			* Note: 'A' is only supported during config phase
			*/
};

struct cnfobj {
	enum cnfobjType objType;
	struct nvlst *nvlst;
	struct objlst *subobjs;
	struct cnfstmt *script;
};

struct objlst {
	struct objlst *next;
	struct cnfobj *obj;
};

struct nvlst {
	struct nvlst *next;
	es_str_t *name;
	struct svar val;
	unsigned char bUsed;
	/**< was this node used during config processing? If not, this
	 *   indicates an error. After all, the user specified a setting
	 *   that the software does not know.
	 */
};

/* the following structures support expressions, and may (very much later
 * be the sole foundation for the AST.
 *
 * nodetypes (list not yet complete)
 * A - (string) array
 * F - function
 * N - number
 * P - fparamlst
 * R - rule
 * S - string
 * V - var
 * ... plus the S_* #define's below:
 */
#define S_STOP 4000
#define S_PRIFILT 4001
#define S_PROPFILT 4002
#define S_IF 4003
#define S_ACT 4004
#define S_NOP 4005	/* usually used to disable some statement */
#define S_SET 4006
#define S_UNSET 4007
#define S_CALL 4008
#define S_FOREACH 4009
#define S_RELOAD_LOOKUP_TABLE 4010
#define S_CALL_INDIRECT 4011
#define S_FUNC_EXISTS 4012 /* special case function which must get varname only */

enum cnfFiltType { CNFFILT_NONE, CNFFILT_PRI, CNFFILT_PROP, CNFFILT_SCRIPT };
const char* cnfFiltType2str(const enum cnfFiltType filttype);


struct cnfstmt {
	unsigned nodetype;
	struct cnfstmt *next;
	uchar *printable; /* printable text for debugging */
	union {
		struct {
			struct cnfexpr *expr;
			struct cnfstmt *t_then;
			struct cnfstmt *t_else;
		} s_if;
		struct {
			uchar *varname;
			struct cnfexpr *expr;
			int force_reset;
		} s_set;
		struct {
			uchar *varname;
		} s_unset;
		struct {
			es_str_t *name;
			struct cnfstmt *stmt;
			ruleset_t *ruleset;	/* non-NULL if the ruleset has a queue assigned */
		} s_call;
		struct {
			struct cnfexpr *expr;
		} s_call_ind;
		struct {
			uchar pmask[LOG_NFACILITIES+1];	/* priority mask */
			struct cnfstmt *t_then;
			struct cnfstmt *t_else;
		} s_prifilt;
		struct {
			fiop_t operation;
			regex_t *regex_cache;/* cache for compiled REs, if used */
			struct cstr_s *pCSCompValue;/* value to "compare" against */
			sbool isNegated;
			msgPropDescr_t prop; /* requested property */
			struct cnfstmt *t_then;
			struct cnfstmt *t_else;
		} s_propfilt;
		struct action_s *act;
	struct {
			struct cnfitr *iter;
			struct cnfstmt *body;
		} s_foreach;
	struct {
			lookup_ref_t *table;
			uchar *table_name;
			uchar *stub_value;
		} s_reload_lookup_table;
	} d;
};

struct cnfexpr {
	unsigned nodetype;
	struct cnfexpr *l;
	struct cnfexpr *r;
} __attribute__((aligned (8)));

struct cnfitr {
	char* var;
	struct cnfexpr* collection;
} __attribute__((aligned (8)));

struct cnfnumval {
	unsigned nodetype;
	long long val;
} __attribute__((aligned (8)));

struct cnfstringval {
	unsigned nodetype;
	es_str_t *estr;
} __attribute__((aligned (8)));

struct cnfvar {
	unsigned nodetype;
	char *name;
	msgPropDescr_t prop;
} __attribute__((aligned (8)));

struct cnfarray {
	unsigned nodetype;
	int nmemb;
	es_str_t **arr;
} __attribute__((aligned (8)));

struct cnffparamlst {
	unsigned nodetype; /* P */
	struct cnffparamlst *next;
	struct cnfexpr *expr;
} __attribute__((aligned (8)));

enum cnffuncid {
	CNFFUNC_INVALID = 0, /**< defunct entry, do not use (should normally not be present) */
	CNFFUNC_NAME = 1,   /**< use name to call function (for future use) */
	CNFFUNC_STRLEN,
	CNFFUNC_SUBSTRING,
	CNFFUNC_GETENV,
	CNFFUNC_TOLOWER,
	CNFFUNC_CSTR,
	CNFFUNC_CNUM,
	CNFFUNC_RE_MATCH,
	CNFFUNC_RE_EXTRACT,
	CNFFUNC_FIELD,
	CNFFUNC_PRIFILT,
	CNFFUNC_LOOKUP,
	CNFFUNC_EXEC_TEMPLATE,
	CNFFUNC_REPLACE,
	CNFFUNC_WRAP,
	CNFFUNC_RANDOM,
	CNFFUNC_DYN_INC,
	CNFFUNC_IPV42NUM,
	CNFFUNC_NUM2IPV4,
	CNFFUNC_INT2HEX,
	CNFFUNC_LTRIM,
	CNFFUNC_RTRIM,
	CNFFUNC_FORMAT_TIME,
	CNFFUNC_PARSE_TIME,
	CNFFUNC_PARSE_JSON,
	CNFFUNC_GET_PROPERTY,
	CNFFUNC_PREVIOUS_ACTION_SUSPENDED,
	CNFFUNC_SCRIPT_ERROR,
	CNFFUNC_HTTP_REQUEST,
	CNFFUNC_IS_TIME
};

typedef struct cnffunc cnffunc_t;
typedef void (*rscriptFuncPtr) (cnffunc_t *, struct svar *, void *, wti_t *);

struct cnffunc {
	unsigned nodetype;
	es_str_t *fname;
	unsigned short nParams;
	rscriptFuncPtr fPtr;
	void *funcdata;	/* global data for function-specific use (e.g. compiled regex) */
	uint8_t destructable_funcdata;
	struct cnfexpr *expr[];
} __attribute__((aligned (8)));


struct cnffuncexists {
	unsigned nodetype;
	const char *varname;
	msgPropDescr_t prop;
} __attribute__((aligned (8)));

struct scriptFunct {
	const char *fname;
	unsigned short minParams;
	unsigned short maxParams;
	rscriptFuncPtr fPtr;
	rsRetVal (*initFunc) (struct cnffunc *);
	void (*destruct) (struct cnffunc *);
	/* currently no optimizer entrypoint, may be added later.
	 * Since the optimizer needs metadata about functions, it does
	 * not seem practical to add such a function at the current state
	 */
};


/* future extensions
<code>
struct x {
	int nodetype;
};
</code>
*/


/* the following defines describe the parameter block for puling
 * config parameters. Note that the focus is on ease and saveness of
 * use, not performance. For example, we address parameters by name
 * instead of index, because the former is less error-prone. The (severe)
 * performance hit does not matter, as it is a one-time hit during config
 * load but never during actual processing. So there is really no reason
 * to care.
 */
struct cnfparamdescr { /* first the param description */
	const char *name;/**< not a es_str_t to ease definition in code */
	ecslCmdHdrlType type;
	unsigned flags;
};
/* flags for cnfparamdescr: */
#define CNFPARAM_REQUIRED	0x0001
#define CNFPARAM_DEPRECATED	0x0002

struct cnfparamblk { /* now the actual param block use in API calls */
	unsigned short version;
	unsigned short nParams;
	struct cnfparamdescr *descr;
};
#define CNFPARAMBLK_VERSION 1
	/**< caller must have same version as engine -- else things may
	 * be messed up. But note that we may support multiple versions
	 * inside the engine, if at some later stage we want to do
	 * that. -- rgerhards, 2011-07-15
	 */
struct cnfparamvals { /* the values we obtained for param descr. */
	struct svar val;
	unsigned char bUsed;
};

struct funcData_prifilt {
	uchar pmask[LOG_NFACILITIES+1];	/* priority mask */
};

/* script errno-like interface error codes: */
#define RS_SCRIPT_EOK		0
#define RS_SCRIPT_EINVAL	1

void varFreeMembers(const struct svar *r);
rsRetVal addMod2List(const int version, struct scriptFunct *functArray);
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* nvlstNewArray(struct cnfarray *ar);
struct nvlst* nvlstNewStr(es_str_t *value);
struct nvlst* nvlstNewStrBackticks(es_str_t *const 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);
struct nvlst* nvlstFindName(struct nvlst *lst, es_str_t *name);
int nvlstChkDisabled(struct nvlst *lst);
struct cnfobj* cnfobjNew(enum cnfobjType objType, struct nvlst *lst);
void cnfobjDestruct(struct cnfobj *o);
void cnfobjPrint(struct cnfobj *o);
struct cnfexpr* cnfexprNew(unsigned nodetype, struct cnfexpr *l, struct cnfexpr *r);
void cnfexprPrint(struct cnfexpr *expr, int indent);
void cnfexprEval(const struct cnfexpr *const expr, struct svar *ret, void *pusr, wti_t *pWti);
int cnfexprEvalBool(struct cnfexpr *expr, void *usrptr, wti_t *pWti);
struct json_object* cnfexprEvalCollection(struct cnfexpr * const expr, void * const usrptr, wti_t *pWti);
void cnfexprDestruct(struct cnfexpr *expr);
struct cnfnumval* cnfnumvalNew(long long val);
struct cnfstringval* cnfstringvalNew(es_str_t *estr);
struct cnfvar* cnfvarNew(char *name);
struct cnffunc * cnffuncNew(es_str_t *fname, struct cnffparamlst* paramlst);
struct cnffuncexists * cnffuncexistsNew(const char *varname);
struct cnffparamlst * cnffparamlstNew(struct cnfexpr *expr, struct cnffparamlst *next);
int cnfDoInclude(const char *name, const int optional);
int cnfparamGetIdx(struct cnfparamblk *params, const char *name);
struct cnfparamvals* nvlstGetParams(struct nvlst *lst, struct cnfparamblk *params,
	       struct cnfparamvals *vals);
void cnfparamsPrint(const struct cnfparamblk *params, const struct cnfparamvals *vals);
int cnfparamvalsIsSet(struct cnfparamblk *params, struct cnfparamvals *vals);
void varDelete(const struct svar *v);
void cnfparamvalsDestruct(const struct cnfparamvals *paramvals, const struct cnfparamblk *blk);
struct cnfstmt * cnfstmtNew(unsigned s_type);
struct cnfitr * cnfNewIterator(char *var, struct cnfexpr *collection);
void cnfstmtPrintOnly(struct cnfstmt *stmt, int indent, sbool subtree);
void cnfstmtPrint(struct cnfstmt *stmt, int indent);
struct cnfstmt* scriptAddStmt(struct cnfstmt *root, struct cnfstmt *s);
struct objlst* objlstAdd(struct objlst *root, struct cnfobj *o);
char *rmLeadingSpace(char *s);
struct cnfstmt * cnfstmtNewPRIFILT(char *prifilt, struct cnfstmt *t_then);
struct cnfstmt * cnfstmtNewPROPFILT(char *propfilt, struct cnfstmt *t_then);
struct cnfstmt * cnfstmtNewAct(struct nvlst *lst);
struct cnfstmt * cnfstmtNewLegaAct(char *actline);
struct cnfstmt * cnfstmtNewSet(char *var, struct cnfexpr *expr, int force_reset);
struct cnfstmt * cnfstmtNewUnset(char *var);
struct cnfstmt * cnfstmtNewCall(es_str_t *name);
struct cnfstmt * cnfstmtNewContinue(void);
struct cnfstmt * cnfstmtNewReloadLookupTable(struct cnffparamlst *fparams);
void cnfstmtDestructLst(struct cnfstmt *root);
struct cnfstmt *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);
void cnfarrayContentDestruct(struct cnfarray *ar);
const char* getFIOPName(unsigned iFIOP);
rsRetVal initRainerscript(void);
void unescapeStr(uchar *s, int len);
const char * tokenval2str(int tok);
uchar* var2CString(struct svar *__restrict__ const r, int *__restrict__ const bMustFree);
long long var2Number(struct svar *r, int *bSuccess);
void includeProcessCnf(struct nvlst *const lst);

/* debug helper */
void cstrPrint(const char *text, es_str_t *estr);

#endif