summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--Makefile.am150
-rw-r--r--action.c2
-rw-r--r--ca.pem14
-rw-r--r--conf.c9
-rw-r--r--configure.ac124
-rw-r--r--dirty.h81
-rw-r--r--doc/features.html6
-rw-r--r--doc/im3195.html46
-rw-r--r--doc/rsyslog_conf.html4
-rw-r--r--doc/rsyslog_ng_comparison.html4
-rw-r--r--doc/src/queueWorkerLogic.dia (renamed from doc/queueWorkerLogic.dia)bin3334 -> 3334 bytes
-rw-r--r--doc/src/tls.diabin0 -> 4656 bytes
-rw-r--r--doc/status.html13
-rw-r--r--glbl.h40
-rw-r--r--gss-misc.c4
-rw-r--r--liblogging-stub.h26
-rw-r--r--omfwd.c644
-rw-r--r--outchannel.c2
-rw-r--r--parse.c2
-rw-r--r--parse.h19
-rw-r--r--plugins/im3195/Makefile.am8
-rw-r--r--plugins/im3195/im3195.c166
-rw-r--r--plugins/imfile/Makefile.am2
-rw-r--r--plugins/imfile/imfile.c12
-rw-r--r--plugins/imgssapi/Makefile.am2
-rw-r--r--plugins/imgssapi/imgssapi.c2
-rw-r--r--plugins/imklog/Makefile.am2
-rw-r--r--plugins/imklog/imklog.c10
-rw-r--r--plugins/imklog/imklog.h2
-rw-r--r--plugins/imklog/linux.c11
-rw-r--r--plugins/immark/Makefile.am2
-rw-r--r--plugins/immark/immark.c4
-rw-r--r--plugins/imrelp/Makefile.am2
-rw-r--r--plugins/imrelp/imrelp.c2
-rw-r--r--plugins/imtcp/Makefile.am2
-rw-r--r--plugins/imtcp/imtcp.c14
-rw-r--r--plugins/imudp/Makefile.am2
-rw-r--r--plugins/imudp/imudp.c8
-rw-r--r--plugins/imuxsock/Makefile.am2
-rw-r--r--plugins/imuxsock/imuxsock.c18
-rw-r--r--plugins/omgssapi/Makefile.am2
-rw-r--r--plugins/omgssapi/omgssapi.c35
-rw-r--r--plugins/omlibdbi/Makefile.am2
-rw-r--r--plugins/omlibdbi/omlibdbi.c2
-rw-r--r--plugins/ommail/Makefile.am2
-rw-r--r--plugins/ommail/ommail.c8
-rw-r--r--plugins/ommysql/Makefile.am2
-rw-r--r--plugins/ommysql/ommysql.c2
-rw-r--r--plugins/ompgsql/Makefile.am2
-rw-r--r--plugins/ompgsql/ompgsql.c2
-rw-r--r--plugins/omrelp/Makefile.am2
-rw-r--r--plugins/omrelp/omrelp.c8
-rw-r--r--plugins/omsnmp/Makefile.am2
-rw-r--r--plugins/omsnmp/omsnmp.c2
-rw-r--r--plugins/omtesting/Makefile.am2
-rw-r--r--plugins/omtesting/omtesting.c2
-rw-r--r--rfc3195d.884
-rw-r--r--rfc3195d.c289
-rw-r--r--runtime/Makefile.am145
-rw-r--r--runtime/atomic.h (renamed from atomic.h)15
-rw-r--r--runtime/cfsysline.c (renamed from cfsysline.c)16
-rw-r--r--runtime/cfsysline.h (renamed from cfsysline.h)15
-rw-r--r--runtime/ctok.c (renamed from ctok.c)0
-rw-r--r--runtime/ctok.h (renamed from ctok.h)0
-rw-r--r--runtime/ctok_token.c (renamed from ctok_token.c)0
-rw-r--r--runtime/ctok_token.h (renamed from ctok_token.h)0
-rw-r--r--runtime/datetime.c (renamed from datetime.c)15
-rw-r--r--runtime/datetime.h (renamed from datetime.h)15
-rw-r--r--runtime/debug.c (renamed from debug.c)15
-rw-r--r--runtime/debug.h (renamed from debug.h)15
-rw-r--r--runtime/errmsg.c (renamed from errmsg.c)29
-rw-r--r--runtime/errmsg.h (renamed from errmsg.h)15
-rw-r--r--runtime/expr.c (renamed from expr.c)0
-rw-r--r--runtime/expr.h (renamed from expr.h)0
-rw-r--r--runtime/glbl.c205
-rw-r--r--runtime/glbl.h59
-rw-r--r--runtime/linkedlist.c (renamed from linkedlist.c)19
-rw-r--r--runtime/linkedlist.h (renamed from linkedlist.h)17
-rw-r--r--runtime/module-template.h (renamed from module-template.h)15
-rw-r--r--runtime/modules.c (renamed from modules.c)16
-rw-r--r--runtime/modules.h (renamed from modules.h)18
-rw-r--r--runtime/msg.c (renamed from msg.c)29
-rw-r--r--runtime/msg.h (renamed from msg.h)16
-rw-r--r--runtime/net.c (renamed from net.c)68
-rw-r--r--runtime/net.h (renamed from net.h)26
-rw-r--r--runtime/netstrm.c305
-rw-r--r--runtime/netstrm.h61
-rw-r--r--runtime/netstrms.c200
-rw-r--r--runtime/netstrms.h52
-rw-r--r--runtime/nsd.h72
-rw-r--r--runtime/nsd_gtls.c444
-rw-r--r--runtime/nsd_gtls.h49
-rw-r--r--runtime/nsd_ptcp.c675
-rw-r--r--runtime/nsd_ptcp.h47
-rw-r--r--runtime/nsdsel_gtls.c184
-rw-r--r--runtime/nsdsel_gtls.h45
-rw-r--r--runtime/nsdsel_ptcp.c222
-rw-r--r--runtime/nsdsel_ptcp.h47
-rw-r--r--runtime/nssel.c229
-rw-r--r--runtime/nssel.h55
-rw-r--r--runtime/obj-types.h (renamed from obj-types.h)59
-rw-r--r--runtime/obj.c (renamed from obj.c)26
-rw-r--r--runtime/obj.h (renamed from obj.h)15
-rw-r--r--runtime/objomsr.c (renamed from objomsr.c)18
-rw-r--r--runtime/objomsr.h (renamed from objomsr.h)15
-rw-r--r--runtime/queue.c (renamed from queue.c)17
-rw-r--r--runtime/queue.h (renamed from queue.h)0
-rw-r--r--runtime/regexp.c (renamed from regexp.c)0
-rw-r--r--runtime/regexp.h (renamed from regexp.h)0
-rw-r--r--runtime/rsyslog.c237
-rw-r--r--runtime/rsyslog.h (renamed from rsyslog.h)97
-rw-r--r--runtime/srUtils.h (renamed from srUtils.h)16
-rw-r--r--runtime/srutils.c (renamed from srUtils.c)66
-rw-r--r--runtime/stream.c (renamed from stream.c)1
-rw-r--r--runtime/stream.h (renamed from stream.h)0
-rw-r--r--runtime/stringbuf.c (renamed from stringbuf.c)17
-rw-r--r--runtime/stringbuf.h (renamed from stringbuf.h)15
-rw-r--r--runtime/sync.c (renamed from sync.c)0
-rw-r--r--runtime/sync.h (renamed from sync.h)0
-rw-r--r--runtime/syslogd-types.h (renamed from syslogd-types.h)19
-rw-r--r--runtime/sysvar.c (renamed from sysvar.c)0
-rw-r--r--runtime/sysvar.h (renamed from sysvar.h)0
-rw-r--r--runtime/var.c (renamed from var.c)0
-rw-r--r--runtime/var.h (renamed from var.h)0
-rw-r--r--runtime/vm.c (renamed from vm.c)0
-rw-r--r--runtime/vm.h (renamed from vm.h)0
-rw-r--r--runtime/vmop.c (renamed from vmop.c)0
-rw-r--r--runtime/vmop.h (renamed from vmop.h)0
-rw-r--r--runtime/vmprg.c (renamed from vmprg.c)0
-rw-r--r--runtime/vmprg.h (renamed from vmprg.h)0
-rw-r--r--runtime/vmstk.c (renamed from vmstk.c)0
-rw-r--r--runtime/vmstk.h (renamed from vmstk.h)0
-rw-r--r--runtime/wti.c (renamed from wti.c)1
-rw-r--r--runtime/wti.h (renamed from wti.h)0
-rw-r--r--runtime/wtp.c (renamed from wtp.c)1
-rw-r--r--runtime/wtp.h (renamed from wtp.h)0
-rw-r--r--tcpclt.c4
-rw-r--r--tcpclt.h1
-rw-r--r--tcps_sess.c47
-rw-r--r--tcps_sess.h14
-rw-r--r--tcpsrv.c421
-rw-r--r--tcpsrv.h20
-rw-r--r--tcpsyslog.c55
-rw-r--r--tcpsyslog.h38
-rw-r--r--template.c2
-rw-r--r--threads.c2
-rw-r--r--threads.h5
-rw-r--r--tools/Makefile.am42
-rw-r--r--tools/iminternal.c (renamed from iminternal.c)0
-rw-r--r--tools/iminternal.h (renamed from iminternal.h)0
-rw-r--r--tools/omdiscard.c (renamed from omdiscard.c)0
-rw-r--r--tools/omdiscard.h (renamed from omdiscard.h)0
-rw-r--r--tools/omfile.c (renamed from omfile.c)5
-rw-r--r--tools/omfile.h (renamed from omfile.h)0
-rw-r--r--tools/omfwd.c625
-rw-r--r--tools/omfwd.h (renamed from omfwd.h)0
-rw-r--r--tools/omshell.c (renamed from omshell.c)0
-rw-r--r--tools/omshell.h (renamed from omshell.h)0
-rw-r--r--tools/omusrmsg.c (renamed from omusrmsg.c)0
-rw-r--r--tools/omusrmsg.h (renamed from omusrmsg.h)0
-rw-r--r--tools/pidfile.c (renamed from pidfile.c)0
-rw-r--r--tools/pidfile.h (renamed from pidfile.h)0
-rw-r--r--tools/rsyslog.conf.5 (renamed from rsyslog.conf.5)0
-rw-r--r--tools/rsyslogd.8 (renamed from rsyslogd.8)0
-rw-r--r--tools/syslogd.c (renamed from syslogd.c)228
-rw-r--r--tools/syslogd.h (renamed from syslogd.h)73
167 files changed, 5237 insertions, 2363 deletions
diff --git a/ChangeLog b/ChangeLog
index 865cfe84..6f73db81 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+---------------------------------------------------------------------------
+Version 3.19.0 (rgerhards), 2008-04-??
+- begins new devel branch version
+- partly rewritten and improved omfwd among others, now loads TCP
+ code only if this is actually necessary
+- implemented im3195, the RFC3195 input as a plugin
+- split of a "runtime library" for rsyslog - this is not yet a clean
+ model, because some modularization is still outstanding. In theory,
+ this shall enable other utilities but rsyslogd to use the same
+ runtime
+- changed directory structure, files are now better organized
+- a lot of cleanup in regard to modularization
+- -c option no longer must be the first option - thanks to varmjofekoj
+ for the patch
+---------------------------------------------------------------------------
Version 3.17.2 (rgerhards), 2008-04-??
- this version is the new beta
- merged in imklog bug fix from v3-stable (3.16.1)
diff --git a/Makefile.am b/Makefile.am
index 0e75710c..a3e67bc8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,125 +1,10 @@
-#sbin_PROGRAMS = rfc3195d rsyslogd
sbin_PROGRAMS =
man_MANS =
-
-if ENABLE_RSYSLOGD
-sbin_PROGRAMS += rsyslogd
-rsyslogd_SOURCES = \
- datetime.c \
- datetime.h \
- errmsg.c \
- errmsg.h \
- syslogd.c \
- syslogd.h \
- sysvar.c \
- sysvar.h \
- vm.c \
- vm.h \
- vmstk.c \
- vmstk.h \
- vmprg.c \
- vmprg.h \
- vmop.c \
- vmop.h \
- debug.c \
- debug.h \
- glbl.h \
- pidfile.c \
- pidfile.h \
- template.c \
- outchannel.c \
- stringbuf.c \
- stringbuf.h \
- srUtils.c \
- srUtils.h \
- parse.c \
- parse.h \
- syslogd-types.h \
- template.h \
- outchannel.h \
- liblogging-stub.h \
- threads.c \
- threads.h \
- stream.c \
- stream.h \
- var.c \
- var.h \
- wtp.c \
- wtp.h \
- wti.c \
- wti.h \
- queue.c \
- queue.h \
- sync.c \
- sync.h \
- obj.c \
- obj.h \
- obj-types.h \
- msg.c \
- msg.h \
- expr.c \
- expr.h \
- ctok.c \
- ctok.h \
- ctok_token.c \
- ctok_token.h \
- conf.c \
- conf.h \
- omshell.c \
- omshell.h \
- omusrmsg.c \
- omusrmsg.h \
- omfwd.c \
- omfwd.h \
- tcpsyslog.c \
- tcpsyslog.h \
- omfile.c \
- omfile.h \
- omdiscard.c \
- omdiscard.h \
- modules.c \
- modules.h \
- module-template.h \
- objomsr.c \
- objomsr.h \
- cfsysline.c \
- cfsysline.h \
- linkedlist.c \
- linkedlist.h \
- iminternal.c \
- iminternal.h \
- action.c \
- action.h \
- atomic.h
-
-rsyslogd_CPPFLAGS = -D_PATH_MODDIR=\"$(pkglibdir)/\" $(pthreads_cflags)
-rsyslogd_LDADD = $(zlib_libs) $(pthreads_libs) $(dl_libs) $(rt_libs)
-rsyslogd_LDFLAGS = -export-dynamic
-
-man_MANS += rsyslogd.8 rsyslog.conf.5
-
-endif # if ENABLE_RSYSLOGD
-
-# now come the library plugins
pkglib_LTLIBRARIES =
-if ENABLE_RFC3195
-# this does so far not work - a manual build is needed
-sbin_PROGRAMS += rfc3195d
-rfc3195d_SOURCES = rfc3195d.c rsyslog.h
-man_MANS += rfc3195d.8
-endif
-
if ENABLE_INET
-pkglib_LTLIBRARIES += lmnet.la lmtcpsrv.la lmtcpclt.la
-#
-# network support
-#
-lmnet_la_SOURCES = net.c net.h
-lmnet_la_CPPFLAGS = $(pthreads_cflags)
-lmnet_la_LDFLAGS = -module -avoid-version
-lmnet_la_LIBADD =
+pkglib_LTLIBRARIES += lmtcpsrv.la lmtcpclt.la
#
#
# TCP (stream) server support
@@ -129,8 +14,8 @@ lmtcpsrv_la_SOURCES = \
tcps_sess.h \
tcpsrv.c \
tcpsrv.h
-lmtcpsrv_la_CPPFLAGS = $(pthreads_cflags)
-lmtcpsrv_la_LDFLAGS = -module -avoid-version
+lmtcpsrv_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmtcpsrv_la_LDFLAGS = -module -avoid-version $(rsrt_libs)
lmtcpsrv_la_LIBADD =
#
@@ -139,31 +24,20 @@ lmtcpsrv_la_LIBADD =
lmtcpclt_la_SOURCES = \
tcpclt.c \
tcpclt.h
-lmtcpclt_la_CPPFLAGS = $(pthreads_cflags)
-lmtcpclt_la_LDFLAGS = -module -avoid-version
+lmtcpclt_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmtcpclt_la_LDFLAGS = -module -avoid-version $(rsrt_libs)
lmtcpclt_la_LIBADD =
endif # if ENABLE_INET
#
-# regular expression support
-#
-if ENABLE_REGEXP
-pkglib_LTLIBRARIES += lmregexp.la
-lmregexp_la_SOURCES = regexp.c regexp.h
-lmregexp_la_CPPFLAGS = $(pthreads_cflags)
-lmregexp_la_LDFLAGS = -module -avoid-version
-lmregexp_la_LIBADD =
-endif
-
-#
# gssapi support
#
if ENABLE_GSSAPI
pkglib_LTLIBRARIES += lmgssutil.la
lmgssutil_la_SOURCES = gss-misc.c gss-misc.h
-lmgssutil_la_CPPFLAGS = $(pthreads_cflags)
-lmgssutil_la_LDFLAGS = -module -avoid-version
+lmgssutil_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmgssutil_la_LDFLAGS = -module -avoid-version $(rsrt_libs)
lmgssutil_la_LIBADD = $(gss_libs)
endif
@@ -179,10 +53,14 @@ EXTRA_DIST = \
COPYING.LESSER \
$(man_MANS)
-SUBDIRS = . doc
+SUBDIRS = doc runtime .
SUBDIRS += plugins/immark plugins/imuxsock plugins/imtcp plugins/imudp plugins/omtesting
+if ENABLE_RSYSLOGD
+SUBDIRS += tools
+endif
+
if ENABLE_IMKLOG
SUBDIRS += plugins/imklog
endif
@@ -222,3 +100,7 @@ endif
if ENABLE_MAIL
SUBDIRS += plugins/ommail
endif
+
+if ENABLE_RFC3195
+SUBDIRS += plugins/im3195
+endif
diff --git a/action.c b/action.c
index 39c37b5b..89ec3f74 100644
--- a/action.c
+++ b/action.c
@@ -34,7 +34,7 @@
#include <time.h>
#include <errno.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "template.h"
#include "action.h"
#include "modules.h"
diff --git a/ca.pem b/ca.pem
new file mode 100644
index 00000000..747250ca
--- /dev/null
+++ b/ca.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICPDCCAaegAwIBAgIBADALBgkqhkiG9w0BAQUwRTELMAkGA1UEBhMCR1IxDDAK
+BgNVBAoTA0ZTRjEPMA0GA1UECxMGR05VVExTMRcwFQYDVQQDEw5HTlVUTFMgVEVT
+VCBDQTAeFw0wNDA2MjgyMjQ0MDBaFw0wNzAzMjQyMjQ0MDBaMEUxCzAJBgNVBAYT
+AkdSMQwwCgYDVQQKEwNGU0YxDzANBgNVBAsTBkdOVVRMUzEXMBUGA1UEAxMOR05V
+VExTIFRFU1QgQ0EwgZwwCwYJKoZIhvcNAQEBA4GMADCBiAKBgMK0cY9Tap5F7DXX
+tu7HpHlZtu+zqfofyLJSIBpUdbiwFIGzB486stbog0mpiy32mGIG5hNlpcRMJMVm
+MmZ1RueqQWR+vdDroBoV199zAZQVww1NmmHi/Wtxa6x9SsXdya+SnoC8KI/V3EKx
+gYG0hYAuYWNA9JnntTU0xCwWOBaPAgMBAAGjQzBBMA8GA1UdEwEB/wQFMAMBAf8w
+DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUeesbb6Nm5nnh0eK129onBkUpCkgw
+CwYJKoZIhvcNAQEFA4GBAGCCzUSCVZOXffm/KFxbyT2Lrltyzqlr0Oknp55eNAIk
+fy+m/viSOmoTCaK9Gmtk3eMAxIeZ8U7TDKrbrxx/NSsggbypqa3EMMwr2JH9kzAZ
+eluQ0vEVqfvRq5jzjuORYYhl7VgqpU0/ctvI3b+9tCZAOCcUX0HPvNweAzYjnkDi
+-----END CERTIFICATE-----
diff --git a/conf.c b/conf.c
index dac46970..dad9ebf2 100644
--- a/conf.c
+++ b/conf.c
@@ -45,7 +45,8 @@
#endif
#include "rsyslog.h"
-#include "syslogd.h"
+#include "syslogd.h" /* this actually *is* part of the syslogd! */
+#include "dirty.h"
#include "parse.h"
#include "action.h"
#include "template.h"
@@ -57,6 +58,10 @@
#include "stringbuf.h"
#include "srUtils.h"
#include "errmsg.h"
+#include "net.h"
+#include "expr.h"
+#include "ctok.h"
+#include "ctok_token.h"
/* forward definitions */
@@ -500,7 +505,6 @@ rsRetVal cflineParseTemplateName(uchar** pp, omodStringRequest_t *pOMSR, int iEn
} else {
/* template specified, pick it up */
if(rsCStrConstruct(&pStrB) != RS_RET_OK) {
- glblHadMemShortage = 1;
iRet = RS_RET_OUT_OF_MEMORY;
goto finalize_it;
}
@@ -563,6 +567,7 @@ cflineParseFileName(uchar* p, uchar *pFileName, omodStringRequest_t *pOMSR, int
* passed back to the caller.
* rgerhards 2005-09-15
*/
+/* GPLv3 - stems back to sysklogd */
static rsRetVal cflineProcessTradPRIFilter(uchar **pline, register selector_t *f)
{
uchar *p;
diff --git a/configure.ac b/configure.ac
index 8a5f6222..d436cec8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,9 +2,9 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT([rsyslog],[3.17.2],[rsyslog@lists.adiscon.com])
+AC_INIT([rsyslog],[3.19.0],[rsyslog@lists.adiscon.com])
AM_INIT_AUTOMAKE
-AC_CONFIG_SRCDIR([syslogd.c])
+AC_CONFIG_SRCDIR([ChangeLog])
AC_CONFIG_HEADERS([config.h])
AC_GNU_SOURCE
@@ -433,42 +433,6 @@ AC_SUBST(libdbi_cflags)
AC_SUBST(libdbi_libs)
-# openssl support
-AC_ARG_ENABLE(openssl,
- [AS_HELP_STRING([--enable-openssl],[Enable openssl support @<:@default=yes@:>@])],
- [case "${enableval}" in
- yes) enable_openssl="yes" ;;
- no) enable_openssl="no" ;;
- *) AC_MSG_ERROR(bad value ${enableval} for --enable-openssl) ;;
- esac],
- [enable_openssl=no]
-)
-if test "x$enable_openssl" = "xyes"; then
- AC_CHECK_HEADERS(
- [openssl/ssl.h],,
- [AC_MSG_FAILURE([openssl is missing])]
- )
- AC_CHECK_LIB(
- [crypto],
- [CRYPTO_new_ex_data],
- [openssl_cflags=""
- openssl_libs="-lcrypto"
- ],
- [AC_MSG_FAILURE([library 'crypto' is missing (needed for openssl)])]
- )
- AC_CHECK_LIB(
- [ssl],
- [SSL_library_init],
- [ openssl_libs+="-lssl"
- ],
- [AC_MSG_FAILURE([library 'ssl' is missing (needed for openssl)])]
- )
-fi
-AM_CONDITIONAL(ENABLE_OPENSSL, test x$enable_openssl = xyes)
-AC_SUBST(openssl_cflags)
-AC_SUBST(openssl_libs)
-
-
# SNMP support
AC_ARG_ENABLE(snmp,
[AS_HELP_STRING([--enable-snmp],[Enable SNMP support @<:@default=no@:>@])],
@@ -498,6 +462,63 @@ AC_SUBST(snmp_cflags)
AC_SUBST(snmp_libs)
+# GNUtls support
+AC_ARG_ENABLE(gnutls,
+ [AS_HELP_STRING([--enable-gnutls],[Enable GNU TLS support @<:@default=yes@:>@])],
+ [case "${enableval}" in
+ yes) enable_gnutls="yes" ;;
+ no) enable_gnutls="no" ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-gnutls) ;;
+ esac],
+ [enable_gnutls=no]
+)
+if test "x$enable_gnutls" = "xyes"; then
+ AC_CHECK_HEADERS(
+ [gnutls/gnutls.h],,
+ [AC_MSG_FAILURE([GNUTls is missing])]
+ )
+ AC_CHECK_PROG(
+ [HAVE_GNUTLS_CONFIG],
+ [libgnutls-config],
+ [yes],,,
+ )
+ if test "x${HAVE_GNUTLS_CONFIG}" != "xyes"; then
+ AC_MSG_FAILURE([libgnutls-config not found in PATH])
+ fi
+ AC_CHECK_LIB(
+ [gnutls],
+ [gnutls_check_version],
+ [gnutls_cflags=`libgnutls-config --cflags`
+ gnutls_libs=`libgnutls-config --libs`
+ ],
+ [AC_MSG_FAILURE([GNU TLS library is missing])],
+ [`libgnutls-config --libs`]
+ )
+fi
+AM_CONDITIONAL(ENABLE_GNUTLS, test x$enable_gnutls = xyes)
+AC_SUBST(gnutls_cflags)
+AC_SUBST(gnutls_libs)
+
+
+# support for building the rsyslogd runtime
+AC_ARG_ENABLE(rsyslogrt,
+ [AS_HELP_STRING([--enable-rsyslogrt],[Build rsyslogrt @<:@default=yes@:>@])],
+ [case "${enableval}" in
+ yes) enable_rsyslogrt="yes" ;;
+ no) enable_rsyslogrt="no" ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-rsyslogrt) ;;
+ esac],
+ [enable_rsyslogrt=yes]
+)
+if test "x$enable_rsyslogrt" = "xyes"; then
+ rsrt_cflags="-I\$(top_srcdir)/runtime -I\$(top_srcdir)"
+ rsrt_libs="\$(top_builddir)/runtime/librsyslog.la"
+fi
+AM_CONDITIONAL(ENABLE_RSYSLOGRT, test x$enable_rsyslogrt = xyes)
+AC_SUBST(rsrt_cflags)
+AC_SUBST(rsrt_libs)
+
+
# support for NOT building rsyslogd (useful for source-based packaging systems)
AC_ARG_ENABLE(rsyslogd,
[AS_HELP_STRING([--enable-rsyslogd],[Build rsyslogd @<:@default=yes@:>@])],
@@ -542,7 +563,6 @@ AC_SUBST(RELP_CFLAGS)
AC_SUBST(RELP_LIBS)
# RFC 3195 support
-# WARNING: THIS IS NOT REALLY PRESENT YET - needs to be build manually!
AC_ARG_ENABLE(rfc3195,
[AS_HELP_STRING([--enable-rfc3195],[Enable RFC3195 support @<:@default=no@:>@])],
[case "${enableval}" in
@@ -553,25 +573,11 @@ AC_ARG_ENABLE(rfc3195,
[enable_rfc3195=no]
)
if test "x$enable_rfc3195" = "xyes"; then
- AC_CHECK_HEADERS(
- [librfc3195.h],,
- [AC_MSG_FAILURE([RFC3195 library is missing (no headers)])]
- )
-# I don't know how to tell that librfc3195 needs -lrt, so I disable
-# this check for now - the header check should work well enough...
-# rgerhards, 2008-03-25
-# AC_CHECK_LIB(
-# [rfc3195],
-# [rfc3195EngineGetVersion],
-# [rfc3195_cflags=""
- rfc3195_libs="-lrfc3195"
-# ],
-# [AC_MSG_FAILURE([RFC3195 library is missing])]
-# )
+ PKG_CHECK_MODULES(LIBLOGGING, liblogging >= 0.7.1)
fi
AM_CONDITIONAL(ENABLE_RFC3195, test x$enable_rfc3195 = xyes)
-AC_SUBST(rfc3195_cflags)
-AC_SUBST(rfc3195_libs)
+AC_SUBST(RFC3195_CFLAGS)
+AC_SUBST(RFC3195_LIBS)
# settings for the template input module; copy and modify this code
@@ -615,9 +621,12 @@ AM_CONDITIONAL(ENABLE_IMTEMPLATE, test x$enable_imtemplate = xyes)
AC_CONFIG_FILES([Makefile \
+ runtime/Makefile \
+ tools/Makefile \
doc/Makefile \
plugins/imudp/Makefile \
plugins/imtcp/Makefile \
+ plugins/im3195/Makefile \
plugins/imgssapi/Makefile \
plugins/imuxsock/Makefile \
plugins/immark/Makefile \
@@ -652,10 +661,11 @@ echo "file input module enabled: $enable_imfile"
echo "input template module will be compiled: $enable_imtemplate"
echo "Large file support enabled: $enable_largefile"
echo "Networking support enabled: $enable_inet"
+echo "GnuTLS network stream driver enabled: $enable_gnutls"
echo "Enable GSSAPI Kerberos 5 support: $want_gssapi_krb5"
echo "Debug mode enabled: $enable_debug"
echo "Runtime Instrumentation enabled: $enable_rtinst"
-echo "openssl enabled: $enable_openssl"
echo "valgrind support settings enabled: $enable_valgrind"
+echo "rsyslog runtime will be built: $enable_rsyslogrt"
echo "rsyslogd will be built: $enable_rsyslogd"
diff --git a/dirty.h b/dirty.h
new file mode 100644
index 00000000..fe188acd
--- /dev/null
+++ b/dirty.h
@@ -0,0 +1,81 @@
+/* This file is an aid to support non-modular object accesses
+ * while we do not have fully modularized everything. Once this is
+ * done, this file can (and should) be deleted. Presence of it
+ * also somewhat indicates that the runtime library is not really
+ * yet a runtime library, because it depends on some functionality
+ * residing somewhere else.
+ *
+ * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#ifndef DIRTY_H_INCLUDED
+#define DIRTY_H_INCLUDED 1
+
+#define MAXLINE 2048 /* maximum line length */
+
+/* Flags to logmsg().
+ */
+#define NOFLAG 0x000 /* no flag is set (to be used when a flag must be specified and none is required) */
+#define INTERNAL_MSG 0x001 /* msg generated by logmsgInternal() --> special handling */
+/* NO LONGER USED: #define SYNC_FILE 0x002 / * do fsync on file after printing */
+#define ADDDATE 0x004 /* add a date to the message */
+#define MARK 0x008 /* this message is a mark */
+
+#define MSG_PARSE_HOSTNAME 1
+#define MSG_DONT_PARSE_HOSTNAME 0
+
+rsRetVal submitMsg(msg_t *pMsg);
+rsRetVal logmsgInternal(int pri, uchar *msg, int flags);
+rsRetVal parseAndSubmitMessage(char *hname, char *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType);
+
+/* TODO: the following 2 need to go in conf obj interface... */
+rsRetVal cflineParseTemplateName(uchar** pp, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *dfltTplName);
+rsRetVal cflineParseFileName(uchar* p, uchar *pFileName, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *pszTpl);
+
+/* Intervals at which we flush out "message repeated" messages,
+ * in seconds after previous message is logged. After each flush,
+ * we move to the next interval until we reach the largest.
+ * TODO: move this to action object! Only action.c and syslogd.c use it.
+ */
+extern int bActExecWhenPrevSusp;
+extern int iActExecOnceInterval;
+extern int MarkInterval;
+extern int repeatinterval[2];
+extern int bReduceRepeatMsgs;
+#define MAXREPEAT ((int)((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1))
+#define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount])
+#define BACKOFF(f) { if (++(f)->f_repeatcount > MAXREPEAT) \
+ (f)->f_repeatcount = MAXREPEAT; \
+ }
+#ifdef USE_NETZIP
+/* config param: minimum message size to try compression. The smaller
+ * the message, the less likely is any compression gain. We check for
+ * gain before we submit the message. But to do so we still need to
+ * do the (costly) compress() call. The following setting sets a size
+ * for which no call to compress() is done at all. This may result in
+ * a few more bytes being transmited but better overall performance.
+ * Note: I have not yet checked the minimum UDP packet size. It might be
+ * that we do not save anything by compressing very small messages, because
+ * UDP might need to pad ;)
+ * rgerhards, 2006-11-30
+ */
+#define MIN_SIZE_FOR_COMPRESS 60
+#endif
+
+#endif /* #ifndef DIRTY_H_INCLUDED */
diff --git a/doc/features.html b/doc/features.html
index 13fc34c6..f9d17818 100644
--- a/doc/features.html
+++ b/doc/features.html
@@ -101,10 +101,8 @@ typically within reach of implementation. Users are encouraged to
submit feature requests there (or via our forums). If we like them but
they look quite long-lived (aka "not soon to be implemented"), they
will possibly be migrated to this list here and at some time moved back
-to the sourceforge tracker.</p>
+to the bugzilla tracker.</p>
<ul>
-<li>implement native email-functionality in selector (probably
-best done as a plug-in)</li>
<li>port it to more *nix variants (eg AIX and HP UX) - this
needs volunteers with access to those machines and knowledge </li>
<li>support for native SSL enryption of plain tcp syslog
@@ -124,4 +122,4 @@ future of RFC 3195 in rsyslog</a>.</li>
<p>To see when each feature was added, see the
<a href="http://www.rsyslog.com/Topic4.phtml">rsyslog
change log</a> (online only).</p>
-</body></html> \ No newline at end of file
+</body></html>
diff --git a/doc/im3195.html b/doc/im3195.html
new file mode 100644
index 00000000..d6f2f2ed
--- /dev/null
+++ b/doc/im3195.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<title>RFC3195 Input Module (im3195)</title>
+
+</head>
+<body>
+<h1>RFC3195 Input Module</h1>
+<p><b>Module Name:&nbsp;&nbsp;&nbsp; im3195</b></p>
+<p><b>Author: </b>Rainer Gerhards
+&lt;rgerhards@adiscon.com&gt;</p>
+<p><b>Description</b>:</p>
+<p>Receives syslog messages via RFC 3195. The RAW profile is fully implemented and the
+COOKED profile is provided in an experimental state. This module uses
+<a href="http://www.liblogging.org">liblogging</a> for the actual protocol handling.</p>
+<p><b>Configuration Directives</b>:</p>
+<ul>
+<li><strong>$Input3195ListenPort &lt;port&gt;</strong><br>
+The port on which imklog listens for RFC 3195 messages. The default port is 601
+(the IANA-assigned port)</li>
+</ul>
+<b>Caveats/Known Bugs:</b>
+<p>Due to no demand at all for RFC3195, we have converted rfc3195d
+to this input module, but we have NOT conducted any testing. Also,
+the module does not yet properly handle the recovery case. If someone
+intends to put this module into production, good testing should be
+cunducted. It also is a good idea to notify the rsyslog project that you intend to use
+it in production. In this case, we'll probably give the module another
+cleanup. We don't do this now because so far it looks just like a big
+waste of time.
+<p>Currently only a single listener can be defined. That one binds to all interfaces.</p>
+<p><b>Sample:</b></p>
+<p>The following sample accepts syslog messages via RFC 3195 on port 1601.
+<br>
+</p>
+<textarea rows="15" cols="60">$ModLoad im3195
+$Input3195ListenPort 1601
+</textarea>
+<p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>]
+[<a href="manual.html">manual index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p>
+<p><font size="2">This documentation is part of the
+<a href="http://www.rsyslog.com/">rsyslog</a> project.<br>
+Copyright &copy; 2008 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/rsyslog_conf.html b/doc/rsyslog_conf.html
index 9325f73c..4dcef903 100644
--- a/doc/rsyslog_conf.html
+++ b/doc/rsyslog_conf.html
@@ -50,6 +50,8 @@ input plugin for plain tcp and GSS-enable syslog</li>
<li><a href="imklog.html">imklog</a> - kernel logging</li>
<li><a href="imuxsock.html">imuxsock</a> -
unix sockets, including the system log socket</li>
+<li><a href="im3195.html">im3195</a> -
+accepts syslog messages via RFC 3195</li>
</ul>
<p>Please note that each module provides configuration
directives, which are NOT necessarily being listed below. Also
@@ -1190,4 +1192,4 @@ additional
and database support). For obvious reasons, the syntax for defining
such features is available in rsyslogd, only.<br>
&nbsp;</p>
-</body></html> \ No newline at end of file
+</body></html>
diff --git a/doc/rsyslog_ng_comparison.html b/doc/rsyslog_ng_comparison.html
index 28413337..0d57a374 100644
--- a/doc/rsyslog_ng_comparison.html
+++ b/doc/rsyslog_ng_comparison.html
@@ -57,7 +57,7 @@ comparison sheet, so please don't be shy ;)</p>
</tr>
<tr>
<td valign="top">RFC 3195/BEEP</td>
-<td valign="top">yes (needs separate build process)</td>
+<td valign="top">yes (via <a href="im3195.html">im3195</a>)</td>
<td valign="top">no</td>
<td></td>
</tr>
@@ -580,4 +580,4 @@ the mean time, you may want to read it in parallel. It is available at
site</a>.</p>
<p>This document is current as of 2008-04-08 and definitely
incomplete (I did not yet manage to complete it!).</p>
-</body></html> \ No newline at end of file
+</body></html>
diff --git a/doc/queueWorkerLogic.dia b/doc/src/queueWorkerLogic.dia
index 068ea50c..068ea50c 100644
--- a/doc/queueWorkerLogic.dia
+++ b/doc/src/queueWorkerLogic.dia
Binary files differ
diff --git a/doc/src/tls.dia b/doc/src/tls.dia
new file mode 100644
index 00000000..77e5d185
--- /dev/null
+++ b/doc/src/tls.dia
Binary files differ
diff --git a/doc/status.html b/doc/status.html
index 63a3f588..3ff8a625 100644
--- a/doc/status.html
+++ b/doc/status.html
@@ -2,19 +2,20 @@
<html><head><title>rsyslog status page</title></head>
<body>
<h2>rsyslog status page</h2>
-<p>This page reflects the status as of 2008-04-15.</p>
+<p>This page reflects the status as of 2008-04-24.</p>
<h2>Current Releases</h2>
<p><b>development:</b> 3.17.1 -
<a href="http://www.rsyslog.com/Article213.phtml">change log</a> -
<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-98.phtml">download</a>
-<br><b>beta:</b> 3.15.1 -
-<a href="http://www.rsyslog.com/Article210.phtml">change log</a> -
-<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-97.phtml">download</a></p>
+<!--<br><b>beta:</b> 3.17.2 -
+<a href="http://www.rsyslog.com/Article213.phtml">change log</a> -
+<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-98.phtml">download</a></p>
+-->
-<p><b>v3 stable:</b> 3.14.2 - <a href="http://www.rsyslog.com/Article209.phtml">change log</a> -
-<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-96.phtml">download</a>
+<p><b>v3 stable:</b> 3.16.0 - <a href="http://www.rsyslog.com/Article215.phtml">change log</a> -
+<a href="http://www.rsyslog.com/Downloads-req-viewdownloaddetails-lid-99.phtml">download</a>
<br><b>v2 stable:</b> 2.0.4 - <a href="http://www.rsyslog.com/Article197.phtml">change log</a> -
<a href="http://www.rsyslog.com/Downloads-index-req-getit-lid-90.phtml">download</a>
diff --git a/glbl.h b/glbl.h
deleted file mode 100644
index 6d08ddd5..00000000
--- a/glbl.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Definition of globally-accessible data items.
- *
- * This module provides access methods to items of global scope. Most often,
- * these globals serve as defaults to initialize local settings. Currently,
- * many of them are either constants or global variable references. However,
- * this module provides the necessary hooks to change that at any time.
- *
- * Please note that there currently is no glbl.c file as we do not yet
- * have any implementations.
- *
- * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-
-#ifndef GLOBALS_H_INCLUDED
-#define GLOBALS_H_INCLUDED
-
-#define glblGetIOBufSize() 4096 /* size of the IO buffer, e.g. for strm class */
-
-extern uchar *glblModPath; /* module load path */
-extern uchar *pszWorkDir;
-#define glblGetWorkDir() (pszWorkDir == NULL ? (uchar*) "" : pszWorkDir)
-
-#endif /* #ifndef GLOBALS_H_INCLUDED */
diff --git a/gss-misc.c b/gss-misc.c
index a80f2e6b..4f0df748 100644
--- a/gss-misc.c
+++ b/gss-misc.c
@@ -41,14 +41,12 @@
#include <fcntl.h>
#endif
#include <gssapi/gssapi.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "srUtils.h"
#include "net.h"
-#include "omfwd.h"
#include "template.h"
#include "msg.h"
-#include "tcpsyslog.h"
#include "module-template.h"
#include "obj.h"
#include "errmsg.h"
diff --git a/liblogging-stub.h b/liblogging-stub.h
deleted file mode 100644
index 03315f08..00000000
--- a/liblogging-stub.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* This is a (now *very slim*) stub for some liblogging
- * code we use in rsyslog.
- *
- * Copyright (C) 2004, 2007 by Rainer Gerhards and Adiscon GmbH
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#ifndef __LIB3195_LIBLOGGINGSTUB_H_INCLUDED__
-#define __LIB3195_LIBLOGGINGSTUB_H_INCLUDED__ 1
-#include <stdio.h>
-#endif
diff --git a/omfwd.c b/omfwd.c
deleted file mode 100644
index 67ef4b64..00000000
--- a/omfwd.c
+++ /dev/null
@@ -1,644 +0,0 @@
-/* omfwd.c
- * This is the implementation of the build-in forwarding output module.
- *
- * NOTE: read comments in module-template.h to understand how this file
- * works!
- *
- * File begun on 2007-07-20 by RGerhards (extracted from syslogd.c)
- * This file is under development and has not yet arrived at being fully
- * self-contained and a real object. So far, it is mostly an excerpt
- * of the "old" message code without any modifications. However, it
- * helps to have things at the right place one we go to the meat of it.
- *
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#include "config.h"
-#ifdef SYSLOG_INET
-#include "rsyslog.h"
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <fnmatch.h>
-#include <assert.h>
-#include <errno.h>
-#include <ctype.h>
-#include <unistd.h>
-#ifdef USE_NETZIP
-#include <zlib.h>
-#endif
-#include <pthread.h>
-#include "syslogd.h"
-#include "syslogd-types.h"
-#include "srUtils.h"
-#include "net.h"
-#include "omfwd.h"
-#include "template.h"
-#include "msg.h"
-#include "tcpsyslog.h"
-#include "tcpclt.h"
-#include "cfsysline.h"
-#include "module-template.h"
-#include "errmsg.h"
-
-MODULE_TYPE_OUTPUT
-
-/* internal structures
- */
-DEF_OMOD_STATIC_DATA
-DEFobjCurrIf(errmsg)
-DEFobjCurrIf(net)
-DEFobjCurrIf(tcpclt)
-
-typedef struct _instanceData {
- char *f_hname;
- short sock; /* file descriptor */
- int *pSockArray; /* sockets to use for UDP */
- enum { /* TODO: we shoud revisit these definitions */
- eDestFORW,
- eDestFORW_SUSP,
- eDestFORW_UNKN
- } eDestState;
- struct addrinfo *f_addr;
- int compressionLevel; /* 0 - no compression, else level for zlib */
- char *port;
- int protocol;
-# define FORW_UDP 0
-# define FORW_TCP 1
- /* following fields for TCP-based delivery */
- time_t ttSuspend; /* time selector was suspended */
- tcpclt_t *pTCPClt; /* our tcpclt object */
-} instanceData;
-
-/* config data */
-static uchar *pszTplName = NULL; /* name of the default template to use */
-
-
-/* get the syslog forward port from selector_t. The passed in
- * struct must be one that is setup for forwarding.
- * rgerhards, 2007-06-28
- * We may change the implementation to try to lookup the port
- * if it is unspecified. So far, we use the IANA default auf 514.
- */
-static char *getFwdSyslogPt(instanceData *pData)
-{
- assert(pData != NULL);
- if(pData->port == NULL)
- return("514");
- else
- return(pData->port);
-}
-
-BEGINcreateInstance
-CODESTARTcreateInstance
- pData->sock = -1;
-ENDcreateInstance
-
-
-BEGINisCompatibleWithFeature
-CODESTARTisCompatibleWithFeature
- if(eFeat == sFEATURERepeatedMsgReduction)
- iRet = RS_RET_OK;
-ENDisCompatibleWithFeature
-
-
-BEGINfreeInstance
-CODESTARTfreeInstance
- switch (pData->eDestState) {
- case eDestFORW:
- case eDestFORW_SUSP:
- freeaddrinfo(pData->f_addr);
- /* fall through */
- case eDestFORW_UNKN:
- if(pData->port != NULL)
- free(pData->port);
- break;
- }
-
- /* final cleanup */
- if(pData->sock >= 0)
- close(pData->sock);
- if(pData->pSockArray != NULL)
- net.closeUDPListenSockets(pData->pSockArray);
-
- if(pData->protocol == FORW_TCP) {
- tcpclt.Destruct(&pData->pTCPClt);
- }
-
- if(pData->f_hname != NULL)
- free(pData->f_hname);
-
-ENDfreeInstance
-
-
-BEGINdbgPrintInstInfo
-CODESTARTdbgPrintInstInfo
- printf("%s", pData->f_hname);
-ENDdbgPrintInstInfo
-
-
-/* Send a message via UDP
- * rgehards, 2007-12-20
- */
-static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len)
-{
- DEFiRet;
- struct addrinfo *r;
- int i;
- unsigned lsent = 0;
- int bSendSuccess;
-
- if(pData->pSockArray != NULL) {
- /* we need to track if we have success sending to the remote
- * peer. Success is indicated by at least one sendto() call
- * succeeding. We track this be bSendSuccess. We can not simply
- * rely on lsent, as a call might initially work, but a later
- * call fails. Then, lsent has the error status, even though
- * the sendto() succeeded.
- * rgerhards, 2007-06-22
- */
- bSendSuccess = FALSE;
- for (r = pData->f_addr; r; r = r->ai_next) {
- for (i = 0; i < *pData->pSockArray; i++) {
- lsent = sendto(pData->pSockArray[i+1], msg, len, 0, r->ai_addr, r->ai_addrlen);
- if (lsent == len) {
- bSendSuccess = TRUE;
- break;
- } else {
- int eno = errno;
- char errStr[1024];
- dbgprintf("sendto() error: %d = %s.\n",
- eno, rs_strerror_r(eno, errStr, sizeof(errStr)));
- }
- }
- if (lsent == len && !send_to_all)
- break;
- }
- /* finished looping */
- if (bSendSuccess == FALSE) {
- dbgprintf("error forwarding via udp, suspending\n");
- iRet = RS_RET_SUSPENDED;
- }
- }
-
- RETiRet;
-}
-
-/* CODE FOR SENDING TCP MESSAGES */
-
-
-/* Send a frame via plain TCP protocol
- * rgerhards, 2007-12-28
- */
-static rsRetVal TCPSendFrame(void *pvData, char *msg, size_t len)
-{
- DEFiRet;
- ssize_t lenSend;
- instanceData *pData = (instanceData *) pvData;
-
- lenSend = send(pData->sock, msg, len, 0);
- dbgprintf("TCP sent %ld bytes, requested %ld\n", (long) lenSend, (long) len);
-
- if(lenSend == -1) {
- /* we have an error case - check what we can live with */
- switch(errno) {
- case EMSGSIZE:
- dbgprintf("message not (tcp)send, too large\n");
- /* This is not a real error, so it is not flagged as one */
- break;
- default:
- dbgprintf("message not (tcp)send");
- iRet = RS_RET_TCP_SEND_ERROR;
- break;
- }
- } else if(lenSend != (ssize_t) len) {
- /* no real error, could "just" not send everything...
- * For the time being, we ignore this...
- * rgerhards, 2005-10-25
- */
- dbgprintf("message not completely (tcp)send, ignoring %ld\n", (long) lenSend);
- usleep(1000); /* experimental - might be benefitial in this situation */
- /* TODO: we need to revisit this code -- rgerhards, 2007-12-28 */
- }
-
- RETiRet;
-}
-
-
-/* This function is called immediately before a send retry is attempted.
- * It shall clean up whatever makes sense.
- * rgerhards, 2007-12-28
- */
-static rsRetVal TCPSendPrepRetry(void *pvData)
-{
- DEFiRet;
- instanceData *pData = (instanceData *) pvData;
-
- assert(pData != NULL);
- close(pData->sock);
- pData->sock = -1;
- RETiRet;
-}
-
-
-/* initialies everything so that TCPSend can work.
- * rgerhards, 2007-12-28
- */
-static rsRetVal TCPSendInit(void *pvData)
-{
- DEFiRet;
- instanceData *pData = (instanceData *) pvData;
-
- assert(pData != NULL);
- if(pData->sock < 0) {
- if((pData->sock = tcpclt.CreateSocket(pData->f_addr)) < 0)
- iRet = RS_RET_TCP_SOCKCREATE_ERR;
- }
-
- RETiRet;
-}
-
-
-/* try to resume connection if it is not ready
- * rgerhards, 2007-08-02
- */
-static rsRetVal doTryResume(instanceData *pData)
-{
- DEFiRet;
- struct addrinfo *res;
- struct addrinfo hints;
- unsigned e;
-
- switch (pData->eDestState) {
- case eDestFORW_SUSP:
- iRet = RS_RET_OK; /* the actual check happens during doAction() only */
- pData->eDestState = eDestFORW;
- break;
-
- case eDestFORW_UNKN:
- /* The remote address is not yet known and needs to be obtained */
- dbgprintf(" %s\n", pData->f_hname);
- memset(&hints, 0, sizeof(hints));
- /* port must be numeric, because config file syntax requests this */
- /* TODO: this code is a duplicate from cfline() - we should later create
- * a common function.
- */
- hints.ai_flags = AI_NUMERICSERV;
- hints.ai_family = family;
- hints.ai_socktype = pData->protocol == FORW_UDP ? SOCK_DGRAM : SOCK_STREAM;
- if((e = getaddrinfo(pData->f_hname,
- getFwdSyslogPt(pData), &hints, &res)) == 0) {
- dbgprintf("%s found, resuming.\n", pData->f_hname);
- pData->f_addr = res;
- pData->eDestState = eDestFORW;
- } else {
- iRet = RS_RET_SUSPENDED;
- }
- break;
- case eDestFORW:
- /* rgerhards, 2007-09-11: this can not happen, but I've included it to
- * a) make the compiler happy, b) detect any logic errors */
- assert(0);
- break;
- }
-
- RETiRet;
-}
-
-
-BEGINtryResume
-CODESTARTtryResume
- iRet = doTryResume(pData);
-ENDtryResume
-
-BEGINdoAction
- char *psz; /* temporary buffering */
- register unsigned l;
-CODESTARTdoAction
- switch (pData->eDestState) {
- case eDestFORW_SUSP:
- dbgprintf("internal error in omfwd.c, eDestFORW_SUSP in doAction()!\n");
- iRet = RS_RET_SUSPENDED;
- break;
-
- case eDestFORW_UNKN:
- dbgprintf("doAction eDestFORW_UNKN\n");
- iRet = doTryResume(pData);
- break;
-
- case eDestFORW:
- dbgprintf(" %s:%s/%s\n", pData->f_hname, getFwdSyslogPt(pData),
- pData->protocol == FORW_UDP ? "udp" : "tcp");
- /* with UDP, check if the socket is there and, if not, alloc
- * it. TODO: there should be a better place for that code.
- * rgerhards, 2007-12-26
- */
- if(pData->protocol == FORW_UDP) {
- if(pData->pSockArray == NULL) {
- pData->pSockArray = net.create_udp_socket((uchar*)pData->f_hname, NULL, 0);
- }
- }
- pData->ttSuspend = time(NULL);
- psz = (char*) ppString[0];
- l = strlen((char*) psz);
- if (l > MAXLINE)
- l = MAXLINE;
-
-# ifdef USE_NETZIP
- /* Check if we should compress and, if so, do it. We also
- * check if the message is large enough to justify compression.
- * The smaller the message, the less likely is a gain in compression.
- * To save CPU cycles, we do not try to compress very small messages.
- * What "very small" means needs to be configured. Currently, it is
- * hard-coded but this may be changed to a config parameter.
- * rgerhards, 2006-11-30
- */
- if(pData->compressionLevel && (l > MIN_SIZE_FOR_COMPRESS)) {
- Bytef out[MAXLINE+MAXLINE/100+12] = "z";
- uLongf destLen = sizeof(out) / sizeof(Bytef);
- uLong srcLen = l;
- int ret;
- ret = compress2((Bytef*) out+1, &destLen, (Bytef*) psz,
- srcLen, pData->compressionLevel);
- dbgprintf("Compressing message, length was %d now %d, return state %d.\n",
- l, (int) destLen, ret);
- if(ret != Z_OK) {
- /* if we fail, we complain, but only in debug mode
- * Otherwise, we are silent. In any case, we ignore the
- * failed compression and just sent the uncompressed
- * data, which is still valid. So this is probably the
- * best course of action.
- * rgerhards, 2006-11-30
- */
- dbgprintf("Compression failed, sending uncompressed message\n");
- } else if(destLen+1 < l) {
- /* only use compression if there is a gain in using it! */
- dbgprintf("there is gain in compression, so we do it\n");
- psz = (char*) out;
- l = destLen + 1; /* take care for the "z" at message start! */
- }
- ++destLen;
- }
-# endif
-
- if(pData->protocol == FORW_UDP) {
- /* forward via UDP */
- CHKiRet(UDPSend(pData, psz, l));
- } else {
- /* forward via TCP */
- rsRetVal ret;
- ret = tcpclt.Send(pData->pTCPClt, pData, psz, l);
- if(ret != RS_RET_OK) {
- /* error! */
- dbgprintf("error forwarding via tcp, suspending\n");
- pData->eDestState = eDestFORW_SUSP;
- iRet = RS_RET_SUSPENDED;
- }
- }
- break;
- }
-finalize_it:
-ENDdoAction
-
-
-BEGINparseSelectorAct
- uchar *q;
- int i;
- int error;
- int bErr;
- struct addrinfo hints, *res;
- TCPFRAMINGMODE tcp_framing = TCP_FRAMING_OCTET_STUFFING;
-CODESTARTparseSelectorAct
-CODE_STD_STRING_REQUESTparseSelectorAct(1)
- if(*p == '@') {
- if((iRet = createInstance(&pData)) != RS_RET_OK)
- goto finalize_it;
- ++p; /* eat '@' */
- if(*p == '@') { /* indicator for TCP! */
- pData->protocol = FORW_TCP;
- ++p; /* eat this '@', too */
- } else {
- pData->protocol = FORW_UDP;
- }
- /* we are now after the protocol indicator. Now check if we should
- * use compression. We begin to use a new option format for this:
- * @(option,option)host:port
- * The first option defined is "z[0..9]" where the digit indicates
- * the compression level. If it is not given, 9 (best compression) is
- * assumed. An example action statement might be:
- * @@(z5,o)127.0.0.1:1400
- * Which means send via TCP with medium (5) compresion (z) to the local
- * host on port 1400. The '0' option means that octet-couting (as in
- * IETF I-D syslog-transport-tls) is to be used for framing (this option
- * applies to TCP-based syslog only and is ignored when specified with UDP).
- * That is not yet implemented.
- * rgerhards, 2006-12-07
- */
- if(*p == '(') {
- /* at this position, it *must* be an option indicator */
- do {
- ++p; /* eat '(' or ',' (depending on when called) */
- /* check options */
- if(*p == 'z') { /* compression */
-# ifdef USE_NETZIP
- ++p; /* eat */
- if(isdigit((int) *p)) {
- int iLevel;
- iLevel = *p - '0';
- ++p; /* eat */
- pData->compressionLevel = iLevel;
- } else {
- errmsg.LogError(NO_ERRCODE, "Invalid compression level '%c' specified in "
- "forwardig action - NOT turning on compression.",
- *p);
- }
-# else
- errmsg.LogError(NO_ERRCODE, "Compression requested, but rsyslogd is not compiled "
- "with compression support - request ignored.");
-# endif /* #ifdef USE_NETZIP */
- } else if(*p == 'o') { /* octet-couting based TCP framing? */
- ++p; /* eat */
- /* no further options settable */
- tcp_framing = TCP_FRAMING_OCTET_COUNTING;
- } else { /* invalid option! Just skip it... */
- errmsg.LogError(NO_ERRCODE, "Invalid option %c in forwarding action - ignoring.", *p);
- ++p; /* eat invalid option */
- }
- /* the option processing is done. We now do a generic skip
- * to either the next option or the end of the option
- * block.
- */
- while(*p && *p != ')' && *p != ',')
- ++p; /* just skip it */
- } while(*p && *p == ','); /* Attention: do.. while() */
- if(*p == ')')
- ++p; /* eat terminator, on to next */
- else
- /* we probably have end of string - leave it for the rest
- * of the code to handle it (but warn the user)
- */
- errmsg.LogError(NO_ERRCODE, "Option block not terminated in forwarding action.");
- }
- /* extract the host first (we do a trick - we replace the ';' or ':' with a '\0')
- * now skip to port and then template name. rgerhards 2005-07-06
- */
- for(q = p ; *p && *p != ';' && *p != ':' ; ++p)
- /* JUST SKIP */;
-
- pData->port = NULL;
- if(*p == ':') { /* process port */
- uchar * tmp;
-
- *p = '\0'; /* trick to obtain hostname (later)! */
- tmp = ++p;
- for(i=0 ; *p && isdigit((int) *p) ; ++p, ++i)
- /* SKIP AND COUNT */;
- pData->port = malloc(i + 1);
- if(pData->port == NULL) {
- errmsg.LogError(NO_ERRCODE, "Could not get memory to store syslog forwarding port, "
- "using default port, results may not be what you intend\n");
- /* we leave f_forw.port set to NULL, this is then handled by
- * getFwdSyslogPt().
- */
- } else {
- memcpy(pData->port, tmp, i);
- *(pData->port + i) = '\0';
- }
- }
-
- /* now skip to template */
- bErr = 0;
- while(*p && *p != ';') {
- if(*p && *p != ';' && !isspace((int) *p)) {
- if(bErr == 0) { /* only 1 error msg! */
- bErr = 1;
- errno = 0;
- errmsg.LogError(NO_ERRCODE, "invalid selector line (port), probably not doing "
- "what was intended");
- }
- }
- ++p;
- }
-
- /* TODO: make this if go away! */
- if(*p == ';') {
- *p = '\0'; /* trick to obtain hostname (later)! */
- CHKmalloc(pData->f_hname = strdup((char*) q));
- *p = ';';
- } else {
- CHKmalloc(pData->f_hname = strdup((char*) q));
- }
-
- /* process template */
- CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
- (pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : pszTplName));
-
- /* first set the pData->eDestState */
- memset(&hints, 0, sizeof(hints));
- /* port must be numeric, because config file syntax requests this */
- hints.ai_flags = AI_NUMERICSERV;
- hints.ai_family = family;
- hints.ai_socktype = pData->protocol == FORW_UDP ? SOCK_DGRAM : SOCK_STREAM;
- if( (error = getaddrinfo(pData->f_hname, getFwdSyslogPt(pData), &hints, &res)) != 0) {
- pData->eDestState = eDestFORW_UNKN;
- pData->ttSuspend = time(NULL);
- } else {
- pData->eDestState = eDestFORW;
- pData->f_addr = res;
- }
- /*
- * Otherwise the host might be unknown due to an
- * inaccessible nameserver (perhaps on the same
- * host). We try to get the ip number later, like
- * FORW_SUSP.
- */
- if(pData->protocol == FORW_TCP) {
- /* create our tcpclt */
- CHKiRet(tcpclt.Construct(&pData->pTCPClt));
- /* and set callbacks */
- CHKiRet(tcpclt.SetSendInit(pData->pTCPClt, TCPSendInit));
- CHKiRet(tcpclt.SetSendFrame(pData->pTCPClt, TCPSendFrame));
- CHKiRet(tcpclt.SetSendPrepRetry(pData->pTCPClt, TCPSendPrepRetry));
- CHKiRet(tcpclt.SetFraming(pData->pTCPClt, tcp_framing));
- }
-
- } else {
- iRet = RS_RET_CONFLINE_UNPROCESSED;
- }
-
- /* TODO: do we need to call freeInstance if we failed - this is a general question for
- * all output modules. I'll address it lates as the interface evolves. rgerhards, 2007-07-25
- */
-CODE_STD_FINALIZERparseSelectorAct
-ENDparseSelectorAct
-
-
-BEGINmodExit
-CODESTARTmodExit
- /* release what we no longer need */
- objRelease(errmsg, CORE_COMPONENT);
- objRelease(net, LM_NET_FILENAME);
- objRelease(tcpclt, LM_TCPCLT_FILENAME);
-
- if(pszTplName != NULL) {
- free(pszTplName);
- pszTplName = NULL;
- }
-ENDmodExit
-
-
-BEGINqueryEtryPt
-CODESTARTqueryEtryPt
-CODEqueryEtryPt_STD_OMOD_QUERIES
-ENDqueryEtryPt
-
-
-/* Reset config variables for this module to default values.
- * rgerhards, 2008-03-28
- */
-static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
-{
- if(pszTplName != NULL) {
- free(pszTplName);
- pszTplName = NULL;
- }
-
- return RS_RET_OK;
-}
-
-
-BEGINmodInit(Fwd)
-CODESTARTmodInit
- *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
-CODEmodInit_QueryRegCFSLineHdlr
- CHKiRet(objUse(errmsg, CORE_COMPONENT));
- CHKiRet(objUse(net, LM_NET_FILENAME));
- CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME));
-
- CHKiRet(regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL));
- CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
-ENDmodInit
-
-#endif /* #ifdef SYSLOG_INET */
-/* vim:set ai:
- */
diff --git a/outchannel.c b/outchannel.c
index d013ea08..5c348b63 100644
--- a/outchannel.c
+++ b/outchannel.c
@@ -37,7 +37,7 @@
#include <assert.h>
#include "stringbuf.h"
#include "outchannel.h"
-#include "syslogd.h"
+#include "dirty.h"
static struct outchannel *ochRoot = NULL; /* the root of the outchannel list */
static struct outchannel *ochLast = NULL; /* points to the last element of the outchannel list */
diff --git a/parse.c b/parse.c
index 171e5355..58458d62 100644
--- a/parse.c
+++ b/parse.c
@@ -3,7 +3,7 @@
*
* begun 2005-09-15 rgerhards
*
- * Copyright 2005
+ * Copyright 2005-2008
* Rainer Gerhards and Adiscon GmbH. All Rights Reserved.
*
* This file is part of rsyslog.
diff --git a/parse.h b/parse.h
index b7ac950d..0fe2bb74 100644
--- a/parse.h
+++ b/parse.h
@@ -101,24 +101,9 @@ int parsIsAtEndOfParseString(rsParsObj *pThis);
int parsGetCurrentPosition(rsParsObj *pThis);
char parsPeekAtCharAtParsPtr(rsParsObj *pThis);
#ifdef SYSLOG_INET
-rsRetVal parsAddrWithBits(rsParsObj *pThis, struct NetAddr **pIP, int *pBits);
-#endif
-
-#if 0 /* later! - but leave it in in case we need it some day... */
-/* Parse a property
- * This is a complex parsing routine. It parses an property
- * entry suitable for use in the property replacer. It is currently
- * just an idea if this should be a parser function.
- */
-parsRet parsProp(parseObj *pThis, ?? **pPropEtry);
+rsRetVal parsAddrWithBits(rsParsObj *pThis, netAddr_t **pIP, int *pBits);
#endif
#endif
-/*
- * Local variables:
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- * vi:set ai:
+/* vim:set ai:
*/
diff --git a/plugins/im3195/Makefile.am b/plugins/im3195/Makefile.am
new file mode 100644
index 00000000..57c8ab8b
--- /dev/null
+++ b/plugins/im3195/Makefile.am
@@ -0,0 +1,8 @@
+pkglib_LTLIBRARIES = im3195.la
+
+im3195_la_SOURCES = im3195.c im3195.h
+im3195_la_CPPFLAGS = $(rsrt_cflags) $(pthreads_cflags) $(LIBLOGGING_CFLAGS)
+im3195_la_LDFLAGS = -module -avoid-version
+im3195_la_LIBADD = $(LIBLOGGING_LIBS)
+
+EXTRA_DIST =
diff --git a/plugins/im3195/im3195.c b/plugins/im3195/im3195.c
new file mode 100644
index 00000000..76d54e40
--- /dev/null
+++ b/plugins/im3195/im3195.c
@@ -0,0 +1,166 @@
+/**
+ * The rfc3195 input module.
+ *
+ * Please note that this file replaces the rfc3195d daemon that was
+ * also present in pre-v3 versions of rsyslog.
+ *
+ * WARNING: due to no demand at all for RFC3195, we have converted rfc3195d
+ * to this input module, but we have NOT conducted any testing. Also,
+ * the module does not yet properly handle the recovery case. If someone
+ * intends to put this module into production, good testing should be
+ * made and it also is a good idea to notify me that you intend to use
+ * it in production. In this case, I'll probably give the module another
+ * cleanup. I don't do this now because so far it looks just like a big
+ * waste of time. -- rgerhards, 2008-04-16
+ *
+ * \author Rainer Gerhards <rgerhards@adiscon.com>
+ *
+ * Copyright 2003-2008 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/errno.h>
+#include <assert.h>
+#include "rsyslog.h"
+#include "dirty.h"
+#include "liblogging/liblogging.h"
+#include "liblogging/srAPI.h"
+#include "liblogging/syslogmessage.h"
+#include "module-template.h"
+#include "cfsysline.h"
+#include "errmsg.h"
+
+MODULE_TYPE_INPUT
+
+/* Module static data */
+DEF_IMOD_STATIC_DATA
+DEFobjCurrIf(errmsg)
+
+/* configuration settings */
+static int listenPort = 601;
+
+/* we use a global API object below, because this listener is
+ * not very complex. As such, this hack should not harm anything.
+ * rgerhards, 2005-10-12
+ */
+static srAPIObj* pAPI;
+
+
+/* This method is called when a message has been fully received.
+ * It passes the received message to the rsyslog main message
+ * queue. Please note that this callback is synchronous, thus
+ * liblogging will be on hold until it returns. This is important
+ * to note because in an error case we might stay in this code
+ * for an extended amount of time. So far, we think this is the
+ * best solution, but real-world experience might tell us a
+ * different truth ;)
+ */
+void OnReceive(srAPIObj __attribute__((unused)) *pMyAPI, srSLMGObj* pSLMG)
+{
+ uchar *pszRawMsg;
+ uchar *fromHost = (uchar*) "[unset]"; /* TODO: get hostname */
+
+ srSLMGGetRawMSG(pSLMG, &pszRawMsg);
+
+ parseAndSubmitMessage((char*)fromHost, (char*) pszRawMsg, strlen((char*)pszRawMsg),
+ MSG_PARSE_HOSTNAME, NOFLAG, eFLOWCTL_FULL_DELAY);
+}
+
+
+BEGINrunInput
+CODESTARTrunInput
+ /* this is an endless loop - it is terminated when the thread is
+ * signalled to do so. This, however, is handled by the framework,
+ * right into the sleep below.
+ */
+ while(!pThrd->bShallStop) {
+ /* now move the listener to running state. Control will only
+ * return after SIGUSR1.
+ */
+ if((iRet = srAPIRunListener(pAPI)) != SR_RET_OK) {
+ errmsg.LogError(NO_ERRCODE, "error %d running liblogging listener - im3195 is defunct", iRet);
+ FINALIZE; /* this causes im3195 to become defunct; TODO: recovery handling */
+ }
+ }
+finalize_it:
+ENDrunInput
+
+
+BEGINwillRun
+CODESTARTwillRun
+ if((pAPI = srAPIInitLib()) == NULL) {
+ errmsg.LogError(NO_ERRCODE, "error initializing liblogging - im3195 is defunct");
+ ABORT_FINALIZE(RS_RET_ERR);
+ }
+
+ if((iRet = srAPISetOption(pAPI, srOPTION_BEEP_LISTENPORT, listenPort)) != SR_RET_OK) {
+ errmsg.LogError(NO_ERRCODE, "error %d setting liblogging listen port - im3195 is defunct", iRet);
+ FINALIZE;
+ }
+
+ if((iRet = srAPISetupListener(pAPI, OnReceive)) != SR_RET_OK) {
+ errmsg.LogError(NO_ERRCODE, "error %d setting up liblogging listener - im3195 is defunct", iRet);
+ FINALIZE;
+ }
+
+finalize_it:
+ENDwillRun
+
+
+BEGINafterRun
+CODESTARTafterRun
+ dbgprintf("Shutting down rfc3195d. Be patient, this can take up to 30 seconds...\n");
+ srAPIShutdownListener(pAPI);
+ENDafterRun
+
+
+BEGINmodExit
+CODESTARTmodExit
+ srAPIExitLib(pAPI); /* terminate liblogging */
+ /* release objects we used */
+ objRelease(errmsg, CORE_COMPONENT);
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_IMOD_QUERIES
+ENDqueryEtryPt
+
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
+{
+ listenPort = 601;
+ return RS_RET_OK;
+}
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"input3195listenport", 0, eCmdHdlrInt, NULL, &listenPort, STD_LOADABLE_MODULE_ID));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ENDmodInit
+/* vim:set ai:
+ */
diff --git a/plugins/imfile/Makefile.am b/plugins/imfile/Makefile.am
index 23b64d1b..a4011d12 100644
--- a/plugins/imfile/Makefile.am
+++ b/plugins/imfile/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = imfile.la
imfile_la_SOURCES = imfile.c
-imfile_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+imfile_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
imfile_la_LDFLAGS = -module -avoid-version
imfile_la_LIBADD =
diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c
index 75e54f04..a5f1cc8f 100644
--- a/plugins/imfile/imfile.c
+++ b/plugins/imfile/imfile.c
@@ -36,13 +36,14 @@
# include <sys/stat.h>
#endif
#include "rsyslog.h" /* error codes etc... */
-#include "syslogd.h"
+#include "dirty.h"
#include "cfsysline.h" /* access to config file objects */
#include "module-template.h" /* generic module interface code - very important, read it! */
#include "srUtils.h" /* some utility functions */
#include "msg.h"
#include "stream.h"
#include "errmsg.h"
+#include "glbl.h"
#include "datetime.h"
MODULE_TYPE_INPUT /* must be present for input modules, do not remove */
@@ -52,6 +53,7 @@ MODULE_TYPE_INPUT /* must be present for input modules, do not remove */
/* Module static data */
DEF_IMOD_STATIC_DATA /* must be present, starts static data */
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
DEFobjCurrIf(datetime)
typedef struct fileInfo_s {
@@ -95,7 +97,7 @@ static rsRetVal enqLine(fileInfo_t *pInfo, cstr_t *cstrLine)
MsgSetUxTradMsg(pMsg, (char*)rsCStrGetSzStr(cstrLine));
MsgSetRawMsg(pMsg, (char*)rsCStrGetSzStr(cstrLine));
MsgSetMSG(pMsg, (char*)rsCStrGetSzStr(cstrLine));
- MsgSetHOSTNAME(pMsg, (char*)LocalHostName);
+ MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName());
MsgSetTAG(pMsg, (char*)pInfo->pszTag);
pMsg->iFacility = LOG_FAC(pInfo->iFacility);
pMsg->iSeverity = LOG_PRI(pInfo->iSeverity);
@@ -121,7 +123,7 @@ openFile(fileInfo_t *pThis)
/* Construct file name */
lenSFNam = snprintf((char*)pszSFNam, sizeof(pszSFNam) / sizeof(uchar), "%s/%s",
- (char*) glblGetWorkDir(), (char*)pThis->pszStateFile);
+ (char*) glbl.GetWorkDir(), (char*)pThis->pszStateFile);
/* check if the file exists */
if(stat((char*) pszSFNam, &stat_buf) == -1) {
@@ -334,7 +336,7 @@ persistStrmState(fileInfo_t *pInfo)
/* TODO: create a function persistObj in obj.c? */
CHKiRet(strmConstruct(&psSF));
- CHKiRet(strmSetDir(psSF, glblGetWorkDir(), strlen((char*)glblGetWorkDir())));
+ CHKiRet(strmSetDir(psSF, glbl.GetWorkDir(), strlen((char*)glbl.GetWorkDir())));
CHKiRet(strmSettOperationsMode(psSF, STREAMMODE_WRITE));
CHKiRet(strmSetiAddtlOpenFlags(psSF, O_TRUNC));
CHKiRet(strmSetsType(psSF, STREAMTYPE_FILE_SINGLE));
@@ -381,6 +383,7 @@ BEGINmodExit
CODESTARTmodExit
/* release objects we used */
objRelease(datetime, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
ENDmodExit
@@ -488,6 +491,7 @@ CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(datetime, CORE_COMPONENT));
CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfilename", 0, eCmdHdlrGetWord,
diff --git a/plugins/imgssapi/Makefile.am b/plugins/imgssapi/Makefile.am
index 42a243f4..a5cce320 100644
--- a/plugins/imgssapi/Makefile.am
+++ b/plugins/imgssapi/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = imgssapi.la
imgssapi_la_SOURCES = imgssapi.c
-imgssapi_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+imgssapi_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
imgssapi_la_LDFLAGS = -module -avoid-version
imgssapi_la_LIBADD = $(gss_libs)
diff --git a/plugins/imgssapi/imgssapi.c b/plugins/imgssapi/imgssapi.c
index 74d5d5c5..c9ac45d1 100644
--- a/plugins/imgssapi/imgssapi.c
+++ b/plugins/imgssapi/imgssapi.c
@@ -45,7 +45,7 @@
#endif
#include <gssapi/gssapi.h>
#include "rsyslog.h"
-#include "syslogd.h"
+#include "dirty.h"
#include "cfsysline.h"
#include "module-template.h"
#include "net.h"
diff --git a/plugins/imklog/Makefile.am b/plugins/imklog/Makefile.am
index 246b3306..8f50cfb2 100644
--- a/plugins/imklog/Makefile.am
+++ b/plugins/imklog/Makefile.am
@@ -11,6 +11,6 @@ if ENABLE_IMKLOG_LINUX
imklog_la_SOURCES += linux.c module.h ksym.c ksyms.h ksym_mod.c
endif
-imklog_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+imklog_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
imklog_la_LDFLAGS = -module -avoid-version
imklog_la_LIBADD =
diff --git a/plugins/imklog/imklog.c b/plugins/imklog/imklog.c
index c6fb1592..e5888620 100644
--- a/plugins/imklog/imklog.c
+++ b/plugins/imklog/imklog.c
@@ -45,21 +45,23 @@
#include <stdarg.h>
#include <ctype.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "cfsysline.h"
#include "obj.h"
#include "msg.h"
#include "module-template.h"
#include "datetime.h"
#include "imklog.h"
+#include "glbl.h"
MODULE_TYPE_INPUT
/* Module static data */
DEF_IMOD_STATIC_DATA
DEFobjCurrIf(datetime)
+DEFobjCurrIf(glbl)
-/* configuration settings TODO: move to instance data? */
+/* configuration settings */
int dbgPrintSymbols = 0; /* this one is extern so the helpers can access it! */
int symbols_twice = 0;
int use_syscall = 0;
@@ -95,7 +97,7 @@ enqMsg(uchar *msg, uchar* pszTag, int iFacility, int iSeverity)
MsgSetUxTradMsg(pMsg, (char*)msg);
MsgSetRawMsg(pMsg, (char*)msg);
MsgSetMSG(pMsg, (char*)msg);
- MsgSetHOSTNAME(pMsg, (char*)LocalHostName);
+ MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName());
MsgSetTAG(pMsg, (char*)pszTag);
pMsg->iFacility = LOG_FAC(iFacility);
pMsg->iSeverity = LOG_PRI(iSeverity);
@@ -225,6 +227,7 @@ ENDafterRun
BEGINmodExit
CODESTARTmodExit
/* release objects we used */
+ objRelease(glbl, CORE_COMPONENT);
objRelease(datetime, CORE_COMPONENT);
ENDmodExit
@@ -251,6 +254,7 @@ CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(datetime, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
iFacilIntMsg = klogFacilIntMsg();
diff --git a/plugins/imklog/imklog.h b/plugins/imklog/imklog.h
index a37ecc9e..0847140b 100644
--- a/plugins/imklog/imklog.h
+++ b/plugins/imklog/imklog.h
@@ -28,7 +28,7 @@
#define IMKLOG_H_INCLUDED 1
#include "rsyslog.h"
-#include "syslogd.h"
+#include "dirty.h"
/* interface to "drivers"
* the platform specific drivers must implement these entry points. Only one
diff --git a/plugins/imklog/linux.c b/plugins/imklog/linux.c
index 31dae2cd..853c8b2c 100644
--- a/plugins/imklog/linux.c
+++ b/plugins/imklog/linux.c
@@ -32,7 +32,6 @@
#include <signal.h>
#include <string.h>
#include <pthread.h>
-#include "syslogd.h"
#include "cfsysline.h"
#include "template.h"
#include "msg.h"
@@ -147,9 +146,7 @@ static enum LOGSRC GetKernelLogSrc(void)
if ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 )
{
- char sz[512];
- snprintf(sz, sizeof(sz), "imklog: Cannot open proc file system, %d - %s.\n", errno, strerror(errno));
- logmsgInternal(LOG_SYSLOG|LOG_ERR, sz, ADDDATE);
+ imklogLogIntMsg(LOG_ERR, "imklog: Cannot open proc file system, %d.\n", errno);
ksyslog(7, NULL, 0); /* TODO: check this, implement more */
return(none);
}
@@ -428,11 +425,9 @@ static void LogKernelLine(void)
memset(log_buffer, '\0', sizeof(log_buffer));
if ( (rdcnt = ksyslog(2, log_buffer, sizeof(log_buffer)-1)) < 0 )
{
- char sz[512];
if(errno == EINTR)
return;
- snprintf(sz, sizeof(sz), "imklog: Error return from sys_sycall: %d - %s\n", errno, strerror(errno));
- logmsgInternal(LOG_SYSLOG|LOG_ERR, sz, ADDDATE);
+ imklogLogIntMsg(LOG_ERR, "imklog Error return from sys_sycall: %d\n", errno);
}
else
LogLine(log_buffer, rdcnt);
@@ -504,7 +499,7 @@ rsRetVal klogWillRun(void)
symbol_lookup = (InitKsyms(symfile) == 1);
symbol_lookup |= InitMsyms();
if (symbol_lookup == 0) {
- //dbgprintf("cannot find any symbols, turning off symbol lookups\n");
+ dbgprintf("cannot find any symbols, turning off symbol lookups\n");
imklogLogIntMsg(LOG_WARNING, "cannot find any symbols, turning off symbol lookups");
}
}
diff --git a/plugins/immark/Makefile.am b/plugins/immark/Makefile.am
index 3dc0e408..9c0f8f64 100644
--- a/plugins/immark/Makefile.am
+++ b/plugins/immark/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = immark.la
immark_la_SOURCES = immark.c immark.h
-immark_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+immark_la_CPPFLAGS = $(rsrt_cflags) -I$(top_srcdir) $(pthreads_cflags)
immark_la_LDFLAGS = -module -avoid-version
immark_la_LIBADD =
diff --git a/plugins/immark/immark.c b/plugins/immark/immark.c
index 30118de0..ebdcabe9 100644
--- a/plugins/immark/immark.c
+++ b/plugins/immark/immark.c
@@ -37,7 +37,7 @@
#include <signal.h>
#include <string.h>
#include <pthread.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "cfsysline.h"
#include "module-template.h"
@@ -75,7 +75,7 @@ CODESTARTrunInput
* rgerhards, 2007-12-17
*/
CHKiRet(thrdSleep(pThrd, iMarkMessagePeriod, 0)); /* seconds, micro seconds */
- logmsgInternal(LOG_INFO, "-- MARK --", ADDDATE|MARK);
+ logmsgInternal(LOG_INFO, (uchar*)"-- MARK --", ADDDATE|MARK);
}
finalize_it:
return iRet;
diff --git a/plugins/imrelp/Makefile.am b/plugins/imrelp/Makefile.am
index 53c9322c..a96e2b42 100644
--- a/plugins/imrelp/Makefile.am
+++ b/plugins/imrelp/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = imrelp.la
imrelp_la_SOURCES = imrelp.c
-imrelp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(RELP_CFLAGS)
+imrelp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(RELP_CFLAGS) $(rsrt_cflags)
imrelp_la_LDFLAGS = -module -avoid-version
imrelp_la_LIBADD = $(RELP_LIBS)
diff --git a/plugins/imrelp/imrelp.c b/plugins/imrelp/imrelp.c
index b7308016..6c969261 100644
--- a/plugins/imrelp/imrelp.c
+++ b/plugins/imrelp/imrelp.c
@@ -38,7 +38,7 @@
#include <sys/socket.h>
#include <librelp.h>
#include "rsyslog.h"
-#include "syslogd.h"
+#include "dirty.h"
#include "cfsysline.h"
#include "module-template.h"
#include "net.h"
diff --git a/plugins/imtcp/Makefile.am b/plugins/imtcp/Makefile.am
index fe43cd98..de746a95 100644
--- a/plugins/imtcp/Makefile.am
+++ b/plugins/imtcp/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = imtcp.la
imtcp_la_SOURCES = imtcp.c
-imtcp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+imtcp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
imtcp_la_LDFLAGS = -module -avoid-version
imtcp_la_LIBADD =
diff --git a/plugins/imtcp/imtcp.c b/plugins/imtcp/imtcp.c
index 7baa95f2..1e599d14 100644
--- a/plugins/imtcp/imtcp.c
+++ b/plugins/imtcp/imtcp.c
@@ -39,10 +39,11 @@
#include <fcntl.h>
#endif
#include "rsyslog.h"
-#include "syslogd.h"
+#include "dirty.h"
#include "cfsysline.h"
#include "module-template.h"
#include "net.h"
+#include "netstrm.h"
#include "tcpsrv.h"
MODULE_TYPE_INPUT
@@ -52,6 +53,7 @@ DEF_IMOD_STATIC_DATA
DEFobjCurrIf(tcpsrv)
DEFobjCurrIf(tcps_sess)
DEFobjCurrIf(net)
+DEFobjCurrIf(netstrm)
/* Module static data */
static tcpsrv_t *pOurTcpsrv = NULL; /* our TCP server(listener) TODO: change for multiple instances */
@@ -70,7 +72,7 @@ isPermittedHost(struct sockaddr *addr, char *fromHostFQDN, void __attribute__((u
}
-static int*
+static rsRetVal
doOpenLstnSocks(tcpsrv_t *pSrv)
{
ISOBJ_TYPE_assert(pSrv, tcpsrv);
@@ -81,10 +83,12 @@ doOpenLstnSocks(tcpsrv_t *pSrv)
static int
doRcvData(tcps_sess_t *pSess, char *buf, size_t lenBuf)
{
- int state;
+ ssize_t state;
assert(pSess != NULL);
- state = recv(pSess->sock, buf, lenBuf, 0);
+ state = lenBuf;
+ if(netstrm.Rcv(pSess->pStrm, (uchar*) buf, &state) != RS_RET_OK)
+ state = -1; // TODO: move this function to an iRet interface! 2008-04-23
return state;
}
@@ -172,6 +176,7 @@ CODESTARTmodExit
/* release objects we used */
objRelease(net, LM_NET_FILENAME);
+ objRelease(netstrm, LM_NETSTRM_FILENAME);
objRelease(tcps_sess, LM_TCPSRV_FILENAME);
objRelease(tcpsrv, LM_TCPSRV_FILENAME);
ENDmodExit
@@ -199,6 +204,7 @@ CODEmodInit_QueryRegCFSLineHdlr
pOurTcpsrv = NULL;
/* request objects we use */
CHKiRet(objUse(net, LM_NET_FILENAME));
+ CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
CHKiRet(objUse(tcps_sess, LM_TCPSRV_FILENAME));
CHKiRet(objUse(tcpsrv, LM_TCPSRV_FILENAME));
diff --git a/plugins/imudp/Makefile.am b/plugins/imudp/Makefile.am
index 53fdad16..28ee9853 100644
--- a/plugins/imudp/Makefile.am
+++ b/plugins/imudp/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = imudp.la
imudp_la_SOURCES = imudp.c
-imudp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+imudp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
imudp_la_LDFLAGS = -module -avoid-version
imudp_la_LIBADD =
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c
index cda794c3..e0f9f1d3 100644
--- a/plugins/imudp/imudp.c
+++ b/plugins/imudp/imudp.c
@@ -33,12 +33,13 @@
#include <unistd.h>
#include <netdb.h>
#include "rsyslog.h"
-#include "syslogd.h"
+#include "dirty.h"
#include "net.h"
#include "cfsysline.h"
#include "module-template.h"
#include "srUtils.h"
#include "errmsg.h"
+#include "glbl.h"
MODULE_TYPE_INPUT
@@ -47,6 +48,7 @@ MODULE_TYPE_INPUT
/* Module static data */
DEF_IMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
DEFobjCurrIf(net)
static int *udpLstnSocks = NULL; /* Internet datagram sockets, first element is nbr of elements
@@ -195,7 +197,7 @@ CODESTARTrunInput
MSG_PARSE_HOSTNAME, NOFLAG, eFLOWCTL_NO_DELAY);
} else {
dbgprintf("%s is not an allowed sender\n", (char*)fromHostFQDN);
- if(option_DisallowWarning) {
+ if(glbl.GetOption_DisallowWarning) {
errmsg.LogError(NO_ERRCODE, "UDP message from disallowed sender %s discarded",
(char*)fromHost);
}
@@ -253,6 +255,7 @@ BEGINmodExit
CODESTARTmodExit
/* release what we no longer need */
objRelease(errmsg, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
objRelease(net, LM_NET_FILENAME);
ENDmodExit
@@ -281,6 +284,7 @@ CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(net, LM_NET_FILENAME));
/* register config file handlers */
diff --git a/plugins/imuxsock/Makefile.am b/plugins/imuxsock/Makefile.am
index e165bb7d..11a0ba3a 100644
--- a/plugins/imuxsock/Makefile.am
+++ b/plugins/imuxsock/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = imuxsock.la
imuxsock_la_SOURCES = imuxsock.c
-imuxsock_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+imuxsock_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
imuxsock_la_LDFLAGS = -module -avoid-version
imuxsock_la_LIBADD =
diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c
index f8798039..94f97eb5 100644
--- a/plugins/imuxsock/imuxsock.c
+++ b/plugins/imuxsock/imuxsock.c
@@ -35,11 +35,13 @@
#include <unistd.h>
#include <sys/stat.h>
#include <sys/un.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "cfsysline.h"
#include "module-template.h"
#include "srUtils.h"
#include "errmsg.h"
+#include "net.h"
+#include "glbl.h"
MODULE_TYPE_INPUT
@@ -62,6 +64,7 @@ MODULE_TYPE_INPUT
/* Module static data */
DEF_IMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
static int startIndexUxLocalSockets; /* process funix from that index on (used to
* suppress local logging. rgerhards 2005-08-01
@@ -100,8 +103,6 @@ static rsRetVal setSystemLogTimestampIgnore(void __attribute__((unused)) *pVal,
*/
static rsRetVal addLstnSocketName(void __attribute__((unused)) *pVal, uchar *pNewVal)
{
- char errStr[1024];
-
if(nfunix < MAXFUNIX) {
if(*pNewVal == ':') {
funixParseHost[nfunix] = 1;
@@ -113,9 +114,8 @@ static rsRetVal addLstnSocketName(void __attribute__((unused)) *pVal, uchar *pNe
funixn[nfunix++] = pNewVal;
}
else {
- snprintf(errStr, sizeof(errStr), "rsyslogd: Out of unix socket name descriptors, ignoring %s\n",
+ errmsg.LogError(NO_ERRCODE, "Out of unix socket name descriptors, ignoring %s\n",
pNewVal);
- logmsgInternal(LOG_SYSLOG|LOG_ERR, errStr, ADDDATE);
}
return RS_RET_OK;
@@ -181,7 +181,7 @@ static rsRetVal readSocket(int fd, int bParseHost, int flags)
iRcvd = recv(fd, line, MAXLINE - 1, 0);
dbgprintf("Message from UNIX socket: #%d\n", fd);
if (iRcvd > 0) {
- parseAndSubmitMessage((char*)LocalHostName, line, iRcvd, bParseHost, flags, eFLOWCTL_LIGHT_DELAY);
+ parseAndSubmitMessage((char*)glbl.GetLocalHostName(), line, iRcvd, bParseHost, flags, eFLOWCTL_LIGHT_DELAY);
} else if (iRcvd < 0 && errno != EINTR) {
char errStr[1024];
rs_strerror_r(errno, errStr, sizeof(errStr));
@@ -289,6 +289,8 @@ ENDafterRun
BEGINmodExit
CODESTARTmodExit
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(errmsg, CORE_COMPONENT);
ENDmodExit
@@ -319,6 +321,7 @@ CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
/* initialize funixn[] array */
for(i = 1 ; i < MAXFUNIX ; ++i) {
@@ -346,6 +349,5 @@ CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogsocketignoremsgtimestamp", 0, eCmdHdlrBinary,
setSystemLogTimestampIgnore, NULL, STD_LOADABLE_MODULE_ID));
ENDmodInit
-/*
- * vi:set ai:
+/* vim:set ai:
*/
diff --git a/plugins/omgssapi/Makefile.am b/plugins/omgssapi/Makefile.am
index 5280a1ce..c2cbe387 100644
--- a/plugins/omgssapi/Makefile.am
+++ b/plugins/omgssapi/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = omgssapi.la
omgssapi_la_SOURCES = omgssapi.c
-omgssapi_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+omgssapi_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
omgssapi_la_LDFLAGS = -module -avoid-version
omgssapi_la_LIBADD = $(gss_libs)
diff --git a/plugins/omgssapi/omgssapi.c b/plugins/omgssapi/omgssapi.c
index 8c6a2006..6d419de0 100644
--- a/plugins/omgssapi/omgssapi.c
+++ b/plugins/omgssapi/omgssapi.c
@@ -43,38 +43,27 @@
#endif
#include <pthread.h>
#include <gssapi/gssapi.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "srUtils.h"
#include "net.h"
-#include "omfwd.h"
#include "template.h"
#include "msg.h"
-#include "tcpsyslog.h"
#include "cfsysline.h"
#include "module-template.h"
#include "gss-misc.h"
#include "tcpclt.h"
+#include "glbl.h"
#include "errmsg.h"
MODULE_TYPE_OUTPUT
-#define INET_SUSPEND_TIME 60
-/* equal to 1 minute - TODO: see if we can get rid of this now that we have
- * the retry intervals in the engine -- rgerhards, 2008-03-12
- */
-
-#define INET_RETRY_MAX 30 /* maximum of retries for gethostbyname() */
- /* was 10, changed to 30 because we reduced INET_SUSPEND_TIME by one third. So
- * this "fixes" some of implications of it (see comment on INET_SUSPEND_TIME).
- * rgerhards, 2005-07-26
- * TODO: this needs to be reviewed in spite of the new engine, too -- rgerhards, 2008-03-12
- */
/* internal structures
*/
DEF_OMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
DEFobjCurrIf(gssutil)
DEFobjCurrIf(tcpclt)
@@ -86,11 +75,9 @@ typedef struct _instanceData {
eDestFORW_SUSP,
eDestFORW_UNKN
} eDestState;
- int iRtryCnt;
struct addrinfo *f_addr;
int compressionLevel; /* 0 - no compression, else level for zlib */
char *port;
- time_t ttSuspend; /* time selector was suspended */
tcpclt_t *pTCPClt; /* our tcpclt object */
gss_ctx_id_t gss_context;
OM_uint32 gss_flags;
@@ -174,8 +161,6 @@ CODESTARTdbgPrintInstInfo
ENDdbgPrintInstInfo
-/* CODE FOR SENDING TCP MESSAGES */
-
/* This function is called immediately before a send retry is attempted.
* It shall clean up whatever makes sense.
* rgerhards, 2007-12-28
@@ -207,9 +192,7 @@ static rsRetVal TCPSendGSSInit(void *pvData)
base = (gss_base_service_name == NULL) ? "host" : gss_base_service_name;
out_tok.length = strlen(pData->f_hname) + strlen(base) + 2;
- if ((out_tok.value = malloc(out_tok.length)) == NULL) {
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- }
+ CHKmalloc(out_tok.value = malloc(out_tok.length));
strcpy(out_tok.value, base);
strcat(out_tok.value, "@");
strcat(out_tok.value, pData->f_hname);
@@ -365,13 +348,12 @@ static rsRetVal doTryResume(instanceData *pData)
* a common function.
*/
hints.ai_flags = AI_NUMERICSERV;
- hints.ai_family = family;
+ hints.ai_family = glbl.GetDefPFFamily();
hints.ai_socktype = SOCK_STREAM;
if((e = getaddrinfo(pData->f_hname,
getFwdSyslogPt(pData), &hints, &res)) == 0) {
dbgprintf("%s found, resuming.\n", pData->f_hname);
pData->f_addr = res;
- pData->iRtryCnt = 0;
pData->eDestState = eDestFORW;
} else {
iRet = RS_RET_SUSPENDED;
@@ -410,7 +392,6 @@ CODESTARTdoAction
case eDestFORW:
dbgprintf(" %s:%s/%s\n", pData->f_hname, getFwdSyslogPt(pData), "tcp-gssapi");
- pData->ttSuspend = time(NULL);
psz = (char*) ppString[0];
l = strlen((char*) psz);
if (l > MAXLINE)
@@ -609,12 +590,10 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1)
memset(&hints, 0, sizeof(hints));
/* port must be numeric, because config file syntax requests this */
hints.ai_flags = AI_NUMERICSERV;
- hints.ai_family = family;
+ hints.ai_family = glbl.GetDefPFFamily();
hints.ai_socktype = SOCK_STREAM;
if( (error = getaddrinfo(pData->f_hname, getFwdSyslogPt(pData), &hints, &res)) != 0) {
pData->eDestState = eDestFORW_UNKN;
- pData->iRtryCnt = INET_RETRY_MAX;
- pData->ttSuspend = time(NULL);
} else {
pData->eDestState = eDestFORW;
pData->f_addr = res;
@@ -637,6 +616,7 @@ ENDparseSelectorAct
BEGINmodExit
CODESTARTmodExit
+ objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
objRelease(gssutil, LM_GSSUTIL_FILENAME);
objRelease(tcpclt, LM_TCPCLT_FILENAME);
@@ -695,6 +675,7 @@ CODESTARTmodInit
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
CODEmodInit_QueryRegCFSLineHdlr
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(objUse(gssutil, LM_GSSUTIL_FILENAME));
CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME));
diff --git a/plugins/omlibdbi/Makefile.am b/plugins/omlibdbi/Makefile.am
index 872fc67c..d224f9e4 100644
--- a/plugins/omlibdbi/Makefile.am
+++ b/plugins/omlibdbi/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = omlibdbi.la
omlibdbi_la_SOURCES = omlibdbi.c
-omlibdbi_la_CPPFLAGS = -I$(top_srcdir) $(libdbi_cflags) $(pthreads_cflags)
+omlibdbi_la_CPPFLAGS = -I$(top_srcdir) $(libdbi_cflags) $(pthreads_cflags) $(rsrt_cflags)
omlibdbi_la_LDFLAGS = -module -avoid-version
omlibdbi_la_LIBADD = $(libdbi_libs)
diff --git a/plugins/omlibdbi/omlibdbi.c b/plugins/omlibdbi/omlibdbi.c
index a942a453..661aee6f 100644
--- a/plugins/omlibdbi/omlibdbi.c
+++ b/plugins/omlibdbi/omlibdbi.c
@@ -40,7 +40,7 @@
#include <errno.h>
#include <time.h>
#include <dbi/dbi.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "cfsysline.h"
#include "srUtils.h"
diff --git a/plugins/ommail/Makefile.am b/plugins/ommail/Makefile.am
index 7e9f5f13..fa470a43 100644
--- a/plugins/ommail/Makefile.am
+++ b/plugins/ommail/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = ommail.la
ommail_la_SOURCES = ommail.c
-ommail_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+ommail_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
ommail_la_LDFLAGS = -module -avoid-version
ommail_la_LIBADD =
diff --git a/plugins/ommail/ommail.c b/plugins/ommail/ommail.c
index 218c73c9..d4158975 100644
--- a/plugins/ommail/ommail.c
+++ b/plugins/ommail/ommail.c
@@ -44,12 +44,13 @@
#include <netdb.h>
#include <time.h>
#include <sys/socket.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "srUtils.h"
#include "cfsysline.h"
#include "module-template.h"
#include "errmsg.h"
+#include "glbl.h"
MODULE_TYPE_OUTPUT
@@ -57,6 +58,7 @@ MODULE_TYPE_OUTPUT
*/
DEF_OMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
static uchar *pszSrv = NULL;
static uchar *pszSrvPort = NULL;
@@ -415,7 +417,7 @@ sendSMTP(instanceData *pData, uchar *body, uchar *subject)
CHKiRet(readResponse(pData, &iState, 220));
CHKiRet(Send(pData->md.smtp.sock, "HELO ", 5));
- CHKiRet(Send(pData->md.smtp.sock, (char*)LocalHostName, strlen((char*)LocalHostName)));
+ CHKiRet(Send(pData->md.smtp.sock, (char*)glbl.GetLocalHostName(), strlen((char*)glbl.GetLocalHostName())));
CHKiRet(Send(pData->md.smtp.sock, "\r\n", sizeof("\r\n") - 1));
CHKiRet(readResponse(pData, &iState, 250));
@@ -589,6 +591,7 @@ CODESTARTmodExit
freeConfigVariables();
/* release what we no longer need */
+ objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
ENDmodExit
@@ -616,6 +619,7 @@ CODESTARTmodInit
CODEmodInit_QueryRegCFSLineHdlr
/* tell which objects we need */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailsmtpserver", 0, eCmdHdlrGetWord, NULL, &pszSrv, STD_LOADABLE_MODULE_ID));
CHKiRet(omsdRegCFSLineHdlr( (uchar *)"actionmailsmtpport", 0, eCmdHdlrGetWord, NULL, &pszSrvPort, STD_LOADABLE_MODULE_ID));
diff --git a/plugins/ommysql/Makefile.am b/plugins/ommysql/Makefile.am
index 3b4e6d75..d5433a40 100644
--- a/plugins/ommysql/Makefile.am
+++ b/plugins/ommysql/Makefile.am
@@ -1,7 +1,7 @@
pkglib_LTLIBRARIES = ommysql.la
ommysql_la_SOURCES = ommysql.c ommysql.h
-ommysql_la_CPPFLAGS = -I$(top_srcdir) $(mysql_cflags) $(pthreads_cflags)
+ommysql_la_CPPFLAGS = $(rsrt_cflags) $(mysql_cflags) $(pthreads_cflags)
ommysql_la_LDFLAGS = -module -avoid-version
ommysql_la_LIBADD = $(mysql_libs)
diff --git a/plugins/ommysql/ommysql.c b/plugins/ommysql/ommysql.c
index 0522e31d..472cb10d 100644
--- a/plugins/ommysql/ommysql.c
+++ b/plugins/ommysql/ommysql.c
@@ -37,7 +37,7 @@
#include <time.h>
#include <mysql/mysql.h>
#include <mysql/errmsg.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "srUtils.h"
#include "template.h"
diff --git a/plugins/ompgsql/Makefile.am b/plugins/ompgsql/Makefile.am
index b2e3effa..cc1c5f49 100644
--- a/plugins/ompgsql/Makefile.am
+++ b/plugins/ompgsql/Makefile.am
@@ -1,7 +1,7 @@
pkglib_LTLIBRARIES = ompgsql.la
ompgsql_la_SOURCES = ompgsql.c ompgsql.h
-ompgsql_la_CPPFLAGS = -I$(top_srcdir) $(pgsql_cflags)
+ompgsql_la_CPPFLAGS = -I$(top_srcdir) $(pgsql_cflags) $(rsrt_cflags)
ompgsql_la_LDFLAGS = -module -avoid-version
ompgsql_la_LIBADD = $(pgsql_libs)
diff --git a/plugins/ompgsql/ompgsql.c b/plugins/ompgsql/ompgsql.c
index 1d7b2eb7..77fd6a07 100644
--- a/plugins/ompgsql/ompgsql.c
+++ b/plugins/ompgsql/ompgsql.c
@@ -36,7 +36,7 @@
#include <errno.h>
#include <time.h>
#include <libpq-fe.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "srUtils.h"
#include "template.h"
diff --git a/plugins/omrelp/Makefile.am b/plugins/omrelp/Makefile.am
index dfc2111f..f8384f42 100644
--- a/plugins/omrelp/Makefile.am
+++ b/plugins/omrelp/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = omrelp.la
omrelp_la_SOURCES = omrelp.c
-omrelp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(RELP_CFLAGS)
+omrelp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(RELP_CFLAGS) $(rsrt_cflags)
omrelp_la_LDFLAGS = -module -avoid-version
omrelp_la_LIBADD = $(RELP_LIBS)
diff --git a/plugins/omrelp/omrelp.c b/plugins/omrelp/omrelp.c
index 04571682..2977053a 100644
--- a/plugins/omrelp/omrelp.c
+++ b/plugins/omrelp/omrelp.c
@@ -36,11 +36,12 @@
#include <errno.h>
#include <ctype.h>
#include <librelp.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "srUtils.h"
#include "cfsysline.h"
#include "module-template.h"
+#include "glbl.h"
#include "errmsg.h"
MODULE_TYPE_OUTPUT
@@ -49,6 +50,7 @@ MODULE_TYPE_OUTPUT
*/
DEF_OMOD_STATIC_DATA
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
static relpEngine_t *pRelpEngine; /* our relp engine */
@@ -118,7 +120,7 @@ static rsRetVal doConnect(instanceData *pData)
DEFiRet;
if(pData->bInitialConnect) {
- iRet = relpCltConnect(pData->pRelpClt, family, (uchar*) pData->port, (uchar*) pData->f_hname);
+ iRet = relpCltConnect(pData->pRelpClt, glbl.GetDefPFFamily(), (uchar*) pData->port, (uchar*) pData->f_hname);
if(iRet == RELP_RET_OK)
pData->bInitialConnect = 0;
} else {
@@ -311,6 +313,7 @@ CODESTARTmodExit
relpEngineDestruct(&pRelpEngine);
/* release what we no longer need */
+ objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
ENDmodExit
@@ -332,6 +335,7 @@ CODEmodInit_QueryRegCFSLineHdlr
/* tell which objects we need */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
ENDmodInit
/* vim:set ai:
diff --git a/plugins/omsnmp/Makefile.am b/plugins/omsnmp/Makefile.am
index d74f7bb4..d784faca 100644
--- a/plugins/omsnmp/Makefile.am
+++ b/plugins/omsnmp/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = omsnmp.la
omsnmp_la_SOURCES = omsnmp.c omsnmp.h
-omsnmp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+omsnmp_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
omsnmp_la_LDFLAGS = -module -avoid-version
omsnmp_la_LIBADD = $(snmp_libs)
diff --git a/plugins/omsnmp/omsnmp.c b/plugins/omsnmp/omsnmp.c
index 161ec073..21165f9b 100644
--- a/plugins/omsnmp/omsnmp.c
+++ b/plugins/omsnmp/omsnmp.c
@@ -36,7 +36,7 @@
#include <netdb.h>
#include <ctype.h>
#include <assert.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "cfsysline.h"
#include "module-template.h"
diff --git a/plugins/omtesting/Makefile.am b/plugins/omtesting/Makefile.am
index 7e376683..8e98ca63 100644
--- a/plugins/omtesting/Makefile.am
+++ b/plugins/omtesting/Makefile.am
@@ -1,6 +1,6 @@
pkglib_LTLIBRARIES = omtesting.la
omtesting_la_SOURCES = omtesting.c
-omtesting_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags)
+omtesting_la_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags)
omtesting_la_LDFLAGS = -module -avoid-version
omtesting_la_LIBADD =
diff --git a/plugins/omtesting/omtesting.c b/plugins/omtesting/omtesting.c
index 15d3cb80..411bcf88 100644
--- a/plugins/omtesting/omtesting.c
+++ b/plugins/omtesting/omtesting.c
@@ -49,7 +49,7 @@
#include <string.h>
#include <ctype.h>
#include <assert.h>
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "module-template.h"
diff --git a/rfc3195d.8 b/rfc3195d.8
deleted file mode 100644
index ae191df6..00000000
--- a/rfc3195d.8
+++ /dev/null
@@ -1,84 +0,0 @@
-.\" Copyright 2005 Rainer Gerhards and Adiscon for the rsyslog modifications
-.\" Distributed under the GNU General Public License.
-.\"
-.TH RFC3195D 8 "02 April 2008" "Version 3.14.0" "Linux System Administration"
-.SH NAME
-rfc3195d \- RFC 3195 listener
-.SH SYNOPSIS
-.B rfc3195d
-.RB [ " \-d " ]
-.RB [ " \-p"
-.IB socket
-]
-.RB [ " \-r"
-.IB port
-]
-.RB [ " \-v " ]
-.LP
-.SH DESCRIPTION
-.B Rfc3195d
-is a utility for receiving syslog messages via RFC 3195. Both
-RAW and COOKED profiles are supported (but COOKED only without
-relay-specific PATH elements).
-rfc3195d accepts messages via RFC 3195 and forwards them to
-the local domain socket specified in the -p option
-(/dev/log3195 by default). There, the messages can be picked up
-by the system syslogd. While rfc3195d can work with any syslogd,
-we highly recommend using
-.B rsyslogd,
-because it has special handling
-for the messages forwarded by rfc3195d. To enable message
-reception in
-.B rsyslogd,
-use the "-a :/dev/log3195" command line
-option (the colon in front of the socket name tells
-.B rsyslogd
-that the messages contain hostnames - this is vital to get the
-right sender name into your logs).
-
-.B Rfc3195d
-currently has very limited functionality. Most importantly,
-it does not allow to limit the senders it receives messages from.
-Documentation is also very sparse. The situation should improve over
-time as the rsyslog project is continously being enhanced.
-.LP
-.SH OPTIONS
-.TP
-.BI "\-p " "socket"
-The socket the received messages are to be sent to. If not specified,
-/dev/log3195 is used.
-.TP
-.BI "\-r " "port"
-The listen port to use. If not specified, IANA-assigned port 601 is used.
-.TP
-.B "\-d"
-Turns on debug mode. In it, rfc3195d spits out diagnostic information
-to stdout.
-.TP
-.B "\-v"
-Print version and exit.
-.SH SIGNALS
-.B Rfc3195d
-reacts to a set of signals.
-.TP
-.B SIGTERM
-.B Rfc3195d
-terminates.
-.TP
-.B SIGUSR1
-.B Rfc3195d
-terminates.
-.LP
-.SH SEE ALSO
-.BR rsyslog.conf (5),
-.BR rsyslogd (8)
-.LP
-.SH MORE INFORMATION
-Is available on the project home page at http://www.rsyslog.com
-.LP
-.SH COLLABORATORS
-Rfc3195d uses liblogging (http://www.liblogging.org) for RFC 3195
-protocol handling.
-.PD 0
-.TP
-Rainer Gerhards <rgerhards@adiscon.com>
diff --git a/rfc3195d.c b/rfc3195d.c
deleted file mode 100644
index f79ec949..00000000
--- a/rfc3195d.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/**
- * rfc3195d.c
- * This is an RFC 3195 listener. All data received is forwarded to
- * local UNIX domain socket, where it can be picked up by a
- * syslog daemon (like rsyslogd ;)).
- *
- * \author Rainer Gerhards <rgerhards@adiscon.com>
- *
- * Copyright 2003-2005 Rainer Gerhards and Adiscon GmbH.
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#include "config.h"
-
-#include <stdio.h>
-#ifndef FEATURE_RFC3195
-/* this is a trick: if RFC3195 is not to be supported, we just do an
- * error message.
- */
-int main()
-{
- fprintf(stderr, "error: not compiled with FEATURE_RFC3195 - terminating.\n");
- return(1);
-}
-#else
-#include <unistd.h>
-#include <signal.h>
-#include <sys/socket.h>
-#include <sys/errno.h>
-#include "rsyslog.h"
-#include "liblogging.h"
-#include "srAPI.h"
-#include "syslogmessage.h"
-
-/* configurable params! */
-static char* pPathLogname = "/dev/log3195";
-static char *PidFile;
-static int NoFork = 0;
-static int Debug = 0;
-static int listenPort = 601;
-
-/* we use a global API object below, because this listener is
- * not very complex. As such, this hack should not harm anything.
- * rgerhards, 2005-10-12
- */
-static srAPIObj* pAPI;
-
-static int LogFile = -1; /* fd for log */
-static int connected; /* have done connect */
-static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
-
-/* small usage info */
-static int usage()
-{
- /* The following usage line is what we intend to have - it
- * is commented out as a reminder. The one below is what we
- * currently actually do...
- fprintf(stderr, "usage: rfc3195d [-dv] [-i pidfile] [-n] [-p path]\n");
- */
- fprintf(stderr, "usage: rfc3195d [-dv] [-r port] [-p path]\n");
- exit(1);
-}
-
-/* CLOSELOG -- close the system log
- */
-static void closelog(void)
-{
- close(LogFile);
- LogFile = -1;
- connected = 0;
-}
-
-/* OPENLOG -- open system log
- */
-static void openlog()
-{
- if (LogFile == -1) {
- SyslogAddr.sa_family = AF_UNIX;
- strncpy(SyslogAddr.sa_data, pPathLogname,
- sizeof(SyslogAddr.sa_data));
- LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
- if(LogFile < 0) {
- char errStr[1024];
- printf("error opening '%s': %s\n",
- pPathLogname, rs_strerror_r(errno, errStr, sizeof(errStr)));
- }
- }
- if (LogFile != -1 && !connected &&
- connect(LogFile, &SyslogAddr, sizeof(SyslogAddr.sa_family)+
- strlen(SyslogAddr.sa_data)) != -1)
- connected = 1;
- else {
- char errStr[1024];
- printf("error connecting '%s': %s\n",
- pPathLogname, rs_strerror_r(errno, errStr, sizeof(errStr)));
- }
-}
-
-
-/* This method is called when a message has been fully received.
- * It passes the received message to the specified unix domain
- * socket. Please note that this callback is synchronous, thus
- * liblogging will be on hold until it returns. This is important
- * to note because in an error case we might stay in this code
- * for an extended amount of time. So far, we think this is the
- * best solution, but real-world experience might tell us a
- * different truth ;)
- * rgerhards 2005-10-12
- */
-void OnReceive(srAPIObj* pAPI, srSLMGObj* pSLMG)
-{
- unsigned char *pszRawMsg;
- int iRetries; /* number of retries connecting to log socket */
- int iSleep;
- int iWriteOffset;
- ssize_t nToWrite;
- ssize_t nWritten;
-
- srSLMGGetRawMSG(pSLMG, &pszRawMsg);
-
- /* we need to loop writing the message. At least in
- * theory, a single write might not send all data to the
- * syslogd. So we need to continue until everything is written.
- * Also, we need to check if there are any socket erros, in
- * which case we reconect. We will re-try indefinitely, if this
- * is not acceptable, you need to change the code.
- * rgerhards 2005-10-12
- */
- iRetries = 0;
- nToWrite = strlen(pszRawMsg);
- iWriteOffset = 0;
- while(nToWrite != 0) {
- if(LogFile < 0 || !connected)
- openlog();
- if(LogFile < 0 || !connected) {
- /* still not connected, retry */
- if(iRetries > 0) {
- iSleep = (iRetries < 30) ? iRetries : 30;
- /* we sleep a little to prevent a thight loop */
- if(Debug)
- printf("multiple retries connecting to log socket"
- " - doing sleep(%d)\n", iSleep);
- sleep(iSleep);
- }
- ++iRetries;
- } else {
- nWritten = write(LogFile, pszRawMsg, strlen(pszRawMsg));
- if(nWritten < 0) {
- /* error, recover! */
- char errStr[1024];
- printf("error writing to domain socket: %s\r\n", rs_strerror_r(errno, errStr, sizeof(errStr)));
- closelog();
- } else {
- /* prepare for (potential) next write */
- nToWrite -= nWritten;
- iWriteOffset += nWritten;
- }
- }
- }
-
- if(Debug) {
- static int largest = 0;
- int sz = strlen(pszRawMsg);
- if(sz > largest)
- largest = sz;
- printf("Msg(%d/%d):%s\n\n", largest, sz, pszRawMsg);
- }
-}
-
-
-/* As we are single-threaded in this example, we need
- * one way to shut down the listener running on this
- * single thread. We use SIG_INT to do so - it effectively
- * provides a short-lived second thread ;-)
- */
-void doShutdown(int i)
-{
- printf("Shutting down rfc3195d. Be patient, this can take up to 30 seconds...\n");
- srAPIShutdownListener(pAPI);
-}
-
-
-/* on the the real program ;) */
-int main(int argc, char* argv[])
-{
- srRetVal iRet;
- int ch;
- struct sigaction sigAct;
-
- while ((ch = getopt(argc, argv, "di:np:r:v")) != EOF)
- switch((char)ch) {
- case 'd': /* debug */
- Debug = 1;
- break;
- case 'i': /* pid file name */
- PidFile = optarg;
- break;
- case 'n': /* don't fork */
- NoFork = 1;
- break;
- case 'p': /* path to regular log socket */
- pPathLogname = optarg;
- break;
- case 'r': /* listen port */
- listenPort = atoi(optarg);
- if(listenPort < 1 || listenPort > 65535) {
- printf("Error: invalid listen port '%s', using 601 instead\n",
- optarg);
- listenPort = 601;
- }
- break;
- case 'v':
- printf("rfc3195d %s.%s (using liblogging version %d.%d.%d).\n",
- VERSION, PATCHLEVEL,
- LIBLOGGING_VERSION_MAJOR, LIBLOGGING_VERSION_MINOR,
- LIBLOGGING_VERSION_SUBMINOR);
- printf("See http://www.rsyslog.com for more information.\n");
- exit(0);
- case '?':
- default:
- usage();
- }
- if ((argc -= optind))
- usage();
-
- memset(&sigAct, 0, sizeof(sigAct));
- sigemptyset(&sigAct.sa_mask);
- sigAct.sa_handler = doShutdown;
- sigaction(SIGUSR1, &sigAct, NULL);
- sigaction(SIGTERM, &sigAct, NULL);
-
- if(!Debug)
- {
- sigAct.sa_handler = SIG_IGN;
- sigaction(SIGINT, &sigAct, NULL);
- }
-
- if((pAPI = srAPIInitLib()) == NULL)
- {
- printf("Error initializing liblogging - aborting!\n");
- exit(1);
- }
-
- if((iRet = srAPISetOption(pAPI, srOPTION_BEEP_LISTENPORT, listenPort)) != SR_RET_OK)
- {
- printf("Error %d setting listen port - aborting\n", iRet);
- exit(100);
- }
-
- if((iRet = srAPISetupListener(pAPI, OnReceive)) != SR_RET_OK)
- {
- printf("Error %d setting up listener - aborting\n", iRet);
- exit(101);
- }
-
- /* now move the listener to running state. Control will only
- * return after SIGUSR1.
- */
- if((iRet = srAPIRunListener(pAPI)) != SR_RET_OK)
- {
- printf("Error %d running the listener - aborting\n", iRet);
- exit(102);
- }
-
- /** control will reach this point after shutdown */
-
- srAPIExitLib(pAPI);
- return 0;
-}
-#endif /* #ifndef FEATURE_RFC3195 - main wrapper */
-
-/*
- * vi:set ai:
- */
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
new file mode 100644
index 00000000..dcb475d8
--- /dev/null
+++ b/runtime/Makefile.am
@@ -0,0 +1,145 @@
+sbin_PROGRAMS =
+man_MANS =
+noinst_LTLIBRARIES = librsyslog.la
+pkglib_LTLIBRARIES =
+#pkglib_LTLIBRARIES = librsyslog.la
+
+librsyslog_la_SOURCES = \
+ rsyslog.c \
+ rsyslog.h \
+ atomic.h \
+ syslogd-types.h \
+ module-template.h \
+ obj-types.h \
+ nsd.h \
+ glbl.h \
+ glbl.c \
+ msg.c \
+ msg.h \
+ linkedlist.c \
+ linkedlist.h \
+ objomsr.c \
+ objomsr.h \
+ stringbuf.c \
+ stringbuf.h \
+ datetime.c \
+ datetime.h \
+ srutils.c \
+ srUtils.h \
+ errmsg.c \
+ errmsg.h \
+ debug.c \
+ debug.h \
+ obj.c \
+ obj.h \
+ modules.c \
+ modules.h \
+ sync.c \
+ sync.h \
+ expr.c \
+ expr.h \
+ ctok.c \
+ ctok.h \
+ ctok_token.c \
+ ctok_token.h \
+ stream.c \
+ stream.h \
+ var.c \
+ var.h \
+ wtp.c \
+ wtp.h \
+ wti.c \
+ wti.h \
+ sysvar.c \
+ sysvar.h \
+ vm.c \
+ vm.h \
+ vmstk.c \
+ vmstk.h \
+ vmprg.c \
+ vmprg.h \
+ vmop.c \
+ vmop.h \
+ queue.c \
+ queue.h \
+ cfsysline.c \
+ cfsysline.h
+
+librsyslog_la_CPPFLAGS = -D_PATH_MODDIR=\"$(pkglibdir)/\" -I$(top_srcdir) $(pthreads_cflags)
+#librsyslog_la_LDFLAGS = -module -avoid-version
+librsyslog_la_LIBADD =
+
+#
+# regular expression support
+#
+if ENABLE_REGEXP
+pkglib_LTLIBRARIES += lmregexp.la
+lmregexp_la_SOURCES = regexp.c regexp.h
+lmregexp_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmregexp_la_LDFLAGS = -module -avoid-version
+lmregexp_la_LIBADD =
+endif
+
+if ENABLE_INET
+pkglib_LTLIBRARIES += lmnet.la lmnetstrms.la lmnetstrm.la lmnssel.la
+#
+# network support
+#
+lmnet_la_SOURCES = net.c net.h
+lmnet_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmnet_la_LDFLAGS = -module -avoid-version
+lmnet_la_LIBADD =
+
+# network stream master class and stream factory
+lmnetstrms_la_SOURCES = netstrms.c netstrms.h
+lmnetstrms_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmnetstrms_la_LDFLAGS = -module -avoid-version
+lmnetstrms_la_LIBADD =
+
+# individual network streams
+lmnetstrm_la_SOURCES = netstrm.c netstrm.h
+lmnetstrm_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmnetstrm_la_LDFLAGS = -module -avoid-version
+lmnetstrm_la_LIBADD =
+
+# network stream select support (a helper class)
+lmnssel_la_SOURCES = nssel.c nssel.h
+lmnssel_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmnssel_la_LDFLAGS = -module -avoid-version
+lmnssel_la_LIBADD =
+
+# netstream drivers
+
+# plain tcp driver - main driver
+pkglib_LTLIBRARIES += lmnsd_ptcp.la
+lmnsd_ptcp_la_SOURCES = nsd_ptcp.c nsd_ptcp.h
+lmnsd_ptcp_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmnsd_ptcp_la_LDFLAGS = -module -avoid-version
+lmnsd_ptcp_la_LIBADD =
+
+# select interface for ptcp driver
+pkglib_LTLIBRARIES += lmnsdsel_ptcp.la
+lmnsdsel_ptcp_la_SOURCES = nsdsel_ptcp.c nsdsel_ptcp.h
+lmnsdsel_ptcp_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmnsdsel_ptcp_la_LDFLAGS = -module -avoid-version
+lmnsdsel_ptcp_la_LIBADD =
+endif # if ENABLE_INET
+
+#
+# GnuTLS netstream driver
+#
+if ENABLE_GNUTLS
+pkglib_LTLIBRARIES += lmnsd_gtls.la
+lmnsd_gtls_la_SOURCES = nsd_gtls.c nsd_gtls.h
+lmnsd_gtls_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags) $(gnutls_cflags)
+lmnsd_gtls_la_LDFLAGS = -module -avoid-version
+lmnsd_gtls_la_LIBADD = $(gnutls_libs)
+#
+# select interface for gtls driver
+pkglib_LTLIBRARIES += lmnsdsel_gtls.la
+lmnsdsel_gtls_la_SOURCES = nsdsel_gtls.c nsdsel_gtls.h
+lmnsdsel_gtls_la_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+lmnsdsel_gtls_la_LDFLAGS = -module -avoid-version
+lmnsdsel_gtls_la_LIBADD =
+endif
+
diff --git a/atomic.h b/runtime/atomic.h
index 2421c826..430ae7f0 100644
--- a/atomic.h
+++ b/runtime/atomic.h
@@ -13,22 +13,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h" /* autotools! */
diff --git a/cfsysline.c b/runtime/cfsysline.c
index 1aebc354..0043ce5c 100644
--- a/cfsysline.c
+++ b/runtime/cfsysline.c
@@ -7,20 +7,23 @@
*
* This file is part of rsyslog.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
@@ -34,7 +37,6 @@
#include <pwd.h>
#include <grp.h>
-#include "syslogd.h" /* TODO: when the module interface & library design is done, this should be able to go away */
#include "cfsysline.h"
#include "obj.h"
#include "errmsg.h"
diff --git a/cfsysline.h b/runtime/cfsysline.h
index 2eec18ab..07ab5fcd 100644
--- a/cfsysline.h
+++ b/runtime/cfsysline.h
@@ -2,22 +2,23 @@
*
* Copyright 2007 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef CFSYSLINE_H_INCLUDED
diff --git a/ctok.c b/runtime/ctok.c
index de2bd8a8..de2bd8a8 100644
--- a/ctok.c
+++ b/runtime/ctok.c
diff --git a/ctok.h b/runtime/ctok.h
index 591f0838..591f0838 100644
--- a/ctok.h
+++ b/runtime/ctok.h
diff --git a/ctok_token.c b/runtime/ctok_token.c
index 0f340675..0f340675 100644
--- a/ctok_token.c
+++ b/runtime/ctok_token.c
diff --git a/ctok_token.h b/runtime/ctok_token.h
index 346d5acd..346d5acd 100644
--- a/ctok_token.h
+++ b/runtime/ctok_token.h
diff --git a/datetime.c b/runtime/datetime.c
index a4817a6d..d72cac3c 100644
--- a/datetime.c
+++ b/runtime/datetime.c
@@ -7,22 +7,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
diff --git a/datetime.h b/runtime/datetime.h
index a35dfe8a..fcb78172 100644
--- a/datetime.h
+++ b/runtime/datetime.h
@@ -2,22 +2,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef INCLUDED_DATETIME_H
#define INCLUDED_DATETIME_H
diff --git a/debug.c b/runtime/debug.c
index 29c65cf1..53624e38 100644
--- a/debug.c
+++ b/runtime/debug.c
@@ -15,22 +15,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h" /* autotools! */
#include <stdio.h>
diff --git a/debug.h b/runtime/debug.h
index 4dcc593a..214b7c05 100644
--- a/debug.h
+++ b/runtime/debug.h
@@ -5,22 +5,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef DEBUG_H_INCLUDED
#define DEBUG_H_INCLUDED
diff --git a/errmsg.c b/runtime/errmsg.c
index 907046b9..1744c902 100644
--- a/errmsg.c
+++ b/runtime/errmsg.c
@@ -1,26 +1,28 @@
/* The errmsg object.
*
* Module begun 2008-03-05 by Rainer Gerhards, based on some code
- * from syslogd.c
+ * from syslogd.c. I converted this module to lgpl and have checked that
+ * all contributors agreed to that step.
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
@@ -31,7 +33,6 @@
#include <assert.h>
#include "rsyslog.h"
-#include "syslogd.h"
#include "obj.h"
#include "errmsg.h"
#include "sysvar.h"
@@ -81,7 +82,8 @@ LogError(int __attribute__((unused)) iErrCode, char *fmt, ... )
}
msg[sizeof(msg)/sizeof(char) - 1] = '\0'; /* just to be on the safe side... */
errno = 0;
- logmsgInternal(LOG_SYSLOG|LOG_ERR, msg, ADDDATE);
+
+ glblErrLogger((uchar*)msg);
ENDfunc
}
@@ -116,5 +118,12 @@ BEGINAbstractObjClassInit(errmsg, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* set our own handlers */
ENDObjClassInit(errmsg)
+/* Exit the class.
+ * rgerhards, 2008-04-17
+ */
+BEGINObjClassExit(errmsg, OBJ_IS_CORE_MODULE) /* class, version */
+ /* release objects we no longer need */
+ENDObjClassExit(errmsg)
+
/* vi:set ai:
*/
diff --git a/errmsg.h b/runtime/errmsg.h
index 12469581..bde6bcff 100644
--- a/errmsg.h
+++ b/runtime/errmsg.h
@@ -2,22 +2,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef INCLUDED_ERRMSG_H
#define INCLUDED_ERRMSG_H
diff --git a/expr.c b/runtime/expr.c
index 9c357404..9c357404 100644
--- a/expr.c
+++ b/runtime/expr.c
diff --git a/expr.h b/runtime/expr.h
index 974b71ec..974b71ec 100644
--- a/expr.h
+++ b/runtime/expr.h
diff --git a/runtime/glbl.c b/runtime/glbl.c
new file mode 100644
index 00000000..787b6ab7
--- /dev/null
+++ b/runtime/glbl.c
@@ -0,0 +1,205 @@
+/* glbl.c - this module holds global defintions and data items.
+ * These are shared among the runtime library. Their use should be
+ * limited to cases where it is actually needed. The main intension for
+ * implementing them was support for the transistion from v2 to v4
+ * (with fully modular design), but it turned out that there may also
+ * be some other good use cases besides backwards-compatibility.
+ *
+ * Module begun 2008-04-16 by Rainer Gerhards
+ *
+ * Copyright 2008 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.
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <assert.h>
+
+#include "rsyslog.h"
+#include "obj.h"
+#include "cfsysline.h"
+#include "glbl.h"
+
+/* some defaults */
+#ifndef DFLT_NETSTRM_DRVR
+// TESTING ONLY# define DFLT_NETSTRM_DRVR ((uchar*)"lmnsd_ptcp")
+#warning "define must be restored for non-testing!"
+# define DFLT_NETSTRM_DRVR ((uchar*)"lmnsd_gtls")
+#endif
+
+/* static data */
+DEFobjStaticHelpers
+
+/* static data
+ * For this object, these variables are obviously what makes the "meat" of the
+ * class...
+ */
+static uchar *pszWorkDir = NULL;
+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 uchar *LocalHostName = NULL;/* our hostname - read-only after startup */
+static uchar *LocalDomain; /* our local domain name - read-only after startup */
+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 */
+
+
+/* define a macro for the simple properties' set and get functions
+ * (which are always the same). This is only suitable for pretty
+ * simple cases which require neither checks nor memory allocation.
+ */
+#define SIMP_PROP(nameFunc, nameVar, dataType) \
+ SIMP_PROP_GET(nameFunc, nameVar, dataType) \
+ SIMP_PROP_SET(nameFunc, nameVar, dataType)
+#define SIMP_PROP_SET(nameFunc, nameVar, dataType) \
+static rsRetVal Set##nameFunc(dataType newVal) \
+{ \
+ nameVar = newVal; \
+ return RS_RET_OK; \
+}
+#define SIMP_PROP_GET(nameFunc, nameVar, dataType) \
+static dataType Get##nameFunc(void) \
+{ \
+ return(nameVar); \
+}
+
+SIMP_PROP(DefPFFamily, iDefPFFamily, int) /* note that in the future we may check the family argument */
+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**)
+
+SIMP_PROP_SET(LocalHostName, LocalHostName, uchar*)
+SIMP_PROP_SET(DfltNetstrmDrvr, pszDfltNetstrmDrvr, uchar*) // TODO: use custom function which frees existing value
+
+#undef SIMP_PROP
+#undef SIMP_PROP_SET
+#undef SIMP_PROP_GET
+
+
+/* return our local hostname. if it is not set, "[localhost]" is returned
+ */
+static uchar*
+GetLocalHostName(void)
+{
+ return(LocalHostName == NULL ? (uchar*) "[localhost]" : LocalHostName);
+}
+
+
+/* return the current working directory */
+static uchar*
+GetWorkDir(void)
+{
+ return(pszWorkDir == NULL ? (uchar*) "" : pszWorkDir);
+}
+
+
+/* return the current default netstream driver */
+static uchar*
+GetDfltNetstrmDrvr(void)
+{
+ return(pszDfltNetstrmDrvr == NULL ? DFLT_NETSTRM_DRVR : pszWorkDir);
+}
+
+
+/* queryInterface function
+ * rgerhards, 2008-02-21
+ */
+BEGINobjQueryInterface(glbl)
+CODESTARTobjQueryInterface(glbl)
+ if(pIf->ifVersion != glblCURR_IF_VERSION) { /* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->GetWorkDir = GetWorkDir;
+#define SIMP_PROP(name) \
+ pIf->Get##name = Get##name; \
+ pIf->Set##name = Set##name;
+ SIMP_PROP(DefPFFamily);
+ SIMP_PROP(DropMalPTRMsgs);
+ SIMP_PROP(Option_DisallowWarning);
+ SIMP_PROP(DisableDNS);
+ SIMP_PROP(LocalHostName)
+ SIMP_PROP(LocalDomain)
+ SIMP_PROP(StripDomains)
+ SIMP_PROP(LocalHosts)
+ SIMP_PROP(DfltNetstrmDrvr)
+#undef SIMP_PROP
+finalize_it:
+ENDobjQueryInterface(glbl)
+
+
+/* Reset config variables to default values.
+ * rgerhards, 2008-04-17
+ */
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
+{
+ if(pszDfltNetstrmDrvr != NULL) {
+ free(pszDfltNetstrmDrvr);
+ pszDfltNetstrmDrvr = NULL;
+ }
+ if(pszWorkDir != NULL) {
+ free(pszWorkDir);
+ pszWorkDir = NULL;
+ }
+ bDropMalPTRMsgs = 0;
+ return RS_RET_OK;
+}
+
+
+
+/* Initialize the glbl class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-19
+ */
+BEGINAbstractObjClassInit(glbl, 1, OBJ_IS_CORE_MODULE) /* class, version */
+ /* request objects we use */
+
+ /* register config handlers (TODO: we need to implement a way to unregister them) */
+ CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs, NULL));
+ CHKiRet(regCfSysLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, NULL));
+ENDObjClassInit(glbl)
+
+
+/* Exit the glbl class.
+ * rgerhards, 2008-04-17
+ */
+BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */
+ if(pszDfltNetstrmDrvr != NULL)
+ free(pszDfltNetstrmDrvr);
+ if(pszWorkDir != NULL)
+ free(pszWorkDir);
+ if(LocalHostName != NULL)
+ free(LocalHostName);
+ENDObjClassExit(glbl)
+
+/* vi:set ai:
+ */
diff --git a/runtime/glbl.h b/runtime/glbl.h
new file mode 100644
index 00000000..b6864f3d
--- /dev/null
+++ b/runtime/glbl.h
@@ -0,0 +1,59 @@
+/* Definition of globally-accessible data items.
+ *
+ * This module provides access methods to items of global scope. Most often,
+ * these globals serve as defaults to initialize local settings. Currently,
+ * many of them are either constants or global variable references. However,
+ * this module provides the necessary hooks to change that at any time.
+ *
+ * Please note that there currently is no glbl.c file as we do not yet
+ * have any implementations.
+ *
+ * Copyright 2008 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.
+ */
+
+#ifndef GLBL_H_INCLUDED
+#define GLBL_H_INCLUDED
+
+#define glblGetIOBufSize() 4096 /* size of the IO buffer, e.g. for strm class */
+
+/* interfaces */
+BEGINinterface(glbl) /* name must also be changed in ENDinterface macro! */
+ uchar* (*GetWorkDir)(void);
+#define SIMP_PROP(name, dataType) \
+ dataType (*Get##name)(void); \
+ rsRetVal (*Set##name)(dataType);
+ SIMP_PROP(DefPFFamily, int);
+ SIMP_PROP(DropMalPTRMsgs, int);
+ SIMP_PROP(Option_DisallowWarning, int);
+ SIMP_PROP(DisableDNS, int);
+ SIMP_PROP(LocalHostName, uchar*)
+ SIMP_PROP(LocalDomain, uchar*)
+ SIMP_PROP(StripDomains, char**)
+ SIMP_PROP(LocalHosts, char**)
+ SIMP_PROP(DfltNetstrmDrvr, uchar*)
+#undef SIMP_PROP
+ENDinterface(glbl)
+#define glblCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+
+/* the remaining prototypes */
+PROTOTYPEObj(glbl);
+
+#endif /* #ifndef GLBL_H_INCLUDED */
diff --git a/linkedlist.c b/runtime/linkedlist.c
index 383cf488..8f842e43 100644
--- a/linkedlist.c
+++ b/runtime/linkedlist.c
@@ -13,22 +13,23 @@
*
* Copyright (C) 2007, 2008 by Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
@@ -409,7 +410,5 @@ finalize_it:
RETiRet;
}
-
-/*
- * vi:set ai:
+/* vim:set ai:
*/
diff --git a/linkedlist.h b/runtime/linkedlist.h
index 98fb76a5..aeacd6d7 100644
--- a/linkedlist.h
+++ b/runtime/linkedlist.h
@@ -1,23 +1,24 @@
/* Definition of the linkedlist object.
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef LINKEDLIST_H_INCLUDED
diff --git a/module-template.h b/runtime/module-template.h
index d5e142b4..5db73d33 100644
--- a/module-template.h
+++ b/runtime/module-template.h
@@ -6,22 +6,23 @@
*
* Copyright 2007 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef MODULE_TEMPLATE_H_INCLUDED
#define MODULE_TEMPLATE_H_INCLUDED 1
diff --git a/modules.c b/runtime/modules.c
index 32a71c0c..c156fef2 100644
--- a/modules.c
+++ b/runtime/modules.c
@@ -13,22 +13,23 @@
*
* Copyright 2007 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
#include "rsyslog.h"
@@ -48,7 +49,6 @@
#include <unistd.h>
#include <sys/file.h>
-#include "syslogd.h"
#include "cfsysline.h"
#include "modules.h"
#include "errmsg.h"
diff --git a/modules.h b/runtime/modules.h
index a8371d05..7d34bcf7 100644
--- a/modules.h
+++ b/runtime/modules.h
@@ -12,30 +12,30 @@
*
* File begun on 2007-07-22 by RGerhards
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef MODULES_H_INCLUDED
#define MODULES_H_INCLUDED 1
#include "objomsr.h"
-#include "threads.h"
/* the following define defines the current version of the module interface.
diff --git a/msg.c b/runtime/msg.c
index 9a12d572..e72ef71b 100644
--- a/msg.c
+++ b/runtime/msg.c
@@ -7,24 +7,25 @@
* of the "old" message code without any modifications. However, it
* helps to have things at the right place one we go to the meat of it.
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
#include <stdio.h>
@@ -35,7 +36,6 @@
#include <assert.h>
#include <ctype.h>
#include "rsyslog.h"
-#include "syslogd.h"
#include "srUtils.h"
#include "stringbuf.h"
#include "template.h"
@@ -684,7 +684,6 @@ char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszTIMESTAMP3164 == NULL) {
if((pM->pszTIMESTAMP3164 = malloc(16)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -696,7 +695,6 @@ char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszTIMESTAMP_MySQL == NULL) {
if((pM->pszTIMESTAMP_MySQL = malloc(15)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -708,7 +706,6 @@ char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszTIMESTAMP_PgSQL == NULL) {
if((pM->pszTIMESTAMP_PgSQL = malloc(21)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -720,7 +717,6 @@ char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszTIMESTAMP3164 == NULL) {
if((pM->pszTIMESTAMP3164 = malloc(16)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -732,7 +728,6 @@ char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszTIMESTAMP3339 == NULL) {
if((pM->pszTIMESTAMP3339 = malloc(33)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return ""; /* TODO: check this: can it cause a free() of constant memory?) */
}
@@ -754,7 +749,6 @@ char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszRcvdAt3164 == NULL) {
if((pM->pszRcvdAt3164 = malloc(16)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -766,7 +760,6 @@ char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszRcvdAt_MySQL == NULL) {
if((pM->pszRcvdAt_MySQL = malloc(15)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -778,7 +771,6 @@ char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszRcvdAt_PgSQL == NULL) {
if((pM->pszRcvdAt_PgSQL = malloc(21)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -790,7 +782,6 @@ char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszRcvdAt3164 == NULL) {
if((pM->pszRcvdAt3164 = malloc(16)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -802,7 +793,6 @@ char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt)
MsgLock(pM);
if(pM->pszRcvdAt3339 == NULL) {
if((pM->pszRcvdAt3339 = malloc(33)) == NULL) {
- glblHadMemShortage = 1;
MsgUnlock(pM);
return "";
}
@@ -1498,7 +1488,6 @@ static uchar *getNOW(eNOWType eNow)
struct syslogTime t;
if((pBuf = (uchar*) malloc(sizeof(uchar) * tmpBUFSIZE)) == NULL) {
- glblHadMemShortage = 1;
return NULL;
}
diff --git a/msg.h b/runtime/msg.h
index 61feaddb..9ec038dd 100644
--- a/msg.h
+++ b/runtime/msg.h
@@ -5,22 +5,23 @@
*
* Copyright 2007 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "template.h" /* this is a quirk, but these two are too interdependant... */
@@ -106,7 +107,6 @@ struct msg {
char *pszTIMESTAMP_PgSQL;/* TIMESTAMP as PgSQL formatted string (always 21 characters) */
int msgFlags; /* flags associated with this message */
};
-typedef struct msg msg_t; /* new name */
/* function prototypes
*/
diff --git a/net.c b/runtime/net.c
index bbd6bec7..1d085290 100644
--- a/net.c
+++ b/runtime/net.c
@@ -4,7 +4,7 @@
* File begun on 2007-07-20 by RGerhards (extracted from syslogd.c)
* This file is under development and has not yet arrived at being fully
* self-contained and a real object. So far, it is mostly an excerpt
- * of the "old" message code without any modifications. However, it
+ * of the "old" networking code without any modifications. However, it
* helps to have things at the right place one we go to the meat of it.
*
* Starting 2007-12-24, I have begun to shuffle more network-related code
@@ -12,24 +12,32 @@
* long term, but it is good to have it out of syslogd.c. Maybe this here is
* an interim location ;)
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * rgerhards, 2008-04-16: I changed this code to LGPL today. I carefully analyzed
+ * that it does not borrow code from the original sysklogd and that I have
+ * permission to do so from all other contributors. My analysis found that all
+ * code from sysklogd has been superseeded by our own functionality, so it
+ * is OK to move this file to LGPL. Some variable sysklogd variable names
+ * remain, but even this will change as the net object evolves.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
@@ -47,7 +55,6 @@
#include <fcntl.h>
#include <unistd.h>
-#include "syslogd.h"
#include "syslogd-types.h"
#include "module-template.h"
#include "parse.h"
@@ -61,6 +68,7 @@ MODULE_TYPE_LIB
/* static data */
DEFobjStaticHelpers
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
/* support for defining allowed TCP and UDP senders. We use the same
* structure to implement this (a linked list), but we define two different
@@ -123,7 +131,6 @@ static rsRetVal AddAllowedSenderEntry(struct AllowedSenders **ppRoot, struct All
assert(iAllow != NULL);
if((pEntry = (struct AllowedSenders*) calloc(1, sizeof(struct AllowedSenders))) == NULL) {
- glblHadMemShortage = 1;
return RS_RET_OUT_OF_MEMORY; /* no options left :( */
}
@@ -227,7 +234,7 @@ static rsRetVal AddAllowedSender(struct AllowedSenders **ppRoot, struct AllowedS
iRet = AddAllowedSenderEntry(ppRoot, ppLast, iAllow, iSignificantBits);
} else {
/* we need to process a hostname ACL */
- if (DisableDNS) {
+ if(glbl.GetDisableDNS()) {
errmsg.LogError(NO_ERRCODE, "Ignoring hostname based ACLs because DNS is disabled.");
ABORT_FINALIZE(RS_RET_OK);
}
@@ -267,7 +274,6 @@ static rsRetVal AddAllowedSender(struct AllowedSenders **ppRoot, struct AllowedS
iSignificantBits = 32;
allowIP.flags = 0;
if((allowIP.addr.NetAddr = malloc(res->ai_addrlen)) == NULL) {
- glblHadMemShortage = 1;
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
memcpy(allowIP.addr.NetAddr, res->ai_addr, res->ai_addrlen);
@@ -284,7 +290,6 @@ static rsRetVal AddAllowedSender(struct AllowedSenders **ppRoot, struct AllowedS
allowIP.flags = 0;
if((allowIP.addr.NetAddr = malloc(sizeof(struct sockaddr_in)))
== NULL) {
- glblHadMemShortage = 1;
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
SIN(allowIP.addr.NetAddr)->sin_family = AF_INET;
@@ -306,7 +311,6 @@ static rsRetVal AddAllowedSender(struct AllowedSenders **ppRoot, struct AllowedS
iSignificantBits = 128;
allowIP.flags = 0;
if((allowIP.addr.NetAddr = malloc(res->ai_addrlen)) == NULL) {
- glblHadMemShortage = 1;
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
memcpy(allowIP.addr.NetAddr, res->ai_addr, res->ai_addrlen);
@@ -651,7 +655,7 @@ gethname(struct sockaddr_storage *f, uchar *pszHostFQDN)
ABORT_FINALIZE(RS_RET_INVALID_SOURCE);
}
- if (!DisableDNS) {
+ if(!glbl.GetDisableDNS()) {
sigemptyset(&nmask);
sigaddset(&nmask, SIGHUP);
pthread_sigmask(SIG_BLOCK, &nmask, &omask);
@@ -662,7 +666,6 @@ gethname(struct sockaddr_storage *f, uchar *pszHostFQDN)
if (error == 0) {
memset (&hints, 0, sizeof (struct addrinfo));
hints.ai_flags = AI_NUMERICHOST;
- hints.ai_socktype = SOCK_DGRAM;
/* we now do a lookup once again. This one should fail,
* because we should not have obtained a non-numeric address. If
@@ -680,7 +683,7 @@ gethname(struct sockaddr_storage *f, uchar *pszHostFQDN)
* time being, we simply drop the name we obtained and use the IP - that one
* is OK in any way. We do also log the error message. rgerhards, 2007-07-16
*/
- if(bDropMalPTRMsgs == 1) {
+ if(glbl.GetDropMalPTRMsgs() == 1) {
snprintf((char*)szErrMsg, sizeof(szErrMsg) / sizeof(uchar),
"Malicious PTR record, message dropped "
"IP = \"%s\" HOST = \"%s\"",
@@ -708,7 +711,7 @@ gethname(struct sockaddr_storage *f, uchar *pszHostFQDN)
pthread_sigmask(SIG_SETMASK, &omask, NULL);
}
- if (error || DisableDNS) {
+ if(error || glbl.GetDisableDNS()) {
dbgprintf("Host name for your address (%s) unknown\n", ip);
strcpy((char*) pszHostFQDN, ip);
ABORT_FINALIZE(RS_RET_ADDRESS_UNKNOWN);
@@ -792,9 +795,8 @@ rsRetVal cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN
/* if we reach this point, we obtained a non-numeric hostname and can now process it */
- /* Convert to lower case, just like LocalDomain above
- */
- for (p = pszHostFQDN ; *p ; p++)
+ /* Convert to lower case */
+ for(p = pszHostFQDN ; *p ; p++)
if (isupper((int) *p))
*p = tolower(*p);
@@ -810,16 +812,19 @@ rsRetVal cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN
*/
strcpy((char*)pszHost, (char*)pszHostFQDN);
if ((p = (uchar*) strchr((char*)pszHost, '.'))) { /* find start of domain name "machine.example.com" */
- if(strcmp((char*) (p + 1), LocalDomain) == 0) {
+ if(strcmp((char*)(p + 1), (char*)glbl.GetLocalDomain()) == 0) {
*p = '\0'; /* simply terminate the string */
} else {
/* now check if we belong to any of the domain names that were specified
* in the -s command line option. If so, remove and we are done.
+ * TODO: this must go away! -- rgerhards, 2008-04-16
+ * For proper modularization, this must be done different, e.g. via a
+ * "to be stripped" property of *this* object itself.
*/
- if (StripDomains) {
+ if(glbl.GetStripDomains() != NULL) {
count=0;
- while (StripDomains[count]) {
- if (strcmp((char*)(p + 1), StripDomains[count]) == 0) {
+ while(glbl.GetStripDomains()[count]) {
+ if (strcmp((char*)(p + 1), glbl.GetStripDomains()[count]) == 0) {
*p = '\0';
FINALIZE; /* we are done */
}
@@ -833,11 +838,12 @@ rsRetVal cvthname(struct sockaddr_storage *f, uchar *pszHost, uchar *pszHostFQDN
* door would be wide-open for all kinds of mixing up of hosts. Because of this,
* you'll see comparison against the full string (pszHost) below. The termination
* still occurs at *p, which points at the first dot after the hostname.
+ * TODO: this must also go away - see comment above -- rgerhards, 2008-04-16
*/
- if (LocalHosts) {
+ if(glbl.GetLocalHosts() != NULL) {
count=0;
- while (LocalHosts[count]) {
- if (!strcmp((char*)pszHost, LocalHosts[count])) {
+ while (glbl.GetLocalHosts()[count]) {
+ if (!strcmp((char*)pszHost, (char*)glbl.GetLocalHosts()[count])) {
*p = '\0';
break; /* we are done */
}
@@ -923,7 +929,7 @@ int *create_udp_socket(uchar *hostname, uchar *pszPort, int bIsServer)
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
else
hints.ai_flags = AI_NUMERICSERV;
- hints.ai_family = family;
+ hints.ai_family = glbl.GetDefPFFamily();
hints.ai_socktype = SOCK_DGRAM;
error = getaddrinfo((char*) hostname, (char*) pszPort, &hints, &res);
if(error) {
@@ -1096,6 +1102,7 @@ ENDobjQueryInterface(net)
BEGINObjClassExit(net, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
CODESTARTObjClassExit(net)
/* release objects we no longer need */
+ objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
ENDObjClassExit(net)
@@ -1107,6 +1114,7 @@ ENDObjClassExit(net)
BEGINAbstractObjClassInit(net, 1, OBJ_IS_CORE_MODULE) /* class, version */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
/* set our own handlers */
ENDObjClassInit(net)
diff --git a/net.h b/runtime/net.h
index 0f5b0bc1..59199451 100644
--- a/net.h
+++ b/runtime/net.h
@@ -1,32 +1,37 @@
/* Definitions for network-related stuff.
*
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ * Copyright 2007, 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef INCLUDED_NET_H
#define INCLUDED_NET_H
-#ifdef SYSLOG_INET
#include <netinet/in.h>
#include <sys/socket.h> /* this is needed on HP UX -- rgerhards, 2008-03-04 */
+typedef enum _TCPFRAMINGMODE {
+ TCP_FRAMING_OCTET_STUFFING = 0, /* traditional LF-delimited */
+ TCP_FRAMING_OCTET_COUNTING = 1 /* -transport-tls like octet count */
+ } TCPFRAMINGMODE;
+
#define F_SET(where, flag) (where)|=(flag)
#define F_ISSET(where, flag) ((where)&(flag))==(flag)
#define F_UNSET(where, flag) (where)&=~(flag)
@@ -49,7 +54,7 @@ struct NetAddr {
};
#ifndef SO_BSDCOMPAT
- /* this shall prevent compiler errors due to undfined name */
+ /* this shall prevent compiler errors due to undefined name */
# define SO_BSDCOMPAT 0
#endif
@@ -114,5 +119,4 @@ PROTOTYPEObj(net);
/* the name of our library binary */
#define LM_NET_FILENAME "lmnet"
-#endif /* #ifdef SYSLOG_INET */
#endif /* #ifndef INCLUDED_NET_H */
diff --git a/runtime/netstrm.c b/runtime/netstrm.c
new file mode 100644
index 00000000..be754aae
--- /dev/null
+++ b/runtime/netstrm.c
@@ -0,0 +1,305 @@
+/* netstrm.c
+ *
+ * This class implements a generic netstrmwork stream class. It supports
+ * sending and receiving data streams over a netstrmwork. The class abstracts
+ * the transport, though it is a safe assumption that TCP is being used.
+ * The class has a number of properties, among which are also ones to
+ * select privacy settings, eg by enabling TLS and/or GSSAPI. In the
+ * long run, this class shall provide all stream-oriented netstrmwork
+ * functionality inside rsyslog.
+ *
+ * It is a high-level class, which uses a number of helper objects
+ * to carry out its work (including, and most importantly, transport
+ * drivers).
+ *
+ * Work on this module begun 2008-04-17 by Rainer Gerhards. This code
+ * borrows from librelp's tcp.c/.h code. librelp is dual licensed and
+ * Rainer Gerhards and Adiscon GmbH have agreed to permit using the code
+ * under the terms of the GNU Lesser General Public License.
+ *
+ * Copyright 2007, 2008 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.
+ */
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "rsyslog.h"
+#include "module-template.h"
+#include "obj.h"
+#include "errmsg.h"
+//#include "nsd.h"
+#include "netstrms.h"
+#include "netstrm.h"
+
+MODULE_TYPE_LIB
+
+/* static data */
+DEFobjStaticHelpers
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(netstrms)
+
+
+/* Standard-Constructor */
+BEGINobjConstruct(netstrm) /* be sure to specify the object type also in END macro! */
+ENDobjConstruct(netstrm)
+
+
+/* destructor for the netstrm object */
+BEGINobjDestruct(netstrm) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDestruct(netstrm)
+ if(pThis->pDrvrData != NULL)
+ iRet = pThis->Drvr.Destruct(&pThis->pDrvrData);
+ENDobjDestruct(netstrm)
+
+
+/* ConstructionFinalizer */
+static rsRetVal
+netstrmConstructFinalize(netstrm_t *pThis)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ CHKiRet(pThis->Drvr.Construct(&pThis->pDrvrData));
+finalize_it:
+ RETiRet;
+}
+
+/* abort a connection. This is much like Destruct(), but tries
+ * to discard any unsent data. -- rgerhards, 2008-03-24
+ */
+static rsRetVal
+AbortDestruct(netstrm_t **ppThis)
+{
+ DEFiRet;
+ assert(ppThis != NULL);
+ ISOBJ_TYPE_assert((*ppThis), netstrm);
+
+ /* we do NOT exit on error, because that would make things worse */
+ (*ppThis)->Drvr.Abort((*ppThis)->pDrvrData);
+ iRet = netstrmDestruct(ppThis);
+
+ RETiRet;
+}
+
+
+/* accept an incoming connection request
+ * The netstrm instance that had the incoming request must be provided. If
+ * the connection request succeeds, a new netstrm object is created and
+ * passed back to the caller. The caller is responsible for destructing it.
+ * pReq is the nsd_t obj that has the accept request.
+ * rgerhards, 2008-04-21
+ */
+static rsRetVal
+AcceptConnReq(netstrm_t *pThis, netstrm_t **ppNew)
+{
+ nsd_t *pNewNsd = NULL;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ assert(ppNew != NULL);
+
+ /* accept the new connection */
+ CHKiRet(pThis->Drvr.AcceptConnReq(pThis->pDrvrData, &pNewNsd));
+ /* construct our object so that we can use it... */
+ CHKiRet(netstrms.CreateStrm(pThis->pNS, ppNew));
+ (*ppNew)->pDrvrData = pNewNsd;
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ /* the close may be redundant, but that doesn't hurt... */
+ if(pNewNsd != NULL)
+ pThis->Drvr.Destruct(&pNewNsd);
+ }
+
+ RETiRet;
+}
+
+
+/* make the netstrm listen to specified port and IP.
+ * pLstnIP points to the port to listen to (NULL means "all"),
+ * iMaxSess has the maximum number of sessions permitted (this ist just a hint).
+ * pLstnPort must point to a port name or number. NULL is NOT permitted.
+ * rgerhards, 2008-04-22
+ */
+static rsRetVal
+LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
+ uchar *pLstnPort, uchar *pLstnIP, int iSessMax)
+{
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pNS, netstrms);
+ assert(fAddLstn != NULL);
+ assert(pLstnPort != NULL);
+
+ CHKiRet(pNS->Drvr.LstnInit(pNS, pUsr, fAddLstn, pLstnPort, pLstnIP, iSessMax));
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* receive data from a tcp socket
+ * The lenBuf parameter must contain the max buffer size on entry and contains
+ * the number of octets read (or -1 in case of error) on exit. This function
+ * never blocks, not even when called on a blocking socket. That is important
+ * for client sockets, which are set to block during send, but should not
+ * block when trying to read data. If *pLenBuf is -1, an error occured and
+ * errno holds the exact error cause.
+ * rgerhards, 2008-03-17
+ */
+static rsRetVal
+Rcv(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ iRet = pThis->Drvr.Rcv(pThis->pDrvrData, pBuf, pLenBuf);
+ RETiRet;
+}
+
+
+/* send a buffer. On entry, pLenBuf contains the number of octets to
+ * write. On exit, it contains the number of octets actually written.
+ * If this number is lower than on entry, only a partial buffer has
+ * been written.
+ * rgerhards, 2008-03-19
+ */
+static rsRetVal
+Send(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ iRet = pThis->Drvr.Send(pThis->pDrvrData, pBuf, pLenBuf);
+ RETiRet;
+}
+
+
+/* get remote hname - slim wrapper for NSD driver function */
+static rsRetVal
+GetRemoteHName(netstrm_t *pThis, uchar **ppsz)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ iRet = pThis->Drvr.GetRemoteHName(pThis->pDrvrData, ppsz);
+ RETiRet;
+}
+
+
+/* get remote IP - slim wrapper for NSD driver function */
+static rsRetVal
+GetRemoteIP(netstrm_t *pThis, uchar **ppsz)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ iRet = pThis->Drvr.GetRemoteIP(pThis->pDrvrData, ppsz);
+ RETiRet;
+}
+
+
+/* open a connection to a remote host (server).
+ * rgerhards, 2008-03-19
+ */
+static rsRetVal
+Connect(netstrm_t *pThis, int family, uchar *port, uchar *host)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrm);
+ assert(port != NULL);
+ assert(host != NULL);
+ iRet = pThis->Drvr.Connect(pThis->pDrvrData, family, port, host);
+ RETiRet;
+}
+
+
+/* queryInterface function
+ */
+BEGINobjQueryInterface(netstrm)
+CODESTARTobjQueryInterface(netstrm)
+ if(pIf->ifVersion != netstrmCURR_IF_VERSION) {/* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->Construct = netstrmConstruct;
+ pIf->ConstructFinalize = netstrmConstructFinalize;
+ pIf->Destruct = netstrmDestruct;
+ pIf->AbortDestruct = AbortDestruct;
+ pIf->Rcv = Rcv;
+ pIf->Send = Send;
+ pIf->Connect = Connect;
+ pIf->LstnInit = LstnInit;
+ pIf->AcceptConnReq = AcceptConnReq;
+ pIf->GetRemoteHName = GetRemoteHName;
+ pIf->GetRemoteIP = GetRemoteIP;
+finalize_it:
+ENDobjQueryInterface(netstrm)
+
+
+/* exit our class
+ */
+BEGINObjClassExit(netstrm, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+CODESTARTObjClassExit(netstrm)
+ /* release objects we no longer need */
+ objRelease(errmsg, CORE_COMPONENT);
+ objRelease(netstrms, LM_NETSTRMS_FILENAME);
+ENDObjClassExit(netstrm)
+
+
+/* Initialize the netstrm class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-19
+ */
+BEGINAbstractObjClassInit(netstrm, 1, OBJ_IS_CORE_MODULE) /* class, version */
+ /* request objects we use */
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
+
+ /* set our own handlers */
+ENDObjClassInit(netstrm)
+
+
+/* --------------- here now comes the plumbing that makes as a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ netstrmClassExit();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(netstrmClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ENDmodInit
+/* vi:set ai:
+ */
diff --git a/runtime/netstrm.h b/runtime/netstrm.h
new file mode 100644
index 00000000..160bbb0b
--- /dev/null
+++ b/runtime/netstrm.h
@@ -0,0 +1,61 @@
+/* Definitions for the stream-based netstrmworking class.
+ *
+ * Copyright 2007, 2008 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.
+ */
+
+#ifndef INCLUDED_NETSTRM_H
+#define INCLUDED_NETSTRM_H
+
+#include "nsd.h" /* we need our driver interface to be defined */
+
+/* the netstrm object */
+struct netstrm_s {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ nsd_t *pDrvrData; /**< the driver's data elements (at most other places, this is called pNsd) */
+ nsd_if_t Drvr; /**< our stream driver */
+ netstrms_t *pNS; /**< pointer to our netstream subsystem object */
+};
+
+
+/* interface */
+BEGINinterface(netstrm) /* name must also be changed in ENDinterface macro! */
+ rsRetVal (*Construct)(netstrm_t **ppThis);
+ rsRetVal (*ConstructFinalize)(netstrm_t *pThis);
+ rsRetVal (*Destruct)(netstrm_t **ppThis);
+ rsRetVal (*AbortDestruct)(netstrm_t **ppThis);
+ rsRetVal (*LstnInit)(netstrms_t *pNS, void *pUsr, rsRetVal(*)(void*,netstrm_t*),
+ uchar *pLstnPort, uchar *pLstnIP, int iSessMax);
+ rsRetVal (*AcceptConnReq)(netstrm_t *pThis, netstrm_t **ppNew);
+ rsRetVal (*Rcv)(netstrm_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf);
+ rsRetVal (*Send)(netstrm_t *pThis, uchar *pBuf, ssize_t *pLenBuf);
+ rsRetVal (*Connect)(netstrm_t *pThis, int family, unsigned char *port, unsigned char *host);
+ rsRetVal (*GetRemoteHName)(netstrm_t *pThis, uchar **pszName);
+ rsRetVal (*GetRemoteIP)(netstrm_t *pThis, uchar **pszIP);
+ENDinterface(netstrm)
+#define netstrmCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+
+/* prototypes */
+PROTOTYPEObj(netstrm);
+
+/* the name of our library binary */
+#define LM_NETSTRM_FILENAME "lmnetstrm"
+
+#endif /* #ifndef INCLUDED_NETSTRM_H */
diff --git a/runtime/netstrms.c b/runtime/netstrms.c
new file mode 100644
index 00000000..661234e4
--- /dev/null
+++ b/runtime/netstrms.c
@@ -0,0 +1,200 @@
+/* netstrms.c
+ *
+ * Work on this module begung 2008-04-23 by Rainer Gerhards.
+ *
+ * Copyright 2008 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.
+ */
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "rsyslog.h"
+#include "module-template.h"
+#include "obj.h"
+//#include "errmsg.h"
+//#include "net.h"
+#include "nsd.h"
+#include "netstrm.h"
+#include "netstrms.h"
+
+MODULE_TYPE_LIB
+
+/* static data */
+DEFobjStaticHelpers
+//DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(netstrm)
+//DEFobjCurrIf(net)
+
+
+/* load our low-level driver. This must be done before any
+ * driver-specific functions (allmost all...) can be carried
+ * out. Note that the driver's .ifIsLoaded is correctly
+ * initialized by calloc() and we depend on that.
+ * rgerhards, 2008-04-18
+ */
+static rsRetVal
+loadDrvr(netstrms_t *pThis)
+{
+ uchar *pDrvrName;
+ DEFiRet;
+
+ pDrvrName = pThis->pDrvrName;
+ if(pDrvrName == NULL) /* if no drvr name is set, use system default */
+ pDrvrName = glbl.GetDfltNetstrmDrvr();
+
+ pThis->Drvr.ifVersion = nsdCURR_IF_VERSION;
+ /* The pDrvrName+2 below is a hack to obtain the object name. It
+ * safes us to have yet another variable with the name without "lm" in
+ * front of it. If we change the module load interface, we may re-think
+ * about this hack, but for the time being it is efficient and clean
+ * enough. -- rgerhards, 2008-04-18
+ */
+ CHKiRet(obj.UseObj(__FILE__, pDrvrName+2, pDrvrName, (void*) &pThis->Drvr));
+finalize_it:
+ RETiRet;
+}
+
+
+/* Standard-Constructor */
+BEGINobjConstruct(netstrms) /* be sure to specify the object type also in END macro! */
+ENDobjConstruct(netstrms)
+
+
+/* destructor for the netstrms object */
+BEGINobjDestruct(netstrms) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDestruct(netstrms)
+ if(pThis->pDrvrName != NULL)
+ free(pThis->pDrvrName);
+ENDobjDestruct(netstrms)
+
+
+/* ConstructionFinalizer */
+static rsRetVal
+netstrmsConstructFinalize(netstrms_t *pThis)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, netstrms);
+ CHKiRet(loadDrvr(pThis));
+finalize_it:
+ RETiRet;
+}
+
+
+/* create an instance of a netstrm object. It is initialized with default
+ * values. The current driver is used. The caller may set netstrm properties
+ * and must call ConstructFinalize().
+ */
+static rsRetVal
+CreateStrm(netstrms_t *pThis, netstrm_t **ppStrm)
+{
+ netstrm_t *pStrm = NULL;
+ DEFiRet;
+
+ CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
+ CHKiRet(netstrm.Construct(&pStrm));
+ /* we copy over our driver structure. We could provide a pointer to
+ * ourselves, but that costs some performance on each driver invocation.
+ * As we already have hefty indirection (and thus performance toll), I
+ * prefer to copy over the function pointers here. -- rgerhards, 2008-04-23
+ */
+ memcpy(&pStrm->Drvr, &pThis->Drvr, sizeof(pThis->Drvr));
+ pStrm->pNS = pThis;
+
+ *ppStrm = pStrm;
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pStrm != NULL)
+ netstrm.Destruct(&pStrm);
+ }
+ RETiRet;
+}
+
+
+/* queryInterface function */
+BEGINobjQueryInterface(netstrms)
+CODESTARTobjQueryInterface(netstrms)
+ if(pIf->ifVersion != netstrmsCURR_IF_VERSION) {/* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->Construct = netstrmsConstruct;
+ pIf->ConstructFinalize = netstrmsConstructFinalize;
+ pIf->Destruct = netstrmsDestruct;
+ pIf->CreateStrm = CreateStrm;
+finalize_it:
+ENDobjQueryInterface(netstrms)
+
+
+/* exit our class */
+BEGINObjClassExit(netstrms, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+CODESTARTObjClassExit(netstrms)
+ /* release objects we no longer need */
+ //objRelease(net, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(netstrm, LM_NETSTRM_FILENAME);
+ENDObjClassExit(netstrms)
+
+
+/* Initialize the netstrms class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-19
+ */
+BEGINAbstractObjClassInit(netstrms, 1, OBJ_IS_CORE_MODULE) /* class, version */
+ /* request objects we use */
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ //CHKiRet(objUse(net, CORE_COMPONENT));
+
+ /* set our own handlers */
+ENDObjClassInit(netstrms)
+
+
+/* --------------- here now comes the plumbing that makes as a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ netstrmsClassExit();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(netstrmsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ENDmodInit
+/* vi:set ai:
+ */
diff --git a/runtime/netstrms.h b/runtime/netstrms.h
new file mode 100644
index 00000000..1e920304
--- /dev/null
+++ b/runtime/netstrms.h
@@ -0,0 +1,52 @@
+/* Definitions for the stream-based netstrmsworking class.
+ *
+ * Copyright 2007, 2008 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.
+ */
+
+#ifndef INCLUDED_NETSTRMS_H
+#define INCLUDED_NETSTRMS_H
+
+#include "nsd.h" /* we need our driver interface to be defined */
+
+/* the netstrms object */
+struct netstrms_s {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ uchar *pDrvrName; /**< nsd driver name to use, or NULL if system default */
+ nsd_if_t Drvr; /**< our stream driver */
+};
+
+
+/* interface */
+BEGINinterface(netstrms) /* name must also be changed in ENDinterface macro! */
+ rsRetVal (*Construct)(netstrms_t **ppThis);
+ rsRetVal (*ConstructFinalize)(netstrms_t *pThis);
+ rsRetVal (*Destruct)(netstrms_t **ppThis);
+ rsRetVal (*CreateStrm)(netstrms_t *pThis, netstrm_t **ppStrm);
+ENDinterface(netstrms)
+#define netstrmsCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+
+/* prototypes */
+PROTOTYPEObj(netstrms);
+
+/* the name of our library binary */
+#define LM_NETSTRMS_FILENAME "lmnetstrms"
+
+#endif /* #ifndef INCLUDED_NETSTRMS_H */
diff --git a/runtime/nsd.h b/runtime/nsd.h
new file mode 100644
index 00000000..1b3702a0
--- /dev/null
+++ b/runtime/nsd.h
@@ -0,0 +1,72 @@
+/* The interface definition for "NetStream Drivers" (nsd).
+ *
+ * This is just an abstract driver interface, which needs to be
+ * implemented by concrete classes. As such, no nsd data type itself
+ * is defined.
+ *
+ * Copyright 2008 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.
+ */
+#ifndef INCLUDED_NSD_H
+#define INCLUDED_NSD_H
+
+enum nsdsel_waitOp_e {
+ NSDSEL_RD = 1,
+ NSDSEL_WR = 2,
+ NSDSEL_RDWR = 3
+}; /**< the operation we wait for */
+
+/* nsd_t is actually obj_t (which is somewhat better than void* but in essence
+ * much the same).
+ */
+
+/* interface */
+BEGINinterface(nsd) /* name must also be changed in ENDinterface macro! */
+ rsRetVal (*Construct)(nsd_t **ppThis);
+ rsRetVal (*Destruct)(nsd_t **ppThis);
+ rsRetVal (*Abort)(nsd_t *pThis);
+ rsRetVal (*Rcv)(nsd_t *pThis, uchar *pRcvBuf, ssize_t *pLenBuf);
+ rsRetVal (*Send)(nsd_t *pThis, uchar *pBuf, ssize_t *pLenBuf);
+ rsRetVal (*Connect)(nsd_t *pThis, int family, unsigned char *port, unsigned char *host);
+ rsRetVal (*LstnInit)(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
+ uchar *pLstnPort, uchar *pLstnIP, int iSessMax);
+ rsRetVal (*AcceptConnReq)(nsd_t *pThis, nsd_t **ppThis);
+ rsRetVal (*GetRemoteHName)(nsd_t *pThis, uchar **pszName);
+ rsRetVal (*GetRemoteIP)(nsd_t *pThis, uchar **pszIP);
+ rsRetVal (*GetSock)(nsd_t *pThis, int *pSock);
+ rsRetVal (*SetSock)(nsd_t *pThis, int sock);
+ /* GetSock() and SetSock() return an error if the driver does not use plain
+ * OS sockets. This interface is primarily meant as an internal aid for
+ * those drivers that utilize the nsd_ptcp to do some of their work.
+ */
+ENDinterface(nsd)
+#define nsdCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+
+/* interface for the select call */
+BEGINinterface(nsdsel) /* name must also be changed in ENDinterface macro! */
+ rsRetVal (*Construct)(nsdsel_t **ppThis);
+ rsRetVal (*Destruct)(nsdsel_t **ppThis);
+ rsRetVal (*Add)(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp);
+ rsRetVal (*Select)(nsdsel_t *pNsdsel, int *piNumReady);
+ rsRetVal (*IsReady)(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady);
+ENDinterface(nsdsel)
+#define nsdselCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+
+#endif /* #ifndef INCLUDED_NSD_H */
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c
new file mode 100644
index 00000000..d59043f2
--- /dev/null
+++ b/runtime/nsd_gtls.c
@@ -0,0 +1,444 @@
+/* nsd_gtls.c
+ *
+ * An implementation of the nsd interface for GnuTLS.
+ *
+ * Copyright (C) 2007, 2008 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.
+ */
+#include "config.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <gnutls/gnutls.h>
+
+#include "rsyslog.h"
+#include "syslogd-types.h"
+#include "module-template.h"
+#include "obj.h"
+#include "errmsg.h"
+#include "nsd_ptcp.h"
+#include "nsd_gtls.h"
+
+MODULE_TYPE_LIB
+
+/* static data */
+DEFobjStaticHelpers
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(nsd_ptcp)
+
+
+/* a macro to check GnuTLS calls against unexpected errors */
+#define CHKgnutls(x) \
+ if((gnuRet = (x)) != 0) { \
+ dbgprintf("unexpected GnuTLS error %d in %s:%d\n", gnuRet, __FILE__, __LINE__); \
+ gnutls_perror(gnuRet); /* TODO: can we do better? */ \
+ ABORT_FINALIZE(RS_RET_GNUTLS_ERR); \
+ }
+
+#define CAFILE "ca.pem" // TODO: allow to specify
+
+/* ------------------------------ GnuTLS specifics ------------------------------ */
+static gnutls_certificate_credentials xcred;
+
+/* globally initialize GnuTLS */
+static rsRetVal
+gtlsGlblInit(void)
+{
+ int gnuRet;
+ DEFiRet;
+
+ CHKgnutls(gnutls_global_init());
+
+ /* X509 stuff */
+ CHKgnutls(gnutls_certificate_allocate_credentials(&xcred));
+
+ /* sets the trusted cas file */
+ gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM);
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* globally de-initialize GnuTLS */
+static rsRetVal
+gtlsGlblExit(void)
+{
+ DEFiRet;
+ /* X509 stuff */
+ gnutls_certificate_free_credentials(xcred);
+ gnutls_global_deinit(); /* we are done... */
+ RETiRet;
+}
+
+
+/* end a GnuTLS session
+ * The function checks if we have a session and ends it only if so. So it can
+ * always be called, even if there currently is no session.
+ */
+static rsRetVal
+gtlsEndSess(nsd_gtls_t *pThis)
+{
+ int gnuRet;
+ DEFiRet;
+
+ if(pThis->bHaveSess) {
+ gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_RDWR);
+ while(gnuRet == GNUTLS_E_INTERRUPTED || gnuRet == GNUTLS_E_AGAIN) {
+ gnuRet = gnutls_bye(pThis->sess, GNUTLS_SHUT_RDWR);
+ }
+ gnutls_deinit(pThis->sess);
+ }
+ RETiRet;
+}
+
+
+/* ---------------------------- end GnuTLS specifics ---------------------------- */
+
+
+/* Standard-Constructor */
+BEGINobjConstruct(nsd_gtls) /* be sure to specify the object type also in END macro! */
+ iRet = nsd_ptcp.Construct(&pThis->pTcp);
+ pThis->iMode = 1; /* TODO: must be made configurable */
+ pThis->iMode = 0; /* TODO: must be made configurable */
+ENDobjConstruct(nsd_gtls)
+
+
+/* destructor for the nsd_gtls object */
+BEGINobjDestruct(nsd_gtls) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDestruct(nsd_gtls)
+ if(pThis->iMode == 1) {
+ gtlsEndSess(pThis);
+ }
+
+ if(pThis->pTcp != NULL) {
+ nsd_ptcp.Destruct(&pThis->pTcp);
+ }
+ENDobjDestruct(nsd_gtls)
+
+
+/* Provide access to the underlying OS socket. This is primarily
+ * useful for other drivers (like nsd_gtls) who utilize ourselfs
+ * for some of their functionality. -- rgerhards, 2008-04-18
+ */
+static rsRetVal
+SetSock(nsd_t *pNsd, int sock)
+{
+ DEFiRet;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+
+ ISOBJ_TYPE_assert((pThis), nsd_gtls);
+ assert(sock >= 0);
+
+ nsd_ptcp.SetSock(pThis->pTcp, sock);
+
+ RETiRet;
+}
+
+
+/* abort a connection. This is meant to be called immediately
+ * before the Destruct call. -- rgerhards, 2008-03-24
+ */
+static rsRetVal
+Abort(nsd_t *pNsd)
+{
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert((pThis), nsd_gtls);
+
+ if(pThis->iMode == 0) {
+ nsd_ptcp.Abort(pThis->pTcp);
+ }
+
+ RETiRet;
+}
+
+
+
+/* initialize the tcp socket for a listner
+ * Here, we use the ptcp driver - because there is nothing special
+ * at this point with GnuTLS. Things become special once we accept
+ * a session, but not during listener setup.
+ * gerhards, 2008-04-25
+ */
+static rsRetVal
+LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
+ uchar *pLstnPort, uchar *pLstnIP, int iSessMax)
+{
+ DEFiRet;
+ iRet = nsd_ptcp.LstnInit(pNS, pUsr, fAddLstn, pLstnPort, pLstnIP, iSessMax);
+ RETiRet;
+}
+
+
+/* get the remote hostname. The returned hostname must be freed by the caller.
+ * rgerhards, 2008-04-25
+ */
+static rsRetVal
+GetRemoteHName(nsd_t *pNsd, uchar **ppszHName)
+{
+ DEFiRet;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+ ISOBJ_TYPE_assert(pThis, nsd_gtls);
+ iRet = nsd_ptcp.GetRemoteHName(pThis->pTcp, ppszHName);
+ RETiRet;
+}
+
+
+/* get the remote host's IP address. The returned string must be freed by the
+ * caller.
+ * rgerhards, 2008-04-25
+ */
+static rsRetVal
+GetRemoteIP(nsd_t *pNsd, uchar **ppszIP)
+{
+ DEFiRet;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+ ISOBJ_TYPE_assert(pThis, nsd_gtls);
+ iRet = nsd_ptcp.GetRemoteIP(pThis->pTcp, ppszIP);
+ RETiRet;
+}
+
+
+/* accept an incoming connection request - here, we do the usual accept
+ * handling. TLS specific handling is done thereafter (and if we run in TLS
+ * mode at this time).
+ * rgerhards, 2008-04-25
+ */
+static rsRetVal
+AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew)
+{
+ DEFiRet;
+ nsd_gtls_t *pNew = NULL;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+
+ ISOBJ_TYPE_assert((pThis), nsd_gtls);
+ // TODO: method to construct without pTcp
+ CHKiRet(nsd_gtlsConstruct(&pNew));
+ CHKiRet(nsd_ptcp.Destruct(&pNew->pTcp));
+ CHKiRet(nsd_ptcp.AcceptConnReq(pThis->pTcp, &pNew->pTcp));
+
+ *ppNew = (nsd_t*) pNew;
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pNew != NULL)
+ nsd_gtlsDestruct(&pNew);
+ }
+ RETiRet;
+}
+
+
+/* receive data from a tcp socket
+ * The lenBuf parameter must contain the max buffer size on entry and contains
+ * the number of octets read (or -1 in case of error) on exit. This function
+ * never blocks, not even when called on a blocking socket. That is important
+ * for client sockets, which are set to block during send, but should not
+ * block when trying to read data. If *pLenBuf is -1, an error occured and
+ * errno holds the exact error cause.
+ * rgerhards, 2008-03-17
+ */
+static rsRetVal
+Rcv(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
+{
+ DEFiRet;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+ ISOBJ_TYPE_assert(pThis, nsd_gtls);
+
+ if(pThis->iMode == 0) {
+ CHKiRet(nsd_ptcp.Rcv(pThis->pTcp, pBuf, pLenBuf));
+ FINALIZE;
+ }
+
+ /* in TLS mode now */
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* send a buffer. On entry, pLenBuf contains the number of octets to
+ * write. On exit, it contains the number of octets actually written.
+ * If this number is lower than on entry, only a partial buffer has
+ * been written.
+ * rgerhards, 2008-03-19
+ */
+static rsRetVal
+Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
+{
+ int iSent;
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, nsd_gtls);
+
+ if(pThis->iMode == 0) {
+ CHKiRet(nsd_ptcp.Send(pThis->pTcp, pBuf, pLenBuf));
+ FINALIZE;
+ }
+
+ /* in TLS mode now */
+ while(1) { /* loop broken inside */
+ iSent = gnutls_record_send(pThis->sess, pBuf, *pLenBuf);
+ if(iSent >= 0) {
+ *pLenBuf = iSent;
+ break;
+ }
+ if(iSent != GNUTLS_E_INTERRUPTED && iSent != GNUTLS_E_AGAIN)
+ ABORT_FINALIZE(RS_RET_GNUTLS_ERR);
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* open a connection to a remote host (server). With GnuTLS, we always
+ * open a plain tcp socket and then, if in TLS mode, do a handshake on it.
+ * rgerhards, 2008-03-19
+ */
+static rsRetVal
+Connect(nsd_t *pNsd, int family, uchar *port, uchar *host)
+{
+ nsd_gtls_t *pThis = (nsd_gtls_t*) pNsd;
+ int sock;
+ int gnuRet;
+ static const int cert_type_priority[3] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, nsd_gtls);
+ assert(port != NULL);
+ assert(host != NULL);
+
+ CHKiRet(nsd_ptcp.Connect(pThis->pTcp, family, port, host));
+
+ if(pThis->iMode == 0)
+ FINALIZE;
+
+ /* we reach this point if in TLS mode */
+ CHKgnutls(gnutls_init(&pThis->sess, GNUTLS_CLIENT));
+ pThis->bHaveSess = 1;
+
+ /* Use default priorities */
+ CHKgnutls(gnutls_set_default_priority(pThis->sess));
+ CHKgnutls(gnutls_certificate_type_set_priority(pThis->sess, cert_type_priority));
+
+ /* put the x509 credentials to the current session */
+ CHKgnutls(gnutls_credentials_set(pThis->sess, GNUTLS_CRD_CERTIFICATE, xcred));
+
+ /* assign the socket to GnuTls */
+ CHKiRet(nsd_ptcp.GetSock(pThis->pTcp, &sock));
+ gnutls_transport_set_ptr(pThis->sess, (gnutls_transport_ptr)sock);
+
+ /* and perform the handshake */
+ CHKgnutls(gnutls_handshake(pThis->sess));
+ dbgprintf("GnuTLS handshake succeeded\n");
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pThis->bHaveSess) {
+ gnutls_deinit(pThis->sess);
+ pThis->bHaveSess = 0;
+ }
+ }
+
+ RETiRet;
+}
+
+
+/* queryInterface function */
+BEGINobjQueryInterface(nsd_gtls)
+CODESTARTobjQueryInterface(nsd_gtls)
+ if(pIf->ifVersion != nsdCURR_IF_VERSION) {/* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->Construct = (rsRetVal(*)(nsd_t**)) nsd_gtlsConstruct;
+ pIf->Destruct = (rsRetVal(*)(nsd_t**)) nsd_gtlsDestruct;
+ pIf->Abort = Abort;
+ pIf->LstnInit = LstnInit;
+ pIf->AcceptConnReq = AcceptConnReq;
+ pIf->Rcv = Rcv;
+ pIf->Send = Send;
+ pIf->Connect = Connect;
+ pIf->SetSock = SetSock;
+ pIf->GetRemoteHName = GetRemoteHName;
+ pIf->GetRemoteIP = GetRemoteIP;
+finalize_it:
+ENDobjQueryInterface(nsd_gtls)
+
+
+/* exit our class
+ */
+BEGINObjClassExit(nsd_gtls, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+CODESTARTObjClassExit(nsd_gtls)
+ gtlsGlblExit(); /* shut down GnuTLS */
+
+ /* release objects we no longer need */
+ objRelease(nsd_ptcp, LM_NSD_PTCP_FILENAME);
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(errmsg, CORE_COMPONENT);
+ENDObjClassExit(nsd_gtls)
+
+
+/* Initialize the nsd_gtls class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-19
+ */
+BEGINObjClassInit(nsd_gtls, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */
+ /* request objects we use */
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(nsd_ptcp, LM_NSD_PTCP_FILENAME));
+
+ /* now do global TLS init stuff */
+ CHKiRet(gtlsGlblInit());
+ENDObjClassInit(nsd_gtls)
+
+
+/* --------------- here now comes the plumbing that makes as a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ nsd_gtlsClassExit();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(nsd_gtlsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ENDmodInit
+/* vi:set ai:
+ */
diff --git a/runtime/nsd_gtls.h b/runtime/nsd_gtls.h
new file mode 100644
index 00000000..c193f57c
--- /dev/null
+++ b/runtime/nsd_gtls.h
@@ -0,0 +1,49 @@
+/* An implementation of the nsd interface for GnuTLS.
+ *
+ * Copyright 2008 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.
+ */
+
+#ifndef INCLUDED_NSD_GTLS_H
+#define INCLUDED_NSD_GTLS_H
+
+#include "nsd.h"
+
+typedef nsd_if_t nsd_gtls_if_t; /* we just *implement* this interface */
+
+/* the nsd_gtls object */
+struct nsd_gtls_s {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ nsd_t *pTcp; /**< our aggregated nsd_ptcp data */
+ int iMode; /* 0 - plain tcp, 1 - TLS */
+ gnutls_session sess;
+ int bHaveSess;
+};
+
+/* interface is defined in nsd.h, we just implement it! */
+#define nsd_gtlsCURR_IF_VERSION nsdCURR_IF_VERSION
+
+/* prototypes */
+PROTOTYPEObj(nsd_gtls);
+
+/* the name of our library binary */
+#define LM_NSD_GTLS_FILENAME "lmnsd_gtls"
+
+#endif /* #ifndef INCLUDED_NSD_GTLS_H */
diff --git a/runtime/nsd_ptcp.c b/runtime/nsd_ptcp.c
new file mode 100644
index 00000000..2a74e061
--- /dev/null
+++ b/runtime/nsd_ptcp.c
@@ -0,0 +1,675 @@
+/* nsd_ptcp.c
+ *
+ * An implementation of the nsd interface for plain tcp sockets.
+ *
+ * Copyright 2007, 2008 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.
+ */
+#include "config.h"
+
+#include "rsyslog.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <fnmatch.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "syslogd-types.h"
+#include "module-template.h"
+#include "parse.h"
+#include "srUtils.h"
+#include "obj.h"
+#include "errmsg.h"
+#include "net.h"
+#include "netstrms.h"
+#include "netstrm.h"
+#include "nsd_ptcp.h"
+
+MODULE_TYPE_LIB
+
+/* static data */
+DEFobjStaticHelpers
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(net)
+DEFobjCurrIf(netstrms)
+DEFobjCurrIf(netstrm)
+
+
+/* a few deinit helpers */
+
+/* close socket if open (may always be called) */
+static void
+sockClose(int *pSock)
+{
+ if(*pSock >= 0) {
+ close(*pSock);
+ *pSock = -1;
+ }
+}
+
+/* Standard-Constructor
+ */
+BEGINobjConstruct(nsd_ptcp) /* be sure to specify the object type also in END macro! */
+ pThis->sock = -1;
+ENDobjConstruct(nsd_ptcp)
+
+
+/* destructor for the nsd_ptcp object */
+BEGINobjDestruct(nsd_ptcp) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDestruct(nsd_ptcp)
+ sockClose(&pThis->sock);
+ if(pThis->pRemHostIP != NULL)
+ free(pThis->pRemHostIP);
+ if(pThis->pRemHostName != NULL)
+ free(pThis->pRemHostName);
+ENDobjDestruct(nsd_ptcp)
+
+
+/* Provide access to the underlying OS socket. This is primarily
+ * useful for other drivers (like nsd_gtls) who utilize ourselfs
+ * for some of their functionality. -- rgerhards, 2008-04-18
+ */
+static rsRetVal
+GetSock(nsd_t *pNsd, int *pSock)
+{
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert((pThis), nsd_ptcp);
+ assert(pSock != NULL);
+
+ *pSock = pThis->sock;
+
+ RETiRet;
+}
+
+
+/* Provide access to the underlying OS socket. This is primarily
+ * useful for other drivers (like nsd_gtls) who utilize ourselfs
+ * for some of their functionality.
+ * This function sets the socket -- rgerhards, 2008-04-25
+ */
+static rsRetVal
+SetSock(nsd_t *pNsd, int sock)
+{
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert((pThis), nsd_ptcp);
+ assert(sock >= 0);
+
+ pThis->sock = sock;
+
+ RETiRet;
+}
+
+
+/* abort a connection. This is meant to be called immediately
+ * before the Destruct call. -- rgerhards, 2008-03-24
+ */
+static rsRetVal
+Abort(nsd_t *pNsd)
+{
+ struct linger ling;
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+
+ DEFiRet;
+ ISOBJ_TYPE_assert((pThis), nsd_ptcp);
+
+ if((pThis)->sock != -1) {
+ ling.l_onoff = 1;
+ ling.l_linger = 0;
+ if(setsockopt((pThis)->sock, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)) < 0 ) {
+ dbgprintf("could not set SO_LINGER, errno %d\n", errno);
+ }
+ }
+
+ RETiRet;
+}
+
+
+/* Set pRemHost based on the address provided. This is to be called upon accept()ing
+ * a connection request. It must be provided by the socket we received the
+ * message on as well as a NI_MAXHOST size large character buffer for the FQDN.
+ * Please see http://www.hmug.org/man/3/getnameinfo.php (under Caveats)
+ * for some explanation of the code found below. If we detect a malicious
+ * hostname, we return RS_RET_MALICIOUS_HNAME and let the caller decide
+ * on how to deal with that.
+ * rgerhards, 2008-03-31
+ */
+static rsRetVal
+FillRemHost(nsd_ptcp_t *pThis, struct sockaddr *pAddr)
+{
+ int error;
+ uchar szIP[NI_MAXHOST] = "";
+ uchar szHname[NI_MAXHOST] = "";
+ struct addrinfo hints, *res;
+ size_t len;
+
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, nsd_ptcp);
+ assert(pAddr != NULL);
+
+ error = getnameinfo(pAddr, SALEN(pAddr), (char*)szIP, sizeof(szIP), NULL, 0, NI_NUMERICHOST);
+
+ if(error) {
+ dbgprintf("Malformed from address %s\n", gai_strerror(error));
+ strcpy((char*)szHname, "???");
+ strcpy((char*)szIP, "???");
+ ABORT_FINALIZE(RS_RET_INVALID_HNAME);
+ }
+
+ if(!glbl.GetDisableDNS()) {
+ error = getnameinfo(pAddr, SALEN(pAddr), (char*)szHname, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
+ if(error == 0) {
+ memset (&hints, 0, sizeof (struct addrinfo));
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_socktype = SOCK_STREAM;
+ /* we now do a lookup once again. This one should fail,
+ * because we should not have obtained a non-numeric address. If
+ * we got a numeric one, someone messed with DNS!
+ */
+ if(getaddrinfo((char*)szHname, NULL, &hints, &res) == 0) {
+ freeaddrinfo (res);
+ /* OK, we know we have evil, so let's indicate this to our caller */
+ snprintf((char*)szHname, NI_MAXHOST, "[MALICIOUS:IP=%s]", szIP);
+ dbgprintf("Malicious PTR record, IP = \"%s\" HOST = \"%s\"", szIP, szHname);
+ iRet = RS_RET_MALICIOUS_HNAME;
+ }
+ } else {
+ strcpy((char*)szHname, (char*)szIP);
+ }
+ } else {
+ strcpy((char*)szHname, (char*)szIP);
+ }
+
+ /* We now have the names, so now let's allocate memory and store them permanently.
+ * (side note: we may hold on to these values for quite a while, thus we trim their
+ * memory consumption)
+ */
+ len = strlen((char*)szIP) + 1; /* +1 for \0 byte */
+ if((pThis->pRemHostIP = malloc(len)) == NULL)
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ memcpy(pThis->pRemHostIP, szIP, len);
+
+ len = strlen((char*)szHname) + 1; /* +1 for \0 byte */
+ if((pThis->pRemHostName = malloc(len)) == NULL) {
+ free(pThis->pRemHostIP); /* prevent leak */
+ pThis->pRemHostIP = NULL;
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ }
+ memcpy(pThis->pRemHostName, szHname, len);
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* accept an incoming connection request
+ * rgerhards, 2008-04-22
+ */
+static rsRetVal
+AcceptConnReq(nsd_t *pNsd, nsd_t **ppNew)
+{
+ int sockflags;
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ struct sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ nsd_ptcp_t *pNew = NULL;
+ int iNewSock = -1;
+
+ DEFiRet;
+ assert(ppNew != NULL);
+ ISOBJ_TYPE_assert(pThis, nsd_ptcp);
+
+ iNewSock = accept(pThis->sock, (struct sockaddr*) &addr, &addrlen);
+ if(iNewSock < 0) {
+ ABORT_FINALIZE(RS_RET_ACCEPT_ERR);
+ }
+
+ /* construct our object so that we can use it... */
+ CHKiRet(nsd_ptcpConstruct(&pNew));
+
+ CHKiRet(FillRemHost(pNew, (struct sockaddr*) &addr));
+
+ /* set the new socket to non-blocking IO -TODO:do we really need to do this here? Do we always want it? */
+ if((sockflags = fcntl(iNewSock, F_GETFL)) != -1) {
+ sockflags |= O_NONBLOCK;
+ /* SETFL could fail too, so get it caught by the subsequent
+ * error check.
+ */
+ sockflags = fcntl(iNewSock, F_SETFL, sockflags);
+ }
+ if(sockflags == -1) {
+ dbgprintf("error %d setting fcntl(O_NONBLOCK) on tcp socket %d", errno, iNewSock);
+ ABORT_FINALIZE(RS_RET_IO_ERROR);
+ }
+
+ pNew->sock = iNewSock;
+ *ppNew = (nsd_t*) pNew;
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pNew != NULL)
+ nsd_ptcpDestruct(&pNew);
+ /* the close may be redundant, but that doesn't hurt... */
+ sockClose(&iNewSock);
+ }
+
+ RETiRet;
+}
+
+
+/* initialize tcp sockets for a listner. The initialized sockets are passed to the
+ * app-level caller via a callback.
+ * pLstnPort must point to a port name or number. NULL is NOT permitted. pLstnIP
+ * points to the port to listen to (NULL means "all"), iMaxSess has the maximum
+ * number of sessions permitted.
+ * rgerhards, 2008-04-22
+ */
+static rsRetVal
+LstnInit(netstrms_t *pNS, void *pUsr, rsRetVal(*fAddLstn)(void*,netstrm_t*),
+ uchar *pLstnPort, uchar *pLstnIP, int iSessMax)
+{
+ DEFiRet;
+ netstrm_t *pNewStrm = NULL;
+ nsd_t *pNewNsd = NULL;
+ int error, maxs, on = 1;
+ int sock;
+ int numSocks;
+ int sockflags;
+ struct addrinfo hints, *res = NULL, *r;
+
+ ISOBJ_TYPE_assert(pNS, netstrms);
+ assert(fAddLstn != NULL);
+ assert(pLstnPort != NULL);
+ assert(iSessMax >= 0);
+
+ dbgprintf("creating tcp listen socket on port %s\n", pLstnPort);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = glbl.GetDefPFFamily();
+ hints.ai_socktype = SOCK_STREAM;
+
+ error = getaddrinfo((char*)pLstnIP, (char*) pLstnPort, &hints, &res);
+ if(error) {
+ dbgprintf("error %d querying port '%s'\n", error, pLstnPort);
+ ABORT_FINALIZE(RS_RET_INVALID_PORT);
+ }
+
+ /* Count max number of sockets we may open */
+ for(maxs = 0, r = res; r != NULL ; r = r->ai_next, maxs++)
+ /* EMPTY */;
+
+ numSocks = 0; /* num of sockets counter at start of array */
+ for(r = res; r != NULL ; r = r->ai_next) {
+ sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+ if(sock < 0) {
+ if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT))
+ dbgprintf("error %d creating tcp listen socket", errno);
+ /* it is debatable if PF_INET with EAFNOSUPPORT should
+ * also be ignored...
+ */
+ continue;
+ }
+
+#ifdef IPV6_V6ONLY
+ if(r->ai_family == AF_INET6) {
+ int iOn = 1;
+ if(setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY,
+ (char *)&iOn, sizeof (iOn)) < 0) {
+ close(sock);
+ continue;
+ }
+ }
+#endif
+ if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0 ) {
+ dbgprintf("error %d setting tcp socket option\n", errno);
+ close(sock);
+ continue;
+ }
+
+ /* We use non-blocking IO! */
+ if((sockflags = fcntl(sock, F_GETFL)) != -1) {
+ sockflags |= O_NONBLOCK;
+ /* SETFL could fail too, so get it caught by the subsequent
+ * error check.
+ */
+ sockflags = fcntl(sock, F_SETFL, sockflags);
+ }
+ if(sockflags == -1) {
+ dbgprintf("error %d setting fcntl(O_NONBLOCK) on tcp socket", errno);
+ close(sock);
+ continue;
+ }
+
+
+
+ /* We need to enable BSD compatibility. Otherwise an attacker
+ * could flood our log files by sending us tons of ICMP errors.
+ */
+#ifndef BSD
+ if(net.should_use_so_bsdcompat()) {
+ if (setsockopt(sock, SOL_SOCKET, SO_BSDCOMPAT,
+ (char *) &on, sizeof(on)) < 0) {
+ errmsg.LogError(NO_ERRCODE, "TCP setsockopt(BSDCOMPAT)");
+ close(sock);
+ continue;
+ }
+ }
+#endif
+
+ if( (bind(sock, r->ai_addr, r->ai_addrlen) < 0)
+#ifndef IPV6_V6ONLY
+ && (errno != EADDRINUSE)
+#endif
+ ) {
+ /* TODO: check if *we* bound the socket - else we *have* an error! */
+ dbgprintf("error %d while binding tcp socket", errno);
+ close(sock);
+ continue;
+ }
+
+ if(listen(sock, iSessMax / 10 + 5) < 0) {
+ /* If the listen fails, it most probably fails because we ask
+ * for a too-large backlog. So in this case we first set back
+ * to a fixed, reasonable, limit that should work. Only if
+ * that fails, too, we give up.
+ */
+ dbgprintf("listen with a backlog of %d failed - retrying with default of 32.",
+ iSessMax / 10 + 5);
+ if(listen(sock, 32) < 0) {
+ dbgprintf("tcp listen error %d, suspending\n", errno);
+ close(sock);
+ continue;
+ }
+ }
+
+ /* if we reach this point, we were able to obtain a valid socket, so we can
+ * construct a new netstrm obj and hand it over to the upper layers for inclusion
+ * into their socket array. -- rgerhards, 2008-04-23
+ */
+RUNLOG_VAR("%d", sock);
+ CHKiRet(pNS->Drvr.Construct(&pNewNsd));
+ CHKiRet(pNS->Drvr.SetSock(pNewNsd, sock));
+RUNLOG;
+ CHKiRet(netstrms.CreateStrm(pNS, &pNewStrm));
+ pNewStrm->pDrvrData = (nsd_t*) pNewNsd;
+RUNLOG;
+ CHKiRet(fAddLstn(pUsr, pNewStrm));
+ pNewNsd = NULL;
+ pNewStrm = NULL;
+ ++numSocks;
+ }
+
+ if(numSocks != maxs)
+ dbgprintf("We could initialize %d TCP listen sockets out of %d we received "
+ "- this may or may not be an error indication.\n", numSocks, maxs);
+
+ if(numSocks == 0) {
+ dbgprintf("No TCP listen sockets could successfully be initialized");
+ ABORT_FINALIZE(RS_RET_COULD_NOT_BIND);
+ }
+
+finalize_it:
+ if(res != NULL)
+ freeaddrinfo(res);
+
+ if(iRet != RS_RET_OK) {
+ if(pNewStrm != NULL)
+ netstrm.Destruct(&pNewStrm);
+ if(pNewNsd != NULL)
+ pNS->Drvr.Destruct(&pNewNsd);
+ }
+
+ RETiRet;
+}
+
+
+/* receive data from a tcp socket
+ * The lenBuf parameter must contain the max buffer size on entry and contains
+ * the number of octets read (or -1 in case of error) on exit. This function
+ * never blocks, not even when called on a blocking socket. That is important
+ * for client sockets, which are set to block during send, but should not
+ * block when trying to read data. If *pLenBuf is -1, an error occured and
+ * errno holds the exact error cause.
+ * rgerhards, 2008-03-17
+ */
+static rsRetVal
+Rcv(nsd_t *pNsd, uchar *pRcvBuf, ssize_t *pLenBuf)
+{
+ DEFiRet;
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ ISOBJ_TYPE_assert(pThis, nsd_ptcp);
+
+ *pLenBuf = recv(pThis->sock, pRcvBuf, *pLenBuf, MSG_DONTWAIT);
+
+ RETiRet;
+}
+
+
+/* send a buffer. On entry, pLenBuf contains the number of octets to
+ * write. On exit, it contains the number of octets actually written.
+ * If this number is lower than on entry, only a partial buffer has
+ * been written.
+ * rgerhards, 2008-03-19
+ */
+static rsRetVal
+Send(nsd_t *pNsd, uchar *pBuf, ssize_t *pLenBuf)
+{
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ ssize_t written;
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, nsd_ptcp);
+
+ written = send(pThis->sock, pBuf, *pLenBuf, 0);
+
+ if(written == -1) {
+ switch(errno) {
+ case EAGAIN:
+ case EINTR:
+ /* this is fine, just retry... */
+ written = 0;
+ break;
+ default:
+ ABORT_FINALIZE(RS_RET_IO_ERROR);
+ break;
+ }
+ }
+
+ *pLenBuf = written;
+finalize_it:
+ RETiRet;
+}
+
+
+/* open a connection to a remote host (server).
+ * rgerhards, 2008-03-19
+ */
+static rsRetVal
+Connect(nsd_t *pNsd, int family, uchar *port, uchar *host)
+{
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ struct addrinfo *res = NULL;
+ struct addrinfo hints;
+
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, nsd_ptcp);
+ assert(port != NULL);
+ assert(host != NULL);
+ assert(pThis->sock == -1);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+ if(getaddrinfo((char*)host, (char*)port, &hints, &res) != 0) {
+ dbgprintf("error %d in getaddrinfo\n", errno);
+ ABORT_FINALIZE(RS_RET_IO_ERROR);
+ }
+
+ if((pThis->sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
+ ABORT_FINALIZE(RS_RET_IO_ERROR);
+ }
+
+ if(connect(pThis->sock, res->ai_addr, res->ai_addrlen) != 0) {
+ ABORT_FINALIZE(RS_RET_IO_ERROR);
+ }
+
+finalize_it:
+ if(res != NULL)
+ freeaddrinfo(res);
+
+ if(iRet != RS_RET_OK) {
+ sockClose(&pThis->sock);
+ }
+
+ RETiRet;
+}
+
+
+/* get the remote hostname. The returned hostname must be freed by the
+ * caller.
+ * rgerhards, 2008-04-24
+ */
+static rsRetVal
+GetRemoteHName(nsd_t *pNsd, uchar **ppszHName)
+{
+ DEFiRet;
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ ISOBJ_TYPE_assert(pThis, nsd_ptcp);
+ assert(ppszHName != NULL);
+
+ // TODO: how can the RemHost be empty?
+ CHKmalloc(*ppszHName = (uchar*)strdup(pThis->pRemHostName == NULL ? "" : (char*) pThis->pRemHostName));
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* get the remote host's IP address. The returned string must be freed by the
+ * caller.
+ * rgerhards, 2008-04-24
+ */
+static rsRetVal
+GetRemoteIP(nsd_t *pNsd, uchar **ppszIP)
+{
+ DEFiRet;
+ nsd_ptcp_t *pThis = (nsd_ptcp_t*) pNsd;
+ ISOBJ_TYPE_assert(pThis, nsd_ptcp);
+ assert(ppszIP != NULL);
+
+ CHKmalloc(*ppszIP = (uchar*)strdup(pThis->pRemHostIP == NULL ? "" : (char*) pThis->pRemHostIP));
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* queryInterface function */
+BEGINobjQueryInterface(nsd_ptcp)
+CODESTARTobjQueryInterface(nsd_ptcp)
+ if(pIf->ifVersion != nsdCURR_IF_VERSION) {/* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->Construct = (rsRetVal(*)(nsd_t**)) nsd_ptcpConstruct;
+ pIf->Destruct = (rsRetVal(*)(nsd_t**)) nsd_ptcpDestruct;
+ pIf->Abort = Abort;
+ pIf->GetSock = GetSock;
+ pIf->SetSock = SetSock;
+ pIf->Rcv = Rcv;
+ pIf->Send = Send;
+ pIf->LstnInit = LstnInit;
+ pIf->AcceptConnReq = AcceptConnReq;
+ pIf->Connect = Connect;
+ pIf->GetRemoteHName = GetRemoteHName;
+ pIf->GetRemoteIP = GetRemoteIP;
+finalize_it:
+ENDobjQueryInterface(nsd_ptcp)
+
+
+/* exit our class
+ */
+BEGINObjClassExit(nsd_ptcp, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+CODESTARTObjClassExit(nsd_ptcp)
+ /* release objects we no longer need */
+ objRelease(net, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(errmsg, CORE_COMPONENT);
+ objRelease(netstrm, LM_NETSTRM_FILENAME);
+ objRelease(netstrms, LM_NETSTRMS_FILENAME);
+ENDObjClassExit(nsd_ptcp)
+
+
+/* Initialize the nsd_ptcp class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-19
+ */
+BEGINObjClassInit(nsd_ptcp, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */
+ /* request objects we use */
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(net, CORE_COMPONENT));
+ CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
+ CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
+
+ /* set our own handlers */
+ENDObjClassInit(nsd_ptcp)
+
+
+/* --------------- here now comes the plumbing that makes as a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ nsd_ptcpClassExit();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(nsd_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ENDmodInit
+/* vi:set ai:
+ */
diff --git a/runtime/nsd_ptcp.h b/runtime/nsd_ptcp.h
new file mode 100644
index 00000000..efd3ed05
--- /dev/null
+++ b/runtime/nsd_ptcp.h
@@ -0,0 +1,47 @@
+/* An implementation of the nsd interface for plain tcp sockets.
+ *
+ * Copyright 2007, 2008 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.
+ */
+
+#ifndef INCLUDED_NSD_PTCP_H
+#define INCLUDED_NSD_PTCP_H
+
+#include "nsd.h"
+typedef nsd_if_t nsd_ptcp_if_t; /* we just *implement* this interface */
+
+/* the nsd_ptcp object */
+struct nsd_ptcp_s {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ uchar *pRemHostIP; /**< IP address of remote peer (currently used in server mode, only) */
+ uchar *pRemHostName; /**< host name of remote peer (currently used in server mode, only) */
+ int sock; /**< the socket we use for regular, single-socket, operations */
+};
+
+/* interface is defined in nsd.h, we just implement it! */
+#define nsd_ptcpCURR_IF_VERSION nsdCURR_IF_VERSION
+
+/* prototypes */
+PROTOTYPEObj(nsd_ptcp);
+
+/* the name of our library binary */
+#define LM_NSD_PTCP_FILENAME "lmnsd_ptcp"
+
+#endif /* #ifndef INCLUDED_NSD_PTCP_H */
diff --git a/runtime/nsdsel_gtls.c b/runtime/nsdsel_gtls.c
new file mode 100644
index 00000000..7cafec49
--- /dev/null
+++ b/runtime/nsdsel_gtls.c
@@ -0,0 +1,184 @@
+/* nsdsel_gtls.c
+ *
+ * An implementation of the nsd select() interface for GnuTLS.
+ *
+ * Copyright (C) 2008 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.
+ */
+#include "config.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/select.h>
+#include <gnutls/gnutls.h>
+
+#include "rsyslog.h"
+#include "module-template.h"
+#include "obj.h"
+#include "errmsg.h"
+#include "nsd.h"
+#include "nsd_gtls.h"
+#include "nsdsel_ptcp.h"
+#include "nsdsel_gtls.h"
+
+MODULE_TYPE_LIB
+
+/* static data */
+DEFobjStaticHelpers
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(nsdsel_ptcp)
+
+
+/* Standard-Constructor
+ */
+BEGINobjConstruct(nsdsel_gtls) /* be sure to specify the object type also in END macro! */
+ iRet = nsdsel_ptcp.Construct(&pThis->pTcp);
+ENDobjConstruct(nsdsel_gtls)
+
+
+/* destructor for the nsdsel_gtls object */
+BEGINobjDestruct(nsdsel_gtls) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDestruct(nsdsel_gtls)
+ if(pThis->pTcp != NULL)
+ nsdsel_ptcp.Destruct(&pThis->pTcp);
+ENDobjDestruct(nsdsel_gtls)
+
+
+/* Add a socket to the select set */
+static rsRetVal
+Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp)
+{
+ DEFiRet;
+ nsdsel_gtls_t *pThis = (nsdsel_gtls_t*) pNsdsel;
+ nsd_gtls_t *pNsdGTLS = (nsd_gtls_t*) pNsd;
+
+ ISOBJ_TYPE_assert(pThis, nsdsel_gtls);
+ ISOBJ_TYPE_assert(pNsdGTLS, nsd_gtls);
+ iRet = nsdsel_ptcp.Add(pThis->pTcp, pNsdGTLS->pTcp, waitOp);
+ RETiRet;
+}
+
+
+/* perform the select() piNumReady returns how many descriptors are ready for IO
+ * TODO: add timeout!
+ */
+static rsRetVal
+Select(nsdsel_t *pNsdsel, int *piNumReady)
+{
+ DEFiRet;
+ nsdsel_gtls_t *pThis = (nsdsel_gtls_t*) pNsdsel;
+
+ ISOBJ_TYPE_assert(pThis, nsdsel_gtls);
+ iRet = nsdsel_ptcp.Select(pThis->pTcp, piNumReady);
+ RETiRet;
+}
+
+
+/* check if a socket is ready for IO */
+static rsRetVal
+IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
+{
+ DEFiRet;
+ nsdsel_gtls_t *pThis = (nsdsel_gtls_t*) pNsdsel;
+ nsd_gtls_t *pNsdGTLS = (nsd_gtls_t*) pNsd;
+
+ ISOBJ_TYPE_assert(pThis, nsdsel_gtls);
+ ISOBJ_TYPE_assert(pNsdGTLS, nsd_gtls);
+ iRet = nsdsel_ptcp.IsReady(pThis->pTcp, pNsdGTLS->pTcp, waitOp, pbIsReady);
+ RETiRet;
+}
+
+
+/* ------------------------------ end support for the select() interface ------------------------------ */
+
+
+/* queryInterface function */
+BEGINobjQueryInterface(nsdsel_gtls)
+CODESTARTobjQueryInterface(nsdsel_gtls)
+ if(pIf->ifVersion != nsdCURR_IF_VERSION) {/* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->Construct = (rsRetVal(*)(nsdsel_t**)) nsdsel_gtlsConstruct;
+ pIf->Destruct = (rsRetVal(*)(nsdsel_t**)) nsdsel_gtlsDestruct;
+ pIf->Add = Add;
+ pIf->Select = Select;
+ pIf->IsReady = IsReady;
+finalize_it:
+ENDobjQueryInterface(nsdsel_gtls)
+
+
+/* exit our class
+ */
+BEGINObjClassExit(nsdsel_gtls, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+CODESTARTObjClassExit(nsdsel_gtls)
+ /* release objects we no longer need */
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(errmsg, CORE_COMPONENT);
+ objRelease(nsdsel_ptcp, LM_NSDSEL_PTCP_FILENAME);
+ENDObjClassExit(nsdsel_gtls)
+
+
+/* Initialize the nsdsel_gtls class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-19
+ */
+BEGINObjClassInit(nsdsel_gtls, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */
+ /* request objects we use */
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(nsdsel_ptcp, LM_NSDSEL_PTCP_FILENAME));
+
+ /* set our own handlers */
+ENDObjClassInit(nsdsel_gtls)
+
+
+/* --------------- here now comes the plumbing that makes as a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ nsdsel_gtlsClassExit();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(nsdsel_gtlsClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ENDmodInit
+/* vi:set ai:
+ */
diff --git a/runtime/nsdsel_gtls.h b/runtime/nsdsel_gtls.h
new file mode 100644
index 00000000..a309d302
--- /dev/null
+++ b/runtime/nsdsel_gtls.h
@@ -0,0 +1,45 @@
+/* An implementation of the nsd select interface for GnuTLS.
+ *
+ * Copyright (C) 2008 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.
+ */
+
+#ifndef INCLUDED_NSDSEL_GTLS_H
+#define INCLUDED_NSDSEL_GTLS_H
+
+#include "nsd.h"
+typedef nsdsel_if_t nsdsel_gtls_if_t; /* we just *implement* this interface */
+
+/* the nsdsel_gtls object */
+struct nsdsel_gtls_s {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ nsdsel_t *pTcp; /* our aggregated ptcp sel handler (which does almost everything) */
+};
+
+/* interface is defined in nsd.h, we just implement it! */
+#define nsdsel_gtlsCURR_IF_VERSION nsdCURR_IF_VERSION
+
+/* prototypes */
+PROTOTYPEObj(nsdsel_gtls);
+
+/* the name of our library binary */
+#define LM_NSDSEL_GTLS_FILENAME "lmnsdsel_gtls"
+
+#endif /* #ifndef INCLUDED_NSDSEL_GTLS_H */
diff --git a/runtime/nsdsel_ptcp.c b/runtime/nsdsel_ptcp.c
new file mode 100644
index 00000000..b439063a
--- /dev/null
+++ b/runtime/nsdsel_ptcp.c
@@ -0,0 +1,222 @@
+/* nsdsel_ptcp.c
+ *
+ * An implementation of the nsd select() interface for plain tcp sockets.
+ *
+ * Copyright 2008 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.
+ */
+#include "config.h"
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/select.h>
+
+#include "rsyslog.h"
+#include "module-template.h"
+#include "obj.h"
+#include "errmsg.h"
+#include "nsd_ptcp.h"
+#include "nsdsel_ptcp.h"
+
+MODULE_TYPE_LIB
+
+/* static data */
+DEFobjStaticHelpers
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
+
+
+/* Standard-Constructor
+ */
+BEGINobjConstruct(nsdsel_ptcp) /* be sure to specify the object type also in END macro! */
+ pThis->maxfds = 0;
+ FD_ZERO(&pThis->readfds);
+ FD_ZERO(&pThis->writefds);
+ENDobjConstruct(nsdsel_ptcp)
+
+
+/* destructor for the nsdsel_ptcp object */
+BEGINobjDestruct(nsdsel_ptcp) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDestruct(nsdsel_ptcp)
+ENDobjDestruct(nsdsel_ptcp)
+
+
+/* Add a socket to the select set */
+static rsRetVal
+Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp)
+{
+ DEFiRet;
+ nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
+ nsd_ptcp_t *pSock = (nsd_ptcp_t*) pNsd;
+
+ ISOBJ_TYPE_assert(pSock, nsd_ptcp);
+ ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
+
+ switch(waitOp) {
+ case NSDSEL_RD:
+ FD_SET(pSock->sock, &pThis->readfds);
+ break;
+ case NSDSEL_WR:
+ FD_SET(pSock->sock, &pThis->writefds);
+ break;
+ case NSDSEL_RDWR:
+ FD_SET(pSock->sock, &pThis->readfds);
+ FD_SET(pSock->sock, &pThis->writefds);
+ break;
+ }
+
+ if(pSock->sock > pThis->maxfds)
+ pThis->maxfds = pSock->sock;
+
+ RETiRet;
+}
+
+
+/* perform the select() piNumReady returns how many descriptors are ready for IO
+ * TODO: add timeout!
+ */
+static rsRetVal
+Select(nsdsel_t *pNsdsel, int *piNumReady)
+{
+ DEFiRet;
+ int i;
+ nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
+
+ ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
+ assert(piNumReady != NULL);
+
+ if(Debug) { // TODO: debug setting!
+ // TODO: name in dbgprintf!
+ dbgprintf("--------<NSDSEL_PTCP> calling select, active fds (max %d): ", pThis->maxfds);
+ for(i = 0; i <= pThis->maxfds; ++i)
+ if(FD_ISSET(i, &pThis->readfds) || FD_ISSET(i, &pThis->writefds))
+ dbgprintf("%d ", i);
+ dbgprintf("\n");
+ }
+
+ /* now do the select */
+ *piNumReady = select(pThis->maxfds+1, &pThis->readfds, &pThis->writefds, NULL, NULL);
+
+ RETiRet;
+}
+
+
+/* check if a socket is ready for IO */
+static rsRetVal
+IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady)
+{
+ DEFiRet;
+ nsdsel_ptcp_t *pThis = (nsdsel_ptcp_t*) pNsdsel;
+ nsd_ptcp_t *pSock = (nsd_ptcp_t*) pNsd;
+
+ ISOBJ_TYPE_assert(pThis, nsdsel_ptcp);
+ ISOBJ_TYPE_assert(pSock, nsd_ptcp);
+ assert(pbIsReady != NULL);
+
+ switch(waitOp) {
+ case NSDSEL_RD:
+ *pbIsReady = FD_ISSET(pSock->sock, &pThis->readfds);
+ break;
+ case NSDSEL_WR:
+ *pbIsReady = FD_ISSET(pSock->sock, &pThis->writefds);
+ break;
+ case NSDSEL_RDWR:
+ *pbIsReady = FD_ISSET(pSock->sock, &pThis->readfds)
+ | FD_ISSET(pSock->sock, &pThis->writefds);
+ break;
+ }
+
+ RETiRet;
+}
+
+
+/* ------------------------------ end support for the select() interface ------------------------------ */
+
+
+/* queryInterface function */
+BEGINobjQueryInterface(nsdsel_ptcp)
+CODESTARTobjQueryInterface(nsdsel_ptcp)
+ if(pIf->ifVersion != nsdCURR_IF_VERSION) {/* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->Construct = (rsRetVal(*)(nsdsel_t**)) nsdsel_ptcpConstruct;
+ pIf->Destruct = (rsRetVal(*)(nsdsel_t**)) nsdsel_ptcpDestruct;
+ pIf->Add = Add;
+ pIf->Select = Select;
+ pIf->IsReady = IsReady;
+finalize_it:
+ENDobjQueryInterface(nsdsel_ptcp)
+
+
+/* exit our class
+ */
+BEGINObjClassExit(nsdsel_ptcp, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+CODESTARTObjClassExit(nsdsel_ptcp)
+ /* release objects we no longer need */
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(errmsg, CORE_COMPONENT);
+ENDObjClassExit(nsdsel_ptcp)
+
+
+/* Initialize the nsdsel_ptcp class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-19
+ */
+BEGINObjClassInit(nsdsel_ptcp, 1, OBJ_IS_LOADABLE_MODULE) /* class, version */
+ /* request objects we use */
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+
+ /* set our own handlers */
+ENDObjClassInit(nsdsel_ptcp)
+
+
+/* --------------- here now comes the plumbing that makes as a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ nsdsel_ptcpClassExit();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(nsdsel_ptcpClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ENDmodInit
+/* vi:set ai:
+ */
diff --git a/runtime/nsdsel_ptcp.h b/runtime/nsdsel_ptcp.h
new file mode 100644
index 00000000..93874e55
--- /dev/null
+++ b/runtime/nsdsel_ptcp.h
@@ -0,0 +1,47 @@
+/* An implementation of the nsd select interface for plain tcp sockets.
+ *
+ * Copyright 2008 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.
+ */
+
+#ifndef INCLUDED_NSDSEL_PTCP_H
+#define INCLUDED_NSDSEL_PTCP_H
+
+#include "nsd.h"
+typedef nsdsel_if_t nsdsel_ptcp_if_t; /* we just *implement* this interface */
+
+/* the nsdsel_ptcp object */
+struct nsdsel_ptcp_s {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ int maxfds;
+ fd_set readfds;
+ fd_set writefds;
+};
+
+/* interface is defined in nsd.h, we just implement it! */
+#define nsdsel_ptcpCURR_IF_VERSION nsdCURR_IF_VERSION
+
+/* prototypes */
+PROTOTYPEObj(nsdsel_ptcp);
+
+/* the name of our library binary */
+#define LM_NSDSEL_PTCP_FILENAME "lmnsdsel_ptcp"
+
+#endif /* #ifndef INCLUDED_NSDSEL_PTCP_H */
diff --git a/runtime/nssel.c b/runtime/nssel.c
new file mode 100644
index 00000000..5333fc75
--- /dev/null
+++ b/runtime/nssel.c
@@ -0,0 +1,229 @@
+/* nssel.c
+ *
+ * The io waiter is a helper object enabling us to wait on a set of streams to become
+ * ready for IO - this is modelled after select(). We need this, because
+ * stream drivers may have different concepts. Consequently,
+ * the structure must contain nsd_t's from the same stream driver type
+ * only. This is implemented as a singly-linked list where every
+ * new element is added at the top of the list.
+ *
+ * Work on this module begun 2008-04-22 by Rainer Gerhards.
+ *
+ * Copyright 2008 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.
+ */
+#include "config.h"
+
+#include "rsyslog.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include "rsyslog.h"
+#include "obj.h"
+#include "module-template.h"
+#include "netstrm.h"
+#include "nssel.h"
+
+MODULE_TYPE_LIB
+
+/* static data */
+DEFobjStaticHelpers
+DEFobjCurrIf(glbl)
+
+
+/* load our low-level driver. This must be done before any
+ * driver-specific functions (allmost all...) can be carried
+ * out. Note that the driver's .ifIsLoaded is correctly
+ * initialized by calloc() and we depend on that.
+ * rgerhards, 2008-04-18
+ */
+static rsRetVal
+loadDrvr(nssel_t *pThis)
+{
+ uchar *pDrvrName;
+ DEFiRet;
+
+ pDrvrName = pThis->pDrvrName;
+ if(pDrvrName == NULL) /* if no drvr name is set, use system default */
+ pDrvrName = glbl.GetDfltNetstrmDrvr();
+
+ pThis->Drvr.ifVersion = nsdCURR_IF_VERSION;
+ /* The pDrvrName+2 below is a hack to obtain the object name. It
+ * safes us to have yet another variable with the name without "lm" in
+ * front of it. If we change the module load interface, we may re-think
+ * about this hack, but for the time being it is efficient and clean
+ * enough. -- rgerhards, 2008-04-18
+ */
+ //CHKiRet(obj.UseObj(__FILE__, pDrvrName+2, pDrvrName, (void*) &pThis->Drvr));
+ CHKiRet(obj.UseObj(__FILE__, "nsdsel_gtls", "lmnsdsel_gtls", (void*) &pThis->Drvr));
+finalize_it:
+ RETiRet;
+}
+
+
+/* Standard-Constructor */
+BEGINobjConstruct(nssel) /* be sure to specify the object type also in END macro! */
+ENDobjConstruct(nssel)
+
+
+/* destructor for the nssel object */
+BEGINobjDestruct(nssel) /* be sure to specify the object type also in END and CODESTART macros! */
+CODESTARTobjDestruct(nssel)
+ if(pThis->pDrvrData != NULL)
+ pThis->Drvr.Destruct(&pThis->pDrvrData);
+ENDobjDestruct(nssel)
+
+
+/* ConstructionFinalizer */
+static rsRetVal
+ConstructFinalize(nssel_t *pThis)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, nssel);
+ CHKiRet(loadDrvr(pThis));
+ CHKiRet(pThis->Drvr.Construct(&pThis->pDrvrData));
+finalize_it:
+ RETiRet;
+}
+
+
+/* Add a stream object to the current select() set.
+ * Note that a single stream may have multiple "sockets" if
+ * it is a listener. If so, all of them are begin added.
+ */
+static rsRetVal
+Add(nssel_t *pThis, netstrm_t *pStrm, nsdsel_waitOp_t waitOp)
+{
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, nssel);
+ ISOBJ_TYPE_assert(pStrm, netstrm);
+
+ CHKiRet(pThis->Drvr.Add(pThis->pDrvrData, pStrm->pDrvrData, waitOp));
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* wait for IO to happen on one of our netstreams. iNumReady has
+ * the number of ready "sockets" after the call. This function blocks
+ * until some are ready. EAGAIN is retried.
+ */
+static rsRetVal
+Wait(nssel_t *pThis, int *piNumReady)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, nssel);
+ assert(piNumReady != NULL);
+ iRet = pThis->Drvr.Select(pThis->pDrvrData, piNumReady);
+ RETiRet;
+}
+
+
+/* Check if a stream is ready for IO. *piNumReady contains the remaining number
+ * of ready streams. Note that this function may say the stream is not ready
+ * but still decrement *piNumReady. This can happen when (e.g. with TLS) the low
+ * level driver requires some IO which is hidden from the upper layer point of view.
+ * rgerhards, 2008-04-23
+ */
+static rsRetVal
+IsReady(nssel_t *pThis, netstrm_t *pStrm, nsdsel_waitOp_t waitOp, int *pbIsReady, int *piNumReady)
+{
+ DEFiRet;
+ ISOBJ_TYPE_assert(pThis, nssel);
+ ISOBJ_TYPE_assert(pStrm, netstrm);
+ assert(pbIsReady != NULL);
+ assert(piNumReady != NULL);
+ iRet = pThis->Drvr.IsReady(pThis->pDrvrData, pStrm->pDrvrData, waitOp, pbIsReady);
+ RETiRet;
+}
+
+
+/* queryInterface function */
+BEGINobjQueryInterface(nssel)
+CODESTARTobjQueryInterface(nssel)
+ if(pIf->ifVersion != nsselCURR_IF_VERSION) {/* check for current version, increment on each change */
+ ABORT_FINALIZE(RS_RET_INTERFACE_NOT_SUPPORTED);
+ }
+
+ /* ok, we have the right interface, so let's fill it
+ * Please note that we may also do some backwards-compatibility
+ * work here (if we can support an older interface version - that,
+ * of course, also affects the "if" above).
+ */
+ pIf->Construct = nsselConstruct;
+ pIf->ConstructFinalize = ConstructFinalize;
+ pIf->Destruct = nsselDestruct;
+ pIf->Add = Add;
+ pIf->Wait = Wait;
+ pIf->IsReady = IsReady;
+finalize_it:
+ENDobjQueryInterface(nssel)
+
+
+/* exit our class
+ */
+BEGINObjClassExit(nssel, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END MACRO! */
+CODESTARTObjClassExit(nssel)
+ /* release objects we no longer need */
+ objRelease(glbl, CORE_COMPONENT);
+ENDObjClassExit(nssel)
+
+
+/* Initialize the nssel class. Must be called as the very first method
+ * before anything else is called inside this class.
+ * rgerhards, 2008-02-19
+ */
+BEGINObjClassInit(nssel, 1, OBJ_IS_CORE_MODULE) /* class, version */
+ /* request objects we use */
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+
+ /* set our own handlers */
+ENDObjClassInit(nssel)
+
+
+/* --------------- here now comes the plumbing that makes us a library module --------------- */
+
+
+BEGINmodExit
+CODESTARTmodExit
+ nsselClassExit();
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_LIB_QUERIES
+ENDqueryEtryPt
+
+
+BEGINmodInit()
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+
+ /* Initialize all classes that are in our module - this includes ourselfs */
+ CHKiRet(nsselClassInit(pModInfo)); /* must be done after tcps_sess, as we use it */
+ENDmodInit
+/* vi:set ai:
+ */
diff --git a/runtime/nssel.h b/runtime/nssel.h
new file mode 100644
index 00000000..2f907caa
--- /dev/null
+++ b/runtime/nssel.h
@@ -0,0 +1,55 @@
+/* Definitions for the nssel IO waiter.
+ *
+ * Copyright 2008 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.
+ */
+
+#ifndef INCLUDED_NSSEL_H
+#define INCLUDED_NSSEL_H
+
+#include "nsd.h"
+
+/* the nssel object */
+struct nssel_s {
+ BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
+ nsd_t *pDrvrData; /**< the driver's data elements */
+ uchar *pDrvrName; /**< nsd driver name to use, or NULL if system default */
+ nsdsel_if_t Drvr; /**< our stream driver */
+};
+
+
+/* interface */
+BEGINinterface(nssel) /* name must also be changed in ENDinterface macro! */
+ rsRetVal (*Construct)(nssel_t **ppThis);
+ rsRetVal (*ConstructFinalize)(nssel_t *pThis);
+ rsRetVal (*Destruct)(nssel_t **ppThis);
+ rsRetVal (*Add)(nssel_t *pThis, netstrm_t *pStrm, nsdsel_waitOp_t waitOp);
+ rsRetVal (*Wait)(nssel_t *pThis, int *pNumReady);
+ rsRetVal (*IsReady)(nssel_t *pThis, netstrm_t *pStrm, nsdsel_waitOp_t waitOp, int *pbIsReady, int *piNumReady);
+ENDinterface(nssel)
+#define nsselCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+
+/* prototypes */
+PROTOTYPEObj(nssel);
+
+/* the name of our library binary */
+#define LM_NSSEL_FILENAME "lmnssel"
+
+#endif /* #ifndef INCLUDED_NSSEL_H */
diff --git a/obj-types.h b/runtime/obj-types.h
index 4cd45153..5f531eb1 100644
--- a/obj-types.h
+++ b/runtime/obj-types.h
@@ -7,22 +7,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef OBJ_TYPES_H_INCLUDED
@@ -63,13 +64,13 @@ typedef enum { /* IDs of base methods supported by all objects - used for jump t
/* the base data type for interfaces
* This MUST be in sync with the ifBEGIN macro
*/
-typedef struct interface_s {
+struct interface_s {
int ifVersion; /* must be set to version requested */
int ifIsLoaded; /* is the interface loaded? (0-no, 1-yes, 2-load failed; if not 1, functions can NOT be called! */
-} interface_t;
+};
-typedef struct objInfo_s {
+struct objInfo_s {
uchar *pszID; /* the object ID as a string */
size_t lenID; /* length of the ID string */
int iObjVers;
@@ -77,16 +78,16 @@ typedef struct objInfo_s {
rsRetVal (*objMethods[OBJ_NUM_METHODS])();
rsRetVal (*QueryIF)(interface_t*);
struct modInfo_s *pModInfo;
-} objInfo_t;
+};
-typedef struct obj { /* the dummy struct that each derived class can be casted to */
+struct obj_s { /* the dummy struct that each derived class can be casted to */
objInfo_t *pObjInfo;
#ifndef NDEBUG /* this means if debug... */
unsigned int iObjCooCKiE; /* must always be 0xBADEFEE for a valid object */
#endif
uchar *pszName; /* the name of *this* specific object instance */
-} obj_t;
+};
/* macros which must be gloablly-visible (because they are used during definition of
@@ -105,14 +106,28 @@ typedef struct obj { /* the dummy struct that each derived class can be casted t
do { \
ASSERT(pObj != NULL); \
ASSERT((unsigned) ((obj_t*) (pObj))->iObjCooCKiE == (unsigned) 0xBADEFEE); \
- ASSERT(!strcmp((char*)(((obj_t*)pObj)->pObjInfo->pszID), #objType)); \
- } while(0);
+ if(strcmp((char*)(((obj_t*)pObj)->pObjInfo->pszID), #objType)) { \
+ dbgprintf("%s:%d ISOBJ assert failure: invalid object type, expected '%s' " \
+ "actual '%s'\n", __FILE__, __LINE__, #objType, (((obj_t*)pObj)->pObjInfo->pszID)); \
+ assert(0); /* trigger assertion, messge we already have */ \
+ } \
+ } while(0)
#else /* non-debug mode, no checks but much faster */
# define BEGINobjInstance obj_t objData
# define ISOBJ_TYPE_assert(pObj, objType)
# define ISOBJ_assert(pObj)
#endif
+/* a set method for *very simple* object accesses. Note that this does
+ * NOT conform to the standard calling conventions and should be
+ * used only if actually nothing can go wrong! -- rgerhards, 2008-04-17
+ */
+#define DEFpropGetMeth(obj, prop, dataType)\
+ dataType obj##Get##prop(void)\
+ { \
+ return pThis->prop = pVal; \
+ }
+
#define DEFpropSetMethPTR(obj, prop, dataType)\
rsRetVal obj##Set##prop(obj##_t *pThis, dataType *pVal)\
{ \
@@ -312,8 +327,8 @@ rsRetVal objName##ClassExit(void) \
}
/* ------------------------------ object loader system ------------------------------ *
- * The following code is the early beginning of a dynamic object loader system. The
- * root idea is that all objects will become dynamically loadable libraries over time,
+ * The following code builds a dynamic object loader system. The
+ * root idea is that all objects are dynamically loadable,
* which is necessary to get a clean plug-in interface where every plugin can access
* rsyslog's rich object model via simple and quite portable methods.
*
@@ -326,17 +341,12 @@ rsRetVal objName##ClassExit(void) \
* macros create a static variable named like the object in each calling objects
* static data block.
*
- * To facilitate moving to this system, I begin to implement some hooks, which
- * allows to use interfaces today (when the rest of the infrastructure is not yet
- * there). This is in the hope that it will ease migration to the full-fledged system
- * once we are ready to work on that.
- * rgerhards, 2008-02-21
+ * rgerhards, 2008-02-21 (initial implementation), 2008-04-17 (update of this note)
*/
/* this defines the QueryInterface print entry point. Over time, it should be
* present in all objects.
*/
-//#define PROTOTYPEObjQueryInterface(obj) rsRetVal obj##QueryInterface(obj##_if_t *pThis)
#define BEGINobjQueryInterface(obj) \
rsRetVal obj##QueryInterface(obj##_if_t *pIf) \
{ \
@@ -371,9 +381,6 @@ rsRetVal objName##ClassExit(void) \
*/
#define CORE_COMPONENT NULL /* use this to indicate this is a core component */
#define DONT_LOAD_LIB NULL /* do not load a library to obtain object interface (currently same as CORE_COMPONENT) */
-/*#define objUse(objName, MYLIB, FILENAME) \
- obj.UseObj(__FILE__, (uchar*)#objName, MYLIB, (uchar*)FILENAME, (void*) &objName)
-*/
#define objUse(objName, FILENAME) \
obj.UseObj(__FILE__, (uchar*)#objName, (uchar*)FILENAME, (void*) &objName)
#define objRelease(objName, FILENAME) \
diff --git a/obj.c b/runtime/obj.c
index 7a4435ea..18a4a726 100644
--- a/obj.c
+++ b/runtime/obj.c
@@ -50,22 +50,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
@@ -1011,13 +1012,6 @@ FindObjInfo(cstr_t *pstrOID, objInfo_t **ppInfo)
bFound = 0;
i = 0;
while(!bFound && i < OBJ_NUM_IDS) {
-#if 0
-RUNLOG_VAR("%d", i);
-if(arrObjInfo[i] != NULL) {
-RUNLOG_VAR("%p", arrObjInfo[i]->pszID);
-RUNLOG_VAR("%s", arrObjInfo[i]->pszID);
-}
-#endif
if(arrObjInfo[i] != NULL && !rsCStrSzStrCmp(pstrOID, arrObjInfo[i]->pszID, arrObjInfo[i]->lenID)) {
bFound = 1;
break;
@@ -1204,7 +1198,7 @@ ReleaseObj(char *srcFile, uchar *pObjName, uchar *pObjFile, interface_t *pIf)
FINALIZE; /* if it is not a lodable module, we do not need to do anything... */
if(pIf->ifIsLoaded == 0) {
- ABORT_FINALIZE(RS_RET_OK); /* we are already set */ /* TODO: flag an error? */
+ ABORT_FINALIZE(RS_RET_OK); /* we are not loaded - this is perfectly OK... */
}
if(pIf->ifIsLoaded == 2) {
pIf->ifIsLoaded = 0; /* clean up */
@@ -1292,10 +1286,10 @@ objClassExit(void)
/* TODO: implement the class exits! */
#if 0
- errmsgClassInit(pModInfo);
cfsyslineInit(pModInfo);
varClassInit(pModInfo);
#endif
+ errmsgClassExit();
moduleClassExit();
RETiRet;
}
diff --git a/obj.h b/runtime/obj.h
index 29ad2ae4..dc04203b 100644
--- a/obj.h
+++ b/runtime/obj.h
@@ -23,22 +23,23 @@
*
* Copyright 2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef OBJ_H_INCLUDED
diff --git a/objomsr.c b/runtime/objomsr.c
index 6a617ad1..21d284f3 100644
--- a/objomsr.c
+++ b/runtime/objomsr.c
@@ -5,22 +5,23 @@
*
* Copyright 2007 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
@@ -140,6 +141,5 @@ int OMSRgetEntry(omodStringRequest_t *pThis, int iEntry, uchar **ppTplName, int
return RS_RET_OK;
}
-/*
- * vi:set ai:
+/* vim:set ai:
*/
diff --git a/objomsr.h b/runtime/objomsr.h
index 9fdddf69..2255e4f3 100644
--- a/objomsr.h
+++ b/runtime/objomsr.h
@@ -2,22 +2,23 @@
*
* Copyright 2007 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef OBJOMSR_H_INCLUDED
diff --git a/queue.c b/runtime/queue.c
index 0f58c545..56711416 100644
--- a/queue.c
+++ b/runtime/queue.c
@@ -43,7 +43,6 @@
#include <errno.h>
#include "rsyslog.h"
-#include "syslogd.h"
#include "queue.h"
#include "stringbuf.h"
#include "srUtils.h"
@@ -53,6 +52,7 @@
/* static data */
DEFobjStaticHelpers
+DEFobjCurrIf(glbl)
/* forward-definitions */
rsRetVal queueChkPersist(queue_t *pThis);
@@ -642,7 +642,7 @@ queueLoadPersStrmInfoFixup(strm_t *pStrm, queue_t __attribute__((unused)) *pThis
DEFiRet;
ISOBJ_TYPE_assert(pStrm, strm);
ISOBJ_TYPE_assert(pThis, queue);
- CHKiRet(strmSetDir(pStrm, glblGetWorkDir(), strlen((char*)glblGetWorkDir())));
+ CHKiRet(strmSetDir(pStrm, glbl.GetWorkDir(), strlen((char*)glbl.GetWorkDir())));
finalize_it:
RETiRet;
}
@@ -667,7 +667,7 @@ queueHaveQIF(queue_t *pThis)
/* Construct file name */
lenQIFNam = snprintf((char*)pszQIFNam, sizeof(pszQIFNam) / sizeof(uchar), "%s/%s.qi",
- (char*) glblGetWorkDir(), (char*)pThis->pszFilePrefix);
+ (char*) glbl.GetWorkDir(), (char*)pThis->pszFilePrefix);
/* check if the file exists */
if(stat((char*) pszQIFNam, &stat_buf) == -1) {
@@ -704,7 +704,7 @@ queueTryLoadPersistedInfo(queue_t *pThis)
/* Construct file name */
lenQIFNam = snprintf((char*)pszQIFNam, sizeof(pszQIFNam) / sizeof(uchar), "%s/%s.qi",
- (char*) glblGetWorkDir(), (char*)pThis->pszFilePrefix);
+ (char*) glbl.GetWorkDir(), (char*)pThis->pszFilePrefix);
/* check if the file exists */
if(stat((char*) pszQIFNam, &stat_buf) == -1) {
@@ -791,7 +791,7 @@ static rsRetVal qConstructDisk(queue_t *pThis)
;
} else {
CHKiRet(strmConstruct(&pThis->tVars.disk.pWrite));
- CHKiRet(strmSetDir(pThis->tVars.disk.pWrite, glblGetWorkDir(), strlen((char*)glblGetWorkDir())));
+ CHKiRet(strmSetDir(pThis->tVars.disk.pWrite, glbl.GetWorkDir(), strlen((char*)glbl.GetWorkDir())));
CHKiRet(strmSetiMaxFiles(pThis->tVars.disk.pWrite, 10000000));
CHKiRet(strmSettOperationsMode(pThis->tVars.disk.pWrite, STREAMMODE_WRITE));
CHKiRet(strmSetsType(pThis->tVars.disk.pWrite, STREAMTYPE_FILE_CIRCULAR));
@@ -799,7 +799,7 @@ static rsRetVal qConstructDisk(queue_t *pThis)
CHKiRet(strmConstruct(&pThis->tVars.disk.pRead));
CHKiRet(strmSetbDeleteOnClose(pThis->tVars.disk.pRead, 1));
- CHKiRet(strmSetDir(pThis->tVars.disk.pRead, glblGetWorkDir(), strlen((char*)glblGetWorkDir())));
+ CHKiRet(strmSetDir(pThis->tVars.disk.pRead, glbl.GetWorkDir(), strlen((char*)glbl.GetWorkDir())));
CHKiRet(strmSetiMaxFiles(pThis->tVars.disk.pRead, 10000000));
CHKiRet(strmSettOperationsMode(pThis->tVars.disk.pRead, STREAMMODE_READ));
CHKiRet(strmSetsType(pThis->tVars.disk.pRead, STREAMTYPE_FILE_CIRCULAR));
@@ -1259,7 +1259,7 @@ rsRetVal queueConstruct(queue_t **ppThis, queueType_t qType, int iWorkerThreads,
/* we have an object, so let's fill the properties */
objConstructSetObjInfo(pThis);
- if((pThis->pszSpoolDir = (uchar*) strdup((char*)glblGetWorkDir())) == NULL)
+ if((pThis->pszSpoolDir = (uchar*) strdup((char*)glbl.GetWorkDir())) == NULL)
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
/* set some water marks so that we have useful defaults if none are set specifically */
@@ -1872,7 +1872,7 @@ static rsRetVal queuePersist(queue_t *pThis, int bIsCheckpoint)
/* Construct file name */
lenQIFNam = snprintf((char*)pszQIFNam, sizeof(pszQIFNam) / sizeof(uchar), "%s/%s.qi",
- (char*) glblGetWorkDir(), (char*)pThis->pszFilePrefix);
+ (char*) glbl.GetWorkDir(), (char*)pThis->pszFilePrefix);
if((bIsCheckpoint != QUEUE_CHECKPOINT) && (queueGetOverallQueueSize(pThis) == 0)) {
if(pThis->bNeedDelQIF) {
@@ -2313,6 +2313,7 @@ rsRetVal queueQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; }
*/
BEGINObjClassInit(queue, 1, OBJ_IS_CORE_MODULE)
/* request objects we use */
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
/* now set our own handlers */
OBJSetMethodHandler(objMethod_SETPROPERTY, queueSetProperty);
diff --git a/queue.h b/runtime/queue.h
index 9e75b31b..9e75b31b 100644
--- a/queue.h
+++ b/runtime/queue.h
diff --git a/regexp.c b/runtime/regexp.c
index 86b3e6c4..86b3e6c4 100644
--- a/regexp.c
+++ b/runtime/regexp.c
diff --git a/regexp.h b/runtime/regexp.h
index 8f6ac891..8f6ac891 100644
--- a/regexp.h
+++ b/runtime/regexp.h
diff --git a/runtime/rsyslog.c b/runtime/rsyslog.c
new file mode 100644
index 00000000..c05119d8
--- /dev/null
+++ b/runtime/rsyslog.c
@@ -0,0 +1,237 @@
+/* rsyslog.c - the main entry point into rsyslog's runtime library (RTL)
+ *
+ * This module contains all function which work on a RTL global level. It's
+ * name is abbreviated to "rsrt" (rsyslog runtime).
+ *
+ * Please note that the runtime library tends to be plugin-safe. That is, it must be
+ * initialized by calling a global initialization function. However, that
+ * function checks if the library is already initialized and, if so, does
+ * nothing except incrementing a refeence count. Similarly, the deinit
+ * function does nothing as long as there are still other users (which
+ * is tracked via the refcount). As such, it is safe to call init and
+ * exit multiple times, as long as this are always matching calls. This
+ * capability is needed for a plugin system, where one plugin never
+ * knows what the other did. HOWEVER, as of this writing, not all runtime
+ * library objects may work cleanly without static global data (the
+ * debug system is a very good example of this). So while we aim at the
+ * ability to work well in a plugin environment, things may not really work
+ * out. If you intend to use the rsyslog runtime library inside plugins,
+ * you should investigate the situation in detail. Please note that the
+ * rsyslog project itself does not yet need this functionality - thus you
+ * can safely assume it is totally untested ;).
+ *
+ * rgerhards, 2008-04-17: I have now once again checked on the plugin-safety.
+ * Unfortunately, there is currently no hook at all with which we could
+ * abstract a global data instance class. As such, we can NOT make the
+ * runtime plugin-safe in the above-described sense. As the rsyslog
+ * project itself does not need this functionality (and it is quesationable
+ * if someone else ever will), we do currently do not make an effort to
+ * support it. So if you intend to use rsyslog runtime inside a non-rsyslog
+ * plugin system, be careful!
+ *
+ * The rsyslog runtime library is in general reentrant and thread-safe. There
+ * are some intentional exceptions (e.g. inside the msg object). These are
+ * documented. Any other threading and reentrency issue can be considered a bug.
+ *
+ * Module begun 2008-04-16 by Rainer Gerhards
+ *
+ * Copyright 2008 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.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "rsyslog.h"
+#include "obj.h"
+#include "vm.h"
+#include "sysvar.h"
+#include "stringbuf.h"
+#include "wti.h"
+#include "wtp.h"
+#include "expr.h"
+#include "ctok.h"
+#include "vmop.h"
+#include "vmstk.h"
+#include "vmprg.h"
+#include "datetime.h"
+#include "queue.h"
+#include "conf.h"
+#include "glbl.h"
+#include "errmsg.h"
+
+/* forward definitions */
+static rsRetVal dfltErrLogger(uchar *errMsg);
+
+/* globally visible static data - see comment in rsyslog.h for details */
+uchar *glblModPath; /* module load path */
+rsRetVal (*glblErrLogger)(uchar*) = dfltErrLogger; /* the error logger to use by the errmsg module */
+
+/* static data */
+static int iRefCount = 0; /* our refcount - it MUST exist only once inside a process (not thread)
+ thus it is perfectly OK to use a static. MUST be initialized to 0! */
+
+/* This is the default instance of the error logger. It simply writes the message
+ * to stderr. It is expected that this is replaced by the runtime user very early
+ * during startup (at least if the default is unsuitable). However, we provide a
+ * default so that we can log errors during the intial phase, most importantly
+ * during initialization. -- rgerhards. 2008-04-17
+ */
+static rsRetVal dfltErrLogger(uchar *errMsg)
+{
+ DEFiRet;
+ fprintf(stderr, "rsyslog runtime error: %s\n", errMsg);
+ RETiRet;
+}
+
+
+/* set the error log function
+ * rgerhards, 2008-04-18
+ */
+rsRetVal
+rsrtSetErrLogger(rsRetVal (*errLogger)(uchar*))
+{
+ DEFiRet;
+ assert(errLogger != NULL);
+ glblErrLogger = errLogger;
+ RETiRet;
+}
+
+
+/* globally initialze the runtime system
+ * NOTE: this is NOT thread safe and must not be called concurrently. If that
+ * ever poses a problem, we may use proper mutex calls - not considered needed yet.
+ * If ppErrObj is provided, it receives a char pointer to the name of the object that
+ * caused the problem (if one occured). The caller must never free this pointer. If
+ * ppErrObj is NULL, no such information will be provided. pObjIF is the pointer to
+ * the "obj" object interface, which may be used to query any other rsyslog objects.
+ * rgerhards, 2008-04-16
+ */
+rsRetVal
+rsrtInit(char **ppErrObj, obj_if_t *pObjIF)
+{
+ DEFiRet;
+
+ if(iRefCount == 0) {
+ /* init runtime only if not yet done */
+ if(ppErrObj != NULL) *ppErrObj = "obj";
+ CHKiRet(objClassInit(NULL)); /* *THIS* *MUST* always be the first class initilizer being called! */
+ CHKiRet(objGetObjInterface(pObjIF)); /* this provides the root pointer for all other queries */
+
+ /* initialize core classes. We must be very careful with the order of events. Some
+ * classes use others and if we do not initialize them in the right order, we may end
+ * up with an invalid call. The most important thing that can happen is that an error
+ * is detected and needs to be logged, wich in turn requires a broader number of classes
+ * to be available. The solution is that we take care in the order of calls AND use a
+ * class immediately after it is initialized. And, of course, we load those classes
+ * first that we use ourselfs... -- rgerhards, 2008-03-07
+ */
+ if(ppErrObj != NULL) *ppErrObj = "glbl";
+ CHKiRet(glblClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "datetime";
+ CHKiRet(datetimeClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "msg";
+ CHKiRet(msgClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "str,";
+ CHKiRet(strmClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "wti";
+ CHKiRet(wtiClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "wtp";
+ CHKiRet(wtpClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "queue";
+ CHKiRet(queueClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "vmstk";
+ CHKiRet(vmstkClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "sysvar";
+ CHKiRet(sysvarClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "vm";
+ CHKiRet(vmClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "vmop";
+ CHKiRet(vmopClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "vmprg";
+ CHKiRet(vmprgClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "ctok_token";
+ CHKiRet(ctok_tokenClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "ctok";
+ CHKiRet(ctokClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "expr";
+ CHKiRet(exprClassInit(NULL));
+ if(ppErrObj != NULL) *ppErrObj = "conf";
+ CHKiRet(confClassInit(NULL));
+
+ /* dummy "classes" */
+ if(ppErrObj != NULL) *ppErrObj = "str";
+ CHKiRet(strInit());
+ }
+
+ ++iRefCount;
+ dbgprintf("rsyslog runtime initialized, version %s, current users %d\n", VERSION, iRefCount);
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* globally de-initialze the runtime system
+ * NOTE: this is NOT thread safe and must not be called concurrently. If that
+ * ever poses a problem, we may use proper mutex calls - not considered needed yet.
+ * This function must be provided with the caller's obj object pointer. This is
+ * automatically deinitialized by the runtime system.
+ * rgerhards, 2008-04-16
+ */
+rsRetVal
+rsrtExit(void)
+{
+ DEFiRet;
+
+ if(iRefCount == 1) {
+ /* do actual de-init only if we are the last runtime user */
+ confClassExit();
+ glblClassExit();
+ objClassExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */
+ }
+
+ --iRefCount;
+ /* TODO we must deinit this pointer! pObjIF = NULL; / * no longer exists for this caller */
+
+ dbgprintf("rsyslog runtime de-initialized, current users %d\n", iRefCount);
+
+ RETiRet;
+}
+
+
+/* returns 0 if the rsyslog runtime is not initialized and another value
+ * if it is. This function is primarily meant to be used by runtime functions
+ * itself. However, it is safe to call it before initializing the runtime.
+ * Plugins should NOT rely on this function. The reason is that another caller
+ * may have already initialized it but deinits it before this plugin is done.
+ * So for plugins and like architectures, the right course of action is to
+ * call rsrtInit() and rsrtExit(), which can be called by multiple callers.
+ * rgerhards, 2008-04-16
+ */
+int rsrtIsInit(void)
+{
+ return iRefCount;
+}
+
+
+/* vim:set ai:
+ */
diff --git a/rsyslog.h b/runtime/rsyslog.h
index c73c659c..19fda468 100644
--- a/rsyslog.h
+++ b/runtime/rsyslog.h
@@ -1,27 +1,28 @@
-/* Header file with global definitions for the whole
- * rsyslog project (including all subprojects like
- * rfc3195d).
+/* This is the header file for the rsyslog runtime. It must be included
+ * if someone intends to use the runtime.
+ *
* Begun 2005-09-15 RGerhards
*
- * Copyright (C) 2005 by Rainer Gerhards and Adiscon GmbH
+ * Copyright (C) 2005-2008 by Rainer Gerhards and Adiscon GmbH
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
+ */
#ifndef INCLUDED_RSYSLOG_H
#define INCLUDED_RSYSLOG_H
@@ -43,6 +44,44 @@
# define _FILE_OFFSET_BITS 64
#endif
+/* portability: not all platforms have these defines, so we
+ * define them here if they are missing. -- rgerhards, 2008-03-04
+ */
+#ifndef LOG_MAKEPRI
+# define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
+#endif
+#ifndef LOG_PRI
+# define LOG_PRI(p) ((p) & LOG_PRIMASK)
+#endif
+#ifndef LOG_FAC
+# define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
+#endif
+
+
+/* define some base data types */
+typedef unsigned char uchar;/* get rid of the unhandy "unsigned char" */
+typedef struct thrdInfo thrdInfo_t;
+typedef struct obj_s obj_t;
+typedef struct filed selector_t;/* TODO: this so far resides in syslogd.c, think about modularization */
+typedef struct NetAddr netAddr_t;
+typedef struct netstrms_s netstrms_t;
+typedef struct netstrm_s netstrm_t;
+typedef struct nssel_s nssel_t;
+typedef enum nsdsel_waitOp_e nsdsel_waitOp_t;
+typedef struct nsd_ptcp_s nsd_ptcp_t;
+typedef struct nsd_gtls_s nsd_gtls_t;
+typedef struct nsd_gsspi_s nsd_gsspi_t;
+typedef struct nsd_nss_s nsd_nss_t;
+typedef struct nsdsel_ptcp_s nsdsel_ptcp_t;
+typedef struct nsdsel_gtls_s nsdsel_gtls_t;
+typedef obj_t nsd_t;
+typedef obj_t nsdsel_t;
+typedef struct msg msg_t;
+typedef struct interface_s interface_t;
+typedef struct objInfo_s objInfo_t;
+typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */
+typedef rsRetVal (*errLogFunc_t)(uchar*); /* this is a trick to store a function ptr to a function returning a function ptr... */
+typedef struct tcpsrv_s tcpsrv_t;
/* some universal 64 bit define... */
typedef long long int64;
@@ -172,6 +211,14 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_MAIL_NO_TO = -2071, /**< recipient for mail destination is missing */
RS_RET_MAIL_NO_FROM = -2072, /**< sender for mail destination is missing */
RS_RET_INVALID_PRI = -2073, /**< PRI value is invalid */
+ RS_RET_MALICIOUS_HNAME = -2074, /**< remote peer is trying malicious things with its hostname */
+ RS_RET_ACCEPT_ERR = -2074, /**< error during accept() system call */
+ RS_RET_INVALID_HNAME = -2075, /**< remote peer's hostname invalid or unobtainable */
+ RS_RET_INVALID_PORT = -2076, /**< invalid port value */
+ RS_RET_COULD_NOT_BIND = -2077, /**< could not bind socket, defunct */
+ RS_RET_GNUTLS_ERR = -2078, /**< (unexpected) error in GnuTLS call */
+ RS_RET_MAX_SESS_REACHED = -2079, /**< max nbr of sessions reached, can not create more */
+ RS_RET_MAX_LSTN_REACHED = -2080, /**< max nbr of listeners reached, can not create more */
/* RainerScript error messages (range 1000.. 1999) */
RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */
@@ -182,7 +229,6 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth
RS_RET_NO_RUN = 3, /**< operation successful, but function does not like to be executed */
RS_RET_OK = 0 /**< operation successful */
};
-typedef enum rsRetVal_ rsRetVal; /**< friendly type for global return value */
/* some helpful macros to work with srRetVals.
* Be sure to call the to-be-returned variable always "iRet" and
@@ -247,9 +293,6 @@ typedef enum rsObjectID rsObjID;
#define RSFREEOBJ(x) {(x)->OID = OIDrsFreed; free(x);}
#endif
-/* get rid of the unhandy "unsigned char"
- */
-typedef unsigned char uchar;
/* for the time being, we do our own portability handling here. It
* looks like autotools either does not yet support checks for it, or
@@ -263,8 +306,26 @@ typedef unsigned char uchar;
void dbgprintf(char *, ...) __attribute__((format(printf, 1, 2)));
#include "debug.h"
+#include "obj.h"
+
+/* the variable below is a trick: before we can init the runtime, the caller
+ * may want to set a module load path. We can not do this via the glbl class
+ * because it needs an initialized runtime system (and may at some point in time
+ * even be loaded itself). So this is a no-go. What we do is use a single global
+ * variable which may be provided with a pointer by the caller. This variable
+ * resides in rsyslog.c, the main runtime file. We have not seen any realy valule
+ * in providing object access functions. If you don't like that, feel free to
+ * add them. -- rgerhards, 2008-04-17
+ */
+extern uchar *glblModPath; /* module load path */
+extern rsRetVal (*glblErrLogger)(uchar*);
+
+/* some runtime prototypes */
+rsRetVal rsrtInit(char **ppErrObj, obj_if_t *pObjIF);
+rsRetVal rsrtExit(void);
+int rsrtIsInit(void);
+rsRetVal rsrtSetErrLogger(rsRetVal (*errLogger)(uchar*));
#endif /* multi-include protection */
-/*
- * vi:set ai:
+/* vim:set ai:
*/
diff --git a/srUtils.h b/runtime/srUtils.h
index ebd6518f..bfce4cbb 100644
--- a/srUtils.h
+++ b/runtime/srUtils.h
@@ -7,22 +7,23 @@
*
* Copyright 2003-2007 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef __SRUTILS_H_INCLUDED__
#define __SRUTILS_H_INCLUDED__ 1
@@ -90,6 +91,7 @@ void mutexCancelCleanup(void *arg);
void srSleep(int iSeconds, int iuSeconds);
char *rs_strerror_r(int errnum, char *buf, size_t buflen);
int decodeSyslogName(uchar *name, syslogName_t *codetab);
+int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep);
/* mutex operations */
/* some macros to cancel-safe lock a mutex (it will automatically be released
diff --git a/srUtils.c b/runtime/srutils.c
index fa451b7e..97cc3252 100644
--- a/srUtils.c
+++ b/runtime/srutils.c
@@ -9,26 +9,28 @@
*
* Copyright 2003-2008 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
#include "rsyslog.h"
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -39,16 +41,16 @@
#include <assert.h>
#include <sys/wait.h>
#include <ctype.h>
-#include "liblogging-stub.h"
#define TRUE 1
#define FALSE 0
#include "srUtils.h"
-#include "syslogd.h"
#include "obj.h"
/* here we host some syslog specific names. There currently is no better place
* to do it, but over here is also not ideal... -- rgerhards, 2008-02-14
+ * rgerhards, 2008-04-16: note in LGPL move: the code tables below exist in
+ * the same way in BSD, so it is not a problem to move them from GPLv3 to LGPL.
*/
syslogName_t syslogPriNames[] = {
{"alert", LOG_ALERT},
@@ -502,5 +504,51 @@ int decodeSyslogName(uchar *name, syslogName_t *codetab)
}
+/**
+ * getSubString
+ *
+ * Copy a string byte by byte until the occurrence
+ * of a given separator.
+ *
+ * \param ppSrc Pointer to a pointer of the source array of characters. If a
+ separator detected the Pointer points to the next char after the
+ separator. Except if the end of the string is dedected ('\n').
+ Then it points to the terminator char.
+ * \param pDst Pointer to the destination array of characters. Here the substing
+ will be stored.
+ * \param DstSize Maximum numbers of characters to store.
+ * \param cSep Separator char.
+ * \ret int Returns 0 if no error occured.
+ *
+ * rgerhards, 2008-02-12: some notes are due... I will once again fix this function, this time
+ * so that it treats ' ' as a request for whitespace. But in general, the function and its callers
+ * should be changed over time, this is not really very good code...
+ */
+int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep)
+{
+ uchar *pSrc = *ppSrc;
+ int iErr = 0; /* 0 = no error, >0 = error */
+ while((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0' && DstSize>1) {
+ *pDst++ = *(pSrc)++;
+ DstSize--;
+ }
+ /* check if the Dst buffer was to small */
+ if ((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0') {
+ dbgprintf("in getSubString, error Src buffer > Dst buffer\n");
+ iErr = 1;
+ }
+ if (*pSrc == '\0' || *pSrc == '\n')
+ /* this line was missing, causing ppSrc to be invalid when it
+ * was returned in case of end-of-string. rgerhards 2005-07-29
+ */
+ *ppSrc = pSrc;
+ else
+ *ppSrc = pSrc+1;
+ *pDst = '\0';
+ return iErr;
+}
+
+
+
/* vim:set ai:
*/
diff --git a/stream.c b/runtime/stream.c
index 1be4571a..3afa9fcd 100644
--- a/stream.c
+++ b/runtime/stream.c
@@ -41,7 +41,6 @@
#include <errno.h>
#include "rsyslog.h"
-#include "syslogd.h"
#include "stringbuf.h"
#include "srUtils.h"
#include "obj.h"
diff --git a/stream.h b/runtime/stream.h
index 371358ab..371358ab 100644
--- a/stream.h
+++ b/runtime/stream.h
diff --git a/stringbuf.c b/runtime/stringbuf.c
index 4254d5bd..93d1e1ef 100644
--- a/stringbuf.c
+++ b/runtime/stringbuf.c
@@ -7,24 +7,25 @@
* All functions in this "class" start with rsCStr (rsyslog Counted String).
* begun 2005-09-07 rgerhards
*
- * Copyright (C) 2007 by Rainer Gerhards and Adiscon GmbH
+ * Copyright (C) 2007-2008 by Rainer Gerhards and Adiscon GmbH
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#include "config.h"
diff --git a/stringbuf.h b/runtime/stringbuf.h
index e44e86e1..c1966449 100644
--- a/stringbuf.h
+++ b/runtime/stringbuf.h
@@ -15,22 +15,23 @@
* Copyright 2005
* Rainer Gerhards and Adiscon GmbH. All Rights Reserved.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef _STRINGBUF_H_INCLUDED__
#define _STRINGBUF_H_INCLUDED__ 1
diff --git a/sync.c b/runtime/sync.c
index a3053e28..a3053e28 100644
--- a/sync.c
+++ b/runtime/sync.c
diff --git a/sync.h b/runtime/sync.h
index 57144fee..57144fee 100644
--- a/sync.h
+++ b/runtime/sync.h
diff --git a/syslogd-types.h b/runtime/syslogd-types.h
index 9aea3778..be0dfdd8 100644
--- a/syslogd-types.h
+++ b/runtime/syslogd-types.h
@@ -6,28 +6,28 @@
*
* Copyright 2007 Rainer Gerhards and Adiscon GmbH.
*
- * This file is part of rsyslog.
+ * This file is part of the rsyslog runtime library.
*
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * The 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.
*
- * Rsyslog is distributed in the hope that it will be useful,
+ * 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 General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ * 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.
*/
#ifndef SYSLOGD_TYPES_INCLUDED
#define SYSLOGD_TYPES_INCLUDED 1
#include "stringbuf.h"
-//#include "net.h"
#include <sys/param.h>
#if HAVE_SYSLOG_H
#include <syslog.h>
@@ -99,6 +99,5 @@ struct syslogTime {
typedef struct syslogTime syslogTime_t;
#endif /* #ifndef SYSLOGD_TYPES_INCLUDED */
-/*
- * vi:set ai:
+/* vi:set ai:
*/
diff --git a/sysvar.c b/runtime/sysvar.c
index 5eec8f67..5eec8f67 100644
--- a/sysvar.c
+++ b/runtime/sysvar.c
diff --git a/sysvar.h b/runtime/sysvar.h
index 35051b64..35051b64 100644
--- a/sysvar.h
+++ b/runtime/sysvar.h
diff --git a/var.c b/runtime/var.c
index 7e51fc6d..7e51fc6d 100644
--- a/var.c
+++ b/runtime/var.c
diff --git a/var.h b/runtime/var.h
index bbe7ba33..bbe7ba33 100644
--- a/var.h
+++ b/runtime/var.h
diff --git a/vm.c b/runtime/vm.c
index bcd331ec..bcd331ec 100644
--- a/vm.c
+++ b/runtime/vm.c
diff --git a/vm.h b/runtime/vm.h
index d2458220..d2458220 100644
--- a/vm.h
+++ b/runtime/vm.h
diff --git a/vmop.c b/runtime/vmop.c
index 219315c4..219315c4 100644
--- a/vmop.c
+++ b/runtime/vmop.c
diff --git a/vmop.h b/runtime/vmop.h
index 97f924d7..97f924d7 100644
--- a/vmop.h
+++ b/runtime/vmop.h
diff --git a/vmprg.c b/runtime/vmprg.c
index a2b744d7..a2b744d7 100644
--- a/vmprg.c
+++ b/runtime/vmprg.c
diff --git a/vmprg.h b/runtime/vmprg.h
index db1f62f0..db1f62f0 100644
--- a/vmprg.h
+++ b/runtime/vmprg.h
diff --git a/vmstk.c b/runtime/vmstk.c
index 1ee3d485..1ee3d485 100644
--- a/vmstk.c
+++ b/runtime/vmstk.c
diff --git a/vmstk.h b/runtime/vmstk.h
index 2d45ee4d..2d45ee4d 100644
--- a/vmstk.h
+++ b/runtime/vmstk.h
diff --git a/wti.c b/runtime/wti.c
index 82cd2165..0e04200c 100644
--- a/wti.c
+++ b/runtime/wti.c
@@ -40,7 +40,6 @@
#include <errno.h>
#include "rsyslog.h"
-#include "syslogd.h"
#include "stringbuf.h"
#include "srUtils.h"
#include "wtp.h"
diff --git a/wti.h b/runtime/wti.h
index b3d92473..b3d92473 100644
--- a/wti.h
+++ b/runtime/wti.h
diff --git a/wtp.c b/runtime/wtp.c
index fcc7589c..0658232b 100644
--- a/wtp.c
+++ b/runtime/wtp.c
@@ -41,7 +41,6 @@
#include <errno.h>
#include "rsyslog.h"
-#include "syslogd.h"
#include "stringbuf.h"
#include "srUtils.h"
#include "wtp.h"
diff --git a/wtp.h b/runtime/wtp.h
index 13ebe536..13ebe536 100644
--- a/wtp.h
+++ b/runtime/wtp.h
diff --git a/tcpclt.c b/tcpclt.c
index 3a76e47d..2bc2ea56 100644
--- a/tcpclt.c
+++ b/tcpclt.c
@@ -38,10 +38,9 @@
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
-#include "syslogd.h"
+#include "dirty.h"
#include "syslogd-types.h"
#include "net.h"
-#include "tcpsyslog.h"
#include "tcpclt.h"
#include "module-template.h"
#include "srUtils.h"
@@ -52,7 +51,6 @@ MODULE_TYPE_LIB
DEFobjStaticHelpers
/* Initialize TCP sockets (for sender)
- * This is done once per selector line, if not yet initialized.
*/
static int
CreateSocket(struct addrinfo *addrDest)
diff --git a/tcpclt.h b/tcpclt.h
index d2f1fe02..b7aada65 100644
--- a/tcpclt.h
+++ b/tcpclt.h
@@ -26,7 +26,6 @@
#ifndef TCPCLT_H_INCLUDED
#define TCPCLT_H_INCLUDED 1
-#include "tcpsyslog.h"
#include "obj.h"
/* the tcpclt object */
diff --git a/tcps_sess.c b/tcps_sess.c
index 001f32f0..33c13aa0 100644
--- a/tcps_sess.c
+++ b/tcps_sess.c
@@ -27,35 +27,27 @@
*
* A copy of the GPL can be found in the file "COPYING" in this distribution.
*/
-
#include "config.h"
#include <stdlib.h>
#include <assert.h>
-#include <string.h>
#include <errno.h>
-#include <unistd.h>
-#include <stdarg.h>
#include <ctype.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
+
#include "rsyslog.h"
-#include "syslogd.h"
+#include "dirty.h"
#include "module-template.h"
#include "net.h"
#include "tcpsrv.h"
#include "tcps_sess.h"
#include "obj.h"
#include "errmsg.h"
+#include "netstrm.h"
/* static data */
DEFobjStaticHelpers
DEFobjCurrIf(errmsg)
+DEFobjCurrIf(netstrm)
/* forward definitions */
static rsRetVal Close(tcps_sess_t *pThis);
@@ -64,7 +56,6 @@ static rsRetVal Close(tcps_sess_t *pThis);
/* Standard-Constructor
*/
BEGINobjConstruct(tcps_sess) /* be sure to specify the object type also in END macro! */
- pThis->sock = -1; /* no sock */
pThis->iMsg = 0; /* just make sure... */
pThis->bAtStrtOfFram = 1; /* indicate frame header expected */
pThis->eFraming = TCP_FRAMING_OCTET_STUFFING; /* just make sure... */
@@ -90,8 +81,8 @@ finalize_it:
/* destructor for the tcps_sess object */
BEGINobjDestruct(tcps_sess) /* be sure to specify the object type also in END and CODESTART macros! */
CODESTARTobjDestruct(tcps_sess)
- if(pThis->sock != -1)
- Close(pThis);
+ if(pThis->pStrm != NULL)
+ netstrm.Destruct(&pThis->pStrm);
if(pThis->pSrv->pOnSessDestruct != NULL) {
pThis->pSrv->pOnSessDestruct(&pThis->pUsr);
@@ -99,7 +90,6 @@ CODESTARTobjDestruct(tcps_sess)
/* now destruct our own properties */
if(pThis->fromHost != NULL)
free(pThis->fromHost);
- close(pThis->sock);
ENDobjDestruct(tcps_sess)
@@ -110,6 +100,10 @@ ENDobjDebugPrint(tcps_sess)
/* set property functions */
+/* set the hostname. Note that the caller *hands over* the string. That is,
+ * the caller no longer controls it once SetHost() has received it. Most importantly,
+ * the caller must not free it. -- gerhards, 2008-04-24
+ */
static rsRetVal
SetHost(tcps_sess_t *pThis, uchar *pszHost)
{
@@ -119,25 +113,24 @@ SetHost(tcps_sess_t *pThis, uchar *pszHost)
if(pThis->fromHost != NULL) {
free(pThis->fromHost);
- pThis->fromHost = NULL;
}
- if((pThis->fromHost = strdup((char*)pszHost)) == NULL)
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ pThis->fromHost = pszHost;
finalize_it:
RETiRet;
}
static rsRetVal
-SetSock(tcps_sess_t *pThis, int sock)
+SetStrm(tcps_sess_t *pThis, netstrm_t *pStrm)
{
DEFiRet;
ISOBJ_TYPE_assert(pThis, tcps_sess);
- pThis->sock = sock;
+ pThis->pStrm = pStrm;
RETiRet;
}
+
static rsRetVal
SetMsgIdx(tcps_sess_t *pThis, int idx)
{
@@ -200,9 +193,8 @@ PrepareClose(tcps_sess_t *pThis)
/* In this case, we have an invalid frame count and thus
* generate an error message and discard the frame.
*/
- errmsg.LogError(NO_ERRCODE, "Incomplete frame at end of stream in session %d - "
- "ignoring extra data (a message may be lost).\n",
- pThis->sock);
+ errmsg.LogError(NO_ERRCODE, "Incomplete frame at end of stream in session %p - "
+ "ignoring extra data (a message may be lost).\n", pThis->pStrm);
/* nothing more to do */
} else { /* here, we have traditional framing. Missing LF at the end
* of message may occur. As such, we process the message in
@@ -228,8 +220,7 @@ Close(tcps_sess_t *pThis)
DEFiRet;
ISOBJ_TYPE_assert(pThis, tcps_sess);
- close(pThis->sock);
- pThis->sock = -1;
+ netstrm.Destruct(&pThis->pStrm);
free(pThis->fromHost);
pThis->fromHost = NULL; /* not really needed, but... */
@@ -403,7 +394,7 @@ CODESTARTobjQueryInterface(tcps_sess)
pIf->SetUsrP = SetUsrP;
pIf->SetTcpsrv = SetTcpsrv;
pIf->SetHost = SetHost;
- pIf->SetSock = SetSock;
+ pIf->SetStrm = SetStrm;
pIf->SetMsgIdx = SetMsgIdx;
finalize_it:
ENDobjQueryInterface(tcps_sess)
@@ -416,6 +407,7 @@ BEGINObjClassExit(tcps_sess, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END
CODESTARTObjClassExit(tcps_sess)
/* release objects we no longer need */
objRelease(errmsg, CORE_COMPONENT);
+ objRelease(netstrm, LM_NETSTRM_FILENAME);
ENDObjClassExit(tcps_sess)
@@ -426,6 +418,7 @@ ENDObjClassExit(tcps_sess)
BEGINObjClassInit(tcps_sess, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANGE class also in END MACRO! */
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
/* set our own handlers */
OBJSetMethodHandler(objMethod_DEBUGPRINT, tcps_sessDebugPrint);
diff --git a/tcps_sess.h b/tcps_sess.h
index 0433fdfb..9f3d10d6 100644
--- a/tcps_sess.h
+++ b/tcps_sess.h
@@ -28,18 +28,12 @@
/* a forward-definition, we are somewhat cyclic */
struct tcpsrv_s;
-/* framing modes for TCP */
-typedef enum _TCPFRAMINGMODE {
- TCP_FRAMING_OCTET_STUFFING = 0, /* traditional LF-delimited */
- TCP_FRAMING_OCTET_COUNTING = 1 /* -transport-tls like octet count */
- } TCPFRAMINGMODE;
-
/* the tcps_sess object */
typedef struct tcps_sess_s {
BEGINobjInstance; /* Data to implement generic object - MUST be the first data element! */
struct tcpsrv_s *pSrv; /* pointer back to my server (e.g. for callbacks) */
- int sock;
- int iMsg; /* index of next char to store in msg */
+ 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? */
enum {
eAtStrtFram,
@@ -49,7 +43,7 @@ typedef struct tcps_sess_s {
int iOctetsRemain; /* Number of Octets remaining in message */
TCPFRAMINGMODE eFraming;
char msg[MAXLINE+1];
- char *fromHost;
+ uchar *fromHost;
void *pUsr; /* a user-pointer */
} tcps_sess_t;
@@ -67,7 +61,7 @@ BEGINinterface(tcps_sess) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetTcpsrv)(tcps_sess_t *pThis, struct tcpsrv_s *pSrv);
rsRetVal (*SetUsrP)(tcps_sess_t*, void*);
rsRetVal (*SetHost)(tcps_sess_t *pThis, uchar*);
- rsRetVal (*SetSock)(tcps_sess_t *pThis, int);
+ rsRetVal (*SetStrm)(tcps_sess_t *pThis, netstrm_t*);
rsRetVal (*SetMsgIdx)(tcps_sess_t *pThis, int);
ENDinterface(tcps_sess)
#define tcps_sessCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
diff --git a/tcpsrv.c b/tcpsrv.c
index 955fb9b5..069c83c0 100644
--- a/tcpsrv.c
+++ b/tcpsrv.c
@@ -54,7 +54,7 @@
#include <fcntl.h>
#endif
#include "rsyslog.h"
-#include "syslogd.h"
+#include "dirty.h"
#include "cfsysline.h"
#include "module-template.h"
#include "net.h"
@@ -62,43 +62,28 @@
#include "conf.h"
#include "tcpsrv.h"
#include "obj.h"
+#include "glbl.h"
+#include "netstrms.h"
+#include "netstrm.h"
+#include "nssel.h"
#include "errmsg.h"
MODULE_TYPE_LIB
/* defines */
#define TCPSESS_MAX_DEFAULT 200 /* default for nbr of tcp sessions if no number is given */
+#define TCPLSTN_MAX_DEFAULT 20 /* default for nbr of listeners */
/* static data */
DEFobjStaticHelpers
DEFobjCurrIf(conf)
+DEFobjCurrIf(glbl)
DEFobjCurrIf(tcps_sess)
DEFobjCurrIf(errmsg)
DEFobjCurrIf(net)
-
-
-
-/* code to free all sockets within a socket table.
- * A socket table is a descriptor table where the zero
- * element has the count of elements. This is used for
- * listening sockets. The socket table itself is also
- * freed.
- * A POINTER to this structure must be provided, thus
- * double indirection!
- * rgerhards, 2007-06-28
- */
-static void freeAllSockets(int **socks)
-{
- assert(socks != NULL);
- assert(*socks != NULL);
- while(**socks) {
- dbgprintf("Closing socket %d.\n", (*socks)[**socks]);
- close((*socks)[**socks]);
- (**socks)--;
- }
- free(*socks);
- *socks = NULL;
-}
+DEFobjCurrIf(netstrms)
+DEFobjCurrIf(netstrm)
+DEFobjCurrIf(nssel)
/* configure TCP listener settings. This is called during command
@@ -197,9 +182,10 @@ TCPSessGetNxtSess(tcpsrv_t *pThis, int iCurr)
register int i;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- for(i = iCurr + 1 ; i < pThis->iSessMax ; ++i)
+ for(i = iCurr + 1 ; i < pThis->iSessMax ; ++i) {
if(pThis->pSessions[i] != NULL)
break;
+ }
return((i < pThis->iSessMax) ? i : -1);
}
@@ -213,17 +199,17 @@ TCPSessGetNxtSess(tcpsrv_t *pThis, int iCurr)
*/
static void deinit_tcp_listener(tcpsrv_t *pThis)
{
- int iTCPSess;
+ int i;
ISOBJ_TYPE_assert(pThis, tcpsrv);
assert(pThis->pSessions != NULL);
/* close all TCP connections! */
- iTCPSess = TCPSessGetNxtSess(pThis, -1);
- while(iTCPSess != -1) {
- tcps_sess.Destruct(&pThis->pSessions[iTCPSess]);
+ i = TCPSessGetNxtSess(pThis, -1);
+ while(i != -1) {
+ tcps_sess.Destruct(&pThis->pSessions[i]);
/* now get next... */
- iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
+ i = TCPSessGetNxtSess(pThis, i);
}
/* we are done with the session table - so get rid of it...
@@ -234,33 +220,49 @@ static void deinit_tcp_listener(tcpsrv_t *pThis)
if(pThis->TCPLstnPort != NULL)
free(pThis->TCPLstnPort);
- /* finally close the listen sockets themselfs */
- freeAllSockets(&pThis->pSocksLstn);
+ /* finally close our listen streams */
+ for(i = 0 ; i < pThis->iLstnMax ; ++i) {
+ netstrm.Destruct(pThis->ppLstn + i);
+ }
}
-/* Initialize TCP sockets (for listener)
- * This function returns either NULL (which means it failed) or
- * a pointer to an array of file descriptiors. If the pointer is
- * returned, the zeroest element [0] contains the count of valid
- * descriptors. The descriptors themself follow in range
- * [1] ... [num-descriptors]. It is guaranteed that each of these
- * descriptors is valid, at least when this function returns.
- * Please note that technically the array may be larger than the number
- * of valid pointers stored in it. The memory overhead is minimal, so
- * we do not bother to re-allocate an array of the exact size. Logically,
- * the array still contains the exactly correct number of descriptors.
+/* add a listen socket to our listen socket array. This is a callback
+ * invoked from the netstrm class. -- rgerhards, 2008-04-23
*/
-static int *create_tcp_socket(tcpsrv_t *pThis)
+static rsRetVal
+addTcpLstn(void *pUsr, netstrm_t *pLstn)
+{
+ tcpsrv_t *pThis = (tcpsrv_t*) pUsr;
+ DEFiRet;
+
+ ISOBJ_TYPE_assert(pThis, tcpsrv);
+ ISOBJ_TYPE_assert(pLstn, netstrm);
+
+ if(pThis->iLstnMax >= TCPLSTN_MAX_DEFAULT)
+ ABORT_FINALIZE(RS_RET_MAX_LSTN_REACHED);
+
+ pThis->ppLstn[pThis->iLstnMax] = pLstn;
+ ++pThis->iLstnMax;
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* Initialize TCP sockets (for listener) and listens on them */
+static rsRetVal
+create_tcp_socket(tcpsrv_t *pThis)
{
- struct addrinfo hints, *res, *r;
- int error, maxs, *s, *socks, on = 1;
- char *TCPLstnPort;
+ DEFiRet;
+ uchar *TCPLstnPort;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- if(!strcmp(pThis->TCPLstnPort, "0"))
- TCPLstnPort = "514";
+ if(!strcmp((char*)pThis->TCPLstnPort, "0"))
+ TCPLstnPort = (uchar*)"514";
+ // TODO: we need to enable the caller to set a port (based on who is
+ // using this, 514 may be totally unsuitable... --- rgerhards, 2008-04-22
/* use default - we can not do service db update, because there is
* no IANA-assignment for syslog/tcp. In the long term, we might
* re-use RFC 3195 port of 601, but that would probably break to
@@ -268,121 +270,10 @@ static int *create_tcp_socket(tcpsrv_t *pThis)
* rgerhards, 2007-06-28
*/
else
- TCPLstnPort = pThis->TCPLstnPort;
- dbgprintf("creating tcp socket on port %s\n", TCPLstnPort);
- memset(&hints, 0, sizeof(hints));
- hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
-
- error = getaddrinfo(NULL, TCPLstnPort, &hints, &res);
- if(error) {
- errmsg.LogError(NO_ERRCODE, "%s", gai_strerror(error));
- return NULL;
- }
-
- /* Count max number of sockets we may open */
- for (maxs = 0, r = res; r != NULL ; r = r->ai_next, maxs++)
- /* EMPTY */;
- socks = malloc((maxs+1) * sizeof(int));
- if (socks == NULL) {
- errmsg.LogError(NO_ERRCODE, "couldn't allocate memory for TCP listen sockets, suspending TCP message reception.");
- freeaddrinfo(res);
- return NULL;
- }
-
- *socks = 0; /* num of sockets counter at start of array */
- s = socks + 1;
- for (r = res; r != NULL ; r = r->ai_next) {
- *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
- if (*s < 0) {
- if(!(r->ai_family == PF_INET6 && errno == EAFNOSUPPORT))
- errmsg.LogError(NO_ERRCODE, "create_tcp_socket(), socket");
- /* it is debatable if PF_INET with EAFNOSUPPORT should
- * also be ignored...
- */
- continue;
- }
-
-#ifdef IPV6_V6ONLY
- if (r->ai_family == AF_INET6) {
- int iOn = 1;
- if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
- (char *)&iOn, sizeof (iOn)) < 0) {
- errmsg.LogError(NO_ERRCODE, "TCP setsockopt");
- close(*s);
- *s = -1;
- continue;
- }
- }
-#endif
- if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR,
- (char *) &on, sizeof(on)) < 0 ) {
- errmsg.LogError(NO_ERRCODE, "TCP setsockopt(REUSEADDR)");
- close(*s);
- *s = -1;
- continue;
- }
-
- /* We need to enable BSD compatibility. Otherwise an attacker
- * could flood our log files by sending us tons of ICMP errors.
- */
-#ifndef OS_BSD
- if(net.should_use_so_bsdcompat()) {
- if (setsockopt(*s, SOL_SOCKET, SO_BSDCOMPAT,
- (char *) &on, sizeof(on)) < 0) {
- errmsg.LogError(NO_ERRCODE, "TCP setsockopt(BSDCOMPAT)");
- close(*s);
- *s = -1;
- continue;
- }
- }
-#endif
+ TCPLstnPort = (uchar*)pThis->TCPLstnPort;
- if( (bind(*s, r->ai_addr, r->ai_addrlen) < 0)
-#ifndef IPV6_V6ONLY
- && (errno != EADDRINUSE)
-#endif
- ) {
- errmsg.LogError(NO_ERRCODE, "TCP bind");
- close(*s);
- *s = -1;
- continue;
- }
-
- if( listen(*s,pThis->iSessMax / 10 + 5) < 0) {
- /* If the listen fails, it most probably fails because we ask
- * for a too-large backlog. So in this case we first set back
- * to a fixed, reasonable, limit that should work. Only if
- * that fails, too, we give up.
- */
- errmsg.LogError(NO_ERRCODE, "listen with a backlog of %d failed - retrying with default of 32.",
- pThis->iSessMax / 10 + 5);
- if(listen(*s, 32) < 0) {
- errmsg.LogError(NO_ERRCODE, "TCP listen, suspending tcp inet");
- close(*s);
- *s = -1;
- continue;
- }
- }
-
- (*socks)++;
- s++;
- }
-
- if(res != NULL)
- freeaddrinfo(res);
-
- if(Debug && *socks != maxs)
- dbgprintf("We could initialize %d TCP listen sockets out of %d we received "
- "- this may or may not be an error indication.\n", *socks, maxs);
-
- if(*socks == 0) {
- errmsg.LogError(NO_ERRCODE, "No TCP listen socket could successfully be initialized, "
- "message reception via TCP disabled.\n");
- free(socks);
- return(NULL);
- }
+ /* TODO: add capability to specify local listen address! */
+ CHKiRet(netstrm.LstnInit(pThis->pNS, (void*)pThis, addTcpLstn, TCPLstnPort, NULL, pThis->iSessMax));
/* OK, we had success. Now it is also time to
* initialize our connections
@@ -393,11 +284,11 @@ static int *create_tcp_socket(tcpsrv_t *pThis)
* we have assigned so far, because we can not really use it...
*/
errmsg.LogError(NO_ERRCODE, "Could not initialize TCP session table, suspending TCP message reception.");
- freeAllSockets(&socks); /* prevent a socket leak */
- return(NULL);
+ ABORT_FINALIZE(RS_RET_ERR);
}
- return(socks);
+finalize_it:
+ RETiRet;
}
@@ -412,34 +303,25 @@ static int *create_tcp_socket(tcpsrv_t *pThis)
* rgerhards, 2008-03-02
*/
static rsRetVal
-SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, int fd)
+SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm)
{
DEFiRet;
tcps_sess_t *pSess;
- int newConn;
+ netstrm_t *pNewStrm = NULL;
int iSess = -1;
struct sockaddr_storage addr;
- socklen_t addrlen = sizeof(struct sockaddr_storage);
- uchar fromHost[NI_MAXHOST];
- uchar fromHostFQDN[NI_MAXHOST];
+ uchar *fromHostFQDN = NULL;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- newConn = accept(fd, (struct sockaddr*) &addr, &addrlen);
- if (newConn < 0) {
- errmsg.LogError(NO_ERRCODE, "tcp accept, ignoring error and connection request");
- ABORT_FINALIZE(RS_RET_ERR); // TODO: better error code
- //was: return -1;
- }
+ CHKiRet(netstrm.AcceptConnReq(pStrm, &pNewStrm));
/* Add to session list */
iSess = TCPSessTblFindFreeSpot(pThis);
if(iSess == -1) {
errno = 0;
errmsg.LogError(NO_ERRCODE, "too many tcp sessions - dropping incoming request");
- close(newConn);
- ABORT_FINALIZE(RS_RET_ERR); // TODO: better error code
- //was: return -1;
+ ABORT_FINALIZE(RS_RET_MAX_SESS_REACHED);
} else {
/* we found a free spot and can construct our session object */
CHKiRet(tcps_sess.Construct(&pSess));
@@ -448,40 +330,28 @@ SessAccept(tcpsrv_t *pThis, tcps_sess_t **ppSess, int fd)
/* OK, we have a "good" index... */
/* get the host name */
- if(net.cvthname(&addr, fromHost, fromHostFQDN) != RS_RET_OK) {
- /* we seem to have something malicous - at least we
- * are now told to discard the connection request.
- * Error message has been generated by cvthname.
- */
- close (newConn);
- ABORT_FINALIZE(RS_RET_ERR); // TODO: better error code
- //was: return -1;
- }
+ CHKiRet(netstrm.GetRemoteHName(pStrm, &fromHostFQDN));
+ /* TODO: check if we need to strip the domain name here -- rgerhards, 2008-04-24 */
- /* Here we check if a host is permitted to send us
- * syslog messages. If it isn't, we do not further
- * process the message but log a warning (if we are
- * configured to do this).
+ /* Here we check if a host is permitted to send us messages. If it isn't, we do not further
+ * process the message but log a warning (if we are configured to do this).
* rgerhards, 2005-09-26
*/
-RUNLOG_VAR("%p", ppSess);
-RUNLOG_VAR("%p", pSess);
if(!pThis->pIsPermittedHost((struct sockaddr*) &addr, (char*) fromHostFQDN, pThis->pUsr, pSess->pUsr)) {
- dbgprintf("%s is not an allowed sender\n", (char *) fromHostFQDN);
- if(option_DisallowWarning) {
+ dbgprintf("%s is not an allowed sender\n", fromHostFQDN);
+ if(glbl.GetOption_DisallowWarning()) {
errno = 0;
- errmsg.LogError(NO_ERRCODE, "TCP message from disallowed sender %s discarded",
- (char*)fromHost);
+ errmsg.LogError(NO_ERRCODE, "TCP message from disallowed sender %s discarded", fromHostFQDN);
}
- close(newConn);
ABORT_FINALIZE(RS_RET_HOST_NOT_PERMITTED);
}
/* OK, we have an allowed sender, so let's continue, what
* means we can finally fill in the session object.
*/
- CHKiRet(tcps_sess.SetHost(pSess, fromHost));
- CHKiRet(tcps_sess.SetSock(pSess, newConn));
+ CHKiRet(tcps_sess.SetHost(pSess, fromHostFQDN));
+ CHKiRet(tcps_sess.SetStrm(pSess, pNewStrm));
+ pNewStrm = NULL; /* prevent it from being freed in error handler, now done in tcps_sess! */
CHKiRet(tcps_sess.SetMsgIdx(pSess, 0));
CHKiRet(tcps_sess.ConstructFinalize(pSess));
@@ -500,80 +370,70 @@ finalize_it:
tcps_sess.Destruct(&pThis->pSessions[iSess]);
}
iSess = -1; // TODO: change this to be fully iRet compliant ;)
+ if(pNewStrm != NULL)
+ netstrm.Destruct(&pNewStrm);
}
RETiRet;
}
-/* This function is called to gather input.
- */
+static void
+RunCancelCleanup(void *arg)
+{
+ nssel_t **ppSel = (nssel_t**) arg;
+
+ if(*ppSel != NULL)
+ nssel.Destruct(ppSel);
+}
+/* This function is called to gather input. */
static rsRetVal
Run(tcpsrv_t *pThis)
{
DEFiRet;
- int maxfds;
int nfds;
int i;
int iTCPSess;
- fd_set readfds;
+ int bIsReady;
tcps_sess_t *pNewSess;
+ nssel_t *pSel;
+ int state;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- /* this is an endless loop - it is terminated when the thread is
- * signalled to do so. This, however, is handled by the framework,
- * right into the sleep below.
+ /* this is an endless loop - it is terminated by the framework canelling
+ * this thread. Thus, we also need to instantiate a cancel cleanup handler
+ * to prevent us from leaking anything. -- rgerharsd, 20080-04-24
*/
+ pthread_cleanup_push(RunCancelCleanup, (void*) &pSel);
while(1) {
- maxfds = 0;
- FD_ZERO (&readfds);
-
- /* Add the TCP listen sockets to the list of read descriptors.
- */
- if(pThis->pSocksLstn != NULL && *pThis->pSocksLstn) {
- for (i = 0; i < *pThis->pSocksLstn; i++) {
- /* The if() below is theoretically not needed, but I leave it in
- * so that a socket may become unsuable during execution. That
- * feature is not yet supported by the current code base.
- */
- if (pThis->pSocksLstn[i+1] != -1) {
- if(Debug)
- net.debugListenInfo(pThis->pSocksLstn[i+1], "TCP");
- FD_SET(pThis->pSocksLstn[i+1], &readfds);
- if(pThis->pSocksLstn[i+1]>maxfds) maxfds=pThis->pSocksLstn[i+1];
- }
- }
- /* do the sessions */
- iTCPSess = TCPSessGetNxtSess(pThis, -1);
- while(iTCPSess != -1) {
- int fdSess;
- fdSess = pThis->pSessions[iTCPSess]->sock; // TODO: NOT CLEAN!, use method
- dbgprintf("Adding TCP Session %d\n", fdSess);
- FD_SET(fdSess, &readfds);
- if (fdSess>maxfds) maxfds=fdSess;
- /* now get next... */
- iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
- }
+ CHKiRet(nssel.Construct(&pSel));
+ // TODO: set driver
+ CHKiRet(nssel.ConstructFinalize(pSel));
+
+ /* Add the TCP listen sockets to the list of read descriptors. */
+ for(i = 0 ; i < pThis->iLstnMax ; ++i) {
+RUNLOG_VAR("%d", i);
+ CHKiRet(nssel.Add(pSel, pThis->ppLstn[i], NSDSEL_RD));
}
- if(Debug) {
- // TODO: name in dbgprintf!
- dbgprintf("--------<TCPSRV> calling select, active file descriptors (max %d): ", maxfds);
- for (nfds = 0; nfds <= maxfds; ++nfds)
- if ( FD_ISSET(nfds, &readfds) )
- dbgprintf("%d ", nfds);
- dbgprintf("\n");
+ /* do the sessions */
+ iTCPSess = TCPSessGetNxtSess(pThis, -1);
+ while(iTCPSess != -1) {
+ /* TODO: access to pNsd is NOT really CLEAN, use method... */
+ CHKiRet(nssel.Add(pSel, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD));
+ /* now get next... */
+ iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
}
/* wait for io to become ready */
- nfds = select(maxfds+1, (fd_set *) &readfds, NULL, NULL, NULL);
+ CHKiRet(nssel.Wait(pSel, &nfds));
- for (i = 0; i < *pThis->pSocksLstn; i++) {
- if (FD_ISSET(pThis->pSocksLstn[i+1], &readfds)) {
- dbgprintf("New connect on TCP inetd socket: #%d\n", pThis->pSocksLstn[i+1]);
-RUNLOG_VAR("%p", &pNewSess);
- SessAccept(pThis, &pNewSess, pThis->pSocksLstn[i+1]);
+ for(i = 0 ; i < pThis->iLstnMax ; ++i) {
+ CHKiRet(nssel.IsReady(pSel, pThis->ppLstn[i], NSDSEL_RD, &bIsReady, &nfds));
+ if(bIsReady) {
+ dbgprintf("New connect on NSD %p.\n", pThis->ppLstn[i]);
+ SessAccept(pThis, &pNewSess, pThis->ppLstn[i]);
--nfds; /* indicate we have processed one */
}
}
@@ -581,12 +441,10 @@ RUNLOG_VAR("%p", &pNewSess);
/* now check the sessions */
iTCPSess = TCPSessGetNxtSess(pThis, -1);
while(nfds && iTCPSess != -1) {
- int fdSess;
- int state;
- fdSess = pThis->pSessions[iTCPSess]->sock; // TODO: not clean, use method
- if(FD_ISSET(fdSess, &readfds)) {
+ CHKiRet(nssel.IsReady(pSel, pThis->pSessions[iTCPSess]->pStrm, NSDSEL_RD, &bIsReady, &nfds));
+ if(bIsReady) {
char buf[MAXLINE];
- dbgprintf("tcp session socket with new data: #%d\n", fdSess);
+ dbgprintf("netstream %p with new data\n", pThis->pSessions[iTCPSess]->pStrm);
/* Receive message */
state = pThis->pRcvData(pThis->pSessions[iTCPSess], buf, sizeof(buf));
@@ -594,7 +452,8 @@ RUNLOG_VAR("%p", &pNewSess);
pThis->pOnRegularClose(pThis->pSessions[iTCPSess]);
tcps_sess.Destruct(&pThis->pSessions[iTCPSess]);
} else if(state == -1) {
- errmsg.LogError(NO_ERRCODE, "TCP session %d will be closed, error ignored\n", fdSess);
+ errmsg.LogError(NO_ERRCODE, "netstream session %p will be closed, error ignored\n",
+ pThis->pSessions[iTCPSess]->pStrm);
pThis->pOnErrClose(pThis->pSessions[iTCPSess]);
tcps_sess.Destruct(&pThis->pSessions[iTCPSess]);
} else {
@@ -613,29 +472,44 @@ RUNLOG_VAR("%p", &pNewSess);
}
iTCPSess = TCPSessGetNxtSess(pThis, iTCPSess);
}
+ CHKiRet(nssel.Destruct(&pSel));
}
+ /* note that this point is usually not reached */
+ pthread_cleanup_pop(0); /* remove cleanup handler */
+
+finalize_it: // TODO: think: is it really good to exit the loop?
RETiRet;
}
-/* Standard-Constructor
- */
+/* Standard-Constructor */
BEGINobjConstruct(tcpsrv) /* be sure to specify the object type also in END macro! */
- pThis->pSocksLstn = NULL;
- pThis->iSessMax = 200; /* TODO: useful default ;) */
+ pThis->iSessMax = TCPSESS_MAX_DEFAULT; /* TODO: useful default ;) */
ENDobjConstruct(tcpsrv)
-/* ConstructionFinalizer
- */
+/* ConstructionFinalizer */
static rsRetVal
-tcpsrvConstructFinalize(tcpsrv_t __attribute__((unused)) *pThis)
+tcpsrvConstructFinalize(tcpsrv_t *pThis)
{
DEFiRet;
ISOBJ_TYPE_assert(pThis, tcpsrv);
- pThis->pSocksLstn = pThis->OpenLstnSocks(pThis);
+ /* prepare network stream subsystem */
+ CHKiRet(netstrms.Construct(&pThis->pNS));
+ // TODO: set driver!
+ CHKiRet(netstrms.ConstructFinalize(pThis->pNS));
+
+ /* set up listeners */
+ CHKmalloc(pThis->ppLstn = calloc(TCPLSTN_MAX_DEFAULT, sizeof(netstrm_t*)));
+ iRet = pThis->OpenLstnSocks(pThis);
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pThis->pNS != NULL)
+ netstrms.Destruct(&pThis->pNS);
+ }
RETiRet;
}
@@ -647,6 +521,11 @@ CODESTARTobjDestruct(tcpsrv)
pThis->OnDestruct(pThis->pUsr);
deinit_tcp_listener(pThis);
+
+ if(pThis->pNS != NULL)
+ netstrms.Destruct(&pThis->pNS);
+ if(pThis->ppLstn != NULL)
+ free(pThis->ppLstn);
ENDobjDestruct(tcpsrv)
@@ -729,7 +608,7 @@ SetCBOnErrClose(tcpsrv_t *pThis, rsRetVal (*pCB)(tcps_sess_t*))
}
static rsRetVal
-SetCBOpenLstnSocks(tcpsrv_t *pThis, int* (*pCB)(tcpsrv_t*))
+SetCBOpenLstnSocks(tcpsrv_t *pThis, rsRetVal (*pCB)(tcpsrv_t*))
{
DEFiRet;
pThis->OpenLstnSocks = pCB;
@@ -793,7 +672,11 @@ CODESTARTObjClassExit(tcpsrv)
/* release objects we no longer need */
objRelease(tcps_sess, DONT_LOAD_LIB);
objRelease(conf, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
objRelease(errmsg, CORE_COMPONENT);
+ objRelease(nssel, LM_NSSEL_FILENAME);
+ objRelease(netstrm, LM_NETSTRM_FILENAME);
+ objRelease(netstrms, LM_NETSTRMS_FILENAME);
objRelease(net, LM_NET_FILENAME);
ENDObjClassExit(tcpsrv)
@@ -806,8 +689,12 @@ BEGINObjClassInit(tcpsrv, 1, OBJ_IS_LOADABLE_MODULE) /* class, version - CHANGE
/* request objects we use */
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(net, LM_NET_FILENAME));
+ CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
+ CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
+ CHKiRet(objUse(nssel, LM_NSSEL_FILENAME));
CHKiRet(objUse(tcps_sess, DONT_LOAD_LIB));
CHKiRet(objUse(conf, CORE_COMPONENT));
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
/* set our own handlers */
OBJSetMethodHandler(objMethod_DEBUGPRINT, tcpsrvDebugPrint);
diff --git a/tcpsrv.h b/tcpsrv.h
index 20a7ea25..ada77aec 100644
--- a/tcpsrv.h
+++ b/tcpsrv.h
@@ -26,9 +26,11 @@
#include "tcps_sess.h"
/* the tcpsrv object */
-typedef struct tcpsrv_s {
+struct tcpsrv_s {
BEGINobjInstance; /**< Data to implement generic object - MUST be the first data element! */
- int *pSocksLstn; /**< listen socket array for server [0] holds count */
+ netstrms_t *pNS; /**< pointer to network stream subsystem */
+ int iLstnMax; /**< max nbr of listeners currently supported */
+ netstrm_t **ppLstn; /**< our netstream listners */
int iSessMax; /**< max number of sessions supported */
char *TCPLstnPort; /**< the port the listener shall listen on */
tcps_sess_t **pSessions;/**< array of all of our sessions */
@@ -36,16 +38,16 @@ typedef struct tcpsrv_s {
/* callbacks */
int (*pIsPermittedHost)(struct sockaddr *addr, char *fromHostFQDN, void*pUsrSrv, void*pUsrSess);
int (*pRcvData)(tcps_sess_t*, char*, size_t);
- int* (*OpenLstnSocks)(struct tcpsrv_s*);
+ rsRetVal (*OpenLstnSocks)(struct tcpsrv_s*);
rsRetVal (*pOnListenDeinit)(void*);
rsRetVal (*OnDestruct)(void*);
rsRetVal (*pOnRegularClose)(tcps_sess_t *pSess);
rsRetVal (*pOnErrClose)(tcps_sess_t *pSess);
/* session specific callbacks */
- rsRetVal (*pOnSessAccept)(struct tcpsrv_s *, tcps_sess_t*);
+ rsRetVal (*pOnSessAccept)(tcpsrv_t *, tcps_sess_t*);
rsRetVal (*OnSessConstructFinalize)(void*);
rsRetVal (*pOnSessDestruct)(void*);
-} tcpsrv_t;
+};
/* interfaces */
@@ -55,13 +57,13 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
rsRetVal (*ConstructFinalize)(tcpsrv_t __attribute__((unused)) *pThis);
rsRetVal (*Destruct)(tcpsrv_t **ppThis);
void (*configureTCPListen)(tcpsrv_t*, char *cOptarg);
- int (*SessAccept)(tcpsrv_t *pThis, tcps_sess_t**ppSess, int fd);
- int* (*create_tcp_socket)(tcpsrv_t *pThis);
+ rsRetVal (*SessAccept)(tcpsrv_t *pThis, tcps_sess_t **ppSess, netstrm_t *pStrm);
+ rsRetVal (*create_tcp_socket)(tcpsrv_t *pThis);
rsRetVal (*Run)(tcpsrv_t *pThis);
/* set methods */
rsRetVal (*SetUsrP)(tcpsrv_t*, void*);
rsRetVal (*SetCBIsPermittedHost)(tcpsrv_t*, int (*) (struct sockaddr *addr, char*, void*, void*));
- rsRetVal (*SetCBOpenLstnSocks)(tcpsrv_t *, int* (*)(tcpsrv_t*));
+ rsRetVal (*SetCBOpenLstnSocks)(tcpsrv_t *, rsRetVal (*)(tcpsrv_t*));
rsRetVal (*SetCBRcvData)(tcpsrv_t *, int (*)(tcps_sess_t*, char*, size_t));
rsRetVal (*SetCBOnListenDeinit)(tcpsrv_t*, rsRetVal (*)(void*));
rsRetVal (*SetCBOnDestruct)(tcpsrv_t*, rsRetVal (*) (void*));
@@ -72,7 +74,7 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
rsRetVal (*SetCBOnSessDestruct)(tcpsrv_t*, rsRetVal (*) (void*));
rsRetVal (*SetCBOnSessConstructFinalize)(tcpsrv_t*, rsRetVal (*) (void*));
ENDinterface(tcpsrv)
-#define tcpsrvCURR_IF_VERSION 1 /* increment whenever you change the interface structure! */
+#define tcpsrvCURR_IF_VERSION 2 /* increment whenever you change the interface structure! */
/* prototypes */
diff --git a/tcpsyslog.c b/tcpsyslog.c
deleted file mode 100644
index d00731d3..00000000
--- a/tcpsyslog.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* tcpsyslog.c
- * This is the implementation of TCP-based syslog. It includes those
- * (few) things that both clients and servers need.
- *
- * File begun on 2007-07-20 by RGerhards (extracted from syslogd.c)
- * This file is under development and has not yet arrived at being fully
- * self-contained and a real object. So far, it is mostly an excerpt
- * of the "old" message code without any modifications. However, it
- * helps to have things at the right place one we go to the meat of it.
- *
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#include "config.h"
-#include "rsyslog.h"
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
-#include <assert.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#if HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#include "syslogd.h"
-#include "syslogd-types.h"
-#include "net.h"
-#include "tcpsyslog.h"
-#include "srUtils.h"
-
-
-/* vi:set ai:
- */
diff --git a/tcpsyslog.h b/tcpsyslog.h
deleted file mode 100644
index 13c40a92..00000000
--- a/tcpsyslog.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* tcpsyslog.h
- * These are the definitions for TCP-based syslog.
- *
- * File begun on 2007-07-21 by RGerhards (extracted from syslogd.c)
- *
- * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
- *
- * This file is part of rsyslog.
- *
- * Rsyslog is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Rsyslog is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
- *
- * A copy of the GPL can be found in the file "COPYING" in this distribution.
- */
-#ifndef TCPSYSLOG_H_INCLUDED
-#define TCPSYSLOG_H_INCLUDED 1
-
-#include <netdb.h>
-
-typedef enum _TCPFRAMINGMODE {
- TCP_FRAMING_OCTET_STUFFING = 0, /* traditional LF-delimited */
- TCP_FRAMING_OCTET_COUNTING = 1 /* -transport-tls like octet count */
- } TCPFRAMINGMODE;
-
-#endif /* #ifndef TCPSYSLOG_H_INCLUDED */
-/*
- * vi:set ai:
- */
diff --git a/template.c b/template.c
index 844c5aec..e5021f35 100644
--- a/template.c
+++ b/template.c
@@ -33,7 +33,7 @@
#include "syslogd-types.h"
#include "template.h"
#include "msg.h"
-#include "syslogd.h"
+#include "dirty.h"
#include "obj.h"
#include "errmsg.h"
diff --git a/threads.c b/threads.c
index e32ff0d9..f4f604fc 100644
--- a/threads.c
+++ b/threads.c
@@ -33,7 +33,7 @@
#include <assert.h>
#include "rsyslog.h"
-#include "syslogd.h"
+#include "dirty.h"
#include "linkedlist.h"
#include "threads.h"
diff --git a/threads.h b/threads.h
index aa6a5c28..78924d95 100644
--- a/threads.h
+++ b/threads.h
@@ -23,16 +23,15 @@
#ifndef THREADS_H_INCLUDED
#define THREADS_H_INCLUDED
-
/* the thread object */
-typedef struct thrdInfo {
+struct thrdInfo {
pthread_mutex_t *mutTermOK; /* Is it ok to terminate that thread now? */
int bIsActive; /* Is thread running? */
int bShallStop; /* set to 1 if the thread should be stopped ? */
rsRetVal (*pUsrThrdMain)(struct thrdInfo*); /* user thread main to be called in new thread */
rsRetVal (*pAfterRun)(struct thrdInfo*); /* cleanup function */
pthread_t thrdID;
-} thrdInfo_t;
+};
/* prototypes */
rsRetVal thrdExit(void);
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 00000000..f00abf0b
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,42 @@
+sbin_PROGRAMS =
+man_MANS =
+
+sbin_PROGRAMS += rsyslogd
+rsyslogd_SOURCES = \
+ syslogd.c \
+ syslogd.h \
+ omshell.c \
+ omshell.h \
+ omusrmsg.c \
+ omusrmsg.h \
+ omfwd.c \
+ omfwd.h \
+ omfile.c \
+ omfile.h \
+ omdiscard.c \
+ omdiscard.h \
+ iminternal.c \
+ iminternal.h \
+ pidfile.c \
+ pidfile.h \
+ \
+ ../action.h \
+ ../action.c \
+ ../threads.c \
+ ../threads.h \
+ \
+ ../parse.c \
+ ../parse.h \
+ \
+ ../outchannel.c \
+ ../outchannel.h \
+ ../template.c \
+ ../template.h \
+ ../conf.c \
+ ../conf.h
+
+rsyslogd_CPPFLAGS = $(pthreads_cflags) $(rsrt_cflags)
+rsyslogd_LDADD = $(zlib_libs) $(pthreads_libs) $(dl_libs) $(rt_libs) $(rsrt_libs)
+rsyslogd_LDFLAGS = -export-dynamic
+
+man_MANS += rsyslogd.8 rsyslog.conf.5
diff --git a/iminternal.c b/tools/iminternal.c
index 60460a99..60460a99 100644
--- a/iminternal.c
+++ b/tools/iminternal.c
diff --git a/iminternal.h b/tools/iminternal.h
index 8dc0f171..8dc0f171 100644
--- a/iminternal.h
+++ b/tools/iminternal.h
diff --git a/omdiscard.c b/tools/omdiscard.c
index f13144e8..f13144e8 100644
--- a/omdiscard.c
+++ b/tools/omdiscard.c
diff --git a/omdiscard.h b/tools/omdiscard.h
index 116308a4..116308a4 100644
--- a/omdiscard.h
+++ b/tools/omdiscard.h
diff --git a/omfile.c b/tools/omfile.c
index 6a53a723..4b5eb280 100644
--- a/omfile.c
+++ b/tools/omfile.c
@@ -85,6 +85,7 @@ static int bEnableSync = 0;/* enable syncing of files (no dash in front of pathn
static uchar *pszTplName = NULL; /* name of the default template to use */
/* end globals for default values */
+
typedef struct _instanceData {
uchar f_fname[MAXFNAME];/* file or template name (display only) */
short fd; /* file descriptor for (current) file */
@@ -280,7 +281,6 @@ int resolveFileSizeLimit(instanceData *pData)
*/
if((pCmd = (uchar*)strdup((char*)pData->f_sizeLimitCmd)) == NULL) {
/* there is not much we can do - we make syslogd close the file in this case */
- glblHadMemShortage = 1;
return 1;
}
@@ -480,7 +480,6 @@ static int prepareDynFile(instanceData *pData, uchar *newFileName, unsigned iMsg
/* we need to allocate memory for the cache structure */
pCache[iFirstFree] = (dynaFileCacheEntry*) calloc(1, sizeof(dynaFileCacheEntry));
if(pCache[iFirstFree] == NULL) {
- glblHadMemShortage = TRUE;
dbgprintf("prepareDynfile(): could not alloc mem, discarding this request\n");
return -1;
}
@@ -775,7 +774,7 @@ CODESTARTparseSelectorAct
pData->fileType = eTypeTTY;
untty();
}
- if (strcmp((char*) p, ctty) == 0)
+ if (strcmp((char*) p, _PATH_CONSOLE) == 0)
pData->fileType = eTypeCONSOLE;
break;
default:
diff --git a/omfile.h b/tools/omfile.h
index 03e081f3..03e081f3 100644
--- a/omfile.h
+++ b/tools/omfile.h
diff --git a/tools/omfwd.c b/tools/omfwd.c
new file mode 100644
index 00000000..719075c7
--- /dev/null
+++ b/tools/omfwd.c
@@ -0,0 +1,625 @@
+/* omfwd.c
+ * This is the implementation of the build-in forwarding output module.
+ *
+ * NOTE: read comments in module-template.h to understand how this file
+ * works!
+ *
+ * File begun on 2007-07-20 by RGerhards (extracted from syslogd.c)
+ * This file is under development and has not yet arrived at being fully
+ * self-contained and a real object. So far, it is mostly an excerpt
+ * of the "old" message code without any modifications. However, it
+ * helps to have things at the right place one we go to the meat of it.
+ *
+ * Copyright 2007 Rainer Gerhards and Adiscon GmbH.
+ *
+ * This file is part of rsyslog.
+ *
+ * Rsyslog is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Rsyslog is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+#include "rsyslog.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <fnmatch.h>
+#include <assert.h>
+#include <errno.h>
+#include <ctype.h>
+#include <unistd.h>
+#ifdef USE_NETZIP
+#include <zlib.h>
+#endif
+#include <pthread.h>
+#include "syslogd.h"
+#include "syslogd-types.h"
+#include "srUtils.h"
+#include "net.h"
+#include "netstrms.h"
+#include "netstrm.h"
+#include "omfwd.h"
+#include "template.h"
+#include "msg.h"
+#include "tcpclt.h"
+#include "cfsysline.h"
+#include "module-template.h"
+#include "glbl.h"
+#include "errmsg.h"
+
+MODULE_TYPE_OUTPUT
+
+/* internal structures
+ */
+DEF_OMOD_STATIC_DATA
+DEFobjCurrIf(errmsg)
+DEFobjCurrIf(glbl)
+DEFobjCurrIf(net)
+DEFobjCurrIf(netstrms)
+DEFobjCurrIf(netstrm)
+DEFobjCurrIf(tcpclt)
+
+typedef struct _instanceData {
+ netstrms_t *pNS; /* netstream subsystem */
+ netstrm_t *pNetstrm; /* our output netstream */
+ char *f_hname;
+ int *pSockArray; /* sockets to use for UDP */
+ int bIsConnected; /* are we connected to remote host? 0 - no, 1 - yes, UDP means addr resolved */
+ struct addrinfo *f_addr;
+ int compressionLevel; /* 0 - no compression, else level for zlib */
+ char *port;
+ int protocol;
+# define FORW_UDP 0
+# define FORW_TCP 1
+ /* following fields for TCP-based delivery */
+ tcpclt_t *pTCPClt; /* our tcpclt object */
+} instanceData;
+
+/* config data */
+static uchar *pszTplName = NULL; /* name of the default template to use */
+
+
+/* get the syslog forward port from selector_t. The passed in
+ * struct must be one that is setup for forwarding.
+ * rgerhards, 2007-06-28
+ * We may change the implementation to try to lookup the port
+ * if it is unspecified. So far, we use the IANA default auf 514.
+ */
+static char *getFwdPt(instanceData *pData)
+{
+ assert(pData != NULL);
+ if(pData->port == NULL)
+ return("514");
+ else
+ return(pData->port);
+}
+
+BEGINcreateInstance
+CODESTARTcreateInstance
+ENDcreateInstance
+
+
+BEGINisCompatibleWithFeature
+CODESTARTisCompatibleWithFeature
+ if(eFeat == sFEATURERepeatedMsgReduction)
+ iRet = RS_RET_OK;
+ENDisCompatibleWithFeature
+
+
+BEGINfreeInstance
+CODESTARTfreeInstance
+ if(pData->f_addr != NULL) { /* TODO: is the check ok? */
+ freeaddrinfo(pData->f_addr);
+ pData->f_addr = NULL;
+ }
+ if(pData->port != NULL)
+ free(pData->port);
+
+ /* final cleanup */
+ if(pData->pNetstrm != NULL)
+ netstrm.Destruct(&pData->pNetstrm);
+ if(pData->pSockArray != NULL)
+ net.closeUDPListenSockets(pData->pSockArray);
+
+ if(pData->protocol == FORW_TCP) {
+ tcpclt.Destruct(&pData->pTCPClt);
+ }
+
+ if(pData->f_hname != NULL)
+ free(pData->f_hname);
+
+ENDfreeInstance
+
+
+BEGINdbgPrintInstInfo
+CODESTARTdbgPrintInstInfo
+ printf("%s", pData->f_hname);
+ENDdbgPrintInstInfo
+
+
+/* Send a message via UDP
+ * rgehards, 2007-12-20
+ */
+static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len)
+{
+ DEFiRet;
+ struct addrinfo *r;
+ int i;
+ unsigned lsent = 0;
+ int bSendSuccess;
+
+ if(pData->pSockArray != NULL) {
+ /* we need to track if we have success sending to the remote
+ * peer. Success is indicated by at least one sendto() call
+ * succeeding. We track this be bSendSuccess. We can not simply
+ * rely on lsent, as a call might initially work, but a later
+ * call fails. Then, lsent has the error status, even though
+ * the sendto() succeeded. -- rgerhards, 2007-06-22
+ */
+ bSendSuccess = FALSE;
+ for (r = pData->f_addr; r; r = r->ai_next) {
+ for (i = 0; i < *pData->pSockArray; i++) {
+ lsent = sendto(pData->pSockArray[i+1], msg, len, 0, r->ai_addr, r->ai_addrlen);
+ if (lsent == len) {
+ bSendSuccess = TRUE;
+ break;
+ } else {
+ int eno = errno;
+ char errStr[1024];
+ dbgprintf("sendto() error: %d = %s.\n",
+ eno, rs_strerror_r(eno, errStr, sizeof(errStr)));
+ }
+ }
+ if (lsent == len && !send_to_all)
+ break;
+ }
+ /* finished looping */
+ if (bSendSuccess == FALSE) {
+ dbgprintf("error forwarding via udp, suspending\n");
+ iRet = RS_RET_SUSPENDED;
+ }
+ }
+
+ RETiRet;
+}
+
+
+/* CODE FOR SENDING TCP MESSAGES */
+
+
+/* Send a frame via plain TCP protocol
+ * rgerhards, 2007-12-28
+ */
+static rsRetVal TCPSendFrame(void *pvData, char *msg, size_t len)
+{
+ DEFiRet;
+ ssize_t lenSend;
+ instanceData *pData = (instanceData *) pvData;
+
+ lenSend = len;
+ CHKiRet(netstrm.Send(pData->pNetstrm, (uchar*)msg, &lenSend));
+ dbgprintf("TCP sent %ld bytes, requested %ld\n", (long) lenSend, (long) len);
+
+ if(lenSend != (ssize_t) len) {
+ /* no real error, could "just" not send everything...
+ * For the time being, we ignore this...
+ * rgerhards, 2005-10-25
+ */
+ dbgprintf("message not completely (tcp)send, ignoring %ld\n", (long) lenSend);
+ usleep(1000); /* experimental - might be benefitial in this situation */
+ /* TODO: we need to revisit this code -- rgerhards, 2007-12-28 */
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+
+/* This function is called immediately before a send retry is attempted.
+ * It shall clean up whatever makes sense.
+ * rgerhards, 2007-12-28
+ */
+static rsRetVal TCPSendPrepRetry(void *pvData)
+{
+ DEFiRet;
+ instanceData *pData = (instanceData *) pvData;
+
+ assert(pData != NULL);
+ netstrm.Destruct(&pData->pNetstrm);
+ RETiRet;
+}
+
+
+/* initializes everything so that TCPSend can work.
+ * rgerhards, 2007-12-28
+ */
+static rsRetVal TCPSendInit(void *pvData)
+{
+ DEFiRet;
+ instanceData *pData = (instanceData *) pvData;
+
+ assert(pData != NULL);
+ if(pData->pNetstrm == NULL) {
+ CHKiRet(netstrms.Construct(&pData->pNS));
+ /* here we may set another netstream driver (e.g. to do TLS) */
+ CHKiRet(netstrms.ConstructFinalize(pData->pNS));
+
+ /* now create the actual stream and connect to the server */
+ CHKiRet(netstrms.CreateStrm(pData->pNS, &pData->pNetstrm));
+ CHKiRet(netstrm.ConstructFinalize(pData->pNetstrm));
+ CHKiRet(netstrm.Connect(pData->pNetstrm, glbl.GetDefPFFamily(),
+ (uchar*)pData->port, (uchar*)pData->f_hname));
+ }
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pData->pNetstrm != NULL)
+ netstrm.Destruct(&pData->pNetstrm);
+ if(pData->pNS != NULL)
+ netstrms.Destruct(&pData->pNS);
+ }
+
+ RETiRet;
+}
+
+
+/* try to resume connection if it is not ready
+ * rgerhards, 2007-08-02
+ */
+static rsRetVal doTryResume(instanceData *pData)
+{
+ DEFiRet;
+ struct addrinfo *res;
+ struct addrinfo hints;
+
+ if(pData->bIsConnected)
+ FINALIZE;
+
+ /* The remote address is not yet known and needs to be obtained */
+ dbgprintf(" %s\n", pData->f_hname);
+ if(pData->protocol == FORW_UDP) {
+ memset(&hints, 0, sizeof(hints));
+ /* port must be numeric, because config file syntax requires this */
+ hints.ai_flags = AI_NUMERICSERV;
+ hints.ai_family = glbl.GetDefPFFamily();
+ hints.ai_socktype = pData->protocol == SOCK_DGRAM;
+ if((getaddrinfo(pData->f_hname, getFwdPt(pData), &hints, &res)) != 0) {
+ ABORT_FINALIZE(RS_RET_SUSPENDED);
+ }
+ dbgprintf("%s found, resuming.\n", pData->f_hname);
+ pData->f_addr = res;
+ pData->bIsConnected = 1;
+ if(pData->pSockArray == NULL) {
+ pData->pSockArray = net.create_udp_socket((uchar*)pData->f_hname, NULL, 0);
+ }
+ } else {
+ CHKiRet(TCPSendInit((void*)pData));
+ }
+
+finalize_it:
+ if(iRet != RS_RET_OK) {
+ if(pData->f_addr != NULL) {
+ freeaddrinfo(pData->f_addr);
+ pData->f_addr = NULL;
+ }
+ iRet = RS_RET_SUSPENDED;
+ }
+
+ RETiRet;
+}
+
+
+BEGINtryResume
+CODESTARTtryResume
+ iRet = doTryResume(pData);
+ENDtryResume
+
+BEGINdoAction
+ char *psz; /* temporary buffering */
+ register unsigned l;
+CODESTARTdoAction
+ CHKiRet(doTryResume(pData));
+
+ dbgprintf(" %s:%s/%s\n", pData->f_hname, getFwdPt(pData),
+ pData->protocol == FORW_UDP ? "udp" : "tcp");
+
+ psz = (char*) ppString[0];
+ l = strlen((char*) psz);
+ if (l > MAXLINE)
+ l = MAXLINE;
+
+# ifdef USE_NETZIP
+ /* Check if we should compress and, if so, do it. We also
+ * check if the message is large enough to justify compression.
+ * The smaller the message, the less likely is a gain in compression.
+ * To save CPU cycles, we do not try to compress very small messages.
+ * What "very small" means needs to be configured. Currently, it is
+ * hard-coded but this may be changed to a config parameter.
+ * rgerhards, 2006-11-30
+ */
+ if(pData->compressionLevel && (l > MIN_SIZE_FOR_COMPRESS)) {
+ Bytef out[MAXLINE+MAXLINE/100+12] = "z";
+ uLongf destLen = sizeof(out) / sizeof(Bytef);
+ uLong srcLen = l;
+ int ret;
+ ret = compress2((Bytef*) out+1, &destLen, (Bytef*) psz,
+ srcLen, pData->compressionLevel);
+ dbgprintf("Compressing message, length was %d now %d, return state %d.\n",
+ l, (int) destLen, ret);
+ if(ret != Z_OK) {
+ /* if we fail, we complain, but only in debug mode
+ * Otherwise, we are silent. In any case, we ignore the
+ * failed compression and just sent the uncompressed
+ * data, which is still valid. So this is probably the
+ * best course of action.
+ * rgerhards, 2006-11-30
+ */
+ dbgprintf("Compression failed, sending uncompressed message\n");
+ } else if(destLen+1 < l) {
+ /* only use compression if there is a gain in using it! */
+ dbgprintf("there is gain in compression, so we do it\n");
+ psz = (char*) out;
+ l = destLen + 1; /* take care for the "z" at message start! */
+ }
+ ++destLen;
+ }
+# endif
+
+ if(pData->protocol == FORW_UDP) {
+ /* forward via UDP */
+ CHKiRet(UDPSend(pData, psz, l));
+ } else {
+ /* forward via TCP */
+ rsRetVal ret;
+ ret = tcpclt.Send(pData->pTCPClt, pData, psz, l);
+ if(ret != RS_RET_OK) {
+ /* error! */
+ dbgprintf("error forwarding via tcp, suspending\n");
+ iRet = RS_RET_SUSPENDED;
+ }
+ }
+finalize_it:
+ENDdoAction
+
+
+/* This function loads TCP support, if not already loaded. It will be called
+ * during config processing. To server ressources, TCP support will only
+ * be loaded if it actually is used. -- rgerhard, 2008-04-17
+ */
+static rsRetVal
+loadTCPSupport(void)
+{
+ DEFiRet;
+ if(!netstrms.ifIsLoaded)
+ CHKiRet(objUse(netstrms, LM_NETSTRMS_FILENAME));
+ if(!netstrm.ifIsLoaded)
+ CHKiRet(objUse(netstrm, LM_NETSTRM_FILENAME));
+ if(!tcpclt.ifIsLoaded)
+ CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME));
+
+finalize_it:
+ RETiRet;
+}
+
+
+BEGINparseSelectorAct
+ uchar *q;
+ int i;
+ int bErr;
+ rsRetVal localRet;
+ struct addrinfo;
+ TCPFRAMINGMODE tcp_framing = TCP_FRAMING_OCTET_STUFFING;
+CODESTARTparseSelectorAct
+CODE_STD_STRING_REQUESTparseSelectorAct(1)
+ if(*p != '@')
+ ABORT_FINALIZE(RS_RET_CONFLINE_UNPROCESSED);
+
+ CHKiRet(createInstance(&pData));
+
+ ++p; /* eat '@' */
+ if(*p == '@') { /* indicator for TCP! */
+ localRet = loadTCPSupport();
+ if(localRet != RS_RET_OK) {
+ errmsg.LogError(NO_ERRCODE, "could not activate network stream modules for TCP "
+ "(internal error %d) - are modules missing?", localRet);
+ ABORT_FINALIZE(localRet);
+ }
+ pData->protocol = FORW_TCP;
+ ++p; /* eat this '@', too */
+ } else {
+ pData->protocol = FORW_UDP;
+ }
+ /* we are now after the protocol indicator. Now check if we should
+ * use compression. We begin to use a new option format for this:
+ * @(option,option)host:port
+ * The first option defined is "z[0..9]" where the digit indicates
+ * the compression level. If it is not given, 9 (best compression) is
+ * assumed. An example action statement might be:
+ * @@(z5,o)127.0.0.1:1400
+ * Which means send via TCP with medium (5) compresion (z) to the local
+ * host on port 1400. The '0' option means that octet-couting (as in
+ * IETF I-D syslog-transport-tls) is to be used for framing (this option
+ * applies to TCP-based syslog only and is ignored when specified with UDP).
+ * That is not yet implemented.
+ * rgerhards, 2006-12-07
+ */
+ if(*p == '(') {
+ /* at this position, it *must* be an option indicator */
+ do {
+ ++p; /* eat '(' or ',' (depending on when called) */
+ /* check options */
+ if(*p == 'z') { /* compression */
+# ifdef USE_NETZIP
+ ++p; /* eat */
+ if(isdigit((int) *p)) {
+ int iLevel;
+ iLevel = *p - '0';
+ ++p; /* eat */
+ pData->compressionLevel = iLevel;
+ } else {
+ errmsg.LogError(NO_ERRCODE, "Invalid compression level '%c' specified in "
+ "forwardig action - NOT turning on compression.",
+ *p);
+ }
+# else
+ errmsg.LogError(NO_ERRCODE, "Compression requested, but rsyslogd is not compiled "
+ "with compression support - request ignored.");
+# endif /* #ifdef USE_NETZIP */
+ } else if(*p == 'o') { /* octet-couting based TCP framing? */
+ ++p; /* eat */
+ /* no further options settable */
+ tcp_framing = TCP_FRAMING_OCTET_COUNTING;
+ } else { /* invalid option! Just skip it... */
+ errmsg.LogError(NO_ERRCODE, "Invalid option %c in forwarding action - ignoring.", *p);
+ ++p; /* eat invalid option */
+ }
+ /* the option processing is done. We now do a generic skip
+ * to either the next option or the end of the option
+ * block.
+ */
+ while(*p && *p != ')' && *p != ',')
+ ++p; /* just skip it */
+ } while(*p && *p == ','); /* Attention: do.. while() */
+ if(*p == ')')
+ ++p; /* eat terminator, on to next */
+ else
+ /* we probably have end of string - leave it for the rest
+ * of the code to handle it (but warn the user)
+ */
+ errmsg.LogError(NO_ERRCODE, "Option block not terminated in forwarding action.");
+ }
+ /* extract the host first (we do a trick - we replace the ';' or ':' with a '\0')
+ * now skip to port and then template name. rgerhards 2005-07-06
+ */
+ for(q = p ; *p && *p != ';' && *p != ':' ; ++p)
+ /* JUST SKIP */;
+
+ pData->port = NULL;
+ if(*p == ':') { /* process port */
+ uchar * tmp;
+
+ *p = '\0'; /* trick to obtain hostname (later)! */
+ tmp = ++p;
+ for(i=0 ; *p && isdigit((int) *p) ; ++p, ++i)
+ /* SKIP AND COUNT */;
+ pData->port = malloc(i + 1);
+ if(pData->port == NULL) {
+ errmsg.LogError(NO_ERRCODE, "Could not get memory to store syslog forwarding port, "
+ "using default port, results may not be what you intend\n");
+ /* we leave f_forw.port set to NULL, this is then handled by getFwdPt(). */
+ } else {
+ memcpy(pData->port, tmp, i);
+ *(pData->port + i) = '\0';
+ }
+ }
+
+ /* now skip to template */
+ bErr = 0;
+ while(*p && *p != ';') {
+ if(*p && *p != ';' && !isspace((int) *p)) {
+ if(bErr == 0) { /* only 1 error msg! */
+ bErr = 1;
+ errno = 0;
+ errmsg.LogError(NO_ERRCODE, "invalid selector line (port), probably not doing "
+ "what was intended");
+ }
+ }
+ ++p;
+ }
+
+ /* TODO: make this if go away! */
+ if(*p == ';') {
+ *p = '\0'; /* trick to obtain hostname (later)! */
+ CHKmalloc(pData->f_hname = strdup((char*) q));
+ *p = ';';
+ } else {
+ CHKmalloc(pData->f_hname = strdup((char*) q));
+ }
+
+ /* process template */
+ CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS,
+ (pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : pszTplName));
+
+ if(pData->protocol == FORW_TCP) {
+ /* create our tcpclt */
+ CHKiRet(tcpclt.Construct(&pData->pTCPClt));
+ /* and set callbacks */
+ CHKiRet(tcpclt.SetSendInit(pData->pTCPClt, TCPSendInit));
+ CHKiRet(tcpclt.SetSendFrame(pData->pTCPClt, TCPSendFrame));
+ CHKiRet(tcpclt.SetSendPrepRetry(pData->pTCPClt, TCPSendPrepRetry));
+ CHKiRet(tcpclt.SetFraming(pData->pTCPClt, tcp_framing));
+ }
+
+CODE_STD_FINALIZERparseSelectorAct
+ENDparseSelectorAct
+
+
+BEGINmodExit
+CODESTARTmodExit
+ /* release what we no longer need */
+ objRelease(errmsg, CORE_COMPONENT);
+ objRelease(glbl, CORE_COMPONENT);
+ objRelease(net, LM_NET_FILENAME);
+ if(netstrm.ifIsLoaded)
+ objRelease(netstrm, LM_NETSTRM_FILENAME);
+ if(netstrms.ifIsLoaded)
+ objRelease(netstrms, LM_NETSTRMS_FILENAME);
+ if(!tcpclt.ifIsLoaded)
+ objRelease(tcpclt, LM_TCPCLT_FILENAME);
+
+ if(pszTplName != NULL) {
+ free(pszTplName);
+ pszTplName = NULL;
+ }
+ENDmodExit
+
+
+BEGINqueryEtryPt
+CODESTARTqueryEtryPt
+CODEqueryEtryPt_STD_OMOD_QUERIES
+ENDqueryEtryPt
+
+
+/* Reset config variables for this module to default values.
+ * rgerhards, 2008-03-28
+ */
+static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
+{
+ if(pszTplName != NULL) {
+ free(pszTplName);
+ pszTplName = NULL;
+ }
+
+ return RS_RET_OK;
+}
+
+
+BEGINmodInit(Fwd)
+CODESTARTmodInit
+ *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
+CODEmodInit_QueryRegCFSLineHdlr
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
+ CHKiRet(objUse(errmsg, CORE_COMPONENT));
+ CHKiRet(objUse(net,LM_NET_FILENAME));
+
+ CHKiRet(regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL));
+ CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID));
+ENDmodInit
+
+/* vim:set ai:
+ */
diff --git a/omfwd.h b/tools/omfwd.h
index dea432e5..dea432e5 100644
--- a/omfwd.h
+++ b/tools/omfwd.h
diff --git a/omshell.c b/tools/omshell.c
index 2176c101..2176c101 100644
--- a/omshell.c
+++ b/tools/omshell.c
diff --git a/omshell.h b/tools/omshell.h
index 3061ad07..3061ad07 100644
--- a/omshell.h
+++ b/tools/omshell.h
diff --git a/omusrmsg.c b/tools/omusrmsg.c
index 42d3291d..42d3291d 100644
--- a/omusrmsg.c
+++ b/tools/omusrmsg.c
diff --git a/omusrmsg.h b/tools/omusrmsg.h
index 52e780f7..52e780f7 100644
--- a/omusrmsg.h
+++ b/tools/omusrmsg.h
diff --git a/pidfile.c b/tools/pidfile.c
index 2be13da6..2be13da6 100644
--- a/pidfile.c
+++ b/tools/pidfile.c
diff --git a/pidfile.h b/tools/pidfile.h
index 40be9069..40be9069 100644
--- a/pidfile.h
+++ b/tools/pidfile.h
diff --git a/rsyslog.conf.5 b/tools/rsyslog.conf.5
index 1c47f535..1c47f535 100644
--- a/rsyslog.conf.5
+++ b/tools/rsyslog.conf.5
diff --git a/rsyslogd.8 b/tools/rsyslogd.8
index 2aa911d9..2aa911d9 100644
--- a/rsyslogd.8
+++ b/tools/rsyslogd.8
diff --git a/syslogd.c b/tools/syslogd.c
index f4ac2080..835a020d 100644
--- a/syslogd.c
+++ b/tools/syslogd.c
@@ -129,6 +129,8 @@
#include <zlib.h>
#endif
+#include <netdb.h>
+
#include "pidfile.h"
#include "srUtils.h"
#include "stringbuf.h"
@@ -140,7 +142,6 @@
#include "msg.h"
#include "modules.h"
#include "action.h"
-#include "tcpsyslog.h"
#include "iminternal.h"
#include "cfsysline.h"
#include "omshell.h"
@@ -151,21 +152,15 @@
#include "threads.h"
#include "queue.h"
#include "stream.h"
-#include "wti.h"
-#include "wtp.h"
-#include "expr.h"
-#include "ctok.h"
#include "conf.h"
-#include "vmop.h"
-#include "vmstk.h"
#include "vm.h"
-#include "vmprg.h"
#include "errmsg.h"
#include "datetime.h"
#include "sysvar.h"
/* definitions for objects we access */
DEFobjCurrIf(obj)
+DEFobjCurrIf(glbl)
DEFobjCurrIf(datetime)
DEFobjCurrIf(conf)
DEFobjCurrIf(expr)
@@ -243,25 +238,17 @@ static rsRetVal GlobalClassExit(void);
# define _PATH_DEV "/dev/"
#endif
-#ifndef _PATH_CONSOLE
-#define _PATH_CONSOLE "/dev/console"
-#endif
-
#ifndef _PATH_TTY
#define _PATH_TTY "/dev/tty"
#endif
static uchar *ConfFile = (uchar*) _PATH_LOGCONF; /* read-only after startup */
static char *PidFile = _PATH_LOGPID; /* read-only after startup */
-char ctty[] = _PATH_CONSOLE; /* this is read-only; used by omfile -- TODO: remove that dependency */
static pid_t myPid; /* our pid for use in self-generated messages, e.g. on startup */
/* mypid is read-only after the initial fork() */
static int restart = 0; /* do restart (config read) - multithread safe */
-int glblHadMemShortage = 0; /* indicates if we had memory shortage some time during the run */
-
-
static int bParseHOSTNAMEandTAG = 1; /* global config var: should the hostname and tag be
* parsed inside message - rgerhards, 2006-03-13 */
static int bFinished = 0; /* used by termination signal handler, read-only except there
@@ -296,25 +283,16 @@ int iCompatibilityMode = 0; /* version we should be compatible with; 0 means sy
static int bDebugPrintTemplateList = 1;/* output template list in debug mode? */
static int bDebugPrintCfSysLineHandlerList = 1;/* output cfsyslinehandler list in debug mode? */
static int bDebugPrintModuleList = 1;/* output module list in debug mode? */
-int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records during DNS lookup */
static uchar cCCEscapeChar = '\\';/* character to be used to start an escape sequence for control chars */
static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */
int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */
int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */
int iActExecOnceInterval = 0; /* execute action once every nn seconds */
-uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing slash) */
-uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */
/* end global config file state variables */
-uchar *LocalHostName;/* our hostname - read-only after startup */
-char *LocalDomain; /* our local domain name - read-only after startup */
int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */
-int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */
int send_to_all = 0; /* send message to all IPv4/IPv6 addresses */
static int NoFork = 0; /* don't fork - don't run in daemon mode - read-only after startup */
-int DisableDNS = 0; /* don't look up IP addresses of remote messages */
-char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */
-char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */
static int bHaveMainQueue = 0;/* set to 1 if the main queue - in queueing mode - is available
* If the main queue is either not yet ready or not running in
* queueing mode (mode DIRECT!), then this is set to 0.
@@ -386,11 +364,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
bDebugPrintModuleList = 1;
bEscapeCCOnRcv = 1; /* default is to escape control characters */
bReduceRepeatMsgs = 0;
- bDropMalPTRMsgs = 0;
- if(pszWorkDir != NULL) {
- free(pszWorkDir);
- pszWorkDir = NULL;
- }
if(pszMainMsgQFName != NULL) {
free(pszMainMsgQFName);
pszMainMsgQFName = NULL;
@@ -418,10 +391,6 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a
}
-
-int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */
-
-
/* hardcoded standard templates (used for defaults) */
static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-rfc3339% %HOSTNAME% %APP-NAME% %PROCID% %MSGID% %STRUCTURED-DATA% %msg%\n\"";
static uchar template_TraditionalFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\"";
@@ -499,7 +468,6 @@ selectorConstruct(selector_t **ppThis)
assert(ppThis != NULL);
if((pThis = (selector_t*) calloc(1, sizeof(selector_t))) == NULL) {
- glblHadMemShortage = 1;
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
}
CHKiRet(llInit(&pThis->llActList, actionDestruct, NULL, NULL));
@@ -680,7 +648,7 @@ rsRetVal printline(char *hname, char *msg, int bParseHost, int flags, flowContro
if(MsgSetUxTradMsg(pMsg, p) != 0)
ABORT_FINALIZE(RS_RET_ERR);
- logmsg(pMsg, flags | SYNC_FILE);
+ logmsg(pMsg, flags);
finalize_it:
RETiRet;
@@ -879,6 +847,19 @@ finalize_it:
RETiRet;
}
+
+/* this is a special function used to submit an error message. This
+ * function is also passed to the runtime library as the generic error
+ * message handler. -- rgerhards, 2008-04-17
+ */
+rsRetVal
+submitErrMsg(uchar *msg)
+{
+ DEFiRet;
+ iRet = logmsgInternal(LOG_SYSLOG|LOG_ERR, msg, ADDDATE);
+ RETiRet;
+}
+
/* rgerhards 2004-11-09: the following is a function that can be used
* to log a message orginating from the syslogd itself. In sysklogd code,
* this is done by simply calling logmsg(). However, logmsg() is changed in
@@ -889,16 +870,16 @@ finalize_it:
* think on the best way to do this.
*/
rsRetVal
-logmsgInternal(int pri, char *msg, int flags)
+logmsgInternal(int pri, uchar *msg, int flags)
{
DEFiRet;
msg_t *pMsg;
CHKiRet(msgConstruct(&pMsg));
- MsgSetUxTradMsg(pMsg, msg);
- MsgSetRawMsg(pMsg, msg);
- MsgSetHOSTNAME(pMsg, (char*)LocalHostName);
- MsgSetRcvFrom(pMsg, (char*)LocalHostName);
+ MsgSetUxTradMsg(pMsg, (char*)msg);
+ MsgSetRawMsg(pMsg, (char*)msg);
+ MsgSetHOSTNAME(pMsg, (char*)glbl.GetLocalHostName());
+ MsgSetRcvFrom(pMsg, (char*)glbl.GetLocalHostName());
MsgSetTAG(pMsg, "rsyslogd:");
pMsg->iFacility = LOG_FAC(pri);
pMsg->iSeverity = LOG_PRI(pri);
@@ -1863,14 +1844,10 @@ static void doDie(int sig)
static void
freeAllDynMemForTermination(void)
{
- if(pszWorkDir != NULL)
- free(pszWorkDir);
if(pszMainMsgQFName != NULL)
free(pszMainMsgQFName);
if(pModDir != NULL)
free(pModDir);
- if(LocalHostName != NULL)
- free(LocalHostName);
}
@@ -1912,7 +1889,7 @@ die(int sig)
"\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.",
(int) myPid, sig);
errno = 0;
- logmsgInternal(LOG_SYSLOG|LOG_INFO, buf, ADDDATE);
+ logmsgInternal(LOG_SYSLOG|LOG_INFO, (uchar*)buf, ADDDATE);
}
/* drain queue (if configured so) and stop main queue worker thread pool */
@@ -1936,8 +1913,6 @@ die(int sig)
tplDeleteAll();
remove_pid(PidFile);
- if(glblHadMemShortage)
- dbgprintf("Had memory shortage at least once during the run.\n");
/* de-init some modules */
modExitIminternal();
@@ -2130,10 +2105,10 @@ static void dbgPrintInitInfo(void)
dbgPrintCfSysLineHandlers();
dbgprintf("Messages with malicious PTR DNS Records are %sdropped.\n",
- bDropMalPTRMsgs ? "" : "not ");
+ glbl.GetDropMalPTRMsgs() ? "" : "not ");
dbgprintf("Control characters are %sreplaced upon reception.\n",
- bEscapeCCOnRcv? "" : "not ");
+ bEscapeCCOnRcv? "" : "not ");
if(bEscapeCCOnRcv)
dbgprintf("Control character escape sequence prefix is '%c'.\n",
@@ -2159,7 +2134,7 @@ static void dbgPrintInitInfo(void)
setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", 100);
setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", 1);
*/
- dbgprintf("Work Directory: '%s'.\n", pszWorkDir);
+ dbgprintf("Work Directory: '%s'.\n", glbl.GetWorkDir());
}
@@ -2282,7 +2257,7 @@ init(void)
if(MainMsgQueType == QUEUETYPE_DISK) {
errno = 0; /* for logerror! */
- if(pszWorkDir == NULL) {
+ if(glbl.GetWorkDir() == NULL) {
errmsg.LogError(NO_ERRCODE, "No $WorkDirectory specified - can not run main message queue in 'disk' mode. "
"Using 'FixedArray' instead.\n");
MainMsgQueType = QUEUETYPE_FIXED_ARRAY;
@@ -2367,7 +2342,7 @@ init(void)
" [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \
"\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"] restart",
(int) myPid);
- logmsgInternal(LOG_SYSLOG|LOG_INFO, bufStartUpMsg, ADDDATE);
+ logmsgInternal(LOG_SYSLOG|LOG_INFO, (uchar*)bufStartUpMsg, ADDDATE);
memset(&sigAct, 0, sizeof (sigAct));
sigemptyset(&sigAct.sa_mask);
@@ -2476,51 +2451,6 @@ void sighup_handler()
}
-/**
- * getSubString
- *
- * Copy a string byte by byte until the occurrence
- * of a given separator.
- *
- * \param ppSrc Pointer to a pointer of the source array of characters. If a
- separator detected the Pointer points to the next char after the
- separator. Except if the end of the string is dedected ('\n').
- Then it points to the terminator char.
- * \param pDst Pointer to the destination array of characters. Here the substing
- will be stored.
- * \param DstSize Maximum numbers of characters to store.
- * \param cSep Separator char.
- * \ret int Returns 0 if no error occured.
- *
- * rgerhards, 2008-02-12: some notes are due... I will once again fix this function, this time
- * so that it treats ' ' as a request for whitespace. But in general, the function and its callers
- * should be changed over time, this is not really very good code...
- */
-int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep)
-{
- uchar *pSrc = *ppSrc;
- int iErr = 0; /* 0 = no error, >0 = error */
- while((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0' && DstSize>1) {
- *pDst++ = *(pSrc)++;
- DstSize--;
- }
- /* check if the Dst buffer was to small */
- if ((cSep == ' ' ? !isspace(*pSrc) : *pSrc != cSep) && *pSrc != '\n' && *pSrc != '\0') {
- dbgprintf("in getSubString, error Src buffer > Dst buffer\n");
- iErr = 1;
- }
- if (*pSrc == '\0' || *pSrc == '\n')
- /* this line was missing, causing ppSrc to be invalid when it
- * was returned in case of end-of-string. rgerhards 2005-07-29
- */
- *ppSrc = pSrc;
- else
- *ppSrc = pSrc+1;
- *pDst = '\0';
- return iErr;
-}
-
-
/* this function pulls all internal messages from the buffer
* and puts them into the processing engine.
* We can only do limited error handling, as this would not
@@ -2679,7 +2609,7 @@ static rsRetVal loadBuildInModules(void)
* is that rsyslog will terminate if we can not register our built-in config commands.
* This, I think, is the right thing to do. -- rgerhards, 2007-07-31
*/
- CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL));
+// CHKiRet(regCfSysLineHdlr((uchar *)"workdirectory", 0, eCmdHdlrGetWord, NULL, &pszWorkDir, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeretrycount", 0, eCmdHdlrInt, NULL, &glbliActionResumeRetryCount, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuefilename", 0, eCmdHdlrGetWord, NULL, &pszMainMsgQFName, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesize", 0, eCmdHdlrInt, NULL, &iMainMsgQueueSize, NULL));
@@ -2707,7 +2637,6 @@ static rsRetVal loadBuildInModules(void)
CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL));
- CHKiRet(regCfSysLineHdlr((uchar *)"dropmsgswithmaliciousdnsptrrecords", 0, eCmdHdlrBinary, NULL, &bDropMalPTRMsgs, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"droptrailinglfonreception", 0, eCmdHdlrBinary, NULL, &bDropTrailingLF, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"template", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_TEMPLATE, NULL));
CHKiRet(regCfSysLineHdlr((uchar *)"outchannel", 0, eCmdHdlrCustomHandler, conf.doNameLine, (void*)DIR_OUTCHANNEL, NULL));
@@ -2828,8 +2757,9 @@ static void mainThread()
}
-/* Method to initialize all global classes.
+/* Method to initialize all global classes and use the objects that we need.
* rgerhards, 2008-01-04
+ * rgerhards, 2008-04-16: the actual initialization is now carried out by the runtime
*/
static rsRetVal
InitGlobalClasses(void)
@@ -2837,67 +2767,34 @@ InitGlobalClasses(void)
DEFiRet;
char *pErrObj; /* tells us which object failed if that happens (useful for troubleshooting!) */
- pErrObj = "obj";
- CHKiRet(objClassInit(NULL)); /* *THIS* *MUST* always be the first class initilizer being called! */
- CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */
- /* the following classes were intialized by objClassInit() */
+ /* Intialize the runtime system */
+ pErrObj = "rsyslog runtime"; /* set in case the runtime errors before setting an object */
+ CHKiRet(rsrtInit(&pErrObj, &obj));
+ CHKiRet(rsrtSetErrLogger(submitErrMsg)); /* set out error handler */
+
+ /* Now tell the system which classes we need ourselfs */
+ pErrObj = "glbl";
+ CHKiRet(objUse(glbl, CORE_COMPONENT));
pErrObj = "errmsg";
CHKiRet(objUse(errmsg, CORE_COMPONENT));
pErrObj = "module";
CHKiRet(objUse(module, CORE_COMPONENT));
pErrObj = "var";
CHKiRet(objUse(var, CORE_COMPONENT));
-
- /* initialize and use classes. We must be very careful with the order of events. Some
- * classes use others and if we do not initialize them in the right order, we may end
- * up with an invalid call. The most important thing that can happen is that an error
- * is detected and needs to be logged, wich in turn requires a broader number of classes
- * to be available. The solution is that we take care in the order of calls AND use a
- * class immediately after it is initialized. And, of course, we load those classes
- * first that we use ourselfs... -- rgerhards, 2008-03-07
- */
pErrObj = "datetime";
- CHKiRet(datetimeClassInit(NULL));
CHKiRet(objUse(datetime, CORE_COMPONENT));
- pErrObj = "msg";
- CHKiRet(msgClassInit(NULL));
- pErrObj = "str,";
- CHKiRet(strmClassInit(NULL));
- pErrObj = "wti";
- CHKiRet(wtiClassInit(NULL));
- pErrObj = "wtp";
- CHKiRet(wtpClassInit(NULL));
- pErrObj = "queue";
- CHKiRet(queueClassInit(NULL));
- pErrObj = "vmstk";
- CHKiRet(vmstkClassInit(NULL));
- pErrObj = "sysvar";
- CHKiRet(sysvarClassInit(NULL));
pErrObj = "vm";
- CHKiRet(vmClassInit(NULL));
CHKiRet(objUse(vm, CORE_COMPONENT));
- pErrObj = "vmop";
- CHKiRet(vmopClassInit(NULL));
- pErrObj = "vmprg";
- CHKiRet(vmprgClassInit(NULL));
- pErrObj = "ctok_token";
- CHKiRet(ctok_tokenClassInit(NULL));
- pErrObj = "ctok";
- CHKiRet(ctokClassInit(NULL));
pErrObj = "expr";
- CHKiRet(exprClassInit(NULL));
CHKiRet(objUse(expr, CORE_COMPONENT));
pErrObj = "conf";
- CHKiRet(confClassInit(NULL));
CHKiRet(objUse(conf, CORE_COMPONENT));
- /* dummy "classes" */
+ /* intialize some dummy classes that are not part of the runtime */
pErrObj = "action";
CHKiRet(actionClassInit());
pErrObj = "template";
CHKiRet(templateInit());
- pErrObj = "str";
- CHKiRet(strInit());
/* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */
pErrObj = "net";
@@ -2937,7 +2834,6 @@ GlobalClassExit(void)
objRelease(datetime, CORE_COMPONENT);
/* TODO: implement the rest of the deinit */
- confClassExit();
#if 0
CHKiRet(datetimeClassInit(NULL));
CHKiRet(msgClassInit(NULL));
@@ -2967,7 +2863,7 @@ GlobalClassExit(void)
CHKiRet(objUse(errmsg, CORE_COMPONENT));
CHKiRet(objUse(module, CORE_COMPONENT));
#endif
- objClassExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */
+ rsrtExit(); /* *THIS* *MUST/SHOULD?* always be the first class initilizer being called (except debug)! */
RETiRet;
}
@@ -3048,18 +2944,19 @@ int realMain(int argc, char **argv)
DEFiRet;
register int i;
- register char *p;
+ register uchar *p;
int num_fds;
int ch;
struct hostent *hent;
extern int optind;
extern char *optarg;
struct sigaction sigAct;
- int bIsFirstOption = 1;
int bEOptionWasGiven = 0;
int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */
char *arg; /* for command line option processing */
uchar legacyConfLine[80];
+ uchar *LocalHostName;
+ uchar *LocalDomain;
/* first, parse the command line options. We do not carry out any actual work, just
* see what we should do. This relieves us from certain anomalies and we can process
@@ -3098,11 +2995,6 @@ int realMain(int argc, char **argv)
CHKiRet(bufOptAdd(ch, optarg));
break;
case 'c': /* compatibility mode */
- if(!bIsFirstOption) {
- fprintf(stderr, "-c option MUST be specified as the first option - aborting...\n");
- usage();
- exit(1);
- }
iCompatibilityMode = atoi(optarg);
break;
case 'd': /* debug - must be handled now, so that debug is active during init! */
@@ -3143,7 +3035,6 @@ int realMain(int argc, char **argv)
default:
usage();
}
- bIsFirstOption = 0; /* we already saw an option character */
}
if ((argc -= optind))
@@ -3173,11 +3064,11 @@ int realMain(int argc, char **argv)
* error log messages, which need the correct hostname. -- rgerhards, 2008-04-04
*/
net.getLocalHostname(&LocalHostName);
- if((p = strchr((char*)LocalHostName, '.'))) {
+ if((p = (uchar*)strchr((char*)LocalHostName, '.'))) {
*p++ = '\0';
LocalDomain = p;
} else {
- LocalDomain = "";
+ LocalDomain = (uchar*)"";
/* It's not clearly defined whether gethostname()
* should return the simple hostname or the fqdn. A
@@ -3197,7 +3088,7 @@ int realMain(int argc, char **argv)
free(LocalHostName);
CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name));
- if((p = strchr((char*)LocalHostName, '.')))
+ if((p = (uchar*)strchr((char*)LocalHostName, '.')))
{
*p++ = '\0';
LocalDomain = p;
@@ -3206,8 +3097,15 @@ int realMain(int argc, char **argv)
}
/* Convert to lower case to recognize the correct domain laterly */
- for (p = (char *)LocalDomain ; *p ; p++)
+ 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);
/* initialize the objects */
if((iRet = modInitIminternal()) != RS_RET_OK) {
@@ -3228,10 +3126,10 @@ int realMain(int argc, char **argv)
dbgprintf("deque option %c, optarg '%s'\n", ch, arg);
switch((char)ch) {
case '4':
- family = PF_INET;
+ glbl.SetDefPFFamily(PF_INET);
break;
case '6':
- family = PF_INET6;
+ glbl.SetDefPFFamily(PF_INET6);
break;
case 'A':
send_to_all++;
@@ -3268,10 +3166,10 @@ int realMain(int argc, char **argv)
PidFile = arg;
break;
case 'l':
- if (LocalHosts) {
+ if(glbl.GetLocalHosts() != NULL) {
fprintf (stderr, "rsyslogd: Only one -l argument allowed, the first one is taken.\n");
} else {
- LocalHosts = crunch_list(arg);
+ glbl.SetLocalHosts(crunch_list(arg));
}
break;
case 'm': /* mark interval */
@@ -3321,10 +3219,10 @@ int realMain(int argc, char **argv)
fprintf(stderr, "-r option only supported in compatibility modes 0 to 2 - ignored\n");
break;
case 's':
- if (StripDomains) {
+ if(glbl.GetStripDomains() != NULL) {
fprintf (stderr, "rsyslogd: Only one -s argument allowed, the first one is taken.\n");
} else {
- StripDomains = crunch_list(arg);
+ glbl.SetStripDomains(crunch_list(arg));
}
break;
case 't': /* enable tcp logging */
@@ -3338,10 +3236,10 @@ int realMain(int argc, char **argv)
bParseHOSTNAMEandTAG = 0;
break;
case 'w': /* disable disallowed host warnigs */
- option_DisallowWarning = 0;
+ glbl.SetOption_DisallowWarning(0);
break;
case 'x': /* disable dns for remote messages */
- DisableDNS = 1;
+ glbl.SetDisableDNS(1);
break;
case '?':
default:
diff --git a/syslogd.h b/tools/syslogd.h
index 46de8d28..e866a16b 100644
--- a/syslogd.h
+++ b/tools/syslogd.h
@@ -29,44 +29,11 @@
#include "linkedlist.h"
#include "expr.h"
-/* portability: not all platforms have these defines, so we
- * define them here if they are missing. -- rgerhards, 2008-03-04
- */
-#ifndef LOG_MAKEPRI
-# define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
-#endif
-#ifndef LOG_PRI
-# define LOG_PRI(p) ((p) & LOG_PRIMASK)
-#endif
-#ifndef LOG_FAC
-# define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
-#endif
-
-#ifdef USE_NETZIP
-/* config param: minimum message size to try compression. The smaller
- * the message, the less likely is any compression gain. We check for
- * gain before we submit the message. But to do so we still need to
- * do the (costly) compress() call. The following setting sets a size
- * for which no call to compress() is done at all. This may result in
- * a few more bytes being transmited but better overall performance.
- * Note: I have not yet checked the minimum UDP packet size. It might be
- * that we do not save anything by compressing very small messages, because
- * UDP might need to pad ;)
- * rgerhards, 2006-11-30
- */
-#define MIN_SIZE_FOR_COMPRESS 60
+#ifndef _PATH_CONSOLE
+#define _PATH_CONSOLE "/dev/console"
#endif
-#define MAXLINE 2048 /* maximum line length */
-
-/* Flags to logmsg().
- */
-#define NOFLAG 0x000 /* no flag is set (to be used when a flag must be specified and none is required) */
-#define INTERNAL_MSG 0x001 /* msg generated by logmsgInternal() --> special handling */
-#define SYNC_FILE 0x002 /* do fsync on file after printing */
-#define ADDDATE 0x004 /* add a date to the message */
-#define MARK 0x008 /* this message is a mark */
/* This structure represents the files that will have log
* copies printed.
@@ -113,54 +80,20 @@ struct filed {
linkedList_t llActList; /* list of configured actions */
};
-typedef struct filed selector_t; /* new type name */
-#define MSG_PARSE_HOSTNAME 1
-#define MSG_DONT_PARSE_HOSTNAME 0
-rsRetVal parseAndSubmitMessage(char *hname, char *msg, int len, int bParseHost, int flags, flowControl_t flowCtlType);
#include "net.h" /* TODO: remove when you remoe isAllowedSender from here! */
void untty(void);
rsRetVal selectorConstruct(selector_t **ppThis);
-rsRetVal cflineParseTemplateName(uchar** pp, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *dfltTplName);
-rsRetVal cflineParseFileName(uchar* p, uchar *pFileName, omodStringRequest_t *pOMSR, int iEntry, int iTplOpts, uchar *pszTpl);
-int getSubString(uchar **ppSrc, char *pDst, size_t DstSize, char cSep);
rsRetVal selectorDestruct(void *pVal);
rsRetVal selectorAddList(selector_t *f);
/* the following prototypes should go away once we have an input
* module interface -- rgerhards, 2007-12-12
*/
-rsRetVal logmsgInternal(int pri, char *msg, int flags);
void logmsg(msg_t *pMsg, int flags);
-rsRetVal submitMsg(msg_t *pMsg);
-extern int glblHadMemShortage; /* indicates if we had memory shortage some time during the run */
-extern uchar *LocalHostName;
-extern int family;
extern int NoHops;
extern int send_to_all;
-extern int option_DisallowWarning;
extern int Debug;
-extern char**LocalHosts;
-extern int DisableDNS;
-extern char **StripDomains;
-extern char *LocalDomain;
-extern int bDropMalPTRMsgs;
-extern char ctty[];
-extern int MarkInterval;
-extern int bReduceRepeatMsgs;
-extern int bActExecWhenPrevSusp;
-extern int iActExecOnceInterval;
-
-/* Intervals at which we flush out "message repeated" messages,
- * in seconds after previous message is logged. After each flush,
- * we move to the next interval until we reach the largest.
- * TODO: move this to action object!
- */
-extern int repeatinterval[2];
-#define MAXREPEAT ((int)((sizeof(repeatinterval) / sizeof(repeatinterval[0])) - 1))
-#define REPEATTIME(f) ((f)->f_time + repeatinterval[(f)->f_repeatcount])
-#define BACKOFF(f) { if (++(f)->f_repeatcount > MAXREPEAT) \
- (f)->f_repeatcount = MAXREPEAT; \
- }
+#include "dirty.h"
#endif /* #ifndef SYSLOGD_H_INCLUDED */