summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/conf.c58
-rw-r--r--runtime/conf.h4
-rw-r--r--runtime/glbl.c3
-rw-r--r--runtime/glbl.h1
-rw-r--r--runtime/queue.c1
-rw-r--r--runtime/rsyslog.h3
-rw-r--r--runtime/var.c40
-rw-r--r--runtime/var.h1
-rw-r--r--runtime/vmop.c37
-rw-r--r--runtime/vmop.h2
-rw-r--r--runtime/vmprg.c39
-rw-r--r--runtime/vmprg.h3
12 files changed, 177 insertions, 15 deletions
diff --git a/runtime/conf.c b/runtime/conf.c
index 71b2b2da..e55b8d18 100644
--- a/runtime/conf.c
+++ b/runtime/conf.c
@@ -83,6 +83,8 @@ DEFobjCurrIf(module)
DEFobjCurrIf(errmsg)
DEFobjCurrIf(net)
+static int iNbrActions; /* number of actions the running config has. Needs to be init on ReInitConf() */
+
/* The following global variables are used for building
* tag and host selector lines during startup and config reload.
* This is stored as a global variable pool because of its ease. It is
@@ -188,6 +190,7 @@ doIncludeLine(uchar **pp, __attribute__((unused)) void* pVal)
char pattern[MAXFNAME];
uchar *cfgFile;
glob_t cfgFiles;
+ int result;
size_t i = 0;
struct stat fileInfo;
@@ -195,14 +198,21 @@ doIncludeLine(uchar **pp, __attribute__((unused)) void* pVal)
ASSERT(*pp != NULL);
if(getSubString(pp, (char*) pattern, sizeof(pattern) / sizeof(char), ' ') != 0) {
- errmsg.LogError(0, RS_RET_NOT_FOUND, "could not extract group name");
+ errmsg.LogError(0, RS_RET_NOT_FOUND, "could not parse config file name");
ABORT_FINALIZE(RS_RET_NOT_FOUND);
}
/* Use GLOB_MARK to append a trailing slash for directories.
* Required by doIncludeDirectory().
*/
- glob(pattern, GLOB_MARK, NULL, &cfgFiles);
+ result = glob(pattern, GLOB_MARK, NULL, &cfgFiles);
+ if(result != 0) {
+ char errStr[1024];
+ rs_strerror_r(errno, errStr, sizeof(errStr));
+ errmsg.LogError(0, RS_RET_FILE_NOT_FOUND, "error accessing config file or directory '%s': %s",
+ pattern, errStr);
+ ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND);
+ }
for(i = 0; i < cfgFiles.gl_pathc; i++) {
cfgFile = (uchar*) cfgFiles.gl_pathv[i];
@@ -560,8 +570,7 @@ cflineParseFileName(uchar* p, uchar *pFileName, omodStringRequest_t *pOMSR, int
}
-/*
- * Helper to cfline(). This function takes the filter part of a traditional, PRI
+/* Helper to cfline(). This function takes the filter part of a traditional, PRI
* based line and decodes the PRIs given in the selector line. It processed the
* line up to the beginning of the action part. A pointer to that beginnig is
* passed back to the caller.
@@ -577,8 +586,9 @@ static rsRetVal cflineProcessTradPRIFilter(uchar **pline, register selector_t *f
int pri;
int singlpri = 0;
int ignorepri = 0;
- uchar buf[MAXLINE];
+ uchar buf[2048]; /* buffer for facility and priority names */
uchar xbuf[200];
+ DEFiRet;
ASSERT(pline != NULL);
ASSERT(*pline != NULL);
@@ -603,7 +613,7 @@ static rsRetVal cflineProcessTradPRIFilter(uchar **pline, register selector_t *f
continue;
/* collect priority name */
- for (bp = buf; *q && !strchr("\t ,;", *q); )
+ for (bp = buf; *q && !strchr("\t ,;", *q) && bp < buf+sizeof(buf)-1 ; )
*bp++ = *q++;
*bp = '\0';
@@ -614,6 +624,7 @@ static rsRetVal cflineProcessTradPRIFilter(uchar **pline, register selector_t *f
/* decode priority name */
if ( *buf == '!' ) {
ignorepri = 1;
+ /* copy below is ok, we can NOT go off the allocated area */
for (bp=buf; *(bp+1); bp++)
*bp=*(bp+1);
*bp='\0';
@@ -639,7 +650,7 @@ static rsRetVal cflineProcessTradPRIFilter(uchar **pline, register selector_t *f
/* scan facilities */
while (*p && !strchr("\t .;", *p)) {
- for (bp = buf; *p && !strchr("\t ,;.", *p); )
+ for (bp = buf; *p && !strchr("\t ,;.", *p) && bp < buf+sizeof(buf)-1 ; )
*bp++ = *p++;
*bp = '\0';
if (*buf == '*') {
@@ -722,7 +733,7 @@ static rsRetVal cflineProcessTradPRIFilter(uchar **pline, register selector_t *f
p++;
*pline = p;
- return RS_RET_OK;
+ RETiRet;
}
@@ -1060,6 +1071,7 @@ static rsRetVal cflineDoAction(uchar **p, action_t **ppAction)
pAction->f_ReduceRepeated = 0;
}
pAction->bEnabled = 1; /* action is enabled */
+ iNbrActions++; /* one more active action! */
}
break;
}
@@ -1159,6 +1171,34 @@ cfline(uchar *line, selector_t **pfCurr)
}
+/* Reinitialize the configuration subsystem. This is a "work-around" to the fact
+ * that we do not yet have actual config objects. This method is to be called
+ * whenever a totally new config is started (which means on startup and HUP).
+ * Note that it MUST NOT be called for an included config file.
+ * rgerhards, 2008-07-28
+ */
+static rsRetVal
+ReInitConf(void)
+{
+ DEFiRet;
+ iNbrActions = 0; /* this is what we created the function for ;) - action count is reset */
+ RETiRet;
+}
+
+
+/* return the current number of active actions
+ * rgerhards, 2008-07-28
+ */
+static rsRetVal
+GetNbrActActions(int *piNbrActions)
+{
+ DEFiRet;
+ assert(piNbrActions != NULL);
+ *piNbrActions = iNbrActions;
+ RETiRet;
+}
+
+
/* queryInterface function
* rgerhards, 2008-02-29
*/
@@ -1179,6 +1219,8 @@ CODESTARTobjQueryInterface(conf)
pIf->doIncludeLine = doIncludeLine;
pIf->cfline = cfline;
pIf->processConfFile = processConfFile;
+ pIf->ReInitConf = ReInitConf;
+ pIf->GetNbrActActions = GetNbrActActions;
finalize_it:
ENDobjQueryInterface(conf)
diff --git a/runtime/conf.h b/runtime/conf.h
index 31ca27b3..2494d4dc 100644
--- a/runtime/conf.h
+++ b/runtime/conf.h
@@ -37,8 +37,10 @@ BEGINinterface(conf) /* name must also be changed in ENDinterface macro! */
rsRetVal (*doIncludeLine)(uchar **pp, __attribute__((unused)) void* pVal);
rsRetVal (*cfline)(uchar *line, selector_t **pfCurr);
rsRetVal (*processConfFile)(uchar *pConfFile);
+ rsRetVal (*ReInitConf)(void);
+ rsRetVal (*GetNbrActActions)(int *);
ENDinterface(conf)
-#define confCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+#define confCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */
/* prototypes */
diff --git a/runtime/glbl.c b/runtime/glbl.c
index 11a664f8..1114fcd3 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -51,6 +51,7 @@ DEFobjStaticHelpers
* class...
*/
static uchar *pszWorkDir = NULL;
+static int iMaxLine = 2048; /* maximum length of a syslog message */
static int iDefPFFamily = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */
static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
static int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */
@@ -84,6 +85,7 @@ static dataType Get##nameFunc(void) \
return(nameVar); \
}
+SIMP_PROP(MaxLine, iMaxLine, int)
SIMP_PROP(DefPFFamily, iDefPFFamily, int) /* note that in the future we may check the family argument */
SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int)
SIMP_PROP(Option_DisallowWarning, option_DisallowWarning, int)
@@ -170,6 +172,7 @@ CODESTARTobjQueryInterface(glbl)
#define SIMP_PROP(name) \
pIf->Get##name = Get##name; \
pIf->Set##name = Set##name;
+ SIMP_PROP(MaxLine);
SIMP_PROP(DefPFFamily);
SIMP_PROP(DropMalPTRMsgs);
SIMP_PROP(Option_DisallowWarning);
diff --git a/runtime/glbl.h b/runtime/glbl.h
index 90436319..0c83bdd5 100644
--- a/runtime/glbl.h
+++ b/runtime/glbl.h
@@ -40,6 +40,7 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
#define SIMP_PROP(name, dataType) \
dataType (*Get##name)(void); \
rsRetVal (*Set##name)(dataType);
+ SIMP_PROP(MaxLine, int)
SIMP_PROP(DefPFFamily, int)
SIMP_PROP(DropMalPTRMsgs, int)
SIMP_PROP(Option_DisallowWarning, int)
diff --git a/runtime/queue.c b/runtime/queue.c
index 00f811a0..7e7d4152 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -2115,7 +2115,6 @@ queueEnqObj(queue_t *pThis, flowControl_t flowCtlType, void *pUsr)
if(pThis->bIsDA)
CHKiRet(queueChkStrtDA(pThis));
-
/* handle flow control
* There are two different flow control mechanisms: basic and advanced flow control.
* Basic flow control has always been implemented and protects the queue structures
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 95b2c756..f75a5663 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -123,6 +123,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_TRUE = -3, /**< to indicate a true state (can be used as TRUE, legacy) */
RS_RET_FALSE = -2, /**< to indicate a false state (can be used as FALSE, legacy) */
RS_RET_NO_IRET = -8, /**< This is a trick for the debuging system - it means no iRet is provided */
+ RS_RET_VALIDATION_RUN = -9, /**< indicates a (config) validation run, processing not carried out */
RS_RET_ERR = -3000, /**< generic failure */
RS_TRUNCAT_TOO_LARGE = -3001, /**< truncation operation where too many chars should be truncated */
RS_RET_FOUND_AT_STRING_END = -3002, /**< some value found, but at the last pos of string */
@@ -248,6 +249,8 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_RETRY = -2100, /**< call should be retried (e.g. EGAIN on recv) */
RS_RET_GSS_ERR = -2101, /**< generic error occured in GSSAPI subsystem */
RS_RET_CERTLESS = -2102, /**< state: we run without machine cert (this may be OK) */
+ RS_RET_NO_ACTIONS = -2103, /**< no active actions are configured (no output will be created) */
+ RS_RET_CONF_FILE_NOT_FOUND = -2104, /**< config file or directory not found */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/runtime/var.c b/runtime/var.c
index 7e51fc6d..559bc56c 100644
--- a/runtime/var.c
+++ b/runtime/var.c
@@ -29,6 +29,7 @@
*/
#include "config.h"
+#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -89,6 +90,44 @@ CODESTARTobjDebugPrint(var)
ENDobjDebugPrint(var)
+/* This function is similar to DebugPrint, but does not send its output to
+ * the debug log but instead to a caller-provided string. The idea here is that
+ * we can use this string to get a textual representation of a variable.
+ * Among others, this is useful for creating testbenches, our first use case for
+ * it. Here, it enables simple comparison of the resulting program to a
+ * reference program by simple string compare.
+ * Note that the caller must initialize the string object. We always add
+ * data to it. So, it can be easily combined into a chain of methods
+ * to generate the final string.
+ * rgerhards, 2008-07-07
+ */
+static rsRetVal
+Obj2Str(var_t *pThis, cstr_t *pstrPrg)
+{
+ DEFiRet;
+ size_t lenBuf;
+ uchar szBuf[2048];
+
+ ISOBJ_TYPE_assert(pThis, var);
+ assert(pstrPrg != NULL);
+ switch(pThis->varType) {
+ case VARTYPE_STR:
+ lenBuf = snprintf((char*) szBuf, sizeof(szBuf), "%s[cstr]", rsCStrGetSzStr(pThis->val.pStr));
+ break;
+ case VARTYPE_NUMBER:
+ lenBuf = snprintf((char*) szBuf, sizeof(szBuf), "%lld[nbr]", pThis->val.num);
+ break;
+ default:
+ lenBuf = snprintf((char*) szBuf, sizeof(szBuf), "**UNKNOWN**[%d]", pThis->varType);
+ break;
+ }
+ CHKiRet(rsCStrAppendStrWithLen(pstrPrg, szBuf, lenBuf));
+
+finalize_it:
+ RETiRet;
+}
+
+
/* duplicates a var instance
* rgerhards, 2008-02-25
*/
@@ -387,6 +426,7 @@ CODESTARTobjQueryInterface(var)
pIf->ConstructFinalize = varConstructFinalize;
pIf->Destruct = varDestruct;
pIf->DebugPrint = varDebugPrint;
+ pIf->Obj2Str = Obj2Str;
pIf->SetNumber = varSetNumber;
pIf->SetString = varSetString;
pIf->ConvForOperation = ConvForOperation;
diff --git a/runtime/var.h b/runtime/var.h
index bbe7ba33..6d890ec9 100644
--- a/runtime/var.h
+++ b/runtime/var.h
@@ -59,6 +59,7 @@ BEGINinterface(var) /* name must also be changed in ENDinterface macro! */
rsRetVal (*ConvToNumber)(var_t *pThis);
rsRetVal (*ConvToBool)(var_t *pThis);
rsRetVal (*ConvToString)(var_t *pThis);
+ rsRetVal (*Obj2Str)(var_t *pThis, cstr_t*);
rsRetVal (*Duplicate)(var_t *pThis, var_t **ppNew);
ENDinterface(var)
#define varCURR_IF_VERSION 1 /* increment whenever you change the interface above! */
diff --git a/runtime/vmop.c b/runtime/vmop.c
index 219315c4..fcacb15b 100644
--- a/runtime/vmop.c
+++ b/runtime/vmop.c
@@ -25,6 +25,7 @@
*/
#include "config.h"
+#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -81,6 +82,39 @@ CODESTARTobjDebugPrint(vmop)
ENDobjDebugPrint(vmop)
+/* This function is similar to DebugPrint, but does not send its output to
+ * the debug log but instead to a caller-provided string. The idea here is that
+ * we can use this string to get a textual representation of an operation.
+ * Among others, this is useful for creating testbenches, our first use case for
+ * it. Here, it enables simple comparison of the resulting program to a
+ * reference program by simple string compare.
+ * Note that the caller must initialize the string object. We always add
+ * data to it. So, it can be easily combined into a chain of methods
+ * to generate the final string.
+ * rgerhards, 2008-07-04
+ */
+static rsRetVal
+Obj2Str(vmop_t *pThis, cstr_t *pstrPrg)
+{
+ uchar *pOpcodeName;
+ uchar szBuf[2048];
+ size_t lenBuf;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, vmop);
+ assert(pstrPrg != NULL);
+ vmopOpcode2Str(pThis, &pOpcodeName);
+ lenBuf = snprintf((char*) szBuf, sizeof(szBuf), "%s\t", pOpcodeName);
+ CHKiRet(rsCStrAppendStrWithLen(pstrPrg, szBuf, lenBuf));
+ if(pThis->operand.pVar != NULL)
+ CHKiRet(var.Obj2Str(pThis->operand.pVar, pstrPrg));
+ CHKiRet(rsCStrAppendChar(pstrPrg, '\n'));
+
+finalize_it:
+ RETiRet;
+}
+
+
/* set operand (variant case)
* rgerhards, 2008-02-20
*/
@@ -206,8 +240,6 @@ CODESTARTobjQueryInterface(vmop)
* work here (if we can support an older interface version - that,
* of course, also affects the "if" above).
*/
- //xxxpIf->oID = OBJvmop;
-
pIf->Construct = vmopConstruct;
pIf->ConstructFinalize = vmopConstructFinalize;
pIf->Destruct = vmopDestruct;
@@ -215,6 +247,7 @@ CODESTARTobjQueryInterface(vmop)
pIf->SetOpcode = vmopSetOpcode;
pIf->SetVar = vmopSetVar;
pIf->Opcode2Str = vmopOpcode2Str;
+ pIf->Obj2Str = Obj2Str;
finalize_it:
ENDobjQueryInterface(vmop)
diff --git a/runtime/vmop.h b/runtime/vmop.h
index 97f924d7..c3d5d5f4 100644
--- a/runtime/vmop.h
+++ b/runtime/vmop.h
@@ -26,6 +26,7 @@
#define INCLUDED_VMOP_H
#include "ctok_token.h"
+#include "stringbuf.h"
/* machine instructions types */
typedef enum { /* do NOT start at 0 to detect uninitialized types after calloc() */
@@ -83,6 +84,7 @@ BEGINinterface(vmop) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetOpcode)(vmop_t *pThis, opcode_t opcode);
rsRetVal (*SetVar)(vmop_t *pThis, var_t *pVar);
rsRetVal (*Opcode2Str)(vmop_t *pThis, uchar **ppName);
+ rsRetVal (*Obj2Str)(vmop_t *pThis, cstr_t *pstr);
ENDinterface(vmop)
#define vmopCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
diff --git a/runtime/vmprg.c b/runtime/vmprg.c
index a2b744d7..705e6948 100644
--- a/runtime/vmprg.c
+++ b/runtime/vmprg.c
@@ -24,12 +24,14 @@
*/
#include "config.h"
+#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "rsyslog.h"
#include "obj.h"
#include "vmprg.h"
+#include "stringbuf.h"
/* static data */
DEFobjStaticHelpers
@@ -79,6 +81,40 @@ CODESTARTobjDebugPrint(vmprg)
ENDobjDebugPrint(vmprg)
+/* This function is similar to DebugPrint, but does not send its output to
+ * the debug log but instead to a caller-provided string. The idea here is that
+ * we can use this string to get a textual representation of a bytecode program.
+ * Among others, this is useful for creating testbenches, our first use case for
+ * it. Here, it enables simple comparison of the resulting program to a
+ * reference program by simple string compare.
+ * Note that the caller must initialize the string object. We always add
+ * data to it. So, it can be easily combined into a chain of methods
+ * to generate the final string.
+ * rgerhards, 2008-07-04
+ */
+static rsRetVal
+Obj2Str(vmprg_t *pThis, cstr_t *pstrPrg)
+{
+ uchar szAddr[12];
+ vmop_t *pOp;
+ int i;
+ int lenAddr;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, vmprg);
+ assert(pstrPrg != NULL);
+ i = 0; /* "program counter" */
+ for(pOp = pThis->vmopRoot ; pOp != NULL ; pOp = pOp->pNext) {
+ lenAddr = snprintf((char*)szAddr, sizeof(szAddr), "%8.8d: ", i++);
+ CHKiRet(rsCStrAppendStrWithLen(pstrPrg, szAddr, lenAddr));
+ vmop.Obj2Str(pOp, pstrPrg);
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+
/* add an operation (instruction) to the end of the current program. This
* function is expected to be called while creating the program, but never
* again after this is done and it is being executed. Results are undefined if
@@ -146,12 +182,11 @@ CODESTARTobjQueryInterface(vmprg)
* work here (if we can support an older interface version - that,
* of course, also affects the "if" above).
*/
- //xxxpIf->oID = OBJvmprg;
-
pIf->Construct = vmprgConstruct;
pIf->ConstructFinalize = vmprgConstructFinalize;
pIf->Destruct = vmprgDestruct;
pIf->DebugPrint = vmprgDebugPrint;
+ pIf->Obj2Str = Obj2Str;
pIf->AddOperation = vmprgAddOperation;
pIf->AddVarOperation = vmprgAddVarOperation;
finalize_it:
diff --git a/runtime/vmprg.h b/runtime/vmprg.h
index db1f62f0..c1042f7d 100644
--- a/runtime/vmprg.h
+++ b/runtime/vmprg.h
@@ -38,7 +38,7 @@
#define INCLUDED_VMPRG_H
#include "vmop.h"
-
+#include "stringbuf.h"
/* the vmprg object */
typedef struct vmprg_s {
@@ -56,6 +56,7 @@ BEGINinterface(vmprg) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Destruct)(vmprg_t **ppThis);
rsRetVal (*AddOperation)(vmprg_t *pThis, vmop_t *pOp);
rsRetVal (*AddVarOperation)(vmprg_t *pThis, opcode_t opcode, var_t *pVar);
+ rsRetVal (*Obj2Str)(vmprg_t *pThis, cstr_t *pstr);
ENDinterface(vmprg)
#define vmprgCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */