summaryrefslogtreecommitdiff
path: root/runtime/glbl.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/glbl.c')
-rw-r--r--runtime/glbl.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/runtime/glbl.c b/runtime/glbl.c
index 73e986e..1867410 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -34,7 +34,9 @@
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
+#include <ctype.h>
#include <assert.h>
+#include <stdint.h>
#include "rsyslog.h"
#include "obj.h"
@@ -45,6 +47,7 @@
#include "atomic.h"
#include "errmsg.h"
#include "action.h"
+#include "parserif.h"
#include "rainerscript.h"
#include "net.h"
@@ -102,6 +105,7 @@ static int bSpaceLFOnRcv = 0; /* replace newlines with spaces on reception: 0 -
static int bEscape8BitChars = 0; /* escape characters > 127 on reception: 0 - no, 1 - yes */
static int bEscapeTab = 1; /* escape tab control character when doing CC escapes: 0 - no, 1 - yes */
static int bParserEscapeCCCStyle = 0; /* escape control characters in c style: 0 - no, 1 - yes */
+short janitorInterval = 10; /* interval (in minutes) at which the janitor runs */
pid_t glbl_ourpid;
#ifndef HAVE_ATOMIC_BUILTINS
@@ -112,6 +116,8 @@ static int iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask); /* si
#endif
static uchar *SourceIPofLocalClient = NULL; /* [ar] Source IP for local client to be used on multihomed host */
+tzinfo_t *tzinfos = NULL;
+static int ntzinfos;
/* tables for interfacing with the v6 config system */
static struct cnfparamdescr cnfparamdescr[] = {
@@ -136,6 +142,7 @@ static struct cnfparamdescr cnfparamdescr[] = {
{ "parser.escapecontrolcharactertab", eCmdHdlrBinary, 0},
{ "parser.escapecontrolcharacterscstyle", eCmdHdlrBinary, 0 },
{ "stdlog.channelspec", eCmdHdlrString, 0 },
+ { "janitor.interval", eCmdHdlrPositiveInt, 0 },
{ "processinternalmessages", eCmdHdlrBinary, 0 }
};
static struct cnfparamblk paramblk =
@@ -144,6 +151,16 @@ static struct cnfparamblk paramblk =
cnfparamdescr
};
+static struct cnfparamdescr timezonecnfparamdescr[] = {
+ { "id", eCmdHdlrString, 0 },
+ { "offset", eCmdHdlrGetWord, 0 }
+};
+static struct cnfparamblk timezonepblk =
+ { CNFPARAMBLK_VERSION,
+ sizeof(timezonecnfparamdescr)/sizeof(struct cnfparamdescr),
+ timezonecnfparamdescr
+ };
+
static struct cnfparamvals *cnfparamvals = NULL;
/* we need to support multiple calls into our param block, so we need
* to persist the current settings. Note that this must be re-set
@@ -677,6 +694,120 @@ glblPrepCnf(void)
cnfparamvals = NULL;
}
+
+static void
+freeTimezoneInfo(void)
+{
+ int i;
+ for(i = 0 ; i < ntzinfos ; ++i)
+ free(tzinfos[i].id);
+ free(tzinfos);
+ tzinfos = NULL;
+}
+
+static void
+displayTzinfos(void)
+{
+ int i;
+ if(!Debug)
+ return;
+ for(i = 0 ; i < ntzinfos ; ++i)
+ dbgprintf("tzinfo: '%s':%c%2.2d:%2.2d\n",
+ tzinfos[i].id, tzinfos[i].offsMode,
+ tzinfos[i].offsHour, tzinfos[i].offsMin);
+}
+
+
+/* Note: this function is NOT thread-safe!
+ * This is currently not needed as used only during
+ * initialization.
+ */
+static inline rsRetVal
+addTimezoneInfo(uchar *tzid, char offsMode, int8_t offsHour, int8_t offsMin)
+{
+ DEFiRet;
+ tzinfo_t *newti;
+ CHKmalloc(newti = realloc(tzinfos, (ntzinfos+1)*sizeof(tzinfo_t)));
+ CHKmalloc(newti[ntzinfos].id = strdup((char*)tzid));
+ newti[ntzinfos].offsMode = offsMode;
+ newti[ntzinfos].offsHour = offsHour;
+ newti[ntzinfos].offsMin = offsMin;
+ ++ntzinfos, tzinfos = newti;
+finalize_it:
+ RETiRet;
+}
+
+
+static int
+bs_arrcmp_tzinfo(const void *s1, const void *s2)
+{
+ return strcmp((char*)s1, (char*)((tzinfo_t*)s2)->id);
+}
+/* returns matching timezone info or NULL if no entry exists */
+tzinfo_t*
+glblFindTimezoneInfo(char *id)
+{
+ return (tzinfo_t*) bsearch(id, tzinfos, ntzinfos, sizeof(tzinfo_t), bs_arrcmp_tzinfo);
+}
+
+/* handle the timezone() object. Each incarnation adds one additional
+ * zone info to the global table of time zones.
+ */
+void
+glblProcessTimezone(struct cnfobj *o)
+{
+ struct cnfparamvals *pvals;
+ uchar *id = NULL;
+ uchar *offset = NULL;
+ char offsMode;
+ int8_t offsHour;
+ int8_t offsMin;
+ int i;
+
+ pvals = nvlstGetParams(o->nvlst, &timezonepblk, NULL);
+ dbgprintf("timezone param blk after glblProcessTimezone:\n");
+ cnfparamsPrint(&timezonepblk, pvals);
+
+ for(i = 0 ; i < timezonepblk.nParams ; ++i) {
+ if(!pvals[i].bUsed)
+ continue;
+ if(!strcmp(timezonepblk.descr[i].name, "id")) {
+ id = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else if(!strcmp(timezonepblk.descr[i].name, "offset")) {
+ offset = (uchar*) es_str2cstr(pvals[i].val.d.estr, NULL);
+ } else {
+ dbgprintf("glblProcessTimezone: program error, non-handled "
+ "param '%s'\n", timezonepblk.descr[i].name);
+ }
+ }
+
+ if( strlen((char*)offset) != 6
+ || !(offset[0] == '-' || offset[0] == '+')
+ || !(isdigit(offset[1]) && isdigit(offset[2]))
+ || offset[3] != ':'
+ || !(isdigit(offset[4]) && isdigit(offset[5]))
+ ) {
+ parser_errmsg("timezone offset has invalid format. Must be +/-hh:mm, e.g. \"-07:00\".");
+ goto done;
+ }
+
+ offsHour = (offset[1] - '0') * 10 + offset[2] - '0';
+ offsMin = (offset[4] - '0') * 10 + offset[5] - '0';
+ offsMode = offset[0];
+
+ if(offsHour > 12 || offsMin > 59) {
+ parser_errmsg("timezone offset outside of supported range (hours 0..12, minutes 0..59)");
+ goto done;
+ }
+
+ addTimezoneInfo(id, offsMode, offsHour, offsMin);
+
+done:
+ cnfparamvalsDestruct(pvals, &timezonepblk);
+ free(id);
+ free(offset);
+}
+
/* handle a global config object. Note that multiple global config statements
* are permitted (because of plugin support), so once we got a param block,
* we need to hold to it.
@@ -737,6 +868,14 @@ glblDestructMainqCnfObj()
mainqCnfObj = NULL;
}
+/* comparison function for qsort() and string array compare
+ * this is for the string lookup table type
+ */
+static int
+qs_arrcmp_tzinfo(const void *s1, const void *s2)
+{
+ return strcmp(((tzinfo_t*)s1)->id, ((tzinfo_t*)s2)->id);
+}
/* This processes the "regular" parameters which are to be set after the
* config has been fully loaded.
@@ -747,6 +886,10 @@ glblDoneLoadCnf(void)
int i;
unsigned char *cstr;
+ qsort(tzinfos, ntzinfos, sizeof(tzinfo_t), qs_arrcmp_tzinfo);
+ DBGPRINTF("Timezone information table (%d entries):\n", ntzinfos);
+ displayTzinfos();
+
if(cnfparamvals == NULL)
goto finalize_it;
@@ -812,6 +955,8 @@ glblDoneLoadCnf(void)
}
}
errmsg.LogError(0, RS_RET_OK, "debug log file is '%s', fd %d", pszAltDbgFileName, altdbg);
+ } else if(!strcmp(paramblk.descr[i].name, "janitor.interval")) {
+ janitorInterval = (int) cnfparamvals[i].val.d.n;
} else {
dbgprintf("glblDoneLoadCnf: program error, non-handled "
"param '%s'\n", paramblk.descr[i].name);
@@ -822,6 +967,7 @@ glblDoneLoadCnf(void)
Debug = DEBUG_ONDEMAND;
stddbg = -1;
}
+
finalize_it: return;
}
@@ -877,6 +1023,7 @@ BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */
free(LocalHostName);
free(LocalHostNameOverride);
free(LocalFQDNName);
+ freeTimezoneInfo();
objRelease(prop, CORE_COMPONENT);
if(propLocalHostNameToDelete != NULL)
prop.Destruct(&propLocalHostNameToDelete);