summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-07-23 17:24:41 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-07-23 17:24:41 +0000
commit9ee5888309e1f39f52546deaea4bcd3bdc216d8d (patch)
treea46550eb83762539b375063e6e74d828d1ebb42f
parent8f236abd49739c0f791c5b893433f7dfa40d3dd8 (diff)
downloadrsyslog-9ee5888309e1f39f52546deaea4bcd3bdc216d8d.tar.gz
rsyslog-9ee5888309e1f39f52546deaea4bcd3bdc216d8d.tar.xz
rsyslog-9ee5888309e1f39f52546deaea4bcd3bdc216d8d.zip
continued working on modularization; begun to create interface for
configuring actions selector lines; begun basic functionality for module initialization and loading built-in modules.
-rw-r--r--ChangeLog1
-rw-r--r--modules.c98
-rw-r--r--modules.h18
-rw-r--r--omfile.c262
-rw-r--r--omfile.h6
-rw-r--r--omfwd.c36
-rw-r--r--omfwd.h2
-rw-r--r--ommysql.c36
-rw-r--r--ommysql.h2
-rw-r--r--omshell.c36
-rw-r--r--omshell.h2
-rw-r--r--omusrmsg.c128
-rw-r--r--omusrmsg.h4
-rw-r--r--rsyslog.h8
-rwxr-xr-xsrUtils.c4
-rw-r--r--syslogd.c311
-rw-r--r--syslogd.h13
17 files changed, 690 insertions, 277 deletions
diff --git a/ChangeLog b/ChangeLog
index 533c4b17..649f69fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
---------------------------------------------------------------------------
Version 1.17.3 (rgerhards), 2007-07-2?
+- continued working on modularization
- fixed a memory leak in config file parsing
thanks to varmojfekoj <varmojfekoj@gmail.com> for the patch
- rsyslogd now checks on startup if it is capable to performa any work
diff --git a/modules.c b/modules.c
index eed6f4b8..85e191b2 100644
--- a/modules.c
+++ b/modules.c
@@ -23,6 +23,7 @@
* 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>
@@ -34,7 +35,7 @@
#include <unistd.h>
#include <sys/file.h>
-#include "rsyslog.h"
+#include "syslogd.h"
#include "modules.h"
static modInfo_t *pLoadedModules = NULL; /* list of currently-loaded modules */
@@ -59,6 +60,15 @@ static rsRetVal moduleConstruct(modInfo_t **pThis)
}
+/* Destructs a module objects. The object must not be linked to the
+ * linked list of modules.
+ */
+static void moduleDestruct(modInfo_t *pThis)
+{
+ free(pThis);
+}
+
+
/* Add a module to the loaded module linked list
*/
static inline void addModToList(modInfo_t *pThis)
@@ -75,28 +85,108 @@ static inline void addModToList(modInfo_t *pThis)
}
+/* Get the next module pointer - this is used to traverse the list.
+ * The function returns the next pointer or NULL, if there is no next one.
+ * The last object must be provided to the function. If NULL is provided,
+ * it starts at the root of the list. Even in this case, NULL may be
+ * returned - then, the list is empty.
+ * rgerhards, 2007-07-23
+ */
+modInfo_t *modGetNxt(modInfo_t *pThis)
+{
+ modInfo_t *pNew;
+
+ if(pThis == NULL)
+ pNew = pLoadedModules;
+ else
+ pNew = pThis->pNext;
+
+ return(pNew);
+}
+
+
/* Add an already-loaded module to the module linked list. This function does
* anything that is needed to fully initialize the module.
*/
-rsRetVal doModInit(rsRetVal *doInit(), uchar *name)
+rsRetVal doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)()), uchar *name)
{
modInfo_t *pNew;
rsRetVal iRet;
+ assert(modInit != NULL);
+
+ printf("Enter doModInit for module '%s'\n", (char*)name);
+
if((iRet = moduleConstruct(&pNew)) != RS_RET_OK)
return iRet;
- if((iRet = *doInit()) != RS_RET_OK)
+ if((iRet = (*modInit)(1, &pNew->iIFVers, &pNew->modQueryEtryPt)) != RS_RET_OK) {
+ moduleDestruct(pNew);
return iRet;
+ }
+
+ if(pNew->iIFVers != 1) {
+ moduleDestruct(pNew);
+ return RS_RET_MISSING_INTERFACE;
+ }
/* OK, we know we can successfully work with the module. So we now fill the
* rest of the data elements.
*/
+ if((iRet = (*pNew->modQueryEtryPt)((uchar*)"doAction", &pNew->mod.om.doAction)) != RS_RET_OK) {
+ moduleDestruct(pNew);
+ return iRet;
+ }
+/* later...
+ if((iRet = (*pNew->modQueryEtryPt)((uchar*)"freeInstance", &pNew->freeInstance)) != RS_RET_OK) {
+ moduleDestruct(pNew);
+ return iRet;
+ }
+*/
+
+ pNew->pszName = (uchar*) strdup((char*)name); /* we do not care if strdup() fails, we can accept that */
+ pNew->eType = eMOD_OUT; /* TODO: take this from module */
- pNew->pszModName = (uchar*) strdup((char*)name); /* we do not care if strdup() fails, we can accept that */
+ /* we initialized the structure, now let's add it to the linked list of modules */
+ addModToList(pNew);
return RS_RET_OK;
}
+
+/* Print loaded modules. This is more or less a
+ * debug or test aid, but anyhow I think it's worth it...
+ * This only works if the dprintf() subsystem is initialized.
+ */
+void modPrintList(void)
+{
+ modInfo_t *pMod;
+
+ pMod = modGetNxt(NULL);
+ while(pMod != NULL) {
+ dprintf("Loaded Module: Name='%s', IFVersion=%d, ",
+ (pMod->pszName == NULL) ? "NULL" : (char*)pMod->pszName,
+ pMod->iIFVers);
+ dprintf("type=");
+ switch(pMod->eType) {
+ case eMOD_OUT:
+ dprintf("output");
+ break;
+ case eMOD_IN:
+ dprintf("input");
+ break;
+ case eMOD_FILTER:
+ dprintf("filter");
+ break;
+ }
+ dprintf(" module.\n");
+ dprintf("Entry points:\n");
+ dprintf("\tqueryEtryPt: 0x%x\n", (unsigned) pMod->modQueryEtryPt);
+ dprintf("\tdoAction: 0x%x\n", (unsigned) pMod->mod.om.doAction);
+ dprintf("\tfreeInstance: 0x%x\n", (unsigned) pMod->freeInstance);
+ dprintf("\n");
+ pMod = modGetNxt(pMod); /* done, go next */
+ }
+}
/*
* vi:set ai:
*/
diff --git a/modules.h b/modules.h
index b626d86e..da37a91c 100644
--- a/modules.h
+++ b/modules.h
@@ -45,13 +45,15 @@ typedef enum eModLinkType_ {
typedef struct moduleInfo {
struct moduleInfo *pNext; /* support for creating a linked module list */
- int iModVers; /* Interface version of module */
- eModType_t eModType; /* type of this module */
- eModLinkType_t eModLinkType;
- uchar* pszModName; /* printable module name, e.g. for dprintf */
+ int iIFVers; /* Interface version of module */
+ eModType_t eType; /* type of this module */
+ eModLinkType_t eLinkType;
+ uchar* pszName; /* printable module name, e.g. for dprintf */
/* functions supported by all types of modules */
- rsRetVal (*modInit)(); /* initialize the module */
+ rsRetVal (*modInit)(int, int*, rsRetVal(**)()); /* initialize the module */
/* be sure to support version handshake! */
+ rsRetVal (*modQueryEtryPt)(uchar *name, rsRetVal (**EtryPoint)()); /* query entry point addresses */
+ rsRetVal (*freeInstance)(struct filed*);/* called before termination or module unload */
rsRetVal (*modExit)(); /* called before termination or module unload */
/* below: parse a configuration line - return if processed
* or not. If not, must be parsed to next module.
@@ -66,16 +68,18 @@ typedef struct moduleInfo {
/* input modules come after output modules are finished, I am
* currently not really thinking about them. rgerhards, 2007-07-19
*/
- };
+ } im;
struct {/* data for output modules */
/* below: perform the configured action
*/
rsRetVal (*doAction)();
- };
+ } om;
} mod;
} modInfo_t;
/* prototypes */
+rsRetVal doModInit(rsRetVal (*modInit)(), uchar *name);
+void modPrintList(void);
#endif /* #ifndef MODULES_H_INCLUDED */
/*
diff --git a/omfile.c b/omfile.c
index 7d41fc0a..28085d34 100644
--- a/omfile.c
+++ b/omfile.c
@@ -35,7 +35,7 @@
#include <time.h>
#include <assert.h>
#include <errno.h>
-
+#include <ctype.h>
#include <unistd.h>
#include <sys/file.h>
@@ -44,9 +44,97 @@
#include "syslogd-types.h"
#include "srUtils.h"
#include "template.h"
+#include "outchannel.h"
#include "omfile.h"
+/* Helper to cfline(). Parses a output channel name up until the first
+ * comma and then looks for the template specifier. Tries
+ * to find that template. Maps the output channel to the
+ * proper filed structure settings. Everything is stored in the
+ * filed struct. Over time, the dependency on filed might be
+ * removed.
+ * rgerhards 2005-06-21
+ */
+static void cflineParseOutchannel(selector_t *f, uchar* p)
+{
+ size_t i;
+ struct outchannel *pOch;
+ char szBuf[128]; /* should be more than sufficient */
+
+ /* this must always be a file, because we can not set a size limit
+ * on a pipe...
+ * rgerhards 2005-06-21: later, this will be a separate type, but let's
+ * emulate things for the time being. When everything runs, we can
+ * extend it...
+ */
+ f->f_type = F_FILE;
+ f->doAction = doActionFile;
+
+ ++p; /* skip '$' */
+ i = 0;
+ /* get outchannel name */
+ while(*p && *p != ';' && *p != ' ' &&
+ i < sizeof(szBuf) / sizeof(char)) {
+ szBuf[i++] = *p++;
+ }
+ szBuf[i] = '\0';
+
+ /* got the name, now look up the channel... */
+ pOch = ochFind(szBuf, i);
+
+ if(pOch == NULL) {
+ char errMsg[128];
+ errno = 0;
+ snprintf(errMsg, sizeof(errMsg)/sizeof(char),
+ "outchannel '%s' not found - ignoring action line",
+ szBuf);
+ logerror(errMsg);
+ f->f_type = F_UNUSED;
+ return;
+ }
+
+ /* check if there is a file name in the outchannel... */
+ if(pOch->pszFileTemplate == NULL) {
+ char errMsg[128];
+ errno = 0;
+ snprintf(errMsg, sizeof(errMsg)/sizeof(char),
+ "outchannel '%s' has no file name template - ignoring action line",
+ szBuf);
+ logerror(errMsg);
+ f->f_type = F_UNUSED;
+ return;
+ }
+
+ /* OK, we finally got a correct template. So let's use it... */
+ strncpy(f->f_un.f_file.f_fname, pOch->pszFileTemplate, MAXFNAME);
+ f->f_un.f_file.f_sizeLimit = pOch->uSizeLimit;
+ /* WARNING: It is dangerous "just" to pass the pointer. As we
+ * never rebuild the output channel description, this is acceptable here.
+ */
+ f->f_un.f_file.f_sizeLimitCmd = pOch->cmdOnSizeLimit;
+
+ /* back to the input string - now let's look for the template to use
+ * Just as a general precaution, we skip whitespace.
+ */
+ while(*p && isspace((int) *p))
+ ++p;
+ if(*p == ';')
+ ++p; /* eat it */
+
+ cflineParseTemplateName(&p, szBuf,
+ sizeof(szBuf) / sizeof(char));
+
+ if(szBuf[0] == '\0') /* no template? */
+ strcpy(szBuf, " TradFmt"); /* use default! */
+
+ cflineSetTemplateAndIOV(f, szBuf);
+
+ dprintf("[outchannel]filename: '%s', template: '%s', size: %lu\n", f->f_un.f_file.f_fname, szBuf,
+ f->f_un.f_file.f_sizeLimit);
+}
+
+
/* rgerhards 2005-06-21: Try to resolve a size limit
* situation. This first runs the command, and then
* checks if we are still above the treshold.
@@ -405,7 +493,7 @@ again:
/* free an instance
* returns 0 if it succeeds, something else otherwise
*/
-int freeInstanceFile(selector_t *f)
+rsRetVal freeInstanceFile(selector_t *f)
{
assert(f != NULL);
if(f->f_un.f_file.bDynamicName) {
@@ -419,12 +507,11 @@ int freeInstanceFile(selector_t *f)
/* call the shell action
* returns 0 if it succeeds, something else otherwise
*/
-int doActionFile(selector_t *f)
+rsRetVal doActionFile(selector_t *f)
{
assert(f != NULL);
dprintf(" (%s)\n", f->f_un.f_file.f_fname);
-printf("iovUsed address: %x, size %d\n",&f->f_iIovUsed, sizeof(selector_t));
/* f->f_file == -1 is an indicator that the we couldn't
* open the file at startup. For dynaFiles, this is ok,
* all others are doomed.
@@ -433,6 +520,173 @@ printf("iovUsed address: %x, size %d\n",&f->f_iIovUsed, sizeof(selector_t));
writeFile(f);
return 0;
}
+
+/* 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
+ */
+rsRetVal parseSelectorActFile(uchar **pp, selector_t *f)
+{
+ uchar *p;
+ int syncfile;
+ rsRetVal iRet = RS_RET_CONFLINE_PROCESSED;
+
+ assert(pp != NULL);
+ assert(f != NULL);
+
+ p = *pp;
+
+ if (*p == '-') {
+ syncfile = 0;
+ p++;
+ } else
+ syncfile = 1;
+
+ switch (*p)
+ {
+ case '$':
+ /* rgerhards 2005-06-21: this is a special setting for output-channel
+ * definitions. In the long term, this setting will probably replace
+ * anything else, but for the time being we must co-exist with the
+ * traditional mode lines.
+ */
+ cflineParseOutchannel(f, p);
+ f->f_un.f_file.bDynamicName = 0;
+ f->f_un.f_file.fCreateMode = fCreateMode; /* preserve current setting */
+ f->f_un.f_file.fDirCreateMode = fDirCreateMode; /* preserve current setting */
+ f->f_file = open(f->f_un.f_file.f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
+ f->f_un.f_file.fCreateMode);
+ break;
+
+ case '?': /* This is much like a regular file handle, but we need to obtain
+ * a template name. rgerhards, 2007-07-03
+ */
+ ++p; /* eat '?' */
+ cflineParseFileName(f, p);
+ f->f_un.f_file.pTpl = tplFind((char*)f->f_un.f_file.f_fname,
+ strlen((char*) f->f_un.f_file.f_fname));
+ if(f->f_un.f_file.pTpl == NULL) {
+ logerrorSz("Template '%s' not found - dynaFile deactivated.", f->f_un.f_file.f_fname);
+ f->f_type = F_UNUSED; /* that's it... :( */
+ }
+ if(f->f_type == F_UNUSED)
+ /* safety measure to make sure we have a valid
+ * selector line before we continue down below.
+ * rgerhards 2005-07-29
+ */
+ break;
+
+ if(syncfile)
+ f->f_flags |= SYNC_FILE;
+ f->f_un.f_file.bDynamicName = 1;
+ f->f_un.f_file.iCurrElt = -1; /* no current element */
+ f->f_un.f_file.fCreateMode = fCreateMode; /* freeze current setting */
+ f->f_un.f_file.fDirCreateMode = fDirCreateMode; /* preserve current setting */
+ f->f_un.f_file.bCreateDirs = bCreateDirs;
+ f->f_un.f_file.bFailOnChown = bFailOnChown;
+ f->f_un.f_file.fileUID = fileUID;
+ f->f_un.f_file.fileGID = fileGID;
+ f->f_un.f_file.dirUID = dirUID;
+ f->f_un.f_file.dirGID = dirGID;
+ f->f_un.f_file.iDynaFileCacheSize = iDynaFileCacheSize; /* freeze current setting */
+ /* we now allocate the cache table. We use calloc() intentionally, as we
+ * need all pointers to be initialized to NULL pointers.
+ */
+ if((f->f_un.f_file.dynCache = (dynaFileCacheEntry**)
+ calloc(iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))) == NULL) {
+ f->f_type = F_UNUSED;
+ dprintf("Could not allocate memory for dynaFileCache - selector disabled.\n");
+ }
+ break;
+
+ case '|':
+ case '/':
+ /* rgerhards 2004-11-17: from now, we need to have different
+ * processing, because after the first comma, the template name
+ * to use is specified. So we need to scan for the first coma first
+ * and then look at the rest of the line.
+ */
+ cflineParseFileName(f, p);
+ if(f->f_type == F_UNUSED)
+ /* safety measure to make sure we have a valid
+ * selector line before we continue down below.
+ * rgerhards 2005-07-29
+ */
+ break;
+
+ if(syncfile)
+ f->f_flags |= SYNC_FILE;
+ f->f_un.f_file.bDynamicName = 0;
+ f->f_un.f_file.fCreateMode = fCreateMode; /* preserve current setting */
+ if(f->f_type == F_PIPE) {
+ f->f_file = open(f->f_un.f_file.f_fname, O_RDWR|O_NONBLOCK);
+ } else {
+ f->f_file = open(f->f_un.f_file.f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
+ f->f_un.f_file.fCreateMode);
+ }
+
+ if ( f->f_file < 0 ){
+ f->f_file = -1;
+ dprintf("Error opening log file: %s\n", f->f_un.f_file.f_fname);
+ logerror(f->f_un.f_file.f_fname);
+ break;
+ }
+ if (isatty(f->f_file)) {
+ f->f_type = F_TTY;
+ untty();
+ }
+ if (strcmp((char*) p, ctty) == 0)
+ f->f_type = F_CONSOLE;
+ break;
+ default:
+ iRet = RS_RET_CONFLINE_UNPROCESSED;
+ break;
+ }
+
+ if(iRet == RS_RET_CONFLINE_PROCESSED)
+ *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, "freeInstance")) {
+ *pEtryPoint = freeInstanceFile;
+ }
+
+ 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;
+
+ *ipIFVersProvided = 1; /* so far, we only support the initial definition */
+
+ *pQueryEtryPt = queryEtryPt;
+ return RS_RET_OK;
+}
+
+
/*
* vi:set ai:
*/
diff --git a/omfile.h b/omfile.h
index 330ee4c1..e2b77706 100644
--- a/omfile.h
+++ b/omfile.h
@@ -26,8 +26,10 @@
/* prototypes */
-int doActionFile(selector_t *f);
-int freeInstanceFile(selector_t *f);
+rsRetVal doActionFile(selector_t *f);
+rsRetVal freeInstanceFile(selector_t *f);
+rsRetVal modInitFile(int iIFVersRequested, int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)());
+rsRetVal parseSelectorActFile(uchar **pp, selector_t *f);
#endif /* #ifndef OMFILE_H_INCLUDED */
/*
diff --git a/omfwd.c b/omfwd.c
index 037bc26f..e38756c6 100644
--- a/omfwd.c
+++ b/omfwd.c
@@ -237,6 +237,42 @@ int doActionFwd(selector_t *f)
return 0;
}
+/* 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 = doActionFwd;
+ } /*else if(!strcmp((char*) name, "freeInstance")) {
+ *pEtryPoint = freeInstanceFile;
+ }*/
+
+ 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 modInitFwd(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())
+{
+ if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))
+ return RS_RET_PARAM_ERROR;
+
+ *ipIFVersProvided = 1; /* so far, we only support the initial definition */
+
+ *pQueryEtryPt = queryEtryPt;
+ return RS_RET_OK;
+}
#endif /* #ifdef SYSLOG_INET */
/*
* vi:set ai:
diff --git a/omfwd.h b/omfwd.h
index 6735f6dd..391c73c2 100644
--- a/omfwd.h
+++ b/omfwd.h
@@ -25,8 +25,8 @@
#define OMFWD_H_INCLUDED 1
/* prototypes */
-
int doActionFwd(selector_t *f);
+rsRetVal modInitFwd(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)());
#endif /* #ifndef OMFWD_H_INCLUDED */
/*
diff --git a/ommysql.c b/ommysql.c
index 34fead8b..9cacd0bb 100644
--- a/ommysql.c
+++ b/ommysql.c
@@ -268,6 +268,42 @@ int doActionMySQL(selector_t *f)
return 0;
}
+/* 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, "freeInstance")) {
+ *pEtryPoint = freeInstanceFile;
+ }*/
+
+ 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 modInitMySQL(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)())
+{
+ if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))
+ return RS_RET_PARAM_ERROR;
+
+ *ipIFVersProvided = 1; /* so far, we only support the initial definition */
+
+ *pQueryEtryPt = queryEtryPt;
+ return RS_RET_OK;
+}
#endif /* #ifdef WITH_DB */
/*
* vi:set ai:
diff --git a/ommysql.h b/ommysql.h
index af654b8c..6b2bcc10 100644
--- a/ommysql.h
+++ b/ommysql.h
@@ -34,7 +34,7 @@ void writeMySQL(register selector_t *f);
void closeMySQL(register selector_t *f);
void reInitMySQL(register selector_t *f);
int checkDBErrorState(register selector_t *f);
-//void DBErrorHandler(register selector_t *f);
+rsRetVal modInitMySQL(int iIFVersRequested, int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)());
int doActionMySQL(selector_t *f);
diff --git a/omshell.c b/omshell.c
index 001fbe2d..05d61a9e 100644
--- a/omshell.c
+++ b/omshell.c
@@ -61,6 +61,42 @@ int doActionShell(selector_t *f)
return 0;
}
+/* 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, "freeInstance")) {
+ *pEtryPoint = freeInstanceFile;
+ }*/
+
+ 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;
+
+ *ipIFVersProvided = 1; /* so far, we only support the initial definition */
+
+ *pQueryEtryPt = queryEtryPt;
+ return RS_RET_OK;
+}
/*
* vi:set ai:
*/
diff --git a/omshell.h b/omshell.h
index 69558ab7..fa146eb8 100644
--- a/omshell.h
+++ b/omshell.h
@@ -25,8 +25,8 @@
#define ACTSHELL_H_INCLUDED 1
/* prototypes */
-
int doActionShell(selector_t *f);
+rsRetVal modInitShell(int iIFVersRequested, int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)());
#endif /* #ifndef ACTSHELL_H_INCLUDED */
/*
diff --git a/omusrmsg.c b/omusrmsg.c
index eb3c15be..6d400655 100644
--- a/omusrmsg.c
+++ b/omusrmsg.c
@@ -205,7 +205,7 @@ static void wallmsg(selector_t *f)
/* call the shell action
* returns 0 if it succeeds, something else otherwise
*/
-int doActionUsrMsg(selector_t *f)
+static int doAction(selector_t *f)
{
assert(f != NULL);
@@ -214,6 +214,132 @@ int doActionUsrMsg(selector_t *f)
return 0;
}
+/* 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, "freeInstance")) {
+ *pEtryPoint = freeInstanceFile;
+ }*/
+
+ return(*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;
+}
+
+/* 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
+ */
+rsRetVal parseSelectorActUsrMsg(uchar **pp, selector_t *f)
+{
+ uchar *p, *q;
+ int i;
+ char szTemplateName[128];
+
+ assert(pp != NULL);
+ assert(f != NULL);
+
+#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(*p == '*') { /* wall */
+ dprintf ("write-all");
+ f->f_type = F_WALL;
+ f->doAction = doAction;
+ if(*(p+1) == ';') {
+ /* we have a template specifier! */
+ p += 2; /* eat "*;" */
+ cflineParseTemplateName(&p, szTemplateName,
+ sizeof(szTemplateName) / sizeof(uchar));
+ }
+ else /* assign default format if none given! */
+ szTemplateName[0] = '\0';
+ if(szTemplateName[0] == '\0')
+ strcpy(szTemplateName, " WallFmt");
+ cflineSetTemplateAndIOV(f, szTemplateName);
+ if(f->f_type != F_UNUSED)
+ /* safety measure to make sure we have a valid
+ * selector line before we continue down below.
+ * rgerhards 2005-07-29
+ */
+ dprintf(" template '%s'\n", szTemplateName);
+ } else {
+ /* everything else is currently treated as a user name
+ * TODO: we must reconsider this - see also comment in
+ * loadBuildInModules() in syslogd.c
+ */
+ dprintf ("users: %s\n", p); /* ASP */
+ f->f_type = F_USERS;
+ f->doAction = doAction;
+ for (i = 0; i < MAXUNAMES && *p && *p != ';'; i++) {
+ for (q = p; *q && *q != ',' && *q != ';'; )
+ q++;
+ (void) strncpy((char*) f->f_un.f_uname[i], (char*) p, UNAMESZ);
+ if ((q - p) > UNAMESZ)
+ f->f_un.f_uname[i][UNAMESZ] = '\0';
+ else
+ f->f_un.f_uname[i][q - p] = '\0';
+ while (*q == ',' || *q == ' ')
+ q++;
+ p = q;
+ }
+ /* done, now check if we have a template name
+ * TODO: we need to handle the case where i >= MAXUNAME!
+ */
+ szTemplateName[0] = '\0';
+ if(*p == ';') {
+ /* we have a template specifier! */
+ ++p; /* eat ";" */
+ cflineParseTemplateName(&p, szTemplateName,
+ sizeof(szTemplateName) / sizeof(char));
+ }
+ if(szTemplateName[0] == '\0')
+ strcpy(szTemplateName, " StdUsrMsgFmt");
+ cflineSetTemplateAndIOV(f, szTemplateName);
+ /* Please note that we would need to check if the template
+ * was found. If not, f->f_type would be F_UNUSED and we
+ * can NOT carry on processing. These checks can be seen
+ * on all other selector line code above. However, as we
+ * do not have anything else to do here, we do not include
+ * this check. Should you add any further processing at
+ * this point here, you must first add a check for this
+ * condition!
+ * rgerhards 2005-07-29
+ */
+ }
+
+ *pp = p;
+ return RS_RET_CONFLINE_PROCESSED;
+}
+
+/* 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;
+
+ *ipIFVersProvided = 1; /* so far, we only support the initial definition */
+
+ *pQueryEtryPt = queryEtryPt;
+ return RS_RET_OK;
+}
+
/*
* vi:set ai:
*/
diff --git a/omusrmsg.h b/omusrmsg.h
index fe176a57..177b83d3 100644
--- a/omusrmsg.h
+++ b/omusrmsg.h
@@ -25,8 +25,8 @@
#define OMUSRMSG_H_INCLUDED 1
/* prototypes */
-
-int doActionUsrMsg(selector_t *f);
+rsRetVal modInitUsrMsg(int iIFVersRequested, int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)());
+rsRetVal parseSelectorActUsrMsg(uchar **pp, selector_t *f);
#endif /* #ifndef OMUSRMSG_H_INCLUDED */
/*
diff --git a/rsyslog.h b/rsyslog.h
index 9927264d..3884635d 100644
--- a/rsyslog.h
+++ b/rsyslog.h
@@ -45,6 +45,11 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_NO_MORE_DATA = -3006, /**< insufficient data, e.g. end of string during parsing */
RS_RET_INVALID_IP = -3007, /**< invalid ip found where valid was expected */
RS_RET_OBJ_CREATION_FAILED = - 3008, /**< the creation of an object failed (no details available) */
+ 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_OK = 0 /**< operation successful */
};
typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */
@@ -106,3 +111,6 @@ typedef unsigned char uchar;
#endif
#endif /* multi-include protection */
+/*
+ * vi:set ai:
+ */
diff --git a/srUtils.c b/srUtils.c
index b38f69c1..6080d607 100755
--- a/srUtils.c
+++ b/srUtils.c
@@ -115,7 +115,7 @@ uchar *srUtilStrDup(uchar *pOld, size_t len)
* are to be created with.
*/
int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode,
- uid_t uid, gid_t gid, int bFailOnChown)
+ uid_t uid, gid_t gid, int bFailOnChownFail)
{
uchar *p;
uchar *pszWork;
@@ -138,7 +138,7 @@ int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode,
if(uid != (uid_t) -1 || gid != (gid_t) -1) {
/* we need to set owner/group */
if(chown((char*)pszWork, uid, gid) != 0)
- if(bFailOnChown)
+ if(bFailOnChownFail)
bErr = 1;
/* silently ignore if configured
* to do so.
diff --git a/syslogd.c b/syslogd.c
index 0429a854..8dca5d28 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -213,6 +213,7 @@
#include "parse.h"
#include "msg.h"
+#include "modules.h"
#include "tcpsyslog.h"
#include "omshell.h"
#include "omusrmsg.h"
@@ -357,7 +358,7 @@ syslogCODE rs_facilitynames[] =
static char *ConfFile = _PATH_LOGCONF; /* read-only after startup */
static char *PidFile = _PATH_LOGPID; /* read-only after startup */
-static char ctty[] = _PATH_CONSOLE; /* this is read-only */
+char ctty[] = _PATH_CONSOLE; /* this is read-only */
static int bModMySQLLoaded = 0; /* was a $ModLoad MySQL done? */
static pid_t myPid; /* our pid for use in self-generated messages, e.g. on startup */
@@ -369,9 +370,9 @@ static int bRequestDoMark = 0; /* do mark processing? (multithread safe) */
#define MAXFUNIX 20
int glblHadMemShortage = 0; /* indicates if we had memory shortage some time during the run */
-static int iDynaFileCacheSize = 10; /* max cache for dynamic files */
-static int fCreateMode = 0644; /* mode to use when creating files */
-static int fDirCreateMode = 0644; /* mode to use when creating files */
+int iDynaFileCacheSize = 10; /* max cache for dynamic files */
+int fCreateMode = 0644; /* mode to use when creating files */
+int fDirCreateMode = 0644; /* mode to use when creating files */
int nfunix = 1; /* number of Unix sockets open / read-only after startup */
int startIndexUxLocalSockets = 0; /* process funix from that index on (used to
* suppress local logging. rgerhards 2005-08-01
@@ -533,13 +534,13 @@ static struct code FacNames[] = {
/* global variables for config file state */
static int bDropTrailingLF = 1; /* drop trailing LF's on reception? */
int Debug; /* debug flag - read-only after startup */
-static int bFailOnChown; /* fail if chown fails? */
-static uid_t fileUID; /* UID to be used for newly created files */
-static uid_t fileGID; /* GID to be used for newly created files */
-static uid_t dirUID; /* UID to be used for newly created directories */
-static uid_t dirGID; /* GID to be used for newly created directories */
+int bFailOnChown; /* fail if chown fails? */
+uid_t fileUID; /* UID to be used for newly created files */
+uid_t fileGID; /* GID to be used for newly created files */
+uid_t dirUID; /* UID to be used for newly created directories */
+uid_t dirGID; /* GID to be used for newly created directories */
+int bCreateDirs; /* auto-create directories for dynaFiles: 0 - no, 1 - yes */
static int bDebugPrintTemplateList;/* output template list in debug mode? */
-static int bCreateDirs; /* auto-create directories for dynaFiles: 0 - no, 1 - yes */
int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
static uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */
static int bEscapeCCOnRcv; /* escape control characters on reception: 0 - no, 1 - yes */
@@ -672,7 +673,6 @@ static void sighup_handler();
static void die(int sig);
static int getSubString(uchar **pSrc, char *pDst, size_t DstSize, char cSep);
-static void cflineSetTemplateAndIOV(selector_t *f, char *pTemplateName);
/* Access functions for the selector_t. These functions are primarily
* necessary to make things thread-safe. Consequently, they are slim
@@ -4462,6 +4462,7 @@ static void init()
printf("\n");
if(bDebugPrintTemplateList)
tplPrintList();
+ modPrintList();
ochPrintList();
#ifdef SYSLOG_INET
@@ -4508,7 +4509,7 @@ static void init()
* to a filed entry and allocates memory for its iovec.
* rgerhards 2004-11-19
*/
-static void cflineSetTemplateAndIOV(selector_t *f, char *pTemplateName)
+void cflineSetTemplateAndIOV(selector_t *f, char *pTemplateName)
{
char errMsg[512];
@@ -4553,7 +4554,7 @@ static void cflineSetTemplateAndIOV(selector_t *f, char *pTemplateName)
* to be \0 in this case.
* rgerhards 2004-11-19
*/
-static void cflineParseTemplateName(uchar** pp,
+void cflineParseTemplateName(uchar** pp,
register char* pTemplateName, int iLenTemplate)
{
register uchar *p;
@@ -4584,7 +4585,7 @@ static void cflineParseTemplateName(uchar** pp,
* filed struct.
* rgerhards 2004-11-18
*/
-static void cflineParseFileName(selector_t *f, uchar* p)
+void cflineParseFileName(selector_t *f, uchar* p)
{
register char *pName;
int i;
@@ -4627,93 +4628,6 @@ static void cflineParseFileName(selector_t *f, uchar* p)
}
-/* Helper to cfline(). Parses a output channel name up until the first
- * comma and then looks for the template specifier. Tries
- * to find that template. Maps the output channel to the
- * proper filed structure settings. Everything is stored in the
- * filed struct. Over time, the dependency on filed might be
- * removed.
- * rgerhards 2005-06-21
- */
-static void cflineParseOutchannel(selector_t *f, uchar* p)
-{
- size_t i;
- struct outchannel *pOch;
- char szBuf[128]; /* should be more than sufficient */
-
- /* this must always be a file, because we can not set a size limit
- * on a pipe...
- * rgerhards 2005-06-21: later, this will be a separate type, but let's
- * emulate things for the time being. When everything runs, we can
- * extend it...
- */
- f->f_type = F_FILE;
- f->doAction = doActionFile;
-
- ++p; /* skip '$' */
- i = 0;
- /* get outchannel name */
- while(*p && *p != ';' && *p != ' ' &&
- i < sizeof(szBuf) / sizeof(char)) {
- szBuf[i++] = *p++;
- }
- szBuf[i] = '\0';
-
- /* got the name, now look up the channel... */
- pOch = ochFind(szBuf, i);
-
- if(pOch == NULL) {
- char errMsg[128];
- errno = 0;
- snprintf(errMsg, sizeof(errMsg)/sizeof(char),
- "outchannel '%s' not found - ignoring action line",
- szBuf);
- logerror(errMsg);
- f->f_type = F_UNUSED;
- return;
- }
-
- /* check if there is a file name in the outchannel... */
- if(pOch->pszFileTemplate == NULL) {
- char errMsg[128];
- errno = 0;
- snprintf(errMsg, sizeof(errMsg)/sizeof(char),
- "outchannel '%s' has no file name template - ignoring action line",
- szBuf);
- logerror(errMsg);
- f->f_type = F_UNUSED;
- return;
- }
-
- /* OK, we finally got a correct template. So let's use it... */
- strncpy(f->f_un.f_file.f_fname, pOch->pszFileTemplate, MAXFNAME);
- f->f_un.f_file.f_sizeLimit = pOch->uSizeLimit;
- /* WARNING: It is dangerous "just" to pass the pointer. As we
- * never rebuild the output channel description, this is acceptable here.
- */
- f->f_un.f_file.f_sizeLimitCmd = pOch->cmdOnSizeLimit;
-
- /* back to the input string - now let's look for the template to use
- * Just as a general precaution, we skip whitespace.
- */
- while(*p && isspace((int) *p))
- ++p;
- if(*p == ';')
- ++p; /* eat it */
-
- cflineParseTemplateName(&p, szBuf,
- sizeof(szBuf) / sizeof(char));
-
- if(szBuf[0] == '\0') /* no template? */
- strcpy(szBuf, " TradFmt"); /* use default! */
-
- cflineSetTemplateAndIOV(f, szBuf);
-
- dprintf("[outchannel]filename: '%s', template: '%s', size: %lu\n", f->f_un.f_file.f_fname, szBuf,
- f->f_un.f_file.f_sizeLimit);
-}
-
-
/*
* Helper to cfline(). This function takes the filter part of a traditional, PRI
* based line and decodes the PRIs given in the selector line. It processed the
@@ -5323,123 +5237,14 @@ static rsRetVal cfline(char *line, register selector_t *f)
break;
case '$':
- /* rgerhards 2005-06-21: this is a special setting for output-channel
- * definitions. In the long term, this setting will probably replace
- * anything else, but for the time being we must co-exist with the
- * traditional mode lines.
- */
- cflineParseOutchannel(f, p);
- f->f_un.f_file.bDynamicName = 0;
- f->f_un.f_file.fCreateMode = fCreateMode; /* preserve current setting */
- f->f_un.f_file.fDirCreateMode = fDirCreateMode; /* preserve current setting */
- f->f_file = open(f->f_un.f_file.f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
- f->f_un.f_file.fCreateMode);
- break;
-
- case '?': /* This is much like a regular file handle, but we need to obtain
- * a template name. rgerhards, 2007-07-03
- */
- ++p; /* eat '?' */
- cflineParseFileName(f, p);
- f->f_un.f_file.pTpl = tplFind((char*)f->f_un.f_file.f_fname,
- strlen((char*) f->f_un.f_file.f_fname));
- if(f->f_un.f_file.pTpl == NULL) {
- logerrorSz("Template '%s' not found - dynaFile deactivated.", f->f_un.f_file.f_fname);
- f->f_type = F_UNUSED; /* that's it... :( */
- }
- if(f->f_type == F_UNUSED)
- /* safety measure to make sure we have a valid
- * selector line before we continue down below.
- * rgerhards 2005-07-29
- */
- break;
-
- if(syncfile)
- f->f_flags |= SYNC_FILE;
- f->f_un.f_file.bDynamicName = 1;
- f->f_un.f_file.iCurrElt = -1; /* no current element */
- f->f_un.f_file.fCreateMode = fCreateMode; /* freeze current setting */
- f->f_un.f_file.fDirCreateMode = fDirCreateMode; /* preserve current setting */
- f->f_un.f_file.bCreateDirs = bCreateDirs;
- f->f_un.f_file.bFailOnChown = bFailOnChown;
- f->f_un.f_file.fileUID = fileUID;
- f->f_un.f_file.fileGID = fileGID;
- f->f_un.f_file.dirUID = dirUID;
- f->f_un.f_file.dirGID = dirGID;
- f->f_un.f_file.iDynaFileCacheSize = iDynaFileCacheSize; /* freeze current setting */
- /* we now allocate the cache table. We use calloc() intentionally, as we
- * need all pointers to be initialized to NULL pointers.
- */
- if((f->f_un.f_file.dynCache = (dynaFileCacheEntry**)
- calloc(iDynaFileCacheSize, sizeof(dynaFileCacheEntry*))) == NULL) {
- f->f_type = F_UNUSED;
- dprintf("Could not allocate memory for dynaFileCache - selector disabled.\n");
- }
- break;
-
+ case '?':
case '|':
case '/':
- /* rgerhards 2004-11-17: from now, we need to have different
- * processing, because after the first comma, the template name
- * to use is specified. So we need to scan for the first coma first
- * and then look at the rest of the line.
- */
- cflineParseFileName(f, p);
- if(f->f_type == F_UNUSED)
- /* safety measure to make sure we have a valid
- * selector line before we continue down below.
- * rgerhards 2005-07-29
- */
- break;
-
- if(syncfile)
- f->f_flags |= SYNC_FILE;
- f->f_un.f_file.bDynamicName = 0;
- f->f_un.f_file.fCreateMode = fCreateMode; /* preserve current setting */
- if(f->f_type == F_PIPE) {
- f->f_file = open(f->f_un.f_file.f_fname, O_RDWR|O_NONBLOCK);
- } else {
- f->f_file = open(f->f_un.f_file.f_fname, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
- f->f_un.f_file.fCreateMode);
- }
-
- if ( f->f_file < 0 ){
- f->f_file = -1;
- dprintf("Error opening log file: %s\n", f->f_un.f_file.f_fname);
- logerror(f->f_un.f_file.f_fname);
- break;
- }
- if (isatty(f->f_file)) {
- f->f_type = F_TTY;
- untty();
- }
- if (strcmp((char*) p, ctty) == 0)
- f->f_type = F_CONSOLE;
+ parseSelectorActFile(&p, f);
break;
case '*':
- dprintf ("write-all");
- f->f_type = F_WALL;
- f->doAction = doActionUsrMsg;
- if(*(p+1) == ';') {
- /* we have a template specifier! */
- p += 2; /* eat "*;" */
- cflineParseTemplateName(&p, szTemplateName,
- sizeof(szTemplateName) / sizeof(uchar));
- }
- else /* assign default format if none given! */
- szTemplateName[0] = '\0';
- if(szTemplateName[0] == '\0')
- strcpy(szTemplateName, " WallFmt");
- cflineSetTemplateAndIOV(f, szTemplateName);
- if(f->f_type == F_UNUSED)
- /* safety measure to make sure we have a valid
- * selector line before we continue down below.
- * rgerhards 2005-07-29
- */
- break;
-
- dprintf(" template '%s'\n", szTemplateName);
+ parseSelectorActUsrMsg(&p, f);
break;
case '~': /* rgerhards 2005-09-09: added support for discard */
@@ -5541,45 +5346,7 @@ static rsRetVal cfline(char *line, register selector_t *f)
break;
default:
- dprintf ("users: %s\n", p); /* ASP */
- f->f_type = F_USERS;
- f->doAction = doActionUsrMsg;
- for (i = 0; i < MAXUNAMES && *p && *p != ';'; i++) {
- for (q = p; *q && *q != ',' && *q != ';'; )
- q++;
- (void) strncpy((char*) f->f_un.f_uname[i], (char*) p, UNAMESZ);
- if ((q - p) > UNAMESZ)
- f->f_un.f_uname[i][UNAMESZ] = '\0';
- else
- f->f_un.f_uname[i][q - p] = '\0';
- while (*q == ',' || *q == ' ')
- q++;
- p = q;
- }
- /* done, now check if we have a template name
- * TODO: we need to handle the case where i >= MAXUNAME!
- */
- szTemplateName[0] = '\0';
- if(*p == ';') {
- /* we have a template specifier! */
- ++p; /* eat ";" */
- cflineParseTemplateName(&p, szTemplateName,
- sizeof(szTemplateName) / sizeof(char));
- }
- if(szTemplateName[0] == '\0')
- strcpy(szTemplateName, " StdUsrMsgFmt");
- cflineSetTemplateAndIOV(f, szTemplateName);
- /* Please note that we would need to check if the template
- * was found. If not, f->f_type would be F_UNUSED and we
- * can NOT carry on processing. These checks can be seen
- * on all other selector line code above. However, as we
- * do not have anything else to do here, we do not include
- * this check. Should you add any further processing at
- * this point here, you must first add a check for this
- * condition!
- * rgerhards 2005-07-29
- */
- break;
+ parseSelectorActUsrMsg(&p, f);
}
return RS_RET_OK;
}
@@ -6157,10 +5924,44 @@ static void checkPermissions()
}
}
+
+/* load build-in modules
+ * very first version begun on 2007-07-23 by rgerhards
+ */
+static rsRetVal loadBuildInModules(void)
+{
+ rsRetVal iRet;
+
+ if((iRet = doModInit(modInitFile, (uchar*) "builtin-file")) != RS_RET_OK)
+ return iRet;
+ if((iRet = doModInit(modInitFwd, (uchar*) "builtin-fwd")) != RS_RET_OK)
+ return iRet;
+ if((iRet = doModInit(modInitShell, (uchar*) "builtin-shell")) != RS_RET_OK)
+ return iRet;
+# ifdef WITH_DB
+ if((iRet = doModInit(modInitMySQL, (uchar*) "builtin-mysql")) != RS_RET_OK)
+ return iRet;
+# endif
+
+ /* dirty, but this must be for the time being: the usrmsg module must always be
+ * loaded as last module. This is because it processes any time of action selector.
+ * If we load it before other modules, these others will never have a chance of
+ * working with the config file. We may change that implementation so that a user name
+ * must start with an alnum, that would definitely help (but would it break backwards
+ * compatibility?). * rgerhards, 2007-07-23
+ */
+ if((iRet = doModInit(modInitUsrMsg, (uchar*) "builtin-usrmsg")) != RS_RET_OK)
+ return iRet;
+
+ return RS_RET_OK;
+}
+
+
int main(int argc, char **argv)
{ register int i;
register char *p;
int num_fds;
+ rsRetVal iRet;
#ifdef MTRACE
mtrace(); /* this is a debug aid for leak detection - either remove
@@ -6185,6 +5986,12 @@ int main(int argc, char **argv)
funix[i] = -1;
}
+ if((iRet = loadBuildInModules()) != RS_RET_OK) {
+ fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n",
+ iRet);
+ exit(1); /* "good" exit, leaving at init for fatal error */
+ }
+
while ((ch = getopt(argc, argv, "46Aa:dehi:f:l:m:nop:r::s:t:u:vwx")) != EOF) {
switch((char)ch) {
case '4':
diff --git a/syslogd.h b/syslogd.h
index 05df1294..88183633 100644
--- a/syslogd.h
+++ b/syslogd.h
@@ -84,6 +84,9 @@ int formatTimestamp3164(struct syslogTime *ts, char* pBuf, size_t iLenBuf);
void iovCreate(selector_t *f);
char *iovAsString(selector_t *f);
void untty(void);
+void cflineSetTemplateAndIOV(selector_t *f, char *pTemplateName);
+void cflineParseTemplateName(uchar** pp, register char* pTemplateName, int iLenTemplate);
+void cflineParseFileName(selector_t *f, uchar* p);
extern int glblHadMemShortage; /* indicates if we had memory shortage some time during the run */
extern syslogCODE rs_prioritynames[];
@@ -101,5 +104,15 @@ extern char **StripDomains;
extern char *LocalDomain;
extern int bDropMalPTRMsgs;
extern struct AllowedSenders *pAllowedSenders_TCP;
+extern int fCreateMode;
+extern int fDirCreateMode;
+extern int bFailOnChown;
+extern uid_t fileUID;
+extern uid_t fileGID;
+extern uid_t dirUID;
+extern uid_t dirGID;
+extern int bCreateDirs;
+extern int iDynaFileCacheSize;
+extern char ctty[];
#endif /* #ifndef SYSLOGD_H_INCLUDED */