Example #1
0
/* 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 dbgprintf() subsystem is initialized.
 * TODO: update for new input modules!
 */
static void modPrintList(void)
{
	modInfo_t *pMod;

	pMod = GetNxt(NULL);
	while(pMod != NULL) {
		dbgprintf("Loaded Module: Name='%s', IFVersion=%d, ",
			(char*) modGetName(pMod), pMod->iIFVers);
		dbgprintf("type=");
		switch(pMod->eType) {
		case eMOD_OUT:
			dbgprintf("output");
			break;
		case eMOD_IN:
			dbgprintf("input");
			break;
		case eMOD_LIB:
			dbgprintf("library");
			break;
		}
		dbgprintf(" module.\n");
		dbgprintf("Entry points:\n");
		dbgprintf("\tqueryEtryPt:        0x%lx\n", (unsigned long) pMod->modQueryEtryPt);
		dbgprintf("\tdoAction:           0x%lx\n", (unsigned long) pMod->mod.om.doAction);
		dbgprintf("\tparseSelectorAct:   0x%lx\n", (unsigned long) pMod->mod.om.parseSelectorAct);
		dbgprintf("\tdbgPrintInstInfo:   0x%lx\n", (unsigned long) pMod->dbgPrintInstInfo);
		dbgprintf("\tfreeInstance:       0x%lx\n", (unsigned long) pMod->freeInstance);
		dbgprintf("\n");
		pMod = GetNxt(pMod); /* done, go next */
	}
}
Example #2
0
/* unlink and destroy a module. The caller must provide a pointer to the module
 * itself as well as one to its immediate predecessor.
 * rgerhards, 2008-02-26
 */
static rsRetVal
modUnlinkAndDestroy(modInfo_t **ppThis)
{
	DEFiRet;
	modInfo_t *pThis;

	assert(ppThis != NULL);
	pThis = *ppThis;
	assert(pThis != NULL);

	pthread_mutex_lock(&mutLoadUnload);

	/* first check if we are permitted to unload */
	if(pThis->eType == eMOD_LIB) {
		if(pThis->uRefCnt > 0) {
			dbgprintf("module %s NOT unloaded because it still has a refcount of %u\n",
				  pThis->pszName, pThis->uRefCnt);
#			ifdef DEBUG
			//modUsrPrintAll();
#			endif
			ABORT_FINALIZE(RS_RET_MODULE_STILL_REFERENCED);
		}
	}

	/* we need to unlink the module before we can destruct it -- rgerhards, 2008-02-26 */
	if(pThis->pPrev == NULL) {
		/* module is root, so we need to set a new root */
		pLoadedModules = pThis->pNext;
	} else {
		pThis->pPrev->pNext = pThis->pNext;
	}

	if(pThis->pNext == NULL) {
		pLoadedModulesLast = pThis->pPrev;
	} else {
		pThis->pNext->pPrev = pThis->pPrev;
	}

	/* finally, we are ready for the module to go away... */
	dbgprintf("Unloading module %s\n", modGetName(pThis));
	CHKiRet(modPrepareUnload(pThis));
	*ppThis = pThis->pNext;

	moduleDestruct(pThis);

finalize_it:
	pthread_mutex_unlock(&mutLoadUnload);
	RETiRet;
}
Example #3
0
/* load a module and initialize it, based on doModLoad() from conf.c
 * rgerhards, 2008-03-05
 * varmojfekoj added support for dynamically loadable modules on 2007-08-13
 * rgerhards, 2007-09-25: please note that the non-threadsafe function dlerror() is
 * called below. This is ok because modules are currently only loaded during
 * configuration file processing, which is executed on a single thread. Should we
 * change that design at any stage (what is unlikely), we need to find a
 * replacement.
 */
