summaryrefslogtreecommitdiffstats
path: root/plugins/immark/immark.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/immark/immark.c')
-rw-r--r--plugins/immark/immark.c337
1 files changed, 337 insertions, 0 deletions
diff --git a/plugins/immark/immark.c b/plugins/immark/immark.c
new file mode 100644
index 0000000..af893a3
--- /dev/null
+++ b/plugins/immark/immark.c
@@ -0,0 +1,337 @@
+/* immark.c
+ * This is the implementation of the build-in mark message input module.
+ *
+ * NOTE: read comments in module-template.h to understand how this file
+ * works!
+ *
+ * File begun on 2007-07-20 by RGerhards (extracted from syslogd.c)
+ * This file is under development and has not yet arrived at being fully
+ * self-contained and a real object. So far, it is mostly an excerpt
+ * of the "old" message code without any modifications. However, it
+ * helps to have things at the right place one we go to the meat of it.
+ *
+ * Copyright 2007-2020 Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "config.h"
+#include "rsyslog.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <signal.h>
+#include <string.h>
+#include <pthread.h>
+#include "dirty.h"
+#include "cfsysline.h"
+#include "module-template.h"
+#include "errmsg.h"
+#include "msg.h"
+#include "srUtils.h"
+#include "glbl.h"
+#include "unicode-helper.h"
+#include "ruleset.h"
+#include "prop.h"
+
+MODULE_TYPE_INPUT
+MODULE_TYPE_NOKEEP
+MODULE_CNFNAME("immark")
+
+/* defines */
+#define DEFAULT_MARK_PERIOD (20 * 60)
+
+/* Module static data */
+DEF_IMOD_STATIC_DATA
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(prop)
+DEFobjCurrIf(ruleset)
+
+static int iMarkMessagePeriod = DEFAULT_MARK_PERIOD;
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ const char *pszMarkMsgText;
+ size_t lenMarkMsgText;
+ uchar *pszBindRuleset;
+ ruleset_t *pBindRuleset;
+ int flags;
+ int bUseMarkFlag;
+ int bUseSyslogAPI;
+ int iMarkMessagePeriod;
+ sbool configSetViaV2Method;
+};
+
+/* module-global parameters */
+static struct cnfparamdescr modpdescr[] = {
+ { "ruleset", eCmdHdlrString, 0 },
+ { "markmessagetext", eCmdHdlrString, 0 },
+ { "use.syslogcall", eCmdHdlrBinary, 0 },
+ { "use.markflag", eCmdHdlrBinary, 0 },
+ { "interval", eCmdHdlrInt, 0 }
+};
+static struct cnfparamblk modpblk =
+ { CNFPARAMBLK_VERSION,
+ sizeof(modpdescr)/sizeof(struct cnfparamdescr),
+ modpdescr
+ };
+
+
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config parameters permitted? */
+static prop_t *pInternalInputName = NULL;
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ if(eFeat == sFEATURENonCancelInputTermination)
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
+
+
+BEGINafterRun
+CODESTARTafterRun
+ENDafterRun
+
+
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ /* init our settings */
+ pModConf->pszMarkMsgText = NULL;
+ pModConf->iMarkMessagePeriod = DEFAULT_MARK_PERIOD;
+ pModConf->bUseSyslogAPI = 1;
+ pModConf->bUseMarkFlag = 1;
+ pModConf->pszBindRuleset = NULL;
+ pModConf->pBindRuleset = NULL;
+ loadModConf->configSetViaV2Method = 0;
+ bLegacyCnfModGlobalsPermitted = 1;
+ENDbeginCnfLoad
+
+static rsRetVal
+checkRuleset(modConfData_t *modConf)
+{
+ ruleset_t *pRuleset;
+ rsRetVal localRet;
+ DEFiRet;
+
+ if(modConf->pszBindRuleset == NULL)
+ FINALIZE;
+
+ localRet = ruleset.GetRuleset(modConf->pConf, &pRuleset, modConf->pszBindRuleset);
+ if(localRet == RS_RET_NOT_FOUND) {
+ LogError(0, NO_ERRCODE, "immark: ruleset '%s' not found - "
+ "using default ruleset instead", modConf->pszBindRuleset);
+ }
+ CHKiRet(localRet);
+ modConf->pBindRuleset = pRuleset;
+
+finalize_it:
+ RETiRet;
+}
+
+BEGINsetModCnf
+ struct cnfparamvals *pvals = NULL;
+ int i;
+CODESTARTsetModCnf
+ pvals = nvlstGetParams(lst, &modpblk, NULL);
+ if(pvals == NULL) {
+ LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module "
+ "config parameters [module(...)]");
+ ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
+ }
+
+ if(Debug) {
+ dbgprintf("module (global) param blk for immark:\n");
+ cnfparamsPrint(&modpblk, pvals);
+ }
+
+ for(i = 0 ; i < modpblk.nParams ; ++i) {
+ if(!pvals[i].bUsed)
+ continue;
+ if(!strcmp(modpblk.descr[i].name, "interval")) {
+ loadModConf->iMarkMessagePeriod = (int) pvals[i].val.d.n;
+ } else if(!strcmp(modpblk.descr[i].name, "use.syslogcall")) {
+ loadModConf->bUseSyslogAPI = (int) pvals[i].val.d.n;
+ } else if(!strcmp(modpblk.descr[i].name, "use.markflag")) {
+ loadModConf->bUseMarkFlag = (int) pvals[i].val.d.n;
+ } else if(!strcmp(modpblk.descr[i].name, "ruleset")) {
+ loadModConf->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else if(!strcmp(modpblk.descr[i].name, "markmessagetext")) {
+ loadModConf->pszMarkMsgText = es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else {
+ dbgprintf("immark: program error, non-handled "
+ "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
+ }
+ }
+
+ /* disable legacy module-global config directives */
+ bLegacyCnfModGlobalsPermitted = 0;
+ loadModConf->configSetViaV2Method = 1;
+
+finalize_it:
+ if(pvals != NULL)
+ cnfparamvalsDestruct(pvals, &modpblk);
+ENDsetModCnf
+
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ if(!loadModConf->configSetViaV2Method) {
+ pModConf->iMarkMessagePeriod = iMarkMessagePeriod;
+ }
+ENDendCnfLoad
+
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ pModConf->flags = (pModConf->bUseMarkFlag) ? MARK : 0;
+ if(pModConf->pszMarkMsgText == NULL) {
+ pModConf->pszMarkMsgText = strdup("-- MARK --");
+ }
+ pModConf->lenMarkMsgText = strlen(pModConf->pszMarkMsgText);
+ if(pModConf->pszBindRuleset != NULL) {
+ checkRuleset(pModConf);
+ if(pModConf->bUseSyslogAPI) {
+ LogError(0, NO_ERRCODE, "immark: ruleset specified, but configured to log "
+ "via syslog call - switching to rsyslog-internal logging");
+ pModConf->bUseSyslogAPI = 0;
+ }
+ }
+ if(pModConf->iMarkMessagePeriod == 0) {
+ LogError(0, NO_ERRCODE, "immark: mark message period must not be 0, can not run");
+ ABORT_FINALIZE(RS_RET_NO_RUN); /* we can not run with this error */
+ }
+finalize_it:
+ENDcheckCnf
+
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ MarkInterval = pModConf->iMarkMessagePeriod;
+ DBGPRINTF("immark set MarkInterval to %d\n", MarkInterval);
+ENDactivateCnf
+
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ENDfreeCnf
+
+
+static rsRetVal
+injectMarkMessage(const int pri)
+{
+ smsg_t *pMsg;
+ DEFiRet;
+
+ CHKiRet(msgConstruct(&pMsg));
+ pMsg->msgFlags = loadModConf->flags;
+ MsgSetInputName(pMsg, pInternalInputName);
+ MsgSetRawMsg(pMsg, loadModConf->pszMarkMsgText,loadModConf->lenMarkMsgText);
+ MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
+ MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp());
+ MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP());
+ MsgSetMSGoffs(pMsg, 0);
+ MsgSetTAG(pMsg, (const uchar*)"rsyslogd:", sizeof("rsyslogd:")-1);
+ msgSetPRI(pMsg, pri);
+ MsgSetRuleset(pMsg, loadModConf->pBindRuleset);
+ submitMsg2(pMsg);
+finalize_it:
+ RETiRet;
+}
+
+/* This function is called to gather input. It must terminate only
+ * a) on failure (iRet set accordingly)
+ * b) on termination of the input module (as part of the unload process)
+ * Code begun 2007-12-12 rgerhards
+ *
+ * This code must simply spawn emit a mark message at each mark interval.
+ * We are running on our own thread, so this is extremely easy: we just
+ * sleep MarkInterval seconds and each time we awake, we inject the message.
+ * Please note that we do not do the other fancy things that sysklogd
+ * (and pre 1.20.2 releases of rsyslog) did in mark procesing. They simply
+ * do not belong here.
+ */
+BEGINrunInput
+CODESTARTrunInput
+ /* this is an endless loop - it is terminated when the thread is
+ * signalled to do so. This, however, is handled by the framework,
+ * right into the sleep below.
+ */
+ while(1) {
+ srSleep(MarkInterval, 0); /* seconds, micro seconds */
+
+ if(glbl.GetGlobalInputTermState() == 1)
+ break; /* terminate input! */
+
+ dbgprintf("immark: injecting mark message\n");
+ if(loadModConf->bUseSyslogAPI) {
+ logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO,
+ (uchar*)loadModConf->pszMarkMsgText, loadModConf->flags);
+ } else {
+ injectMarkMessage(LOG_SYSLOG|LOG_INFO);
+ }
+ }
+ENDrunInput
+
+
+BEGINwillRun
+CODESTARTwillRun
+ENDwillRun
+
+
+BEGINmodExit
+CODESTARTmodExit
+ if(pInternalInputName != NULL)
+ prop.Destruct(&pInternalInputName);
+ objRelease(ruleset, CORE_COMPONENT);
+ objRelease(prop, CORE_COMPONENT);
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_IMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES
+CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
+ENDqueryEtryPt
+
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
+{
+ iMarkMessagePeriod = DEFAULT_MARK_PERIOD;
+ return RS_RET_OK;
+}
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(prop, CORE_COMPONENT));
+ CHKiRet(objUse(ruleset, CORE_COMPONENT));
+
+ /* we need to create the inputName property (only once during our lifetime) */
+ CHKiRet(prop.Construct(&pInternalInputName));
+ CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("immark"), sizeof("immark") - 1));
+ CHKiRet(prop.ConstructFinalize(pInternalInputName));
+
+ /* legacy config handlers */
+ CHKiRet(regCfSysLineHdlr2((uchar *)"markmessageperiod", 0, eCmdHdlrInt, NULL,
+ &iMarkMessagePeriod, STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
+ resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ENDmodInit