1 /* rsyslog rainerscript definitions 2 * 3 * Copyright 2011-2018 Rainer Gerhards 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * -or- 11 * see COPYING.ASL20 in the source distribution 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 #ifndef INC_UTILS_H 20 #define INC_UTILS_H 21 #include <stdio.h> 22 #include <libestr.h> 23 #include <typedefs.h> 24 #include <sys/types.h> 25 #include <json.h> 26 #include <regex.h> 27 #include "typedefs.h" 28 29 #define LOG_NFACILITIES 24+1 /* we copy&paste this as including rsyslog.h gets us in off64_t trouble... :-( */ 30 #define CNFFUNC_MAX_ARGS 32 31 /**< maximum number of arguments that any function can have (among 32 * others, this is used to size data structures). 33 */ 34 35 enum cnfobjType { 36 CNFOBJ_ACTION, 37 CNFOBJ_RULESET, 38 CNFOBJ_GLOBAL, 39 CNFOBJ_INPUT, 40 CNFOBJ_MODULE, 41 CNFOBJ_TPL, 42 CNFOBJ_PROPERTY, 43 CNFOBJ_CONSTANT, 44 CNFOBJ_MAINQ, 45 CNFOBJ_LOOKUP_TABLE, 46 CNFOBJ_PARSER, 47 CNFOBJ_TIMEZONE, 48 CNFOBJ_DYN_STATS, 49 CNFOBJ_PERCTILE_STATS, 50 CNFOBJ_INVALID = 0 51 }; 52 53 const char* cnfobjType2str(enum cnfobjType ot); 54 55 /* a variant type, for example used for expression evaluation 56 * 2011-07-15/rger: note that there exists a "legacy" object var, 57 * which implements the same idea, but in a suboptimal manner. I have 58 * stipped this down as much as possible, but will keep it for a while 59 * to avoid unnecessary complexity during development. TODO: in the long 60 * term, var shall be replaced by struct svar. 61 */ 62 struct svar{ 63 union { 64 es_str_t *estr; 65 struct cnfarray *ar; 66 long long n; 67 struct json_object *json; 68 } d; 69 char datatype; /* 'N' number, 'S' string, 'J' JSON, 'A' array 70 * Note: 'A' is only supported during config phase 71 */ 72 }; 73 74 struct cnfobj { 75 enum cnfobjType objType; 76 struct nvlst *nvlst; 77 struct objlst *subobjs; 78 struct cnfstmt *script; 79 }; 80 81 struct objlst { 82 struct objlst *next; 83 struct cnfobj *obj; 84 }; 85 86 struct nvlst { 87 struct nvlst *next; 88 es_str_t *name; 89 struct svar val; 90 unsigned char bUsed; 91 /**< was this node used during config processing? If not, this 92 * indicates an error. After all, the user specified a setting 93 * that the software does not know. 94 */ 95 }; 96 97 /* the following structures support expressions, and may (very much later 98 * be the sole foundation for the AST. 99 * 100 * nodetypes (list not yet complete) 101 * A - (string) array 102 * F - function 103 * N - number 104 * P - fparamlst 105 * R - rule 106 * S - string 107 * V - var 108 * ... plus the S_* #define's below: 109 */ 110 #define S_STOP 4000 111 #define S_PRIFILT 4001 112 #define S_PROPFILT 4002 113 #define S_IF 4003 114 #define S_ACT 4004 115 #define S_NOP 4005 /* usually used to disable some statement */ 116 #define S_SET 4006 117 #define S_UNSET 4007 118 #define S_CALL 4008 119 #define S_FOREACH 4009 120 #define S_RELOAD_LOOKUP_TABLE 4010 121 #define S_CALL_INDIRECT 4011 122 #define S_FUNC_EXISTS 4012 /* special case function which must get varname only */ 123 124 enum cnfFiltType { CNFFILT_NONE, CNFFILT_PRI, CNFFILT_PROP, CNFFILT_SCRIPT }; 125 const char* cnfFiltType2str(const enum cnfFiltType filttype); 126 127 128 struct cnfstmt { 129 unsigned nodetype; 130 struct cnfstmt *next; 131 uchar *printable; /* printable text for debugging */ 132 union { 133 struct { 134 struct cnfexpr *expr; 135 struct cnfstmt *t_then; 136 struct cnfstmt *t_else; 137 } s_if; 138 struct { 139 uchar *varname; 140 struct cnfexpr *expr; 141 int force_reset; 142 } s_set; 143 struct { 144 uchar *varname; 145 } s_unset; 146 struct { 147 es_str_t *name; 148 struct cnfstmt *stmt; 149 ruleset_t *ruleset; /* non-NULL if the ruleset has a queue assigned */ 150 } s_call; 151 struct { 152 struct cnfexpr *expr; 153 } s_call_ind; 154 struct { 155 uchar pmask[LOG_NFACILITIES+1]; /* priority mask */ 156 struct cnfstmt *t_then; 157 struct cnfstmt *t_else; 158 } s_prifilt; 159 struct { 160 fiop_t operation; 161 regex_t *regex_cache;/* cache for compiled REs, if used */ 162 struct cstr_s *pCSCompValue;/* value to "compare" against */ 163 sbool isNegated; 164 msgPropDescr_t prop; /* requested property */ 165 struct cnfstmt *t_then; 166 struct cnfstmt *t_else; 167 } s_propfilt; 168 struct action_s *act; 169 struct { 170 struct cnfitr *iter; 171 struct cnfstmt *body; 172 } s_foreach; 173 struct { 174 lookup_ref_t *table; 175 uchar *table_name; 176 uchar *stub_value; 177 } s_reload_lookup_table; 178 } d; 179 }; 180 181 struct cnfexpr { 182 unsigned nodetype; 183 struct cnfexpr *l; 184 struct cnfexpr *r; 185 } __attribute__((aligned (8))); 186 187 struct cnfitr { 188 char* var; 189 struct cnfexpr* collection; 190 } __attribute__((aligned (8))); 191 192 struct cnfnumval { 193 unsigned nodetype; 194 long long val; 195 } __attribute__((aligned (8))); 196 197 struct cnfstringval { 198 unsigned nodetype; 199 es_str_t *estr; 200 } __attribute__((aligned (8))); 201 202 struct cnfvar { 203 unsigned nodetype; 204 char *name; 205 msgPropDescr_t prop; 206 } __attribute__((aligned (8))); 207 208 struct cnfarray { 209 unsigned nodetype; 210 int nmemb; 211 es_str_t **arr; 212 } __attribute__((aligned (8))); 213 214 struct cnffparamlst { 215 unsigned nodetype; /* P */ 216 struct cnffparamlst *next; 217 struct cnfexpr *expr; 218 } __attribute__((aligned (8))); 219 220 enum cnffuncid { 221 CNFFUNC_INVALID = 0, /**< defunct entry, do not use (should normally not be present) */ 222 CNFFUNC_NAME = 1, /**< use name to call function (for future use) */ 223 CNFFUNC_STRLEN, 224 CNFFUNC_SUBSTRING, 225 CNFFUNC_GETENV, 226 CNFFUNC_TOLOWER, 227 CNFFUNC_CSTR, 228 CNFFUNC_CNUM, 229 CNFFUNC_RE_MATCH, 230 CNFFUNC_RE_EXTRACT, 231 CNFFUNC_FIELD, 232 CNFFUNC_PRIFILT, 233 CNFFUNC_LOOKUP, 234 CNFFUNC_EXEC_TEMPLATE, 235 CNFFUNC_REPLACE, 236 CNFFUNC_WRAP, 237 CNFFUNC_RANDOM, 238 CNFFUNC_DYN_INC, 239 CNFFUNC_IPV42NUM, 240 CNFFUNC_NUM2IPV4, 241 CNFFUNC_INT2HEX, 242 CNFFUNC_LTRIM, 243 CNFFUNC_RTRIM, 244 CNFFUNC_FORMAT_TIME, 245 CNFFUNC_PARSE_TIME, 246 CNFFUNC_PARSE_JSON, 247 CNFFUNC_GET_PROPERTY, 248 CNFFUNC_PREVIOUS_ACTION_SUSPENDED, 249 CNFFUNC_SCRIPT_ERROR, 250 CNFFUNC_HTTP_REQUEST, 251 CNFFUNC_IS_TIME 252 }; 253 254 typedef struct cnffunc cnffunc_t; 255 typedef void (*rscriptFuncPtr) (cnffunc_t *, struct svar *, void *, wti_t *); 256 257 struct cnffunc { 258 unsigned nodetype; 259 es_str_t *fname; 260 unsigned short nParams; 261 rscriptFuncPtr fPtr; 262 void *funcdata; /* global data for function-specific use (e.g. compiled regex) */ 263 uint8_t destructable_funcdata; 264 struct cnfexpr *expr[]; 265 } __attribute__((aligned (8))); 266 267 268 struct cnffuncexists { 269 unsigned nodetype; 270 const char *varname; 271 msgPropDescr_t prop; 272 } __attribute__((aligned (8))); 273 274 struct scriptFunct { 275 const char *fname; 276 unsigned short minParams; 277 unsigned short maxParams; 278 rscriptFuncPtr fPtr; 279 rsRetVal (*initFunc) (struct cnffunc *); 280 void (*destruct) (struct cnffunc *); 281 /* currently no optimizer entrypoint, may be added later. 282 * Since the optimizer needs metadata about functions, it does 283 * not seem practical to add such a function at the current state 284 */ 285 }; 286 287 288 /* future extensions 289 <code> 290 struct x { 291 int nodetype; 292 }; 293 </code> 294 */ 295 296 297 /* the following defines describe the parameter block for puling 298 * config parameters. Note that the focus is on ease and saveness of 299 * use, not performance. For example, we address parameters by name 300 * instead of index, because the former is less error-prone. The (severe) 301 * performance hit does not matter, as it is a one-time hit during config 302 * load but never during actual processing. So there is really no reason 303 * to care. 304 */ 305 struct cnfparamdescr { /* first the param description */ 306 const char *name;/**< not a es_str_t to ease definition in code */ 307 ecslCmdHdrlType type; 308 unsigned flags; 309 }; 310 /* flags for cnfparamdescr: */ 311 #define CNFPARAM_REQUIRED 0x0001 312 #define CNFPARAM_DEPRECATED 0x0002 313 314 struct cnfparamblk { /* now the actual param block use in API calls */ 315 unsigned short version; 316 unsigned short nParams; 317 struct cnfparamdescr *descr; 318 }; 319 #define CNFPARAMBLK_VERSION 1 320 /**< caller must have same version as engine -- else things may 321 * be messed up. But note that we may support multiple versions 322 * inside the engine, if at some later stage we want to do 323 * that. -- rgerhards, 2011-07-15 324 */ 325 struct cnfparamvals { /* the values we obtained for param descr. */ 326 struct svar val; 327 unsigned char bUsed; 328 }; 329 330 struct funcData_prifilt { 331 uchar pmask[LOG_NFACILITIES+1]; /* priority mask */ 332 }; 333 334 /* script errno-like interface error codes: */ 335 #define RS_SCRIPT_EOK 0 336 #define RS_SCRIPT_EINVAL 1 337 338 void varFreeMembers(const struct svar *r); 339 rsRetVal addMod2List(const int version, struct scriptFunct *functArray); 340 void readConfFile(FILE *fp, es_str_t **str); 341 struct objlst* objlstNew(struct cnfobj *obj); 342 void objlstDestruct(struct objlst *lst); 343 void objlstPrint(struct objlst *lst); 344 struct nvlst* nvlstNewArray(struct cnfarray *ar); 345 struct nvlst* nvlstNewStr(es_str_t *value); 346 struct nvlst* nvlstNewStrBackticks(es_str_t *const value); 347 struct nvlst* nvlstSetName(struct nvlst *lst, es_str_t *name); 348 void nvlstDestruct(struct nvlst *lst); 349 void nvlstPrint(struct nvlst *lst); 350 void nvlstChkUnused(struct nvlst *lst); 351 struct nvlst* nvlstFindName(struct nvlst *lst, es_str_t *name); 352 int nvlstChkDisabled(struct nvlst *lst); 353 struct cnfobj* cnfobjNew(enum cnfobjType objType, struct nvlst *lst); 354 void cnfobjDestruct(struct cnfobj *o); 355 void cnfobjPrint(struct cnfobj *o); 356 struct cnfexpr* cnfexprNew(unsigned nodetype, struct cnfexpr *l, struct cnfexpr *r); 357 void cnfexprPrint(struct cnfexpr *expr, int indent); 358 void cnfexprEval(const struct cnfexpr *const expr, struct svar *ret, void *pusr, wti_t *pWti); 359 int cnfexprEvalBool(struct cnfexpr *expr, void *usrptr, wti_t *pWti); 360 struct json_object* cnfexprEvalCollection(struct cnfexpr * const expr, void * const usrptr, wti_t *pWti); 361 void cnfexprDestruct(struct cnfexpr *expr); 362 struct cnfnumval* cnfnumvalNew(long long val); 363 struct cnfstringval* cnfstringvalNew(es_str_t *estr); 364 struct cnfvar* cnfvarNew(char *name); 365 struct cnffunc * cnffuncNew(es_str_t *fname, struct cnffparamlst* paramlst); 366 struct cnffuncexists * cnffuncexistsNew(const char *varname); 367 struct cnffparamlst * cnffparamlstNew(struct cnfexpr *expr, struct cnffparamlst *next); 368 int cnfDoInclude(const char *name, const int optional); 369 int cnfparamGetIdx(struct cnfparamblk *params, const char *name); 370 struct cnfparamvals* nvlstGetParams(struct nvlst *lst, struct cnfparamblk *params, 371 struct cnfparamvals *vals); 372 void cnfparamsPrint(const struct cnfparamblk *params, const struct cnfparamvals *vals); 373 int cnfparamvalsIsSet(struct cnfparamblk *params, struct cnfparamvals *vals); 374 void varDelete(const struct svar *v); 375 void cnfparamvalsDestruct(const struct cnfparamvals *paramvals, const struct cnfparamblk *blk); 376 struct cnfstmt * cnfstmtNew(unsigned s_type); 377 struct cnfitr * cnfNewIterator(char *var, struct cnfexpr *collection); 378 void cnfstmtPrintOnly(struct cnfstmt *stmt, int indent, sbool subtree); 379 void cnfstmtPrint(struct cnfstmt *stmt, int indent); 380 struct cnfstmt* scriptAddStmt(struct cnfstmt *root, struct cnfstmt *s); 381 struct objlst* objlstAdd(struct objlst *root, struct cnfobj *o); 382 char *rmLeadingSpace(char *s); 383 struct cnfstmt * cnfstmtNewPRIFILT(char *prifilt, struct cnfstmt *t_then); 384 struct cnfstmt * cnfstmtNewPROPFILT(char *propfilt, struct cnfstmt *t_then); 385 struct cnfstmt * cnfstmtNewAct(struct nvlst *lst); 386 struct cnfstmt * cnfstmtNewLegaAct(char *actline); 387 struct cnfstmt * cnfstmtNewSet(char *var, struct cnfexpr *expr, int force_reset); 388 struct cnfstmt * cnfstmtNewUnset(char *var); 389 struct cnfstmt * cnfstmtNewCall(es_str_t *name); 390 struct cnfstmt * cnfstmtNewContinue(void); 391 struct cnfstmt * cnfstmtNewReloadLookupTable(struct cnffparamlst *fparams); 392 void cnfstmtDestructLst(struct cnfstmt *root); 393 struct cnfstmt *cnfstmtOptimize(struct cnfstmt *root); 394 struct cnfarray* cnfarrayNew(es_str_t *val); 395 struct cnfarray* cnfarrayDup(struct cnfarray *old); 396 struct cnfarray* cnfarrayAdd(struct cnfarray *ar, es_str_t *val); 397 void cnfarrayContentDestruct(struct cnfarray *ar); 398 const char* getFIOPName(unsigned iFIOP); 399 rsRetVal initRainerscript(void); 400 void unescapeStr(uchar *s, int len); 401 const char * tokenval2str(int tok); 402 uchar* var2CString(struct svar *__restrict__ const r, int *__restrict__ const bMustFree); 403 long long var2Number(struct svar *r, int *bSuccess); 404 void includeProcessCnf(struct nvlst *const lst); 405 406 /* debug helper */ 407 void cstrPrint(const char *text, es_str_t *estr); 408 409 #endif 410