summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-04-23 14:51:34 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-04-23 14:51:34 +0200
commit2eea95f626badb5a93ff7eca97cc68e5d2f3940a (patch)
treec7467c2ace398cda5d39e0f6fbda07e38fdc8e5c
parent7d8ac48a4a214da917f7455f24b4c292c3e6d015 (diff)
parent9b06a4c26422b0a8727e1b3c6cc7141226186105 (diff)
downloadrsyslog-2eea95f626badb5a93ff7eca97cc68e5d2f3940a.tar.gz
rsyslog-2eea95f626badb5a93ff7eca97cc68e5d2f3940a.tar.xz
rsyslog-2eea95f626badb5a93ff7eca97cc68e5d2f3940a.zip
Merge branch 'master' into master-elasticsearch
Conflicts: plugins/omelasticsearch/omelasticsearch.c
-rw-r--r--ChangeLog75
-rw-r--r--configure.ac2
-rw-r--r--doc/imklog.html5
-rw-r--r--doc/imptcp.html6
-rw-r--r--doc/imtcp.html6
-rw-r--r--doc/imuxsock.html11
-rw-r--r--doc/manual.html11
-rw-r--r--doc/property_replacer.html34
-rw-r--r--doc/rsyslog_conf_global.html26
-rw-r--r--doc/v5compatibility.html6
-rw-r--r--doc/version_naming.html4
-rw-r--r--plugins/imdiag/imdiag.c3
-rw-r--r--plugins/imgssapi/imgssapi.c2
-rw-r--r--plugins/imklog/imklog.c5
-rw-r--r--plugins/impstats/impstats.c8
-rw-r--r--plugins/imptcp/imptcp.c22
-rw-r--r--plugins/imtcp/imtcp.c10
-rw-r--r--plugins/imudp/imudp.c5
-rw-r--r--plugins/imuxsock/imuxsock.c25
-rw-r--r--plugins/omelasticsearch/omelasticsearch.c1
-rw-r--r--runtime/cfsysline.c69
-rw-r--r--runtime/errmsg.c4
-rw-r--r--runtime/glbl.c214
-rw-r--r--runtime/glbl.h34
-rw-r--r--runtime/msg.c172
-rw-r--r--runtime/net.c52
-rw-r--r--runtime/net.h6
-rw-r--r--runtime/queue.c13
-rw-r--r--runtime/queue.h1
-rw-r--r--runtime/rsyslog.h1
-rw-r--r--runtime/ruleset.c15
-rw-r--r--runtime/ruleset.h16
-rw-r--r--tcps_sess.c4
-rw-r--r--tcps_sess.h3
-rw-r--r--tcpsrv.c8
-rw-r--r--tcpsrv.h6
-rw-r--r--template.c73
-rw-r--r--template.h4
-rw-r--r--tools/syslogd.c179
39 files changed, 825 insertions, 316 deletions
diff --git a/ChangeLog b/ChangeLog
index 4e2d0468..e22967e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,17 @@
---------------------------------------------------------------------------
-Version 6.3.8 [DEVEL] 2012-02-??
-- added $PStatsJSON directive to permit stats records in JSON format
+Version 6.3.9 [DEVEL] 2012-04-??
+- added the "jsonf" property replacer option (and fieldname)
+- bugfix: property replacer option "json" could lead to content loss
+ message was truncated if escaping was necessary
+- bugfix: assigned ruleset was lost when using disk queues
+ This looked quite hard to diagnose for disk-assisted queues, as the
+ pure memory part worked well, but ruleset info was lost for messages
+ stored inside the disk queue.
+- bugfix/imuxsock: solving abort if hostname was not set; configured
+ hostname was not used (both merge regressions)
+---------------------------------------------------------------------------
+Version 6.3.8 [DEVEL] 2012-04-16
+- added $PStatJSON directive to permit stats records in JSON format
- added "date-unixtimestamp" property replacer option to format as a
unix timestamp (seconds since epoch)
- added "json" property replacer option to support JSON encoding on a
@@ -12,6 +23,9 @@ Version 6.3.8 [DEVEL] 2012-02-??
- ommysql
- omlibdbi
- omsnmp
+- added configuration directives to customize queue light delay marks
+ $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both
+ specify number of messages starting at which a delay happens.
- added message property parsesuccess to indicate if the last run
higher-level parser could successfully parse the message or not
(see property replacer html doc for details)
@@ -20,6 +34,19 @@ Version 6.3.8 [DEVEL] 2012-02-??
- bugfix: property $!all-json made rsyslog abort if no normalized data
was available
- bugfix: memory leak in array passing output module mode
+- added configuration directives to customize queue light delay marks
+- permit size modifiers (k,m,g,...) in integer config parameters
+ Thanks to Jo Rhett for the suggestion.
+- bugfix: hostname was not requeried on HUP
+ Thanks to Per Jessen for reporting this bug and Marius Tomaschewski for
+ his help in testing the fix.
+- bugfix: imklog invalidly computed facility and severity
+ closes: http://bugzilla.adiscon.com/show_bug.cgi?id=313
+- added configuration directive to disable octet-counted framing
+ for imtcp, directive is $InputTCPServerSupportOctetCountedFraming
+ for imptcp, directive is $InputPTCPServerSupportOctetCountedFraming
+- added capability to use a local interface IP address as fromhost-ip for
+ locally originating messages. New directive $LocalHostIPIF
---------------------------------------------------------------------------
Version 6.3.7 [DEVEL] 2012-02-02
- imported refactored v5.9.6 imklog linux driver, now combined with BSD
@@ -369,6 +396,26 @@ expected that interfaces, even new ones, break during the initial
syslog plain tcp input plugin (NOT supporting TLS!)
[ported from v4]
---------------------------------------------------------------------------
+Version 5.9.6 [V5-BETA], 2012-04-12
+- added configuration directives to customize queue light delay marks
+- permit size modifiers (k,m,g,...) in integer config parameters
+ Thanks to Jo Rhett for the suggestion.
+- bugfix: hostname was not requeried on HUP
+ Thanks to Per Jessen for reporting this bug and Marius Tomaschewski for
+ his help in testing the fix.
+- bugfix: imklog invalidly computed facility and severity
+ closes: http://bugzilla.adiscon.com/show_bug.cgi?id=313
+- bugfix: imptcp input name could not be set
+ config directive was accepted, but had no effect
+- added configuration directive to disable octet-counted framing
+ for imtcp, directive is $InputTCPServerSupportOctetCountedFraming
+ for imptcp, directive is $InputPTCPServerSupportOctetCountedFraming
+- added capability to use a local interface IP address as fromhost-ip for
+ locally originating messages. New directive $LocalHostIPIF
+- added configuration directives to customize queue light delay marks
+ $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both
+ specify number of messages starting at which a delay happens.
+---------------------------------------------------------------------------
Version 5.9.5 [V5-DEVEL], 2012-01-27
- improved impstats subsystem, added many new counters
- enhanced module loader to not rely on PATH_MAX
@@ -484,7 +531,23 @@ Version 5.9.0 [V5-DEVEL] (rgerhards), 2011-06-08
affected directive was: $ActionExecOnlyWhenPreviousIsSuspended on
closes: http://bugzilla.adiscon.com/show_bug.cgi?id=236
---------------------------------------------------------------------------
-Version 5.8.10 [V5-stable] 2012-??-??
+Version 5.8.11 [V5-stable] 2012-04-??
+- bugfix: imptcp input name could not be set
+ config directive was accepted, but had no effect
+- bugfix: assigned ruleset was lost when using disk queues
+ This looked quite hard to diagnose for disk-assisted queues, as the
+ pure memory part worked well, but ruleset info was lost for messages
+ stored inside the disk queue.
+- bugfix: hostname was not requeried on HUP
+ Thanks to Per Jessen for reporting this bug and Marius Tomaschewski for
+ his help in testing the fix.
+---------------------------------------------------------------------------
+Version 5.8.10 [V5-stable] 2012-04-05
+- bugfix: segfault on startup if $actionqueuefilename was missing for disk
+ queue config
+ Thanks to Tomas Heinrich for the patch.
+- bugfix: segfault if disk-queue was started up with old queue file
+ Thanks to Tomas Heinrich for the patch.
- bugfix: memory leak in array passing output module mode
---------------------------------------------------------------------------
Version 5.8.9 [V5-stable] 2012-03-15
@@ -497,6 +560,12 @@ Version 5.8.9 [V5-stable] 2012-03-15
stats subsystem.
---------------------------------------------------------------------------
Version 5.8.8 [V5-stable] 2012-03-05
+- added capability to use a local interface IP address as fromhost-ip for
+ imuxsock imklog
+ new config directives: $IMUXSockLocalIPIF, $klogLocalIPIF
+- added configuration directives to customize queue light delay marks
+ $MainMsgQueueLightDelayMark, $ActionQueueLightDelayMark; both
+ specify number of messages starting at which a delay happens.
- bugfix: omprog made rsyslog abort on startup if not binary to
execute was configured
- bugfix: imklog invalidly computed facility and severity
diff --git a/configure.ac b/configure.ac
index 8642da2f..94d43d85 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],[6.3.7-tmp1],[rsyslog@lists.adiscon.com])
+AC_INIT([rsyslog],[6.3.8],[rsyslog@lists.adiscon.com])
AM_INIT_AUTOMAKE
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
diff --git a/doc/imklog.html b/doc/imklog.html
index f273753f..2e3b3bc2 100644
--- a/doc/imklog.html
+++ b/doc/imklog.html
@@ -36,6 +36,11 @@ processing.<span style="font-weight: bold;"></span></li>
<li><span style="font-weight: bold;"></span>$DebugPrintKernelSymbols
[on/<b>off</b>]<br>
Linux only, ignored on other platforms (but may be specified)</li>
+<li><b>$klogLocalIPIF</b> [interface name] - (available since 5.9.6) - if provided, the IP of the specified
+interface (e.g. "eth0") shall be used as fromhost-ip for imklog-originating messages.
+If this directive is not given OR the interface cannot be found (or has no IP address),
+the default of "127.0.0.1" is used.
+</li>
<li>$klogSymbolLookup [on/<b>off</b>] --
disables imklog kernel symbol translation (former klogd -x option). NOTE that
this option is counter-productive on recent kernels (>= 2.6) because the
diff --git a/doc/imptcp.html b/doc/imptcp.html
index a4f43249..4307c603 100644
--- a/doc/imptcp.html
+++ b/doc/imptcp.html
@@ -43,6 +43,12 @@ very limited interest in fixing this issue. This directive <b>can not</b> fix th
That would require much more code changes, which I was unable to do so far. Full details
can be found at the <a href="http://www.rsyslog.com/Article321.phtml">Cisco tcp syslog anomaly</a>
page.
+<li><b>$InputPTCPSupportOctetCountedFraming</b> &lt;<b>on</b>|off&gt;<br>
+If set to "on", the legacy octed-counted framing (similar to RFC5425 framing) is
+activated. This is the default and should be left unchanged until you know
+very well what you do. It may be useful to turn it off, if you know this framing
+is not used and some senders emit multi-line messages into the message stream.
+</li>
<li>$InputPTCPServerNotifyOnConnectionClose [on/<b>off</b>]<br>
instructs imptcp to emit a message if the remote peer closes a connection.<br>
<li><b>$InputPTCPServerKeepAlive</b> &lt;on/<b>off</b>&gt;<br>
diff --git a/doc/imtcp.html b/doc/imtcp.html
index 7653f601..649b08f8 100644
--- a/doc/imtcp.html
+++ b/doc/imtcp.html
@@ -86,6 +86,12 @@ listener. &lt;id-string&gt; semantics depend on the currently selected
AuthMode and&nbsp; <a href="netstream.html">network stream driver</a>. PermittedPeers may not be set in anonymous modes.</li>
<li><b>$InputTCPServerBindRuleset</b> &lt;ruleset&gt;<br>
Binds the listener to a specific <a href="multi_ruleset.html">ruleset</a>.</li>
+<li><b>$InputTCPSupportOctetCountedFraming</b> &lt;<b>on</b>|off&gt;<br>
+If set to "on", the legacy octed-counted framing (similar to RFC5425 framing) is
+activated. This is the default and should be left unchanged until you know
+very well what you do. It may be useful to turn it off, if you know this framing
+is not used and some senders emit multi-line messages into the message stream.
+</li>
</ul>
<b>Caveats/Known Bugs:</b>
<ul>
diff --git a/doc/imuxsock.html b/doc/imuxsock.html
index 734ae889..34a696d9 100644
--- a/doc/imuxsock.html
+++ b/doc/imuxsock.html
@@ -76,6 +76,11 @@ burst in number of messages. Default is 200.
<li><b>$IMUXSockRateLimitSeverity</b> [numerical severity] - specifies the severity of
messages that shall be rate-limited.
</li>
+<li><b>$IMUXSockLocalIPIF</b> [interface name] - (available since 5.9.6) - if provided, the IP of the specified
+interface (e.g. "eth0") shall be used as fromhost-ip for imuxsock-originating messages.
+If this directive is not given OR the interface cannot be found (or has no IP address),
+the default of "127.0.0.1" is used.
+</li>
<li><b>$InputUnixListenSocketUsePIDFromSystem</b> [on/<b>off</b>] - specifies if the pid being logged shall
be obtained from the log socket itself. If so, the TAG part of the message is rewritten.
It is recommended to turn this option on, but the default is "off" to keep compatible
@@ -181,8 +186,10 @@ $SystemLogSocketAnnotate on
<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; 2008-2011 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-2012 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/manual.html b/doc/manual.html
index 565b3758..8f74e806 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 6.3.7 (devel branch) of rsyslog.</b>
+<p><b>This documentation is for version 6.3.8 (devel branch) of rsyslog.</b>
Visit the <i><a href="http://www.rsyslog.com/status">rsyslog status page</a></i></b>
to obtain current version information and project status.
</p><p><b>If you like rsyslog, you might
@@ -49,8 +49,9 @@ if you do not read the doc, but doing so will definitely improve your experience
<li><a href="generic_design.html">backgrounder on generic syslog application design</a></li>
<li><a href="modules.html">description of rsyslog modules</a></li>
<li><a href="rsyslog_packages.html">rsyslog packages</a></li>
-<li><a href="http://cookbook.rsyslog.com">the rsyslog "cookbook"</a> - a set of configurations ready to use</li>
</ul>
+<p><b>To keep current on rsyslog development, follow
+<a href="http://twitter.com/rgerhards">Rainer's twitter feed</a>.</b></p>
<p><b>We have some in-depth papers on</b></p>
<ul>
<li><a href="install.html">installing rsyslog</a></li>
@@ -106,14 +107,16 @@ online documentation (most current version only)</a></li>
mailing list</a>. If you are interested in the "backstage", you
may find
<a href="http://www.gerhards.net/rainer">Rainer</a>'s
-<a href="http://rgerhards.blogspot.com/">blog</a> an
+<a href="http://blog.gerhards.net/">blog</a> an
interesting read (filter on syslog and rsyslog tags).
+Or meet <a href="http://www.facebook.com/people/Rainer-Gerhards/1349393098">Rainer Gerhards at Facebook</a>
+or <a href="https://plus.google.com/112402185904751517878/posts">Google+</a>.
If you would like to use rsyslog source code inside your open source project, you can do that without
any restriction as long as your license is GPLv3 compatible. If your license is incompatible to GPLv3,
you may even be still permitted to use rsyslog source code. However, then you need to look at the way
<a href="licensing.html">rsyslog is licensed</a>.</p>
<p>Feedback is always welcome, but if you have a support question, please do not
mail Rainer directly (<a href="free_support.html">why not?</a>) - use the
-<a href="http://lists.adiscon.net/mailman/listinfo/rsyslog">rsyslogmailing list</a>
+<a href="http://lists.adiscon.net/mailman/listinfo/rsyslog">rsyslog mailing list</a>
or <a href="http://kb.monitorware.com/rsyslog-f40.html">rsyslog formum</a> instead.
</body></html>
diff --git a/doc/property_replacer.html b/doc/property_replacer.html
index 3af56182..5ee1d096 100644
--- a/doc/property_replacer.html
+++ b/doc/property_replacer.html
@@ -13,7 +13,7 @@ the value, e.g. by converting all characters to lower case.</p>
<p>Syslog message properties are used inside templates. They are
accessed by putting them between percent signs. Properties can be
modified by the property replacer. The full syntax is as follows:</p>
-<blockquote><b><code>%propname:fromChar:toChar:options%</code></b></blockquote>
+<blockquote><b><code>%propname:fromChar:toChar:options:fieldname%</code></b></blockquote>
<h2>Available Properties</h2>
<p><b><code>propname</code></b> is the
name of the property to access. It is case-insensitive (prior to 3.17.0, they were case-senstive).
@@ -179,6 +179,10 @@ than messages generated somewhere.
in templates for RFC5424 support, when the character set is know to be
Unicode.</td>
</tr>
+<td><b>$uptime</b></td>
+<td>system-uptime in seconds (as reported by operating system).
+</td>
+</tr>
<tr>
<td><b>$now</b></td>
<td>The current date stamp in the format YYYY-MM-DD</td>
@@ -345,7 +349,24 @@ case-insensitive. Currently, the following options are defined:
<td><b>json</b></td>
<td>encode the value so that it can be used inside a JSON field. This means
that several characters (according to the JSON spec) are being escaped, for
-example US-ASCII LF is replaced by "\n".</td>
+example US-ASCII LF is replaced by "\n".
+The json option cannot be used together with either jsonf or csv options.
+</td>
+</tr>
+<tr>
+<td><b>jsonf</b></td>
+<td><i>(available in 6.3.9+)</i>
+This signifies that the property should be expressed as a json <b>f</b>ield.
+That means not only the property is written, but rather a complete json field in
+the format<br>
+"fieldname"="value"</b>
+where "filedname" is the assigend field name (or the property name if none was assigned)
+and value is the end result of property replacer operation. Note that value supports
+all property replacer options, like substrings, case converson and the like.
+Values are properly json-escaped. However, field names are (currently) not. It is
+expected that proper field names are configured.
+The jsonf option cannot be used together with either json or csv options.
+</td>
</tr>
<tr>
<td valign="top"><b>csv</b></td>
@@ -356,6 +377,7 @@ text, you need to define a proper template. An example is this one:
<br>$template csvline,"%syslogtag:::csv%,%msg:::csv%"
<br>Most importantly, you need to provide the commas between the fields
inside the template.
+The csv option cannot be used together with either json or jsonf options.
<br><i>This feature was introduced in rsyslog 4.1.6.</i>
</td>
</tr>
@@ -461,13 +483,19 @@ Useful for secure pathname generation (with dynafiles).
them. For example "escape-cc,sp-if-no-1st-sp". If you use conflicting options together,
the last one will override the previous one. For example, using "escape-cc,drop-cc" will
use drop-cc and "drop-cc,escape-cc" will use escape-cc mode.
+<h2>Fieldname</h2>
+<p><i>(available in 6.3.9+)</i>
+<p>This field permits to specify a field name for structured-data emitting property replacer
+options. It was initially introduced to support the "jsonf" option, for which it provides
+the capability to set an alternative field name. If it is not specified, it defaults to
+the property name.
<h2>Further Links</h2>
<ul>
<li>Article on "<a href="rsyslog_recording_pri.html">Recording
the Priority of Syslog Messages</a>" (describes use of templates
to record severity and facility of a message)</li>
<li><a href="rsyslog_conf.html">Configuration file
-syntax</a>, this is where you actually use the property replacer.</li>
+format</a>, this is where you actually use the property replacer.</li>
</ul>
<p>[<a href="manual.html">manual index</a>]
[<a href="rsyslog_conf.html">rsyslog.conf</a>]
diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html
index b254f366..6c20f4c2 100644
--- a/doc/rsyslog_conf_global.html
+++ b/doc/rsyslog_conf_global.html
@@ -153,15 +153,6 @@ our paper on <a href="multi_ruleset.html">using multiple rule sets in rsyslog</a
<li><a href="rsconf1_gssforwardservicename.html">$GssForwardServiceName</a></li>
<li><a href="rsconf1_gsslistenservicename.html">$GssListenServiceName</a></li>
<li><a href="rsconf1_gssmode.html">$GssMode</a></li>
-<li>$HUPisRestart [on/<b>off</b>] - if set to on, a HUP is a full daemon restart. This means any queued messages are discarded (depending
-on queue configuration, of course) all modules are unloaded and reloaded. This mode keeps compatible with sysklogd, but is
-not recommended for use with rsyslog. To do a full restart, simply stop and start the daemon. The default (since 4.5.1) is "off".
-If it is set to "off", a HUP will only close open files. This is a much quicker action and usually
-the only one that is needed e.g. for log rotation. <b>Restart-type HUPs (value "on") are depricated</b>
-and will go away in rsyslog v5. So it is a good idea to change anything that needs it, now.
-Usually that should not be a big issue, as the restart-type HUP can easily be replaced by
-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>$LocalHostName</b> [name] - this directive permits to overwrite the system
hostname with the one specified in the directive. If the directive is given
@@ -302,9 +293,22 @@ the value, the less precise the timestamp.
<li><b>$Sleep</b> &lt;seconds&gt; - puts the rsyslog main thread to sleep for the specified
number of seconds immediately when the directive is encountered. You should have a
good reason for using this directive!</li>
+<li><b>$LocalHostIPIF</b> &lt;interface name&gt; - (available since 5.9.6) - if provided, the IP of the specified
+interface (e.g. "eth0") shall be used as fromhost-ip for locall-originating messages.
+If this directive is not given OR the interface cannot be found (or has no IP address),
+the default of "127.0.0.1" is used. Note that this directive can be given only
+once. Trying to reset will result in an error message and the new value will
+be ignored. Please note that modules must have support for obtaining the local
+IP address set via this directive. While this is the case for rsyslog-provided
+modules, it may not always be the case for contributed plugins.
+<br><b>Important:</b> This directive shall be placed <b>right at the top of
+rsyslog.conf</b>. Otherwise, if error messages are triggered before this directive
+is processed, rsyslog will fix the local host IP to "127.0.0.1", what than can
+not be reset.
+</li>
<li><a href="rsconf1_umask.html">$UMASK</a></li>
</ul>
-<p><b>Where &lt;size_nbr&gt; is specified above,</b>
+<p><b>Where &lt;size_nbr&gt; or integers are specified above,</b>
modifiers can be used after the number part. For example, 1k means
1024. Supported are k(ilo), m(ega), g(iga), t(era), p(eta) and e(xa).
Lower case letters refer to the traditional binary defintion (e.g. 1m
@@ -312,7 +316,7 @@ equals 1,048,576) whereas upper case letters refer to their new
1000-based definition (e.g 1M equals 1,000,000).</p>
<p>Numbers may include '.' and ',' for readability. So you can
for example specify either "1000" or "1,000" with the same result.
-Please note that rsyslogd simply ignores the punctuation. Form it's
+Please note that rsyslogd simply ignores the punctuation. From it's
point of view, "1,,0.0.,.,0" also has the value 1000. </p>
<p>[<a href="manual.html">manual index</a>]
diff --git a/doc/v5compatibility.html b/doc/v5compatibility.html
index 6d60062f..fc4289c5 100644
--- a/doc/v5compatibility.html
+++ b/doc/v5compatibility.html
@@ -16,6 +16,12 @@ available. This processing was redundant and had a lot a drawbacks.
For details, please see the
<a href="v4compatibility.html">rsyslog v4 compatibility notes</a> which elaborate
on the reasons and the (few) things you may need to change.
+<p>Please note that starting with 5.8.11 HUP will also requery the local hostname.
+<h2>Queue on-disk format</h2>
+<p>The queue information file format has been changed. When upgrading from v4 to
+v5, make sure that the queue is emptied and no on-disk structure present. We did
+not go great length in understanding the old format, as there was too little demand
+for that (and it being quite some effort if done right).
<h2>Queue Worker Thread Shutdown</h2>
<p>Previous rsyslog versions had the capability to &quot;run&quot; on zero queue worker
if no work was required. This was done to save a very limited number of resources. However,
diff --git a/doc/version_naming.html b/doc/version_naming.html
index 8c1b9187..3bfa19bb 100644
--- a/doc/version_naming.html
+++ b/doc/version_naming.html
@@ -105,7 +105,7 @@ versions. It applies to versions 1.0.0 and above. Versions below that
are all unstable and have a different naming schema.</p>
<p><b>Please note that version naming is currently being
changed. There is a
-<a href="http://rgerhards.blogspot.com/2007/08/on-rsyslog-versions.html">blog
+<a href="http://blog.gerhards.net/2007/08/on-rsyslog-versions.html">blog
post about future rsyslog versions</a>.</b></p>
<p>The major version is incremented whenever a considerate, major
features have been added. This is expected to happen quite infrequently.</p>
@@ -127,4 +127,4 @@ expected to happen quite infrequently.</p>
<p>In general, the unstable branch carries all new development.
Once it concludes with a sufficiently-enhanced, quite stable version, a
new major stable version is assigned.</p>
-</body></html> \ No newline at end of file
+</body></html>
diff --git a/plugins/imdiag/imdiag.c b/plugins/imdiag/imdiag.c
index 48573853..6ea615a1 100644
--- a/plugins/imdiag/imdiag.c
+++ b/plugins/imdiag/imdiag.c
@@ -381,7 +381,8 @@ static rsRetVal addTCPListener(void __attribute__((unused)) *pVal, uchar *pNewVa
/* initialized, now add socket */
CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, pszInputName == NULL ?
UCHAR_CONSTANT("imdiag") : pszInputName));
- tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal);
+ /* we support octect-cuunted frame (constant 1 below) */
+ tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal, 1);
finalize_it:
if(iRet != RS_RET_OK) {
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index 9668d1ac..4e3a70ab 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -340,7 +340,7 @@ addGSSListener(void __attribute__((unused)) *pVal, uchar *pNewVal)
CHKiRet(tcpsrv.SetCBOnRegularClose(pOurTcpsrv, onRegularClose));
CHKiRet(tcpsrv.SetCBOnErrClose(pOurTcpsrv, onErrClose));
CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, UCHAR_CONSTANT("imgssapi")));
- tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal);
+ tcpsrv.configureTCPListen(pOurTcpsrv, pNewVal, 1);
CHKiRet(tcpsrv.ConstructFinalize(pOurTcpsrv));
}
diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c
index 71cb9ac6..90b424f3 100644
--- a/plugins/imklog/imklog.c
+++ b/plugins/imklog/imklog.c
@@ -47,6 +47,7 @@
#include <stdarg.h>
#include <ctype.h>
#include <stdlib.h>
+#include <sys/socket.h>
#include "dirty.h"
#include "cfsysline.h"
@@ -55,6 +56,7 @@
#include "module-template.h"
#include "datetime.h"
#include "imklog.h"
+#include "net.h"
#include "glbl.h"
#include "prop.h"
#include "unicode-helper.h"
@@ -68,6 +70,7 @@ DEF_IMOD_STATIC_DATA
DEFobjCurrIf(datetime)
DEFobjCurrIf(glbl)
DEFobjCurrIf(prop)
+DEFobjCurrIf(net)
/* config settings */
typedef struct configSettings_s {
@@ -359,6 +362,7 @@ CODESTARTmodExit
/* release objects we used */
objRelease(glbl, CORE_COMPONENT);
+ objRelease(net, CORE_COMPONENT);
objRelease(datetime, CORE_COMPONENT);
objRelease(prop, CORE_COMPONENT);
ENDmodExit
@@ -394,6 +398,7 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(datetime, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(prop, CORE_COMPONENT));
+ CHKiRet(objUse(net, CORE_COMPONENT));
/* we need to create the inputName property (only once during our lifetime) */
CHKiRet(prop.CreateStringProp(&pInputName, UCHAR_CONSTANT("imklog"), sizeof("imklog") - 1));
diff --git a/plugins/impstats/impstats.c b/plugins/impstats/impstats.c
index dfca25da..4fec8e70 100644
--- a/plugins/impstats/impstats.c
+++ b/plugins/impstats/impstats.c
@@ -75,7 +75,6 @@ static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current lo
static configSettings_t cs;
static prop_t *pInputName = NULL;
-static prop_t *pLocalHostIP = NULL;
BEGINisCompatibleWithFeature
CODESTARTisCompatibleWithFeature
@@ -106,7 +105,7 @@ doSubmitMsg(uchar *line)
MsgSetRawMsgWOSize(pMsg, (char*)line);
MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp());
- MsgSetRcvFromIP(pMsg, pLocalHostIP);
+ MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP());
MsgSetMSGoffs(pMsg, 0);
MsgSetTAG(pMsg, UCHAR_CONSTANT("rsyslogd-pstats:"), sizeof("rsyslogd-pstats:") - 1);
pMsg->iFacility = runModConf->iFacility;
@@ -221,7 +220,6 @@ ENDafterRun
BEGINmodExit
CODESTARTmodExit
prop.Destruct(&pInputName);
- prop.Destruct(&pLocalHostIP);
/* release objects we used */
objRelease(glbl, CORE_COMPONENT);
objRelease(prop, CORE_COMPONENT);
@@ -266,10 +264,6 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(prop.Construct(&pInputName));
CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("impstats"), sizeof("impstats") - 1));
CHKiRet(prop.ConstructFinalize(pInputName));
-
- CHKiRet(prop.Construct(&pLocalHostIP));
- CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1));
- CHKiRet(prop.ConstructFinalize(pLocalHostIP));
ENDmodInit
/* vi:set ai:
*/
diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c
index ec6836c1..ba323a94 100644
--- a/plugins/imptcp/imptcp.c
+++ b/plugins/imptcp/imptcp.c
@@ -97,6 +97,7 @@ typedef struct configSettings_s {
int iKeepAliveProbes;
int iKeepAliveTime;
int bEmitMsgOnClose; /* emit an informational message on close by remote peer */
+ int bSuppOctetFram; /* support octet-counted framing? */
int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */
uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */
uchar *lstnIP; /* which IP we should listen on? */
@@ -111,6 +112,7 @@ struct instanceConf_s {
int iKeepAliveProbes;
int iKeepAliveTime;
int bEmitMsgOnClose;
+ int bSuppOctetFram; /* support octet-counted framing? */
int iAddtlFrameDelim;
uchar *pszBindPort; /* port to bind to */
uchar *pszBindAddr; /* IP to bind socket to */
@@ -157,6 +159,7 @@ struct ptcpsrv_s {
pthread_mutex_t mutSessLst;
sbool bKeepAlive; /* support keep-alive packets */
sbool bEmitMsgOnClose;
+ sbool bSuppOctetFram;
};
/* the ptcp session object. Describes a single active session.
@@ -171,6 +174,7 @@ struct ptcpsess_s {
//--- from tcps_sess.h
int iMsg; /* index of next char to store in msg */
int bAtStrtOfFram; /* are we at the very beginning of a new frame? */
+ sbool bSuppOctetFram; /**< copy from listener, to speed up access */
enum {
eAtStrtFram,
eInOctetCnt,
@@ -191,6 +195,7 @@ struct ptcplstn_s {
ptcpsrv_t *pSrv; /* our server */
ptcplstn_t *prev, *next;
int sock;
+ sbool bSuppOctetFram;
epolld_t *epd;
statsobj_t *stats; /* listener stats */
STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit)
@@ -325,7 +330,9 @@ startupSrv(ptcpsrv_t *pSrv)
continue;
}
#endif
- }
+ } else {
+ isIPv6 = 0;
+ }
if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0 ) {
DBGPRINTF("error %d setting tcp socket option\n", errno);
close(sock);
@@ -665,7 +672,7 @@ processDataRcvd(ptcpsess_t *pThis, char c, struct syslogTime *stTime, time_t ttG
DEFiRet;
if(pThis->inputState == eAtStrtFram) {
- if(isdigit((int) c)) {
+ if(pThis->bSuppOctetFram && isdigit((int) c)) {
pThis->inputState = eInOctetCnt;
pThis->iOctetsRemain = 0;
pThis->eFraming = TCP_FRAMING_OCTET_COUNTING;
@@ -805,6 +812,7 @@ initConfigSettings(void)
{
cs.bEmitMsgOnClose = 0;
cs.wrkrMax = 2;
+ cs.bSuppOctetFram = 1;
cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
cs.pszInputName = NULL;
cs.pszBindRuleset = NULL;
@@ -821,7 +829,7 @@ addEPollSock(epolld_type_t typ, void *ptr, int sock, epolld_t **pEpd)
DEFiRet;
epolld_t *epd = NULL;
- CHKmalloc(epd = malloc(sizeof(epolld_t)));
+ CHKmalloc(epd = calloc(sizeof(epolld_t), 1));
epd->typ = typ;
epd->ptr = ptr;
*pEpd = epd;
@@ -883,6 +891,7 @@ addLstn(ptcpsrv_t *pSrv, int sock, int isIPv6)
CHKmalloc(pLstn = malloc(sizeof(ptcplstn_t)));
pLstn->pSrv = pSrv;
+ pLstn->bSuppOctetFram = pSrv->bSuppOctetFram;
pLstn->sock = sock;
/* support statistics gathering */
CHKiRet(statsobj.Construct(&(pLstn->stats)));
@@ -891,6 +900,7 @@ addLstn(ptcpsrv_t *pSrv, int sock, int isIPv6)
isIPv6 ? "IPv6" : "IPv4");
statname[sizeof(statname)-1] = '\0'; /* just to be on the save side... */
CHKiRet(statsobj.SetName(pLstn->stats, statname));
+ STATSCOUNTER_INIT(pLstn->ctrSubmit, pLstn->mutCtrSubmit);
CHKiRet(statsobj.AddCounter(pLstn->stats, UCHAR_CONSTANT("submitted"),
ctrType_IntCtr, &(pLstn->ctrSubmit)));
CHKiRet(statsobj.ConstructFinalize(pLstn->stats));
@@ -922,6 +932,7 @@ addSess(ptcplstn_t *pLstn, int sock, prop_t *peerName, prop_t *peerIP)
CHKmalloc(pSess->pMsg = malloc(iMaxLine * sizeof(uchar)));
pSess->pLstn = pLstn;
pSess->sock = sock;
+ pSess->bSuppOctetFram = pLstn->bSuppOctetFram;
pSess->inputState = eAtStrtFram;
pSess->iMsg = 0;
pSess->bAtStrtOfFram = 1;
@@ -1013,6 +1024,7 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
CHKmalloc(inst->pszInputName = ustrdup(cs.pszInputName));
}
inst->pBindRuleset = NULL;
+ inst->bSuppOctetFram = cs.bSuppOctetFram;
inst->bKeepAlive = cs.bKeepAlive;
inst->iKeepAliveIntvl = cs.iKeepAliveTime;
inst->iKeepAliveProbes = cs.iKeepAliveProbes;
@@ -1045,6 +1057,7 @@ addListner(modConfData_t __attribute__((unused)) *modConf, instanceConf_t *inst)
pthread_mutex_init(&pSrv->mutSessLst, NULL);
pSrv->pSess = NULL;
pSrv->pLstn = NULL;
+ pSrv->bSuppOctetFram = inst->bSuppOctetFram;
pSrv->bKeepAlive = inst->bKeepAlive;
pSrv->iKeepAliveIntvl = inst->iKeepAliveTime;
pSrv->iKeepAliveProbes = inst->iKeepAliveProbes;
@@ -1530,6 +1543,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
cs.iKeepAliveProbes = 0;
cs.iKeepAliveTime = 0;
cs.iKeepAliveIntvl = 0;
+ cs.bSuppOctetFram = 1;
cs.iAddtlFrameDelim = TCPSRV_NO_ADDTL_DELIMITER;
free(cs.pszInputName);
cs.pszInputName = NULL;
@@ -1586,6 +1600,8 @@ CODEmodInit_QueryRegCFSLineHdlr
NULL, &cs.iKeepAliveTime, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserverkeepalive_intvl"), 0, eCmdHdlrInt,
NULL, &cs.iKeepAliveIntvl, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserversupportoctetcountedframing"), 0, eCmdHdlrBinary,
+ NULL, &cs.bSuppOctetFram, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpservernotifyonconnectionclose"), 0,
eCmdHdlrBinary, NULL, &cs.bEmitMsgOnClose, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputptcpserveraddtlframedelimiter"), 0, eCmdHdlrInt,
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index 15f9fa72..33404fee 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -88,6 +88,7 @@ static permittedPeers_t *pPermPeersRoot = NULL;
static struct configSettings_s {
int iTCPSessMax;
int iTCPLstnMax;
+ int bSuppOctetFram;
int iStrmDrvrMode;
int bKeepAlive;
int bEmitMsgOnClose;
@@ -104,6 +105,7 @@ struct instanceConf_s {
uchar *pszBindRuleset; /* name of ruleset to bind to */
ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */
uchar *pszInputName; /* value for inputname property, NULL is OK and handled by core engine */
+ int bSuppOctetFram;
struct instanceConf_s *next;
};
@@ -115,6 +117,7 @@ struct modConfData_s {
int iTCPLstnMax; /* max number of sessions */
int iStrmDrvrMode; /* mode for stream driver, driver-dependent (0 mostly means plain tcp) */
int iAddtlFrameDelim; /* addtl frame delimiter, e.g. for netscreen, default none */
+ int bSuppOctetFram;
sbool bDisableLFDelim; /* disable standard LF delimiter */
sbool bUseFlowControl; /* use flow control, what means indicate ourselfs a "light delayable" */
sbool bKeepAlive;
@@ -222,6 +225,7 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
} else {
CHKmalloc(inst->pszInputName = ustrdup(cs.pszInputName));
}
+ inst->bSuppOctetFram = cs.bSuppOctetFram;
inst->next = NULL;
/* node created, let's add to config */
@@ -274,7 +278,7 @@ addListner(modConfData_t *modConf, instanceConf_t *inst)
CHKiRet(tcpsrv.SetRuleset(pOurTcpsrv, inst->pBindRuleset));
CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, inst->pszInputName == NULL ?
UCHAR_CONSTANT("imtcp") : inst->pszInputName));
- tcpsrv.configureTCPListen(pOurTcpsrv, inst->pszBindPort);
+ tcpsrv.configureTCPListen(pOurTcpsrv, inst->pszBindPort, inst->bSuppOctetFram);
finalize_it:
if(iRet != RS_RET_OK) {
@@ -301,6 +305,7 @@ CODESTARTendCnfLoad
pModConf->iTCPLstnMax = cs.iTCPLstnMax;
pModConf->iStrmDrvrMode = cs.iStrmDrvrMode;
pModConf->bEmitMsgOnClose = cs.bEmitMsgOnClose;
+ pModConf->bSuppOctetFram = cs.bSuppOctetFram;
pModConf->iAddtlFrameDelim = cs.iAddtlFrameDelim;
pModConf->bDisableLFDelim = cs.bDisableLFDelim;
pModConf->bUseFlowControl = cs.bUseFlowControl;
@@ -417,6 +422,7 @@ resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unus
{
cs.iTCPSessMax = 200;
cs.iTCPLstnMax = 20;
+ cs.bSuppOctetFram = 1;
cs.iStrmDrvrMode = 0;
cs.bUseFlowControl = 0;
cs.bKeepAlive = 0;
@@ -459,6 +465,8 @@ CODEmodInit_QueryRegCFSLineHdlr
addInstance, NULL, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserverkeepalive"), 0, eCmdHdlrBinary,
NULL, &cs.bKeepAlive, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpserversupportoctetcountedframing"), 0, eCmdHdlrBinary,
+ NULL, &cs.bSuppOctetFram, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxsessions"), 0, eCmdHdlrInt,
NULL, &cs.iTCPSessMax, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr(UCHAR_CONSTANT("inputtcpmaxlisteners"), 0, eCmdHdlrInt,
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index 48cb2774..6abeab07 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -256,6 +256,7 @@ addListner(instanceConf_t *inst)
snprintf((char*)statname, sizeof(statname), "imudp(%s:%s)", bindName, port);
statname[sizeof(statname)-1] = '\0'; /* just to be on the save side... */
CHKiRet(statsobj.SetName(newlcnfinfo->stats, statname));
+ STATSCOUNTER_INIT(newlcnfinfo->ctrSubmit, newlcnfinfo->mutCtrSubmit);
CHKiRet(statsobj.AddCounter(newlcnfinfo->stats, UCHAR_CONSTANT("submitted"),
ctrType_IntCtr, &(newlcnfinfo->ctrSubmit)));
CHKiRet(statsobj.ConstructFinalize(newlcnfinfo->stats));
@@ -266,9 +267,11 @@ addListner(instanceConf_t *inst)
lcnfRoot = newlcnfinfo;
if(lcnfLast == NULL)
lcnfLast = newlcnfinfo;
- else
+ else {
lcnfLast->next = newlcnfinfo;
+ lcnfLast = newlcnfinfo;
#endif //>>>>>>> ef34821a2737799f48c3032b9616418e4f7fa34f
+ }
}
}
diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c
index 193cbb33..2d26e652 100644
--- a/plugins/imuxsock/imuxsock.c
+++ b/plugins/imuxsock/imuxsock.c
@@ -94,6 +94,7 @@ DEF_IMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
DEFobjCurrIf(glbl)
DEFobjCurrIf(prop)
+DEFobjCurrIf(net)
DEFobjCurrIf(parser)
DEFobjCurrIf(datetime)
DEFobjCurrIf(statsobj)
@@ -330,6 +331,7 @@ static rsRetVal addInstance(void __attribute__((unused)) *pVal, uchar *pNewVal)
CHKmalloc(inst = MALLOC(sizeof(instanceConf_t)));
inst->sockName = pNewVal;
inst->ratelimitInterval = cs.ratelimitInterval;
+ inst->pLogHostName = cs.pLogHostName;
inst->ratelimitBurst = cs.ratelimitBurst;
inst->ratelimitSeverity = cs.ratelimitSeverity;
inst->bUseFlowCtl = cs.bUseFlowCtl;
@@ -376,14 +378,13 @@ addListner(instanceConf_t *inst)
} else {
listeners[nfd].bParseHost = 0;
}
- CHKiRet(prop.Construct(&(listeners[nfd].hostName)));
if(inst->pLogHostName == NULL) {
- CHKiRet(prop.SetString(listeners[nfd].hostName, glbl.GetLocalHostName(),
- ustrlen(glbl.GetLocalHostName())));
+ listeners[nfd].hostName = NULL;
} else {
+ CHKiRet(prop.Construct(&(listeners[nfd].hostName)));
CHKiRet(prop.SetString(listeners[nfd].hostName, inst->pLogHostName, ustrlen(inst->pLogHostName)));
+ CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName));
}
- CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName));
if(inst->ratelimitInterval > 0) {
if((listeners[nfd].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) {
/* in this case, we simply turn off rate-limiting */
@@ -866,7 +867,7 @@ SubmitMsg(uchar *pRcv, int lenRcv, lstn_t *pLstn, struct ucred *cred, struct tim
pMsg->msgFlags = pLstn->flags;
}
- MsgSetRcvFrom(pMsg, pLstn->hostName);
+ MsgSetRcvFrom(pMsg, pLstn->hostName == NULL ? glbl.GetLocalHostNameProp() : pLstn->hostName);
CHKiRet(MsgSetRcvFromIP(pMsg, pLocalHostIP));
CHKiRet(submitMsg(pMsg));
@@ -1256,6 +1257,7 @@ CODESTARTmodInit
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(net, CORE_COMPONENT));
CHKiRet(objUse(prop, CORE_COMPONENT));
CHKiRet(objUse(statsobj, CORE_COMPONENT));
CHKiRet(objUse(datetime, CORE_COMPONENT));
@@ -1272,6 +1274,13 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imuxsock"), sizeof("imuxsock") - 1));
CHKiRet(prop.ConstructFinalize(pInputName));
+ /* right now, glbl does not permit per-instance IP address notation. As long as this
+ * is the case, it is OK to query the HostIP once here at this location. HOWEVER, the
+ * whole concept is not 100% clean and needs to be addressed on a higher layer.
+ * TODO / rgerhards, 2012-04-11
+ */
+ pLocalHostIP = glbl.GetLocalHostIP();
+
/* init system log socket settings */
listeners[0].flags = IGNDATE;
listeners[0].sockName = UCHAR_CONSTANT(_PATH_LOG);
@@ -1290,15 +1299,11 @@ CODEmodInit_QueryRegCFSLineHdlr
listeners[i].fd = -1;
}
+ /* now init listen socket zero, the local log socket */
CHKiRet(prop.Construct(&pLocalHostIP));
CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1));
CHKiRet(prop.ConstructFinalize(pLocalHostIP));
- /* now init listen socket zero, the local log socket */
- CHKiRet(prop.Construct(&(listeners[0].hostName)));
- CHKiRet(prop.SetString(listeners[0].hostName, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName())));
- CHKiRet(prop.ConstructFinalize(listeners[0].hostName));
-
/* register config file handlers */
CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary,
NULL, &cs.bOmitLocalLogging, STD_LOADABLE_MODULE_ID));
diff --git a/plugins/omelasticsearch/omelasticsearch.c b/plugins/omelasticsearch/omelasticsearch.c
index 0b2e0bf1..79a24ffe 100644
--- a/plugins/omelasticsearch/omelasticsearch.c
+++ b/plugins/omelasticsearch/omelasticsearch.c
@@ -29,7 +29,6 @@
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
-//#include <curl/types.h>
#include <curl/easy.h>
#include <assert.h>
#include <signal.h>
diff --git a/runtime/cfsysline.c b/runtime/cfsysline.c
index 7814e86a..af88b3de 100644
--- a/runtime/cfsysline.c
+++ b/runtime/cfsysline.c
@@ -155,36 +155,6 @@ finalize_it:
}
-/* Parse a number from the configuration line.
- * rgerhards, 2007-07-31
- */
-static rsRetVal doGetInt(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal)
-{
- uchar *p;
- DEFiRet;
- int64 i;
-
- assert(pp != NULL);
- assert(*pp != NULL);
-
- CHKiRet(parseIntVal(pp, &i));
- p = *pp;
-
- if(pSetHdlr == NULL) {
- /* we should set value directly to var */
- *((int*)pVal) = (int) i;
- } else {
- /* we set value via a set function */
- CHKiRet(pSetHdlr(pVal, (int) i));
- }
-
- *pp = p;
-
-finalize_it:
- RETiRet;
-}
-
-
/* Parse a size from the configuration line. This is basically an integer
* syntax, but modifiers may be added after the integer (e.g. 1k to mean
* 1024). The size must immediately follow the number. Note that the
@@ -238,7 +208,44 @@ finalize_it:
}
-/* Parse and interpet a $FileCreateMode and $umask line. This function
+/* Parse a number from the configuration line.
+ * rgerhards, 2007-07-31
+ */
+static rsRetVal doGetInt(uchar **pp, rsRetVal (*pSetHdlr)(void*, uid_t), void *pVal)
+{
+ uchar *p;
+ DEFiRet;
+ int64 i;
+ uchar errMsg[256]; /* for dynamic error messages */
+
+ assert(pp != NULL);
+ assert(*pp != NULL);
+
+ CHKiRet(doGetSize(pp, NULL,&i));
+ p = *pp;
+ if(i > 2147483648ll) { /*2^31*/
+ snprintf((char*) errMsg, sizeof(errMsg)/sizeof(uchar),
+ "value %lld too large for integer argument.", i);
+ errmsg.LogError(0, RS_RET_INVALID_VALUE, "%s", errMsg);
+ ABORT_FINALIZE(RS_RET_INVALID_VALUE);
+ }
+
+ if(pSetHdlr == NULL) {
+ /* we should set value directly to var */
+ *((int*)pVal) = (int) i;
+ } else {
+ /* we set value via a set function */
+ CHKiRet(pSetHdlr(pVal, (int) i));
+ }
+
+ *pp = p;
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* Parse and interpret a $FileCreateMode and $umask line. This function
* pulls the creation mode and, if successful, stores it
* into the global variable so that the rest of rsyslogd
* opens files with that mode. Any previous value will be
diff --git a/runtime/errmsg.c b/runtime/errmsg.c
index 06c553be..dcb5b185 100644
--- a/runtime/errmsg.c
+++ b/runtime/errmsg.c
@@ -83,13 +83,13 @@ LogError(int iErrno, int iErrCode, char *fmt, ... )
if(iErrno != 0) {
rs_strerror_r(iErrno, errStr, sizeof(errStr));
- if(iErrCode == NO_ERRCODE) {
+ if(iErrCode == NO_ERRCODE || iErrCode == RS_RET_ERR) {
snprintf(msg, sizeof(msg), "%s: %s", buf, errStr);
} else {
snprintf(msg, sizeof(msg), "%s: %s [try http://www.rsyslog.com/e/%d ]", buf, errStr, iErrCode * -1);
}
} else {
- if(iErrCode == NO_ERRCODE) {
+ if(iErrCode == NO_ERRCODE || iErrCode == RS_RET_ERR) {
snprintf(msg, sizeof(msg), "%s", buf);
} else {
snprintf(msg, sizeof(msg), "%s [try http://www.rsyslog.com/e/%d ]", buf, iErrCode * -1);
diff --git a/runtime/glbl.c b/runtime/glbl.c
index 885d8468..537b7b4f 100644
--- a/runtime/glbl.c
+++ b/runtime/glbl.c
@@ -11,21 +11,19 @@
*
* This file is part of the rsyslog runtime library.
*
- * The rsyslog runtime library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * The rsyslog runtime library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
#include "config.h"
@@ -45,6 +43,7 @@
#include "atomic.h"
#include "errmsg.h"
#include "rainerscript.h"
+#include "net.h"
/* some defaults */
#ifndef DFLT_NETSTRM_DRVR
@@ -55,6 +54,7 @@
DEFobjStaticHelpers
DEFobjCurrIf(prop)
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(net)
/* static data
* For this object, these variables are obviously what makes the "meat" of the
@@ -69,11 +69,12 @@ static int iDefPFFamily = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both)
static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
static int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */
static int bDisableDNS = 0; /* don't look up IP addresses of remote messages */
+static prop_t *propLocalIPIF = NULL;/* IP address to report for the local host (default is 127.0.0.1) */
static prop_t *propLocalHostName = NULL;/* our hostname as FQDN - read-only after startup */
-static uchar *LocalHostName = NULL;/* our hostname - read-only after startup */
+static uchar *LocalHostName = NULL;/* our hostname - read-only after startup, except HUP */
static uchar *LocalHostNameOverride = NULL;/* user-overridden hostname - read-only after startup */
-static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup */
-static uchar *LocalDomain; /* our local domain name - read-only after startup */
+static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup, except HUP */
+static uchar *LocalDomain = NULL;/* our local domain name - read-only after startup, except HUP */
static char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */
static char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */
static uchar *pszDfltNetstrmDrvr = NULL; /* module name of default netstream driver */
@@ -139,15 +140,12 @@ SIMP_PROP(DefPFFamily, iDefPFFamily, int) /* note that in the future we may chec
SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int)
SIMP_PROP(Option_DisallowWarning, option_DisallowWarning, int)
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*)
SIMP_PROP_SET(DfltNetstrmDrvr, pszDfltNetstrmDrvr, uchar*) /* TODO: use custom function which frees existing value */
SIMP_PROP_SET(DfltNetstrmDrvrCAF, pszDfltNetstrmDrvrCAF, uchar*) /* TODO: use custom function which frees existing value */
SIMP_PROP_SET(DfltNetstrmDrvrKeyFile, pszDfltNetstrmDrvrKeyFile, uchar*) /* TODO: use custom function which frees existing value */
@@ -176,6 +174,60 @@ static void SetGlobalInputTermination(void)
}
+/* set the local host IP address to a specific string. Helper to
+ * small set of functions. No checks done, caller must ensure it is
+ * ok to call. Most importantly, the IP address must not already have
+ * been set. -- rgerhards, 2012-03-21
+ */
+static inline rsRetVal
+storeLocalHostIPIF(uchar *myIP)
+{
+ DEFiRet;
+ CHKiRet(prop.Construct(&propLocalIPIF));
+ CHKiRet(prop.SetString(propLocalIPIF, myIP, ustrlen(myIP)));
+ CHKiRet(prop.ConstructFinalize(propLocalIPIF));
+ DBGPRINTF("rsyslog/glbl: using '%s' as localhost IP\n", myIP);
+finalize_it:
+ RETiRet;
+}
+
+
+/* This function is used to set the IP address that is to be
+ * reported for the local host. Note that in order to ease things
+ * for the v6 config interface, we do not allow to set this more
+ * than once.
+ * rgerhards, 2012-03-21
+ */
+static rsRetVal
+setLocalHostIPIF(void __attribute__((unused)) *pVal, uchar *pNewVal)
+{
+ uchar myIP[128];
+ rsRetVal localRet;
+ DEFiRet;
+
+ CHKiRet(objUse(net, CORE_COMPONENT));
+
+ if(propLocalIPIF != NULL) {
+ errmsg.LogError(0, RS_RET_ERR, "$LocalHostIPIF is already set "
+ "and cannot be reset; place it at TOP OF rsyslog.conf!");
+ ABORT_FINALIZE(RS_RET_ERR_WRKDIR);
+ }
+
+ localRet = net.GetIFIPAddr(pNewVal, AF_UNSPEC, myIP, (int) sizeof(myIP));
+ if(localRet != RS_RET_OK) {
+ errmsg.LogError(0, RS_RET_ERR, "$LocalHostIPIF: IP address for interface "
+ "'%s' cannnot be obtained - ignoring directive", pNewVal);
+ } else {
+ storeLocalHostIPIF(myIP);
+ }
+
+
+finalize_it:
+ free(pNewVal); /* no longer needed -> is in prop! */
+ RETiRet;
+}
+
+
/* This function is used to set the global work directory name.
* It verifies that the provided directory actually exists and
* emits an error message if not.
@@ -226,6 +278,36 @@ finalize_it:
RETiRet;
}
+/* return our local IP.
+ * If no local IP is set, "127.0.0.1" is selected *and* set. This
+ * is an intensional side effect that we do in order to keep things
+ * consistent and avoid config errors (this will make us not accept
+ * setting the local IP address once a module has obtained it - so
+ * it forces the $LocalHostIPIF directive high up in rsyslog.conf)
+ * rgerhards, 2012-03-21
+ */
+static prop_t*
+GetLocalHostIP(void)
+{
+ if(propLocalIPIF == NULL)
+ storeLocalHostIPIF((uchar*)"127.0.0.1");
+ return(propLocalIPIF);
+}
+
+
+/* set our local hostname. Free previous hostname, if it was already set.
+ * Note that we do now do this in a thread
+ * "once in a lifetime" action which can not be undone. -- gerhards, 2009-07-20
+ */
+static rsRetVal
+SetLocalHostName(uchar *newname)
+{
+ free(LocalHostName);
+ LocalHostName = newname;
+ return RS_RET_OK;
+}
+
+
/* return our local hostname. if it is not set, "[localhost]" is returned
*/
static uchar*
@@ -251,6 +333,26 @@ done:
}
+/* set our local domain name. Free previous domain, if it was already set.
+ */
+static rsRetVal
+SetLocalDomain(uchar *newname)
+{
+ free(LocalDomain);
+ LocalDomain = newname;
+ return RS_RET_OK;
+}
+
+
+/* return our local hostname. if it is not set, "[localhost]" is returned
+ */
+static uchar*
+GetLocalDomain(void)
+{
+ return LocalDomain;
+}
+
+
/* generate the local hostname property. This must be done after the hostname info
* has been set as well as PreserveFQDN.
* rgerhards, 2009-06-30
@@ -295,6 +397,14 @@ GetLocalHostNameProp(void)
}
+static rsRetVal
+SetLocalFQDNName(uchar *newname)
+{
+ free(LocalFQDNName);
+ LocalFQDNName = newname;
+ return RS_RET_OK;
+}
+
/* return the current localhost name as FQDN (requires FQDN to be set)
* TODO: we should set the FQDN ourselfs in here!
*/
@@ -362,6 +472,7 @@ CODESTARTobjQueryInterface(glbl)
pIf->GetWorkDir = GetWorkDir;
pIf->GenerateLocalHostNameProperty = GenerateLocalHostNameProperty;
pIf->GetLocalHostNameProp = GetLocalHostNameProp;
+ pIf->GetLocalHostIP = GetLocalHostIP;
pIf->SetGlobalInputTermination = SetGlobalInputTermination;
pIf->GetGlobalInputTermState = GetGlobalInputTermState;
#define SIMP_PROP(name) \
@@ -397,30 +508,18 @@ ENDobjQueryInterface(glbl)
*/
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
{
- if(pszDfltNetstrmDrvr != NULL) {
- free(pszDfltNetstrmDrvr);
- pszDfltNetstrmDrvr = NULL;
- }
- if(pszDfltNetstrmDrvrCAF != NULL) {
- free(pszDfltNetstrmDrvrCAF);
- pszDfltNetstrmDrvrCAF = NULL;
- }
- if(pszDfltNetstrmDrvrKeyFile != NULL) {
- free(pszDfltNetstrmDrvrKeyFile);
- pszDfltNetstrmDrvrKeyFile = NULL;
- }
- if(pszDfltNetstrmDrvrCertFile != NULL) {
- free(pszDfltNetstrmDrvrCertFile);
- pszDfltNetstrmDrvrCertFile = NULL;
- }
- if(LocalHostNameOverride != NULL) {
- free(LocalHostNameOverride);
- LocalHostNameOverride = NULL;
- }
- if(pszWorkDir != NULL) {
- free(pszWorkDir);
- pszWorkDir = NULL;
- }
+ free(pszDfltNetstrmDrvr);
+ pszDfltNetstrmDrvr = NULL;
+ free(pszDfltNetstrmDrvrCAF);
+ pszDfltNetstrmDrvrCAF = NULL;
+ free(pszDfltNetstrmDrvrKeyFile);
+ pszDfltNetstrmDrvrKeyFile = NULL;
+ free(pszDfltNetstrmDrvrCertFile);
+ pszDfltNetstrmDrvrCertFile = NULL;
+ free(LocalHostNameOverride);
+ LocalHostNameOverride = NULL;
+ free(pszWorkDir);
+ pszWorkDir = NULL;
bDropMalPTRMsgs = 0;
bOptimizeUniProc = 1;
bPreserveFQDN = 0;
@@ -515,7 +614,7 @@ BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */
CHKiRet(objUse(prop, CORE_COMPONENT));
CHKiRet(objUse(errmsg, CORE_COMPONENT));
- /* register config handlers (TODO: we need to implement a way to unregister them) */
+ /* config handlers are never unregistered and need not be - we are always loaded ;) */
CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, setWorkDir, NULL, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriver", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvr, NULL));
@@ -523,6 +622,7 @@ BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdriverkeyfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrKeyFile, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"defaultnetstreamdrivercertfile", 0, eCmdHdlrGetWord, NULL, &pszDfltNetstrmDrvrCertFile, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"localhostname", 0, eCmdHdlrGetWord, NULL, &LocalHostNameOverride, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"localhostipif", 0, eCmdHdlrGetWord, setLocalHostIPIF, NULL, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"optimizeforuniprocessor", 0, eCmdHdlrBinary, NULL, &bOptimizeUniProc, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"preservefqdn", 0, eCmdHdlrBinary, NULL, &bPreserveFQDN, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"maxmessagesize", 0, eCmdHdlrSize,
@@ -537,21 +637,15 @@ ENDObjClassInit(glbl)
* rgerhards, 2008-04-17
*/
BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */
- if(pszDfltNetstrmDrvr != NULL)
- free(pszDfltNetstrmDrvr);
- if(pszDfltNetstrmDrvrCAF != NULL)
- free(pszDfltNetstrmDrvrCAF);
- if(pszDfltNetstrmDrvrKeyFile != NULL)
- free(pszDfltNetstrmDrvrKeyFile);
- if(pszDfltNetstrmDrvrCertFile != NULL)
- free(pszDfltNetstrmDrvrCertFile);
- if(pszWorkDir != NULL)
- free(pszWorkDir);
- if(LocalHostName != NULL)
- free(LocalHostName);
+ free(pszDfltNetstrmDrvr);
+ free(pszDfltNetstrmDrvrCAF);
+ free(pszDfltNetstrmDrvrKeyFile);
+ free(pszDfltNetstrmDrvrCertFile);
+ free(pszWorkDir);
+ free(LocalDomain);
+ free(LocalHostName);
free(LocalHostNameOverride);
- if(LocalFQDNName != NULL)
- free(LocalFQDNName);
+ free(LocalFQDNName);
objRelease(prop, CORE_COMPONENT);
DESTROY_ATOMIC_HELPER_MUT(mutTerminateInputs);
ENDObjClassExit(glbl)
diff --git a/runtime/glbl.h b/runtime/glbl.h
index 262b2cc2..d2d1e66a 100644
--- a/runtime/glbl.h
+++ b/runtime/glbl.h
@@ -8,25 +8,23 @@
* Please note that there currently is no glbl.c file as we do not yet
* have any implementations.
*
- * Copyright 2008, 2009 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2008-2012 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
- * The rsyslog runtime library is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * The rsyslog runtime library 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 Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with the rsyslog runtime library. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * -or-
+ * see COPYING.ASL20 in the source distribution
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
#ifndef GLBL_H_INCLUDED
@@ -77,7 +75,9 @@ BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
*/
SIMP_PROP(FdSetSize, int)
/* v7: was neeeded to mean v5+v6 - do NOT add anything else for that version! */
- /* next is v8! */
+ /* next change is v9! */
+ /* v8 - 2012-03-21 */
+ prop_t* (*GetLocalHostIP)(void);
#undef SIMP_PROP
ENDinterface(glbl)
#define glblCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */
diff --git a/runtime/msg.c b/runtime/msg.c
index 8f92565a..9c7a2203 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -36,6 +36,7 @@
#include <assert.h>
#include <ctype.h>
#include <sys/socket.h>
+#include <sys/sysinfo.h>
#include <netdb.h>
#include <libestr.h>
#include <libee/libee.h>
@@ -55,6 +56,7 @@
#include "ruleset.h"
#include "prop.h"
#include "net.h"
+#include "rsconf.h"
/* static data */
DEFobjStaticHelpers
@@ -261,6 +263,9 @@ static struct {
{ UCHAR_CONSTANT("190"), 5},
{ UCHAR_CONSTANT("191"), 5}
};
+static char hexdigit[16] =
+ {'0', '1', '2', '3', '4', '5', '6', '7', '8',
+ '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/*syslog facility names (as of RFC5424) */
static char *syslog_fac_names[24] = { "kern", "user", "mail", "daemon", "auth", "syslog", "lpr",
@@ -421,7 +426,6 @@ resolveDNS(msg_t *pMsg) {
uchar fromHostFQDN[NI_MAXHOST];
DEFiRet;
-dbgprintf("XXXX: in msg/resolveDNS (dnscache)\n");
MsgLock(pMsg);
CHKiRet(objUse(net, CORE_COMPONENT));
if(pMsg->msgFlags & NEEDS_DNSRESOL) {
@@ -562,6 +566,8 @@ propNameStrToID(uchar *pName, propid_t *pPropID)
*pPropID = PROP_CEE;
} else if(!strcmp((char*) pName, "$bom")) {
*pPropID = PROP_SYS_BOM;
+ } else if(!strcmp((char*) pName, "$uptime")) {
+ *pPropID = PROP_SYS_UPTIME;
} else {
*pPropID = PROP_INVALID;
iRet = RS_RET_VAR_NOT_FOUND;
@@ -1069,6 +1075,12 @@ static rsRetVal MsgSerialize(msg_t *pThis, strm_t *pStrm)
objSerializePTR(pStrm, pCSAPPNAME, CSTR);
objSerializePTR(pStrm, pCSPROCID, CSTR);
objSerializePTR(pStrm, pCSMSGID, CSTR);
+
+ if(pThis->pRuleset != NULL) {
+ rulesetGetName(pThis->pRuleset);
+ CHKiRet(obj.SerializeProp(pStrm, UCHAR_CONSTANT("pszRuleset"), PROPTYPE_PSZ,
+ rulesetGetName(pThis->pRuleset)));
+ }
/* offset must be serialized after pszRawMsg, because we need that to obtain the correct
* MSG size.
@@ -1694,6 +1706,16 @@ void MsgSetRuleset(msg_t *pMsg, ruleset_t *pRuleset)
}
+/* rgerhards 2012-04-18: set associated ruleset (by ruleset name)
+ * If ruleset cannot be found, no update is done.
+ */
+static void
+MsgSetRulesetByName(msg_t *pMsg, cstr_t *rulesetName)
+{
+ rulesetGetRuleset(runConf, &(pMsg->pRuleset), rsCStrGetSzStrNoNULL(rulesetName));
+}
+
+
/* set TAG in msg object
* (rewritten 2009-06-18 rgerhards)
*/
@@ -2351,81 +2373,67 @@ finalize_it:
}
-/* encode a property in JSON escaped format. This is a helper
- * to MsgGetProp. It needs to update all provided parameters.
- * Note: Code is borrowed from libee (my own code, so ASL 2.0
- * is fine with it); this function may later be replaced by
- * some "better" and more complete implementation (maybe from
- * libee or its helpers).
- * For performance reasons, we begin to copy the string only
- * when we recognice that we actually need to do some escaping.
- * rgerhards, 2012-03-16
+/* Encode a JSON value and add it to provided string. Note that
+ * the string object may be NULL. In this case, it is created
+ * if and only if escaping is needed.
*/
static rsRetVal
-jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen)
+jsonAddVal(uchar *pSrc, unsigned buflen, es_str_t **dst)
{
- static char hexdigit[16] =
- {'0', '1', '2', '3', '4', '5', '6', '7', '8',
- '9', 'A', 'B', 'C', 'D', 'E', 'F' };
unsigned char c;
es_size_t i;
char numbuf[4];
int j;
- unsigned buflen;
- uchar *pSrc;
- es_str_t *dst = NULL;
DEFiRet;
- pSrc = *ppRes;
- buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen;
for(i = 0 ; i < buflen ; ++i) {
c = pSrc[i];
if( (c >= 0x23 && c <= 0x5b)
|| (c >= 0x5d /* && c <= 0x10FFFF*/)
|| c == 0x20 || c == 0x21) {
/* no need to escape */
- if(dst != NULL)
- es_addChar(&dst, c);
+ if(*dst != NULL)
+ es_addChar(dst, c);
} else {
- if(dst == NULL) {
+ if(*dst == NULL) {
if(i == 0) {
/* we hope we have only few escapes... */
- dst = es_newStr(buflen+10);
+ *dst = es_newStr(buflen+10);
} else {
- dst = es_newStrFromBuf((char*)pSrc, i-1);
+ *dst = es_newStrFromBuf((char*)pSrc, i-1);
}
- if(dst == NULL) {
+ if(*dst == NULL) {
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
}
/* we must escape, try RFC4627-defined special sequences first */
switch(c) {
case '\0':
- es_addBuf(&dst, "\\u0000", 6);
+ es_addBuf(dst, "\\u0000", 6);
break;
case '\"':
- es_addBuf(&dst, "\\\"", 2);
+ es_addBuf(dst, "\\\"", 2);
break;
case '/':
- es_addBuf(&dst, "\\/", 2);
+ es_addBuf(dst, "\\/", 2);
break;
case '\\':
- es_addBuf(&dst, "\\\\", 2);
+ es_addBuf(dst, "\\\\", 2);
break;
case '\010':
- es_addBuf(&dst, "\\b", 2);
+ es_addBuf(dst, "\\b", 2);
break;
case '\014':
- es_addBuf(&dst, "\\f", 2);
+ es_addBuf(dst, "\\f", 2);
break;
case '\n':
- es_addBuf(&dst, "\\n", 2);
+ es_addBuf(dst, "\\n", 2);
break;
case '\r':
- es_addBuf(&dst, "\\r", 2);
+ es_addBuf(dst, "\\r", 2);
break;
case '\t':
- es_addBuf(&dst, "\\t", 2);
+ es_addBuf(dst, "\\t", 2);
break;
default:
/* TODO : proper Unicode encoding (see header comment) */
@@ -2433,12 +2441,38 @@ jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen)
numbuf[3-j] = hexdigit[c % 16];
c = c / 16;
}
- es_addBuf(&dst, "\\u", 2);
- es_addBuf(&dst, numbuf, 4);
+ es_addBuf(dst, "\\u", 2);
+ es_addBuf(dst, numbuf, 4);
break;
}
}
}
+finalize_it:
+ RETiRet;
+}
+
+
+/* encode a property in JSON escaped format. This is a helper
+ * to MsgGetProp. It needs to update all provided parameters.
+ * Note: Code is borrowed from libee (my own code, so ASL 2.0
+ * is fine with it); this function may later be replaced by
+ * some "better" and more complete implementation (maybe from
+ * libee or its helpers).
+ * For performance reasons, we begin to copy the string only
+ * when we recognice that we actually need to do some escaping.
+ * rgerhards, 2012-03-16
+ */
+static rsRetVal
+jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen)
+{
+ unsigned buflen;
+ uchar *pSrc;
+ es_str_t *dst = NULL;
+ DEFiRet;
+
+ pSrc = *ppRes;
+ buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen;
+ CHKiRet(jsonAddVal(pSrc, buflen, &dst));
if(dst != NULL) {
/* we updated the string and need to replace the
@@ -2448,6 +2482,7 @@ jsonEncode(uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen)
free(*ppRes);
*ppRes = (uchar*)es_str2cstr(dst, NULL);
*pbMustBeFreed = 1;
+ *pBufLen = -1;
es_deleteStr(dst);
}
@@ -2456,6 +2491,46 @@ finalize_it:
}
+/* Format a property as JSON field, that means
+ * "name"="value"
+ * where value is JSON-escaped (here we assume that the name
+ * only contains characters from the valid character set).
+ * Note: this function duplicates code from jsonEncode().
+ * TODO: these two functions should be combined, at least if
+ * that makes any sense from a performance PoV - definitely
+ * something to consider at a later stage. rgerhards, 2012-04-19
+ */
+static rsRetVal
+jsonField(struct templateEntry *pTpe, uchar **ppRes, unsigned short *pbMustBeFreed, int *pBufLen)
+{
+ unsigned buflen;
+ uchar *pSrc;
+ es_str_t *dst = NULL;
+ DEFiRet;
+
+ pSrc = *ppRes;
+ buflen = (*pBufLen == -1) ? ustrlen(pSrc) : *pBufLen;
+ /* we hope we have only few escapes... */
+ dst = es_newStr(buflen+es_strlen(pTpe->data.field.fieldName)+15);
+ es_addChar(&dst, '"');
+ es_addStr(&dst, pTpe->data.field.fieldName);
+ es_addBufConstcstr(&dst, "\"=\"");
+ CHKiRet(jsonAddVal(pSrc, buflen, &dst));
+ es_addChar(&dst, '"');
+
+ if(*pbMustBeFreed)
+ free(*ppRes);
+ /* we know we do not have \0 chars - so the size does not change */
+ *pBufLen = es_strlen(dst);
+ *ppRes = (uchar*)es_str2cstr(dst, NULL);
+ *pbMustBeFreed = 1;
+ es_deleteStr(dst);
+
+finalize_it:
+ RETiRet;
+}
+
+
/* This function returns a string-representation of the
* requested message property. This is a generic function used
* to abstract properties so that these can be easier
@@ -2673,6 +2748,23 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
pRes = (uchar*) "\xEF\xBB\xBF";
*pbMustBeFreed = 0;
break;
+ case PROP_SYS_UPTIME:
+ {
+ struct sysinfo s_info;
+
+ if((pRes = (uchar*) MALLOC(sizeof(uchar) * 32)) == NULL) {
+ RET_OUT_OF_MEMORY;
+ }
+ *pbMustBeFreed = 1;
+
+ if(sysinfo(&s_info) < 0) {
+ *pPropLen = sizeof("**SYSCALL FAILED**") - 1;
+ return(UCHAR_CONSTANT("**SYSCALL FAILED**"));
+ }
+
+ snprintf((char*) pRes, sizeof(uchar) * 32, "%ld", s_info.uptime);
+ }
+ break;
default:
/* there is no point in continuing, we may even otherwise render the
* error message unreadable. rgerhards, 2007-07-10
@@ -3264,6 +3356,8 @@ dbgprintf("prop repl 4, pRes='%s', len %d\n", pRes, bufLen);
*pbMustBeFreed = 1;
} else if(pTpe->data.field.options.bJSON) {
jsonEncode(&pRes, pbMustBeFreed, &bufLen);
+ } else if(pTpe->data.field.options.bJSONf) {
+ jsonField(pTpe, &pRes, pbMustBeFreed, &bufLen);
}
if(bufLen == -1)
@@ -3332,7 +3426,6 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name)
propNameStrToID(name, &propid);
pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, NULL, &propLen, &bMustBeFreed);
-dbgprintf("ZZZZ: var %s returns '%s'\n", name, pszProp);
estr = es_newStrFromCStr((char*)pszProp, propLen);
if(bMustBeFreed)
free(pszProp);
@@ -3403,8 +3496,13 @@ rsRetVal MsgSetProperty(msg_t *pThis, var_t *pProp)
memcpy(&pThis->tRcvdAt, &pProp->val.vSyslogTime, sizeof(struct syslogTime));
} else if(isProp("tTIMESTAMP")) {
memcpy(&pThis->tTIMESTAMP, &pProp->val.vSyslogTime, sizeof(struct syslogTime));
+ } else if(isProp("pszRuleset")) {
+ MsgSetRulesetByName(pThis, pProp->val.pStr);
} else if(isProp("pszMSG")) {
dbgprintf("no longer supported property pszMSG silently ignored\n");
+ } else {
+ dbgprintf("unknown supported property '%s' silently ignored\n",
+ rsCStrGetSzStrNoNULL(pProp->pcsName));
}
finalize_it:
diff --git a/runtime/net.c b/runtime/net.c
index 4631adc4..dcf9cb52 100644
--- a/runtime/net.c
+++ b/runtime/net.c
@@ -54,6 +54,9 @@
#include <fnmatch.h>
#include <fcntl.h>
#include <unistd.h>
+#include <ifaddrs.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
#include "syslogd-types.h"
#include "module-template.h"
@@ -1480,6 +1483,54 @@ finalize_it:
}
+/* return the IP address (IPv4/6) for the provided interface. Returns
+ * RS_RET_NOT_FOUND if interface can not be found in interface list.
+ * The family must be correct (AF_INET vs. AF_INET6, AF_UNSPEC means
+ * either of *these two*).
+ * The function re-queries the interface list (at least in theory).
+ * However, it caches entries in order to avoid too-frequent requery.
+ * rgerhards, 2012-03-06
+ */
+static rsRetVal
+getIFIPAddr(uchar *szif, int family, uchar *pszbuf, int lenBuf)
+{
+ struct ifaddrs * ifaddrs = NULL;
+ struct ifaddrs * ifa;
+ void * pAddr;
+ DEFiRet;
+
+ if(getifaddrs(&ifaddrs) != 0) {
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+
+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
+ if(strcmp(ifa->ifa_name, (char*)szif))
+ continue;
+ if( (family == AF_INET6 || family == AF_UNSPEC)
+ && ifa->ifa_addr->sa_family == AF_INET6) {
+ pAddr = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
+ inet_ntop(AF_INET6, pAddr, (char*)pszbuf, lenBuf);
+ break;
+ } else if(/* (family == AF_INET || family == AF_UNSPEC)
+ &&*/ ifa->ifa_addr->sa_family == AF_INET) {
+ pAddr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
+ inet_ntop(AF_INET, pAddr, (char*)pszbuf, lenBuf);
+ break;
+ }
+ }
+
+ if(ifaddrs != NULL)
+ freeifaddrs(ifaddrs);
+
+ if(ifa == NULL)
+ iRet = RS_RET_NOT_FOUND;
+
+finalize_it:
+ RETiRet;
+
+}
+
+
/* queryInterface function
* rgerhards, 2008-03-05
*/
@@ -1511,6 +1562,7 @@ CODESTARTobjQueryInterface(net)
pIf->PermittedPeerWildcardMatch = PermittedPeerWildcardMatch;
pIf->CmpHost = CmpHost;
pIf->HasRestrictions = HasRestrictions;
+ pIf->GetIFIPAddr = getIFIPAddr;
/* data members */
pIf->pACLAddHostnameOnFail = &ACLAddHostnameOnFail;
pIf->pACLDontResolve = &ACLDontResolve;
diff --git a/runtime/net.h b/runtime/net.h
index 101ce79d..1b41c81c 100644
--- a/runtime/net.h
+++ b/runtime/net.h
@@ -1,6 +1,6 @@
/* Definitions for network-related stuff.
*
- * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of the rsyslog runtime library.
*
@@ -151,11 +151,13 @@ BEGINinterface(net) /* name must also be changed in ENDinterface macro! */
/* v6 interface additions - 2009-11-16 */
rsRetVal (*HasRestrictions)(uchar *, int *bHasRestrictions);
int (*isAllowedSender2)(uchar *pszType, struct sockaddr *pFrom, const char *pszFromHost, int bChkDNS);
+ /* v7 interface additions - 2012-03-06 */
+ rsRetVal (*GetIFIPAddr)(uchar *szif, int family, uchar *pszbuf, int lenBuf);
/* data members - these should go away over time... TODO */
int *pACLAddHostnameOnFail; /* add hostname to acl when DNS resolving has failed */
int *pACLDontResolve; /* add hostname to acl instead of resolving it to IP(s) */
ENDinterface(net)
-#define netCURR_IF_VERSION 6 /* increment whenever you change the interface structure! */
+#define netCURR_IF_VERSION 7 /* increment whenever you change the interface structure! */
/* prototypes */
PROTOTYPEObj(net);
diff --git a/runtime/queue.c b/runtime/queue.c
index cd64b1fc..7085c829 100644
--- a/runtime/queue.c
+++ b/runtime/queue.c
@@ -2156,13 +2156,16 @@ static rsRetVal qqueuePersist(qqueue_t *pThis, int bIsCheckpoint)
CHKiRet(obj.EndSerialize(psQIF));
/* now persist the stream info */
- CHKiRet(strm.Serialize(pThis->tVars.disk.pWrite, psQIF));
- CHKiRet(strm.Serialize(pThis->tVars.disk.pReadDel, psQIF));
+ if(pThis->tVars.disk.pWrite != NULL)
+ CHKiRet(strm.Serialize(pThis->tVars.disk.pWrite, psQIF));
+ if(pThis->tVars.disk.pReadDel != NULL)
+ CHKiRet(strm.Serialize(pThis->tVars.disk.pReadDel, psQIF));
/* tell the input file object that it must not delete the file on close if the queue
* is non-empty - but only if we are not during a simple checkpoint
*/
- if(bIsCheckpoint != QUEUE_CHECKPOINT) {
+ if(bIsCheckpoint != QUEUE_CHECKPOINT
+ && pThis->tVars.disk.pReadDel != NULL) {
CHKiRet(strm.SetbDeleteOnClose(pThis->tVars.disk.pReadDel, 0));
}
@@ -2254,7 +2257,8 @@ CODESTARTobjDestruct(qqueue)
* direct queue - because in both cases we have none... ;)
* with a child! -- rgerhards, 2008-01-28
*/
- if(pThis->qType != QUEUETYPE_DIRECT && !pThis->bEnqOnly && pThis->pqParent == NULL)
+ if(pThis->qType != QUEUETYPE_DIRECT && !pThis->bEnqOnly && pThis->pqParent == NULL
+ && pThis->pWtpReg != NULL)
ShutdownWorkers(pThis);
if(pThis->bIsDA && getPhysicalQueueSize(pThis) > 0 && pThis->bSaveOnShutdown) {
@@ -2658,6 +2662,7 @@ DEFpropSetMeth(qqueue, iLowWtrMrk, int)
DEFpropSetMeth(qqueue, iDiscardMrk, int)
DEFpropSetMeth(qqueue, iFullDlyMrk, int)
DEFpropSetMeth(qqueue, iDiscardSeverity, int)
+DEFpropSetMeth(qqueue, iLightDlyMrk, int)
DEFpropSetMeth(qqueue, bIsDA, int)
DEFpropSetMeth(qqueue, iMinMsgsPerWrkr, int)
DEFpropSetMeth(qqueue, bSaveOnShutdown, int)
diff --git a/runtime/queue.h b/runtime/queue.h
index c9fdd94c..3841615a 100644
--- a/runtime/queue.h
+++ b/runtime/queue.h
@@ -205,6 +205,7 @@ PROTOTYPEpropSetMeth(qqueue, toQShutdown, long);
PROTOTYPEpropSetMeth(qqueue, toActShutdown, long);
PROTOTYPEpropSetMeth(qqueue, toWrkShutdown, long);
PROTOTYPEpropSetMeth(qqueue, toEnq, long);
+PROTOTYPEpropSetMeth(qqueue, iLightDlyMrk, int);
PROTOTYPEpropSetMeth(qqueue, iHighWtrMrk, int);
PROTOTYPEpropSetMeth(qqueue, iLowWtrMrk, int);
PROTOTYPEpropSetMeth(qqueue, iDiscardMrk, int);
diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h
index fb0da2d2..058322bd 100644
--- a/runtime/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -141,6 +141,7 @@ typedef uintTiny propid_t;
#define PROP_CEE 200
#define PROP_CEE_ALL_JSON 201
#define PROP_SYS_BOM 159
+#define PROP_SYS_UPTIME 160
/* The error codes below are orginally "borrowed" from
diff --git a/runtime/ruleset.c b/runtime/ruleset.c
index 00d96714..c384663a 100644
--- a/runtime/ruleset.c
+++ b/runtime/ruleset.c
@@ -312,8 +312,8 @@ GetRulesetQueue(ruleset_t *pThis)
/* Find the ruleset with the given name and return a pointer to its object.
*/
-static rsRetVal
-GetRuleset(rsconf_t *conf, ruleset_t **ppRuleset, uchar *pszName)
+rsRetVal
+rulesetGetRuleset(rsconf_t *conf, ruleset_t **ppRuleset, uchar *pszName)
{
DEFiRet;
assert(ppRuleset != NULL);
@@ -335,7 +335,7 @@ SetDefaultRuleset(rsconf_t *conf, uchar *pszName)
DEFiRet;
assert(pszName != NULL);
- CHKiRet(GetRuleset(conf, &pRuleset, pszName));
+ CHKiRet(rulesetGetRuleset(conf, &pRuleset, pszName));
conf->rulesets.pDflt = pRuleset;
dbgprintf("default rule set changed to %p: '%s'\n", pRuleset, pszName);
@@ -353,7 +353,7 @@ SetCurrRuleset(rsconf_t *conf, uchar *pszName)
DEFiRet;
assert(pszName != NULL);
- CHKiRet(GetRuleset(conf, &pRuleset, pszName));
+ CHKiRet(rulesetGetRuleset(conf, &pRuleset, pszName));
conf->rulesets.pCurr = pRuleset;
dbgprintf("current rule set changed to %p: '%s'\n", pRuleset, pszName);
@@ -497,6 +497,7 @@ debugPrintAll(rsconf_t *conf)
static inline rsRetVal
doRulesetCreateQueue(rsconf_t *conf, int *pNewVal)
{
+ uchar *rulesetMainQName;
DEFiRet;
if(conf->rulesets.pCurr == NULL) {
@@ -515,7 +516,9 @@ doRulesetCreateQueue(rsconf_t *conf, int *pNewVal)
FINALIZE; /* if it is turned off, we do not need to change anything ;) */
dbgprintf("adding a ruleset-specific \"main\" queue");
- CHKiRet(createMainQueue(&conf->rulesets.pCurr->pQueue, UCHAR_CONSTANT("ruleset")));
+ rulesetMainQName = (conf->rulesets.pCurr->pszName == NULL)? UCHAR_CONSTANT("ruleset") :
+ conf->rulesets.pCurr->pszName;
+ CHKiRet(createMainQueue(&conf->rulesets.pCurr->pQueue, rulesetMainQName));
finalize_it:
RETiRet;
@@ -599,7 +602,7 @@ CODESTARTobjQueryInterface(ruleset)
pIf->SetName = setName;
pIf->DebugPrintAll = debugPrintAll;
pIf->GetCurrent = GetCurrent;
- pIf->GetRuleset = GetRuleset;
+ pIf->GetRuleset = rulesetGetRuleset;
pIf->SetDefaultRuleset = SetDefaultRuleset;
pIf->SetCurrRuleset = SetCurrRuleset;
pIf->GetRulesetQueue = GetRulesetQueue;
diff --git a/runtime/ruleset.h b/runtime/ruleset.h
index 9d50f6f7..f4443e18 100644
--- a/runtime/ruleset.h
+++ b/runtime/ruleset.h
@@ -69,7 +69,23 @@ PROTOTYPEObj(ruleset);
/* TODO: remove these -- currently done dirty for config file
* redo -- rgerhards, 2011-04-19
+ * rgerhards, 2012-04-19: actually, it may be way cooler not to remove
+ * them and use plain c-style conventions at least inside core objects.
*/
rsRetVal rulesetDestructForLinkedList(void *pData);
rsRetVal rulesetKeyDestruct(void __attribute__((unused)) *pData);
+
+/* Get name associated to ruleset. This function cannot fail (except,
+ * of course, if previously something went really wrong). Returned
+ * pointer is read-only.
+ * rgerhards, 2012-04-18
+ */
+static inline uchar*
+rulesetGetName(ruleset_t *pRuleset)
+{
+ return pRuleset->pszName;
+}
+
+
+rsRetVal rulesetGetRuleset(rsconf_t *conf, ruleset_t **ppRuleset, uchar *pszName);
#endif /* #ifndef INCLUDED_RULESET_H */
diff --git a/tcps_sess.c b/tcps_sess.c
index bd461449..eb3740e4 100644
--- a/tcps_sess.c
+++ b/tcps_sess.c
@@ -200,6 +200,8 @@ SetLstnInfo(tcps_sess_t *pThis, tcpLstnPortList_t *pLstnInfo)
ISOBJ_TYPE_assert(pThis, tcps_sess);
assert(pLstnInfo != NULL);
pThis->pLstnInfo = pLstnInfo;
+ /* set cached elements */
+ pThis->bSuppOctetFram = pLstnInfo->bSuppOctetFram;
RETiRet;
}
@@ -366,7 +368,7 @@ processDataRcvd(tcps_sess_t *pThis, char c, struct syslogTime *stTime, time_t tt
ISOBJ_TYPE_assert(pThis, tcps_sess);
if(pThis->inputState == eAtStrtFram) {
- if(isdigit((int) c)) {
+ if(pThis->bSuppOctetFram && isdigit((int) c)) {
pThis->inputState = eInOctetCnt;
pThis->iOctetsRemain = 0;
pThis->eFraming = TCP_FRAMING_OCTET_COUNTING;
diff --git a/tcps_sess.h b/tcps_sess.h
index 0799db99..054ce397 100644
--- a/tcps_sess.h
+++ b/tcps_sess.h
@@ -35,7 +35,8 @@ struct tcps_sess_s {
tcpLstnPortList_t *pLstnInfo; /* pointer back to listener info */
netstrm_t *pStrm;
int iMsg; /* index of next char to store in msg */
- int bAtStrtOfFram; /* are we at the very beginning of a new frame? */
+ sbool bAtStrtOfFram; /* are we at the very beginning of a new frame? */
+ sbool bSuppOctetFram; /**< copy from listener, to speed up access */
enum {
eAtStrtFram,
eInOctetCnt,
diff --git a/tcpsrv.c b/tcpsrv.c
index 63edad68..b5b64f07 100644
--- a/tcpsrv.c
+++ b/tcpsrv.c
@@ -119,7 +119,7 @@ static int wrkrRunning;
* rgerhards, 2009-05-21
*/
static inline rsRetVal
-addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort)
+addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort, int bSuppOctetFram)
{
tcpLstnPortList_t *pEntry;
uchar statname[64];
@@ -132,6 +132,7 @@ addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort)
pEntry->pszPort = pszPort;
pEntry->pSrv = pThis;
pEntry->pRuleset = pThis->pRuleset;
+ pEntry->bSuppOctetFram = bSuppOctetFram;
/* we need to create a property */
CHKiRet(prop.Construct(&pEntry->pInputName));
@@ -147,6 +148,7 @@ addNewLstnPort(tcpsrv_t *pThis, uchar *pszPort)
snprintf((char*)statname, sizeof(statname), "%s(%s)", pThis->pszInputName, pszPort);
statname[sizeof(statname)-1] = '\0'; /* just to be on the save side... */
CHKiRet(statsobj.SetName(pEntry->stats, statname));
+ STATSCOUNTER_INIT(pEntry->ctrSubmit, pEntry->mutCtrSubmit);
CHKiRet(statsobj.AddCounter(pEntry->stats, UCHAR_CONSTANT("submitted"),
ctrType_IntCtr, &(pEntry->ctrSubmit)));
CHKiRet(statsobj.ConstructFinalize(pEntry->stats));
@@ -161,7 +163,7 @@ finalize_it:
* rgerhards, 2008-03-20
*/
static rsRetVal
-configureTCPListen(tcpsrv_t *pThis, uchar *pszPort)
+configureTCPListen(tcpsrv_t *pThis, uchar *pszPort, int bSuppOctetFram)
{
int i;
uchar *pPort = pszPort;
@@ -177,7 +179,7 @@ configureTCPListen(tcpsrv_t *pThis, uchar *pszPort)
}
if(i >= 0 && i <= 65535) {
- CHKiRet(addNewLstnPort(pThis, pszPort));
+ CHKiRet(addNewLstnPort(pThis, pszPort, bSuppOctetFram));
} else {
errmsg.LogError(0, NO_ERRCODE, "Invalid TCP listen port %s - ignored.\n", pszPort);
}
diff --git a/tcpsrv.h b/tcpsrv.h
index 2bb9c05b..d66f682c 100644
--- a/tcpsrv.h
+++ b/tcpsrv.h
@@ -41,6 +41,7 @@ struct tcpLstnPortList_s {
tcpsrv_t *pSrv; /**< pointer to higher-level server instance */
ruleset_t *pRuleset; /**< associated ruleset */
statsobj_t *stats; /**< associated stats object */
+ sbool bSuppOctetFram; /**< do we support octect-counted framing? (if no->legay only!)*/
STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit)
tcpLstnPortList_t *pNext; /**< next port or NULL */
};
@@ -105,7 +106,7 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
rsRetVal (*Construct)(tcpsrv_t **ppThis);
rsRetVal (*ConstructFinalize)(tcpsrv_t __attribute__((unused)) *pThis);
rsRetVal (*Destruct)(tcpsrv_t **ppThis);
- rsRetVal (*configureTCPListen)(tcpsrv_t*, uchar *pszPort);
+ rsRetVal (*configureTCPListen)(tcpsrv_t*, uchar *pszPort, int bSuppOctetFram);
//rsRetVal (*SessAccept)(tcpsrv_t *pThis, tcpLstnPortList_t*, tcps_sess_t **ppSess, netstrm_t *pStrm);
rsRetVal (*create_tcp_socket)(tcpsrv_t *pThis);
rsRetVal (*Run)(tcpsrv_t *pThis);
@@ -142,11 +143,12 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
/* added v11 -- rgerhards, 2011-05-09 */
rsRetVal (*SetKeepAlive)(tcpsrv_t*, int);
ENDinterface(tcpsrv)
-#define tcpsrvCURR_IF_VERSION 11 /* increment whenever you change the interface structure! */
+#define tcpsrvCURR_IF_VERSION 12 /* increment whenever you change the interface structure! */
/* change for v4:
* - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
* - SetInputName() added -- rgerhards, 2008-12-10
* change for v5 and up: see above
+ * for v12: param bSuppOctetFram added to configureTCPListen
*/
diff --git a/template.c b/template.c
index 2326819c..c6878459 100644
--- a/template.c
+++ b/template.c
@@ -493,18 +493,18 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe)
p = *pp;
- while(*p && *p != '%') {
+ while(*p && *p != '%' && *p != ':') {
/* outer loop - until end of options */
i = 0;
while((i < sizeof(Buf) / sizeof(char)) &&
- *p && *p != '%' && *p != ',') {
+ *p && *p != '%' && *p != ':' && *p != ',') {
/* inner loop - until end of ONE option */
Buf[i++] = tolower((int)*p);
++p;
}
Buf[i] = '\0'; /* terminate */
/* check if we need to skip oversize option */
- while(*p && *p != '%' && *p != ',')
+ while(*p && *p != '%' && *p != ':' && *p != ',')
++p; /* just skip */
if(*p == ',')
++p; /* eat ',' */
@@ -544,19 +544,26 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe)
} else if(!strcmp((char*)Buf, "secpath-replace")) {
pTpe->data.field.options.bSecPathReplace = 1;
} else if(!strcmp((char*)Buf, "csv")) {
- if(pTpe->data.field.options.bJSON) {
- errmsg.LogError(0, NO_ERRCODE, "error: can not specify "
- "both csv and json options - csv ignored");
+ if(pTpe->data.field.options.bJSON || pTpe->data.field.options.bJSONf) {
+ errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
+ "one option out of (json, jsonf, csv) - csv ignored");
} else {
pTpe->data.field.options.bCSV = 1;
}
} else if(!strcmp((char*)Buf, "json")) {
- if(pTpe->data.field.options.bCSV) {
- errmsg.LogError(0, NO_ERRCODE, "error: can not specify "
- "both csv and json options - json ignored");
+ if(pTpe->data.field.options.bCSV || pTpe->data.field.options.bJSON) {
+ errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
+ "one option out of (json, jsonf, csv) - json ignored");
} else {
pTpe->data.field.options.bJSON = 1;
}
+ } else if(!strcmp((char*)Buf, "jsonf")) {
+ if(pTpe->data.field.options.bCSV || pTpe->data.field.options.bJSON) {
+ errmsg.LogError(0, NO_ERRCODE, "error: can only specify "
+ "one option out of (json, jsonf, csv) - jsonf ignored");
+ } else {
+ pTpe->data.field.options.bJSONf = 1;
+ }
} else {
dbgprintf("Invalid field option '%s' specified - ignored.\n", Buf);
}
@@ -573,7 +580,8 @@ static void doOptions(unsigned char **pp, struct templateEntry *pTpe)
static int do_Parameter(unsigned char **pp, struct template *pTpl)
{
unsigned char *p;
- cstr_t *pStrB;
+ cstr_t *pStrProp;
+ cstr_t *pStrField = NULL;
struct templateEntry *pTpe;
int iNum; /* to compute numbers */
#ifdef FEATURE_REGEXP
@@ -590,7 +598,7 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl)
p = (unsigned char*) *pp;
- if(cstrConstruct(&pStrB) != RS_RET_OK)
+ if(cstrConstruct(&pStrProp) != RS_RET_OK)
return 1;
if((pTpe = tpeConstruct(pTpl)) == NULL) {
@@ -601,25 +609,24 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl)
pTpe->eEntryType = FIELD;
while(*p && *p != '%' && *p != ':') {
- cstrAppendChar(pStrB, tolower(*p));
+ cstrAppendChar(pStrProp, tolower(*p));
++p; /* do NOT do this in tolower()! */
}
/* got the name */
- cstrFinalize(pStrB);
+ cstrFinalize(pStrProp);
- if(propNameToID(pStrB, &pTpe->data.field.propid) != RS_RET_OK) {
- cstrDestruct(&pStrB);
+ if(propNameToID(pStrProp, &pTpe->data.field.propid) != RS_RET_OK) {
+ cstrDestruct(&pStrProp);
return 1;
}
if(pTpe->data.field.propid == PROP_CEE) {
/* in CEE case, we need to preserve the actual property name */
- if((pTpe->data.field.propName = es_newStrFromCStr((char*)cstrGetSzStrNoNULL(pStrB)+2, cstrLen(pStrB)-2)) == NULL) {
- cstrDestruct(&pStrB);
+ if((pTpe->data.field.propName = es_newStrFromCStr((char*)cstrGetSzStrNoNULL(pStrProp)+2, cstrLen(pStrProp)-2)) == NULL) {
+ cstrDestruct(&pStrProp);
return 1;
}
}
- cstrDestruct(&pStrB);
/* Check frompos, if it has an R, then topos should be a regex */
if(*p == ':') {
@@ -873,6 +880,34 @@ static int do_Parameter(unsigned char **pp, struct template *pTpl)
doOptions(&p, pTpe);
}
+ /* check field name */
+ if(*p == ':') {
+ ++p; /* eat ':' */
+ if(cstrConstruct(&pStrField) != RS_RET_OK)
+ return 1;
+ while(*p != ':' && *p != '%' && *p != '\0') {
+ cstrAppendChar(pStrField, *p);
+ ++p;
+ }
+ cstrFinalize(pStrField);
+ }
+
+ /* save field name - if none was given, use the property name instead */
+ if(pStrField == NULL) {
+ if((pTpe->data.field.fieldName =
+ es_newStrFromCStr((char*)cstrGetSzStrNoNULL(pStrProp), cstrLen(pStrProp))) == NULL) {
+ return 1;
+ }
+ } else {
+ if((pTpe->data.field.fieldName =
+ es_newStrFromCStr((char*)cstrGetSzStrNoNULL(pStrField), cstrLen(pStrField))) == NULL) {
+ return 1;
+ }
+ cstrDestruct(&pStrField);
+ }
+
+ cstrDestruct(&pStrProp);
+
if(*p) ++p; /* eat '%' */
*pp = p;
@@ -1130,6 +1165,8 @@ void tplDeleteAll(rsconf_t *conf)
}
if(pTpeDel->data.field.propName != NULL)
es_deleteStr(pTpeDel->data.field.propName);
+ if(pTpeDel->data.field.fieldName != NULL)
+ es_deleteStr(pTpeDel->data.field.fieldName);
#endif
break;
}
diff --git a/template.h b/template.h
index a9eff6b1..f55f64b3 100644
--- a/template.h
+++ b/template.h
@@ -91,6 +91,7 @@ struct templateEntry {
int field_expand; /* use multiple instances of the field delimiter as a single one? */
es_str_t *propName; /**< property name (currently being used for CEE only) */
+ es_str_t *fieldName; /**< field name to be used for structured output */
enum tplFormatTypes eDateFormat;
enum tplFormatCaseConvTypes eCaseConv;
@@ -101,9 +102,10 @@ struct templateEntry {
unsigned bDropLastLF: 1; /* drop last LF char in msg (PIX!) */
unsigned bSecPathDrop: 1; /* drop slashes, replace dots, empty string */
unsigned bSecPathReplace: 1; /* replace slashes, replace dots, empty string */
- unsigned bSPIffNo1stSP: 1; /* replace slashes, replace dots, empty string */
+ unsigned bSPIffNo1stSP: 1; /* be a space if 1st pos if field is no space*/
unsigned bCSV: 1; /* format field in CSV (RFC 4180) format */
unsigned bJSON: 1; /* format field JSON escaped */
+ unsigned bJSONf: 1; /* format field JSON *field* (n/v pair) */
} options; /* options as bit fields */
} field;
} data;
diff --git a/tools/syslogd.c b/tools/syslogd.c
index 2e7a1e23..04379dfb 100644
--- a/tools/syslogd.c
+++ b/tools/syslogd.c
@@ -21,7 +21,7 @@
* For further information, please see http://www.rsyslog.com
*
* rsyslog - An Enhanced syslogd Replacement.
- * Copyright 2003-2011 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2003-2012 Rainer Gerhards and Adiscon GmbH.
*
* This file is part of rsyslog.
*
@@ -143,6 +143,7 @@ DEFobjCurrIf(net) /* TODO: make go away! */
/* forward definitions */
static rsRetVal GlobalClassExit(void);
+static rsRetVal queryLocalHostname(void);
#ifndef _PATH_LOGCONF
@@ -190,7 +191,6 @@ static rsRetVal GlobalClassExit(void);
rsconf_t *ourConf; /* our config object */
static prop_t *pInternalInputName = NULL; /* there is only one global inputName for all internally-generated messages */
-static prop_t *pLocalHostIP = NULL; /* there is only one global IP for all internally-generated messages */
static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */
static char *PidFile = _PATH_LOGPID; /* read-only after startup */
@@ -448,7 +448,8 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags)
MsgSetRawMsgWOSize(pMsg, (char*)msg);
MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp());
- MsgSetRcvFromIP(pMsg, pLocalHostIP);
+dbgprintf("ZZZZ: pLocalHostIPIF used!\n");
+ MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP());
MsgSetMSGoffs(pMsg, 0);
/* check if we have an error code associated and, if so,
* adjust the tag. -- rgerhards, 2008-06-27
@@ -882,8 +883,6 @@ die(int sig)
/* destruct our global properties */
if(pInternalInputName != NULL)
prop.Destruct(&pInternalInputName);
- if(pLocalHostIP != NULL)
- prop.Destruct(&pLocalHostIP);
/* terminate the remaining classes */
GlobalClassExit();
@@ -1258,6 +1257,11 @@ DEFFUNC_llExecFunc(doHUPActions)
* is *NOT* the sighup handler. The signal is recorded by the handler, that record
* detected inside the mainloop and then this function is called to do the
* real work. -- rgerhards, 2008-10-22
+ * Note: there is a VERY slim chance of a data race when the hostname is reset.
+ * We prefer to take this risk rather than sync all accesses, because to the best
+ * of my analysis it can not really hurt (the actual property is reference-counted)
+ * but the sync would require some extra CPU for *each* message processed.
+ * rgerhards, 2012-04-11
*/
static inline void
doHUP(void)
@@ -1273,6 +1277,7 @@ doHUP(void)
logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0);
}
+ queryLocalHostname(); /* re-read our name */
ruleset.IterateAllActions(ourConf, doHUPActions, NULL);
}
@@ -1489,6 +1494,93 @@ GlobalClassExit(void)
}
+/* query our host and domain names - we need to do this early as we may emit
+ * rgerhards, 2012-04-11
+ */
+static rsRetVal
+queryLocalHostname(void)
+{
+ uchar *LocalHostName;
+ uchar *LocalDomain;
+ uchar *LocalFQDNName;
+ uchar *p;
+ struct hostent *hent;
+ DEFiRet;
+
+ net.getLocalHostname(&LocalFQDNName);
+ CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName));
+ glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */
+ if((p = (uchar*)strchr((char*)LocalHostName, '.'))) {
+ *p++ = '\0';
+ LocalDomain = p;
+ } else {
+ LocalDomain = (uchar*)"";
+
+ /* It's not clearly defined whether gethostname()
+ * should return the simple hostname or the fqdn. A
+ * good piece of software should be aware of both and
+ * we want to distribute good software. Joey
+ *
+ * Good software also always checks its return values...
+ * If syslogd starts up before DNS is up & /etc/hosts
+ * doesn't have LocalHostName listed, gethostbyname will
+ * return NULL.
+ */
+ /* TODO: gethostbyname() is not thread-safe, but replacing it is
+ * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25
+ */
+ hent = gethostbyname((char*)LocalHostName);
+ if(hent) {
+ int i = 0;
+
+ if(hent->h_aliases) {
+ size_t hnlen;
+
+ hnlen = strlen((char *) LocalHostName);
+
+ for (i = 0; hent->h_aliases[i]; i++) {
+ if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen)
+ && hent->h_aliases[i][hnlen] == '.') {
+ /* found a matching hostname */
+ break;
+ }
+ }
+ }
+
+ free(LocalHostName);
+ if(hent->h_aliases && hent->h_aliases[i]) {
+ CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i]));
+ } else {
+ CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name));
+ }
+
+ if((p = (uchar*)strchr((char*)LocalHostName, '.')))
+ {
+ *p++ = '\0';
+ LocalDomain = p;
+ }
+ }
+ }
+
+ /* LocalDomain is "" or part of LocalHostName, allocate a new string */
+ CHKmalloc(LocalDomain = (uchar*)strdup((char*)LocalDomain));
+
+ /* Convert to lower case to recognize the correct domain laterly */
+ for(p = LocalDomain ; *p ; p++)
+ *p = (char)tolower((int)*p);
+
+ /* we now have our hostname and can set it inside the global vars.
+ * TODO: think if all of this would better be a runtime function
+ * rgerhards, 2008-04-17
+ */
+ glbl.SetLocalHostName(LocalHostName);
+ glbl.SetLocalDomain(LocalDomain);
+ glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */
+finalize_it:
+ RETiRet;
+}
+
+
/* some support for command line option parsing. Any non-trivial options must be
* buffered until the complete command line has been parsed. This is necessary to
* prevent dependencies between the options. That, in turn, means we need to have
@@ -1691,16 +1783,12 @@ int realMain(int argc, char **argv)
rsRetVal localRet;
register uchar *p;
int ch;
- struct hostent *hent;
extern int optind;
extern char *optarg;
int bEOptionWasGiven = 0;
int iHelperUOpt;
int bChDirRoot = 1; /* change the current working directory to "/"? */
char *arg; /* for command line option processing */
- uchar *LocalHostName;
- uchar *LocalDomain;
- uchar *LocalFQDNName;
char cwdbuf[128]; /* buffer to obtain/display current working directory */
DEFiRet;
@@ -1790,82 +1878,13 @@ int realMain(int argc, char **argv)
/* we need to create the inputName property (only once during our lifetime) */
CHKiRet(prop.Construct(&pInternalInputName));
- CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslgod") - 1));
+ CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd") - 1));
CHKiRet(prop.ConstructFinalize(pInternalInputName));
- CHKiRet(prop.Construct(&pLocalHostIP));
- CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1));
- CHKiRet(prop.ConstructFinalize(pLocalHostIP));
-
/* get our host and domain names - we need to do this early as we may emit
* error log messages, which need the correct hostname. -- rgerhards, 2008-04-04
*/
- net.getLocalHostname(&LocalFQDNName);
- CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName));
- glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */
- if((p = (uchar*)strchr((char*)LocalHostName, '.'))) {
- *p++ = '\0';
- LocalDomain = p;
- } else {
- LocalDomain = (uchar*)"";
-
- /* It's not clearly defined whether gethostname()
- * should return the simple hostname or the fqdn. A
- * good piece of software should be aware of both and
- * we want to distribute good software. Joey
- *
- * Good software also always checks its return values...
- * If syslogd starts up before DNS is up & /etc/hosts
- * doesn't have LocalHostName listed, gethostbyname will
- * return NULL.
- */
- /* TODO: gethostbyname() is not thread-safe, but replacing it is
- * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25
- */
- hent = gethostbyname((char*)LocalHostName);
- if(hent) {
- int i = 0;
-
- if(hent->h_aliases) {
- size_t hnlen;
-
- hnlen = strlen((char *) LocalHostName);
-
- for (i = 0; hent->h_aliases[i]; i++) {
- if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen)
- && hent->h_aliases[i][hnlen] == '.') {
- /* found a matching hostname */
- break;
- }
- }
- }
-
- free(LocalHostName);
- if(hent->h_aliases && hent->h_aliases[i]) {
- CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i]));
- } else {
- CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name));
- }
-
- if((p = (uchar*)strchr((char*)LocalHostName, '.')))
- {
- *p++ = '\0';
- LocalDomain = p;
- }
- }
- }
-
- /* Convert to lower case to recognize the correct domain laterly */
- for(p = LocalDomain ; *p ; p++)
- *p = (char)tolower((int)*p);
-
- /* we now have our hostname and can set it inside the global vars.
- * TODO: think if all of this would better be a runtime function
- * rgerhards, 2008-04-17
- */
- glbl.SetLocalHostName(LocalHostName);
- glbl.SetLocalDomain(LocalDomain);
- glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */
+ queryLocalHostname();
/* initialize the objects */
if((iRet = modInitIminternal()) != RS_RET_OK) {