summaryrefslogtreecommitdiffstats
path: root/modules.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules.c')
-rw-r--r--modules.c397
1 files changed, 0 insertions, 397 deletions
diff --git a/modules.c b/modules.c
deleted file mode 100644
index 406cf32a..00000000
--- a/modules.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/* modules.c
- * This is the implementation of syslogd modules object.
- * This object handles plug-ins and buil-in modules of all kind.
- *
- * File begun on 2007-07-22 by RGerhards
- *
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * 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>
-#include <string.h>
-#include <time.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <dlfcn.h> /* TODO: replace this with the libtools equivalent! */
-
-#include <unistd.h>
-#include <sys/file.h>
-
-#include "syslogd.h"
-#include "cfsysline.h"
-#include "modules.h"
-
-static modInfo_t *pLoadedModules = NULL; /* list of currently-loaded modules */
-static modInfo_t *pLoadedModulesLast = NULL; /* tail-pointer */
-static int bCfsyslineInitialized = 0;
-
-
-/* Construct a new module object
- */
-static rsRetVal moduleConstruct(modInfo_t **pThis)
-{
- modInfo_t *pNew;
-
- if((pNew = calloc(1, sizeof(modInfo_t))) == NULL)
- return RS_RET_OUT_OF_MEMORY;
-
- /* OK, we got the element, now initialize members that should
- * not be zero-filled.
- */
-
- *pThis = pNew;
- return RS_RET_OK;
-}
-
-
-/* Destructs a module object. The object must not be linked to the
- * linked list of modules. Please note that all other dependencies on this
- * modules must have been removed before (e.g. CfSysLineHandlers!)
- */
-static void moduleDestruct(modInfo_t *pThis)
-{
- if(pThis->pszName != NULL)
- free(pThis->pszName);
- if(pThis->pModHdlr != NULL)
- dlclose(pThis->pModHdlr);
- free(pThis);
-}
-
-
-/* The followind function is the queryEntryPoint for host-based entry points.
- * Modules may call it to get access to core interface functions. Please note
- * that utility functions can be accessed via shared libraries - at least this
- * is my current shool of thinking.
- * Please note that the implementation as a query interface allows to take
- * care of plug-in interface version differences. -- rgerhards, 2007-07-31
- */
-rsRetVal queryHostEtryPt(uchar *name, rsRetVal (**pEtryPoint)())
-{
- DEFiRet;
-
- if((name == NULL) || (pEtryPoint == NULL))
- return RS_RET_PARAM_ERROR;
-
- if(!strcmp((char*) name, "regCfSysLineHdlr")) {
- *pEtryPoint = regCfSysLineHdlr;
- }
-
- if(iRet == RS_RET_OK)
- iRet = (*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;
- return iRet;
-}
-
-
-/* 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
- */
-uchar *modGetStateName(modInfo_t *pThis)
-{
- return(modGetName(pThis));
-}
-
-
-/* get the name of a module
- */
-uchar *modGetName(modInfo_t *pThis)
-{
- return((pThis->pszName == NULL) ? (uchar*) "" : pThis->pszName);
-}
-
-
-/* Add a module to the loaded module linked list
- */
-static inline void addModToList(modInfo_t *pThis)
-{
- assert(pThis != NULL);
-
- if(pLoadedModules == NULL) {
- pLoadedModules = pLoadedModulesLast = pThis;
- } else {
- /* there already exist entries */
- pLoadedModulesLast->pNext = pThis;
- pLoadedModulesLast = 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);
-}
-
-
-/* this function is like modGetNxt(), but it returns pointers to
- * output modules only. As we currently deal just with output modules,
- * it is a dummy, to be filled with real code later.
- * rgerhards, 2007-07-24
- */
-modInfo_t *omodGetNxt(modInfo_t *pThis)
-{
- return(modGetNxt(pThis));
-}
-
-
-/* Prepare a module for unloading.
- * This is currently a dummy, to be filled when we have a plug-in
- * interface - rgerhards, 2007-08-09
- * rgerhards, 2007-11-21:
- * When this function is called, all instance-data must already have
- * been destroyed. In the case of output modules, this happens when the
- * rule set is being destroyed. When we implement other module types, we
- * need to think how we handle it there (and if we have any instance data).
- */
-static rsRetVal modPrepareUnload(modInfo_t *pThis)
-{
- DEFiRet;
- void *pModCookie;
-
- assert(pThis != NULL);
-
- /* WARNING - the current code does NOT work and causes an abort - this is acceptable right now
- * as I am DEVELOPING the working code and will NOT release until it is there. If you use a
- * CVS snapshot, be aware of this limitation. For now, you can just remove everything up to
- * (but not including) the END DEVEL comment. That will do the trick. rgerhards, 2007-11-21
- */
- CHKiRet(pThis->modGetID(&pModCookie));
- pThis->modExit(); /* tell the module to get ready for unload */
- CHKiRet(unregCfSysLineHdlrs4Owner(pModCookie));
-
- /* END DEVEL */
-
-finalize_it:
- return iRet;
-}
-
-
-/* Add an already-loaded module to the module linked list. This function does
- * everything needed to fully initialize the module.
- */
-rsRetVal doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)()), uchar *name, void *pModHdlr)
-{
- DEFiRet;
- modInfo_t *pNew;
-
- assert(modInit != NULL);
-
- if(bCfsyslineInitialized == 0) {
- /* we need to initialize the cfsysline subsystem first */
- CHKiRet(cfsyslineInit());
- bCfsyslineInitialized = 1;
- }
-
- if((iRet = moduleConstruct(&pNew)) != RS_RET_OK)
- return iRet;
-
- if((iRet = (*modInit)(1, &pNew->iIFVers, &pNew->modQueryEtryPt, queryHostEtryPt)) != 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;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"parseSelectorAct", &pNew->mod.om.parseSelectorAct)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"isCompatibleWithFeature",
- &pNew->isCompatibleWithFeature)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"dbgPrintInstInfo",
- &pNew->dbgPrintInstInfo)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"getWriteFDForSelect", &pNew->getWriteFDForSelect)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"onSelectReadyWrite", &pNew->onSelectReadyWrite)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"needUDPSocket", &pNew->needUDPSocket)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"tryResume", &pNew->tryResume)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"freeInstance", &pNew->freeInstance)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"modGetID", &pNew->modGetID)) != RS_RET_OK) {
- moduleDestruct(pNew);
- return iRet;
- }
- if((iRet = (*pNew->modQueryEtryPt)((uchar*)"modExit", &pNew->modExit)) != 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->pModHdlr = pModHdlr;
- pNew->eType = eMOD_OUT; /* TODO: take this from module */
- /* TODO: take this from module */
- if(pModHdlr == NULL)
- pNew->eLinkType = eMOD_LINK_STATIC;
- else
- pNew->eLinkType = eMOD_LINK_DYNAMIC_LOADED;
-
- /* we initialized the structure, now let's add it to the linked list of modules */
- addModToList(pNew);
-
-finalize_it:
- return iRet;
-}
-
-/* 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.
- */
-void modPrintList(void)
-{
- modInfo_t *pMod;
-
- pMod = modGetNxt(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_FILTER:
- dbgprintf("filter");
- 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 = modGetNxt(pMod); /* done, go next */
- }
-}
-
-
-/* unload all modules and free module linked list
- * rgerhards, 2007-08-09
- */
-rsRetVal modUnloadAndDestructAll(void)
-{
- DEFiRet;
- modInfo_t *pMod;
- modInfo_t *pModPrev;
-
- pMod = modGetNxt(NULL);
- while(pMod != NULL) {
- pModPrev = pMod;
- pMod = modGetNxt(pModPrev); /* get next */
- /* now we can destroy the previous module */
- dbgprintf("Unloading module %s\n", modGetName(pModPrev));
- modPrepareUnload(pModPrev);
- moduleDestruct(pModPrev);
- }
-
- return iRet;
-}
-
-
-rsRetVal modUnloadAndDestructDynamic(void)
-{
- DEFiRet;
- modInfo_t *pMod;
- modInfo_t *pModPrev;
-
- pLoadedModulesLast = NULL;
-
- pMod = modGetNxt(NULL);
- while(pMod != NULL) {
- pModPrev = pMod;
- pMod = modGetNxt(pModPrev); /* get next */
- /* now we can destroy the previous module */
- if(pModPrev->eLinkType != eMOD_LINK_STATIC) {
- dbgprintf("Unloading module %s\n", modGetName(pModPrev));
- modPrepareUnload(pModPrev);
- moduleDestruct(pModPrev);
- } else {
- pLoadedModulesLast = pModPrev;
- }
- }
-
- /* Note: the last modules pNext pointer is now invalid
- * (except if the last module was not touched, what is highly
- * unlikely. We simply fix this be setting it to NULL. After all,
- * it is the last module ;). This bug had some severe effects in
- * v3, but none in v2 because in v2 the list was never again
- * traversed before a new one was added. But even in v2 it may cause
- * a segfault if the number of loaded modules changed between HUPs.
- * rgerhards, 2008-02-26
- */
- if(pLoadedModulesLast != NULL)
- pLoadedModulesLast->pNext = NULL;
-
- return iRet;
-}
-/*
- * vi:set ai:
- */