summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarius Tomaschewski <mt@suse.de>2008-10-20 17:36:31 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2008-10-20 17:36:31 +0200
commit19ccebbf4c49c5f9954c7a1a092399303156a1f3 (patch)
tree026156076969b9bccfc575260b167068d9403bc6
parent8892c5293248d730907bed5f956cbcfa2938fc6e (diff)
downloadrsyslog-19ccebbf4c49c5f9954c7a1a092399303156a1f3.tar.gz
rsyslog-19ccebbf4c49c5f9954c7a1a092399303156a1f3.tar.xz
rsyslog-19ccebbf4c49c5f9954c7a1a092399303156a1f3.zip
added capability to support multiple module search pathes.
Signed-off-by: Rainer Gerhards <rgerhards@adiscon.com>
-rw-r--r--ChangeLog2
-rw-r--r--configure.ac22
-rw-r--r--runtime/Makefile.am4
-rw-r--r--runtime/modules.c108
4 files changed, 101 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index f0bbf02c..46830143 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,8 @@ Version 3.21.6 [DEVEL] (rgerhards), 2008-10-??
and consistency
- bugfix: subsecond time properties generated by imfile, imklog and
internal messages could be slightly inconsistent
+- added capability to support multiple module search pathes. Thank
+ to Marius Tomaschewski for providing the patch.
---------------------------------------------------------------------------
Version 3.21.5 [DEVEL] (rgerhards), 2008-09-30
- performance optimization: unnecessary time() calls during message
diff --git a/configure.ac b/configure.ac
index fea7c063..4d74c957 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,6 +156,28 @@ fi
+# Additional module directories
+AC_ARG_WITH(moddirs,
+ [AS_HELP_STRING([--with-moddirs=DIRS],[Additional module search paths appended to @<:@$libdir/rsyslog@:>@])],
+ [_save_IFS=$IFS ; IFS=$PATH_SEPARATOR ; moddirs=""
+ for w in ${with_moddirs} ;
+ do
+ case $w in
+ "") continue ;; */) ;; *) w="${w}/" ;;
+ esac
+ for m in ${moddirs} ;
+ do
+ test "x$w" = "x${libdir}/${PACKAGE}/" || \
+ test "x$w" = "x$m" || test "x$w" = "x/" && \
+ continue 2
+ done
+ case $moddirs in
+ "") moddirs="$w" ;; *) moddirs="${moddirs}:${w}" ;;
+ esac
+ done ; IFS=$_save_IFS],[moddirs=""]
+)
+AM_CONDITIONAL(WITH_MODDIRS, test x$moddirs != x)
+AC_SUBST(moddirs)
# Large file support
AC_ARG_ENABLE(largefile,
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index 81a9d5bd..8dd8ad12 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -83,7 +83,11 @@ librsyslog_la_SOURCES = \
# the files with ../ we need to work on - so that they either become part of the
# runtime or will no longer be needed. -- rgerhards, 2008-06-13
+if WITH_MODDIRS
+librsyslog_la_CPPFLAGS = -D_PATH_MODDIR=\"$(pkglibdir)/:$(moddirs)\" $(pthreads_cflags)
+else
librsyslog_la_CPPFLAGS = -D_PATH_MODDIR=\"$(pkglibdir)/\" -I$(top_srcdir) $(pthreads_cflags)
+endif
#librsyslog_la_LDFLAGS = -module -avoid-version
librsyslog_la_LIBADD = $(dl_libs) $(rt_libs)
diff --git a/runtime/modules.c b/runtime/modules.c
index ceb4768c..d5730ede 100644
--- a/runtime/modules.c
+++ b/runtime/modules.c
@@ -570,6 +570,8 @@ Load(uchar *pModName)
int bHasExtension;
void *pModHdlr, *pModInit;
modInfo_t *pModInfo;
+ uchar *pModDirCurr, *pModDirNext;
+ int iLoadCnt;
assert(pModName != NULL);
dbgprintf("Requested to load module '%s'\n", pModName);
@@ -591,48 +593,84 @@ Load(uchar *pModName)
pModInfo = GetNxt(pModInfo);
}
- /* now build our load module name */
- if(*pModName == '/') {
- *szPath = '\0'; /* we do not need to append the path - its already in the module name */
- iPathLen = 0;
- } else {
- *szPath = '\0';
- strncat((char *) szPath, (pModDir == NULL) ? _PATH_MODDIR : (char*) pModDir, sizeof(szPath) - 1);
- iPathLen = strlen((char*) szPath);
- if((szPath[iPathLen - 1] != '/')) {
- if((iPathLen <= sizeof(szPath) - 2)) {
- szPath[iPathLen++] = '/';
- szPath[iPathLen] = '\0';
- } else {
- errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_PATHLEN, "could not load module '%s', path too long\n", pModName);
+ pModDirCurr = (uchar *)((pModDir == NULL) ? _PATH_MODDIR : (char *)pModDir);
+ pModDirNext = NULL;
+ pModHdlr = NULL;
+ iLoadCnt = 0;
+ do {
+ /* now build our load module name */
+ if(*pModName == '/') {
+ *szPath = '\0'; /* we do not need to append the path - its already in the module name */
+ iPathLen = 0;
+ } else {
+ *szPath = '\0';
+
+ iPathLen = strlen((char *)pModDirCurr);
+ pModDirNext = (uchar *)strchr((char *)pModDirCurr, ':');
+ if(pModDirNext)
+ iPathLen = (size_t)(pModDirNext - pModDirCurr);
+
+ if(iPathLen == 0) {
+ if(pModDirNext) {
+ pModDirCurr = pModDirNext + 1;
+ continue;
+ }
+ break;
+ } else if(iPathLen > sizeof(szPath) - 1) {
+ errmsg.LogError(0, NO_ERRCODE, "could not load module '%s', module path too long\n", pModName);
ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN);
}
+
+ strncat((char *) szPath, (char *)pModDirCurr, iPathLen);
+ iPathLen = strlen((char*) szPath);
+
+ if(pModDirNext)
+ pModDirCurr = pModDirNext + 1;
+
+ if((szPath[iPathLen - 1] != '/')) {
+ if((iPathLen <= sizeof(szPath) - 2)) {
+ szPath[iPathLen++] = '/';
+ szPath[iPathLen] = '\0';
+ } else {
+ errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_PATHLEN, "could not load module '%s', path too long\n", pModName);
+ ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN);
+ }
+ }
}
- }
- /* ... add actual name ... */
- strncat((char *) szPath, (char *) pModName, sizeof(szPath) - iPathLen - 1);
+ /* ... add actual name ... */
+ strncat((char *) szPath, (char *) pModName, sizeof(szPath) - iPathLen - 1);
+
+ /* now see if we have an extension and, if not, append ".so" */
+ if(!bHasExtension) {
+ /* we do not have an extension and so need to add ".so"
+ * TODO: I guess this is highly importable, so we should change the
+ * algo over time... -- rgerhards, 2008-03-05
+ */
+ /* ... so now add the extension */
+ strncat((char *) szPath, ".so", sizeof(szPath) - strlen((char*) szPath) - 1);
+ iPathLen += 3;
+ }
- /* now see if we have an extension and, if not, append ".so" */
- if(!bHasExtension) {
- /* we do not have an extension and so need to add ".so"
- * TODO: I guess this is highly importable, so we should change the
- * algo over time... -- rgerhards, 2008-03-05
- */
- /* ... so now add the extension */
- strncat((char *) szPath, ".so", sizeof(szPath) - strlen((char*) szPath) - 1);
- iPathLen += 3;
- }
+ if(iPathLen + strlen((char*) pModName) >= sizeof(szPath)) {
+ errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_PATHLEN, "could not load module '%s', path too long\n", pModName);
+ ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN);
+ }
- if(iPathLen + strlen((char*) pModName) >= sizeof(szPath)) {
- errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_PATHLEN, "could not load module '%s', path too long\n", pModName);
- ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN);
- }
+ /* complete load path constructed, so ... GO! */
+ dbgprintf("loading module '%s'\n", szPath);
+ pModHdlr = dlopen((char *) szPath, RTLD_NOW);
+ iLoadCnt++;
+
+ } while(pModHdlr == NULL && *pModName != '/' && pModDirNext);
- /* complete load path constructed, so ... GO! */
- dbgprintf("loading module '%s'\n", szPath);
- if(!(pModHdlr = dlopen((char *) szPath, RTLD_NOW))) {
- errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_DLOPEN, "could not load module '%s', dlopen: %s\n", szPath, dlerror());
+ if(!pModHdlr) {
+ if(iLoadCnt) {
+ errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_DLOPEN, "could not load module '%s', dlopen: %s\n", szPath, dlerror());
+ } else {
+ errmsg.LogError(0, NO_ERRCODE, "could not load module '%s', ModDir was '%s'\n", szPath,
+ ((pModDir == NULL) ? _PATH_MODDIR : (char *)pModDir));
+ }
ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_DLOPEN);
}
if(!(pModInit = dlsym(pModHdlr, "modInit"))) {