File rsyslog-3.18.3-moddirs.dif of Package rsyslog

--- configure.ac
+++ configure.ac	2008/09/09 10:35:00
@@ -107,6 +107,26 @@ AC_TRY_COMPILE([
 	AC_MSG_RESULT(no; defined as 64)
 )
 
+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,
         [AS_HELP_STRING([--enable-largefile],[Enable large file support @<:@default=yes@:>@])],
--- Makefile.am
+++ Makefile.am	2008/09/09 11:44:47
@@ -92,7 +92,11 @@ rsyslogd_SOURCES = \
 	action.h \
 	atomic.h
 
+if WITH_MODDIRS
+rsyslogd_CPPFLAGS =  -D_PATH_MODDIR=\"$(pkglibdir)/:$(moddirs)\" $(pthreads_cflags)
+else
 rsyslogd_CPPFLAGS =  -D_PATH_MODDIR=\"$(pkglibdir)/\" $(pthreads_cflags)
+endif
 rsyslogd_LDADD = $(zlib_libs) $(pthreads_libs) $(dl_libs) $(rt_libs)
 rsyslogd_LDFLAGS = -export-dynamic
 
--- modules.c
+++ modules.c	2008/09/09 13:19:37
@@ -563,6 +563,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);
@@ -584,48 +586,86 @@ 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(NO_ERRCODE, "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);
+			else
+				pModDirNext = NULL;
+
+			if(iPathLen == 0) {
+				if(pModDirNext) {
+					pModDirCurr = pModDirNext + 1;
+					continue;
+				}
+				break;
+			} else if(iPathLen > sizeof(szPath) - 1) {
+				errmsg.LogError(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(NO_ERRCODE, "could not load module '%s', module 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(NO_ERRCODE, "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(NO_ERRCODE, "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);
-	if(!(pModHdlr = dlopen((char *) szPath, RTLD_NOW))) {
-		errmsg.LogError(NO_ERRCODE, "could not load module '%s', dlopen: %s\n", szPath, dlerror());
+		/* complete load path constructed, so ... GO! */
+		dbgprintf("loading module '%s'\n", szPath);
+		pModHdlr = dlopen((char *) szPath, RTLD_NOW);
+		iLoadCnt++;
+
+	} while(pModHdlr == NULL && *pModName != '/' && pModDirNext);
+
+	if(!pModHdlr) {
+		if(iLoadCnt) {
+			errmsg.LogError(NO_ERRCODE, "could not load module '%s', dlopen: %s\n", szPath, dlerror());
+		} else {
+			errmsg.LogError(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"))) {
openSUSE Build Service is sponsored by