summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/imdiag/imdiag.c239
-rw-r--r--plugins/imfile/imfile.c5
-rw-r--r--plugins/imgssapi/imgssapi.c5
-rw-r--r--plugins/imklog/imklog.c7
-rw-r--r--plugins/imklog/ksym_mod.c42
-rw-r--r--plugins/imklog/ksyms.h4
-rw-r--r--plugins/imtcp/imtcp.c35
-rw-r--r--plugins/imudp/imudp.c5
-rw-r--r--plugins/omgssapi/omgssapi.c2
-rw-r--r--plugins/omoracle/omoracle.c290
-rw-r--r--plugins/omoracle/omoracle.h8
-rw-r--r--plugins/ompgsql/ompgsql.c50
12 files changed, 563 insertions, 129 deletions
diff --git a/plugins/imdiag/imdiag.c b/plugins/imdiag/imdiag.c
index 3cd2dcf8..40f94692 100644
--- a/plugins/imdiag/imdiag.c
+++ b/plugins/imdiag/imdiag.c
@@ -7,7 +7,7 @@
*
* File begun on 2008-07-25 by RGerhards
*
- * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2008, 2009 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -26,8 +26,8 @@
*
* A copy of the GPL can be found in the file "COPYING" in this distribution.
*/
-
#include "config.h"
+#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
@@ -43,110 +43,247 @@
#include <fcntl.h>
#endif
#include "rsyslog.h"
-//#include "dirty.h"
+#include "dirty.h"
#include "cfsysline.h"
#include "module-template.h"
+#include "unicode-helper.h"
#include "net.h"
#include "netstrm.h"
#include "errmsg.h"
+#include "tcpsrv.h"
+#include "srUtils.h"
+#include "net.h" /* for permittedPeers, may be removed when this is removed */
MODULE_TYPE_INPUT
/* static data */
DEF_IMOD_STATIC_DATA
+DEFobjCurrIf(tcpsrv)
+DEFobjCurrIf(tcps_sess)
DEFobjCurrIf(net)
DEFobjCurrIf(netstrm)
DEFobjCurrIf(errmsg)
/* Module static data */
-netstrms_t *pNS; /**< pointer to network stream subsystem */
-netstrm_t **ppLstn[10]; /**< our netstream listners */
-int iLstnMax = 0; /**< max nbr of listeners currently supported */
+static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */
+static permittedPeers_t *pPermPeersRoot = NULL;
/* config settings */
+static int iTCPSessMax = 20; /* max number of sessions */
+static int iStrmDrvrMode = 0; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
+static uchar *pszStrmDrvrAuthMode = NULL; /* authentication mode to use */
+static uchar *pszInputName = NULL; /* value for inputname property, NULL is OK and handled by core engine */
+
+
+/* callbacks */
+/* this shall go into a specific ACL module! */
+static int
+isPermittedHost(struct sockaddr __attribute__((unused)) *addr, char __attribute__((unused)) *fromHostFQDN,
+ void __attribute__((unused)) *pUsrSrv, void __attribute__((unused)) *pUsrSess)
+{
+ return 1; /* TODO: implement ACLs ... or via some other way? */
+}
-/* add a listen socket to our listen socket array. This is a callback
- * invoked from the netstrm class. -- rgerhards, 2008-04-23
+static rsRetVal
+doOpenLstnSocks(tcpsrv_t *pSrv)
+{
+ ISOBJ_TYPE_assert(pSrv, tcpsrv);
+ return tcpsrv.create_tcp_socket(pSrv);
+}
+
+
+static rsRetVal
+doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf, ssize_t *piLenRcvd)
+{
+ DEFiRet;
+ assert(pSess != NULL);
+ assert(piLenRcvd != NULL);
+
+ *piLenRcvd = lenBuf;
+ CHKiRet(netstrm.Rcv(pSess->pStrm, (uchar*) buf, piLenRcvd));
+finalize_it:
+ RETiRet;
+}
+
+static rsRetVal
+onRegularClose(tcps_sess_t *pSess)
+{
+ DEFiRet;
+ assert(pSess != NULL);
+
+ /* process any incomplete frames left over */
+ tcps_sess.PrepareClose(pSess);
+ /* Session closed */
+ tcps_sess.Close(pSess);
+ RETiRet;
+}
+
+
+static rsRetVal
+onErrClose(tcps_sess_t *pSess)
+{
+ DEFiRet;
+ assert(pSess != NULL);
+
+ tcps_sess.Close(pSess);
+ RETiRet;
+}
+
+/* ------------------------------ end callbacks ------------------------------ */
+
+
+/* This function waits until the main queue is drained (size = 0)
*/
static rsRetVal
-addTcpLstn(void *pUsr, netstrm_t *pLstn)
+waitMainQEmpty(void)
{
+ int iMsgQueueSize;
DEFiRet;
- ISOBJ_TYPE_assert(pLstn, netstrm);
+ CHKiRet(diagGetMainMsgQSize(&iMsgQueueSize));
+ while(iMsgQueueSize > 0) {
+ srSleep(0,2); /* wait a little bit */
+ CHKiRet(diagGetMainMsgQSize(&iMsgQueueSize));
+ }
+
+finalize_it:
+ RETiRet;
+}
+
- if(iLstnMax >= sizeof(ppLstn)/sizeof(netstrm_t))
- ABORT_FINALIZE(RS_RET_MAX_LSTN_REACHED);
+/* Function to handle received messages. This is our core function!
+ * rgerhards, 2009-05-24
+ */
+static rsRetVal
+OnMsgReceived(tcps_sess_t *pSess, uchar *pRcv, int iLenMsg)
+{
+ ssize_t len;
+ int iMsgQueueSize;
+ uchar *pszMsg;
+ uchar buf[1024];
+ DEFiRet;
- ppLstn[pThis->iLstnMax] = pLstn;
- ++iLstnMax;
+ assert(pSess != NULL);
+ assert(pRcv != NULL);
+
+ /* NOTE: pRcv is NOT a C-String but rather an array of characters
+ * WITHOUT a termination \0 char. So we need to convert it to one
+ * before proceeding.
+ */
+ CHKmalloc(pszMsg = malloc(sizeof(uchar) * (iLenMsg + 1)));
+ memcpy(pszMsg, pRcv, iLenMsg);
+ pszMsg[iLenMsg] = '\0';
+
+ if(!ustrcmp(pszMsg, UCHAR_CONSTANT("GetMainMsgQueueSize"))) {
+ CHKiRet(diagGetMainMsgQSize(&iMsgQueueSize));
+ len = snprintf((char*)buf, sizeof(buf)/sizeof(uchar), "%d\n", iMsgQueueSize);
+ CHKiRet(netstrm.Send(pSess->pStrm, buf, &len));
+ } else if(!ustrcmp(pszMsg, UCHAR_CONSTANT("WaitMainQueueEmpty"))) {
+ CHKiRet(waitMainQEmpty());
+ len = snprintf((char*)buf, sizeof(buf)/sizeof(uchar), "mainqueue empty\n");
+ CHKiRet(netstrm.Send(pSess->pStrm, buf, &len));
+ } else {
+ len = snprintf((char*)buf, sizeof(buf)/sizeof(uchar), "unkown command '%s'\n", pszMsg);
+ CHKiRet(netstrm.Send(pSess->pStrm, buf, &len));
+ }
finalize_it:
RETiRet;
}
-/* initialize network stream subsystem */
+/* set permitted peer -- rgerhards, 2008-05-19
+ */
static rsRetVal
-initNetstrm(void)
+setPermittedPeer(void __attribute__((unused)) *pVal, uchar *pszID)
+{
+ DEFiRet;
+ CHKiRet(net.AddPermittedPeer(&pPermPeersRoot, pszID));
+ free(pszID); /* no longer needed, but we need to free as of interface def */
+finalize_it:
+ RETiRet;
+}
+
+
+static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVal)
{
DEFiRet;
- /* prepare network stream subsystem */
- CHKiRet(netstrms.Construct(&pNS));
- CHKiRet(netstrms.SetDrvrMode(pNS, 0)); /* always plain text */
- //CHKiRet(netstrms.SetDrvrAuthMode(pThis->pNS, pThis->pszDrvrAuthMode));
- //CHKiRet(netstrms.SetDrvrPermPeers(pThis->pNS, pThis->pPermPeers));
- // TODO: set driver!
- CHKiRet(netstrms.ConstructFinalize(pThis->pNS));
+ if(pOurTcpsrv == NULL) {
+ CHKiRet(tcpsrv.Construct(&pOurTcpsrv));
+ CHKiRet(tcpsrv.SetSessMax(pOurTcpsrv, iTCPSessMax));
+ CHKiRet(tcpsrv.SetCBIsPermittedHost(pOurTcpsrv, isPermittedHost));
+ CHKiRet(tcpsrv.SetCBRcvData(pOurTcpsrv, doRcvData));
+ CHKiRet(tcpsrv.SetCBOpenLstnSocks(pOurTcpsrv, doOpenLstnSocks));
+ CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose));
+ CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose));
+ CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode));
+ CHKiRet(tcpsrv.SetOnMsgReceive(pOurTcpsrv, OnMsgReceived));
+ /* now set optional params, but only if they were actually configured */
+ if(pszStrmDrvrAuthMode != NULL) {
+ CHKiRet(tcpsrv.SetDrvrAuthMode(pOurTcpsrv, pszStrmDrvrAuthMode));
+ }
+ if(pPermPeersRoot != NULL) {
+ CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot));
+ }
+ }
- /* set up listeners */
- CHKiRet(netstrm.LstnInit(pNS, NULL, addTcpLstn, "127.0.0.1", "44514", 1));
+ /* initialized, now add socket */
+ CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ?
+ UCHAR_CONSTANT("imdiag") : pszInputName));
+ tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal);
finalize_it:
if(iRet != RS_RET_OK) {
- if(pThis->pNS != NULL)
- netstrms.Destruct(&pThis->pNS);
+ errmsg.LogError(0, NO_ERRCODE, "error %d trying to add listener", iRet);
+ if(pOurTcpsrv != NULL)
+ tcpsrv.Destruct(&pOurTcpsrv);
}
RETiRet;
}
-
-/* This function is called to gather input. In our case, it is a bit abused
- * to drive the listener loop for the diagnostics code.
+/* This function is called to gather input.
*/
BEGINrunInput
CODESTARTrunInput
+ CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
+ iRet = tcpsrv.Run(pOurTcpsrv);
+finalize_it:
ENDrunInput
/* initialize and return if will run or not */
BEGINwillRun
CODESTARTwillRun
- iRet = initNetstrm();
+ /* first apply some config settings */
+ if(pOurTcpsrv == NULL)
+ ABORT_FINALIZE(RS_RET_NO_RUN);
+finalize_it:
ENDwillRun
BEGINafterRun
CODESTARTafterRun
/* do cleanup here */
- /* finally close our listen streams */
- for(i = 0 ; i < iLstnMax ; ++i) {
- netstrm.Destruct(ppLstn + i);
- }
-
- /* destruct netstream subsystem */
- netstrms.Destruct(pNS);
ENDafterRun
BEGINmodExit
CODESTARTmodExit
+ if(pOurTcpsrv != NULL)
+ iRet = tcpsrv.Destruct(&pOurTcpsrv);
+
+ if(pPermPeersRoot != NULL) {
+ net.DestructPermittedPeers(&pPermPeersRoot);
+ }
+
/* release objects we used */
objRelease(net, LM_NET_FILENAME);
objRelease(netstrm, LM_NETSTRMS_FILENAME);
+ objRelease(tcps_sess, LM_TCPSRV_FILENAME);
+ objRelease(tcpsrv, LM_TCPSRV_FILENAME);
objRelease(errmsg, CORE_COMPONENT);
ENDmodExit
@@ -154,6 +291,14 @@ ENDmodExit
static rsRetVal
resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
+ iTCPSessMax = 200;
+ iStrmDrvrMode = 0;
+ free(pszInputName);
+ pszInputName = NULL;
+ if(pszStrmDrvrAuthMode != NULL) {
+ free(pszStrmDrvrAuthMode);
+ pszStrmDrvrAuthMode = NULL;
+ }
return RS_RET_OK;
}
@@ -173,23 +318,25 @@ CODEmodInit_QueryRegCFSLineHdlr
/* request objects we use */
CHKiRet(objUse(net, LM_NET_FILENAME));
CHKiRet(objUse(netstrm, LM_NETSTRMS_FILENAME));
+ CHKiRet(objUse(tcps_sess, LM_TCPSRV_FILENAME));
+ CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME));
CHKiRet(objUse(errmsg, CORE_COMPONENT));
-#if 0
/* register config file handlers */
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("imdiagserverrun"), 0, eCmdHdlrGetWord,
addTCPListener, NULL, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("imdiagmaxsessions"), 0, eCmdHdlrInt,
NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdrivermode", 0,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("imdiagserverstreamdrivermode"), 0,
eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverauthmode", 0,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("imdiagserverstreamdriverauthmode"), 0,
eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverpermittedpeer", 0,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("imdiagserverstreamdriverpermittedpeer"), 0,
eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("imdiagserverinputname"), 0,
+ eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
-#endif
ENDmodInit
diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
index b0211bf6..92fd30c3 100644
--- a/plugins/imfile/imfile.c
+++ b/plugins/imfile/imfile.c
@@ -45,6 +45,7 @@
#include "errmsg.h"
#include "glbl.h"
#include "datetime.h"
+#include "unicode-helper.h"
MODULE_TYPE_INPUT /* must be present for input modules, do not remove */
@@ -94,11 +95,11 @@ static rsRetVal enqLine(fileInfo_t *pInfo, cstr_t *cstrLine)
CHKiRet(msgConstruct(&pMsg));
MsgSetFlowControlType(pMsg, eFLOWCTL_FULL_DELAY);
- MsgSetInputName(pMsg, "imfile");
+ MsgSetInputName(pMsg, UCHAR_CONSTANT("imfile"));
MsgSetUxTradMsg(pMsg, (char*)rsCStrGetSzStr(cstrLine));
MsgSetRawMsg(pMsg, (char*)rsCStrGetSzStr(cstrLine));
MsgSetMSG(pMsg, (char*)rsCStrGetSzStr(cstrLine));
- MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName());
+ MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName());
MsgSetTAG(pMsg, (char*)pInfo->pszTag);
pMsg->iFacility = LOG_FAC(pInfo->iFacility);
pMsg->iSeverity = LOG_PRI(pInfo->iSeverity);
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index debe935e..d8791880 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -9,7 +9,7 @@
* NOTE: read comments in module-template.h to understand how this file
* works!
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -249,7 +249,6 @@ onErrClose(tcps_sess_t *pSess)
static rsRetVal
doOpenLstnSocks(tcpsrv_t *pSrv)
{
- int *pRet = NULL;
gsssrv_t *pGSrv;
DEFiRet;
@@ -331,7 +330,7 @@ addGSSListener(void __attribute__((unused)) *pVal, uchar *pNewVal)
CHKiRet(tcpsrv.SetCBOnSessAccept(pOurTcpsrv, onSessAccept));
CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose));
CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose));
- tcpsrv.configureTCPListen(pOurTcpsrv, (char *) pNewVal);
+ tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal);
CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
}
diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c
index 20bc34ab..ecb6c100 100644
--- a/plugins/imklog/imklog.c
+++ b/plugins/imklog/imklog.c
@@ -53,6 +53,7 @@
#include "datetime.h"
#include "imklog.h"
#include "glbl.h"
+#include "unicode-helper.h"
MODULE_TYPE_INPUT
@@ -94,14 +95,14 @@ enqMsg(uchar *msg, uchar* pszTag, int iFacility, int iSeverity)
CHKiRet(msgConstruct(&pMsg));
MsgSetFlowControlType(pMsg, eFLOWCTL_LIGHT_DELAY);
- MsgSetInputName(pMsg, "imklog");
+ MsgSetInputName(pMsg, UCHAR_CONSTANT("imklog"));
MsgSetRawMsg(pMsg, (char*)msg);
MsgSetUxTradMsg(pMsg, (char*)msg);
MsgSetRawMsg(pMsg, (char*)msg);
MsgSetMSG(pMsg, (char*)msg);
- MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName());
+ MsgSetRcvFrom(pMsg, glbl.GetLocalHostName());
MsgSetRcvFromIP(pMsg, (uchar*)"127.0.0.1");
- MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName());
+ MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName());
MsgSetTAG(pMsg, (char*)pszTag);
pMsg->iFacility = LOG_FAC(iFacility);
pMsg->iSeverity = LOG_PRI(iSeverity);
diff --git a/plugins/imklog/ksym_mod.c b/plugins/imklog/ksym_mod.c
index 6e48e89e..be5fdee9 100644
--- a/plugins/imklog/ksym_mod.c
+++ b/plugins/imklog/ksym_mod.c
@@ -1,9 +1,8 @@
-/*
- * ksym_mod.c - functions for building symbol lookup tables for klogd
+/* ksym_mod.c - functions for building symbol lookup tables for klogd
* Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
* Copyright (c) 1996 Enjellic Systems Development
* Copyright (c) 1998-2007 Martin Schulze <joey@infodrom.org>
- * Copyright (C) 2007-2008 Rainer Gerhards <rgerhards@adiscon.com>
+ * Copyright (C) 2007-2009 Rainer Gerhards <rgerhards@adiscon.com>
*
* This file is part of rsyslog.
*
@@ -83,7 +82,6 @@
* Changed llseek() to lseek64() in order to skip a libc warning.
*/
-
/* Includes. */
#include "config.h"
#include <stdio.h>
@@ -112,7 +110,7 @@
#define KSYMS "/proc/kallsyms"
static int num_modules = 0;
-struct Module *sym_array_modules = (struct Module *) 0;
+struct Module *sym_array_modules = (struct Module *) NULL;
static int have_modules = 0;
@@ -266,7 +264,7 @@ static void FreeModules()
}
free(sym_array_modules);
- sym_array_modules = (struct Module *) 0;
+ sym_array_modules = (struct Module *) NULL;
num_modules = 0;
return;
}
@@ -390,11 +388,11 @@ static int AddSymbol(line)
mp->sym_array = (struct sym_table *) realloc(mp->sym_array, \
(mp->num_syms+1) * sizeof(struct sym_table));
- if ( mp->sym_array == (struct sym_table *) 0 )
+ if ( mp->sym_array == (struct sym_table *) NULL )
return(0);
mp->sym_array[mp->num_syms].name = strdup(p);
- if ( mp->sym_array[mp->num_syms].name == (char *) 0 )
+ if ( mp->sym_array[mp->num_syms].name == (char *) NULL )
return(0);
/* Stuff interesting information into the module. */
@@ -424,15 +422,21 @@ static int AddSymbol(line)
* If a match cannot be found a diagnostic string is printed.
* If a match is found the pointer to the symbolic name most
* closely matching the address is returned.
+ *
+ * TODO: We are using int values for the offset, but longs for the value
+ * values. This may create some trouble in the future (on 64 Bit OS?).
+ * Anyhow, I have not changed this, because we do not seem to have any
+ * issue and my understanding of this code is limited (and I don't see
+ * need to invest more time to dig much deeper).
+ * rgerhards, 2009-04-17
**************************************************************************/
extern char * LookupModuleSymbol(value, sym)
unsigned long value;
struct symbol *sym;
{
- auto int nmod,
- nsym;
- auto struct sym_table *last;
- auto struct Module *mp;
+ int nmod, nsym;
+ struct sym_table *last;
+ struct Module *mp;
static char ret[100];
sym->size = 0;
@@ -443,8 +447,7 @@ extern char * LookupModuleSymbol(value, sym)
for (nmod = 0; nmod < num_modules; ++nmod) {
mp = &sym_array_modules[nmod];
- /*
- * Run through the list of symbols in this module and
+ /* Run through the list of symbols in this module and
* see if the address can be resolved.
*/
for(nsym = 1, last = &mp->sym_array[0];
@@ -453,13 +456,12 @@ extern char * LookupModuleSymbol(value, sym)
if ( mp->sym_array[nsym].value > value )
{
if ( sym->size == 0 ||
- (value - last->value) < sym->offset ||
- ( (sym->offset == (value - last->value)) &&
- (mp->sym_array[nsym].value-last->value) < sym->size ) )
+ (int) (value - last->value) < sym->offset ||
+ ( (sym->offset == (int) (value - last->value)) &&
+ (int) (mp->sym_array[nsym].value-last->value) < sym->size ) )
{
sym->offset = value - last->value;
- sym->size = mp->sym_array[nsym].value - \
- last->value;
+ sym->size = mp->sym_array[nsym].value - last->value;
ret[sizeof(ret)-1] = '\0';
if ( mp->name == NULL )
snprintf(ret, sizeof(ret)-1,
@@ -478,5 +480,5 @@ extern char * LookupModuleSymbol(value, sym)
return(ret);
/* It has been a hopeless exercise. */
- return((char *) 0);
+ return(NULL);
}
diff --git a/plugins/imklog/ksyms.h b/plugins/imklog/ksyms.h
index b5362ff3..a168947b 100644
--- a/plugins/imklog/ksyms.h
+++ b/plugins/imklog/ksyms.h
@@ -2,7 +2,7 @@
* Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
* Copyright (c) 1996 Enjellic Systems Development
* Copyright (c) 2004-7 Martin Schulze <joey@infodrom.org>
- * Copyright (c) 2007-2008 Rainer Gerhards <rgerhards@adiscon.com>
+ * Copyright (c) 2007-2009 Rainer Gerhards <rgerhards@adiscon.com>
*
* This file is part of rsyslog.
*
@@ -26,7 +26,7 @@
struct symbol
{
- char *name;
+ uchar *name;
int size;
int offset;
};
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index 5a8a62f6..f0efe1ee 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -3,7 +3,7 @@
*
* File begun on 2007-12-21 by RGerhards (extracted from syslogd.c)
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -56,6 +56,7 @@
#include "dirty.h"
#include "cfsysline.h"
#include "module-template.h"
+#include "unicode-helper.h"
#include "net.h"
#include "netstrm.h"
#include "errmsg.h"
@@ -91,7 +92,7 @@ static int
isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((unused)) *pUsrSrv,
void __attribute__((unused)) *pUsrSess)
{
- return net.isAllowedSender((uchar*) "TCP", addr, fromHostFQDN);
+ return net.isAllowedSender(UCHAR_CONSTANT("TCP"), addr, fromHostFQDN);
}
@@ -169,7 +170,6 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa
CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose));
CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose));
CHKiRet(tcpsrv.SetDrvrMode(pOurTcpsrv, iStrmDrvrMode));
- CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ? (uchar*)"imtcp" : pszInputName));
CHKiRet(tcpsrv.SetAddtlFrameDelim(pOurTcpsrv, iAddtlFrameDelim));
/* now set optional params, but only if they were actually configured */
if(pszStrmDrvrAuthMode != NULL) {
@@ -178,11 +178,14 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa
if(pPermPeersRoot != NULL) {
CHKiRet(tcpsrv.SetDrvrPermPeers(pOurTcpsrv, pPermPeersRoot));
}
- /* most params set, now start listener */
- tcpsrv.configureTCPListen(pOurTcpsrv, (char *) pNewVal);
- CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
}
+dbgprintf("XXX: try add listen port %s\n", pNewVal);
+ /* initialized, now add socket */
+ CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ?
+ UCHAR_CONSTANT("imtcp") : pszInputName));
+ tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal);
+
finalize_it:
if(iRet != RS_RET_OK) {
errmsg.LogError(0, NO_ERRCODE, "error %d trying to add listener", iRet);
@@ -199,7 +202,9 @@ CODESTARTrunInput
/* TODO: we must be careful to start the listener here. Currently, tcpsrv.c seems to
* do that in ConstructFinalize
*/
+ CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
iRet = tcpsrv.Run(pOurTcpsrv);
+finalize_it:
ENDrunInput
@@ -217,7 +222,7 @@ ENDwillRun
BEGINafterRun
CODESTARTafterRun
/* do cleanup here */
- net.clearAllowedSenders((uchar*)"TCP");
+ net.clearAllowedSenders(UCHAR_CONSTANT("TCP"));
ENDafterRun
@@ -277,21 +282,21 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
/* register config file handlers */
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverrun", 0, eCmdHdlrGetWord,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverrun"), 0, eCmdHdlrGetWord,
addTCPListener, NULL, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpmaxsessions", 0, eCmdHdlrInt,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt,
NULL, &iTCPSessMax, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdrivermode", 0,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdrivermode"), 0,
eCmdHdlrInt, NULL, &iStrmDrvrMode, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverauthmode", 0,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverauthmode"), 0,
eCmdHdlrGetWord, NULL, &pszStrmDrvrAuthMode, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverstreamdriverpermittedpeer", 0,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverstreamdriverpermittedpeer"), 0,
eCmdHdlrGetWord, setPermittedPeer, NULL, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserveraddtlframedelimiter", 0, eCmdHdlrInt,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserveraddtlframedelimiter"), 0, eCmdHdlrInt,
NULL, &iAddtlFrameDelim, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputtcpserverinputname", 0,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverinputname"), 0,
eCmdHdlrGetWord, NULL, &pszInputName, STD_LOADABLE_MODULE_ID));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("resetconfigvariables"), 1, eCmdHdlrCustomHandler,
resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index c7e8c1d4..f3448095 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -43,6 +43,7 @@
#include "msg.h"
#include "parser.h"
#include "datetime.h"
+#include "unicode-helper.h"
MODULE_TYPE_INPUT
@@ -219,11 +220,11 @@ processSocket(int fd, struct sockaddr_storage *frominetPrev, int *pbIsPermitted,
CHKmalloc(pMsg->pszRawMsg = malloc(sizeof(uchar)* lenRcvBuf));
memcpy(pMsg->pszRawMsg, pRcvBuf, lenRcvBuf);
pMsg->iLenRawMsg = lenRcvBuf;
- MsgSetInputName(pMsg, "imudp");
+ MsgSetInputName(pMsg, UCHAR_CONSTANT("imudp"));
MsgSetFlowControlType(pMsg, eFLOWCTL_NO_DELAY);
pMsg->msgFlags = NEEDS_PARSING | PARSE_HOSTNAME;
pMsg->bParseHOSTNAME = 1;
- MsgSetRcvFrom(pMsg, (char*)fromHost);
+ MsgSetRcvFrom(pMsg, fromHost);
CHKiRet(MsgSetRcvFromIP(pMsg, fromHostIP));
CHKiRet(submitMsg(pMsg));
}
diff --git a/plugins/omgssapi/omgssapi.c b/plugins/omgssapi/omgssapi.c
index e0cc8af6..361f657f 100644
--- a/plugins/omgssapi/omgssapi.c
+++ b/plugins/omgssapi/omgssapi.c
@@ -444,7 +444,7 @@ CODESTARTdoAction
/* error! */
dbgprintf("error forwarding via tcp, suspending\n");
pData->eDestState = eDestFORW_SUSP;
- iRet = RS_RET_SUSPENDED;
+ ABORT_FINALIZE(RS_RET_SUSPENDED);
}
break;
}
diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c
index ea910d3a..331b7dd4 100644
--- a/plugins/omoracle/omoracle.c
+++ b/plugins/omoracle/omoracle.c
@@ -12,12 +12,48 @@
namely:
$OmoracleDBUser: user name to log in on the database.
+
$OmoracleDBPassword: password to log in on the database.
+
$OmoracleDB: connection string (an Oracle easy connect or a db
name as specified by tnsnames.ora)
-
- All fields are mandatory. The dbstring can be an Oracle easystring
- or a DB name, as present in the tnsnames.ora file.
+
+ $OmoracleBatchSize: Number of elements to send to the DB on each
+ transaction.
+
+ $OmoracleBatchItemSize: Number of characters each property may
+ have. Make it as big as the longest value you expect for *any*
+ property in the sentence. For instance, if you expect 5 arguments
+ to the statement, 4 have 10 bytes and the 5th may be up to 3KB,
+ then specify $OmoracleBatchItemSize 3072. Please, remember to
+ leave space to the trailing \0!!
+
+ $OmoracleStatementTemplate: Name of the template containing the
+ statement to be prepared and executed in batches. Please note that
+ Oracle's prepared statements have their placeholders as
+ ':identifier', and this module uses the colon to guess how many
+ placeholders there will be.
+
+ All these directives are mandatory. The dbstring can be an Oracle
+ easystring or a DB name, as present in the tnsnames.ora file.
+
+ The form of the template is just a list of strings you want
+ inserted to the DB, for instance:
+
+ $template TestStmt,"%hostname%%msg%"
+
+ Will provide the arguments to a statement like
+
+ $OmoracleStatement \
+ insert into foo(hostname,message)values(:host,:message)
+
+ Also note that identifiers to placeholders are arbitrarry. You
+ need to define the properties on the template in the correct order
+ you want them passed to the statement!
+
+ This file is licensed under the terms of the GPL version 3 or, at
+ your choice, any later version. Exceptionally (perhaps), you are
+ allowed to link to the Oracle Call Interface in your derived work
Author: Luis Fernando Muñoz Mejías
<Luis.Fernando.Munoz.Mejias@cern.ch>
@@ -35,6 +71,7 @@
#include <signal.h>
#include <time.h>
#include <assert.h>
+#include <ctype.h>
#include "dirty.h"
#include "syslogd-types.h"
#include "srUtils.h"
@@ -50,6 +87,24 @@ MODULE_TYPE_OUTPUT
DEF_OMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
+/** */
+struct oracle_batch
+{
+ /* Batch size */
+ int size;
+ /* Last element inserted in the buffer. The batch will be
+ * executed when n == size */
+ int n;
+ /* Number of arguments the statement takes */
+ int arguments;
+ /** Maximum size of each parameter */
+ int param_size;
+ /* Parameters to pass to the statement on this transaction */
+ char*** parameters;
+ /* Binding parameters */
+ OCIBind** bindings;
+};
+
typedef struct _instanceData {
/* Environment handler, the base for any OCI work. */
OCIEnv* environment;
@@ -63,10 +118,12 @@ typedef struct _instanceData {
OCISvcCtx* service;
/* Credentials object for the connection. */
OCIAuthInfo* authinfo;
- /* Binding parameters, currently unused */
- OCIBind* binding;
/* Connection string, kept here for possible retries. */
char* connection;
+ /* Statement to be prepared. */
+ char* txt_statement;
+ /* Batch */
+ struct oracle_batch batch;
} instanceData;
/** Database name, to be filled by the $OmoracleDB directive */
@@ -76,6 +133,12 @@ static char* db_name;
static char* db_user;
/** Database password, to be filled by the $OmoracleDBPassword */
static char* db_password;
+/** Batch size. */
+static int batch_size;
+/** Size of each element in the batch. */
+static int batch_item_size;
+/** Statement to prepare and execute */
+static char* db_statement;
/** Generic function for handling errors from OCI.
@@ -128,9 +191,90 @@ static int oci_errors(void* handle, ub4 htype, sword status)
return OCI_ERROR;
}
+/** Callback for OCIBindDynamic.
+ *
+ * OCI doesn't insert an array of char* by itself (although it can
+ * handle arrays of int), so we must either run in batches of size one
+ * (no way) or bind all parameters with OCI_DATA_AT_EXEC instead of
+ * OCI_DEFAULT, and then give this function as an argument to
+ * OCIBindDynamic so that it is able to handle all strings in a single
+ * server trip.
+ *
+ * See the documentation of OCIBindDynamic
+ * (http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28395/oci16rel003.htm#i444015)
+ * for more details.
+ */
+static int bind_dynamic (char** in, OCIBind __attribute__((unused))* bind,
+ int iter, int __attribute__((unused)) idx,
+ char** out, int* buflen, unsigned char* piece,
+ void** bd)
+{
+ *out = in[iter];
+ *buflen = strlen(*out) + 1;
+ dbgprintf ("omoracle bound line %d, length %d: %s\n", iter, *buflen,
+ *out);
+ *piece = OCI_ONE_PIECE;
+ *bd = NULL;
+ return OCI_CONTINUE;
+}
+
+
+/** Returns the number of bind parameters for the statement given as
+ * an argument. It counts the number of appearances of ':', as in
+ *
+ * insert into foo(bar, baz) values(:bar, :baz)
+ *
+ * while taking in account that string literals must not be parsed. */
+static int count_bind_parameters(char* p)
+{
+ int n = 0;
+ int enable = 1;
+
+ for (; *p; p++)
+ if (enable && *p == BIND_MARK )
+ n++;
+ else if (*p == '\'')
+ enable ^= 1;
+ dbgprintf ("omoracle statement has %d parameters\n", n);
+ return n;
+}
+
+/** Prepares the statement, binding all its positional parameters */
+static int prepare_statement(instanceData* pData)
+{
+ int i;
+ DEFiRet;
+
+ CHECKERR(pData->error,
+ OCIStmtPrepare(pData->statement,
+ pData->error,
+ pData->txt_statement,
+ strlen(pData->txt_statement),
+ OCI_NTV_SYNTAX, OCI_DEFAULT));
+ for (i = 0; i < pData->batch.arguments; i++) {
+ CHECKERR(pData->error,
+ OCIBindByPos(pData->statement,
+ pData->batch.bindings+i,
+ pData->error, i+1, NULL,
+ pData->batch.param_size,
+ SQLT_STR, NULL, NULL, NULL,
+ 0, 0, OCI_DATA_AT_EXEC));
+ CHECKERR(pData->error,
+ OCIBindDynamic(pData->batch.bindings[i],
+ pData->error,
+ pData->batch.parameters[i],
+ bind_dynamic, NULL, NULL));
+ }
+
+finalize_it:
+ RETiRet;
+}
+
/* Resource allocation */
BEGINcreateInstance
+ int i, j;
+ struct template* tpl;
CODESTARTcreateInstance
ASSERT(pData != NULL);
@@ -147,15 +291,77 @@ CODESTARTcreateInstance
CHECKENV(pData->environment,
OCIHandleAlloc(pData->environment, (void*) &(pData->statement),
OCI_HTYPE_STMT, 0, NULL));
+ tpl = tplFind(db_statement, strlen(db_statement));
+ pData->txt_statement = strdup(tpl->pEntryRoot->data.constant.pConstant);
+ CHKmalloc(pData->txt_statement);
+ dbgprintf("omoracle will run stored statement: %s\n",
+ pData->txt_statement);
+
+ pData->batch.n = 0;
+ pData->batch.size = batch_size;
+ pData->batch.param_size = batch_item_size *
+ sizeof ***pData->batch.parameters;
+ pData->batch.arguments = count_bind_parameters(pData->txt_statement);
+
+ /* I know, this can be done with a single malloc() call but this is
+ * easier to read. :) */
+ pData->batch.parameters = calloc(pData->batch.arguments,
+ sizeof *pData->batch.parameters);
+ CHKmalloc(pData->batch.parameters);
+ for (i = 0; i < pData->batch.arguments; i++) {
+ pData->batch.parameters[i] = calloc(pData->batch.size,
+ sizeof **pData->batch.parameters);
+ CHKmalloc(pData->batch.parameters[i]);
+ for (j = 0; j < pData->batch.size; j++) {
+ /* Each entry has at most
+ * pData->batch.param_size bytes because OCI
+ * doesn't like null-terminated strings when
+ * operating with batches, and the maximum
+ * size of each entry must be provided when
+ * binding parameters. pData->batch.param_size
+ * is long enough for usual entries. */
+ pData->batch.parameters[i][j] = malloc(pData->batch.param_size);
+ CHKmalloc(pData->batch.parameters[i][j]);
+ }
+ }
+
+ pData->batch.bindings = calloc(pData->batch.arguments,
+ sizeof *pData->batch.bindings);
+ CHKmalloc(pData->batch.bindings);
finalize_it:
ENDcreateInstance
+/* Inserts all stored statements into the database, releasing any
+ * allocated memory. */
+static int insert_to_db(instanceData* pData)
+{
+ DEFiRet;
+
+ CHECKERR(pData->error,
+ OCIStmtExecute(pData->service,
+ pData->statement,
+ pData->error,
+ pData->batch.n, 0, NULL, NULL,
+ OCI_BATCH_ERRORS));
+
+finalize_it:
+ pData->batch.n = 0;
+ OCITransCommit(pData->service, pData->error, 0);
+ dbgprintf ("omoracle insertion to DB %s\n", iRet == RS_RET_OK ?
+ "succeeded" : "did not succeed");
+ RETiRet;
+}
+
/** Close the session and free anything allocated by
createInstance. */
BEGINfreeInstance
+ int i, j;
CODESTARTfreeInstance
+/* Before actually releasing our resources, let's try to commit
+ * anything pending so that we don't lose any messages. */
+ insert_to_db(pData);
OCISessionRelease(pData->service, pData->error, NULL, 0, OCI_DEFAULT);
OCIHandleFree(pData->environment, OCI_HTYPE_ENV);
OCIHandleFree(pData->error, OCI_HTYPE_ERROR);
@@ -163,8 +369,15 @@ CODESTARTfreeInstance
OCIHandleFree(pData->authinfo, OCI_HTYPE_AUTHINFO);
OCIHandleFree(pData->statement, OCI_HTYPE_STMT);
free(pData->connection);
+ free(pData->txt_statement);
+ for (i = 0; i < pData->batch.arguments; i++) {
+ for (j = 0; j < pData->batch.size; j++)
+ free(pData->batch.parameters[i][j]);
+ free(pData->batch.parameters[i]);
+ }
+ free(pData->batch.parameters);
+ free(pData->batch.bindings);
dbgprintf ("omoracle freed all its resources\n");
- RETiRet;
ENDfreeInstance
@@ -190,7 +403,7 @@ CODESTARTtryResume
* ... of course I don't know why Oracle might need a full restart...
* rgerhards, 2009-03-26
*/
- dbgprintf("Attempting to reconnect to DB server\n");
+ dbgprintf("omoracle attempting to reconnect to DB server\n");
OCISessionRelease(pData->service, pData->error, NULL, 0, OCI_DEFAULT);
OCIHandleFree(pData->service, OCI_HTYPE_SVCCTX);
CHECKERR(pData->error, OCISessionGet(pData->environment, pData->error,
@@ -198,6 +411,7 @@ CODESTARTtryResume
pData->connection,
strlen(pData->connection), NULL, 0,
NULL, NULL, NULL, OCI_DEFAULT));
+ CHKiRet(prepare_statement(pData));
finalize_it:
ENDtryResume
@@ -228,12 +442,10 @@ finalize_it:
BEGINisCompatibleWithFeature
CODESTARTisCompatibleWithFeature
/* Right now, this module is compatible with nothing. */
- dbgprintf ("***** OMORACLE ***** At isCompatibleWithFeature\n");
iRet = RS_RET_INCOMPATIBLE;
ENDisCompatibleWithFeature
BEGINparseSelectorAct
-
CODESTARTparseSelectorAct
CODE_STD_STRING_REQUESTparseSelectorAct(1);
@@ -251,11 +463,13 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1);
}
CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0,
- OMSR_RQD_TPL_OPT_SQL, " StdFmt"));
+ OMSR_TPL_AS_ARRAY, " StdFmt"));
CHKiRet(createInstance(&pData));
CHKmalloc(pData->connection = strdup(db_name));
CHKiRet(startSession(pData, db_name, db_user, db_password));
-
+
+ CHKiRet(prepare_statement(pData));
+
dbgprintf ("omoracle module got all its resources allocated "
"and connected to the DB\n");
@@ -263,21 +477,24 @@ CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
BEGINdoAction
+ int i;
+ char **params = (char**) ppString[0];
CODESTARTdoAction
- dbgprintf("omoracle attempting to execute statement %s\n", *ppString);
- CHECKERR(pData->error,
- OCIStmtPrepare(pData->statement, pData->error, *ppString,
- strlen(*ppString), OCI_NTV_SYNTAX,
- OCI_DEFAULT));
- CHECKERR(pData->error,
- OCIStmtExecute(pData->service, pData->statement, pData->error,
- 1, 0, NULL, NULL, OCI_DEFAULT));
- CHECKERR(pData->error,
- OCITransCommit(pData->service, pData->error, 0));
+
+ if (pData->batch.n == pData->batch.size) {
+ dbgprintf("omoracle batch size limit hit, sending into DB\n");
+ CHKiRet(insert_to_db(pData));
+ }
+
+ for (i = 0; i < pData->batch.arguments && params[i]; i++) {
+ dbgprintf("batch[%d][%d]=%s\n", i, pData->batch.n, params[i]);
+ strncpy(pData->batch.parameters[i][pData->batch.n], params[i],
+ pData->batch.param_size);
+ CHKmalloc(pData->batch.parameters[i][pData->batch.n]);
+ }
+ pData->batch.n++;
+
finalize_it:
- dbgprintf ("omoracle %s at executing statement %s\n",
- iRet?"did not succeed":"succeeded", *ppString);
-/* Clean credentials to avoid leakage in case of core dump. */
ENDdoAction
BEGINmodExit
@@ -309,19 +526,24 @@ resetConfigVariables(uchar __attribute__((unused)) *pp,
memset(db_password, 0, n);
free(db_password);
}
- db_name = db_user = db_password = NULL;
+ if (db_statement != NULL)
+ free(db_statement);
+ db_name = db_user = db_password = db_statement = NULL;
+ batch_size = batch_item_size = 0;
RETiRet;
}
BEGINmodInit()
+ rsRetVal (*supported_options)(unsigned long *pOpts);
+ unsigned long opts;
CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION;
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
- /* CHKiRet(omsdRegCFSLineHdlr((uchar*)"actionomoracle", */
CHKiRet(omsdRegCFSLineHdlr((uchar*) "resetconfigvariables", 1,
eCmdHdlrCustomHandler, resetConfigVariables,
NULL, STD_LOADABLE_MODULE_ID));
+
CHKiRet(omsdRegCFSLineHdlr((uchar*) "omoracledbuser", 0,
eCmdHdlrGetWord, NULL, &db_user,
STD_LOADABLE_MODULE_ID));
@@ -331,4 +553,20 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(omsdRegCFSLineHdlr((uchar*) "omoracledb", 0,
eCmdHdlrGetWord, NULL, &db_name,
STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar*) "omoraclebatchsize", 0,
+ eCmdHdlrInt, NULL, &batch_size,
+ STD_LOADABLE_MODULE_ID));
+ CHKiRet(pHostQueryEtryPt((uchar*)"OMSRgetSupportedTplOpts", &supported_options));
+ CHKiRet((*supported_options)(&opts));
+ if (!(opts & OMSR_TPL_AS_ARRAY))
+ ABORT_FINALIZE(RS_RET_RSCORE_TOO_OLD);
+
+ CHKiRet(omsdRegCFSLineHdlr((uchar*) "omoraclestatementtemplate", 0,
+ eCmdHdlrGetWord, NULL,
+ &db_statement, STD_LOADABLE_MODULE_ID));
+
+ CHKiRet(omsdRegCFSLineHdlr((uchar*) "omoraclebatchitemsize", 0,
+ eCmdHdlrInt, NULL,
+ &batch_item_size, STD_LOADABLE_MODULE_ID));
+
ENDmodInit
diff --git a/plugins/omoracle/omoracle.h b/plugins/omoracle/omoracle.h
index b0e70917..0ff879b3 100644
--- a/plugins/omoracle/omoracle.h
+++ b/plugins/omoracle/omoracle.h
@@ -3,6 +3,12 @@
This module needs OCI to be installed (on Red Hat-like systems
this is usually the oracle-instantclient-devel RPM).
+ This file is part of rsyslog.
+
+ This file is licensed under the terms of the GPL version 3 or, at
+ your choice, any later version. Exceptionally (perhaps), you are
+ allowed to link to the Oracle Call Interface in your derived work
+
Author: Luis Fernando Muñoz Mejías <Luis.Fernando.Munoz.Mejias@cern.ch>
*/
#ifndef __OMORACLEH__
@@ -20,4 +26,6 @@
enum { MAX_BUFSIZE = 2048 };
+#define BIND_MARK ':'
+
#endif
diff --git a/plugins/ompgsql/ompgsql.c b/plugins/ompgsql/ompgsql.c
index 7658f036..6daac1c7 100644
--- a/plugins/ompgsql/ompgsql.c
+++ b/plugins/ompgsql/ompgsql.c
@@ -6,7 +6,11 @@
*
* File begun on 2007-10-18 by sur5r (converted from ommysql.c)
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2009 Rainer Gerhards and Adiscon GmbH.
+ *
+ * The following link my be useful for the not-so-postgres literate
+ * when setting up a test environment (on Fedora):
+ * http://www.jboss.org/community/wiki/InstallPostgreSQLonFedora
*
* This file is part of rsyslog.
*
@@ -154,26 +158,55 @@ static rsRetVal initPgSQL(instanceData *pData, int bSilent)
}
+/* try the insert into postgres and return if that failed or not
+ * (1 = had error, 0=ok). We do not use the standard IRET calling convention
+ * rgerhards, 2009-04-17
+ */
+static inline int
+tryExec(uchar *pszCmd, instanceData *pData)
+{
+ PGresult *pgRet;
+ ExecStatusType execState;
+ int bHadError = 0;
+
+ /* try insert */
+ pgRet = PQexec(pData->f_hpgsql, (char*)pszCmd);
+ execState = PQresultStatus(pgRet);
+ if(execState != PGRES_COMMAND_OK && execState != PGRES_TUPLES_OK) {
+ dbgprintf("postgres query execution failed: %s\n", PQresStatus(PQresultStatus(pgRet)));
+ bHadError = 1;
+ }
+ PQclear(pgRet);
+
+ return(bHadError);
+}
+
+
/* The following function writes the current log entry
* to an established PgSQL session.
+ * Enhanced function to take care of the returned error
+ * value (if there is such). Note that this may happen due to
+ * a sql format error - connection aborts were properly handled
+ * before my patch. -- rgerhards, 2009-04-17
*/
rsRetVal writePgSQL(uchar *psz, instanceData *pData)
{
+ int bHadError = 0;
DEFiRet;
assert(psz != NULL);
assert(pData != NULL);
- dbgprintf("writePgSQL: %s", psz);
+ dbgprintf("writePgSQL: %s\n", psz);
- /* try insert */
- PQclear(PQexec(pData->f_hpgsql, (char*)psz));
- if(PQstatus(pData->f_hpgsql) != CONNECTION_OK) {
+ bHadError = tryExec(psz, pData); /* try insert */
+
+ if(bHadError || (PQstatus(pData->f_hpgsql) != CONNECTION_OK)) {
/* error occured, try to re-init connection and retry */
closePgSQL(pData); /* close the current handle */
CHKiRet(initPgSQL(pData, 0)); /* try to re-open */
- PQclear(PQexec(pData->f_hpgsql, (char*)psz));
- if(PQstatus(pData->f_hpgsql) != CONNECTION_OK) { /* re-try insert */
+ bHadError = tryExec(psz, pData); /* retry */
+ if(bHadError || (PQstatus(pData->f_hpgsql) != CONNECTION_OK)) {
/* we failed, giving up for now */
reportDBError(pData, 0);
closePgSQL(pData); /* free ressources */
@@ -290,6 +323,5 @@ CODESTARTmodInit
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
ENDmodInit
-/*
- * vi:set ai:
+/* vi:set ai:
*/