summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/Makefile.am12
-rw-r--r--tools/logctl.c458
-rw-r--r--tools/omfile.c148
-rw-r--r--tools/omfwd.c135
-rw-r--r--tools/ompipe.c102
-rw-r--r--tools/pidfile.c6
-rw-r--r--tools/pmrfc3164.c4
-rw-r--r--tools/syslogd.c38
8 files changed, 839 insertions, 64 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am
index e8da168d..9dd4e3bd 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -1,4 +1,5 @@
sbin_PROGRAMS =
+bin_PROGRAMS =
man_MANS = rsyslogd.8 rsyslog.conf.5
sbin_PROGRAMS += rsyslogd
@@ -39,7 +40,7 @@ rsyslogd_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) $(CNF_LIBS)
# note: it looks like librsyslog.la must be explicitely given on LDDADD,
# otherwise dependencies are not properly calculated (resulting in a
# potentially incomplete build, a problem we had several times...)
-rsyslogd_LDADD = $(ZLIB_LIBS) $(PTHREADS_LIBS) $(RSRT_LIBS) $(SOL_LIBS) $(LIBEE_LIBS) $(LIBLOGNORM_LIBS) $(CNF_LIBS) ../grammar/libgrammar.la ../runtime/librsyslog.la
+rsyslogd_LDADD = $(ZLIB_LIBS) $(PTHREADS_LIBS) $(RSRT_LIBS) $(SOL_LIBS) $(LIBEE_LIBS) $(LIBLOGNORM_LIBS) $(CNF_LIBS) $(LIBUUID_LIBS) ../grammar/libgrammar.la ../runtime/librsyslog.la
rsyslogd_LDFLAGS = -export-dynamic
if ENABLE_DIAGTOOLS
@@ -50,5 +51,14 @@ zpipe_LDADD = -lz
msggen_SOURCES = msggen.c
endif
+if ENABLE_USERTOOLS
+if ENABLE_OMMONGODB
+bin_PROGRAMS += logctl
+logctl_SOURCES = logctl.c
+logctl_CPPFLAGS = $(LIBMONGO_CLIENT_CFLAGS)
+logctl_LDADD = $(LIBMONGO_CLIENT_LIBS)
+endif
+endif
+
EXTRA_DIST = $(man_MANS) \
recover_qi.pl
diff --git a/tools/logctl.c b/tools/logctl.c
new file mode 100644
index 00000000..df332bc2
--- /dev/null
+++ b/tools/logctl.c
@@ -0,0 +1,458 @@
+/**
+ * logctl - a tool to access lumberjack logs in MongoDB
+ * ... and potentially other sources in the future.
+ *
+ * Copyright 2012 Ulrike Gerhards and Adiscon GmbH.
+ *
+ * long short
+
+ * level l read records with level x
+ * severity s read records with severity x
+ * ret r number of records to return
+ * skip k number of records to skip
+ * sys y read records of system x
+ * msg m read records with message containing x
+ * datef f read records starting on time received x
+ * dateu u read records until time received x
+ *
+ * examples:
+ *
+ * logctl -f 15/05/2012-12:00:00 -u 15/05/2012-12:37:00
+ * logctl -s 50 --ret 10
+ * logctl -m "closed"
+ * logctl -l "INFO"
+ * logctl -s 3
+ * logctl -y "ubuntu"
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog 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 Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <mongo.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#define N 80
+
+static struct option long_options[] =
+{
+ {"level", required_argument, NULL, 'l'},
+ {"severity", required_argument, NULL, 's'},
+ {"ret", required_argument, NULL, 'r'},
+ {"skip", required_argument, NULL, 'k'},
+ {"sys", required_argument, NULL, 'y'},
+ {"msg", required_argument, NULL, 'm'},
+ {"datef", required_argument, NULL, 'f'},
+ {"dateu", required_argument, NULL, 'u'},
+ {NULL, 0, NULL, 0}
+};
+
+struct queryopt
+{
+ gint32 e_sever;
+ gint32 e_ret;
+ gint32 e_skip;
+ char *e_date;
+ char *e_level;
+ char *e_msg;
+ char *e_sys;
+ char *e_dateu;
+ int bsever;
+ int blevel;
+ int bskip;
+ int bret;
+ int bsys;
+ int bmsg;
+ int bdate;
+ int bdatef;
+ int bdateu;
+};
+
+struct ofields
+{
+ const char *msg;
+ const char *syslog_tag;
+ const char *prog;
+ char *date;
+ gint64 date_r;
+};
+
+struct query_doc
+{
+ bson *query;
+};
+
+struct select_doc
+{
+ bson *select;
+};
+
+struct db_connect
+{
+ mongo_sync_connection *conn;
+};
+
+struct output
+{
+ mongo_packet *p;
+};
+
+struct db_cursor
+{
+ mongo_sync_cursor *cursor;
+};
+
+struct results
+{
+ bson *result;
+};
+
+
+
+void formater(struct ofields *fields)
+{
+ time_t rtime;
+ rtime = (time_t) (fields->date_r / 1000);
+ char str[N];
+ strftime(str, N, "%b %d %H:%M:%S", gmtime(&rtime));
+ printf("%s %s %s %s\n", str, fields->prog, fields->syslog_tag, fields->msg);
+
+}
+
+struct ofields* get_data(struct results *res)
+{
+ struct ofields *fields;
+ const char *msg;
+ const char *prog;
+ const char *level;
+ const char *syslog_tag;
+ gint64 date_r;
+ bson_cursor *c;
+
+ fields = malloc(sizeof(struct ofields));
+
+ c = bson_find (res->result, "msg");
+ if (!bson_cursor_get_string (c, &msg))
+ {
+ perror ("bson_cursor_get_string()");
+ exit (1);
+ }
+ bson_cursor_free (c);
+
+ c = bson_find (res->result, "sys");
+ if (!bson_cursor_get_string (c, &prog))
+ {
+ perror ("bson_cursor_get_string()");
+ exit (1);
+ }
+ bson_cursor_free (c);
+
+ c = bson_find (res->result, "syslog_tag");
+ if (!bson_cursor_get_string (c, &syslog_tag))
+ {
+ perror ("bson_cursor_get_string()");
+ exit (1);
+ }
+ bson_cursor_free (c);
+
+ c = bson_find (res->result, "time_rcvd");
+ if (!bson_cursor_get_utc_datetime (c, &date_r))
+ {
+ perror ("bson_cursor_get_utc_datetime()");
+ exit (1);
+ }
+
+ bson_cursor_free (c);
+ fields->msg = msg;
+ fields->prog = prog;
+ fields->syslog_tag = syslog_tag;
+ fields->date_r = date_r;
+
+ return fields;
+
+}
+
+void getoptions(int argc, char *argv[], struct queryopt *opt)
+{
+ int iarg;
+ while ((iarg = getopt_long(argc, argv, "l:s:r:k:y:f:u:m:", long_options, NULL)) != -1)
+ {
+ // check to see if a single character or long option came through
+ switch (iarg)
+ {
+ // short option 's'
+ case 's':
+ opt->bsever = 1;
+ opt->e_sever = atoi(optarg);
+ break;
+ // short option 'r'
+ case 'r':
+ opt->bret = 1;
+ opt->e_ret = atoi(optarg);
+ break;
+ // short option 'f' : date from
+ case 'f':
+ opt->bdate = 1;
+ opt->bdatef = 1;
+ opt->e_date = optarg;
+ break;
+ // short option 'u': date until
+ case 'u':
+ opt->bdate = 1;
+ opt->bdateu = 1;
+ opt->e_dateu = optarg;
+ break;
+ // short option 'k'
+ case 'k':
+ opt->bskip = 1;
+ opt->e_skip = atoi(optarg);
+ break;
+ // short option 'l'
+ case 'l':
+ opt->blevel = 1;
+ opt->e_level = optarg;
+ break;
+ // short option 'm'
+ case 'm':
+ opt->bmsg = 1;
+ opt->e_msg = optarg;
+ break;
+ // short option 'y'
+ case 'y':
+ opt->bsys = 1;
+ opt->e_sys = optarg;
+ break;
+ } // end switch iarg
+ } // end while
+
+} // end void getoptions
+
+struct select_doc* create_select()
+// BSON object indicating the fields to return
+{
+ struct select_doc *s_doc;
+ s_doc = malloc(sizeof(struct select_doc));
+ s_doc->select = bson_new ();
+ bson_append_string (s_doc->select, "syslog_tag", "s", -1);
+ bson_append_string (s_doc->select, "msg", "ERROR", -1);
+ bson_append_string (s_doc->select, "sys", "sys", -1);
+ bson_append_utc_datetime (s_doc->select, "time_rcvd", 1ll);
+ bson_finish (s_doc->select);
+ return s_doc;
+}
+
+struct query_doc* create_query(struct queryopt *opt)
+{
+ struct query_doc *qu_doc;
+ bson *query_what, *order_what, *order_how, *msg_what, *date_what;
+ struct tm tm;
+ time_t t;
+ gint64 ts;
+ qu_doc = malloc(sizeof(struct query_doc));
+ qu_doc->query = bson_new ();
+
+ query_what = bson_new ();
+ if (opt->bsever == 1)
+ {
+ bson_append_int32 (query_what, "syslog_sever", opt->e_sever);
+ }
+ if (opt->blevel == 1)
+ {
+ bson_append_string (query_what, "level", opt->e_level, -1);
+ }
+
+ if (opt->bmsg == 1)
+ {
+ msg_what = bson_new ();
+ bson_append_string (msg_what, "$regex", opt->e_msg, -1);
+ bson_append_string (msg_what, "$options", "i", -1);
+ bson_finish (msg_what);
+ bson_append_document (query_what, "msg", msg_what);
+ }
+
+ if (opt->bdate == 1)
+ {
+ date_what = bson_new ();
+ if (opt->bdatef == 1)
+ {
+ tm.tm_isdst = -1;
+ strptime(opt->e_date, "%d/%m/%Y-%H:%M:%S", &tm);
+ tm.tm_hour = tm.tm_hour + 1;
+ t = mktime(&tm);
+ ts = 1000 * (gint64) t;
+
+ bson_append_utc_datetime (date_what,"$gt", ts) ;
+ }
+
+ if (opt->bdateu == 1)
+ {
+ tm.tm_isdst = -1;
+ strptime(opt->e_dateu, "%d/%m/%Y-%H:%M:%S", &tm);
+ tm.tm_hour = tm.tm_hour +1;
+ t = mktime(&tm);
+ ts = 1000 * (gint64) t;
+ bson_append_utc_datetime (date_what,"$lt", ts);
+
+ }
+ bson_finish (date_what);
+ bson_append_document (query_what, "time_rcvd", date_what);
+ }
+
+ if (opt->bsys == 1)
+ {
+ bson_append_string (query_what, "sys", opt->e_sys, -1);
+ }
+
+ bson_finish (query_what);
+
+ order_what = bson_new ();
+ bson_append_utc_datetime (order_what, "time_rcvd", 1ll);
+ bson_finish (order_what);
+
+ bson_append_document (qu_doc->query, "$query", query_what);
+ bson_append_document (qu_doc->query, "$orderby", order_what);
+ bson_finish (qu_doc->query);
+ bson_free (order_what);
+ return qu_doc;
+}
+
+struct db_connect* create_conn()
+{
+ struct db_connect *db_conn;
+ db_conn = malloc(sizeof(struct db_connect));
+ db_conn->conn = mongo_sync_connect ("localhost", 27017, TRUE);
+
+ if (!db_conn->conn)
+ {
+ perror ("mongo_sync_connect()");
+ exit (1);
+ }
+ return db_conn;
+}
+
+void close_conn(struct db_connect *db_conn)
+{
+ mongo_sync_disconnect (db_conn->conn);
+}
+
+void free_cursor(struct db_cursor *db_c)
+{
+ mongo_sync_cursor_free (db_c->cursor);
+}
+
+struct output* launch_query(struct queryopt *opt, struct select_doc *s_doc,
+ struct query_doc *qu_doc,
+ struct db_connect *db_conn)
+{
+ struct output *out;
+ out = malloc(sizeof(struct output));
+ out->p = mongo_sync_cmd_query (db_conn->conn, "syslog.log", 0,
+ opt->e_skip, opt->e_ret, qu_doc->query, s_doc->select);
+ if (!out->p)
+ {
+ perror ("mongo_sync_cmd_query()");
+ printf("no records found\n");
+ exit (1);
+ }
+ return out;
+}
+
+struct db_cursor* open_cursor(struct db_connect *db_conn, struct output *out)
+{
+ struct db_cursor *db_c;
+ db_c = malloc(sizeof(struct db_cursor));
+
+ db_c->cursor = mongo_sync_cursor_new (db_conn->conn, "syslog.log", out->p);
+ if (!db_c->cursor)
+ {
+ perror ("mongo_sync_cursor_new()");
+ exit (1);
+ }
+ return db_c;
+}
+
+struct results* read_data(struct db_cursor *db_c)
+{
+ struct results *res;
+ res = malloc(sizeof(struct results));
+ res->result = mongo_sync_cursor_get_data (db_c->cursor);
+ if (!res->result)
+ {
+ perror ("mongo_sync_cursor_get_data()");
+ exit (1);
+ }
+ return res;
+}
+
+gboolean cursor_next (struct db_cursor *db_c)
+{
+ if (!mongo_sync_cursor_next (db_c->cursor))
+ return FALSE;
+ else
+ return TRUE;
+
+}
+
+int main (int argc, char *argv[])
+{
+
+ struct queryopt opt;
+ struct ofields *fields;
+ struct bson_doc *doc;
+ struct select_doc *s_doc;
+ struct query_doc *qu_doc;
+ struct db_connect *db_conn;
+ struct output *out;
+ struct db_cursor *db_c;
+ struct results *res;
+
+ opt.e_skip = 0; // standard
+ opt.e_ret = 0; // standard
+ opt.bsever = 0;
+ opt.blevel = 0;
+ opt.bdate = 0;
+ opt.bdateu = 0;
+ opt.bdatef = 0;
+ opt.bmsg = 0;
+ opt.bskip = 0;
+ opt.bsys = 0;
+
+ getoptions(argc, argv, &opt);
+ qu_doc = create_query(&opt); // crate query
+ s_doc = create_select();
+ db_conn = create_conn(); // create connection
+ out = launch_query(&opt, s_doc, qu_doc, db_conn); // launch the query
+ db_c = open_cursor(db_conn, out); // open cursor
+
+ while (cursor_next(db_c))
+ {
+ res = read_data(db_c);
+ fields = get_data(res);
+ formater(fields); // formate output
+ free(fields);
+ }
+
+ free_cursor(db_c);
+ close_conn(db_conn);
+
+ return (0);
+}
diff --git a/tools/omfile.c b/tools/omfile.c
index 90b452bf..715b218c 100644
--- a/tools/omfile.c
+++ b/tools/omfile.c
@@ -121,7 +121,7 @@ struct s_dynaFileCacheEntry {
typedef struct s_dynaFileCacheEntry dynaFileCacheEntry;
-#define IOBUF_DFLT_SIZE 1024 /* default size for io buffers */
+#define IOBUF_DFLT_SIZE 4096 /* default size for io buffers */
#define FLUSH_INTRVL_DFLT 1 /* default buffer flush interval (in seconds) */
#define USE_ASYNCWRITER_DFLT 0 /* default buffer use async writer */
#define FLUSHONTX_DFLT 1 /* default for flush on TX end */
@@ -180,7 +180,25 @@ typedef struct configSettings_s {
static configSettings_t cs;
uchar *pszFileDfltTplName; /* name of the default template to use */
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ uchar *tplName; /* default template */
+};
+
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current exec process */
+
/* tables for interfacing with the v6 config system */
+/* module-global parameters */
+static struct cnfparamdescr modpdescr[] = {
+ { "template", eCmdHdlrGetWord, 0 },
+};
+static struct cnfparamblk modpblk =
+ { CNFPARAMBLK_VERSION,
+ sizeof(modpdescr)/sizeof(struct cnfparamdescr),
+ modpdescr
+ };
+
/* action (instance) parameters */
static struct cnfparamdescr actpdescr[] = {
{ "dynafilecachesize", eCmdHdlrInt, 0 }, /* legacy: dynafilecachesize */
@@ -201,7 +219,6 @@ static struct cnfparamdescr actpdescr[] = {
{ "file", eCmdHdlrString, 0 }, /* either "file" or ... */
{ "dynafile", eCmdHdlrString, 0 }, /* "dynafile" MUST be present */
{ "template", eCmdHdlrGetWord, 0 },
- //{ "", eCmdHdlrGetWord, 0 }, /* legacy: */
};
static struct cnfparamblk actpblk =
{ CNFPARAMBLK_VERSION,
@@ -210,6 +227,21 @@ static struct cnfparamblk actpblk =
};
+/* this function gets the default template. It coordinates action between
+ * old-style and new-style configuration parts.
+ */
+static inline uchar*
+getDfltTpl(void)
+{
+ if(loadModConf != NULL && loadModConf->tplName != NULL)
+ return loadModConf->tplName;
+ else if(pszFileDfltTplName == NULL)
+ return (uchar*)"RSYSLOG_FileFormat";
+ else
+ return pszFileDfltTplName;
+}
+
+
BEGINinitConfVars /* (re)set config variables to default values */
CODESTARTinitConfVars
pszFileDfltTplName = NULL; /* make sure this can be free'ed! */
@@ -246,6 +278,31 @@ CODESTARTdbgPrintInstInfo
ENDdbgPrintInstInfo
+
+/* set the default template to be used
+ * This is a module-global parameter, and as such needs special handling. It needs to
+ * be coordinated with values set via the v2 config system (rsyslog v6+). What we do
+ * is we do not permit this directive after the v2 config system has been used to set
+ * the parameter.
+ */
+rsRetVal
+setLegacyDfltTpl(void __attribute__((unused)) *pVal, uchar* newVal)
+{
+ DEFiRet;
+
+ if(loadModConf != NULL && loadModConf->tplName != NULL) {
+ free(newVal);
+ errmsg.LogError(0, RS_RET_ERR, "omfile default template already set via module "
+ "global parameter - can no longer be changed");
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ free(pszFileDfltTplName);
+ pszFileDfltTplName = newVal;
+finalize_it:
+ RETiRet;
+}
+
+
/* set the dynaFile cache size. Does some limit checking.
* rgerhards, 2007-07-31
*/
@@ -333,8 +390,7 @@ static rsRetVal cflineParseOutchannel(instanceData *pData, uchar* p, omodStringR
*/
pData->pszSizeLimitCmd = pOch->cmdOnSizeLimit;
- iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts,
- (pszFileDfltTplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : pszFileDfltTplName);
+ iRet = cflineParseTemplateName(&p, pOMSR, iEntry, iTplOpts, getDfltTpl());
finalize_it:
RETiRet;
@@ -647,7 +703,7 @@ doWrite(instanceData *pData, uchar *pszBuf, int lenBuf)
ASSERT(pData != NULL);
ASSERT(pszBuf != NULL);
-dbgprintf("write to stream, pData->pStrm %p, lenBuf %d\n", pData->pStrm, lenBuf);
+ DBGPRINTF("write to stream, pData->pStrm %p, lenBuf %d\n", pData->pStrm, lenBuf);
if(pData->pStrm != NULL){
CHKiRet(strm.Write(pData->pStrm, pszBuf, lenBuf));
FINALIZE;
@@ -690,6 +746,72 @@ finalize_it:
}
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ pModConf->tplName = NULL;
+ENDbeginCnfLoad
+
+BEGINsetModCnf
+ struct cnfparamvals *pvals = NULL;
+ int i;
+CODESTARTsetModCnf
+ pvals = nvlstGetParams(lst, &modpblk, NULL);
+ if(pvals == NULL) {
+ errmsg.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 omfile:\n");
+ cnfparamsPrint(&modpblk, pvals);
+ }
+
+ for(i = 0 ; i < modpblk.nParams ; ++i) {
+ if(!pvals[i].bUsed)
+ continue;
+ if(!strcmp(modpblk.descr[i].name, "template")) {
+ loadModConf->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ if(pszFileDfltTplName != NULL) {
+ errmsg.LogError(0, RS_RET_DUP_PARAM, "omfile: warning: default template "
+ "was already set via legacy directive - may lead to inconsistent "
+ "results.");
+ }
+ } else {
+ dbgprintf("omfile: program error, non-handled "
+ "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
+ }
+ }
+finalize_it:
+ if(pvals != NULL)
+ cnfparamvalsDestruct(pvals, &modpblk);
+ENDsetModCnf
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ loadModConf = NULL; /* done loading */
+ /* free legacy config vars */
+ free(pszFileDfltTplName);
+ pszFileDfltTplName = NULL;
+ENDendCnfLoad
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ runModConf = pModConf;
+ENDactivateCnf
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ free(pModConf->tplName);
+ENDfreeCnf
+
+
BEGINcreateInstance
CODESTARTcreateInstance
pData->pStrm = NULL;
@@ -698,6 +820,7 @@ ENDcreateInstance
BEGINfreeInstance
CODESTARTfreeInstance
+ free(pData->tplName);
free(pData->f_fname);
if(pData->bDynamicName) {
dynaFileFreeCache(pData);
@@ -837,9 +960,7 @@ CODESTARTnewActInst
ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
}
- CHKiRet(OMSRsetEntry(*ppOMSR, 0, ustrdup((pData->tplName == NULL) ?
- (uchar*)"RSYSLOG_FileFormat" : pData->tplName),
- OMSR_NO_RQD_TPL_OPTS));
+ CHKiRet(OMSRsetEntry(*ppOMSR, 0, ustrdup(getDfltTpl()), OMSR_NO_RQD_TPL_OPTS));
if(pData->bDynamicName) {
/* "filename" is actually a template name, we need this as string 1. So let's add it
@@ -902,8 +1023,7 @@ CODESTARTparseSelectorAct
*/
CODE_STD_STRING_REQUESTparseSelectorAct(2)
++p; /* eat '?' */
- CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
- (pszFileDfltTplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : pszFileDfltTplName));
+ CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl()));
pData->f_fname = ustrdup(fname);
pData->bDynamicName = 1;
pData->iCurrElt = -1; /* no current element */
@@ -919,8 +1039,7 @@ CODESTARTparseSelectorAct
case '/':
case '.':
CODE_STD_STRING_REQUESTparseSelectorAct(1)
- CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
- (pszFileDfltTplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : pszFileDfltTplName));
+ CHKiRet(cflineParseFileName(p, fname, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl()));
pData->f_fname = ustrdup(fname);
pData->bDynamicName = 0;
break;
@@ -991,7 +1110,6 @@ BEGINmodExit
CODESTARTmodExit
objRelease(errmsg, CORE_COMPONENT);
objRelease(strm, CORE_COMPONENT);
- free(pszFileDfltTplName);
DESTROY_ATOMIC_HELPER_MUT(mutClock);
ENDmodExit
@@ -999,6 +1117,8 @@ ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_OMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES
CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES
CODEqueryEtryPt_TXIF_OMOD_QUERIES /* we support the transactional interface! */
CODEqueryEtryPt_doHUP
@@ -1033,7 +1153,7 @@ INITLegCnfVars
CHKiRet(omsdRegCFSLineHdlr((uchar *)"failonchownfailure", 0, eCmdHdlrBinary, NULL, &cs.bFailOnChown, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileforcechown", 0, eCmdHdlrGoneAway, NULL, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfileenablesync", 0, eCmdHdlrBinary, NULL, &cs.bEnableSync, STD_LOADABLE_MODULE_ID));
- CHKiRet(regCfSysLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszFileDfltTplName, NULL));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, setLegacyDfltTpl, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
/* vi:set ai:
diff --git a/tools/omfwd.c b/tools/omfwd.c
index b4a28c34..2fd24bdf 100644
--- a/tools/omfwd.c
+++ b/tools/omfwd.c
@@ -115,6 +115,16 @@ typedef struct configSettings_s {
static configSettings_t cs;
/* tables for interfacing with the v6 config system */
+/* module-global parameters */
+static struct cnfparamdescr modpdescr[] = {
+ { "template", eCmdHdlrGetWord, 0 },
+};
+static struct cnfparamblk modpblk =
+ { CNFPARAMBLK_VERSION,
+ sizeof(modpdescr)/sizeof(struct cnfparamdescr),
+ modpdescr
+ };
+
/* action (instance) parameters */
static struct cnfparamdescr actpdescr[] = {
{ "target", eCmdHdlrGetWord, 0 },
@@ -135,6 +145,14 @@ static struct cnfparamblk actpblk =
actpdescr
};
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ uchar *tplName; /* default template */
+};
+
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current exec process */
+
BEGINinitConfVars /* (re)set config variables to default values */
CODESTARTinitConfVars
@@ -151,6 +169,44 @@ ENDinitConfVars
static rsRetVal doTryResume(instanceData *pData);
+/* this function gets the default template. It coordinates action between
+ * old-style and new-style configuration parts.
+ */
+static inline uchar*
+getDfltTpl(void)
+{
+ if(loadModConf != NULL && loadModConf->tplName != NULL)
+ return loadModConf->tplName;
+ else if(cs.pszTplName == NULL)
+ return (uchar*)"RSYSLOG_TraditionalForwardFormat";
+ else
+ return cs.pszTplName;
+}
+
+
+/* set the default template to be used
+ * This is a module-global parameter, and as such needs special handling. It needs to
+ * be coordinated with values set via the v2 config system (rsyslog v6+). What we do
+ * is we do not permit this directive after the v2 config system has been used to set
+ * the parameter.
+ */
+static rsRetVal
+setLegacyDfltTpl(void __attribute__((unused)) *pVal, uchar* newVal)
+{
+ DEFiRet;
+
+ if(loadModConf != NULL && loadModConf->tplName != NULL) {
+ free(newVal);
+ errmsg.LogError(0, RS_RET_ERR, "omfwd default template already set via module "
+ "global parameter - can no longer be changed");
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+ free(cs.pszTplName);
+ cs.pszTplName = newVal;
+finalize_it:
+ RETiRet;
+}
+
/* Close the UDP sockets.
* rgerhards, 2009-05-29
*/
@@ -189,6 +245,72 @@ DestructTCPInstanceData(instanceData *pData)
netstrms.Destruct(&pData->pNS);
}
+
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ pModConf->tplName = NULL;
+ENDbeginCnfLoad
+
+BEGINsetModCnf
+ struct cnfparamvals *pvals = NULL;
+ int i;
+CODESTARTsetModCnf
+ pvals = nvlstGetParams(lst, &modpblk, NULL);
+ if(pvals == NULL) {
+ errmsg.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 omfwd:\n");
+ cnfparamsPrint(&modpblk, pvals);
+ }
+
+ for(i = 0 ; i < modpblk.nParams ; ++i) {
+ if(!pvals[i].bUsed)
+ continue;
+ if(!strcmp(modpblk.descr[i].name, "template")) {
+ loadModConf->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ if(cs.pszTplName != NULL) {
+ errmsg.LogError(0, RS_RET_DUP_PARAM, "omfwd: warning: default template "
+ "was already set via legacy directive - may lead to inconsistent "
+ "results.");
+ }
+ } else {
+ dbgprintf("omfwd: program error, non-handled "
+ "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
+ }
+ }
+finalize_it:
+ if(pvals != NULL)
+ cnfparamvalsDestruct(pvals, &modpblk);
+ENDsetModCnf
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ loadModConf = NULL; /* done loading */
+ /* free legacy config vars */
+ free(cs.pszTplName);
+ cs.pszTplName = NULL;
+ENDendCnfLoad
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ runModConf = pModConf;
+ENDactivateCnf
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ free(pModConf->tplName);
+ENDfreeCnf
+
BEGINcreateInstance
CODESTARTcreateInstance
pData->offsSndBuf = 0;
@@ -759,9 +881,7 @@ CODESTARTnewActInst
}
CODE_STD_STRING_REQUESTnewActInst(1)
- CHKiRet(OMSRsetEntry(*ppOMSR, 0, ustrdup((pData->tplName == NULL) ?
- (uchar*)"RSYSLOG_TraditionalForwardFormat" : (uchar*)pData->tplName),
- OMSR_NO_RQD_TPL_OPTS));
+ CHKiRet(OMSRsetEntry(*ppOMSR, 0, ustrdup(getDfltTpl()), OMSR_NO_RQD_TPL_OPTS));
CHKiRet(initTCP(pData));
CODE_STD_FINALIZERnewActInst
@@ -917,8 +1037,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
cs.iTCPRebindInterval : cs.iUDPRebindInterval;
/* process template */
- CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
- (cs.pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : cs.pszTplName));
+ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, getDfltTpl()));
if(pData->protocol == FORW_TCP) {
pData->bResendLastOnRecon = cs.bResendLastOnRecon;
@@ -944,8 +1063,6 @@ ENDparseSelectorAct
static void
freeConfigVars(void)
{
- free(cs.pszTplName);
- cs.pszTplName = NULL;
free(cs.pszStrmDrvr);
cs.pszStrmDrvr = NULL;
free(cs.pszStrmDrvrAuthMode);
@@ -971,6 +1088,8 @@ ENDmodExit
BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_OMOD_QUERIES
+CODEqueryEtryPt_STD_CONF2_QUERIES
+CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES
CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES
CODEqueryEtryPt_TXIF_OMOD_QUERIES /* we support the transactional interface! */
ENDqueryEtryPt
@@ -1002,7 +1121,7 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(net,LM_NET_FILENAME));
- CHKiRet(regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &cs.pszTplName, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, setLegacyDfltTpl, NULL, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionsendtcprebindinterval", 0, eCmdHdlrInt, NULL, &cs.iTCPRebindInterval, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionsendudprebindinterval", 0, eCmdHdlrInt, NULL, &cs.iUDPRebindInterval, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionsendstreamdriver", 0, eCmdHdlrGetWord, NULL, &cs.pszStrmDrvr, NULL));
diff --git a/tools/ompipe.c b/tools/ompipe.c
index 30cb9bfc..d293114f 100644
--- a/tools/ompipe.c
+++ b/tools/ompipe.c
@@ -65,10 +65,6 @@ DEF_OMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
-/* globals for default values */
-/* end globals for default values */
-
-
typedef struct _instanceData {
uchar *pipe; /* pipe or template name (display only) */
uchar *tplName; /* format template to use */
@@ -82,6 +78,16 @@ typedef struct configSettings_s {
static configSettings_t __attribute__((unused)) cs;
/* tables for interfacing with the v6 config system */
+/* module-global parameters */
+static struct cnfparamdescr modpdescr[] = {
+ { "template", eCmdHdlrGetWord, 0 },
+};
+static struct cnfparamblk modpblk =
+ { CNFPARAMBLK_VERSION,
+ sizeof(modpdescr)/sizeof(struct cnfparamdescr),
+ modpdescr
+ };
+
/* action (instance) parameters */
static struct cnfparamdescr actpdescr[] = {
{ "pipe", eCmdHdlrString, CNFPARAM_REQUIRED },
@@ -93,6 +99,25 @@ static struct cnfparamblk actpblk =
actpdescr
};
+struct modConfData_s {
+ rsconf_t *pConf; /* our overall config object */
+ uchar *tplName; /* default template */
+};
+
+static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
+static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current exec process */
+
+/* this function gets the default template */
+static inline uchar*
+getDfltTpl(void)
+{
+ if(loadModConf != NULL && loadModConf->tplName != NULL)
+ return loadModConf->tplName;
+ else
+ return (uchar*)"RSYSLOG_FileFormat";
+}
+
+
BEGINinitConfVars /* (re)set config variables to default values */
CODESTARTinitConfVars
ENDinitConfVars
@@ -181,6 +206,71 @@ finalize_it:
}
+BEGINbeginCnfLoad
+CODESTARTbeginCnfLoad
+ loadModConf = pModConf;
+ pModConf->pConf = pConf;
+ pModConf->tplName = NULL;
+ENDbeginCnfLoad
+
+BEGINsetModCnf
+ struct cnfparamvals *pvals = NULL;
+ int i;
+CODESTARTsetModCnf
+ pvals = nvlstGetParams(lst, &modpblk, NULL);
+ if(pvals == NULL) {
+ errmsg.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 ompipe:\n");
+ cnfparamsPrint(&modpblk, pvals);
+ }
+
+ for(i = 0 ; i < modpblk.nParams ; ++i) {
+ if(!pvals[i].bUsed)
+ continue;
+ if(!strcmp(modpblk.descr[i].name, "template")) {
+ loadModConf->tplName = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
+ if(pszFileDfltTplName != NULL) {
+ errmsg.LogError(0, RS_RET_DUP_PARAM, "ompipe: warning: default template "
+ "was already set via legacy directive - may lead to inconsistent "
+ "results.");
+ }
+ } else {
+ dbgprintf("ompipe: program error, non-handled "
+ "param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
+ }
+ }
+finalize_it:
+ if(pvals != NULL)
+ cnfparamvalsDestruct(pvals, &modpblk);
+ENDsetModCnf
+
+BEGINendCnfLoad
+CODESTARTendCnfLoad
+ loadModConf = NULL; /* done loading */
+ /* free legacy config vars */
+ free(pszFileDfltTplName);
+ pszFileDfltTplName = NULL;
+ENDendCnfLoad
+
+BEGINcheckCnf
+CODESTARTcheckCnf
+ENDcheckCnf
+
+BEGINactivateCnf
+CODESTARTactivateCnf
+ runModConf = pModConf;
+ENDactivateCnf
+
+BEGINfreeCnf
+CODESTARTfreeCnf
+ free(pModConf->tplName);
+ENDfreeCnf
+
BEGINcreateInstance
CODESTARTcreateInstance
pData->pipe = NULL;
@@ -273,7 +363,7 @@ CODESTARTparseSelectorAct
CHKmalloc(pData->pipe = malloc(512));
++p;
CHKiRet(cflineParseFileName(p, (uchar*) pData->pipe, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
- (pszFileDfltTplName == NULL) ? (uchar*)"RSYSLOG_FileFormat" : pszFileDfltTplName));
+ getDfltTpl()));
CODE_STD_FINALIZERparseSelectorAct
ENDparseSelectorAct
@@ -297,7 +387,9 @@ BEGINqueryEtryPt
CODESTARTqueryEtryPt
CODEqueryEtryPt_STD_OMOD_QUERIES
CODEqueryEtryPt_doHUP
+CODEqueryEtryPt_STD_CONF2_QUERIES
CODEqueryEtryPt_STD_CONF2_CNFNAME_QUERIES
+CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES
CODEqueryEtryPt_STD_CONF2_OMOD_QUERIES
ENDqueryEtryPt
diff --git a/tools/pidfile.c b/tools/pidfile.c
index e7744513..e9601232 100644
--- a/tools/pidfile.c
+++ b/tools/pidfile.c
@@ -125,7 +125,7 @@ int write_pid (char *pidfile)
char errStr[1024];
rs_strerror_r(errno, errStr, sizeof(errStr));
printf("Can't write pid , %s.\n", errStr);
- close(fd);
+ fclose(f);
return 0;
}
fflush(f);
@@ -135,11 +135,11 @@ int write_pid (char *pidfile)
char errStr[1024];
rs_strerror_r(errno, errStr, sizeof(errStr));
printf("Can't unlock pidfile %s, %s.\n", pidfile, errStr);
- close(fd);
+ fclose(f);
return 0;
}
#endif
- close(fd);
+ fclose(f);
return pid;
}
diff --git a/tools/pmrfc3164.c b/tools/pmrfc3164.c
index 2657780d..bcded428 100644
--- a/tools/pmrfc3164.c
+++ b/tools/pmrfc3164.c
@@ -79,7 +79,7 @@ BEGINparse
uchar bufParseTAG[CONF_TAG_MAXSIZE];
uchar bufParseHOSTNAME[CONF_HOSTNAME_MAXSIZE];
CODESTARTparse
- dbgprintf("Message will now be parsed by the legacy syslog parser (one size fits all... ;)).\n");
+ DBGPRINTF("Message will now be parsed by the legacy syslog parser (one size fits all... ;)).\n");
assert(pMsg != NULL);
assert(pMsg->pszRawMsg != NULL);
lenMsg = pMsg->iLenRawMsg - pMsg->offAfterPRI; /* note: offAfterPRI is already the number of PRI chars (do not add one!) */
@@ -229,7 +229,7 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(parser, CORE_COMPONENT));
CHKiRet(objUse(datetime, CORE_COMPONENT));
- dbgprintf("rfc3164 parser init called\n");
+ DBGPRINTF("rfc3164 parser init called\n");
bParseHOSTNAMEandTAG = glbl.GetParseHOSTNAMEandTAG(); /* cache value, is set only during rsyslogd option processing */
diff --git a/tools/syslogd.c b/tools/syslogd.c
index b158feb3..3bd0f018 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -125,6 +125,7 @@
#include "rsconf.h"
#include "dnscache.h"
#include "sd-daemon.h"
+#include "rainerscript.h"
/* definitions for objects we access */
DEFobjCurrIf(obj)
@@ -447,7 +448,6 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags)
MsgSetRawMsgWOSize(pMsg, (char*)msg);
MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp());
-dbgprintf("ZZZZ: pLocalHostIPIF used!\n");
MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP());
MsgSetMSGoffs(pMsg, 0);
/* check if we have an error code associated and, if so,
@@ -801,26 +801,6 @@ static void doDie(int sig)
}
-/* This function frees all dynamically allocated memory for program termination.
- * It must be called only immediately before exit(). It is primarily an aid
- * for memory debuggers, which prevents cluttered outupt.
- * rgerhards, 2008-03-20
- */
-static void
-freeAllDynMemForTermination(void)
-{
- free(ourConf->globals.pszConfDAGFile);
- struct queuefilenames_s *qfn, *qfnDel;
-
- for(qfn = queuefilenames ; qfn != NULL ; ) {
- qfnDel = qfn;
- qfn = qfn->next;
- free(qfnDel->name);
- free(qfnDel);
- }
-}
-
-
/* Finalize and destruct all actions.
*/
static inline void
@@ -890,14 +870,16 @@ die(int sig)
destructAllActions();
DBGPRINTF("all primary multi-thread sources have been terminated - now doing aux cleanup...\n");
+
+ DBGPRINTF("destructing current config...\n");
+ rsconf.Destruct(&runConf);
+
/* rger 2005-02-22
* now clean up the in-memory structures. OK, the OS
* would also take care of that, but if we do it
* ourselfs, this makes finding memory leaks a lot
* easier.
*/
- tplDeleteAll(runConf);
-
/* de-init some modules */
modExitIminternal();
@@ -921,15 +903,8 @@ die(int sig)
/* dbgClassExit MUST be the last one, because it de-inits the debug system */
dbgClassExit();
- /* free all remaining memory blocks - this is not absolutely necessary, but helps
- * us keep memory debugger logs clean and this is in aid in developing. It doesn't
- * cost much time, so we do it always. -- rgerhards, 2008-03-20
- */
- freeAllDynMemForTermination();
- /* NO CODE HERE - feeelAllDynMemForTermination() must be the last thing before exit()! */
-
+ /* NO CODE HERE - dbgClassExit() must be the last thing before exit()! */
remove_pid(PidFile);
-
exit(0); /* "good" exit, this is the terminator function for rsyslog [die()] */
}
@@ -1495,6 +1470,7 @@ InitGlobalClasses(void)
pErrObj = "net";
CHKiRet(objUse(net, LM_NET_FILENAME));
dnscacheInit();
+ initRainerscript();
finalize_it:
if(iRet != RS_RET_OK) {