summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/im3195/im3195.c3
-rw-r--r--plugins/imgssapi/imgssapi.c1
-rw-r--r--plugins/imklog/ksym_mod.c42
-rw-r--r--plugins/imklog/ksyms.h4
-rw-r--r--plugins/omdtn/Makefile.am8
-rw-r--r--plugins/omdtn/omdtn.c130
-rw-r--r--plugins/omgssapi/omgssapi.c2
-rw-r--r--plugins/omoracle/Makefile.am8
-rw-r--r--plugins/omoracle/omoracle.c569
-rw-r--r--plugins/omoracle/omoracle.h25
-rw-r--r--plugins/omoracle/omoracle.te13
-rw-r--r--plugins/omprog/Makefile.am8
-rw-r--r--plugins/omprog/omprog.c357
-rw-r--r--plugins/omstdout/omstdout.c2
14 files changed, 1008 insertions, 164 deletions
diff --git a/plugins/im3195/im3195.c b/plugins/im3195/im3195.c
index 1c2502fe..106da2c8 100644
--- a/plugins/im3195/im3195.c
+++ b/plugins/im3195/im3195.c
@@ -47,6 +47,7 @@
#include "liblogging/syslogmessage.h"
#include "module-template.h"
#include "cfsysline.h"
+#include "msg.h"
#include "errmsg.h"
MODULE_TYPE_INPUT
@@ -83,7 +84,7 @@ void OnReceive(srAPIObj __attribute__((unused)) *pMyAPI, srSLMGObj* pSLMG)
srSLMGGetRawMSG(pSLMG, &pszRawMsg);
parseAndSubmitMessage(fromHost, fromHostIP, pszRawMsg, strlen((char*)pszRawMsg),
- MSG_PARSE_HOSTNAME, NOFLAG, eFLOWCTL_FULL_DELAY, (uchar*)"im3195");
+ PARSE_HOSTNAME, eFLOWCTL_FULL_DELAY, (uchar*)"im3195", NULL, 0);
}
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index debe935e..b9d7dfe3 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -249,7 +249,6 @@ onErrClose(tcps_sess_t *pSess)
static rsRetVal
doOpenLstnSocks(tcpsrv_t *pSrv)
{
- int *pRet = NULL;
gsssrv_t *pGSrv;
DEFiRet;
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/omdtn/Makefile.am b/plugins/omdtn/Makefile.am
deleted file mode 100644
index afb57476..00000000
--- a/plugins/omdtn/Makefile.am
+++ /dev/null
@@ -1,8 +0,0 @@
-pkglib_LTLIBRARIES = omdtn.la
-
-omdtn_la_SOURCES = omdtn.c
-omdtn_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS)
-omdtn_la_LDFLAGS = -module -avoid-version
-omdtn_la_LIBADD =
-
-EXTRA_DIST =
diff --git a/plugins/omdtn/omdtn.c b/plugins/omdtn/omdtn.c
deleted file mode 100644
index 761bde79..00000000
--- a/plugins/omdtn/omdtn.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/* omdtn.c
- * This is the plugin for rsyslog use in the interplanetary Internet,
- * especially useful for rsyslog in space ships of all kinds.
- * The core idea was introduced in early 2009 and considered
- * doable.
- *
- * Note that this has not yet been tested for robustness but needs
- * to prior to placing it on top of a rocket.
- *
- * NOTE: read comments in module-template.h for more specifics!
- *
- * File begun on 2009-04-01 by RGerhards
- *
- * Copyright 2009 Rainer Gerhards and Adiscon GmbH.
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#include "config.h"
-#include "rsyslog.h"
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <signal.h>
-#include <errno.h>
-#include <unistd.h>
-#include "dirty.h"
-#include "syslogd-types.h"
-#include "srUtils.h"
-#include "template.h"
-#include "module-template.h"
-#include "errmsg.h"
-#include "cfsysline.h"
-
-MODULE_TYPE_OUTPUT
-
-/* internal structures
- */
-DEF_OMOD_STATIC_DATA
-
-typedef struct _instanceData {
-} instanceData;
-
-BEGINcreateInstance
-CODESTARTcreateInstance
-ENDcreateInstance
-
-
-BEGINisCompatibleWithFeature
-CODESTARTisCompatibleWithFeature
- if(eFeat == sFEATURERepeatedMsgReduction)
- iRet = RS_RET_OK;
-ENDisCompatibleWithFeature
-
-
-BEGINfreeInstance
-CODESTARTfreeInstance
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
-ENDdbgPrintInstInfo
-
-
-BEGINtryResume
-CODESTARTtryResume
-ENDtryResume
-
-BEGINdoAction
-CODESTARTdoAction
- write(1, (char*)ppString[0], strlen((char*)ppString[0]));
-ENDdoAction
-
-
-BEGINparseSelectorAct
-CODESTARTparseSelectorAct
-CODE_STD_STRING_REQUESTparseSelectorAct(1)
- /* first check if this config line is actually for us */
- if(strncmp((char*) p, ":omstdout:", sizeof(":omstdout:") - 1)) {
- ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
- }
-
- /* ok, if we reach this point, we have something for us */
- p += sizeof(":omstdout:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
- CHKiRet(createInstance(&pData));
-
- /* check if a non-standard template is to be applied */
- if(*(p-1) == ';')
- --p;
- CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, (uchar*) "RSYSLOG_FileFormat"));
-CODE_STD_FINALIZERparseSelectorAct
-ENDparseSelectorAct
-
-
-BEGINmodExit
-CODESTARTmodExit
-ENDmodExit
-
-
-BEGINqueryEtryPt
-CODESTARTqueryEtryPt
-CODEqueryEtryPt_STD_OMOD_QUERIES
-ENDqueryEtryPt
-
-
-BEGINmodInit()
-CODESTARTmodInit
- *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
-CODEmodInit_QueryRegCFSLineHdlr
-ENDmodInit
-
-/* vi:set ai:
- */
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/Makefile.am b/plugins/omoracle/Makefile.am
new file mode 100644
index 00000000..11257fb2
--- /dev/null
+++ b/plugins/omoracle/Makefile.am
@@ -0,0 +1,8 @@
+pkglib_LTLIBRARIES = omoracle.la
+
+omoracle_la_SOURCES = omoracle.c omoracle.h
+omoracle_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(ORACLE_CFLAGS)
+omoracle_la_LDFLAGS = -module -avoid-version
+omoracle_la_LIBADD = $(ORACLE_LIBS)
+
+#EXTRA_DIST =
diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c
new file mode 100644
index 00000000..71cc8e1f
--- /dev/null
+++ b/plugins/omoracle/omoracle.c
@@ -0,0 +1,569 @@
+/** omoracle.c
+
+ This is an output module feeding directly to an Oracle
+ database. It uses Oracle Call Interface, a propietary module
+ provided by Oracle.
+
+ Selector lines to be used are of this form:
+
+ :omoracle:;TemplateName
+
+ The module gets its configuration via rsyslog $... directives,
+ 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)
+
+ $OmoracleBatchSize: Number of elements to send to the DB on each
+ transaction.
+
+ $OmoracleStatement: 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!
+
+ Author: Luis Fernando Muñoz Mejías
+ <Luis.Fernando.Munoz.Mejias@cern.ch>
+
+ This file is part of rsyslog.
+*/
+#include "config.h"
+#include "rsyslog.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <oci.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <time.h>
+#include <assert.h>
+#include <ctype.h>
+#include "dirty.h"
+#include "syslogd-types.h"
+#include "srUtils.h"
+#include "template.h"
+#include "module-template.h"
+#include "errmsg.h"
+#include "cfsysline.h"
+#include "omoracle.h"
+
+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;
+ /* 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;
+ /* Session handler, the actual DB connection object. */
+ OCISession* session;
+ /* Error handler for OCI calls. */
+ OCIError* error;
+ /* Prepared statement. */
+ OCIStmt* statement;
+ /* Service handler. */
+ OCISvcCtx* service;
+ /* Credentials object for the connection. */
+ OCIAuthInfo* authinfo;
+ /* 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 */
+static char* db_name;
+/** Database user name, to be filled by the $OmoracleDBUser
+ * directive */
+static char* db_user;
+/** Database password, to be filled by the $OmoracleDBPassword */
+static char* db_password;
+/** Batch size. */
+static int batch_size;
+/** Statement to prepare and execute */
+static char* db_statement;
+/** Whether or not the core supports the newer array interface. The
+ * module is able to work in both modes, but the newer is the
+ * recommended one for performance reasons. */
+static int array_passing;
+
+/** Generic function for handling errors from OCI.
+
+ It will be called only inside CHECKERR and CHECKENV macros.
+
+ Arguments: handle The error or environment handle to check.
+ htype: OCI_HTYPE_* constant, usually OCI_HTYPE_ERROR or
+ OCI_HTYPE_ENV
+ status: status code to check, usually the return value of an OCI
+ function.
+
+ Returns OCI_SUCCESS on success, OCI_ERROR otherwise.
+*/
+static int oci_errors(void* handle, ub4 htype, sword status)
+{
+ sb4 errcode;
+ unsigned char buf[MAX_BUFSIZE];
+
+ switch (status) {
+ case OCI_SUCCESS:
+ return OCI_SUCCESS;
+ break;
+ case OCI_SUCCESS_WITH_INFO:
+ errmsg.LogError(0, NO_ERRCODE, "OCI SUCCESS - With info\n");
+ break;
+ case OCI_NEED_DATA:
+ errmsg.LogError(0, NO_ERRCODE, "OCI NEEDS MORE DATA\n");
+ break;
+ case OCI_ERROR:
+ dbgprintf ("OCI GENERAL ERROR\n");
+ if (handle) {
+ OCIErrorGet(handle, 1, NULL, &errcode, buf,
+ sizeof buf, htype);
+ errmsg.LogError(0, NO_ERRCODE, "Error message: %s", buf);
+ } else
+ errmsg.LogError(0, NO_ERRCODE, "NULL handle\n"
+ "Unable to extract further "
+ "information");
+ break;
+ case OCI_INVALID_HANDLE:
+ errmsg.LogError(0, NO_ERRCODE, "OCI INVALID HANDLE\n");
+ break;
+ case OCI_STILL_EXECUTING:
+ errmsg.LogError(0, NO_ERRCODE, "Still executing...\n");
+ break;
+ case OCI_CONTINUE:
+ errmsg.LogError(0, NO_ERRCODE, "OCI CONTINUE\n");
+ break;
+ }
+ 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,
+ MAX_BUFSIZE *
+ sizeof ***pData->batch.parameters,
+ 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;
+CODESTARTcreateInstance
+
+ ASSERT(pData != NULL);
+
+ CHECKENV(pData->environment,
+ OCIEnvCreate((void*) &(pData->environment), OCI_DEFAULT,
+ NULL, NULL, NULL, NULL, 0, NULL));
+ CHECKENV(pData->environment,
+ OCIHandleAlloc(pData->environment, (void*) &(pData->error),
+ OCI_HTYPE_ERROR, 0, NULL));
+ CHECKENV(pData->environment,
+ OCIHandleAlloc(pData->environment, (void*) &(pData->authinfo),
+ OCI_HTYPE_AUTHINFO, 0, NULL));
+ CHECKENV(pData->environment,
+ OCIHandleAlloc(pData->environment, (void*) &(pData->statement),
+ OCI_HTYPE_STMT, 0, NULL));
+ pData->txt_statement = strdup(db_statement);
+ 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.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 MAX_BUFSIZE 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. MAX_BUFSIZE is long enough for
+ * usual entries. */
+ pData->batch.parameters[i][j] = calloc(MAX_BUFSIZE,
+ sizeof ***pData->batch.parameters);
+ 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_DEFAULT));
+
+ CHECKERR(pData->error,
+ OCITransCommit(pData->service, pData->error, 0));
+
+ pData->batch.n = 0;
+finalize_it:
+ 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);
+ OCIHandleFree(pData->service, OCI_HTYPE_SVCCTX);
+ 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");
+
+ENDfreeInstance
+
+BEGINtryResume
+CODESTARTtryResume
+ /* Here usually only a reconnect is done. The rsyslog core will call
+ * this entry point from time to time when the action suspended itself.
+ * Note that the rsyslog core expects that if the plugin suspended itself
+ * the action was not carried out during that invocation. Thus, rsyslog
+ * will call the action with *the same* data item again AFTER a resume
+ * was successful. As such, tryResume should NOT write the failed data
+ * item. If it needs to for some reason, it must delete the item again,
+ * otherwise, it will get duplicated.
+ * This handling inside the rsyslog core is important to be able to
+ * preserve data over rsyslog restarts. With it, the core can ensure that
+ * it queues all not-yet-processed messages without the plugin needing
+ * to take care about that.
+ * So in essence, it is recommended that just a reconnet is tried, but
+ * the last action not restarted. Note that it is not a real problem
+ * (but causes a slight performance degradation) if tryResume returns
+ * successfully but the next call to doAction() immediately returns
+ * RS_RET_SUSPENDED. So it is OK to do the actual restart inside doAction().
+ * ... of course I don't know why Oracle might need a full restart...
+ * rgerhards, 2009-03-26
+ */
+ 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,
+ &pData->service, pData->authinfo,
+ pData->connection,
+ strlen(pData->connection), NULL, 0,
+ NULL, NULL, NULL, OCI_DEFAULT));
+ CHKiRet(prepare_statement(pData));
+
+finalize_it:
+ENDtryResume
+
+static rsRetVal startSession(instanceData* pData, char* connection, char* user,
+ char * password)
+{
+ DEFiRet;
+ CHECKERR(pData->error,
+ OCIAttrSet(pData->authinfo, OCI_HTYPE_AUTHINFO, user,
+ strlen(user), OCI_ATTR_USERNAME, pData->error));
+ CHECKERR(pData->error,
+ OCIAttrSet(pData->authinfo, OCI_HTYPE_AUTHINFO, password,
+ strlen(password), OCI_ATTR_PASSWORD, pData->error));
+ CHECKERR(pData->error,
+ OCISessionGet(pData->environment, pData->error,
+ &pData->service, pData->authinfo, connection,
+ strlen(connection), NULL, 0, NULL, NULL, NULL,
+ OCI_DEFAULT));
+finalize_it:
+ if (iRet != RS_RET_OK)
+ errmsg.LogError(0, NO_ERRCODE,
+ "Unable to start Oracle session\n");
+ RETiRet;
+}
+
+
+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);
+
+ if (strncmp((char*) p, ":omoracle:", sizeof ":omoracle:" - 1)) {
+ ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
+ }
+
+ p += sizeof ":omoracle:" - 1;
+
+ if (*p == '\0' || *p == ',') {
+ errmsg.LogError(0, NO_ERRCODE,
+ "Wrong char processing module arguments: %c\n",
+ *p);
+ ABORT_FINALIZE(RS_RET_INVALID_PARAMS);
+ }
+
+ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0,
+ 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");
+
+CODE_STD_FINALIZERparseSelectorAct
+ENDparseSelectorAct
+
+BEGINdoAction
+ int i;
+ char **params = (char**) ppString[0];
+CODESTARTdoAction
+
+ 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],
+ MAX_BUFSIZE);
+ CHKmalloc(pData->batch.parameters[i][pData->batch.n]);
+ }
+ pData->batch.n++;
+
+finalize_it:
+ENDdoAction
+
+BEGINmodExit
+CODESTARTmodExit
+ENDmodExit
+
+BEGINdbgPrintInstInfo
+CODESTARTdbgPrintInstInfo
+ENDdbgPrintInstInfo
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
+
+static rsRetVal
+resetConfigVariables(uchar __attribute__((unused)) *pp,
+ void __attribute__((unused)) *pVal)
+{
+ int n;
+ DEFiRet;
+ if(db_user != NULL)
+ free(db_user);
+ if(db_name != NULL)
+ free(db_name);
+ if (db_password != NULL) {
+ n = strlen(db_password);
+ memset(db_password, 0, n);
+ free(db_password);
+ }
+ if (db_statement != NULL)
+ free(db_statement);
+ db_name = db_user = db_password = db_statement = NULL;
+ RETiRet;
+}
+
+/** As I don't find any handler that reads an entire line, I write my
+ * own. */
+static int get_db_statement(char** line, char** stmt)
+{
+ DEFiRet;
+
+ while (isspace(**line))
+ (*line)++;
+ dbgprintf ("Config line: %s\n", *line);
+ *stmt = strdup(*line);
+ CHKmalloc(*stmt);
+ dbgprintf ("Statement: %s\n", *stmt);
+finalize_it:
+ 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*) "resetconfigvariables", 1,
+ eCmdHdlrCustomHandler, resetConfigVariables,
+ NULL, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar*) "omoracledbuser", 0,
+ eCmdHdlrGetWord, NULL, &db_user,
+ STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar*) "omoracledbpassword", 0,
+ eCmdHdlrGetWord, NULL, &db_password,
+ STD_LOADABLE_MODULE_ID));
+ 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 (!(array_passing = opts & OMSR_TPL_AS_ARRAY))
+ ABORT_FINALIZE(RS_RET_RSCORE_TOO_OLD);
+
+ CHKiRet(omsdRegCFSLineHdlr((uchar*) "omoraclestatement", 0,
+ eCmdHdlrCustomHandler, get_db_statement,
+ &db_statement, STD_LOADABLE_MODULE_ID));
+
+ENDmodInit
diff --git a/plugins/omoracle/omoracle.h b/plugins/omoracle/omoracle.h
new file mode 100644
index 00000000..92bcacab
--- /dev/null
+++ b/plugins/omoracle/omoracle.h
@@ -0,0 +1,25 @@
+/** Definitions for the Oracle output module.
+
+ This module needs OCI to be installed (on Red Hat-like systems
+ this is usually the oracle-instantclient-devel RPM).
+
+ Author: Luis Fernando Muñoz Mejías <Luis.Fernando.Munoz.Mejias@cern.ch>
+*/
+#ifndef __OMORACLEH__
+#define __OMORACLEH__
+
+/** Macros to make error handling easier. */
+
+/** Checks for errors on the OCI handling. */
+#define CHECKERR(handle,status) CHKiRet(oci_errors((handle), \
+ OCI_HTYPE_ERROR, (status)))
+
+/** Checks for errors when handling the environment of OCI. */
+#define CHECKENV(handle,status) CHKiRet(oci_errors((handle), \
+ OCI_HTYPE_ENV, (status)))
+
+enum { MAX_BUFSIZE = 2048 };
+
+#define BIND_MARK ':'
+
+#endif
diff --git a/plugins/omoracle/omoracle.te b/plugins/omoracle/omoracle.te
new file mode 100644
index 00000000..81eb6cf1
--- /dev/null
+++ b/plugins/omoracle/omoracle.te
@@ -0,0 +1,13 @@
+
+module omoracle 1.0;
+
+require {
+ type syslogd_t;
+ type port_t;
+ class process { execstack execmem };
+ class tcp_socket name_connect;
+}
+
+#============= syslogd_t ==============
+allow syslogd_t port_t:tcp_socket name_connect;
+allow syslogd_t self:process { execstack execmem };
diff --git a/plugins/omprog/Makefile.am b/plugins/omprog/Makefile.am
new file mode 100644
index 00000000..63fe09b8
--- /dev/null
+++ b/plugins/omprog/Makefile.am
@@ -0,0 +1,8 @@
+pkglib_LTLIBRARIES = omprog.la
+
+omprog_la_SOURCES = omprog.c
+omprog_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS)
+omprog_la_LDFLAGS = -module -avoid-version
+omprog_la_LIBADD =
+
+EXTRA_DIST =
diff --git a/plugins/omprog/omprog.c b/plugins/omprog/omprog.c
new file mode 100644
index 00000000..2a078a6d
--- /dev/null
+++ b/plugins/omprog/omprog.c
@@ -0,0 +1,357 @@
+/* omprog.c
+ * This output plugin enables rsyslog to execute a program and
+ * feed it the message stream as standard input.
+ *
+ * NOTE: read comments in module-template.h for more specifics!
+ *
+ * File begun on 2009-04-01 by RGerhards
+ *
+ * Copyright 2009 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+#include "rsyslog.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <wait.h>
+#include "dirty.h"
+#include "syslogd-types.h"
+#include "srUtils.h"
+#include "template.h"
+#include "module-template.h"
+#include "errmsg.h"
+#include "cfsysline.h"
+
+MODULE_TYPE_OUTPUT
+
+/* internal structures
+ */
+DEF_OMOD_STATIC_DATA
+DEFobjCurrIf(errmsg)
+
+typedef struct _instanceData {
+ uchar *szBinary; /* name of binary to call */
+ pid_t pid; /* pid of currently running process */
+ int fdPipe; /* file descriptor to write to */
+ int bIsRunning; /* is binary currently running? 0-no, 1-yes */
+} instanceData;
+
+/* config settings */
+static uchar *szBinary = NULL; /* name of binary to call */
+
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ if(eFeat == sFEATURERepeatedMsgReduction)
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
+
+
+BEGINfreeInstance
+CODESTARTfreeInstance
+ if(pData->szBinary != NULL)
+ free(pData->szBinary);
+ENDfreeInstance
+
+
+BEGINdbgPrintInstInfo
+CODESTARTdbgPrintInstInfo
+ENDdbgPrintInstInfo
+
+
+BEGINtryResume
+CODESTARTtryResume
+ENDtryResume
+
+
+/* execute the child process (must be called in child context
+ * after fork).
+ */
+
+static void execBinary(instanceData *pData, int fdStdin)
+{
+ int i;
+ struct sigaction sigAct;
+ char *newargv[] = { NULL };
+ char *newenviron[] = { NULL };
+
+ assert(pData != NULL);
+
+ fclose(stdin);
+ dup(fdStdin);
+ //fclose(stdout);
+
+ /* we close all file handles as we fork soon
+ * Is there a better way to do this? - mail me! rgerhards@adiscon.com
+ */
+# ifndef VALGRIND /* we can not use this with valgrind - too many errors... */
+ for(i = 3 ; i <= 65535 ; ++i)
+ close(i);
+# endif
+
+ /* reset signal handlers to default */
+ memset(&sigAct, 0, sizeof(sigAct));
+ sigfillset(&sigAct.sa_mask);
+ sigAct.sa_handler = SIG_DFL;
+ for(i = 1 ; i < NSIG ; ++i)
+ sigaction(i, &sigAct, NULL);
+
+ alarm(0);
+
+ /* finally exec child */
+ execve((char*)pData->szBinary, newargv, newenviron);
+ /* switch to?
+ execlp((char*)program, (char*) program, (char*)arg, NULL);
+ */
+
+ /* we should never reach this point, but if we do, we terminate */
+ exit(1);
+}
+
+
+/* creates a pipe and starts program, uses pipe as stdin for program.
+ * rgerhards, 2009-04-01
+ */
+static rsRetVal
+openPipe(instanceData *pData)
+{
+ int pipefd[2];
+ pid_t cpid;
+ DEFiRet;
+
+ assert(pData != NULL);
+
+ if(pipe(pipefd) == -1) {
+ ABORT_FINALIZE(RS_RET_ERR_CREAT_PIPE);
+ }
+
+ DBGPRINTF("executing program '%s'\n", pData->szBinary);
+
+ /* NO OUTPUT AFTER FORK! */
+
+ cpid = fork();
+ if(cpid == -1) {
+ ABORT_FINALIZE(RS_RET_ERR_FORK);
+ }
+
+ if(cpid == 0) {
+ /* we are now the child, just set the right selectors and
+ * exec the binary. If that fails, there is not much we can do.
+ */
+ close(pipefd[1]);
+ execBinary(pData, pipefd[0]);
+ /*NO CODE HERE - WILL NEVER BE REACHED!*/
+ }
+
+ DBGPRINTF("child has pid %d\n", cpid);
+ pData->fdPipe = pipefd[1];
+ pData->pid = cpid;
+ close(pipefd[0]);
+ pData->bIsRunning = 1;
+finalize_it:
+ RETiRet;
+}
+
+
+/* clean up after a terminated child
+ */
+static inline rsRetVal
+cleanup(instanceData *pData)
+{
+ int status;
+ int ret;
+ char errStr[1024];
+ DEFiRet;
+
+ assert(pData != NULL);
+ assert(pData->bIsRunning == 1);
+RUNLOG_VAR("%d", pData->pid);
+ ret = waitpid(pData->pid, &status, 0);
+ if(ret != pData->pid) {
+ /* if waitpid() fails, we can not do much - try to ignore it... */
+ DBGPRINTF("waitpid() returned state %d[%s], future malfunction may happen\n", ret,
+ rs_strerror_r(errno, errStr, sizeof(errStr)));
+ } else {
+ /* check if we should print out some diagnostic information */
+ DBGPRINTF("waitpid status return for program '%s': %2.2x\n",
+ pData->szBinary, status);
+ if(WIFEXITED(status)) {
+ errmsg.LogError(0, NO_ERRCODE, "program '%s' exited normally, state %d",
+ pData->szBinary, WEXITSTATUS(status));
+ } else if(WIFSIGNALED(status)) {
+ errmsg.LogError(0, NO_ERRCODE, "program '%s' terminated by signal %d.",
+ pData->szBinary, WTERMSIG(status));
+ }
+ }
+
+ pData->bIsRunning = 0;
+ RETiRet;
+}
+
+
+/* try to restart the binary when it has stopped.
+ */
+static inline rsRetVal
+tryRestart(instanceData *pData)
+{
+ DEFiRet;
+ assert(pData != NULL);
+ assert(pData->bIsRunning == 0);
+
+ iRet = openPipe(pData);
+ RETiRet;
+}
+
+
+/* write to pipe
+ * note that we do not try to run block-free. If the users fears something
+ * may block (and this not be acceptable), the action should be run on its
+ * own action queue.
+ */
+static rsRetVal
+writePipe(instanceData *pData, uchar *szMsg)
+{
+ int lenWritten;
+ int lenWrite;
+ int writeOffset;
+ char errStr[1024];
+ DEFiRet;
+
+ assert(pData != NULL);
+
+ lenWrite = strlen((char*)szMsg);
+ writeOffset = 0;
+
+ do
+ {
+ lenWritten = write(pData->fdPipe, ((char*)szMsg)+writeOffset, lenWrite);
+ if(lenWritten == -1) {
+ switch(errno) {
+ case EPIPE:
+ DBGPRINTF("Program '%s' terminated, trying to restart\n",
+ pData->szBinary);
+ CHKiRet(cleanup(pData));
+ CHKiRet(tryRestart(pData));
+ break;
+ default:
+ DBGPRINTF("error %d writing to pipe: %s\n", errno,
+ rs_strerror_r(errno, errStr, sizeof(errStr)));
+ ABORT_FINALIZE(RS_RET_ERR_WRITE_PIPE);
+ break;
+ }
+ } else {
+ writeOffset += lenWritten;
+ }
+ } while(lenWritten != lenWrite);
+
+
+finalize_it:
+ RETiRet;
+}
+
+
+BEGINdoAction
+CODESTARTdoAction
+ if(pData->bIsRunning == 0) {
+ openPipe(pData);
+ }
+
+ iRet = writePipe(pData, ppString[0]);
+
+ if(iRet != RS_RET_OK)
+ iRet = RS_RET_SUSPENDED;
+ENDdoAction
+
+
+BEGINparseSelectorAct
+CODESTARTparseSelectorAct
+CODE_STD_STRING_REQUESTparseSelectorAct(1)
+ /* first check if this config line is actually for us */
+ if(strncmp((char*) p, ":omprog:", sizeof(":omprog:") - 1)) {
+ ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
+ }
+
+ /* ok, if we reach this point, we have something for us */
+ p += sizeof(":omprog:") - 1; /* eat indicator sequence (-1 because of '\0'!) */
+ CHKiRet(createInstance(&pData));
+
+ CHKmalloc(pData->szBinary = (uchar*) strdup((char*)szBinary));
+ /* check if a non-standard template is to be applied */
+ if(*(p-1) == ';')
+ --p;
+ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, 0, (uchar*) "RSYSLOG_FileFormat"));
+CODE_STD_FINALIZERparseSelectorAct
+ENDparseSelectorAct
+
+
+BEGINmodExit
+CODESTARTmodExit
+ if(szBinary != NULL) {
+ free(szBinary);
+ szBinary = NULL;
+ }
+ CHKiRet(objRelease(errmsg, CORE_COMPONENT));
+finalize_it:
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
+
+
+
+/* Reset config variables for this module to default values.
+ */
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
+{
+ DEFiRet;
+
+ if(szBinary != NULL) {
+ free(szBinary);
+ szBinary = NULL;
+ }
+
+ RETiRet;
+}
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionomprogbinary", 0, eCmdHdlrGetWord, NULL, &szBinary, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+CODEmodInit_QueryRegCFSLineHdlr
+ENDmodInit
+
+/* vi:set ai:
+ */
diff --git a/plugins/omstdout/omstdout.c b/plugins/omstdout/omstdout.c
index 7c63b5c4..181895a4 100644
--- a/plugins/omstdout/omstdout.c
+++ b/plugins/omstdout/omstdout.c
@@ -110,7 +110,7 @@ CODESTARTdoAction
if(iParam > 0)
szBuf[iBuf++] = ','; /* all but first need a delimiter */
iParamVal = 0;
- while(szParams[iParam][iParamVal] != '\0' && iBuf < sizeof(szBuf)) {
+ while(szParams[iParam][iParamVal] != '\0' && iBuf < (int) sizeof(szBuf)) {
szBuf[iBuf++] = szParams[iParam][iParamVal++];
}
++iParam;