summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-07-25 10:25:38 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-07-25 10:25:38 +0000
commit4c69b80ca0366db28bbbb46ddd03dfbc9d85b09c (patch)
tree09bdad5c352f1635ddeaa9d550d6330a0435f321
parentc8eca687f4f0ee08d927e72da1289ffc9d8ff01c (diff)
downloadrsyslog-4c69b80ca0366db28bbbb46ddd03dfbc9d85b09c.tar.gz
rsyslog-4c69b80ca0366db28bbbb46ddd03dfbc9d85b09c.tar.xz
rsyslog-4c69b80ca0366db28bbbb46ddd03dfbc9d85b09c.zip
changed output modules to use a template-based code generation system for
standard entry points (implemented via preprocessor)
-rw-r--r--Makefile.am2
-rw-r--r--module-template.h192
-rw-r--r--modules.c2
-rw-r--r--modules.h2
-rw-r--r--omdiscard.c111
-rw-r--r--omfile.c120
-rw-r--r--omfwd.c156
-rw-r--r--ommysql.c132
-rw-r--r--omshell.c122
-rw-r--r--omusrmsg.c117
-rw-r--r--rsyslog.h1
-rw-r--r--syslogd-types.h3
-rw-r--r--syslogd.c10
13 files changed, 478 insertions, 492 deletions
diff --git a/Makefile.am b/Makefile.am
index ef90b9dc..eb8f0d45 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,7 @@ rfc3195d_SOURCES=rfc3195d.c rsyslog.h
man_MANS = rfc3195d.8 rklogd.8 rsyslogd.8 rsyslog.conf.5
-rsyslogd_SOURCES=syslogd.c pidfile.c template.c outchannel.c stringbuf.c srUtils.c parse.c syslogd-types.h template.h outchannel.h syslogd.h stringbuf.h parse.h srUtils.h liblogging-stub.h net.c net.h msg.c msg.h omshell.c omshell.h omusrmsg.c omusrmsg.h ommysql.c ommysql.h omfwd.c omfwd.h tcpsyslog.c tcpsyslog.h omfile.h omfile.c omdiscard.c omdiscard.h modules.c modules.h
+rsyslogd_SOURCES=syslogd.c pidfile.c template.c outchannel.c stringbuf.c srUtils.c parse.c syslogd-types.h template.h outchannel.h syslogd.h stringbuf.h parse.h srUtils.h liblogging-stub.h net.c net.h msg.c msg.h omshell.c omshell.h omusrmsg.c omusrmsg.h ommysql.c ommysql.h omfwd.c omfwd.h tcpsyslog.c tcpsyslog.h omfile.h omfile.c omdiscard.c omdiscard.h modules.c modules.h module-template.h
rsyslogd_CPPFLAGS=$(mysql_includes)
rsyslogd_LDADD=$(mysql_libs) $(zlib_libs) $(pthreads_libs)
diff --git a/module-template.h b/module-template.h
new file mode 100644
index 00000000..6ce1a08f
--- /dev/null
+++ b/module-template.h
@@ -0,0 +1,192 @@
+/* module-template.h
+ * This header contains macros that can be used to implement the
+ * plumbing of modules.
+ *
+ * File begun on 2007-07-25 by RGerhards
+ *
+ * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#ifndef MODULE_TEMPLATE_H_INCLUDED
+#define MODULE_TEMPLATE_H_INCLUDED 1
+
+/* to following macros are used to generate function headers and standard
+ * functionality. It works as follows (described on the sample case of
+ * createInstance()):
+ *
+ * BEGINcreateInstance
+ * ... custom variable definitions (on stack) ... (if any)
+ * CODESTARTcreateInstance
+ * ... custom code ... (if any)
+ * ENDcreateInstance
+ */
+
+/* createInstance()
+ */
+#define BEGINcreateInstance \
+static rsRetVal createInstance(instanceData **ppData)\
+ {\
+ rsRetVal iRet = RS_RET_OK; /* store error code here */\
+ instanceData *pData; /* use this to point to data elements */
+
+#define CODESTARTcreateInstance \
+ if((pData = calloc(1, sizeof(instanceData))) == NULL)\
+ return RS_RET_OUT_OF_MEMORY;
+
+#define ENDcreateInstance \
+ *ppData = pData;\
+ return iRet;\
+}
+
+/* freeInstance()
+ */
+#define BEGINfreeInstance \
+static rsRetVal freeInstance(selector_t *f)\
+{\
+ rsRetVal iRet = RS_RET_OK;
+
+#define CODESTARTfreeInstance \
+ assert(f != NULL);
+
+#define ENDfreeInstance \
+ return iRet;\
+}
+
+/* isCompatibleWithFeature()
+ */
+#define BEGINisCompatibleWithFeature \
+static rsRetVal isCompatibleWithFeature(syslogFeature eFeat)\
+{\
+ rsRetVal iRet = RS_RET_INCOMPATIBLE;
+
+#define CODESTARTisCompatibleWithFeature
+
+#define ENDisCompatibleWithFeature \
+ return iRet;\
+}
+
+/* doAction()
+ */
+#define BEGINdoAction \
+static rsRetVal doAction(selector_t *f)\
+{\
+ rsRetVal iRet = RS_RET_OK;
+
+#define CODESTARTdoAction \
+ assert(f != NULL);
+
+#define ENDdoAction \
+ return iRet;\
+}
+
+/* parseSelectorAct()
+ * Extra comments:
+ * try to process a selector action line. Checks if the action
+ * applies to this module and, if so, processed it. If not, it
+ * is left untouched. The driver will then call another module
+ */
+#define BEGINparseSelectorAct \
+static rsRetVal parseSelectorAct(uchar **pp, selector_t *f, void **ppModData)\
+{\
+ rsRetVal iRet = RS_RET_OK;\
+ instanceData *pModData = NULL;
+
+#define CODESTARTparseSelectorAct \
+ assert(pp != NULL);\
+ assert(ppModData != NULL);\
+ assert(f != NULL);
+
+#define ENDparseSelectorAct \
+ return iRet;\
+}
+
+/* queryEtryPt()
+ */
+#define BEGINqueryEtryPt \
+static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\
+{\
+ rsRetVal iRet = RS_RET_OK;
+
+#define CODESTARTqueryEtryPt \
+ if((name == NULL) || (pEtryPoint == NULL))\
+ return RS_RET_PARAM_ERROR;\
+ *pEtryPoint = NULL;
+
+#define ENDqueryEtryPt \
+ if(iRet == RS_RET_OK)\
+ iRet = (*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;\
+ return iRet;\
+}
+
+/* the following defintion is the standard block for queryEtryPt for output
+ * modules. This can be used if no specific handling (e.g. to cover version
+ * differences) is needed.
+ */
+#define CODEqueryEtryPt_STD_OMOD_QUERIES\
+ if(!strcmp((char*) name, "doAction")) {\
+ *pEtryPoint = doAction;\
+ } else if(!strcmp((char*) name, "parseSelectorAct")) {\
+ *pEtryPoint = parseSelectorAct;\
+ } else if(!strcmp((char*) name, "isCompatibleWithFeature")) {\
+ *pEtryPoint = isCompatibleWithFeature;\
+ } else if(!strcmp((char*) name, "freeInstance")) {\
+ *pEtryPoint = freeInstance;\
+ }
+
+/* modInit()
+ * This has an extra parameter, which is the specific name of the modInit
+ * function. That is needed for built-in modules, which must have unique
+ * names in order to link statically.
+ *
+ * Extra Comments:
+ * initialize the module
+ *
+ * Later, much more must be done. So far, we only return a pointer
+ * to the queryEtryPt() function
+ * TODO: do interface version checking & handshaking
+ * iIfVersRequeted is the version of the interface specification that the
+ * caller would like to see being used. ipIFVersProvided is what we
+ * decide to provide.
+ */
+#define BEGINmodInit(uniqName) \
+rsRetVal modInit##uniqName(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())\
+{\
+ rsRetVal iRet = RS_RET_OK;
+
+#define CODESTARTmodInit \
+ if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))\
+ return RS_RET_PARAM_ERROR;
+
+#define ENDmodInit \
+ *pQueryEtryPt = queryEtryPt;\
+ return iRet;\
+}
+
+/*
+ */
+#define BEGIN \
+
+#define CODESTART \
+
+#define END \
+
+
+#endif /* #ifndef MODULE_TEMPLATE_H_INCLUDED */
+/*
+ * vi:set ai:
+ */
diff --git a/modules.c b/modules.c
index e1c1a271..0096cfbc 100644
--- a/modules.c
+++ b/modules.c
@@ -146,8 +146,6 @@ rsRetVal doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)()), uchar *name)
assert(modInit != NULL);
- printf("Enter doModInit for module '%s'\n", (char*)name);
-
if((iRet = moduleConstruct(&pNew)) != RS_RET_OK)
return iRet;
diff --git a/modules.h b/modules.h
index a3479918..871fbc1b 100644
--- a/modules.h
+++ b/modules.h
@@ -74,7 +74,7 @@ typedef struct moduleInfo {
/* below: perform the configured action
*/
rsRetVal (*doAction)();
- rsRetVal (*parseSelectorAct)(uchar**, selector_t*);
+ rsRetVal (*parseSelectorAct)(uchar**, selector_t*, void**);
} om;
} mod;
} modInfo_t;
diff --git a/omdiscard.c b/omdiscard.c
index 3d871133..8153d7e1 100644
--- a/omdiscard.c
+++ b/omdiscard.c
@@ -31,49 +31,44 @@
#include "syslogd.h"
#include "syslogd-types.h"
#include "omdiscard.h"
+#include "module-template.h"
-
-/* query feature compatibility
+/* internal structures
*/
-static rsRetVal isCompatibleWithFeature(syslogFeature __attribute__((unused)) eFeat)
-{
- /* this module is incompatible with all currently-known optional
- * syslog features. Turn them on if that changes over time.
- */
- return RS_RET_INCOMPATIBLE;
-}
+typedef struct _instanceData {
+} instanceData;
+/* we do not need a createInstance()!
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+*/
-/* call the shell action
- */
-static rsRetVal doAction(__attribute__((unused)) selector_t *f)
-{
- dprintf("Discarding message based on selector config\n");
- return RS_RET_DISCARDMSG;
-}
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ /* we are not compatible with repeated msg reduction feature, so do not allow it */
+ENDisCompatibleWithFeature
-/* free an instance
- */
-static rsRetVal freeInstance(selector_t *f)
-{
- assert(f != NULL);
- return RS_RET_OK;
-}
+BEGINdoAction
+CODESTARTdoAction
+ iRet = RS_RET_DISCARDMSG;
+ENDdoAction
-/* try to process a selector action line. Checks if the action
- * applies to this module and, if so, processed it. If not, it
- * is left untouched. The driver will then call another module
- */
-static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
-{
- uchar *p;
- rsRetVal iRet = RS_RET_CONFLINE_PROCESSED;
- assert(pp != NULL);
- assert(f != NULL);
+BEGINfreeInstance
+CODESTARTfreeInstance
+ /* we do not have instance data, so we do not need to
+ * do anything here. -- rgerhards, 2007-07-25
+ */
+ENDfreeInstance
+
+BEGINparseSelectorAct
+ uchar *p;
+CODESTARTparseSelectorAct
+ pModData = NULL; /* this action does not have any instance data */
p = *pp;
if(*p == '~') {
@@ -84,51 +79,23 @@ static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
iRet = RS_RET_CONFLINE_UNPROCESSED;
}
- if(iRet == RS_RET_CONFLINE_PROCESSED)
+ if(iRet == RS_RET_OK) {
+ *ppModData = pModData;
*pp = p;
- return iRet;
-}
-
-/* query an entry point
- */
-static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
-{
- if((name == NULL) || (pEtryPoint == NULL))
- return RS_RET_PARAM_ERROR;
-
- *pEtryPoint = NULL;
- if(!strcmp((char*) name, "doAction")) {
- *pEtryPoint = doAction;
- } else if(!strcmp((char*) name, "parseSelectorAct")) {
- *pEtryPoint = parseSelectorAct;
- } else if(!strcmp((char*) name, "isCompatibleWithFeature")) {
- *pEtryPoint = isCompatibleWithFeature;
- } else if(!strcmp((char*) name, "freeInstance")) {
- *pEtryPoint = freeInstance;
}
+ENDparseSelectorAct
- return(*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;
-}
-/* initialize the module
- *
- * Later, much more must be done. So far, we only return a pointer
- * to the queryEtryPt() function
- * TODO: do interface version checking & handshaking
- * iIfVersRequeted is the version of the interface specification that the
- * caller would like to see being used. ipIFVersProvided is what we
- * decide to provide.
- */
-rsRetVal modInitDiscard(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())
-{
- if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))
- return RS_RET_PARAM_ERROR;
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
- *ipIFVersProvided = 1; /* so far, we only support the initial definition */
- *pQueryEtryPt = queryEtryPt;
- return RS_RET_OK;
-}
+BEGINmodInit(Discard)
+CODESTARTmodInit
+ *ipIFVersProvided = 1; /* so far, we only support the initial definition */
+ENDmodInit
/*
* vi:set ai:
*/
diff --git a/omfile.c b/omfile.c
index a5563c54..016b1402 100644
--- a/omfile.c
+++ b/omfile.c
@@ -46,17 +46,19 @@
#include "template.h"
#include "outchannel.h"
#include "omfile.h"
+#include "module-template.h"
-
-/* query feature compatibility
+/* internal structures
*/
-static rsRetVal isCompatibleWithFeature(syslogFeature eFeat)
-{
- if(eFeat == sFEATURERepeatedMsgReduction)
- return RS_RET_OK;
- return RS_RET_INCOMPATIBLE;
-}
+typedef struct _instanceData {
+} instanceData;
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ if(eFeat == sFEATURERepeatedMsgReduction)
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
/* Helper to cfline(). Parses a output channel name up until the first
@@ -502,26 +504,22 @@ again:
}
-/* free an instance
- */
-static rsRetVal freeInstance(selector_t *f)
-{
- assert(f != NULL);
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINfreeInstance
+CODESTARTfreeInstance
if(f->f_un.f_file.bDynamicName) {
dynaFileFreeCache(f);
} else
close(f->f_file);
- return RS_RET_OK;
-}
-
+ENDfreeInstance
-/* call the shell action
- */
-static rsRetVal doActionFile(selector_t *f)
-{
- assert(f != NULL);
- rsRetVal iRet = RS_RET_OK;
+BEGINdoAction
+CODESTARTdoAction
dprintf(" (%s)\n", f->f_un.f_file.f_fname);
/* f->f_file == -1 is an indicator that the we couldn't
* open the file at startup. For dynaFiles, this is ok,
@@ -529,23 +527,13 @@ static rsRetVal doActionFile(selector_t *f)
*/
if(f->f_un.f_file.bDynamicName || (f->f_file != -1))
iRet = writeFile(f);
+ENDdoAction
- return iRet;
-}
-/* try to process a selector action line. Checks if the action
- * applies to this module and, if so, processed it. If not, it
- * is left untouched. The driver will then call another module
- */
-static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
-{
+BEGINparseSelectorAct
uchar *p;
int syncfile;
- rsRetVal iRet = RS_RET_CONFLINE_PROCESSED;
-
- assert(pp != NULL);
- assert(f != NULL);
-
+CODESTARTparseSelectorAct
p = *pp;
if (*p == '-') {
@@ -554,6 +542,14 @@ static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
} else
syncfile = 1;
+ /* yes, the if below is redundant, but I need it now. Will go away as
+ * the code further changes. -- rgerhards, 2007-07-25
+ */
+ if(*p == '$' || *p == '?' || *p == '|' || *p == '/') {
+ if((iRet = createInstance(&pModData)) != RS_RET_OK)
+ return iRet;
+ }
+
switch (*p)
{
case '$':
@@ -649,55 +645,23 @@ static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
break;
}
- if(iRet == RS_RET_OK)
- iRet = RS_RET_CONFLINE_PROCESSED;
-
- if(iRet == RS_RET_CONFLINE_PROCESSED)
+ if(iRet == RS_RET_OK) {
+ *ppModData = (void*) pModData;
*pp = p;
- return iRet;
-}
-
-
-/* query an entry point
- */
-static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
-{
- if((name == NULL) || (pEtryPoint == NULL))
- return RS_RET_PARAM_ERROR;
-
- *pEtryPoint = NULL;
- if(!strcmp((char*) name, "doAction")) {
- *pEtryPoint = doActionFile;
- } else if(!strcmp((char*) name, "parseSelectorAct")) {
- *pEtryPoint = parseSelectorAct;
- } else if(!strcmp((char*) name, "isCompatibleWithFeature")) {
- *pEtryPoint = isCompatibleWithFeature;
- } else if(!strcmp((char*) name, "freeInstance")) {
- *pEtryPoint = freeInstance;
}
+ENDparseSelectorAct
- return(*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;
-}
-/* initialize the module
- *
- * Later, much more must be done. So far, we only return a pointer
- * to the queryEtryPt() function
- * TODO: do interface version checking & handshaking
- * iIfVersRequeted is the version of the interface specification that the
- * caller would like to see being used. ipIFVersProvided is what we
- * decide to provide.
- */
-rsRetVal modInitFile(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())
-{
- if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))
- return RS_RET_PARAM_ERROR;
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
- *ipIFVersProvided = 1; /* so far, we only support the initial definition */
- *pQueryEtryPt = queryEtryPt;
- return RS_RET_OK;
-}
+BEGINmodInit(File)
+CODESTARTmodInit
+ *ipIFVersProvided = 1; /* so far, we only support the initial definition */
+ENDmodInit
/*
diff --git a/omfwd.c b/omfwd.c
index cffd4ac2..e1b20464 100644
--- a/omfwd.c
+++ b/omfwd.c
@@ -50,6 +50,7 @@
#include "template.h"
#include "msg.h"
#include "tcpsyslog.h"
+#include "module-template.h"
/*
* This table contains plain text for h_errno errors used by the
@@ -64,33 +65,50 @@ static const char *sys_h_errlist[] = {
"no address, look for MX record" /* NO_ADDRESS */
};
-/* query feature compatibility
+/* internal structures
*/
-static rsRetVal isCompatibleWithFeature(syslogFeature eFeat)
-{
+
+typedef struct _instanceData {
+} instanceData;
+
+
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
if(eFeat == sFEATURERepeatedMsgReduction)
- return RS_RET_OK;
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
+
- return RS_RET_INCOMPATIBLE;
-}
+BEGINfreeInstance
+CODESTARTfreeInstance
+ switch (f->f_type) {
+ case F_FORW:
+ case F_FORW_SUSP:
+ freeaddrinfo(f->f_un.f_forw.f_addr);
+ /* fall through */
+ case F_FORW_UNKN:
+ if(f->f_un.f_forw.port != NULL)
+ free(f->f_un.f_forw.port);
+ break;
+ }
+ENDfreeInstance
-/* call the shell action
- */
-static rsRetVal doActionFwd(selector_t *f)
-{
+BEGINdoAction
char *psz; /* temporary buffering */
register unsigned l;
- rsRetVal iRet = RS_RET_OK;
int i;
unsigned e, lsent = 0;
int bSendSuccess;
time_t fwd_suspend;
struct addrinfo *res, *r;
struct addrinfo hints;
-
- assert(f != NULL);
-
+CODESTARTdoAction
switch (f->f_type) {
case F_FORW_SUSP:
fwd_suspend = time(NULL) - f->f_un.f_forw.ttSuspend;
@@ -249,32 +267,22 @@ static rsRetVal doActionFwd(selector_t *f)
}
break;
}
- return iRet;
-}
+ENDdoAction
-/* try to process a selector action line. Checks if the action
- * applies to this module and, if so, processed it. If not, it
- * is left untouched. The driver will then call another module
- */
-static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
-{
+BEGINparseSelectorAct
uchar *p, *q;
int i;
int error;
int bErr;
- rsRetVal iRet = RS_RET_CONFLINE_PROCESSED;
struct addrinfo hints, *res;
char szTemplateName[128];
-
- assert(pp != NULL);
- assert(f != NULL);
-
+CODESTARTparseSelectorAct
p = *pp;
- switch (*p)
- {
- case '@':
+ if(*p == '@') {
+ if((iRet = createInstance(&pModData)) != RS_RET_OK)
+ return iRet;
++p; /* eat '@' */
if(*p == '@') { /* indicator for TCP! */
f->f_un.f_forw.protocol = FORW_TCP;
@@ -416,91 +424,41 @@ static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
}
/* then try to find the template */
- if((iRet = cflineSetTemplateAndIOV(f, szTemplateName)) != RS_RET_OK)
- break;
-
- dprintf("forwarding host: '%s:%s/%s' template '%s'\n", q, getFwdSyslogPt(f),
- f->f_un.f_forw.protocol == FORW_UDP ? "udp" : "tcp",
- szTemplateName);
+ if((iRet = cflineSetTemplateAndIOV(f, szTemplateName)) == RS_RET_OK) {
+ dprintf("forwarding host: '%s:%s/%s' template '%s'\n", q, getFwdSyslogPt(f),
+ f->f_un.f_forw.protocol == FORW_UDP ? "udp" : "tcp",
+ szTemplateName);
+ }
/*
* Otherwise the host might be unknown due to an
* inaccessible nameserver (perhaps on the same
* host). We try to get the ip number later, like
* FORW_SUSP.
*/
- break;
- default:
+ } else {
iRet = RS_RET_CONFLINE_UNPROCESSED;
- break;
}
- if(iRet == RS_RET_OK)
- iRet = RS_RET_CONFLINE_PROCESSED;
-
- if(iRet == RS_RET_CONFLINE_PROCESSED)
+ if(iRet == RS_RET_OK) {
+ *ppModData = pModData;
*pp = p;
- return iRet;
-}
-
-/* free an instance
- */
-static rsRetVal freeInstance(selector_t *f)
-{
- assert(f != NULL);
- switch (f->f_type) {
- case F_FORW:
- case F_FORW_SUSP:
- freeaddrinfo(f->f_un.f_forw.f_addr);
- /* fall through */
- case F_FORW_UNKN:
- if(f->f_un.f_forw.port != NULL)
- free(f->f_un.f_forw.port);
- break;
}
- return RS_RET_OK;
-}
-
-
-/* query an entry point
- */
-static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
-{
- if((name == NULL) || (pEtryPoint == NULL))
- return RS_RET_PARAM_ERROR;
+ /* TODO: do we need to call freeInstance if we failed - this is a general question for
+ * all output modules. I'll address it lates as the interface evolves. rgerhards, 2007-07-25
+ */
+ENDparseSelectorAct
- *pEtryPoint = NULL;
- if(!strcmp((char*) name, "doAction")) {
- *pEtryPoint = doActionFwd;
- } else if(!strcmp((char*) name, "parseSelectorAct")) {
- *pEtryPoint = parseSelectorAct;
- } else if(!strcmp((char*) name, "isCompatibleWithFeature")) {
- *pEtryPoint = isCompatibleWithFeature;
- } else if(!strcmp((char*) name, "freeInstance")) {
- *pEtryPoint = freeInstance;
- }
- return(*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;
-}
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
-/* initialize the module
- *
- * Later, much more must be done. So far, we only return a pointer
- * to the queryEtryPt() function
- * TODO: do interface version checking & handshaking
- * iIfVersRequeted is the version of the interface specification that the
- * caller would like to see being used. ipIFVersProvided is what we
- * decide to provide.
- */
-rsRetVal modInitFwd(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())
-{
- if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))
- return RS_RET_PARAM_ERROR;
+BEGINmodInit(Fwd)
+CODESTARTmodInit
*ipIFVersProvided = 1; /* so far, we only support the initial definition */
-
- *pQueryEtryPt = queryEtryPt;
- return RS_RET_OK;
-}
+ENDmodInit
#endif /* #ifdef SYSLOG_INET */
/*
diff --git a/ommysql.c b/ommysql.c
index 509d5b39..dfa1a283 100644
--- a/ommysql.c
+++ b/ommysql.c
@@ -43,18 +43,37 @@
#include "ommysql.h"
#include "mysql/mysql.h"
#include "mysql/errmsg.h"
+#include "module-template.h"
-
-static rsRetVal reInitMySQL(register selector_t *f);
-/* query feature compatibility
+/* internal structures
*/
-static rsRetVal isCompatibleWithFeature(syslogFeature eFeat)
-{
+typedef struct _instanceData {
+} instanceData;
+
+
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
if(eFeat == sFEATURERepeatedMsgReduction)
- return RS_RET_OK;
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
- return RS_RET_INCOMPATIBLE;
-}
+
+BEGINfreeInstance
+CODESTARTfreeInstance
+ switch (f->f_type) {
+# ifdef WITH_DB
+ closeMySQL(f);
+# endif
+ }
+ENDfreeInstance
+
+
+static rsRetVal reInitMySQL(register selector_t *f);
/**
@@ -270,33 +289,29 @@ rsRetVal writeMySQL(register selector_t *f)
return iRet;
}
-/* call the shell action
- */
-static rsRetVal doActionMySQL(selector_t *f)
-{
- assert(f != NULL);
+BEGINdoAction
+CODESTARTdoAction
dprintf("\n");
- return writeMySQL(f);
-}
+ iRet = writeMySQL(f);
+ENDdoAction
-/* try to process a selector action line. Checks if the action
- * applies to this module and, if so, processed it. If not, it
- * is left untouched. The driver will then call another module
- */
-static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
-{
+BEGINparseSelectorAct
uchar *p;
- rsRetVal iRet = RS_RET_CONFLINE_PROCESSED;
int iMySQLPropErr = 0;
char szTemplateName[128];
-
- assert(pp != NULL);
- assert(f != NULL);
-
+CODESTARTparseSelectorAct
p = *pp;
+ /* yes, the if below is redundant, but I need it now. Will go away as
+ * the code further changes. -- rgerhards, 2007-07-25
+ */
+ if(*p == '>') {
+ if((iRet = createInstance(&pModData)) != RS_RET_OK)
+ return iRet;
+ }
+
switch (*p)
{
case '>':
@@ -381,68 +396,23 @@ static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
break;
}
- if(iRet == RS_RET_OK)
- iRet = RS_RET_CONFLINE_PROCESSED;
-
- if(iRet == RS_RET_CONFLINE_PROCESSED)
+ if(iRet == RS_RET_OK) {
+ *ppModData = pModData;
*pp = p;
- return iRet;
-}
-
-
-/* free an instance
- */
-static rsRetVal freeInstance(selector_t *f)
-{
- assert(f != NULL);
- switch (f->f_type) {
-# ifdef WITH_DB
- closeMySQL(f);
-# endif
}
- return RS_RET_OK;
-}
+ENDparseSelectorAct
-/* query an entry point
- */
-static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
-{
- if((name == NULL) || (pEtryPoint == NULL))
- return RS_RET_PARAM_ERROR;
-
- *pEtryPoint = NULL;
- if(!strcmp((char*) name, "doAction")) {
- *pEtryPoint = doActionMySQL;
- } else if(!strcmp((char*) name, "parseSelectorAct")) {
- *pEtryPoint = parseSelectorAct;
- } else if(!strcmp((char*) name, "isCompatibleWithFeature")) {
- *pEtryPoint = isCompatibleWithFeature;
- } else if(!strcmp((char*) name, "freeInstance")) {
- *pEtryPoint = freeInstance;
- }
- return(*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;
-}
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
-/* initialize the module
- *
- * Later, much more must be done. So far, we only return a pointer
- * to the queryEtryPt() function
- * TODO: do interface version checking & handshaking
- * iIfVersRequeted is the version of the interface specification that the
- * caller would like to see being used. ipIFVersProvided is what we
- * decide to provide.
- */
-rsRetVal modInitMySQL(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())
-{
- if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))
- return RS_RET_PARAM_ERROR;
+BEGINmodInit(MySQL)
+CODESTARTmodInit
*ipIFVersProvided = 1; /* so far, we only support the initial definition */
-
- *pQueryEtryPt = queryEtryPt;
- return RS_RET_OK;
-}
+ENDmodInit
#endif /* #ifdef WITH_DB */
/*
diff --git a/omshell.c b/omshell.c
index df9da9f5..503372e5 100644
--- a/omshell.c
+++ b/omshell.c
@@ -38,26 +38,36 @@
#include "syslogd-types.h"
#include "srUtils.h"
#include "omshell.h"
+#include "module-template.h"
-
-/* query feature compatibility
+/* internal structures
*/
-static rsRetVal isCompatibleWithFeature(syslogFeature eFeat)
-{
+typedef struct _instanceData {
+} instanceData;
+
+
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
if(eFeat == sFEATURERepeatedMsgReduction)
- return RS_RET_OK;
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
- return RS_RET_INCOMPATIBLE;
-}
+BEGINfreeInstance
+CODESTARTfreeInstance
+ /* TODO: free the instance pointer (currently a leak, will go away) */
+ENDfreeInstance
-/* call the shell action
- */
-static rsRetVal doActionShell(selector_t *f)
-{
- uchar *psz;
- assert(f != NULL);
+
+BEGINdoAction
+ uchar *psz;
+CODESTARTdoAction
/* TODO: using f->f_un.f_file.f_name is not clean from the point of
* modularization. We'll change that as we go ahead with modularization.
* rgerhards, 2007-07-20
@@ -67,24 +77,21 @@ static rsRetVal doActionShell(selector_t *f)
psz = (uchar*) iovAsString(f);
if(execProg((uchar*) f->f_un.f_file.f_fname, 1, (uchar*) psz) == 0)
logerrorSz("Executing program '%s' failed", f->f_un.f_file.f_fname);
-
- return RS_RET_OK;
-}
+ENDdoAction
-/* try to process a selector action line. Checks if the action
- * applies to this module and, if so, processed it. If not, it
- * is left untouched. The driver will then call another module
- */
-static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
-{
+BEGINparseSelectorAct
uchar *p;
- rsRetVal iRet = RS_RET_CONFLINE_PROCESSED;
-
- assert(pp != NULL);
- assert(f != NULL);
-
+CODESTARTparseSelectorAct
p = *pp;
+ /* yes, the if below is redundant, but I need it now. Will go away as
+ * the code further changes. -- rgerhards, 2007-07-25
+ */
+ if(*p == '^') {
+ if((iRet = createInstance(&pModData)) != RS_RET_OK)
+ return iRet;
+ }
+
switch (*p)
{
@@ -101,63 +108,24 @@ static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
break;
}
- if(iRet == RS_RET_OK)
- iRet = RS_RET_CONFLINE_PROCESSED;
-
- if(iRet == RS_RET_CONFLINE_PROCESSED)
+ if(iRet == RS_RET_OK) {
+ *ppModData = pModData;
*pp = p;
- return iRet;
-}
-
-
-/* free an instance
- */
-static rsRetVal freeInstance(selector_t *f)
-{
- assert(f != NULL);
- return RS_RET_OK;
-}
-
-/* query an entry point
- */
-static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
-{
- if((name == NULL) || (pEtryPoint == NULL))
- return RS_RET_PARAM_ERROR;
-
- *pEtryPoint = NULL;
- if(!strcmp((char*) name, "doAction")) {
- *pEtryPoint = doActionShell;
- } else if(!strcmp((char*) name, "parseSelectorAct")) {
- *pEtryPoint = parseSelectorAct;
- } else if(!strcmp((char*) name, "isCompatibleWithFeature")) {
- *pEtryPoint = isCompatibleWithFeature;
- } else if(!strcmp((char*) name, "freeInstance")) {
- *pEtryPoint = freeInstance;
}
+ENDparseSelectorAct
- return(*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;
-}
-/* initialize the module
- *
- * Later, much more must be done. So far, we only return a pointer
- * to the queryEtryPt() function
- * TODO: do interface version checking & handshaking
- * iIfVersRequeted is the version of the interface specification that the
- * caller would like to see being used. ipIFVersProvided is what we
- * decide to provide.
- */
-rsRetVal modInitShell(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())
-{
- if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))
- return RS_RET_PARAM_ERROR;
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
+
+BEGINmodInit(Shell)
+CODESTARTmodInit
*ipIFVersProvided = 1; /* so far, we only support the initial definition */
+ENDmodInit
- *pQueryEtryPt = queryEtryPt;
- return RS_RET_OK;
-}
/*
* vi:set ai:
*/
diff --git a/omusrmsg.c b/omusrmsg.c
index 196738e6..43b6ebe2 100644
--- a/omusrmsg.c
+++ b/omusrmsg.c
@@ -50,17 +50,30 @@
#include "syslogd-types.h"
#include "syslogd.h"
#include "omusrmsg.h"
+#include "module-template.h"
-
-/* query feature compatibility
+/* internal structures
*/
-static rsRetVal isCompatibleWithFeature(syslogFeature eFeat)
-{
+typedef struct _instanceData {
+} instanceData;
+
+
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
if(eFeat == sFEATURERepeatedMsgReduction)
- return RS_RET_OK;
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
- return RS_RET_INCOMPATIBLE;
-}
+
+BEGINfreeInstance
+CODESTARTfreeInstance
+ /* TODO: free the instance pointer (currently a leak, will go away) */
+ENDfreeInstance
static jmp_buf ttybuf;
@@ -213,36 +226,28 @@ static void wallmsg(selector_t *f)
}
-/* call the shell action
- */
-static rsRetVal doAction(selector_t *f)
-{
- assert(f != NULL);
-
+BEGINdoAction
+CODESTARTdoAction
dprintf("\n");
+ /* TODO: change wallmsg so that it returns iRet */
wallmsg(f);
- return RS_RET_OK;
-}
+ENDdoAction
-/* try to process a selector action line. Checks if the action
- * applies to this module and, if so, processed it. If not, it
- * is left untouched. The driver will then call another module
- */
-static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
-{
+
+BEGINparseSelectorAct
uchar *p, *q;
int i;
char szTemplateName[128];
- rsRetVal iRet = RS_RET_CONFLINE_PROCESSED;
-
- assert(pp != NULL);
- assert(f != NULL);
+CODESTARTparseSelectorAct
#if 0 /* TODO: think about it and activate later - see comments in else below */
if(**pp != '*')
return RS_RET_CONFLINE_UNPROCESSED;
#endif
p = *pp;
+ if((iRet = createInstance(&pModData)) != RS_RET_OK)
+ return iRet;
+
if(*p == '*') { /* wall */
dprintf ("write-all");
@@ -299,63 +304,23 @@ static rsRetVal parseSelectorAct(uchar **pp, selector_t *f)
*/
}
- if(iRet == RS_RET_OK)
- iRet = RS_RET_CONFLINE_PROCESSED;
-
- if(iRet == RS_RET_CONFLINE_PROCESSED)
+ if(iRet == RS_RET_OK) {
+ *ppModData = pModData;
*pp = p;
- return iRet;
-}
-
-
-/* free an instance
- */
-static rsRetVal freeInstance(selector_t *f)
-{
- assert(f != NULL);
- return RS_RET_OK;
-}
-
-/* query an entry point
- */
-static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
-{
- if((name == NULL) || (pEtryPoint == NULL))
- return RS_RET_PARAM_ERROR;
-
- *pEtryPoint = NULL;
- if(!strcmp((char*) name, "doAction")) {
- *pEtryPoint = doAction;
- } else if(!strcmp((char*) name, "parseSelectorAct")) {
- *pEtryPoint = parseSelectorAct;
- } else if(!strcmp((char*) name, "isCompatibleWithFeature")) {
- *pEtryPoint = isCompatibleWithFeature;
- } else if(!strcmp((char*) name, "freeInstance")) {
- *pEtryPoint = freeInstance;
}
+ENDparseSelectorAct
- return(*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;
-}
-/* initialize the module
- *
- * Later, much more must be done. So far, we only return a pointer
- * to the queryEtryPt() function
- * TODO: do interface version checking & handshaking
- * iIfVersRequeted is the version of the interface specification that the
- * caller would like to see being used. ipIFVersProvided is what we
- * decide to provide.
- */
-rsRetVal modInitUsrMsg(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())
-{
- if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))
- return RS_RET_PARAM_ERROR;
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
- *ipIFVersProvided = 1; /* so far, we only support the initial definition */
- *pQueryEtryPt = queryEtryPt;
- return RS_RET_OK;
-}
+BEGINmodInit(UsrMsg)
+CODESTARTmodInit
+ *ipIFVersProvided = 1; /* so far, we only support the initial definition */
+ENDmodInit
/*
* vi:set ai:
diff --git a/rsyslog.h b/rsyslog.h
index 0f8666de..c6776aa4 100644
--- a/rsyslog.h
+++ b/rsyslog.h
@@ -48,7 +48,6 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_PARAM_ERROR = -1000, /**< invalid parameter in call to function */
RS_RET_MISSING_INTERFACE = -1001,/**< interface version mismatch, required missing */
/* return states for config file processing */
- RS_RET_CONFLINE_PROCESSED = -2000, /**< config line was processed, do not pass to any other module */
RS_RET_CONFLINE_UNPROCESSED = -2001,/**< config line was not processed, pass to other module */
RS_RET_DISCARDMSG = -2002, /**< discard message (no error state, processing request!) */
RS_RET_INCOMPATIBLE = -2003, /**< function not compatible with requested feature */
diff --git a/syslogd-types.h b/syslogd-types.h
index a9a045a1..a4c70ca0 100644
--- a/syslogd-types.h
+++ b/syslogd-types.h
@@ -156,6 +156,7 @@ struct filed {
rsCStrObj *pCSHostnameComp;/* hostname to check */
rsCStrObj *pCSProgNameComp; /* tag to check or NULL, if not to be checked */
struct moduleInfo *pMod; /* pointer to output module handling this selector */
+ void *pModData; /* pointer to module data - contents is module-specific */
union {
u_char f_pmask[LOG_NFACILITIES+1]; /* priority mask */
struct {
@@ -171,6 +172,7 @@ struct filed {
char isNegated; /* actually a boolean ;) */
} prop;
} f_filterData;
+#if 1
union {
char f_uname[MAXUNAMES][UNAMESZ+1];
#ifdef WITH_DB
@@ -232,6 +234,7 @@ struct filed {
char *f_sizeLimitCmd; /* command to carry out when size limit is reached */
} f_file;
} f_un;
+#endif
int f_ReduceRepeated; /* reduce repeated lines 0 - no, 1 - yes */
int f_prevcount; /* repetition cnt of prevline */
int f_repeatcount; /* number of "repeated" msgs */
diff --git a/syslogd.c b/syslogd.c
index 5ab17880..53d6bd43 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -3307,7 +3307,6 @@ rsRetVal fprintlog(register selector_t *f)
iRet = f->pMod->mod.om.doAction(f); /* call configured action */
if(iRet == RS_RET_DISABLE_ACTION)
f->bEnabled = 0; /* that's it... */
- // TODO: this causes problems for the emergency logging system!
if (f->f_type != F_FORW_UNKN)
f->f_prevcount = 0;
@@ -4462,6 +4461,7 @@ static void init()
printf("%s, ", f->f_un.f_uname[i]);
break;
}
+ printf("\tinstance data: 0x%x\n", (unsigned) f->pModData);
if(f->f_ReduceRepeated)
printf(" [RepeatedMsgReduction]");
if(f->bEnabled == 0)
@@ -5023,6 +5023,7 @@ static rsRetVal cfline(char *line, register selector_t *f)
uchar *p;
rsRetVal iRet;
modInfo_t *pMod;
+ void *pModData;
dprintf("cfline(%s)", line);
@@ -5071,12 +5072,13 @@ static rsRetVal cfline(char *line, register selector_t *f)
/* loop through all modules and see if one picks up the line */
pMod = omodGetNxt(NULL);
while(pMod != NULL) {
- iRet = pMod->mod.om.parseSelectorAct(&p , f);
+ iRet = pMod->mod.om.parseSelectorAct(&p , f, &pModData);
dprintf("trying selector action for %s: %d\n", modGetName(pMod), iRet);
- if(iRet == RS_RET_CONFLINE_PROCESSED) {
+ if(iRet == RS_RET_OK) {
dprintf("Module %s processed this config line.\n",
modGetName(pMod));
f->pMod = pMod;
+ f->pModData = pModData;
/* now check if the module is compatible with select features */
if(pMod->isCompatibleWithFeature(sFEATURERepeatedMsgReduction) == RS_RET_OK)
f->f_ReduceRepeated = bReduceRepeatMsgs;
@@ -5100,7 +5102,7 @@ static rsRetVal cfline(char *line, register selector_t *f)
pMod = omodGetNxt(pMod);
}
- return (iRet == RS_RET_CONFLINE_PROCESSED) ? RS_RET_OK : RS_RET_NOENTRY;
+ return iRet;
}