static rsRetVal
Load(uchar *pModName)
{
	DEFiRet;
	
	size_t iPathLen, iModNameLen;
	uchar szPath[PATH_MAX];
	uchar *pModNameCmp;
	int bHasExtension;
        void *pModHdlr, *pModInit;
	modInfo_t *pModInfo;
	uchar *pModDirCurr, *pModDirNext;
	int iLoadCnt;
	struct dlhandle_s *pHandle = NULL;

	assert(pModName != NULL);
	dbgprintf("Requested to load module '%s'\n", pModName);

	pthread_mutex_lock(&mutLoadUnload);

	iModNameLen = strlen((char *) pModName);
	if(iModNameLen > 3 && !strcmp((char *) pModName + iModNameLen - 3, ".so")) {
		iModNameLen -= 3;
		bHasExtension = TRUE;
	} else
		bHasExtension = FALSE;

	pModInfo = GetNxt(NULL);
	while(pModInfo != NULL) {
		if(!strncmp((char *) pModName, (char *) (pModNameCmp = modGetName(pModInfo)), iModNameLen) &&
		   (!*(pModNameCmp + iModNameLen) || !strcmp((char *) pModNameCmp + iModNameLen, ".so"))) {
			dbgprintf("Module '%s' already loaded\n", pModName);
			ABORT_FINALIZE(RS_RET_OK);
		}
		pModInfo = GetNxt(pModInfo);
	}

	pModDirCurr = (uchar *)((pModDir == NULL) ? _PATH_MODDIR : (char *)pModDir);
	pModDirNext = NULL;
	pModHdlr    = NULL;
	iLoadCnt    = 0;
	do {
		/* now build our load module name */
		if(*pModName == '/' || *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);

		/* 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);
		}

		/* complete load path constructed, so ... GO! */
		dbgprintf("loading module '%s'\n", szPath);

		/* see if we have this one already */
		for (pHandle = pHandles; pHandle; pHandle = pHandle->next) {
			if (!strcmp((char *)pModName, (char *)pHandle->pszName)) {
				pModHdlr = pHandle->pModHdlr;
				break;
			}
		}

		/* not found, try to dynamically link it */
		if (!pModHdlr) {
			pModHdlr = dlopen((char *) szPath, RTLD_NOW);
		}

		iLoadCnt++;
	
	} while(pModHdlr == NULL && *pModName != '/' && pModDirNext);

	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"))) {
		errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_NO_INIT, "could not load module '%s', dlsym: %s\n", szPath, dlerror());
		dlclose(pModHdlr);
		ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_NO_INIT);
	}
	if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr)) != RS_RET_OK) {
		errmsg.LogError(0, RS_RET_MODULE_LOAD_ERR_INIT_FAILED, "could not load module '%s', rsyslog error %d\n", szPath, iRet);
		dlclose(pModHdlr);
		ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_INIT_FAILED);
	}

finalize_it:
	pthread_mutex_unlock(&mutLoadUnload);
	RETiRet;
}
Example #4
0
/* 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 dbgprintf() subsystem is initialized.
 * TODO: update for new input modules!
 */
