rsRetVal dynstatsClassInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); CHKiRet(objUse(errmsg, CORE_COMPONENT)); CHKiRet(objUse(statsobj, CORE_COMPONENT)); finalize_it: RETiRet; }
rsRetVal lookupClassInit(void) { DEFiRet; CHKiRet(objGetObjInterface(&obj)); CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(errmsg, CORE_COMPONENT)); finalize_it: RETiRet; }
/* check if a CStr object matches a regex. * [email protected] 2007-07-12 * @return returns 0 if matched * bug: doesn't work for CStr containing \0 * rgerhards, 2007-07-16: bug is no real bug, because rsyslogd ensures there * never is a \0 *inside* a property string. * Note that the function returns -1 if regexp functionality is not available. * rgerhards: 2009-03-04: ERE support added, via parameter iType: 0 - BRE, 1 - ERE * Arnaud Cornet/rgerhards: 2009-04-02: performance improvement by caching compiled regex * If a caller does not need the cached version, it must still provide memory for it * and must call rsCStrRegexDestruct() afterwards. */ rsRetVal rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz, int iType, void *rc) { regex_t **cache = (regex_t**) rc; int ret; DEFiRet; assert(pCS1 != NULL); assert(psz != NULL); assert(cache != NULL); if(objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { if (*cache == NULL) { *cache = calloc(sizeof(regex_t), 1); regexp.regcomp(*cache, (char*) rsCStrGetSzStr(pCS1), (iType == 1 ? REG_EXTENDED : 0) | REG_NOSUB); } ret = regexp.regexec(*cache, (char*) psz, 0, NULL, 0); if(ret != 0) ABORT_FINALIZE(RS_RET_NOT_FOUND); } else { ABORT_FINALIZE(RS_RET_NOT_FOUND); } finalize_it: RETiRet; }
/* accept an incoming connection request * The netstrm instance that had the incoming request must be provided. If * the connection request succeeds, a new netstrm object is created and * passed back to the caller. The caller is responsible for destructing it. * pReq is the nsd_t obj that has the accept request. * rgerhards, 2008-04-21 */ static rsRetVal AcceptConnReq(netstrm_t *pThis, netstrm_t **ppNew) { nsd_t *pNewNsd = NULL; DEFiRet; ISOBJ_TYPE_assert(pThis, netstrm); assert(ppNew != NULL); /* accept the new connection */ CHKiRet(pThis->Drvr.AcceptConnReq(pThis->pDrvrData, &pNewNsd)); /* construct our object so that we can use it... */ CHKiRet(objUse(netstrms, DONT_LOAD_LIB)); /* use netstrms obj if not already done so */ CHKiRet(netstrms.CreateStrm(pThis->pNS, ppNew)); (*ppNew)->pDrvrData = pNewNsd; finalize_it: if(iRet != RS_RET_OK) { /* the close may be redundant, but that doesn't hurt... */ if(pNewNsd != NULL) pThis->Drvr.Destruct(&pNewNsd); } RETiRet; }
/* init function (must be called once) */ rsRetVal dnscacheInit(void) { DEFiRet; if((dnsCache.ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, (void(*)(void*))entryDestruct)) == NULL) { DBGPRINTF("dnscache: error creating hash table!\n"); ABORT_FINALIZE(RS_RET_ERR); // TODO: make this degrade, but run! } dnsCache.nEntries = 0; pthread_rwlock_init(&dnsCache.rwlock, NULL); CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ CHKiRet(objUse(glbl, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); prop.Construct(&staticErrValue); prop.SetString(staticErrValue, (uchar*)"???", 3); prop.ConstructFinalize(staticErrValue); finalize_it: RETiRet; }
/* free a cached compiled regex * Caller must provide a pointer to a buffer that was created by * rsCStrSzStrMatchRegexCache() */ void rsCStrRegexDestruct(void *rc) { regex_t **cache = rc; assert(cache != NULL); assert(*cache != NULL); if(objUse(regexp, LM_REGEXP_FILENAME) == RS_RET_OK) { regexp.regfree(*cache); free(*cache); *cache = NULL; } }
/* Method to initialize all global classes and use the objects that we need. * rgerhards, 2008-01-04 * rgerhards, 2008-04-16: the actual initialization is now carried out by the runtime */ rsRetVal rsyslogd_InitGlobalClasses(void) { DEFiRet; char *pErrObj; /* tells us which object failed if that happens (useful for troubleshooting!) */ /* Intialize the runtime system */ pErrObj = "rsyslog runtime"; /* set in case the runtime errors before setting an object */ CHKiRet(rsrtInit(&pErrObj, &obj)); rsrtSetErrLogger(rsyslogd_submitErrMsg); /* Now tell the system which classes we need ourselfs */ pErrObj = "glbl"; CHKiRet(objUse(glbl, CORE_COMPONENT)); pErrObj = "errmsg"; CHKiRet(objUse(errmsg, CORE_COMPONENT)); pErrObj = "module"; CHKiRet(objUse(module, CORE_COMPONENT)); pErrObj = "datetime"; CHKiRet(objUse(datetime, CORE_COMPONENT)); pErrObj = "ruleset"; CHKiRet(objUse(ruleset, CORE_COMPONENT)); /*pErrObj = "conf"; CHKiRet(objUse(conf, CORE_COMPONENT));*/ pErrObj = "prop"; CHKiRet(objUse(prop, CORE_COMPONENT)); pErrObj = "parser"; CHKiRet(objUse(parser, CORE_COMPONENT)); pErrObj = "rsconf"; CHKiRet(objUse(rsconf, CORE_COMPONENT)); /* intialize some dummy classes that are not part of the runtime */ pErrObj = "action"; CHKiRet(actionClassInit()); pErrObj = "template"; CHKiRet(templateInit()); /* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ pErrObj = "net"; CHKiRet(objUse(net, LM_NET_FILENAME)); dnscacheInit(); initRainerscript(); ratelimitModInit(); /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInternalInputName)); CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd") - 1)); CHKiRet(prop.ConstructFinalize(pInternalInputName)); finalize_it: if(iRet != RS_RET_OK) { /* we know we are inside the init sequence, so we can safely emit * messages to stderr. -- rgerhards, 2008-04-02 */ fprintf(stderr, "Error during class init for object '%s' - failing...\n", pErrObj); fprintf(stderr, "rsyslogd initializiation failed - global classes could not be initialized.\n" "Did you do a \"make install\"?\n" "Suggested action: run rsyslogd with -d -n options to see what exactly " "fails.\n"); } RETiRet; }
/* Add an already-loaded module to the module linked list. This function does * everything needed to fully initialize the module. */ static rsRetVal doModInit(rsRetVal (*modInit)(int, int*, rsRetVal(**)(), rsRetVal(*)(), modInfo_t*), uchar *name, void *pModHdlr) { rsRetVal localRet; modInfo_t *pNew = NULL; uchar *pName; parser_t *pParser; /* used for parser modules */ strgen_t *pStrgen; /* used for strgen modules */ rsRetVal (*GetName)(uchar**); rsRetVal (*modGetType)(eModType_t *pType); rsRetVal (*modGetKeepType)(eModKeepType_t *pKeepType); struct dlhandle_s *pHandle = NULL; DEFiRet; assert(modInit != NULL); if((iRet = moduleConstruct(&pNew)) != RS_RET_OK) { pNew = NULL; ABORT_FINALIZE(iRet); } CHKiRet((*modInit)(CURR_MOD_IF_VERSION, &pNew->iIFVers, &pNew->modQueryEtryPt, queryHostEtryPt, pNew)); if(pNew->iIFVers != CURR_MOD_IF_VERSION) { ABORT_FINALIZE(RS_RET_MISSING_INTERFACE); } /* We now poll the module to see what type it is. We do this only once as this * can never change in the lifetime of an module. -- rgerhards, 2007-12-14 */ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"getType", &modGetType)); CHKiRet((*modGetType)(&pNew->eType)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"getKeepType", &modGetKeepType)); CHKiRet((*modGetKeepType)(&pNew->eKeepType)); dbgprintf("module of type %d being loaded.\n", pNew->eType); /* OK, we know we can successfully work with the module. So we now fill the * rest of the data elements. First we load the interfaces common to all * module types. */ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"modGetID", &pNew->modGetID)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"modExit", &pNew->modExit)); localRet = (*pNew->modQueryEtryPt)((uchar*)"isCompatibleWithFeature", &pNew->isCompatibleWithFeature); if(localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) pNew->isCompatibleWithFeature = dummyIsCompatibleWithFeature; else if(localRet != RS_RET_OK) ABORT_FINALIZE(localRet); /* ... and now the module-specific interfaces */ switch(pNew->eType) { case eMOD_IN: CHKiRet((*pNew->modQueryEtryPt)((uchar*)"runInput", &pNew->mod.im.runInput)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"willRun", &pNew->mod.im.willRun)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"afterRun", &pNew->mod.im.afterRun)); pNew->mod.im.bCanRun = 0; break; case eMOD_OUT: CHKiRet((*pNew->modQueryEtryPt)((uchar*)"freeInstance", &pNew->freeInstance)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"dbgPrintInstInfo", &pNew->dbgPrintInstInfo)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"doAction", &pNew->mod.om.doAction)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"parseSelectorAct", &pNew->mod.om.parseSelectorAct)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"tryResume", &pNew->tryResume)); /* try load optional interfaces */ localRet = (*pNew->modQueryEtryPt)((uchar*)"doHUP", &pNew->doHUP); if(localRet != RS_RET_OK && localRet != RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) ABORT_FINALIZE(localRet); localRet = (*pNew->modQueryEtryPt)((uchar*)"beginTransaction", &pNew->mod.om.beginTransaction); if(localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) pNew->mod.om.beginTransaction = dummyBeginTransaction; else if(localRet != RS_RET_OK) ABORT_FINALIZE(localRet); localRet = (*pNew->modQueryEtryPt)((uchar*)"endTransaction", &pNew->mod.om.endTransaction); if(localRet == RS_RET_MODULE_ENTRY_POINT_NOT_FOUND) { pNew->mod.om.endTransaction = dummyEndTransaction; } else if(localRet != RS_RET_OK) { ABORT_FINALIZE(localRet); } break; case eMOD_LIB: break; case eMOD_PARSER: /* first, we need to obtain the parser object. We could not do that during * init as that would have caused class bootstrap issues which are not * absolutely necessary. Note that we can call objUse() multiple times, it * handles that. */ CHKiRet(objUse(parser, CORE_COMPONENT)); /* here, we create a new parser object */ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"parse", &pNew->mod.pm.parse)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"GetParserName", &GetName)); CHKiRet(GetName(&pName)); CHKiRet(parser.Construct(&pParser)); /* check some features */ localRet = pNew->isCompatibleWithFeature(sFEATUREAutomaticSanitazion); if(localRet == RS_RET_OK){ CHKiRet(parser.SetDoSanitazion(pParser, TRUE)); } localRet = pNew->isCompatibleWithFeature(sFEATUREAutomaticPRIParsing); if(localRet == RS_RET_OK){ CHKiRet(parser.SetDoPRIParsing(pParser, TRUE)); } CHKiRet(parser.SetName(pParser, pName)); CHKiRet(parser.SetModPtr(pParser, pNew)); CHKiRet(parser.ConstructFinalize(pParser)); break; case eMOD_STRGEN: /* first, we need to obtain the strgen object. We could not do that during * init as that would have caused class bootstrap issues which are not * absolutely necessary. Note that we can call objUse() multiple times, it * handles that. */ CHKiRet(objUse(strgen, CORE_COMPONENT)); /* here, we create a new parser object */ CHKiRet((*pNew->modQueryEtryPt)((uchar*)"strgen", &pNew->mod.sm.strgen)); CHKiRet((*pNew->modQueryEtryPt)((uchar*)"GetName", &GetName)); CHKiRet(GetName(&pName)); CHKiRet(strgen.Construct(&pStrgen)); CHKiRet(strgen.SetName(pStrgen, pName)); CHKiRet(strgen.SetModPtr(pStrgen, pNew)); CHKiRet(strgen.ConstructFinalize(pStrgen)); break; } pNew->pszName = (uchar*) strdup((char*)name); /* we do not care if strdup() fails, we can accept that */ pNew->pModHdlr = pModHdlr; /* TODO: take this from module */ if(pModHdlr == NULL) { pNew->eLinkType = eMOD_LINK_STATIC; } else { pNew->eLinkType = eMOD_LINK_DYNAMIC_LOADED; /* if we need to keep the linked module, save it */ if (pNew->eKeepType == eMOD_KEEP) { /* see if we have this one already */ for (pHandle = pHandles; pHandle; pHandle = pHandle->next) { if (!strcmp((char *)name, (char *)pHandle->pszName)) break; } /* not found, create it */ if (!pHandle) { if((pHandle = malloc(sizeof (*pHandle))) == NULL) { ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } if((pHandle->pszName = (uchar*) strdup((char*)name)) == NULL) { free(pHandle); ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); } pHandle->pModHdlr = pModHdlr; pHandle->next = pHandles; pHandles = pHandle; } } } /* we initialized the structure, now let's add it to the linked list of modules */ addModToList(pNew); finalize_it: if(iRet != RS_RET_OK) { if(pNew != NULL) moduleDestruct(pNew); } RETiRet; }