summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog28
-rw-r--r--configure.ac18
-rw-r--r--dirty.h1
-rw-r--r--doc/expression.html21
-rw-r--r--doc/imuxsock.html28
-rw-r--r--doc/manual.html2
-rw-r--r--doc/omoracle.html11
-rw-r--r--doc/rainerscript.html18
-rw-r--r--doc/rsconf1_omfileforcechown.html64
-rw-r--r--doc/rsyslog_conf_global.html6
-rw-r--r--gss-misc.c25
-rw-r--r--plugins/imgssapi/imgssapi.c16
-rw-r--r--plugins/imudp/imudp.c20
-rw-r--r--plugins/imuxsock/imuxsock.c34
-rw-r--r--plugins/omoracle/omoracle.c64
-rw-r--r--runtime/Makefile.am1
-rw-r--r--runtime/debug.c4
-rw-r--r--runtime/debug.h5
-rw-r--r--runtime/glbl.c12
-rw-r--r--runtime/glbl.h11
-rw-r--r--runtime/nsdsel_ptcp.c51
-rw-r--r--runtime/nsdsel_ptcp.h5
-rw-r--r--runtime/unlimited_select.h45
-rw-r--r--runtime/vm.c44
-rw-r--r--tests/Makefile.am3
-rwxr-xr-xtests/diag.sh2
-rwxr-xr-xtests/rsf_getenv.sh17
-rw-r--r--tests/testsuites/rsf_getenv.conf17
-rw-r--r--tools/omfile.c27
-rw-r--r--tools/syslogd.c55
30 files changed, 569 insertions, 86 deletions
diff --git a/ChangeLog b/ChangeLog
index 35f92a29..1f6a883c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,32 @@
---------------------------------------------------------------------------
+Version 4.7.0 [v4-devel] (rgerhards), 2009-09-??
+- added function getenv() to RainerScript
+- added new config option $InputUnixListenSocketCreatePath
+ to permit the auto-creation of pathes to additional log sockets. This
+ turns out to be useful if they reside on temporary file systems and
+ rsyslogd starts up before the daemons that create these sockets
+ (rsyslogd always creates the socket itself if it does not exist).
+- added $LogRSyslogStatusMessages configuration directive
+ permitting to turn off rsyslog start/stop/HUP messages. See Debian
+ ticket http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=463793
+- added new config directive $omfileForceChown to (try to) fix some broken
+ system configs.
+ See ticket for details: http://bugzilla.adiscon.com/show_bug.cgi?id=150
+- added $EscapeControlCharacterTab config directive
+ Thanks to Jonathan Bond-Caron for the patch.
+- added option to use unlimited-size select() calls
+ Thanks to varmjofekoj for the patch
+- debugondemand mode caused backgrounding to fail - close to a bug, but I'd
+ consider the ability to background in this mode a new feature...
+- bugfix (kind of): check if TCP connection is still alive if using TLS
+ Thanks to Jonathan Bond-Caron for the patch.
+- imported changes from 4.5.7 and below
+- bugfix: potential segfault when -p command line option was used
+ Thanks for varmojfekoj for pointing me at this bug.
+- bugfix: potential segfaults during queue shutdown
+ (bugs require certain non-standard settings to appear)
+ Thanks to varmojfekoj for the patch [imported from 4.5.8]
+---------------------------------------------------------------------------
Version 4.5.8 [v4-beta] (rgerhards), 2010-01-??
- bugfix: -d did not enable display of debug messages
regression from introduction of "debug on demand" mode
diff --git a/configure.ac b/configure.ac
index 9a637d4d..8c6fc6b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT([rsyslog],[4.5.7],[rsyslog@lists.adiscon.com])
+AC_INIT([rsyslog],[4.7.0],[rsyslog@lists.adiscon.com])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([ChangeLog])
AC_CONFIG_MACRO_DIR([m4])
@@ -342,6 +342,21 @@ AC_ARG_ENABLE([fsstnd],
])
+# support for unlimited select() syscall
+AC_ARG_ENABLE(unlimited_select,
+ [AS_HELP_STRING([--enable-unlimited-select],[Enable unlimited select() syscall @<:@default=no@:>@])],
+ [case "${enableval}" in
+ yes) enable_unlimited_select="yes" ;;
+ no) enable_unlimited_select="no" ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-unlimited-select) ;;
+ esac],
+ [enable_unlimited_select="no"]
+)
+if test "$enable_unlimited_select" = "yes"; then
+ AC_DEFINE(USE_UNLIMITED_SELECT, 1, [If defined, the select() syscall won't be limited to a particular number of file descriptors.])
+fi
+
+
# debug
AC_ARG_ENABLE(debug,
[AS_HELP_STRING([--enable-debug],[Enable debug mode @<:@default=no@:>@])],
@@ -844,6 +859,7 @@ echo " Zlib compression support enabled: $enable_zlib"
echo " rsyslog runtime will be built: $enable_rsyslogrt"
echo " rsyslogd will be built: $enable_rsyslogd"
echo " custom module 1 will be built: $enable_cust1"
+echo " Unlimited select() support enabled: $enable_unlimited_select"
echo
echo "---{ input plugins }---"
echo " Klog functionality enabled: $enable_klog ($os_type)"
diff --git a/dirty.h b/dirty.h
index 0153cb69..f1904574 100644
--- a/dirty.h
+++ b/dirty.h
@@ -54,6 +54,7 @@ extern int bReduceRepeatMsgs;
extern int bDropTrailingLF;
extern uchar cCCEscapeChar;
extern int bEscapeCCOnRcv;
+extern int bEscapeTab;
#ifdef USE_NETZIP
/* config param: minimum message size to try compression. The smaller
* the message, the less likely is any compression gain. We check for
diff --git a/doc/expression.html b/doc/expression.html
index 9e37cb7a..c401d9ab 100644
--- a/doc/expression.html
+++ b/doc/expression.html
@@ -1,17 +1,22 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
-<meta http-equiv="Content-Language" content="en"><title>Expressions</title></head>
+<meta http-equiv="Content-Language" content="en">
+<title>Expressions in rsyslog</title></head>
<body>
-<a href="rsyslog_conf_filter.html">back</a>
-<h1>Expressions</h1>
+<a href="rsyslog_conf_filter.html">back to rsyslog filter conditions</a>
+<h1>Expressions in rsyslog</h1>
<p>Rsyslog supports expressions at a growing number of places. So
-far, they are supported for filtering messages.</p><p>Expression support is provided by RainerScript. For now, please see the formal expression definition in <a href="rainerscript.html">RainerScript ABNF</a>. It is the "expr" node.</p><p>C-like comments (/* some comment */) are supported <span style="font-weight: bold;">inside</span> the expression, but not yet in the rest of the configuration file.</p><p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
+far, they are supported for filtering messages.</p>
+<p>Expression support is provided by RainerScript. Please see the
+<a href="rainerscript.html">RainerScript documentation</a> for more details.</p>
+<p>C-like comments (/* some comment */) are supported <b>inside</b> the expression,
+but not yet in the rest of the configuration file.</p>
+
+<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
[<a href="manual.html">manual index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
<p><font size="2">This documentation is part of the
-<a href="http://www.rsyslog.com/">rsyslog</a>
-project.<br>
-Copyright © 2008 by <a href="http://www.gerhards.net/rainer">Rainer
-Gerhards</a> and
+<a href="http://www.rsyslog.com/">rsyslog</a> project.<br>
+Copyright &copy; 2008, 2009 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and
<a href="http://www.adiscon.com/">Adiscon</a>.
Released under the GNU GPL version 3 or higher.</font></p>
</body></html>
diff --git a/doc/imuxsock.html b/doc/imuxsock.html
index 472470a0..15c365a6 100644
--- a/doc/imuxsock.html
+++ b/doc/imuxsock.html
@@ -46,6 +46,18 @@ Ignore timestamps included in the messages, applies to messages received via the
<li><b>$SystemLogSocketName</b> &lt;name-of-socket&gt; -- former -p option</li>
<li><b>$SystemLogFlowControl</b> [on/<b>off</b>] - specifies if flow control should be applied
to the system log socket.</li>
+<li><b>$InputUnixListenSocketCreatePath</b> [on/<b>off</b>] - create directories in the socket path
+if they do not already exist. They are created with 0755 permissions with the owner being the process under
+which rsyslogd runs. The default is not to create directories. Keep in mind, though, that rsyslogd always
+creates the socket itself if it does not exist (just not the directories by default).
+<br>Note that this statement affects the
+next $AddUnixListenSocket directive that follows in sequence in the configuration file. It never works
+on the system log socket (where it is deemed unnecessary). Also note that it is automatically
+being reset to &quot;off&quot; after the $AddUnixListenSocket directive, so if you would have it active
+for two additional listen sockets, you need to specify it in front of each one. This option is primarily considered
+useful for defining additional sockets that reside on non-permanent file systems. As rsyslogd probably starts
+up before the daemons that create these sockets, it is a vehicle to enable rsyslogd to listen to those
+sockets even though their directories do not yet exist. [available since 4.7.0 and 5.3.0]</li>
<li><b>$AddUnixListenSocket</b> &lt;name-of-socket&gt; adds additional unix socket, default none -- former -a option</li>
<li><b>$InputUnixListenSocketHostName</b> &lt;hostname&gt; permits to override the hostname that
shall be used inside messages taken from the <b>next</b> $AddUnixListenSocket socket. Note that
@@ -57,20 +69,32 @@ that the local hostname can be overridden in cases where that is desired.</li>
<br>
This documentation is sparse and incomplete.
<p><b>Sample:</b></p>
-<p>The following sample is the minimum setup required to accept syslog messages from applications running on the local system.<br>
+<p>The following sample is the minimum setup required to accept syslog messages from applications running
+on the local system.<br>
</p>
<textarea rows="2" cols="70">$ModLoad imuxsock # needs to be done just once
$SystemLogSocketFlowControl on # enable flow control (use if needed)
</textarea>
<p>The following sample is a configuration where rsyslogd pulls logs from two
jails, and assigns different hostnames to each of the jails: </p>
-<textarea rows="6" cols="60">$ModLoad imuxsock # needs to be done just once
+<textarea rows="6" cols="70">$ModLoad imuxsock # needs to be done just once
$InputUnixListenSocketHostName jail1.example.net
$AddUnixListenSocket /jail/1/dev/log
$InputUnixListenSocketHostName jail2.example.net
$AddUnixListenSocket /jail/2/dev/log
</textarea>
+<p>The following sample is a configuration where rsyslogd reads the openssh log
+messages via a separate socket, but this socket is created on a temporary file
+system. As rsyslogd starts up before the sshd, it needs to create the socket
+directories, because it otherwise can not open the socket and thus not listen
+to openssh messages. Note that it is vital not to place any other socket between
+the $InputUnixListenSocketCreatePath and the $InputUnixListenSocketHostName.</p>
+<textarea rows="6" cols="70">$ModLoad imuxsock # needs to be done just once
+
+$InputUnixListenSocketCreatePath on # turn on for *next* socket
+$InputUnixListenSocketHostName /var/run/sshd/dev/log
+</textarea>
<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
[<a href="manual.html">manual index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
<p><font size="2">This documentation is part of the
diff --git a/doc/manual.html b/doc/manual.html
index 785845b6..52a8380e 100644
--- a/doc/manual.html
+++ b/doc/manual.html
@@ -19,7 +19,7 @@ rsyslog support</a> available directly from the source!</p>
<p><b>Please visit the <a href="http://www.rsyslog.com/sponsors">rsyslog sponsor's page</a>
to honor the project sponsors or become one yourself!</b> We are very grateful for any help towards the
project goals.</p>
-<p><b>This documentation is for version 4.5.7 (v4-beta branch) of rsyslog.</b>
+<p><b>This documentation is for version 4.7.0 (v4-devel branch) of rsyslog.</b>
Visit the <i><a href="http://www.rsyslog.com/doc-status.html">rsyslog status page</a></i></b>
to obtain current version information and project status.
</p><p><b>If you like rsyslog, you might
diff --git a/doc/omoracle.html b/doc/omoracle.html
index cfcf277f..2bb6aa5d 100644
--- a/doc/omoracle.html
+++ b/doc/omoracle.html
@@ -13,10 +13,11 @@
<p><b>Available since: </b>: 4.3.0
<p><b>Status: </b>: contributed module, not maitained by rsyslog core authors
<p><b>Description</b>:</p>
-<p>This module provides native support for logging to Oracle databases. It offers
-superior performance over the more generic <a href="omlibdbi.html">omlibdbi</a> module.
-It also includes a number of enhancements, most importantly prepared statements and
-batching, what provides a big performance improvements.
+<p>This module provides native support for logging to Oracle
+databases. It offers superior performance over the more
+generic <a href="omlibdbi.html">omlibdbi</a> module. It also includes
+a number of enhancements, most importantly prepared statements and
+batching, what provides a big performance improvement.
</p>
<p>Note that this module is maintained by its original author. If you need assistance with it,
it is suggested to post questions to the
@@ -63,7 +64,7 @@ it is suggested to post questions to the
$OmoracleStatement \
insert into foo(hostname,message)values(:host,:message)
- Also note that identifiers to placeholders are arbitrarry. You
+ Also note that identifiers to placeholders are arbitrary. You
need to define the properties on the template in the correct order
you want them passed to the statement!
</pre>
diff --git a/doc/rainerscript.html b/doc/rainerscript.html
index ef0e41cb..63a79040 100644
--- a/doc/rainerscript.html
+++ b/doc/rainerscript.html
@@ -51,13 +51,25 @@ of a and b should be tested as "a &lt;&gt; b". The "not" operator
should be reserved to cases where it actually is needed to form a
complex boolean expression. In those cases, parenthesis are highly
recommended.
+<h2>Functions</h2>
+<p>RainerScript supports a currently quite limited set of functions:
+<ul>
+<li>getenv(str) - like the OS call, returns the value of the environment
+variable, if it exists. Returns an empty string if it does not exist.
+<li>strlen(str) - returns the length of the provided string
+<li>tolower(str) - converts the provided string into lowercase
+</ul>
+<p>The following example can be used to build a dynamic filter based on some environment
+variable:
+<pre>
+if $msg contains getenv('TRIGGERVAR') then /path/to/errfile
+</pre>
<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
[<a href="manual.html">manual index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
<p><font size="2">This documentation is part of the
<a href="http://www.rsyslog.com/">rsyslog</a>
project.<br>
-Copyright © 2008 by <a href="http://www.gerhards.net/rainer">Rainer
-Gerhards</a> and
+Copyright &copy; 2008, 2009 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and
<a href="http://www.adiscon.com/">Adiscon</a>.
Released under the GNU GPL version 3 or higher.</font></p>
-</body></html> \ No newline at end of file
+</body></html>
diff --git a/doc/rsconf1_omfileforcechown.html b/doc/rsconf1_omfileforcechown.html
new file mode 100644
index 00000000..7415a6f6
--- /dev/null
+++ b/doc/rsconf1_omfileforcechown.html
@@ -0,0 +1,64 @@
+<html>
+<head>
+<title>rsyslog.conf file</title>
+</head>
+<body>
+<a href="rsyslog_conf_global.html">back</a>
+
+<h2>$omfileForceChown</h2>
+<p><b>Type:</b> global configuration directive</p>
+<p><b>Parameter Values:</b> boolean (on/off, yes/no)</p>
+<p><b>Available since:</b> 4.7.0+, 5.3.0+</p>
+<p><b>Default:</b> off</p>
+<p><b>Description:</b></p>
+<p>Forces rsyslogd to change the ownership for output files that already exist. Please note
+that this tries to fix a potential problem that exists outside the scope of rsyslog. Actually,
+it tries to fix invalid ownership/permission settings set by the original file creator.
+<p>Rsyslog changes the ownership during initial execution with root privileges. When a privelege
+drop is configured, privileges are dropped after the file owner ship is changed. Not that this currently
+is a limitation in rsyslog's privilege drop code, which is on the TODO list to be removed. See Caveats
+section below for the important implications.
+<p><b>Caveats:</b></p>
+<p>This directive tries to fix a problem that actually is outside the scope of rsyslog. As such,
+there are a couple of restrictions and situations in which it will not work. <b>Users are strongly
+encouraged to fix their system instead of turning this directive on</b> - it should only be used
+as a last resort.
+<p>At least in the following scenario, this directive will fail expectedly:
+<p>It does not address
+the situation that someone changes the ownership *after* rsyslogd has started.
+Let's, for example, consider a log rotation script.
+<ul>
+<li>rsyslog is started
+<li>ownership is changed
+<li>privileges dropped
+<li>log rotation (lr) script starts
+<li>lr removes files
+<li>lr creates new files with root:adm (or whatever else)
+<li>lr HUPs rsyslogd
+<li>rsyslogd closes files
+<li>rsyslogd tries to open files
+<li>rsyslogd tries to change ownership --&gt; fail as we are non-root now
+<li>file open fails
+</ul>
+
+Please note that once the privilege drop code is refactored, this directive will
+no longer work, because then privileges will be dropped before any action is performed,
+and thus we will no longer be able to chown files that do not belong to the
+user rsyslogd is configured to run under.
+
+<p>So <b>expect the directive to go away</b>. It will not
+be removed in version 4, but may disappear at any time for any version greater than 4.
+
+<p><b>Sample:</b></p>
+<p><code><b>$FileOwner loguser</b>
+<br><b>$omfileForceChown on</b></code></p>
+
+<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>] [<a href="manual.html">manual
+index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
+<p><font size="2">This documentation is part of the
+<a href="http://www.rsyslog.com/">rsyslog</a> project.<br>
+Copyright &copy; 2007 by <a href="http://www.gerhards.net/rainer">Rainer Gerhards</a> and
+<a href="http://www.adiscon.com/">Adiscon</a>. Released under the GNU GPL
+version 2 or higher.</font></p>
+</body>
+</html>
diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html
index 50d83a50..76dce26d 100644
--- a/doc/rsyslog_conf_global.html
+++ b/doc/rsyslog_conf_global.html
@@ -130,6 +130,7 @@ our paper on <a href="multi_ruleset.html">using multiple rule sets in rsyslog</a
<li><a href="rsconf1_droptrailinglfonreception.html">$DropTrailingLFOnReception</a></li>
<li><a href="rsconf1_dynafilecachesize.html">$DynaFileCacheSize</a></li>
<li><a href="rsconf1_escapecontrolcharactersonreceive.html">$EscapeControlCharactersOnReceive</a></li>
+<li><b>$EscapeControlCharactersOnReceive</b> [<b>on</b>|off] - escape USASCII HT character</li>
<li>$ErrorMessagesToStderr [<b>on</b>|off] - direct rsyslogd error message to stderr (in addition to other targets)</li>
<li><a href="rsconf1_failonchownfailure.html">$FailOnChownFailure</a></li>
<li><a href="rsconf1_filecreatemode.html">$FileCreateMode</a></li>
@@ -149,6 +150,10 @@ Usually that should not be a big issue, as the restart-type HUP can easily be re
something along the lines of &quot;/etc/init.d/rsyslog restart&quot;.
</li>
<li><a href="rsconf1_includeconfig.html">$IncludeConfig</a></li><li>MainMsgQueueCheckpointInterval &lt;number&gt;</li>
+<li><b>$LogRSyslogStatusMessages</b> [<b>on</b>/off] - If set to on (the default),
+rsyslog emits message on startup and shutdown as well as when it is HUPed.
+This information might be needed by some log analyzers. If set to off, no such
+status messages are logged, what may be useful for other scenarios.
<li>$MainMsgQueueDequeueSlowdown &lt;number&gt; [number
is timeout in <i> micro</i>seconds (1000000us is 1sec!),
default 0 (no delay). Simple rate-limiting!]</li>
@@ -221,6 +226,7 @@ error recovery thus can handle write errors without data loss. Note that this op
severely reduces the effect of zip compression and should be switched to off
for that use case. Note that the default -off- is primarily an aid to preserve
the traditional syslogd behaviour.</li>
+<li><a href="rsconf1_omfileforcechown.html">$omfileForceChown</a> - force ownership change for all files</li>
<li><b>$RepeatedMsgContainsOriginalMsg</b> [on/<b>off</b>] - "last message repeated n times" messages, if generated,
have a different format that contains the message that is being repeated.
Note that only the first "n" characters are included, with n to be at least 80 characters, most
diff --git a/gss-misc.c b/gss-misc.c
index c9220595..978454ff 100644
--- a/gss-misc.c
+++ b/gss-misc.c
@@ -51,11 +51,14 @@
#include "obj.h"
#include "errmsg.h"
#include "gss-misc.h"
+#include "glbl.h"
+#include "unlimited_select.h"
MODULE_TYPE_LIB
/* static data */
DEFobjStaticHelpers
+DEFobjCurrIf(glbl)
DEFobjCurrIf(errmsg)
static void display_status_(char *m, OM_uint32 code, int type)
@@ -108,28 +111,38 @@ static int read_all(int fd, char *buf, unsigned int nbyte)
{
int ret;
char *ptr;
- fd_set rfds;
struct timeval tv;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pRfds = malloc(glbl.GetFdSetSize());
+#else
+ fd_set rfds;
+ fd_set *pRfds = &rfds;
+#endif
for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) {
- FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
+ FD_ZERO(pRfds);
+ FD_SET(fd, pRfds);
tv.tv_sec = 1;
tv.tv_usec = 0;
- if ((ret = select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) <= 0
- || !FD_ISSET(fd, &rfds))
+ if ((ret = select(FD_SETSIZE, pRfds, NULL, NULL, &tv)) <= 0
+ || !FD_ISSET(fd, pRfds)) {
+ freeFdSet(pRfds);
return ret;
+ }
ret = recv(fd, ptr, nbyte, 0);
if (ret < 0) {
if (errno == EINTR)
continue;
+ freeFdSet(pRfds);
return (ret);
} else if (ret == 0) {
+ freeFdSet(pRfds);
return (ptr - buf);
}
}
+ freeFdSet(pRfds);
return (ptr - buf);
}
@@ -264,6 +277,7 @@ BEGINObjClassExit(gssutil, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END M
CODESTARTObjClassExit(gssutil)
/* release objects we no longer need */
objRelease(errmsg, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
ENDObjClassExit(gssutil)
@@ -274,6 +288,7 @@ ENDObjClassExit(gssutil)
BEGINAbstractObjClassInit(gssutil, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE class also in END MACRO! */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
ENDObjClassInit(gssutil)
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index d8791880..1aad6622 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -56,6 +56,7 @@
#include "errmsg.h"
#include "netstrm.h"
#include "glbl.h"
+#include "unlimited_select.h"
MODULE_TYPE_INPUT
@@ -414,15 +415,20 @@ OnSessAcceptGSS(tcpsrv_t *pThis, tcps_sess_t *pSess)
CHKiRet(netstrm.GetSock(pSess->pStrm, &fdSess)); // TODO: method access!
if (allowedMethods & ALLOWEDMETHOD_TCP) {
int len;
- fd_set fds;
struct timeval tv;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pFds = malloc(glbl.GetFdSetSize());
+#else
+ fd_set fds;
+ fd_set *pFds = &fds;
+#endif
do {
- FD_ZERO(&fds);
- FD_SET(fdSess, &fds);
+ FD_ZERO(pFds);
+ FD_SET(fdSess, pFds);
tv.tv_sec = 1;
tv.tv_usec = 0;
- ret = select(fdSess + 1, &fds, NULL, NULL, &tv);
+ ret = select(fdSess + 1, pFds, NULL, NULL, &tv);
} while (ret < 0 && errno == EINTR);
if (ret < 0) {
errmsg.LogError(0, RS_RET_ERR, "TCP session %p will be closed, error ignored\n", pSess);
@@ -475,6 +481,8 @@ OnSessAcceptGSS(tcpsrv_t *pThis, tcps_sess_t *pSess)
pGSess->allowedMethods = ALLOWEDMETHOD_TCP;
ABORT_FINALIZE(RS_RET_OK); // TODO: define good error codes
}
+
+ freeFdSet(pFds);
}
context = &pGSess->gss_context;
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 0970259d..ecc36c28 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -45,6 +45,7 @@
#include "datetime.h"
#include "prop.h"
#include "unicode-helper.h"
+#include "unlimited_select.h"
MODULE_TYPE_INPUT
@@ -287,12 +288,18 @@ BEGINrunInput
int maxfds;
int nfds;
int i;
- fd_set readfds;
struct sockaddr_storage frominetPrev;
int bIsPermitted;
uchar fromHost[NI_MAXHOST];
uchar fromHostIP[NI_MAXHOST];
uchar fromHostFQDN[NI_MAXHOST];
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = malloc(glbl.GetFdSetSize());
+#else
+ fd_set readfds;
+ fd_set *pReadfds = &readfds;
+#endif
+
CODESTARTrunInput
/* start "name caching" algo by making sure the previous system indicator
* is invalidated.
@@ -311,30 +318,30 @@ CODESTARTrunInput
* is given without -a, we do not need to listen at all..
*/
maxfds = 0;
- FD_ZERO (&readfds);
+ FD_ZERO (pReadfds);
/* Add the UDP listen sockets to the list of read descriptors. */
for (i = 0; i < *udpLstnSocks; i++) {
if (udpLstnSocks[i+1] != -1) {
if(Debug)
net.debugListenInfo(udpLstnSocks[i+1], "UDP");
- FD_SET(udpLstnSocks[i+1], &readfds);
+ FD_SET(udpLstnSocks[i+1], pReadfds);
if(udpLstnSocks[i+1]>maxfds) maxfds=udpLstnSocks[i+1];
}
}
if(Debug) {
dbgprintf("--------imUDP calling select, active file descriptors (max %d): ", maxfds);
for (nfds = 0; nfds <= maxfds; ++nfds)
- if ( FD_ISSET(nfds, &readfds) )
+ if ( FD_ISSET(nfds, pReadfds) )
dbgprintf("%d ", nfds);
dbgprintf("\n");
}
/* wait for io to become ready */
- nfds = select(maxfds+1, (fd_set *) &readfds, NULL, NULL, NULL);
+ nfds = select(maxfds+1, (fd_set *) pReadfds, NULL, NULL, NULL);
for(i = 0; nfds && i < *udpLstnSocks; i++) {
- if(FD_ISSET(udpLstnSocks[i+1], &readfds)) {
+ if(FD_ISSET(udpLstnSocks[i+1], pReadfds)) {
processSocket(udpLstnSocks[i+1], &frominetPrev, &bIsPermitted,
fromHost, fromHostFQDN, fromHostIP);
--nfds; /* indicate we have processed one descriptor */
@@ -343,6 +350,7 @@ CODESTARTrunInput
/* end of a run, back to loop for next recv() */
}
+ freeFdSet(pReadfds);
return iRet;
ENDrunInput
diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c
index 424d0904..5aa3c25b 100644
--- a/plugins/imuxsock/imuxsock.c
+++ b/plugins/imuxsock/imuxsock.c
@@ -45,6 +45,7 @@
#include "glbl.h"
#include "msg.h"
#include "prop.h"
+#include "unlimited_select.h"
MODULE_TYPE_INPUT
@@ -77,6 +78,7 @@ static int startIndexUxLocalSockets; /* process funix from that index on (used t
*/
static int funixParseHost[MAXFUNIX] = { 0, }; /* should parser parse host name? read-only after startup */
static int funixFlags[MAXFUNIX] = { IGNDATE, }; /* should parser parse host name? read-only after startup */
+static int funixCreateSockPath[MAXFUNIX] = { 0, }; /* auto-creation of socket directory? */
static uchar *funixn[MAXFUNIX] = { (uchar*) _PATH_LOG }; /* read-only after startup */
static uchar *funixHName[MAXFUNIX] = { NULL, }; /* host-name override - if set, use this instead of actual name */
static int funixFlowCtl[MAXFUNIX] = { eFLOWCTL_NO_DELAY, }; /* flow control settings for this socket */
@@ -89,6 +91,8 @@ static uchar *pLogSockName = NULL;
static uchar *pLogHostName = NULL; /* host name to use with this socket */
static int bUseFlowCtl = 0; /* use flow control or not (if yes, only LIGHT is used! */
static int bIgnoreTimestamp = 1; /* ignore timestamps present in the incoming message? */
+#define DFLT_bCreateSockPath 0
+static int bCreateSockPath = DFLT_bCreateSockPath; /* auto-create socket path? */
/* set the timestamp ignore / not ignore option for the system
@@ -132,6 +136,7 @@ static rsRetVal addLstnSocketName(void __attribute__((unused)) *pVal, uchar *pNe
pLogHostName = NULL; /* re-init for next, not freed because funixHName[] now owns it */
funixFlowCtl[nfunix] = bUseFlowCtl ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY;
funixFlags[nfunix] = bIgnoreTimestamp ? IGNDATE : NOFLAG;
+ funixCreateSockPath[nfunix] = bCreateSockPath;
funixn[nfunix++] = pNewVal;
}
else {
@@ -165,7 +170,7 @@ static rsRetVal discardFunixn(void)
}
-static int create_unix_socket(const char *path)
+static int create_unix_socket(const char *path, int bCreatePath)
{
struct sockaddr_un sunx;
int fd;
@@ -177,6 +182,9 @@ static int create_unix_socket(const char *path)
memset(&sunx, 0, sizeof(sunx));
sunx.sun_family = AF_UNIX;
+ if(bCreatePath) {
+ makeFileParentDirs((uchar*)path, strlen(path), 0755, -1, -1, 0);
+ }
(void) strncpy(sunx.sun_path, path, sizeof(sunx.sun_path));
fd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (fd < 0 || bind(fd, (struct sockaddr *) &sunx, SUN_LEN(&sunx)) < 0 ||
@@ -249,7 +257,13 @@ BEGINrunInput
int nfds;
int i;
int fd;
- fd_set readfds;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = malloc(glbl.GetFdSetSize());
+#else
+ fd_set readfds;
+ fd_set *pReadfds = &readfds;
+#endif
+
CODESTARTrunInput
/* this is an endless loop - it is terminated when the thread is
* signalled to do so. This, however, is handled by the framework,
@@ -263,11 +277,11 @@ CODESTARTrunInput
* is given without -a, we do not need to listen at all..
*/
maxfds = 0;
- FD_ZERO (&readfds);
+ FD_ZERO (pReadfds);
/* Copy master connections */
for (i = startIndexUxLocalSockets; i < nfunix; i++) {
if (funix[i] != -1) {
- FD_SET(funix[i], &readfds);
+ FD_SET(funix[i], pReadfds);
if (funix[i]>maxfds) maxfds=funix[i];
}
}
@@ -275,22 +289,23 @@ CODESTARTrunInput
if(Debug) {
dbgprintf("--------imuxsock calling select, active file descriptors (max %d): ", maxfds);
for (nfds= 0; nfds <= maxfds; ++nfds)
- if ( FD_ISSET(nfds, &readfds) )
+ if ( FD_ISSET(nfds, pReadfds) )
dbgprintf("%d ", nfds);
dbgprintf("\n");
}
/* wait for io to become ready */
- nfds = select(maxfds+1, (fd_set *) &readfds, NULL, NULL, NULL);
+ nfds = select(maxfds+1, (fd_set *) pReadfds, NULL, NULL, NULL);
for (i = 0; i < nfunix && nfds > 0; i++) {
- if ((fd = funix[i]) != -1 && FD_ISSET(fd, &readfds)) {
+ if ((fd = funix[i]) != -1 && FD_ISSET(fd, pReadfds)) {
readSocket(fd, i);
--nfds; /* indicate we have processed one */
}
}
}
+ freeFdSet(pReadfds);
RETiRet;
ENDrunInput
@@ -306,7 +321,7 @@ CODESTARTwillRun
/* initialize and return if will run or not */
for (i = startIndexUxLocalSockets ; i < nfunix ; i++) {
- if ((funix[i] = create_unix_socket((char*) funixn[i])) != -1)
+ if ((funix[i] = create_unix_socket((char*) funixn[i], funixCreateSockPath[i])) != -1)
dbgprintf("Opened UNIX socket '%s' (fd %d).\n", funixn[i], funix[i]);
}
@@ -376,6 +391,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
nfunix = 1;
bIgnoreTimestamp = 1;
bUseFlowCtl = 0;
+ bCreateSockPath = DFLT_bCreateSockPath;
return RS_RET_OK;
}
@@ -409,6 +425,8 @@ CODEmodInit_QueryRegCFSLineHdlr
NULL, &pLogHostName, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketflowcontrol", 0, eCmdHdlrBinary,
NULL, &bUseFlowCtl, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketcreatepath", 0, eCmdHdlrBinary,
+ NULL, &bCreateSockPath, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"addunixlistensocket", 0, eCmdHdlrGetWord,
addLstnSocketName, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler,
diff --git a/plugins/omoracle/omoracle.c b/plugins/omoracle/omoracle.c
index 331b7dd4..48ee1fa4 100644
--- a/plugins/omoracle/omoracle.c
+++ b/plugins/omoracle/omoracle.c
@@ -47,9 +47,9 @@
$OmoracleStatement \
insert into foo(hostname,message)values(:host,:message)
- Also note that identifiers to placeholders are arbitrarry. You
- need to define the properties on the template in the correct order
- you want them passed to the statement!
+ Also note that identifiers to placeholders are arbitrary. You need
+ to define the properties on the template in the correct order you
+ want them passed to the statement!
This file is licensed under the terms of the GPL version 3 or, at
your choice, any later version. Exceptionally (perhaps), you are
@@ -87,7 +87,8 @@ MODULE_TYPE_OUTPUT
DEF_OMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
-/** */
+/** Structure defining a batch of items to be sent to the database in
+ * the same statement execution. */
struct oracle_batch
{
/* Batch size */
@@ -162,8 +163,10 @@ static int oci_errors(void* handle, ub4 htype, sword status)
return OCI_SUCCESS;
break;
case OCI_SUCCESS_WITH_INFO:
- errmsg.LogError(0, NO_ERRCODE, "OCI SUCCESS - With info\n");
- break;
+ OCIErrorGet(handle, 1, NULL, &errcode, buf, sizeof buf, htype);
+ errmsg.LogError(0, NO_ERRCODE, "OCI SUCCESS - With info: %s",
+ buf);
+ return OCI_SUCCESS_WITH_INFO;
case OCI_NEED_DATA:
errmsg.LogError(0, NO_ERRCODE, "OCI NEEDS MORE DATA\n");
break;
@@ -180,6 +183,9 @@ static int oci_errors(void* handle, ub4 htype, sword status)
break;
case OCI_INVALID_HANDLE:
errmsg.LogError(0, NO_ERRCODE, "OCI INVALID HANDLE\n");
+ /* In this case we may have to trigger a call to
+ * tryResume(). */
+ return RS_RET_SUSPENDED;
break;
case OCI_STILL_EXECUTING:
errmsg.LogError(0, NO_ERRCODE, "Still executing...\n");
@@ -332,6 +338,48 @@ CODESTARTcreateInstance
finalize_it:
ENDcreateInstance
+/* Analyses the errors during a batch statement execution, and logs
+ * all the corresponding ORA-MESSAGES, together with some useful
+ * information. */
+static void log_detailed_err(instanceData* pData)
+{
+ DEFiRet;
+ int errs, i, row, code, j;
+ OCIError *er = NULL, *er2 = NULL;
+ unsigned char buf[MAX_BUFSIZE];
+
+ OCIAttrGet(pData->statement, OCI_HTYPE_STMT, &errs, 0,
+ OCI_ATTR_NUM_DML_ERRORS, pData->error);
+ errmsg.LogError(0, NO_ERRCODE, "OCI: %d errors in execution of "
+ "statement: %s", errs, pData->txt_statement);
+
+ CHECKENV(pData->environment,
+ OCIHandleAlloc(pData->environment, &er, OCI_HTYPE_ERROR,
+ 0, NULL));
+ CHECKENV(pData->environment,
+ OCIHandleAlloc(pData->environment, &er2, OCI_HTYPE_ERROR,
+ 0, NULL));
+
+ for (i = 0; i < errs; i++) {
+ OCIParamGet(pData->error, OCI_HTYPE_ERROR,
+ er2, &er, i);
+ OCIAttrGet(er, OCI_HTYPE_ERROR, &row, 0,
+ OCI_ATTR_DML_ROW_OFFSET, er2);
+ errmsg.LogError(0, NO_ERRCODE, "OCI failure in row %d:", row);
+ for (j = 0; j < pData->batch.arguments; j++)
+ errmsg.LogError(0, NO_ERRCODE, "%s",
+ pData->batch.parameters[j][row]);
+ OCIErrorGet(er, 1, NULL, &code, buf, sizeof buf,
+ OCI_HTYPE_ERROR);
+ errmsg.LogError(0, NO_ERRCODE, "FAILURE DETAILS: %s", buf);
+ }
+
+finalize_it:
+ OCIHandleFree(er, OCI_HTYPE_ERROR);
+ OCIHandleFree(er2, OCI_HTYPE_ERROR);
+}
+
+
/* Inserts all stored statements into the database, releasing any
* allocated memory. */
static int insert_to_db(instanceData* pData)
@@ -346,6 +394,10 @@ static int insert_to_db(instanceData* pData)
OCI_BATCH_ERRORS));
finalize_it:
+ if (iRet == OCI_SUCCESS_WITH_INFO) {
+ log_detailed_err(pData);
+ iRet = RS_RET_OK;
+ }
pData->batch.n = 0;
OCITransCommit(pData->service, pData->error, 0);
dbgprintf ("omoracle insertion to DB %s\n", iRet == RS_RET_OK ?
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
index 14abe722..c1a15198 100644
--- a/runtime/Makefile.am
+++ b/runtime/Makefile.am
@@ -15,6 +15,7 @@ librsyslog_la_SOURCES = \
nsd.h \
glbl.h \
glbl.c \
+ unlimited_select.h \
conf.c \
conf.h \
parser.h \
diff --git a/runtime/debug.c b/runtime/debug.c
index 9547eee6..c23dec3b 100644
--- a/runtime/debug.c
+++ b/runtime/debug.c
@@ -1271,11 +1271,11 @@ dbgGetRuntimeOptions(void)
/* this is earlier in the process than the -d option, as such it
* allows us to spit out debug messages from the very beginning.
*/
- Debug = 1;
+ Debug = DEBUG_FULL;
debugging_on = 1;
} else if(!strcasecmp((char*)optname, "debugondemand")) {
/* Enables debugging, but turns off debug output */
- Debug = 1;
+ Debug = DEBUG_ONDEMAND;
debugging_on = 1;
dbgprintf("Note: debug on demand turned on via configuraton file, "
"use USR1 signal to activate.\n");
diff --git a/runtime/debug.h b/runtime/debug.h
index dcbfb930..cfdf819c 100644
--- a/runtime/debug.h
+++ b/runtime/debug.h
@@ -29,6 +29,11 @@
#include <pthread.h>
#include "obj-types.h"
+/* some settings for various debug modes */
+#define DEBUG_OFF 0
+#define DEBUG_ONDEMAND 1
+#define DEBUG_FULL 2
+
/* external static data elements (some time to be replaced) */
extern int Debug; /* debug flag - read-only after startup */
extern int debugging_on; /* read-only, except on sig USR1 */
diff --git a/runtime/glbl.c b/runtime/glbl.c
index 7fa61963..58558ed2 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -72,6 +72,9 @@ static uchar *pszDfltNetstrmDrvr = NULL; /* module name of default netstream dri
static uchar *pszDfltNetstrmDrvrCAF = NULL; /* default CA file for the netstrm driver */
static uchar *pszDfltNetstrmDrvrKeyFile = NULL; /* default key file for the netstrm driver (server) */
static uchar *pszDfltNetstrmDrvrCertFile = NULL; /* default cert file for the netstrm driver (server) */
+#ifdef USE_UNLIMITED_SELECT
+static int iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask); /* size of select() bitmask in bytes */
+#endif
/* define a macro for the simple properties' set and get functions
@@ -104,6 +107,9 @@ SIMP_PROP(DisableDNS, bDisableDNS, int)
SIMP_PROP(LocalDomain, LocalDomain, uchar*)
SIMP_PROP(StripDomains, StripDomains, char**)
SIMP_PROP(LocalHosts, LocalHosts, char**)
+#ifdef USE_UNLIMITED_SELECT
+SIMP_PROP(FdSetSize, iFdSetSize, int)
+#endif
SIMP_PROP_SET(LocalFQDNName, LocalFQDNName, uchar*)
SIMP_PROP_SET(LocalHostName, LocalHostName, uchar*)
@@ -261,6 +267,9 @@ CODESTARTobjQueryInterface(glbl)
SIMP_PROP(DfltNetstrmDrvrCAF)
SIMP_PROP(DfltNetstrmDrvrKeyFile)
SIMP_PROP(DfltNetstrmDrvrCertFile)
+#ifdef USE_UNLIMITED_SELECT
+ SIMP_PROP(FdSetSize)
+#endif
#undef SIMP_PROP
finalize_it:
ENDobjQueryInterface(glbl)
@@ -295,6 +304,9 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
bOptimizeUniProc = 1;
bHUPisRestart = 0;
bPreserveFQDN = 0;
+#ifdef USE_UNLIMITED_SELECT
+ iFdSetSize = howmany(FD_SETSIZE, __NFDBITS) * sizeof (fd_mask);
+#endif
return RS_RET_OK;
}
diff --git a/runtime/glbl.h b/runtime/glbl.h
index dcfb6d5f..6a332576 100644
--- a/runtime/glbl.h
+++ b/runtime/glbl.h
@@ -62,9 +62,18 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
/* added v3, 2009-06-30 */
rsRetVal (*GenerateLocalHostNameProperty)(void);
prop_t* (*GetLocalHostNameProp)(void);
+ /* note: v4, v5 are already used by more recent versions, so we need to skip them! */
+ /* added v6, 2009-11-16 as part of varmojfekoj's "unlimited select()" patch
+ * Note that it must be always present, otherwise the interface would have different
+ * versions depending on compile settings, what is not acceptable.
+ * Use this property with care, it is only truly available if UNLIMITED_SELECT is enabled
+ * (I did not yet further investigate the details, because that code hopefully can be removed
+ * at some later stage).
+ */
+ SIMP_PROP(FdSetSize, int)
#undef SIMP_PROP
ENDinterface(glbl)
-#define glblCURR_IF_VERSION 3 /* increment whenever you change the interface structure! */
+#define glblCURR_IF_VERSION 6 /* increment whenever you change the interface structure! */
/* version 2 had PreserveFQDN added - rgerhards, 2008-12-08 */
/* the remaining prototypes */
diff --git a/runtime/nsdsel_ptcp.c b/runtime/nsdsel_ptcp.c
index 41b85e0c..e2cfca7c 100644
--- a/runtime/nsdsel_ptcp.c
+++ b/runtime/nsdsel_ptcp.c
@@ -36,6 +36,7 @@
#include "errmsg.h"
#include "nsd_ptcp.h"
#include "nsdsel_ptcp.h"
+#include "unlimited_select.h"
/* static data */
DEFobjStaticHelpers
@@ -47,14 +48,23 @@ DEFobjCurrIf(glbl)
*/
BEGINobjConstruct(nsdsel_ptcp) /* be sure to specify the object type also in END macro! */
pThis->maxfds = 0;
+#ifdef USE_UNLIMITED_SELECT
+ pThis->pReadfds = calloc(1, glbl.GetFdSetSize());
+ pThis->pWritefds = calloc(1, glbl.GetFdSetSize());
+#else
FD_ZERO(&pThis->readfds);
FD_ZERO(&pThis->writefds);
+#endif
ENDobjConstruct(nsdsel_ptcp)
/* destructor for the nsdsel_ptcp object */
BEGINobjDestruct(nsdsel_ptcp) /* be sure to specify the object type also in END and CODESTART macros! */
CODESTARTobjDestruct(nsdsel_ptcp)
+#ifdef USE_UNLIMITED_SELECT
+ freeFdSet(pThis->pReadfds);
+ freeFdSet(pThis->pWritefds);
+#endif
ENDobjDestruct(nsdsel_ptcp)
@@ -65,20 +75,27 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp)
DEFiRet;
nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
nsd_ptcp_t *pSock = (nsd_ptcp_t*) pNsd;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = pThis->pReadfds;
+ fd_set *pWritefds = pThis->pWritefds;
+#else
+ fd_set *pReadfds = &pThis->readfds;
+ fd_set *pWritefds = &pThis->writefds;
+#endif
ISOBJ_TYPE_assert(pSock, nsd_ptcp);
ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
switch(waitOp) {
case NSDSEL_RD:
- FD_SET(pSock->sock, &pThis->readfds);
+ FD_SET(pSock->sock, pReadfds);
break;
case NSDSEL_WR:
- FD_SET(pSock->sock, &pThis->writefds);
+ FD_SET(pSock->sock, pWritefds);
break;
case NSDSEL_RDWR:
- FD_SET(pSock->sock, &pThis->readfds);
- FD_SET(pSock->sock, &pThis->writefds);
+ FD_SET(pSock->sock, pReadfds);
+ FD_SET(pSock->sock, pWritefds);
break;
}
@@ -98,6 +115,13 @@ Select(nsdsel_t *pNsdsel, int *piNumReady)
DEFiRet;
int i;
nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = pThis->pReadfds;
+ fd_set *pWritefds = pThis->pWritefds;
+#else
+ fd_set *pReadfds = &pThis->readfds;
+ fd_set *pWritefds = &pThis->writefds;
+#endif
ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
assert(piNumReady != NULL);
@@ -106,13 +130,13 @@ Select(nsdsel_t *pNsdsel, int *piNumReady)
// TODO: name in dbgprintf!
dbgprintf("--------<NSDSEL_PTCP> calling select, active fds (max %d): ", pThis->maxfds);
for(i = 0; i <= pThis->maxfds; ++i)
- if(FD_ISSET(i, &pThis->readfds) || FD_ISSET(i, &pThis->writefds))
+ if(FD_ISSET(i, pReadfds) || FD_ISSET(i, pWritefds))
dbgprintf("%d ", i);
dbgprintf("\n");
}
/* now do the select */
- *piNumReady = select(pThis->maxfds+1, &pThis->readfds, &pThis->writefds, NULL, NULL);
+ *piNumReady = select(pThis->maxfds+1, pReadfds, pWritefds, NULL, NULL);
RETiRet;
}
@@ -125,6 +149,13 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
DEFiRet;
nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
nsd_ptcp_t *pSock = (nsd_ptcp_t*) pNsd;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds = pThis->pReadfds;
+ fd_set *pWritefds = pThis->pWritefds;
+#else
+ fd_set *pReadfds = &pThis->readfds;
+ fd_set *pWritefds = &pThis->writefds;
+#endif
ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
ISOBJ_TYPE_assert(pSock, nsd_ptcp);
@@ -132,14 +163,14 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
switch(waitOp) {
case NSDSEL_RD:
- *pbIsReady = FD_ISSET(pSock->sock, &pThis->readfds);
+ *pbIsReady = FD_ISSET(pSock->sock, pReadfds);
break;
case NSDSEL_WR:
- *pbIsReady = FD_ISSET(pSock->sock, &pThis->writefds);
+ *pbIsReady = FD_ISSET(pSock->sock, pWritefds);
break;
case NSDSEL_RDWR:
- *pbIsReady = FD_ISSET(pSock->sock, &pThis->readfds)
- | FD_ISSET(pSock->sock, &pThis->writefds);
+ *pbIsReady = FD_ISSET(pSock->sock, pReadfds)
+ | FD_ISSET(pSock->sock, pWritefds);
break;
}
diff --git a/runtime/nsdsel_ptcp.h b/runtime/nsdsel_ptcp.h
index 6c0c7fa7..f9ec8210 100644
--- a/runtime/nsdsel_ptcp.h
+++ b/runtime/nsdsel_ptcp.h
@@ -31,8 +31,13 @@ typedef nsdsel_if_t nsdsel_ptcp_if_t; /* we just *implement* this interface */
struct nsdsel_ptcp_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
int maxfds;
+#ifdef USE_UNLIMITED_SELECT
+ fd_set *pReadfds;
+ fd_set *pWritefds;
+#else
fd_set readfds;
fd_set writefds;
+#endif
};
/* interface is defined in nsd.h, we just implement it! */
diff --git a/runtime/unlimited_select.h b/runtime/unlimited_select.h
new file mode 100644
index 00000000..32dadc03
--- /dev/null
+++ b/runtime/unlimited_select.h
@@ -0,0 +1,45 @@
+/* unlimited_select.h
+ * Tweak the macros for accessing fd_set so that the select() syscall
+ * won't be limited to a particular number of file descriptors.
+ *
+ * Copyright 2009 Rainer Gerhards and Adiscon GmbH.
+ *
+ * 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.
+ */
+
+#ifndef UNLIMITED_SELECT_H_INCLUDED
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/select.h>
+#include "glbl.h"
+
+#ifdef USE_UNLIMITED_SELECT
+# undef FD_ZERO
+# define FD_ZERO(set) memset((set), 0, glbl.GetFdSetSize());
+#endif
+
+#ifdef USE_UNLIMITED_SELECT
+void freeFdSet(fd_set *p) {
+ free(p);
+}
+#else
+# define freeFdSet(x)
+#endif
+
+#endif /* #ifndef UNLIMITED_SELECT_H_INCLUDED */
diff --git a/runtime/vm.c b/runtime/vm.c
index d7cd52d5..a1d992c3 100644
--- a/runtime/vm.c
+++ b/runtime/vm.c
@@ -34,6 +34,7 @@
#include "vm.h"
#include "sysvar.h"
#include "stringbuf.h"
+#include "unicode-helper.h"
/* static data */
DEFobjStaticHelpers
@@ -41,6 +42,8 @@ DEFobjCurrIf(vmstk)
DEFobjCurrIf(var)
DEFobjCurrIf(sysvar)
+static pthread_mutex_t mutGetenv; /* we need to make this global because otherwise we can not guarantee proper init! */
+
/* ------------------------------ function registry code and structures ------------------------------ */
/* we maintain a registry of known functions */
@@ -539,6 +542,42 @@ finalize_it:
}
+/* The getenv function. Note that we guard the OS call by a mutex, as that
+ * function is not guaranteed to be thread-safe. This implementation here is far from
+ * being optimal, at least we should cache the result. This is left TODO for
+ * a later revision.
+ * rgerhards, 2009-11-03
+ */
+static rsRetVal
+rsf_getenv(vmstk_t *pStk, int numOperands)
+{
+ DEFiRet;
+ var_t *operand1;
+ char *envResult;
+ cstr_t *pCstr;
+
+ if(numOperands != 1)
+ ABORT_FINALIZE(RS_RET_INVLD_NBR_ARGUMENTS);
+
+ /* pop args and do operaton (trivial case here...) */
+ vmstk.PopString(pStk, &operand1);
+ d_pthread_mutex_lock(&mutGetenv);
+ envResult = getenv((char*) rsCStrGetSzStr(operand1->val.pStr));
+ DBGPRINTF("rsf_getenv(): envvar '%s', return '%s'\n", rsCStrGetSzStr(operand1->val.pStr),
+ envResult == NULL ? "(NULL)" : envResult);
+ iRet = rsCStrConstructFromszStr(&pCstr, (envResult == NULL) ? UCHAR_CONSTANT("") : (uchar*)envResult);
+ d_pthread_mutex_unlock(&mutGetenv);
+ if(iRet != RS_RET_OK)
+ FINALIZE; /* need to do this after mutex is unlocked! */
+
+ /* Store result and cleanup */
+ var.SetString(operand1, pCstr);
+ vmstk.Push(pStk, operand1);
+finalize_it:
+ RETiRet;
+}
+
+
/* The "tolower" function, which converts its sole argument to lower case.
* Quite honestly, currently this is primarily a test driver for me...
* rgerhards, 2009-04-06
@@ -756,6 +795,8 @@ BEGINObjClassExit(vm, OBJ_IS_CORE_MODULE) /* class, version */
objRelease(sysvar, CORE_COMPONENT);
objRelease(var, CORE_COMPONENT);
objRelease(vmstk, CORE_COMPONENT);
+
+ pthread_mutex_destroy(&mutGetenv);
ENDObjClassExit(vm)
@@ -776,6 +817,9 @@ BEGINObjClassInit(vm, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* register built-in functions // TODO: move to its own module */
CHKiRet(rsfrAddFunction((uchar*)"strlen", rsf_strlen));
CHKiRet(rsfrAddFunction((uchar*)"tolower", rsf_tolower));
+ CHKiRet(rsfrAddFunction((uchar*)"getenv", rsf_getenv));
+
+ pthread_mutex_init(&mutGetenv, NULL);
ENDObjClassInit(vm)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 2026aec1..6091896b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -7,6 +7,7 @@ TESTS = $(TESTRUNS) cfg.sh \
diskqueue.sh \
diskqueue-fsync.sh \
manytcp.sh \
+ rsf_getenv.sh \
sndrcv.sh \
sndrcv_gzip.sh \
queue-persist.sh \
@@ -95,6 +96,8 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \
killrsyslog.sh \
parsertest.sh \
fieldtest.sh \
+ rsf_getenv.sh \
+ testsuites/rsf_getenv.conf \
diskqueue.sh \
testsuites/diskqueue.conf \
diskqueue-fsync.sh \
diff --git a/tests/diag.sh b/tests/diag.sh
index f3d75a15..3198d7d4 100755
--- a/tests/diag.sh
+++ b/tests/diag.sh
@@ -9,7 +9,7 @@
#valgrind="valgrind --tool=drd --log-fd=1"
#valgrind="valgrind --tool=helgrind --log-fd=1"
#set -o xtrace
-#export RSYSLOG_DEBUG="debug nostdout printmutexaction"
+#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction"
#export RSYSLOG_DEBUGLOG="log"
case $1 in
'init') $srcdir/killrsyslog.sh # kill rsyslogd if it runs for some reason
diff --git a/tests/rsf_getenv.sh b/tests/rsf_getenv.sh
new file mode 100755
index 00000000..42de20fe
--- /dev/null
+++ b/tests/rsf_getenv.sh
@@ -0,0 +1,17 @@
+# Test for the getenv() rainerscript function
+# this is a quick test, but it gurantees that the code path is
+# at least progressed (but we do not check for unset envvars!)
+# added 2009-11-03 by Rgerhards
+# This file is part of the rsyslog project, released under GPLv3
+# uncomment for debugging support:
+echo ===============================================================================
+echo \[rsf_getenv.sh\]: testing RainerScript getenv\(\) function
+export MSGNUM="msgnum:"
+source $srcdir/diag.sh init
+source $srcdir/diag.sh startup rsf_getenv.conf
+source $srcdir/diag.sh tcpflood 127.0.0.1 13514 1 10000
+source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages
+source $srcdir/diag.sh wait-shutdown
+source $srcdir/diag.sh seq-check 0 9999
+unset MSGNUM
+source $srcdir/diag.sh exit
diff --git a/tests/testsuites/rsf_getenv.conf b/tests/testsuites/rsf_getenv.conf
new file mode 100644
index 00000000..2f2eb58c
--- /dev/null
+++ b/tests/testsuites/rsf_getenv.conf
@@ -0,0 +1,17 @@
+# Test for RainerScript getenv() function (see .sh file for details)
+# Note envvar MSGNUM must be set to "msgnum:"
+# rgerhards, 2009-11-03
+$IncludeConfig diag-common.conf
+
+$ModLoad ../plugins/imtcp/.libs/imtcp
+$MainMsgQueueTimeoutShutdown 10000
+$InputTCPServerRun 13514
+
+# set spool locations and switch queue to disk-only mode
+$WorkDirectory test-spool
+$MainMsgQueueFilename mainq
+$MainMsgQueueType disk
+
+$template outfmt,"%msg:F,58:2%\n"
+$template dynfile,"rsyslog.out.log" # trick to use relative path names!
+if $msg contains getenv('MSGNUM') then ?dynfile;outfmt
diff --git a/tools/omfile.c b/tools/omfile.c
index db49a05c..efdaead4 100644
--- a/tools/omfile.c
+++ b/tools/omfile.c
@@ -87,11 +87,13 @@ typedef struct s_dynaFileCacheEntry dynaFileCacheEntry;
#define IOBUF_DFLT_SIZE 1024 /* default size for io buffers */
#define FLUSH_INTRVL_DFLT 1 /* default buffer flush interval (in seconds) */
+#define DFLT_bForceChown 0
/* globals for default values */
static int iDynaFileCacheSize = 10; /* max cache for dynamic files */
static int fCreateMode = 0644; /* mode to use when creating files */
static int fDirCreateMode = 0700; /* mode to use when creating files */
static int bFailOnChown; /* fail if chown fails? */
+static int bForceChown = DFLT_bForceChown; /* Force chown() on existing files? */
static uid_t fileUID; /* UID to be used for newly created files */
static uid_t fileGID; /* GID to be used for newly created files */
static uid_t dirUID; /* UID to be used for newly created directories */
@@ -115,6 +117,7 @@ typedef struct _instanceData {
int fDirCreateMode; /* creation mode for mkdir() */
int bCreateDirs; /* auto-create directories? */
int bSyncFile; /* should the file by sync()'ed? 1- yes, 0- no */
+ bool bForceChown; /* force chown() on existing files? */
uid_t fileUID; /* IDs for creation */
uid_t dirUID;
gid_t fileGID;
@@ -152,6 +155,7 @@ CODESTARTdbgPrintInstInfo
"\tcreate directories: %s\n"
"\tfile owner %d, group %d\n"
"\tdirectory owner %d, group %d\n"
+ "\tforce chown() for all files: %s\n"
"\tdir create mode 0%3.3o, file create mode 0%3.3o\n"
"\tfail if owner/group can not be set: %s\n",
pData->f_fname,
@@ -159,6 +163,7 @@ CODESTARTdbgPrintInstInfo
pData->bCreateDirs ? "yes" : "no",
pData->fileUID, pData->fileGID,
pData->dirUID, pData->dirGID,
+ pData->bForceChown ? "yes" : "no",
pData->fDirCreateMode, pData->fCreateMode,
pData->bFailOnChown ? "yes" : "no"
);
@@ -348,7 +353,22 @@ prepareFile(instanceData *pData, uchar *newFileName)
int fd;
DEFiRet;
- if(access((char*)newFileName, F_OK) != 0) {
+ if(access((char*)newFileName, F_OK) == 0) {
+ if(pData->bForceChown) {
+ /* Try to fix wrong ownership set by someone else. Note that this code
+ * will no longer work once we have made the $PrivDrop code fully secure.
+ * This change is based on an idea of Michael Terry, provided as part of
+ * the effort to make rsyslogd the Ubuntu default syslogd.
+ * rgerhards, 2009-09-11
+ */
+ if(chown((char*)newFileName, pData->fileUID, pData->fileGID) != 0) {
+ if(pData->bFailOnChown) {
+ int eSave = errno;
+ errno = eSave;
+ }
+ }
+ }
+ } else {
/* file does not exist, create it (and eventually parent directories */
fd = -1;
if(pData->bCreateDirs) {
@@ -369,7 +389,7 @@ prepareFile(instanceData *pData, uchar *newFileName)
pData->fCreateMode);
if(fd != -1) {
/* check and set uid/gid */
- if(pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) {
+ if(pData->bForceChown || pData->fileUID != (uid_t)-1 || pData->fileGID != (gid_t) -1) {
/* we need to set owner/group */
if(fchown(fd, pData->fileUID, pData->fileGID) != 0) {
if(pData->bFailOnChown) {
@@ -694,6 +714,7 @@ CODESTARTparseSelectorAct
pData->fDirCreateMode = fDirCreateMode;
pData->bCreateDirs = bCreateDirs;
pData->bFailOnChown = bFailOnChown;
+ pData->bForceChown = bForceChown;
pData->fileUID = fileUID;
pData->fileGID = fileGID;
pData->dirUID = dirUID;
@@ -728,6 +749,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
dirUID = -1;
dirGID = -1;
bFailOnChown = 1;
+ bForceChown = DFLT_bForceChown;
iDynaFileCacheSize = 10;
fCreateMode = 0644;
fDirCreateMode = 0700;
@@ -794,6 +816,7 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(omsdRegCFSLineHdlr((uchar *)"filecreatemode", 0, eCmdHdlrFileCreateMode, NULL, &fCreateMode, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"createdirs", 0, eCmdHdlrBinary, NULL, &bCreateDirs, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"failonchownfailure", 0, eCmdHdlrBinary, NULL, &bFailOnChown, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"omfileForceChown", 0, eCmdHdlrBinary, NULL, &bForceChown, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"actionfileenablesync", 0, eCmdHdlrBinary, NULL, &bEnableSync, STD_LOADABLE_MODULE_ID));
CHKiRet(regCfSysLineHdlr((uchar *)"actionfiledefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
diff --git a/tools/syslogd.c b/tools/syslogd.c
index ab8f015d..8fcb8dd0 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -249,11 +249,14 @@ int bDropTrailingLF = 1; /* drop trailing LF's on reception? */
int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sysklogd. It is
the default, so if no -c<n> option is given, we make ourselvs
as compatible to sysklogd as possible. */
+#define DFLT_bLogStatusMsgs 1
+static int bLogStatusMsgs = DFLT_bLogStatusMsgs; /* log rsyslog start/stop/HUP messages? */
static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */
static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */
static int bDebugPrintModuleList = 1;/* output module list in debug mode? */
-uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */
+uchar cCCEscapeChar = '#';/* character to be used to start an escape sequence for control chars */
int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */
+int bEscapeTab = 1; /* treat tab as escape control character: 0 - no, 1 - yes */
static int bErrMsgToStderr = 1; /* print error messages to stderr (in addition to everything else)? */
int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */
int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */
@@ -332,12 +335,14 @@ getFIOPName(unsigned iFIOP)
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
cCCEscapeChar = '#';
+ bLogStatusMsgs = DFLT_bLogStatusMsgs;
bActExecWhenPrevSusp = 0;
iActExecOnceInterval = 0;
bDebugPrintTemplateList = 1;
bDebugPrintCfSysLineHandlerList = 1;
bDebugPrintModuleList = 1;
bEscapeCCOnRcv = 1; /* default is to escape control characters */
+ bEscapeTab = 1;
bReduceRepeatMsgs = 0;
free(pszMainMsgQFName);
pszMainMsgQFName = NULL;
@@ -804,7 +809,7 @@ parseAndSubmitMessage(uchar *hname, uchar *hnameIP, uchar *msg, int len, int fla
/* log an error? Very questionable... rgerhards, 2006-11-30 */
/* decided: we do not log an error, it won't help... rger, 2007-06-21 */
++pData;
- } else if(bEscapeCCOnRcv && iscntrl((int) *pData)) {
+ } else if(bEscapeCCOnRcv && iscntrl((int) *pData) && (*pData != '\t' || bEscapeTab)) {
/* we are configured to escape control characters. Please note
* that this most probably break non-western character sets like
* Japanese, Korean or Chinese. rgerhards, 2007-07-17
@@ -901,7 +906,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags)
* permits us to process unmodified config files which otherwise contain a
* supressor statement.
*/
- if(((Debug || NoFork) && bErrMsgToStderr) || iConfigVerify) {
+ if(((Debug == DEBUG_FULL || NoFork) && bErrMsgToStderr) || iConfigVerify) {
if(LOG_PRI(pri) == LOG_ERR)
fprintf(stderr, "rsyslogd: %s\n", msg);
}
@@ -1194,8 +1199,7 @@ int parseLegacySyslogMsg(msg_t *pMsg, int flags)
assert(pMsg != NULL);
assert(pMsg->pszRawMsg != NULL);
lenMsg = pMsg->iLenRawMsg - (pMsg->offAfterPRI + 1);
-RUNLOG_VAR("%d", pMsg->offAfterPRI);
-RUNLOG_VAR("%d", lenMsg);
+
p2parse = pMsg->pszRawMsg + pMsg->offAfterPRI; /* point to start of text, after PRI */
/* Check to see if msg contains a timestamp. We start by assuming
@@ -1641,10 +1645,10 @@ static void doDie(int sig)
# define MSG1 "DoDie called.\n"
# define MSG2 "DoDie called 5 times - unconditional exit\n"
static int iRetries = 0; /* debug aid */
- if(Debug)
+ if(Debug == DEBUG_FULL)
write(1, MSG1, sizeof(MSG1) - 1);
if(iRetries++ == 4) {
- if(Debug)
+ if(Debug == DEBUG_FULL)
write(1, MSG2, sizeof(MSG2) - 1);
abort();
}
@@ -1710,7 +1714,7 @@ die(int sig)
thrdTerminateAll();
/* and THEN send the termination log message (see long comment above) */
- if (sig) {
+ if(sig && bLogStatusMsgs) {
(void) snprintf(buf, sizeof(buf) / sizeof(char),
" [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \
"\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.",
@@ -1831,6 +1835,9 @@ static rsRetVal setMaxFiles(void __attribute__((unused)) *pVal, int iFiles)
iFiles, errStr, (long) maxFiles.rlim_max);
ABORT_FINALIZE(RS_RET_ERR_RLIM_NOFILE);
}
+#ifdef USE_UNLIMITED_SELECT
+ glbl.SetFdSetSize(howmany(iFiles, __NFDBITS) * sizeof (fd_mask));
+#endif
DBGPRINTF("Max number of files set to %d [kernel max %ld].\n", iFiles, (long) maxFiles.rlim_max);
finalize_it:
@@ -2404,11 +2411,13 @@ init()
/* we now generate the startup message. It now includes everything to
* identify this instance. -- rgerhards, 2005-08-17
*/
- snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char),
- " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \
- "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] (re)start",
- (int) myPid);
- logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0);
+ if(bLogStatusMsgs) {
+ snprintf(bufStartUpMsg, sizeof(bufStartUpMsg)/sizeof(char),
+ " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \
+ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] (re)start",
+ (int) myPid);
+ logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, 0);
+ }
memset(&sigAct, 0, sizeof (sigAct));
sigemptyset(&sigAct.sa_mask);
@@ -2557,12 +2566,14 @@ doHUP(void)
{
char buf[512];
- snprintf(buf, sizeof(buf) / sizeof(char),
- " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION
- "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed, type '%s'.",
- (int) myPid, glbl.GetHUPisRestart() ? "restart" : "lightweight");
- errno = 0;
- logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0);
+ if(bLogStatusMsgs) {
+ snprintf(buf, sizeof(buf) / sizeof(char),
+ " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION
+ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] rsyslogd was HUPed, type '%s'.",
+ (int) myPid, glbl.GetHUPisRestart() ? "restart" : "lightweight");
+ errno = 0;
+ logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0);
+ }
if(glbl.GetHUPisRestart()) {
DBGPRINTF("Received SIGHUP, configured to be restart, reloading rsyslogd.\n");
@@ -2683,6 +2694,7 @@ static rsRetVal loadBuildInModules(void)
* is that rsyslog will terminate if we can not register our built-in config commands.
* This, I think, is the right thing to do. -- rgerhards, 2007-07-31
*/
+ CHKiRet(regCfSysLineHdlr((uchar *)"logrsyslogstatusmessages", 0, eCmdHdlrBinary, NULL, &bLogStatusMsgs, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"defaultruleset", 0, eCmdHdlrGetWord, setDefaultRuleset, NULL, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"ruleset", 0, eCmdHdlrGetWord, setCurrRuleset, NULL, NULL));
@@ -2713,6 +2725,7 @@ static rsRetVal loadBuildInModules(void)
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactertab", 0, eCmdHdlrBinary, NULL, &bEscapeTab, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL));
@@ -2870,7 +2883,7 @@ static rsRetVal mainThread()
* is still in its infancy (and not really done), we currently accept this issue.
* rgerhards, 2009-06-29
*/
- if(!(Debug || NoFork)) {
+ if(!(Debug == DEBUG_FULL || NoFork)) {
close(1);
close(2);
bErrMsgToStderr = 0;
@@ -3061,7 +3074,7 @@ doGlblProcessInit(void)
thrdInit();
- if( !(Debug || NoFork) )
+ if( !(Debug == DEBUG_FULL || NoFork) )
{
DBGPRINTF("Checking pidfile.\n");
if (!check_pid(PidFile))