diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | module-template.h | 192 | ||||
-rw-r--r-- | modules.c | 2 | ||||
-rw-r--r-- | modules.h | 2 | ||||
-rw-r--r-- | omdiscard.c | 111 | ||||
-rw-r--r-- | omfile.c | 120 | ||||
-rw-r--r-- | omfwd.c | 156 | ||||
-rw-r--r-- | ommysql.c | 132 | ||||
-rw-r--r-- | omshell.c | 122 | ||||
-rw-r--r-- | omusrmsg.c | 117 | ||||
-rw-r--r-- | rsyslog.h | 1 | ||||
-rw-r--r-- | syslogd-types.h | 3 | ||||
-rw-r--r-- | syslogd.c | 10 |
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: + */ @@ -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; @@ -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: */ @@ -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 /* @@ -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 */ /* @@ -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 */ /* @@ -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: */ @@ -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: @@ -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 */ @@ -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; } |