summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-08-01 09:57:02 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-08-01 09:57:02 +0000
commitbec7683ec23befea56d885bc18e7e0fdc6fdf08b (patch)
tree62007690114b8dde08639c1e9e71e592756a0646
parent6c305fdc9a635e03727b19425318ce2eab924c0b (diff)
downloadrsyslog-bec7683ec23befea56d885bc18e7e0fdc6fdf08b.tar.gz
rsyslog-bec7683ec23befea56d885bc18e7e0fdc6fdf08b.tar.xz
rsyslog-bec7683ec23befea56d885bc18e7e0fdc6fdf08b.zip
enhanced $Include to allow inclusion of a complete directory
-rw-r--r--cfsysline.c20
-rw-r--r--configure.ac2
-rw-r--r--syslogd.c86
3 files changed, 100 insertions, 8 deletions
diff --git a/cfsysline.c b/cfsysline.c
index af197269..6244c2ee 100644
--- a/cfsysline.c
+++ b/cfsysline.c
@@ -436,7 +436,7 @@ static rsRetVal cslchCallHdlr(cslCmdHdlr_t *pThis, uchar **ppConfLine)
CHKiRet(pHdlr(ppConfLine, pThis->cslCmdHdlr, pThis->pData));
finalize_it:
- return RS_RET_OK;
+ return iRet;
}
@@ -571,6 +571,7 @@ finalize_it:
rsRetVal processCfSysLineCommand(uchar *pCmdName, uchar **p)
{
DEFiRet;
+ rsRetVal iRetLL; /* for linked list handling */
cslCmd_t *pCmd;
cslCmdHdlr_t *pCmdHdlr;
linkedListCookie_t llCookieCmdHdlr;
@@ -578,10 +579,18 @@ rsRetVal processCfSysLineCommand(uchar *pCmdName, uchar **p)
int bWasOnceOK; /* was the result of an handler at least once RS_RET_OK? */
uchar *pOKp = NULL; /* returned conf line pointer when it was OK */
- CHKiRet(llFind(&llCmdList, (void *) pCmdName, (void**) &pCmd));
+ iRet = llFind(&llCmdList, (void *) pCmdName, (void**) &pCmd);
+
+ if(iRet == RS_RET_NOT_FOUND) {
+ logerror("invalid or yet-unknown config file command - have you forgotten to load a module?");
+ }
+
+ if(iRet != RS_RET_OK)
+ goto finalize_it;
+
llCookieCmdHdlr = NULL;
bWasOnceOK = 0;
- while((iRet = llGetNextElt(&pCmd->llCmdHdlrs, &llCookieCmdHdlr, (void**)&pCmdHdlr)) == RS_RET_OK) {
+ while((iRetLL = llGetNextElt(&pCmd->llCmdHdlrs, &llCookieCmdHdlr, (void**)&pCmdHdlr)) == RS_RET_OK) {
/* for the time being, we ignore errors during handlers. The
* reason is that handlers are independent. An error in one
* handler does not necessarily mean that another one will
@@ -590,7 +599,7 @@ rsRetVal processCfSysLineCommand(uchar *pCmdName, uchar **p)
* necessary). -- rgerhards, 2007-07-31
*/
pHdlrP = *p;
- if(cslchCallHdlr(pCmdHdlr, &pHdlrP) == RS_RET_OK) {
+ if((iRet = cslchCallHdlr(pCmdHdlr, &pHdlrP)) == RS_RET_OK) {
bWasOnceOK = 1;
pOKp = pHdlrP;
}
@@ -601,6 +610,9 @@ rsRetVal processCfSysLineCommand(uchar *pCmdName, uchar **p)
iRet = RS_RET_OK;
}
+ if(iRetLL != RS_RET_END_OF_LINKEDLIST)
+ iRet = iRetLL;
+
finalize_it:
return iRet;
}
diff --git a/configure.ac b/configure.ac
index 1e11c930..0d3f1ed5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,7 +65,7 @@ AC_TYPE_SIGNAL
AC_FUNC_STAT
AC_FUNC_VPRINTF
AC_FUNC_WAIT3
-AC_CHECK_FUNCS([setsid alarm gethostbyname gethostname gettimeofday memset regcomp select socket strcasecmp strchr strerror strndup strrchr strstr strtol strtoul uname])
+AC_CHECK_FUNCS([setsid alarm gethostbyname gethostname gettimeofday memset regcomp select socket strcasecmp strchr strerror strndup strnlen strrchr strstr strtol strtoul uname])
# Large file support
diff --git a/syslogd.c b/syslogd.c
index 7f0a4673..f6ef5fc0 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -144,6 +144,7 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
+#include <stddef.h>
#include <ctype.h>
#define GNU_SOURCE
#include <string.h>
@@ -172,6 +173,7 @@
#include <netinet/in.h>
#include <netdb.h>
#include <fnmatch.h>
+#include <dirent.h>
#ifndef __sun
#endif
@@ -3419,6 +3421,77 @@ static rsRetVal addAllowedSenderLine(char* pName, uchar** ppRestOfConfLine)
}
+/* process a directory and include all of its files into
+ * the current config file. There is no specific order of inclusion,
+ * files are included in the order they are read from the directory.
+ * The caller must have make sure that the provided parameter is
+ * indeed a directory.
+ * rgerhards, 2007-08-01
+ */
+static rsRetVal doIncludeDirectory(uchar *pDirName)
+{
+ DEFiRet;
+ int iEntriesDone = 0;
+ DIR *pDir;
+ union {
+ struct dirent d;
+ char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
+ } u;
+ struct dirent *res;
+ size_t iDirNameLen;
+ size_t iFileNameLen;
+ uchar szFullFileName[MAXFNAME];
+
+ assert(pDirName != NULL);
+
+ if((pDir = opendir((char*) pDirName)) == NULL) {
+ logerror("error opening include directory");
+ ABORT_FINALIZE(RS_RET_FOPEN_FAILURE);
+ }
+
+ /* prepare file name buffer */
+ iDirNameLen = strlen((char*) pDirName);
+ memcpy(szFullFileName, pDirName, iDirNameLen);
+
+ /* now read the directory */
+ iEntriesDone = 0;
+ while(readdir_r(pDir, &u.d, &res) == 0) {
+ if(res == NULL)
+ break; /* this also indicates end of directory */
+ if(res->d_type != DT_REG)
+ continue; /* we are not interested in special files */
+ if(res->d_name[0] == '.')
+ continue; /* these files we are also not interested in */
+ ++iEntriesDone;
+ /* construct filename */
+ iFileNameLen = strnlen(res->d_name, NAME_MAX);
+ memcpy(szFullFileName + iDirNameLen, res->d_name, iFileNameLen);
+ *(szFullFileName + iDirNameLen + iFileNameLen) = '\0';
+ dprintf("including file '%s'\n", szFullFileName);
+ processConfFile(szFullFileName);
+ /* we deliberately ignore the iRet of processConfFile() - this is because
+ * failure to process one file does not mean all files will fail. By ignoring,
+ * we retry with the next file, which is the best thing we can do. -- rgerhards, 2007-08-01
+ */
+ }
+
+ if(iEntriesDone == 0) {
+ /* I just make it a debug output, because I can think of a lot of cases where it
+ * makes sense not to have any files. E.g. a system maintainer may place a $Include
+ * into the config file just in case, when additional modules be installed. When none
+ * are installed, the directory will be empty, which is fine. -- rgerhards 2007-08-01
+ */
+ dprintf("warning: the include directory contained no files - this may be ok.\n");
+ }
+
+finalize_it:
+ if(pDir != NULL)
+ closedir(pDir);
+
+ return iRet;
+}
+
+
/* process a $include config line. That type of line requires
* inclusion of another file.
* rgerhards, 2007-08-01
@@ -3436,9 +3509,13 @@ static rsRetVal doIncludeLine(uchar **pp, __attribute__((unused)) void* pVal)
ABORT_FINALIZE(RS_RET_NOT_FOUND);
}
- dprintf("Requested to include config file '%s'\n", cfgFile);
-
- processConfFile(cfgFile);
+ if(*(cfgFile+strlen((char*) cfgFile) - 1) == '/') {
+ dprintf("requested to include directory '%s'\n", cfgFile);
+ iRet = doIncludeDirectory(cfgFile);
+ } else {
+ dprintf("Requested to include config file '%s'\n", cfgFile);
+ iRet = processConfFile(cfgFile);
+ }
finalize_it:
return iRet;
@@ -3572,6 +3649,8 @@ rsRetVal cfsysline(uchar *p)
/* we now try and see if we can find the command in the registered
* list of cfsysline handlers. -- rgerhards, 2007-07-31
*/
+ CHKiRet(processCfSysLineCommand(szCmd, &p));
+#if 0
if((iRet = processCfSysLineCommand(szCmd, &p)) != RS_RET_OK) {
/* invalid command! */
char err[256];
@@ -3580,6 +3659,7 @@ rsRetVal cfsysline(uchar *p)
logerror(err);
ABORT_FINALIZE(RS_RET_INVALID_CMD);
}
+#endif
/* now check if we have some extra characters left on the line - that
* should not be the case. Whitespace is OK, but everything else should