summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'runtime')
-rw-r--r--runtime/Makefile.am7
-rw-r--r--runtime/conf.c1
-rw-r--r--runtime/cryprov.h2
-rw-r--r--runtime/glbl.c42
-rw-r--r--runtime/libgcry.h3
-rw-r--r--runtime/librsgt.c10
-rw-r--r--runtime/librsgt.h3
-rw-r--r--runtime/librsgt_read.c4
-rw-r--r--runtime/msg.c18
-rw-r--r--runtime/msg.h3
-rw-r--r--runtime/net.c1
-rw-r--r--runtime/nsd_gtls.c19
-rw-r--r--runtime/queue.c79
-rw-r--r--runtime/rsyslog.h5
-rw-r--r--runtime/ruleset.c4
-rw-r--r--runtime/stream.c2
-rw-r--r--runtime/stream.h3
-rw-r--r--runtime/stringbuf.c9
-rw-r--r--runtime/typedefs.h4
19 files changed, 162 insertions, 57 deletions
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index dea06fe0..34384bea 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -97,12 +97,13 @@ librsyslog_la_SOURCES = \
#
if WITH_MODDIRS
-librsyslog_la_CPPFLAGS = -DSD_EXPORT_SYMBOLS -D_PATH_MODDIR=\"$(pkglibdir)/:$(moddirs)\" $(PTHREADS_CFLAGS) -I\$(top_srcdir)/tools
+librsyslog_la_CPPFLAGS = -DSD_EXPORT_SYMBOLS -D_PATH_MODDIR=\"$(pkglibdir)/:$(moddirs)\"
else
-librsyslog_la_CPPFLAGS = -DSD_EXPORT_SYMBOLS -D_PATH_MODDIR=\"$(pkglibdir)/\" -I$(top_srcdir) $(PTHREADS_CFLAGS) -I\$(top_srcdir)/tools -I\$(top_srcdir)/grammar
+librsyslog_la_CPPFLAGS = -DSD_EXPORT_SYMBOLS -D_PATH_MODDIR=\"$(pkglibdir)/\" -I\$(top_srcdir) -I\$(top_srcdir)/grammar
endif
#librsyslog_la_LDFLAGS = -module -avoid-version
-librsyslog_la_LIBADD = $(DL_LIBS) $(RT_LIBS)
+librsyslog_la_CPPFLAGS += $(PTHREADS_CFLAGS) $(LIBEE_CFLAGS) $(LIBUUID_CFLAGS) $(JSON_C_CFLAGS) -I\$(top_srcdir)/tools
+librsyslog_la_LIBADD = $(DL_LIBS) $(RT_LIBS) $(LIBEE_LIBS) $(LIBUUID_LIBS) $(JSON_C_LIBS)
#
# regular expression support
diff --git a/runtime/conf.c b/runtime/conf.c
index c3c7e447..c01715cb 100644
--- a/runtime/conf.c
+++ b/runtime/conf.c
@@ -573,6 +573,7 @@ rsRetVal DecodePropFilter(uchar *pline, struct cnfstmt *stmt)
} else {
errmsg.LogError(0, NO_ERRCODE, "error: invalid compare operation '%s' - ignoring selector",
(char*) rsCStrGetSzStrNoNULL(pCSCompOp));
+ return(RS_RET_ERR);
}
rsCStrDestruct(&pCSCompOp); /* no longer needed */
diff --git a/runtime/cryprov.h b/runtime/cryprov.h
index 8496b745..005b33f7 100644
--- a/runtime/cryprov.h
+++ b/runtime/cryprov.h
@@ -24,8 +24,6 @@
#ifndef INCLUDED_CRYPROV_H
#define INCLUDED_CRYPROV_H
-#include <gcrypt.h>
-
/* interface */
BEGINinterface(cryprov) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Construct)(void *ppThis);
diff --git a/runtime/glbl.c b/runtime/glbl.c
index b3fe3a1d..41d56c2c 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <pthread.h>
#include <assert.h>
#include "rsyslog.h"
@@ -71,6 +72,7 @@ static int option_DisallowWarning = 1; /* complain if message from disallowed se
static int bDisableDNS = 0; /* don't look up IP addresses of remote messages */
static prop_t *propLocalIPIF = NULL;/* IP address to report for the local host (default is 127.0.0.1) */
static prop_t *propLocalHostName = NULL;/* our hostname as FQDN - read-only after startup */
+static prop_t *propLocalHostNameToDelete = NULL;/* see GenerateLocalHostName function hdr comment! */
static uchar *LocalHostName = NULL;/* our hostname - read-only after startup, except HUP */
static uchar *LocalHostNameOverride = NULL;/* user-overridden hostname - read-only after startup */
static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup, except HUP */
@@ -379,17 +381,31 @@ GetLocalDomain(void)
/* generate the local hostname property. This must be done after the hostname info
* has been set as well as PreserveFQDN.
* rgerhards, 2009-06-30
+ * NOTE: This function tries to avoid locking by not destructing the previous value
+ * immediately. This is so that current readers can continue to use the previous name.
+ * Otherwise, we would need to use read/write locks to protect the update process.
+ * In order to do so, we save the previous value and delete it when we are called again
+ * the next time. Note that this in theory is racy and can lead to a double-free.
+ * In practice, however, the window of exposure to trigger this is extremely short
+ * and as this functions is very infrequently being called (on HUP), the trigger
+ * condition for this bug is so highly unlikely that it never occurs in practice.
+ * Probably if you HUP rsyslog every few milliseconds, but who does that...
+ * To further reduce risk potential, we do only update the property when there
+ * actually is a hostname change, which makes it even less likely.
+ * rgerhards, 2013-10-28
*/
static rsRetVal
GenerateLocalHostNameProperty(void)
{
- DEFiRet;
+ uchar *pszPrev;
+ int lenPrev;
+ prop_t *hostnameNew;
uchar *pszName;
+ DEFiRet;
- if(propLocalHostName != NULL)
- prop.Destruct(&propLocalHostName);
+ if(propLocalHostNameToDelete != NULL)
+ prop.Destruct(&propLocalHostNameToDelete);
- CHKiRet(prop.Construct(&propLocalHostName));
if(LocalHostNameOverride == NULL) {
if(LocalHostName == NULL)
pszName = (uchar*) "[localhost]";
@@ -403,8 +419,20 @@ GenerateLocalHostNameProperty(void)
pszName = LocalHostNameOverride;
}
DBGPRINTF("GenerateLocalHostName uses '%s'\n", pszName);
- CHKiRet(prop.SetString(propLocalHostName, pszName, ustrlen(pszName)));
- CHKiRet(prop.ConstructFinalize(propLocalHostName));
+
+ if(propLocalHostName == NULL)
+ pszPrev = (uchar*)""; /* make sure strcmp() below does not match */
+ else
+ prop.GetString(propLocalHostName, &pszPrev, &lenPrev);
+
+ if(ustrcmp(pszPrev, pszName)) {
+ /* we need to update */
+ CHKiRet(prop.Construct(&hostnameNew));
+ CHKiRet(prop.SetString(hostnameNew, pszName, ustrlen(pszName)));
+ CHKiRet(prop.ConstructFinalize(hostnameNew));
+ propLocalHostNameToDelete = propLocalHostName;
+ propLocalHostName = hostnameNew;
+ }
finalize_it:
RETiRet;
@@ -667,6 +695,8 @@ BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */
free(LocalHostNameOverride);
free(LocalFQDNName);
objRelease(prop, CORE_COMPONENT);
+ if(propLocalHostNameToDelete != NULL)
+ prop.Destruct(&propLocalHostNameToDelete);
DESTROY_ATOMIC_HELPER_MUT(mutTerminateInputs);
ENDObjClassExit(glbl)
diff --git a/runtime/libgcry.h b/runtime/libgcry.h
index b77b0f9e..692ce408 100644
--- a/runtime/libgcry.h
+++ b/runtime/libgcry.h
@@ -21,7 +21,7 @@
#ifndef INCLUDED_LIBGCRY_H
#define INCLUDED_LIBGCRY_H
#include <stdint.h>
-
+#include <gcrypt.h>
struct gcryctx_s {
uchar *key;
@@ -52,6 +52,7 @@ void rsgcryCtxDel(gcryctx ctx);
int gcryfileDestruct(gcryfile gf, off64_t offsLogfile);
rsRetVal rsgcryInitCrypt(gcryctx ctx, gcryfile *pgf, uchar *fname);
int rsgcryEncrypt(gcryfile pF, uchar *buf, size_t *len);
+int gcryGetKeyFromProg(char *cmd, char **key, unsigned *keylen);
/* error states */
#define RSGCRYE_EI_OPEN 1 /* error opening .encinfo file */
diff --git a/runtime/librsgt.c b/runtime/librsgt.c
index 85fc7742..a8124568 100644
--- a/runtime/librsgt.c
+++ b/runtime/librsgt.c
@@ -75,7 +75,7 @@ reportGTAPIErr(gtctx ctx, gtfile gf, char *apiname, int ecode)
char errbuf[4096];
snprintf(errbuf, sizeof(errbuf), "%s[%s:%d]: %s",
(gf == NULL) ? (uchar*)"" : gf->sigfilename,
- apiname, ecode, GT_getErrorString(ecode));
+ apiname, ecode, GTHTTP_getErrorString(ecode));
errbuf[sizeof(errbuf)-1] = '\0';
reportErr(ctx, errbuf);
}
@@ -285,7 +285,9 @@ int
tlv8Write(gtfile gf, int flags, int tlvtype, int len)
{
int r;
- r = tlvbufAddOctet(gf, (flags << 5)|tlvtype);
+ assert((flags & RSGT_TYPE_MASK) == 0);
+ assert((tlvtype & RSGT_TYPE_MASK) == tlvtype);
+ r = tlvbufAddOctet(gf, (flags & ~RSGT_FLAG_TLV16) | tlvtype);
if(r != 0) goto done;
r = tlvbufAddOctet(gf, len & 0xff);
done: return r;
@@ -296,7 +298,9 @@ tlv16Write(gtfile gf, int flags, int tlvtype, uint16_t len)
{
uint16_t typ;
int r;
- typ = ((flags|1) << 15)|tlvtype;
+ assert((flags & RSGT_TYPE_MASK) == 0);
+ assert((tlvtype >> 8 & RSGT_TYPE_MASK) == (tlvtype >> 8));
+ typ = ((flags | RSGT_FLAG_TLV16) << 8) | tlvtype;
r = tlvbufAddOctet(gf, typ >> 8);
if(r != 0) goto done;
r = tlvbufAddOctet(gf, typ & 0xff);
diff --git a/runtime/librsgt.h b/runtime/librsgt.h
index bfcc4628..bf9c9c31 100644
--- a/runtime/librsgt.h
+++ b/runtime/librsgt.h
@@ -151,7 +151,10 @@ struct rsgtstatefile {
};
/* Flags and record types for TLV handling */
+#define RSGT_FLAG_NONCRIT 0x80
+#define RSGT_FLAG_FORWARD 0x40
#define RSGT_FLAG_TLV16 0x20
+#define RSGT_TYPE_MASK 0x1f
/* error states */
#define RSGTE_IO 1 /* any kind of io error */
diff --git a/runtime/librsgt_read.c b/runtime/librsgt_read.c
index a6e33160..a9a50798 100644
--- a/runtime/librsgt_read.c
+++ b/runtime/librsgt_read.c
@@ -249,7 +249,7 @@ rsgt_tlvRecRead(FILE *fp, tlvrecord_t *rec)
NEXTC;
rec->hdr[0] = c;
rec->tlvtype = c & 0x1f;
- if(c & 0x80) { /* tlv16? */
+ if(c & RSGT_FLAG_TLV16) { /* tlv16? */
rec->lenHdr = 4;
NEXTC;
rec->hdr[1] = c;
@@ -290,7 +290,7 @@ rsgt_tlvDecodeSUBREC(tlvrecord_t *rec, uint16_t *stridx, tlvrecord_t *newrec)
c = rec->data[(*stridx)++];
newrec->hdr[0] = c;
newrec->tlvtype = c & 0x1f;
- if(c & 0x80) { /* tlv16? */
+ if(c & RSGT_FLAG_TLV16) { /* tlv16? */
newrec->lenHdr = 4;
if(rec->tlvlen == *stridx) {r=RSGTE_LEN; goto done;}
c = rec->data[(*stridx)++];
diff --git a/runtime/msg.c b/runtime/msg.c
index 9d5fa883..10ecf48a 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -41,9 +41,9 @@
#endif
#include <netdb.h>
#include <libestr.h>
-#include <json/json.h>
+#include <json.h>
/* For struct json_object_iter, should not be necessary in future versions */
-#include <json/json_object_private.h>
+#include <json_object_private.h>
#if HAVE_MALLOC_H
# include <malloc.h>
#endif
@@ -1113,7 +1113,6 @@ MsgDeserialize(msg_t *pMsg, strm_t *pStrm)
prop_t *propRcvFrom = NULL;
prop_t *propRcvFromIP = NULL;
struct json_tokener *tokener;
- struct json_object *json;
var_t *pVar = NULL;
DEFiRet;
@@ -1197,8 +1196,9 @@ MsgDeserialize(msg_t *pMsg, strm_t *pStrm)
}
if(isProp("json")) {
tokener = json_tokener_new();
- json = json_tokener_parse_ex(tokener, (char*)rsCStrGetSzStrNoNULL(pVar->val.pStr),
+ pMsg->json = json_tokener_parse_ex(tokener, (char*)rsCStrGetSzStrNoNULL(pVar->val.pStr),
cstrLen(pVar->val.pStr));
+ json_tokener_free(tokener);
reinitVar(pVar);
CHKiRet(objDeserializeProperty(pVar, pStrm));
}
@@ -2495,10 +2495,10 @@ static uchar *getNOW(eNOWType eNow, struct syslogTime *t)
memcpy(pBuf, two_digits[(int)t->hour], 3);
break;
case NOW_HHOUR:
- memcpy(pBuf, two_digits[t->hour/30], 3);
+ memcpy(pBuf, two_digits[t->minute/30], 3);
break;
case NOW_QHOUR:
- memcpy(pBuf, two_digits[t->hour/15], 3);
+ memcpy(pBuf, two_digits[t->minute/15], 3);
break;
case NOW_MINUTE:
memcpy(pBuf, two_digits[(int)t->minute], 3);
@@ -3934,6 +3934,12 @@ msgAddJSON(msg_t *pM, uchar *name, struct json_object *json)
}
leaf = jsonPathGetLeaf(name, ustrlen(name));
CHKiRet(jsonPathFindParent(pM, name, leaf, &parent, 1));
+ if (json_object_get_type(parent) != json_type_object) {
+ DBGPRINTF("msgAddJSON: not a container in json path,"
+ "name is '%s'\n", name);
+ json_object_put(json);
+ ABORT_FINALIZE(RS_RET_INVLD_SETOP);
+ }
leafnode = json_object_object_get(parent, (char*)leaf);
if(leafnode == NULL) {
json_object_object_add(parent, (char*)leaf, json);
diff --git a/runtime/msg.h b/runtime/msg.h
index 6faf066a..e7babdbb 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -30,7 +30,7 @@
#include <pthread.h>
#include <libestr.h>
-#include <json/json.h>
+#include <json.h>
#include "obj.h"
#include "syslogd-types.h"
#include "template.h"
@@ -62,7 +62,6 @@ struct msg {
once data has entered the queue, this property is no longer needed. */
pthread_mutex_t mut;
int iRefCount; /* reference counter (0 = unused) */
- sbool bAlreadyFreed; /* aid to help detect a well-hidden bad bug -- TODO: remove when no longer needed */
sbool bParseSuccess; /* set to reflect state of last executed higher level parser */
short iSeverity; /* the severity 0..7 */
short iFacility; /* Facility code 0 .. 23*/
diff --git a/runtime/net.c b/runtime/net.c
index b291213e..13391cc0 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -232,6 +232,7 @@ finalize_it:
/* enqueue the element */
if(pPeer->pWildcardRoot == NULL) {
pPeer->pWildcardRoot = pNew;
+ pPeer->pWildcardLast = pNew;
} else {
pPeer->pWildcardLast->pNext = pNew;
}
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c
index 6ef4feba..1110c7a4 100644
--- a/runtime/nsd_gtls.c
+++ b/runtime/nsd_gtls.c
@@ -2,7 +2,7 @@
*
* An implementation of the nsd interface for GnuTLS.
*
- * Copyright (C) 2007, 2008 Rainer Gerhards and Adiscon GmbH.
+ * Copyright (C) 2007-2013 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@@ -547,10 +547,20 @@ gtlsAddOurCert(void)
keyFile = glbl.GetDfltNetstrmDrvrKeyFile();
dbgprintf("GTLS certificate file: '%s'\n", certFile);
dbgprintf("GTLS key file: '%s'\n", keyFile);
+ if(certFile == NULL) {
+ errmsg.LogError(0, RS_RET_CERT_MISSING, "error: certificate file is not set, cannot "
+ "continue");
+ ABORT_FINALIZE(RS_RET_CERT_MISSING);
+ }
+ if(keyFile == NULL) {
+ errmsg.LogError(0, RS_RET_CERTKEY_MISSING, "error: key file is not set, cannot "
+ "continue");
+ ABORT_FINALIZE(RS_RET_CERTKEY_MISSING);
+ }
CHKgnutls(gnutls_certificate_set_x509_key_file(xcred, (char*)certFile, (char*)keyFile, GNUTLS_X509_FMT_PEM));
finalize_it:
- if(iRet != RS_RET_OK) {
+ if(iRet != RS_RET_OK && iRet != RS_RET_CERT_MISSING && iRet != RS_RET_CERTKEY_MISSING) {
pGnuErr = gtlsStrerror(gnuRet);
errno = 0;
errmsg.LogError(0, iRet, "error adding our certificate. GnuTLS error %d, message: '%s', "
@@ -580,6 +590,11 @@ gtlsGlblInit(void)
/* sets the trusted cas file */
cafile = glbl.GetDfltNetstrmDrvrCAF();
+ if(cafile == NULL) {
+ errmsg.LogError(0, RS_RET_CA_CERT_MISSING, "error: ca certificate is not set, cannot "
+ "continue");
+ ABORT_FINALIZE(RS_RET_CA_CERT_MISSING);
+ }
dbgprintf("GTLS CA file: '%s'\n", cafile);
gnuRet = gnutls_certificate_set_x509_trust_file(xcred, (char*)cafile, GNUTLS_X509_FMT_PEM);
if(gnuRet < 0) {
diff --git a/runtime/queue.c b/runtime/queue.c
index 85b1e45b..935a8106 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -877,7 +877,8 @@ static rsRetVal qDestructDisk(qqueue_t *pThis)
DEFiRet;
ASSERT(pThis != NULL);
-
+
+ free(pThis->pszQIFNam);
if(pThis->tVars.disk.pWrite != NULL)
strm.Destruct(&pThis->tVars.disk.pWrite);
if(pThis->tVars.disk.pReadDeq != NULL)
@@ -1022,7 +1023,7 @@ qqueueAdd(qqueue_t *pThis, msg_t *pMsg)
if(pThis->qType != QUEUETYPE_DIRECT) {
ATOMIC_INC(&pThis->iQueueSize, &pThis->mutQueueSize);
- DBGOPRINT((obj_t*) pThis, "entry added, size now log %d, phys %d entries\n",
+ DBGOPRINT((obj_t*) pThis, "qqueueAdd: entry added, size now log %d, phys %d entries\n",
getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis));
}
@@ -1466,7 +1467,7 @@ DoDeleteBatchFromQStore(qqueue_t *pThis, int nElem)
*/
if(bytesDel != 0) {
pThis->tVars.disk.sizeOnDisk -= bytesDel;
- DBGOPRINT((obj_t*) pThis, "a %lld octet file has been deleted, now %lld octets disk "
+ DBGOPRINT((obj_t*) pThis, "doDeleteBatch: a %lld octet file has been deleted, now %lld octets disk "
"space used\n", bytesDel, pThis->tVars.disk.sizeOnDisk);
/* awake possibly waiting enq process */
pthread_cond_signal(&pThis->notFull); /* we hold the mutex while we are in here! */
@@ -1480,7 +1481,7 @@ DoDeleteBatchFromQStore(qqueue_t *pThis, int nElem)
/* iQueueSize is not decremented by qDel(), so we need to do it ourselves */
ATOMIC_SUB(&pThis->iQueueSize, nElem, &pThis->mutQueueSize);
ATOMIC_SUB(&pThis->nLogDeq, nElem, &pThis->mutLogDeq);
- DBGPRINTF("delete batch from store, new sizes: log %d, phys %d\n",
+ DBGPRINTF("doDeleteBatch: delete batch from store, new sizes: log %d, phys %d\n",
getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis));
++pThis->deqIDDel; /* one more batch dequeued */
@@ -1550,13 +1551,13 @@ DeleteProcessedBatch(qqueue_t *pThis, batch_t *pBatch)
localRet = doEnqSingleObj(pThis, eFLOWCTL_NO_DELAY, MsgAddRef(pMsg));
++nEnqueued;
if(localRet != RS_RET_OK) {
- DBGPRINTF("error %d re-enqueuing unprocessed data element - discarded\n", localRet);
+ DBGPRINTF("DeleteProcessedBatch: error %d re-enqueuing unprocessed data element - discarded\n", localRet);
}
}
msgDestruct(&pMsg);
}
- DBGPRINTF("we deleted %d objects and enqueued %d objects\n", i-nEnqueued, nEnqueued);
+ DBGPRINTF("DeleteProcessedBatch: we deleted %d objects and enqueued %d objects\n", i-nEnqueued, nEnqueued);
if(nEnqueued > 0)
qqueueChkPersist(pThis, nEnqueued);
@@ -1913,8 +1914,16 @@ ConsumerDA(qqueue_t *pThis, wti_t *pWti)
/* iterate over returned results and enqueue them in DA queue */
for(i = 0 ; i < pWti->batch.nElem && !pThis->bShutdownImmediate ; i++) {
- CHKiRet(qqueueEnqMsg(pThis->pqDA, eFLOWCTL_NO_DELAY,
- MsgAddRef(pWti->batch.pElem[i].pMsg)));
+ iRet = qqueueEnqMsg(pThis->pqDA, eFLOWCTL_NO_DELAY, MsgAddRef(pWti->batch.pElem[i].pMsg));
+ if(iRet != RS_RET_OK) {
+ if(iRet == RS_RET_ERR_QUEUE_EMERGENCY) {
+ /* Queue emergency error occured */
+ DBGOPRINT((obj_t*) pThis, "ConsumerDA:qqueueEnqMsg caught RS_RET_ERR_QUEUE_EMERGENCY, aborting loop.\n");
+ FINALIZE;
+ } else {
+ DBGOPRINT((obj_t*) pThis, "ConsumerDA:qqueueEnqMsg item (%d) returned with error state: '%d'\n", i, iRet);
+ }
+ }
pWti->batch.eltState[i] = BATCH_STATE_COMM; /* commited to other queue! */
}
@@ -1922,10 +1931,38 @@ ConsumerDA(qqueue_t *pThis, wti_t *pWti)
pthread_setcancelstate(iCancelStateSave, NULL);
finalize_it:
+ /* Check the last return state of qqueueEnqMsg. If an error was returned, we acknowledge it only.
+ * Unless the error code is RS_RET_ERR_QUEUE_EMERGENCY, we reset the return state to RS_RET_OK.
+ * Otherwise the Caller functions would run into an infinite Loop trying to enqueue the
+ * same messages over and over again.
+ *
+ * However we do NOT overwrite positive return states like
+ * RS_RET_TERMINATE_NOW,
+ * RS_RET_NO_RUN,
+ * RS_RET_IDLE,
+ * RS_RET_TERMINATE_WHEN_IDLE
+ * These return states are important for Queue handling of the upper laying functions.
+ * RGer: Note that checking for iRet < 0 is a bit bold. In theory, positive iRet
+ * values are "OK" states, and things that the caller shall deal with. However,
+ * this has not been done so consistently. Andre convinced me that the current
+ * code is an elegant solution. However, if problems with queue workers and/or
+ * shutdown come up, this code here should be looked at suspiciously. In those
+ * cases it may work out to check all status codes explicitely, just to avoid
+ * a pitfall due to unexpected states being passed on to the caller.
+ */
+ if( iRet != RS_RET_OK &&
+ iRet != RS_RET_ERR_QUEUE_EMERGENCY &&
+ iRet < 0) {
+ DBGOPRINT((obj_t*) pThis, "ConsumerDA:qqueueEnqMsg Resetting iRet from %d back to RS_RET_OK\n", iRet);
+ iRet = RS_RET_OK;
+ } else {
+ DBGOPRINT((obj_t*) pThis, "ConsumerDA:qqueueEnqMsg returns with iRet %d\n", iRet);
+ }
+
/* now we are done, but potentially need to re-aquire the mutex */
if(bNeedReLock)
d_pthread_mutex_lock(pThis->mut);
- DBGOPRINT((obj_t*) pThis, "DAConsumer returns with iRet %d\n", iRet);
+
RETiRet;
}
@@ -2089,12 +2126,12 @@ qqueueStart(qqueue_t *pThis) /* this is the ConstructionFinalizer */
pThis->iFullDlyMrk = wrk;
}
- DBGOPRINT((obj_t*) pThis, "type %d, enq-only %d, disk assisted %d, maxFileSz %lld, lqsize %d, pqsize %d, child %d, "
- "full delay %d, light delay %d, deq batch size %d starting\n",
- pThis->qType, pThis->bEnqOnly, pThis->bIsDA, pThis->iMaxFileSize,
+ DBGOPRINT((obj_t*) pThis, "type %d, enq-only %d, disk assisted %d, maxFileSz %lld, maxQSize %d, lqsize %d, pqsize %d, child %d, "
+ "full delay %d, light delay %d, deq batch size %d starting, high wtrrmrk %d, low wtrmrk %d\n",
+ pThis->qType, pThis->bEnqOnly, pThis->bIsDA, pThis->iMaxFileSize, pThis->iMaxQueueSize,
getLogicalQueueSize(pThis), getPhysicalQueueSize(pThis),
pThis->pqParent == NULL ? 0 : 1, pThis->iFullDlyMrk, pThis->iLightDlyMrk,
- pThis->iDeqBatchSize);
+ pThis->iDeqBatchSize, pThis->iHighWtrMrk, pThis->iLowWtrMrk);
pThis->bQueueStarted = 1;
if(pThis->qType == QUEUETYPE_DIRECT)
@@ -2491,7 +2528,7 @@ doEnqSingleObj(qqueue_t *pThis, flowControl_t flowCtlType, msg_t *pMsg)
* In any case, this was the old code (if we do the TODO):
* pthread_cond_wait(&pThis->belowFullDlyWtrMrk, pThis->mut);
*/
- DBGOPRINT((obj_t*) pThis, "enqueueMsg: FullDelay mark reached for full delayable message "
+ DBGOPRINT((obj_t*) pThis, "doEnqSingleObject: FullDelay mark reached for full delayable message "
"- blocking, queue size is %d.\n", pThis->iQueueSize);
timeoutComp(&t, 1000);
err = pthread_cond_timedwait(&pThis->belowLightDlyWtrMrk, pThis->mut, &t);
@@ -2508,7 +2545,7 @@ doEnqSingleObj(qqueue_t *pThis, flowControl_t flowCtlType, msg_t *pMsg)
}
} else if(flowCtlType == eFLOWCTL_LIGHT_DELAY && !glbl.GetGlobalInputTermState()) {
if(pThis->iQueueSize >= pThis->iLightDlyMrk) {
- DBGOPRINT((obj_t*) pThis, "enqueueMsg: LightDelay mark reached for light "
+ DBGOPRINT((obj_t*) pThis, "doEnqSingleObject: LightDelay mark reached for light "
"delayable message - blocking a bit.\n");
timeoutComp(&t, 1000); /* 1000 millisconds = 1 second TODO: make configurable */
err = pthread_cond_timedwait(&pThis->belowLightDlyWtrMrk, pThis->mut, &t);
@@ -2531,24 +2568,26 @@ doEnqSingleObj(qqueue_t *pThis, flowControl_t flowCtlType, msg_t *pMsg)
&& pThis->tVars.disk.sizeOnDisk > pThis->sizeOnDiskMax)) {
STATSCOUNTER_INC(pThis->ctrFull, pThis->mutCtrFull);
if(pThis->toEnq == 0 || pThis->bEnqOnly) {
- DBGOPRINT((obj_t*) pThis, "enqueueMsg: queue FULL - configured for immediate discarding.\n");
+ DBGOPRINT((obj_t*) pThis, "doEnqSingleObject: queue FULL - configured for immediate discarding QueueSize=%d "
+ "MaxQueueSize=%d sizeOnDisk=%lld sizeOnDiskMax=%lld\n", pThis->iQueueSize, pThis->iMaxQueueSize,
+ pThis->tVars.disk.sizeOnDisk, pThis->sizeOnDiskMax);
STATSCOUNTER_INC(pThis->ctrFDscrd, pThis->mutCtrFDscrd);
msgDestruct(&pMsg);
ABORT_FINALIZE(RS_RET_QUEUE_FULL);
} else {
- DBGOPRINT((obj_t*) pThis, "enqueueMsg: queue FULL - waiting %dms to drain.\n", pThis->toEnq);
+ DBGOPRINT((obj_t*) pThis, "doEnqSingleObject: queue FULL - waiting %dms to drain.\n", pThis->toEnq);
if(glbl.GetGlobalInputTermState()) {
- DBGOPRINT((obj_t*) pThis, "enqueueMsg: queue FULL, discard due to FORCE_TERM.\n");
+ DBGOPRINT((obj_t*) pThis, "doEnqSingleObject: queue FULL, discard due to FORCE_TERM.\n");
ABORT_FINALIZE(RS_RET_FORCE_TERM);
}
timeoutComp(&t, pThis->toEnq);
if(pthread_cond_timedwait(&pThis->notFull, pThis->mut, &t) != 0) {
- DBGOPRINT((obj_t*) pThis, "enqueueMsg: cond timeout, dropping message!\n");
+ DBGOPRINT((obj_t*) pThis, "doEnqSingleObject: cond timeout, dropping message!\n");
STATSCOUNTER_INC(pThis->ctrFDscrd, pThis->mutCtrFDscrd);
msgDestruct(&pMsg);
ABORT_FINALIZE(RS_RET_QUEUE_FULL);
}
- dbgoprint((obj_t*) pThis, "enqueueMsg: wait solved queue full condition, enqueing\n");
+ dbgoprint((obj_t*) pThis, "doEnqSingleObject: wait solved queue full condition, enqueing\n");
}
}
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index 47b34783..e62ba867 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -3,7 +3,7 @@
*
* Begun 2005-09-15 RGerhards
*
- * Copyright (C) 2005-2008 by Rainer Gerhards and Adiscon GmbH
+ * Copyright (C) 2005-2013 by Rainer Gerhards and Adiscon GmbH
*
* This file is part of the rsyslog runtime library.
*
@@ -413,6 +413,9 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_CRY_INVLD_ALGO = -2326,/**< user specified invalid (unkonwn) crypto algorithm */
RS_RET_CRY_INVLD_MODE = -2327,/**< user specified invalid (unkonwn) crypto mode */
RS_RET_QUEUE_DISK_NO_FN = -2328,/**< disk queue configured, but filename not set */
+ RS_RET_CA_CERT_MISSING = -2329,/**< a CA cert is missing where one is required (e.g. TLS) */
+ RS_RET_CERT_MISSING = -2330,/**< a cert is missing where one is required (e.g. TLS) */
+ RS_RET_CERTKEY_MISSING = -2331,/**< a cert (private) key is missing where one is required (e.g. TLS) */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/runtime/ruleset.c b/runtime/ruleset.c
index cbfd847a..1afb4039 100644
--- a/runtime/ruleset.c
+++ b/runtime/ruleset.c
@@ -766,7 +766,7 @@ CODESTARTobjDestruct(ruleset)
parser.DestructParserList(&pThis->pParserLst);
}
free(pThis->pszName);
- cnfstmtDestruct(pThis->root);
+ cnfstmtDestructLst(pThis->root);
ENDobjDestruct(ruleset)
@@ -976,7 +976,7 @@ rulesetProcessCnf(struct cnfobj *o)
errmsg.LogError(0, RS_RET_RULESET_EXISTS,
"error: ruleset '%s' specified more than once",
rsName);
- cnfstmtDestruct(o->script);
+ cnfstmtDestructLst(o->script);
ABORT_FINALIZE(RS_RET_RULESET_EXISTS);
} else if(localRet != RS_RET_NOT_FOUND) {
ABORT_FINALIZE(localRet);
diff --git a/runtime/stream.c b/runtime/stream.c
index 54210e40..94fc0ca7 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -1605,7 +1605,7 @@ finalize_it:
/* property set methods */
/* simple ones first */
DEFpropSetMeth(strm, bDeleteOnClose, int)
-DEFpropSetMeth(strm, iMaxFileSize, int)
+DEFpropSetMeth(strm, iMaxFileSize, int64)
DEFpropSetMeth(strm, iFileNumDigits, int)
DEFpropSetMeth(strm, tOperationsMode, int)
DEFpropSetMeth(strm, tOpenMode, mode_t)
diff --git a/runtime/stream.h b/runtime/stream.h
index 61d5ede2..4f4a4301 100644
--- a/runtime/stream.h
+++ b/runtime/stream.h
@@ -158,7 +158,6 @@ BEGINinterface(strm) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Construct)(strm_t **ppThis);
rsRetVal (*ConstructFinalize)(strm_t *pThis);
rsRetVal (*Destruct)(strm_t **ppThis);
- rsRetVal (*SetMaxFileSize)(strm_t *pThis, int64 iMaxFileSize);
rsRetVal (*SetFileName)(strm_t *pThis, uchar *pszName, size_t iLenName);
rsRetVal (*ReadChar)(strm_t *pThis, uchar *pC);
rsRetVal (*UnreadChar)(strm_t *pThis, uchar c);
@@ -176,7 +175,7 @@ BEGINinterface(strm) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetWCntr)(strm_t *pThis, number_t *pWCnt);
rsRetVal (*Dup)(strm_t *pThis, strm_t **ppNew);
INTERFACEpropSetMeth(strm, bDeleteOnClose, int);
- INTERFACEpropSetMeth(strm, iMaxFileSize, int);
+ INTERFACEpropSetMeth(strm, iMaxFileSize, int64);
INTERFACEpropSetMeth(strm, iMaxFiles, int);
INTERFACEpropSetMeth(strm, iFileNumDigits, int);
INTERFACEpropSetMeth(strm, tOperationsMode, int);
diff --git a/runtime/stringbuf.c b/runtime/stringbuf.c
index cb4f0457..13f38710 100644
--- a/runtime/stringbuf.c
+++ b/runtime/stringbuf.c
@@ -107,7 +107,8 @@ finalize_it:
/* a helper function for rsCStr*Strf()
*/
-static rsRetVal rsCStrConstructFromszStrv(cstr_t **ppThis, uchar *fmt, va_list ap)
+static rsRetVal rsCStrConstructFromszStrv(cstr_t **ppThis, char *fmt, va_list ap) __attribute__((format(gnu_printf,2, 0)));
+static rsRetVal rsCStrConstructFromszStrv(cstr_t **ppThis, char *fmt, va_list ap)
{
DEFiRet;
cstr_t *pThis;
@@ -147,7 +148,7 @@ rsRetVal rsCStrConstructFromszStrf(cstr_t **ppThis, char *fmt, ...)
va_list ap;
va_start(ap, fmt);
- iRet = rsCStrConstructFromszStrv(ppThis, (uchar*)fmt, ap);
+ iRet = rsCStrConstructFromszStrv(ppThis, fmt, ap);
va_end(ap);
RETiRet;
@@ -315,7 +316,7 @@ rsRetVal rsCStrAppendStrf(cstr_t *pThis, uchar *fmt, ...)
cstr_t *pStr = NULL;
va_start(ap, fmt);
- iRet = rsCStrConstructFromszStrv(&pStr, fmt, ap);
+ iRet = rsCStrConstructFromszStrv(&pStr, (char*)fmt, ap);
va_end(ap);
CHKiRet(iRet);
@@ -563,7 +564,7 @@ rsRetVal cstrTrimTrailingWhiteSpace(cstr_t *pThis)
}
/* i now is the new string length! */
pThis->iStrLen = i;
- pThis->pBuf[pThis->iStrLen] = '0'; /* we always have this space */
+ pThis->pBuf[pThis->iStrLen] = '\0'; /* we always have this space */
done: return RS_RET_OK;
}
diff --git a/runtime/typedefs.h b/runtime/typedefs.h
index 8db567f0..d3f68b4a 100644
--- a/runtime/typedefs.h
+++ b/runtime/typedefs.h
@@ -29,6 +29,10 @@
#include <sys/types.h>
#endif
+#ifndef HAVE_LSEEK64
+#include <unistd.h>
+#endif
+
/* some universal fixed size integer defines ... */
typedef long long int64;
typedef long long unsigned uint64;