static void modPrintList(void)
{
	modInfo_t *pMod;

	pMod = GetNxt(NULL);
	while(pMod != NULL) {
		dbgprintf("Loaded Module: Name='%s', IFVersion=%d, ",
			(char*) modGetName(pMod), pMod->iIFVers);
		dbgprintf("type=");
		switch(pMod->eType) {
		case eMOD_OUT:
			dbgprintf("output");
			break;
		case eMOD_IN:
			dbgprintf("input");
			break;
		case eMOD_LIB:
			dbgprintf("library");
			break;
		case eMOD_PARSER:
			dbgprintf("parser");
			break;
		case eMOD_STRGEN:
			dbgprintf("strgen");
			break;
		}
		dbgprintf(" module.\n");
		dbgprintf("Entry points:\n");
		dbgprintf("\tqueryEtryPt:        0x%lx\n", (unsigned long) pMod->modQueryEtryPt);
		dbgprintf("\tdbgPrintInstInfo:   0x%lx\n", (unsigned long) pMod->dbgPrintInstInfo);
		dbgprintf("\tfreeInstance:       0x%lx\n", (unsigned long) pMod->freeInstance);
		switch(pMod->eType) {
		case eMOD_OUT:
			dbgprintf("Output Module Entry Points:\n");
			dbgprintf("\tdoAction:           0x%lx\n", (unsigned long) pMod->mod.om.doAction);
			dbgprintf("\tparseSelectorAct:   0x%lx\n", (unsigned long) pMod->mod.om.parseSelectorAct);
			dbgprintf("\ttryResume:          0x%lx\n", (unsigned long) pMod->tryResume);
			dbgprintf("\tdoHUP:              0x%lx\n", (unsigned long) pMod->doHUP);
			dbgprintf("\tBeginTransaction:   0x%lx\n", (unsigned long)
								   ((pMod->mod.om.beginTransaction == dummyBeginTransaction) ?
								    0 :  pMod->mod.om.beginTransaction));
			dbgprintf("\tEndTransaction:     0x%lx\n", (unsigned long)
								   ((pMod->mod.om.endTransaction == dummyEndTransaction) ?
								    0 :  pMod->mod.om.endTransaction));
			break;
		case eMOD_IN:
			dbgprintf("Input Module Entry Points\n");
			dbgprintf("\trunInput:           0x%lx\n", (unsigned long) pMod->mod.im.runInput);
			dbgprintf("\twillRun:            0x%lx\n", (unsigned long) pMod->mod.im.willRun);
			dbgprintf("\tafterRun:           0x%lx\n", (unsigned long) pMod->mod.im.afterRun);
			break;
		case eMOD_LIB:
			break;
		case eMOD_PARSER:
			dbgprintf("Parser Module Entry Points\n");
			dbgprintf("\tparse:              0x%lx\n", (unsigned long) pMod->mod.pm.parse);
			break;
		case eMOD_STRGEN:
			dbgprintf("Strgen Module Entry Points\n");
			dbgprintf("\tstrgen:            0x%lx\n", (unsigned long) pMod->mod.sm.strgen);
			break;
		}
		dbgprintf("\n");
		pMod = GetNxt(pMod); /* done, go next */
	}
}
Example #5
0
/* get the state-name of a module. The state name is its name
 * together with a short description of the module state (which
 * is pulled from the module itself.
 * rgerhards, 2007-07-24
 * TODO: the actual state name is not yet pulled
 */
static uchar *modGetStateName(modInfo_t *pThis)
{
	return(modGetName(pThis));
}
Example #6
0
/* load a module and initialize it, based on doModLoad() from conf.c
 * rgerhards, 2008-03-05
 * varmojfekoj added support for dynamically loadable modules on 2007-08-13
 * rgerhards, 2007-09-25: please note that the non-threadsafe function dlerror() is
 * called below. This is ok because modules are currently only loaded during
 * configuration file processing, which is executed on a single thread. Should we
 * change that design at any stage (what is unlikely), we need to find a
 * replacement.
 */
static rsRetVal
Load(uchar *pModName)
{
	DEFiRet;
	
	size_t iPathLen, iModNameLen;
	uchar szPath[PATH_MAX];
	uchar *pModNameCmp;
	int bHasExtension;
        void *pModHdlr, *pModInit;
	modInfo_t *pModInfo;

	assert(pModName != NULL);
	dbgprintf("Requested to load module '%s'\n", pModName);

	iModNameLen = strlen((char *) pModName);
	if(iModNameLen > 3 && !strcmp((char *) pModName + iModNameLen - 3, ".so")) {
		iModNameLen -= 3;
		bHasExtension = TRUE;
	} else
		bHasExtension = FALSE;

	pModInfo = GetNxt(NULL);
	while(pModInfo != NULL) {
		if(!strncmp((char *) pModName, (char *) (pModNameCmp = modGetName(pModInfo)), iModNameLen) &&
		   (!*(pModNameCmp + iModNameLen) || !strcmp((char *) pModNameCmp + iModNameLen, ".so"))) {
			dbgprintf("Module '%s' already loaded\n", pModName);
			ABORT_FINALIZE(RS_RET_OK);
		}
		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);
				ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN);
			}
		}
	}

	/* ... 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;
	}

	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());
		ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_DLOPEN);
	}
	if(!(pModInit = dlsym(pModHdlr, "modInit"))) {
		errmsg.LogError(NO_ERRCODE, "could not load module '%s', dlsym: %s\n", szPath, dlerror());
		dlclose(pModHdlr);
		ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_NO_INIT);
	}
	if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr)) != RS_RET_OK) {
		errmsg.LogError(NO_ERRCODE, "could not load module '%s', rsyslog error %d\n", szPath, iRet);
		dlclose(pModHdlr);
		ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_INIT_FAILED);
	}

finalize_it:
	RETiRet;
}