summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-10-13 11:59:53 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2013-10-13 11:59:53 +0200
commit42bfcef69a068f52579b2ac2cc7dcca77c89dfc4 (patch)
treed2400724222da7f0ae39d10d8e6809e530cb4616
parent2ff36f90b04e3374bf2fbbc8485658096ee7c490 (diff)
parent32467b3bcd7cfd755117b24675a9985135179207 (diff)
downloadrsyslog-42bfcef69a068f52579b2ac2cc7dcca77c89dfc4.tar.gz
rsyslog-42bfcef69a068f52579b2ac2cc7dcca77c89dfc4.tar.bz2
rsyslog-42bfcef69a068f52579b2ac2cc7dcca77c89dfc4.zip
Merge branch 'master-lookup'
Conflicts: grammar/rainerscript.h runtime/rsyslog.h
-rw-r--r--doc/lookup_tables.html2
-rw-r--r--grammar/lexer.l2
-rw-r--r--grammar/rainerscript.c49
-rw-r--r--grammar/rainerscript.h6
-rw-r--r--runtime/Makefile.am2
-rw-r--r--runtime/lookup.c375
-rw-r--r--runtime/lookup.h57
-rw-r--r--runtime/rsconf.c6
-rw-r--r--runtime/rsconf.h2
-rw-r--r--runtime/rsyslog.c3
-rw-r--r--runtime/rsyslog.h1
-rw-r--r--runtime/typedefs.h4
-rw-r--r--tools/syslogd.c1
13 files changed, 507 insertions, 3 deletions
diff --git a/doc/lookup_tables.html b/doc/lookup_tables.html
index d72810f1..b7fcff04 100644
--- a/doc/lookup_tables.html
+++ b/doc/lookup_tables.html
@@ -104,7 +104,7 @@ lookup_table(name="name" file="/path/to/file" reloadOnHUP="on|off")
<h3>lookup() Function</h3>
<p>This function is used to actually do the table lookup. Format:
<pre>
-lookup_table("name", indexvalue)
+lookup("name", indexvalue)
</pre>
<h4>Parameters</h4>
<ul>
diff --git a/grammar/lexer.l b/grammar/lexer.l
index 438ccdd8..d254d47e 100644
--- a/grammar/lexer.l
+++ b/grammar/lexer.l
@@ -192,6 +192,8 @@ int fileno(FILE *stream);
BEGIN INOBJ; return BEGINOBJ; }
"module"[ \n\t]*"(" { yylval.objType = CNFOBJ_MODULE;
BEGIN INOBJ; return BEGINOBJ; }
+"lookup_table"[ \n\t]*"(" { yylval.objType = CNFOBJ_LOOKUP_TABLE;
+ BEGIN INOBJ; return BEGINOBJ; }
"action"[ \n\t]*"(" { BEGIN INOBJ; return BEGIN_ACTION; }
^[ \t]*:\$?[a-z\-]+[ ]*,[ ]*!?[a-z]+[ ]*,[ ]*\"(\\\"|[^\"])*\" {
yylval.s = strdup(rmLeadingSpace(yytext));
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index f4833679..328ec7fc 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -1334,6 +1334,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
int bMustFree;
es_str_t *estr;
char *str;
+ char *s;
uchar *resStr;
int retval;
struct var r[CNFFUNC_MAX_ARGS];
@@ -1471,6 +1472,19 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
ret->d.n = 1;
ret->datatype = 'N';
break;
+ case CNFFUNC_LOOKUP:
+dbgprintf("DDDD: executing lookup\n");
+ ret->datatype = 'S';
+ if(func->funcdata == NULL) {
+ ret->d.estr = es_newStrFromCStr("TABLE-NOT-FOUND", sizeof("TABLE-NOT-FOUND")-1);
+ break;
+ }
+ cnfexprEval(func->expr[1], &r[1], usrptr);
+ str = (char*) var2CString(&r[1], &bMustFree);
+ ret->d.estr = lookupKey_estr(func->funcdata, (uchar*)str);
+ if(bMustFree) free(str);
+ if(r[1].datatype == 'S') es_deleteStr(r[1].d.estr);
+ break;
default:
if(Debug) {
fname = es_str2cstr(func->fname, NULL);
@@ -3234,6 +3248,13 @@ funcName2ID(es_str_t *fname, unsigned short nParams)
return CNFFUNC_INVALID;
}
return CNFFUNC_PRIFILT;
+ } else if(!es_strbufcmp(fname, (unsigned char*)"lookup", sizeof("lookup") - 1)) {
+ if(nParams != 2) {
+ parser_errmsg("number of parameters for lookup() must be two "
+ "but is %d.", nParams);
+ return CNFFUNC_INVALID;
+ }
+ return CNFFUNC_LOOKUP;
} else {
return CNFFUNC_INVALID;
}
@@ -3298,6 +3319,31 @@ finalize_it:
}
+static inline rsRetVal
+initFunc_lookup(struct cnffunc *func)
+{
+ struct funcData_prifilt *pData;
+ uchar *cstr = NULL;
+ DEFiRet;
+
+ func->funcdata = NULL;
+ if(func->expr[0]->nodetype != 'S') {
+ parser_errmsg("table name (param 1) of lookup() must be a constant string");
+ FINALIZE;
+ }
+
+ cstr = (uchar*)es_str2cstr(((struct cnfstringval*) func->expr[0])->estr, NULL);
+ if((func->funcdata = lookupFindTable(cstr)) == NULL) {
+ parser_errmsg("lookup table '%s' not found", cstr);
+ FINALIZE;
+ }
+
+finalize_it:
+ free(cstr);
+ RETiRet;
+}
+
+
struct cnffunc *
cnffuncNew(es_str_t *fname, struct cnffparamlst* paramlst)
{
@@ -3335,6 +3381,9 @@ cnffuncNew(es_str_t *fname, struct cnffparamlst* paramlst)
case CNFFUNC_PRIFILT:
initFunc_prifilt(func);
break;
+ case CNFFUNC_LOOKUP:
+ initFunc_lookup(func);
+ break;
default:break;
}
}
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
index 3e59fc60..4a508f93 100644
--- a/grammar/rainerscript.h
+++ b/grammar/rainerscript.h
@@ -25,6 +25,7 @@ enum cnfobjType {
CNFOBJ_PROPERTY,
CNFOBJ_CONSTANT,
CNFOBJ_MAINQ,
+ CNFOBJ_LOOKUP_TABLE,
CNFOBJ_INVALID = 0
};
@@ -58,6 +59,8 @@ cnfobjType2str(enum cnfobjType ot)
break;
case CNFOBJ_MAINQ:
return "main_queue";
+ case CNFOBJ_LOOKUP_TABLE:
+ return "lookup_table";
break;
default:return "error: invalid cnfobjType";
}
@@ -232,7 +235,8 @@ enum cnffuncid {
CNFFUNC_RE_MATCH,
CNFFUNC_RE_EXTRACT,
CNFFUNC_FIELD,
- CNFFUNC_PRIFILT
+ CNFFUNC_PRIFILT,
+ CNFFUNC_LOOKUP
};
struct cnffunc {
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index 34384bea..230be69e 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -69,6 +69,8 @@ librsyslog_la_SOURCES = \
prop.h \
ratelimit.c \
ratelimit.h \
+ lookup.c \
+ lookup.h \
cfsysline.c \
cfsysline.h \
sd-daemon.c \
diff --git a/runtime/lookup.c b/runtime/lookup.c
new file mode 100644
index 00000000..bc3b1a94
--- /dev/null
+++ b/runtime/lookup.c
@@ -0,0 +1,375 @@
+/* lookup.c
+ * Support for lookup tables in RainerScript.
+ *
+ * Copyright 2013 Adiscon GmbH.
+ *
+ * This file is part of the rsyslog runtime library.
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <json/json.h>
+#include <json/json.h>
+#include <assert.h>
+
+#include "rsyslog.h"
+#include "srUtils.h"
+#include "errmsg.h"
+#include "lookup.h"
+#include "msg.h"
+#include "rsconf.h"
+#include "dirty.h"
+#include "unicode-helper.h"
+
+/* definitions for objects we access */
+DEFobjStaticHelpers
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
+
+/* forward definitions */
+static rsRetVal lookupReadFile(lookup_t *pThis);
+
+/* static data */
+/* tables for interfacing with the v6 config system (as far as we need to) */
+static struct cnfparamdescr modpdescr[] = {
+ { "name", eCmdHdlrString, CNFPARAM_REQUIRED },
+ { "file", eCmdHdlrString, CNFPARAM_REQUIRED }
+};
+static struct cnfparamblk modpblk =
+ { CNFPARAMBLK_VERSION,
+ sizeof(modpdescr)/sizeof(struct cnfparamdescr),
+ modpdescr
+ };
+
+
+/* create a new lookup table object AND include it in our list of
+ * lookup tables.
+ */
+rsRetVal
+lookupNew(lookup_t **ppThis)
+{
+ lookup_t *pThis = NULL;
+ DEFiRet;
+
+ CHKmalloc(pThis = malloc(sizeof(lookup_t)));
+ pthread_rwlock_init(&pThis->rwlock, NULL);
+ pThis->name = NULL;
+
+ if(loadConf->lu_tabs.root == NULL) {
+ loadConf->lu_tabs.root = pThis;
+ pThis->next = NULL;
+ } else {
+ pThis->next = loadConf->lu_tabs.last;
+ }
+ loadConf->lu_tabs.last = pThis;
+
+ *ppThis = pThis;
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ free(pThis);
+ }
+ RETiRet;
+}
+void
+lookupDestruct(lookup_t *pThis)
+{
+ pthread_rwlock_destroy(&pThis->rwlock);
+ free(pThis->name);
+ free(pThis);
+}
+
+void
+lookupInitCnf(lookup_tables_t *lu_tabs)
+{
+ lu_tabs->root = NULL;
+ lu_tabs->last = NULL;
+}
+
+
+/* comparison function for qsort() and string array compare
+ * this is for the string lookup table type
+ */
+static int
+qs_arrcmp_strtab(const void *s1, const void *s2)
+{
+ return ustrcmp(((lookup_string_tab_etry_t*)s1)->key, ((lookup_string_tab_etry_t*)s2)->key);
+}
+/* comparison function for bsearch() and string array compare
+ * this is for the string lookup table type
+ */
+static int
+bs_arrcmp_strtab(const void *s1, const void *s2)
+{
+ return strcmp((char*)s1, (char*)((lookup_string_tab_etry_t*)s2)->key);
+}
+
+rsRetVal
+lookupBuildTable(lookup_t *pThis, struct json_object *jroot)
+{
+ struct json_object *jversion, *jnomatch, *jtype, *jtab;
+ struct json_object *jrow, *jindex, *jvalue;
+ uint32_t i;
+ uint32_t maxStrSize;
+ DEFiRet;
+
+ jversion = json_object_object_get(jroot, "version");
+ jnomatch = json_object_object_get(jroot, "nomatch");
+ jtype = json_object_object_get(jroot, "type");
+ jtab = json_object_object_get(jroot, "table");
+ pThis->nmemb = json_object_array_length(jtab);
+ CHKmalloc(pThis->d.strtab = malloc(pThis->nmemb * sizeof(lookup_string_tab_etry_t)));
+
+ maxStrSize = 0;
+ for(i = 0 ; i < pThis->nmemb ; ++i) {
+ jrow = json_object_array_get_idx(jtab, i);
+ jindex = json_object_object_get(jrow, "index");
+ jvalue = json_object_object_get(jrow, "value");
+ CHKmalloc(pThis->d.strtab[i].key = (uchar*) strdup(json_object_get_string(jindex)));
+ CHKmalloc(pThis->d.strtab[i].val = (uchar*) strdup(json_object_get_string(jvalue)));
+ maxStrSize += ustrlen(pThis->d.strtab[i].val);
+ }
+
+ qsort(pThis->d.strtab, pThis->nmemb, sizeof(lookup_string_tab_etry_t), qs_arrcmp_strtab);
+dbgprintf("DDDD: table loaded (max size %u):\n", maxStrSize);
+for(i = 0 ; i < pThis->nmemb ; ++i)
+ dbgprintf("key: '%s', val: '%s'\n", pThis->d.strtab[i].key, pThis->d.strtab[i].val);
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* find a lookup table. This is a naive O(n) algo, but this really
+ * doesn't matter as it is called only a few times during config
+ * load. The function returns either a pointer to the requested
+ * table or NULL, if not found.
+ */
+lookup_t *
+lookupFindTable(uchar *name)
+{
+ lookup_t *curr;
+
+ for(curr = loadConf->lu_tabs.root ; curr != NULL ; curr = curr->next) {
+ if(!ustrcmp(curr->name, name))
+ break;
+ }
+ return curr;
+}
+
+
+/* this reloads a lookup table. This is done while the engine is running,
+ * as such the function must ensure proper locking and proper order of
+ * operations (so that nothing can interfere). If the table cannot be loaded,
+ * the old table is continued to be used.
+ */
+static rsRetVal
+lookupReload(lookup_t *pThis)
+{
+ uint32_t i;
+ lookup_t newlu; /* dummy to be able to use support functions without
+ affecting current settings. */
+ DEFiRet;
+
+ DBGPRINTF("reload requested for lookup table '%s'\n", pThis->name);
+ memset(&newlu, 0, sizeof(newlu));
+ CHKmalloc(newlu.name = ustrdup(pThis->name));
+ CHKmalloc(newlu.filename = ustrdup(pThis->filename));
+ CHKiRet(lookupReadFile(&newlu));
+ /* all went well, copy over data members */
+ pthread_rwlock_wrlock(&pThis->rwlock);
+ for(i = 0 ; i < pThis->nmemb ; ++i) {
+ free(pThis->d.strtab[i].key), /* we don't care about exec order of frees */
+ free(pThis->d.strtab[i].val);
+ }
+ free(pThis->d.strtab);
+ pThis->d.strtab = newlu.d.strtab; /* hand table AND ALL STRINGS over! */
+ pthread_rwlock_unlock(&pThis->rwlock);
+ errmsg.LogError(0, RS_RET_OK, "lookup table '%s' reloaded from file '%s'",
+ pThis->name, pThis->filename);
+finalize_it:
+ free(newlu.name);
+ free(newlu.filename);
+ RETiRet;
+}
+
+
+/* reload all lookup tables on HUP */
+void
+lookupDoHUP()
+{
+ lookup_t *lu;
+ for(lu = loadConf->lu_tabs.root ; lu != NULL ; lu = lu->next) {
+ lookupReload(lu);
+ }
+}
+
+
+/* returns either a pointer to the value (read only!) or NULL
+ * if either the key could not be found or an error occured.
+ * Note that an estr_t object is returned. The caller is
+ * responsible for freeing it.
+ */
+es_str_t *
+lookupKey_estr(lookup_t *pThis, uchar *key)
+{
+ lookup_string_tab_etry_t *etry;
+ char *r;
+ es_str_t *estr;
+
+ pthread_rwlock_rdlock(&pThis->rwlock);
+ etry = bsearch(key, pThis->d.strtab, pThis->nmemb, sizeof(lookup_string_tab_etry_t), bs_arrcmp_strtab);
+ if(etry == NULL) {
+ r = ""; // TODO: use set default
+ } else {
+ r = (char*)etry->val;
+ }
+ estr = es_newStrFromCStr(r, strlen(r));
+ pthread_rwlock_unlock(&pThis->rwlock);
+ return estr;
+}
+
+
+/* note: widely-deployed json_c 0.9 does NOT support incremental
+ * parsing. In order to keep compatible with e.g. Ubuntu 12.04LTS,
+ * we read the file into one big memory buffer and parse it at once.
+ * While this is not very elegant, it will not pose any real issue
+ * for "reasonable" lookup tables (and "unreasonably" large ones
+ * will probably have other issues as well...).
+ */
+static rsRetVal
+lookupReadFile(lookup_t *pThis)
+{
+ struct json_tokener *tokener = NULL;
+ struct json_object *json = NULL;
+ int eno = errno;
+ char errStr[1024];
+ char *iobuf = NULL;
+ int fd;
+ ssize_t nread;
+ struct stat sb;
+ DEFiRet;
+
+
+ if(stat((char*)pThis->filename, &sb) == -1) {
+ eno = errno;
+ errmsg.LogError(0, RS_RET_FILE_NOT_FOUND,
+ "lookup table file '%s' stat failed: %s",
+ pThis->filename, rs_strerror_r(eno, errStr, sizeof(errStr)));
+ ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND);
+ }
+
+ CHKmalloc(iobuf = malloc(sb.st_size));
+
+ if((fd = open((const char*) pThis->filename, O_RDONLY)) == -1) {
+ eno = errno;
+ errmsg.LogError(0, RS_RET_FILE_NOT_FOUND,
+ "lookup table file '%s' could not be opened: %s",
+ pThis->filename, rs_strerror_r(eno, errStr, sizeof(errStr)));
+ ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND);
+ }
+
+ tokener = json_tokener_new();
+ nread = read(fd, iobuf, sb.st_size);
+ if(nread != (ssize_t) sb.st_size) {
+ eno = errno;
+ errmsg.LogError(0, RS_RET_READ_ERR,
+ "lookup table file '%s' read error: %s",
+ pThis->filename, rs_strerror_r(eno, errStr, sizeof(errStr)));
+ ABORT_FINALIZE(RS_RET_READ_ERR);
+ }
+
+ json = json_tokener_parse_ex(tokener, iobuf, sb.st_size);
+ if(json == NULL) {
+ errmsg.LogError(0, RS_RET_JSON_PARSE_ERR,
+ "lookup table file '%s' json parsing error",
+ pThis->filename);
+ ABORT_FINALIZE(RS_RET_JSON_PARSE_ERR);
+ }
+ free(iobuf); /* early free to sever resources*/
+ iobuf = NULL; /* make sure no double-free */
+
+ /* got json object, now populate our own in-memory structure */
+ CHKiRet(lookupBuildTable(pThis, json));
+
+finalize_it:
+ free(iobuf);
+ if(tokener != NULL)
+ json_tokener_free(tokener);
+ if(json != NULL)
+ json_object_put(json);
+ RETiRet;
+}
+
+
+rsRetVal
+lookupProcessCnf(struct cnfobj *o)
+{
+ struct cnfparamvals *pvals;
+ lookup_t *lu;
+ short i;
+ DEFiRet;
+
+ pvals = nvlstGetParams(o->nvlst, &modpblk, NULL);
+ if(pvals == NULL) {
+ ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
+ }
+ DBGPRINTF("lookupProcessCnf params:\n");
+ cnfparamsPrint(&modpblk, pvals);
+
+ CHKiRet(lookupNew(&lu));
+
+ for(i = 0 ; i < modpblk.nParams ; ++i) {
+ if(!pvals[i].bUsed)
+ continue;
+ if(!strcmp(modpblk.descr[i].name, "file")) {
+ CHKmalloc(lu->filename = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL));
+ } else if(!strcmp(modpblk.descr[i].name, "name")) {
+ CHKmalloc(lu->name = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL));
+ } else {
+ dbgprintf("lookup_table: program error, non-handled "
+ "param '%s'\n", modpblk.descr[i].name);
+ }
+ }
+ CHKiRet(lookupReadFile(lu));
+ DBGPRINTF("lookup table '%s' loaded from file '%s'\n", lu->name, lu->filename);
+
+finalize_it:
+ cnfparamvalsDestruct(pvals, &modpblk);
+ RETiRet;
+}
+
+void
+lookupClassExit(void)
+{
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(errmsg, CORE_COMPONENT);
+}
+
+rsRetVal
+lookupClassInit(void)
+{
+ DEFiRet;
+ CHKiRet(objGetObjInterface(&obj));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+finalize_it:
+ RETiRet;
+}
diff --git a/runtime/lookup.h b/runtime/lookup.h
new file mode 100644
index 00000000..c478d679
--- /dev/null
+++ b/runtime/lookup.h
@@ -0,0 +1,57 @@
+/* header for lookup.c
+ *
+ * Copyright 2013 Adiscon GmbH.
+ *
+ * This file is part of the rsyslog runtime library.
+ *
+ * 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.
+ */
+#ifndef INCLUDED_LOOKUP_H
+#define INCLUDED_LOOKUP_H
+#include <libestr.h>
+
+struct lookup_tables_s {
+ lookup_t *root; /* the root of the template list */
+ lookup_t *last; /* points to the last element of the template list */
+};
+
+struct lookup_string_tab_etry_s {
+ uchar *key;
+ uchar *val;
+};
+
+/* a single lookup table */
+struct lookup_s {
+ pthread_rwlock_t rwlock; /* protect us in case of dynamic reloads */
+ uchar *name;
+ uchar *filename;
+ uint32_t nmemb;
+ union {
+ lookup_string_tab_etry_t *strtab;
+ } d;
+ lookup_t *next;
+};
+
+/* prototypes */
+void lookupInitCnf(lookup_tables_t *lu_tabs);
+rsRetVal lookupProcessCnf(struct cnfobj *o);
+lookup_t *lookupFindTable(uchar *name);
+es_str_t * lookupKey_estr(lookup_t *pThis, uchar *key);
+void lookupDestruct(lookup_t *pThis);
+void lookupClassExit(void);
+void lookupDoHUP();
+rsRetVal lookupClassInit(void);
+
+#endif /* #ifndef INCLUDED_LOOKUP_H */
diff --git a/runtime/rsconf.c b/runtime/rsconf.c
index 3976a52f..b739608a 100644
--- a/runtime/rsconf.c
+++ b/runtime/rsconf.c
@@ -2,7 +2,7 @@
*
* Module begun 2011-04-19 by Rainer Gerhards
*
- * Copyright 2011-2012 Adiscon GmbH.
+ * Copyright 2011-2013 Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@@ -124,6 +124,7 @@ BEGINobjConstruct(rsconf) /* be sure to specify the object type also in END macr
pThis->templates.last = NULL;
pThis->templates.lastStatic = NULL;
pThis->actions.nbrActions = 0;
+ lookupInitCnf(&pThis->lu_tabs);
CHKiRet(llInit(&pThis->rulesets.llRulesets, rulesetDestructForLinkedList,
rulesetKeyDestruct, strcasecmp));
/* queue params */
@@ -418,6 +419,9 @@ void cnfDoObj(struct cnfobj *o)
case CNFOBJ_INPUT:
inputProcessCnf(o);
break;
+ case CNFOBJ_LOOKUP_TABLE:
+ lookupProcessCnf(o);
+ break;
case CNFOBJ_TPL:
if(tplProcessCnf(o) != RS_RET_OK)
parser_errmsg("error processing template object");
diff --git a/runtime/rsconf.h b/runtime/rsconf.h
index 484fec8c..894c0d12 100644
--- a/runtime/rsconf.h
+++ b/runtime/rsconf.h
@@ -25,6 +25,7 @@
#include "linkedlist.h"
#include "queue.h"
+#include "lookup.h"
/* --- configuration objects (the plan is to have ALL upper layers in this file) --- */
@@ -143,6 +144,7 @@ struct rsconf_s {
globals_t globals;
defaults_t defaults;
templates_t templates;
+ lookup_tables_t lu_tabs;
outchannels_t och;
actions_t actions;
rulesets_t rulesets;
diff --git a/runtime/rsyslog.c b/runtime/rsyslog.c
index 047dfa9b..53c7855a 100644
--- a/runtime/rsyslog.c
+++ b/runtime/rsyslog.c
@@ -74,6 +74,7 @@
#include "prop.h"
#include "ruleset.h"
#include "parser.h"
+#include "lookup.h"
#include "strgen.h"
#include "statsobj.h"
#include "atomic.h"
@@ -186,6 +187,8 @@ rsrtInit(char **ppErrObj, obj_if_t *pObjIF)
CHKiRet(strgenClassInit(NULL));
if(ppErrObj != NULL) *ppErrObj = "rsconf";
CHKiRet(rsconfClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "lookup";
+ CHKiRet(lookupClassInit());
/* dummy "classes" */
if(ppErrObj != NULL) *ppErrObj = "str";
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index fffcfbf4..71849bec 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -426,6 +426,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_RELP_AUTH_FAIL = -2353,/**< RELP peer authentication failed */
RS_RET_ERR_UDPSEND = -2354,/**< sending msg via UDP failed */
RS_RET_LAST_ERRREPORT = -2355,/**< module does not emit more error messages as limit is reached */
+ RS_RET_READ_ERR = -2356,/**< read error occured (file i/o) */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
diff --git a/runtime/typedefs.h b/runtime/typedefs.h
index d3f68b4a..a929b30c 100644
--- a/runtime/typedefs.h
+++ b/runtime/typedefs.h
@@ -25,6 +25,7 @@
*/
#ifndef INCLUDED_TYPEDEFS_H
#define INCLUDED_TYPEDEFS_H
+#include <stdint.h>
#if defined(__FreeBSD__)
#include <sys/types.h>
#endif
@@ -100,6 +101,9 @@ typedef struct outchannels_s outchannels_t;
typedef struct modConfData_s modConfData_t;
typedef struct instanceConf_s instanceConf_t;
typedef struct ratelimit_s ratelimit_t;
+typedef struct lookup_string_tab_etry_s lookup_string_tab_etry_t;
+typedef struct lookup_tables_s lookup_tables_t;
+typedef struct lookup_s lookup_t;
typedef struct action_s action_t;
typedef int rs_size_t; /* we do never need more than 2Gig strings, signed permits to
* use -1 as a special flag. */
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 2f0f64c3..fba60df5 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -1253,6 +1253,7 @@ doHUP(void)
queryLocalHostname(); /* re-read our name */
ruleset.IterateAllActions(ourConf, doHUPActions, NULL);
+ lookupDoHUP();
}