diff options
37 files changed, 501 insertions, 198 deletions
@@ -1,4 +1,19 @@ --------------------------------------------------------------------------- +Version 5.7.2 [V5-DEVEL] (rgerhards), 2010-11-26 +- bugfix(important): problem in TLS handling could cause rsyslog to loop + in a tight loop, effectively disabling functionality and bearing the + risk of unresponsiveness of the whole system. + Bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=194 +- bugfix: imfile state file was not written when relative file name + for it was specified +- bugfix: compile failed on systems without epoll_create1() + Thanks to David Hill for providing a fix. +- bugfix: atomic increment for msg object may not work correct on all + platforms. Thanks to Chris Metcalf for the patch +- bugfix: replacements for atomic operations for non-int sized types had + problems. At least one instance of that problem could potentially lead + to abort (inside omfile). +--------------------------------------------------------------------------- Version 5.7.1 [V5-DEVEL] (rgerhards), 2010-10-05 - support for Hadoop's HDFS added (via omhdfs) - imuxsock now optionally use SCM_CREDENTIALS to pull the pid from the log @@ -29,6 +44,45 @@ Version 5.7.0 [V5-DEVEL] (rgerhards), 2010-09-16 thanks to Lennart Poettering for this patch * sd-systemd API added as part of rsyslog runtime library --------------------------------------------------------------------------- +Version 5.6.2 [V5-STABLE] (rgerhards), 2010-11-?? +- bugfix: compile failed on systems without epoll_create1() + Thanks to David Hill for providing a fix. +- bugfix: atomic increment for msg object may not work correct on all + platforms. Thanks to Chris Metcalf for the patch +- bugfix: replacements for atomic operations for non-int sized types had + problems. At least one instance of that problem could potentially lead + to abort (inside omfile). +- added the $InputFilePersistStateInterval config directive to imfile +- changed imfile so that the state file is never deleted (makes imfile + more robust in regard to fatal failures) +--------------------------------------------------------------------------- +Version 5.6.1 [V5-STABLE] (rgerhards), 2010-11-24 +- bugfix(important): problem in TLS handling could cause rsyslog to loop + in a tight loop, effectively disabling functionality and bearing the + risk of unresponsiveness of the whole system. + Bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=194 +- permitted imptcp to work on systems which support epoll(), but not + epoll_create(). + Bug: http://bugzilla.adiscon.com/show_bug.cgi?id=204 + Thanks to Nicholas Brink for reporting this problem. +- bugfix: testbench failed if imptcp was not enabled +- bugfix: segfault when an *empty* template was used + Bug: http://bugzilla.adiscon.com/show_bug.cgi?id=206 + Thanks to David Hill for alerting us. +- bugfix: compile failed with --enable-unlimited-select + thanks varmojfekoj for the patch +--------------------------------------------------------------------------- +Version 5.6.0 [V5-STABLE] (rgerhards), 2010-10-19 + +This release brings all changes and enhancements of the 5.5.x series +to the v5-stable branch. + +- bugfix: a couple of problems that imfile had on some platforms, namely + Ubuntu (not their fault, but occured there) +- bugfix: imfile utilizes 32 bit to track offset. Most importantly, + this problem can not experienced on Fedora 64 bit OS (which has + 64 bit long's!) +--------------------------------------------------------------------------- Version 5.5.7 [V5-BETA] (rgerhards), 2010-08-09 - changed omudpspoof default spoof address to simplify typical use case thanks to David Lang for suggesting this @@ -511,6 +565,14 @@ Version 4.7.3 [v4-devel] (rgerhards), 2010-??-?? this is the counterpart to imuxsock, enabling fast local forwarding - added imptcp, a simplified, Linux-specific and potentielly fast syslog plain tcp input plugin (NOT supporting TLS!) +- bugfix: a couple of problems that imfile had on some platforms, namely + Ubuntu (not their fault, but occured there) +- bugfix: imfile utilizes 32 bit to track offset. Most importantly, + this problem can not experienced on Fedora 64 bit OS (which has + 64 bit long's!) +- added the $InputFilePersistStateInterval config directive to imfile +- changed imfile so that the state file is never deleted (makes imfile + more robust in regard to fatal failures) --------------------------------------------------------------------------- Version 4.7.2 [v4-devel] (rgerhards), 2010-05-03 - bugfix: problems with atomic operations emulaton @@ -556,6 +618,17 @@ Version 4.7.0 [v4-devel] (rgerhards), 2010-04-14 Thanks for varmojfekoj for pointing me at this bug. - imported changes from 4.5.6 and below --------------------------------------------------------------------------- +Version 4.6.5 [v4-stable] (rgerhards), 2010-??-?? +- bugfix(important): problem in TLS handling could cause rsyslog to loop + in a tight loop, effectively disabling functionality and bearing the + risk of unresponsiveness of the whole system. + Bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=194 +- bugfix: a couple of problems that imfile had on some platforms, namely + Ubuntu (not their fault, but occured there) +- bugfix: imfile utilizes 32 bit to track offset. Most importantly, + this problem can not experienced on Fedora 64 bit OS (which has + 64 bit long's!) +--------------------------------------------------------------------------- Version 4.6.4 [v4-stable] (rgerhards), 2010-08-05 - bugfix: zero-sized (empty) messages were processed by imtcp they are now dropped as they always should have been @@ -1182,6 +1255,12 @@ version before switching to this one. - bugfix: memory leak in ompgsql Thanks to Ken for providing the patch --------------------------------------------------------------------------- +Version 3.22.3 [v3-stable] (rgerhards), 2010-11-24 +- bugfix(important): problem in TLS handling could cause rsyslog to loop + in a tight loop, effectively disabling functionality and bearing the + risk of unresponsiveness of the whole system. + Bug tracker: http://bugzilla.adiscon.com/show_bug.cgi?id=194 +--------------------------------------------------------------------------- Version 3.22.2 [v3-stable] (rgerhards), 2010-08-05 - bugfix: comment char ('#') in literal terminated script parsing and thus could not be used. diff --git a/Makefile.am b/Makefile.am index 54b6815..680a819 100644 --- a/Makefile.am +++ b/Makefile.am @@ -217,9 +217,9 @@ DISTCHECK_CONFIGURE_FLAGS= --enable-gssapi_krb5 \ --enable-imdiag \ --enable-imptcp \ --enable-omuxsock \ - --enable-shave \ --enable-extended-tests \ --enable-impstats \ + --enable-imptcp \ --enable-memcheck \ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) ACLOCAL_AMFLAGS = -I m4 diff --git a/Makefile.in b/Makefile.in index 1b54f42..b8fe4c1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -485,9 +485,9 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-gssapi_krb5 \ --enable-imdiag \ --enable-imptcp \ --enable-omuxsock \ - --enable-shave \ --enable-extended-tests \ --enable-impstats \ + --enable-imptcp \ --enable-memcheck \ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) @@ -1358,7 +1358,7 @@ doSubmitToActionQNotAllMarkBatch(action_t *pAction, batch_t *pBatch) time_t now = 0; time_t lastAct; int i; - int bProcessMarkMsgs; + int bProcessMarkMsgs = 0; int bModifiedFilter; sbool FilterSave[128]; sbool *pFilterSave; @@ -1388,7 +1388,7 @@ doSubmitToActionQNotAllMarkBatch(action_t *pAction, batch_t *pBatch) } else { bProcessMarkMsgs = 1; } - } while(ATOMIC_CAS(&pAction->f_time, lastAct, + } while(ATOMIC_CAS_time_t(&pAction->f_time, lastAct, ((msg_t*)(pBatch->pElem[i].pUsrp))->ttGenTime, &pAction->mutCAS) == 0); } if(bProcessMarkMsgs) { diff --git a/config.h.in b/config.h.in index 1d840bd..fb14023 100644 --- a/config.h.in +++ b/config.h.in @@ -94,6 +94,9 @@ /* Define to 1 if you have the `localtime_r' function. */ #undef HAVE_LOCALTIME_R +/* Define to 1 if you have the `lseek64' function. */ +#undef HAVE_LSEEK64 + /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC @@ -141,6 +144,9 @@ /* Define to 1 if you have the <resolv.h> header file. */ #undef HAVE_RESOLV_H +/* set define */ +#undef HAVE_SCM_CREDENTIALS + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for rsyslog 5.7.1. +# Generated by GNU Autoconf 2.65 for rsyslog 5.7.2. # # Report bugs to <rsyslog@lists.adiscon.com>. # @@ -701,8 +701,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='rsyslog' PACKAGE_TARNAME='rsyslog' -PACKAGE_VERSION='5.7.1' -PACKAGE_STRING='rsyslog 5.7.1' +PACKAGE_VERSION='5.7.2' +PACKAGE_STRING='rsyslog 5.7.2' PACKAGE_BUGREPORT='rsyslog@lists.adiscon.com' PACKAGE_URL='' @@ -1589,7 +1589,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures rsyslog 5.7.1 to adapt to many kinds of systems. +\`configure' configures rsyslog 5.7.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1659,7 +1659,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of rsyslog 5.7.1:";; + short | recursive ) echo "Configuration of rsyslog 5.7.2:";; esac cat <<\_ACEOF @@ -1821,7 +1821,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -rsyslog configure 5.7.1 +rsyslog configure 5.7.2 generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. @@ -2396,7 +2396,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by rsyslog $as_me 5.7.1, which was +It was created by rsyslog $as_me 5.7.2, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -3204,7 +3204,7 @@ fi # Define the identity of the package. PACKAGE='rsyslog' - VERSION='5.7.1' + VERSION='5.7.2' cat >>confdefs.h <<_ACEOF @@ -13416,7 +13416,7 @@ fi done -for ac_func in flock basename alarm clock_gettime gethostbyname gethostname gettimeofday localtime_r memset mkdir regcomp select setid socket strcasecmp strchr strdup strerror strndup strnlen strrchr strstr strtol strtoul uname ttyname_r getline malloc_trim prctl epoll_create epoll_create1 fdatasync +for ac_func in flock basename alarm clock_gettime gethostbyname gethostname gettimeofday localtime_r memset mkdir regcomp select setid socket strcasecmp strchr strdup strerror strndup strnlen strrchr strstr strtol strtoul uname ttyname_r getline malloc_trim prctl epoll_create epoll_create1 fdatasync lseek64 do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -13430,6 +13430,18 @@ fi done +# the check below is probably ugly. If someone knows how to do it in a better way, please +# let me know! -- rgerhards, 2010-10-06 +ac_fn_c_check_decl "$LINENO" "SCM_CREDENTIALS" "ac_cv_have_decl_SCM_CREDENTIALS" "#include <sys/types.h> +#include <sys/socket.h> +" +if test "x$ac_cv_have_decl_SCM_CREDENTIALS" = x""yes; then : + +$as_echo "#define HAVE_SCM_CREDENTIALS 1" >>confdefs.h + +fi + + # Check for MAXHOSTNAMELEN { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MAXHOSTNAMELEN" >&5 $as_echo_n "checking for MAXHOSTNAMELEN... " >&6; } @@ -16701,7 +16713,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by rsyslog $as_me 5.7.1, which was +This file was extended by rsyslog $as_me 5.7.2, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -16767,7 +16779,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -rsyslog config.status 5.7.1 +rsyslog config.status 5.7.2 configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 7254b99..c1b4111 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([rsyslog],[5.7.1],[rsyslog@lists.adiscon.com]) +AC_INIT([rsyslog],[5.7.2],[rsyslog@lists.adiscon.com]) AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -108,7 +108,12 @@ AC_TYPE_SIGNAL AC_FUNC_STAT AC_FUNC_STRERROR_R AC_FUNC_VPRINTF -AC_CHECK_FUNCS([flock basename alarm clock_gettime gethostbyname gethostname gettimeofday localtime_r memset mkdir regcomp select setid socket strcasecmp strchr strdup strerror strndup strnlen strrchr strstr strtol strtoul uname ttyname_r getline malloc_trim prctl epoll_create epoll_create1 fdatasync]) +AC_CHECK_FUNCS([flock basename alarm clock_gettime gethostbyname gethostname gettimeofday localtime_r memset mkdir regcomp select setid socket strcasecmp strchr strdup strerror strndup strnlen strrchr strstr strtol strtoul uname ttyname_r getline malloc_trim prctl epoll_create epoll_create1 fdatasync lseek64]) + +# the check below is probably ugly. If someone knows how to do it in a better way, please +# let me know! -- rgerhards, 2010-10-06 +AC_CHECK_DECL([SCM_CREDENTIALS], [AC_DEFINE(HAVE_SCM_CREDENTIALS, [1], [set define])], [], [#include <sys/types.h> +#include <sys/socket.h>]) # Check for MAXHOSTNAMELEN AC_MSG_CHECKING(for MAXHOSTNAMELEN) diff --git a/doc/imfile.html b/doc/imfile.html index af0413d..f6b140a 100644 --- a/doc/imfile.html +++ b/doc/imfile.html @@ -86,6 +86,16 @@ level may be needed. Even if you need quick response, 1 seconds should be well enough. Please note that imfile keeps reading files as long as there is any data in them. So a "polling sleep" will only happen when nothing is left to be processed.</li> +<li><b>$InputFilePersistStateInterval</b> [lines]</b><br> +Available in 4.7.3+, 5.6.2+<br> +Specifies how often the state file shall be written when processing the input +file. The default value is 0, which means a new state file is only written when +the monitored files is being closed (end of rsyslogd execution). Any other +value n means that the state file is written every time n file lines have +been processed. This setting can be used to guard against message duplication due +to fatal errors (like power fail). Note that this setting affects imfile +performance, especially when set to a low value. Frequently writing the state +file is very time consuming. </ul> <b>Caveats/Known Bugs:</b> <p>So far, only 100 files can be monitored. If more are needed, diff --git a/doc/imuxsock.html b/doc/imuxsock.html index 1ab99a7..ee5db22 100644 --- a/doc/imuxsock.html +++ b/doc/imuxsock.html @@ -39,6 +39,7 @@ config statements just use the prefix $IMUXSockRateLimit... but otherwise works exactly the same. When working with severities, please keep in mind that higher severity numbers mean lower severity and configure things accordingly. +To turn off rate limiting, set the interval to zero. <p><b>Unix log sockets can be flow-controlled.</b> That is, if processing queues fill up, the unix socket reader is blocked for a short while. This may be useful to prevent overruning the queues (which may cause exessive disk-io where it actually would not be needed). However, @@ -55,7 +56,7 @@ the implications. Note that for many systems, turning on flow control does not h <li><b>$InputUnixListenSocketFlowControl</b> [on/<b>off</b>] - specifies if flow control should be applied to the next socket.</li> <li><b>$IMUXSockRateLimitInterval</b> [number] - specifies the rate-limiting -interval in seconds. Default value is 5 seconds. +interval in seconds. Default value is 5 seconds. Set it to 0 to turn rate limiting off. </li> <li><b>$IMUXSockRateLimitBurst</b> [number] - specifies the rate-limiting burst in number of messages. Default is 200. @@ -78,7 +79,7 @@ be obtained from the log socket itself. If so, the TAG part of the message is re It is recommended to turn this option on, but the default is "off" to keep compatible with earlier versions of rsyslog. This option was introduced in 5.7.0.</li> <li><b>$SystemLogRateLimitInterval</b> [number] - specifies the rate-limiting -interval in seconds. Default value is 5 seconds. +interval in seconds. Default value is 5 seconds. Set it to 0 to turn rate limiting off. </li> <li><b>$SystemLogRateLimitBurst</b> [number] - specifies the rate-limiting burst in number of messages. Default is 200. @@ -138,6 +139,12 @@ the $InputUnixListenSocketCreatePath and the $InputUnixListenSocketHostName.</p> $InputUnixListenSocketCreatePath on # turn on for *next* socket $InputUnixListenSocketHostName /var/run/sshd/dev/log </textarea> +<p>The following sample is used to turn off input rate limiting on the system log +socket. +<textarea rows="6" cols="70">$ModLoad imuxsock # needs to be done just once + +$SystemLogRateLimitInterval 0 # turn off rate limiting +</textarea> <p>[<a href="rsyslog_conf.html">rsyslog.conf overview</a>] [<a href="manual.html">manual index</a>] [<a href="http://www.rsyslog.com/">rsyslog site</a>]</p> <p><font size="2">This documentation is part of the diff --git a/doc/manual.html b/doc/manual.html index 6affe74..7fdf3f1 100644 --- a/doc/manual.html +++ b/doc/manual.html @@ -19,7 +19,7 @@ rsyslog support</a> available directly from the source!</p> <p><b>Please visit the <a href="http://www.rsyslog.com/sponsors">rsyslog sponsor's page</a> to honor the project sponsors or become one yourself!</b> We are very grateful for any help towards the project goals.</p> -<p><b>This documentation is for version 5.7.1 (beta branch) of rsyslog.</b> +<p><b>This documentation is for version 5.7.2 (beta branch) of rsyslog.</b> Visit the <i><a href="http://www.rsyslog.com/status">rsyslog status page</a></i></b> to obtain current version information and project status. </p><p><b>If you like rsyslog, you might diff --git a/doc/tls_cert_machine.html b/doc/tls_cert_machine.html index 5ecde0d..095e15c 100644 --- a/doc/tls_cert_machine.html +++ b/doc/tls_cert_machine.html @@ -75,7 +75,15 @@ Locality name: <font color="red">Somewhere</font> State or province name: <font color="red">CA</font> Common name: <font color="red">machine.example.net</font> UID: -Enter a challenge password: +Enter a dnsName of the subject of the certificate: +Enter the IP address of the subject of the certificate: +Enter the e-mail of the subject of the certificate: +Enter a challange password: +Does the certificate belong to an authority? (y/N): <font color="red">n</font> +Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N): +Will the certificate be used for encryption (RSA ciphersuites)? (y/N): +Is this a TLS web client certificate? (y/N): <font color="red">y</font> +Is this also a TLS web server certificate? (y/N): <font color="red">y</font> [root@rgf9dev sample]# <font color="red">certtool --generate-certificate --load-request request.pem --outfile cert.pem --load-ca-certificate ca.pem --load-ca-privkey ca-key.pem</font> Generating a signed certificate... Enter the certificate's serial number (decimal): @@ -86,10 +94,12 @@ The certificate will expire in (days): 1000 Extensions. +Do you want to honour the extensions from the request? (y/N): Does the certificate belong to an authority? (Y/N): <font color="red">n</font> Is this a TLS web client certificate? (Y/N): <font color="red">y</font> Is this also a TLS web server certificate? (Y/N): <font color="red">y</font> Enter the dnsName of the subject of the certificate: <font color="red">machine.example.net</font> <i>{This is the name of the machine that will use the certificate}</i> +Enter the IP address of the subject of certificate: Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (Y/N): Will the certificate be used for encryption (RSA ciphersuites)? (Y/N): X.509 Certificate Information: diff --git a/plugins/imfile/imfile.c b/plugins/imfile/imfile.c index 8a10e26..8681ac8 100644 --- a/plugins/imfile/imfile.c +++ b/plugins/imfile/imfile.c @@ -47,6 +47,7 @@ #include "datetime.h" #include "unicode-helper.h" #include "prop.h" +#include "stringbuf.h" MODULE_TYPE_INPUT /* must be present for input modules, do not remove */ @@ -67,15 +68,21 @@ typedef struct fileInfo_s { uchar *pszStateFile; /* file in which state between runs is to be stored */ int iFacility; int iSeverity; + int nRecords; /**< How many records did we process before persisting the stream? */ + int iPersistStateInterval; /**< how often should state be persisted? (0=on close only) */ strm_t *pStrm; /* its stream (NULL if not assigned) */ } fileInfo_t; +/* forward definitions */ +static rsRetVal persistStrmState(fileInfo_t *pInfo); + /* config variables */ static uchar *pszFileName = NULL; static uchar *pszFileTag = NULL; static uchar *pszStateFile = NULL; static int iPollInterval = 10; /* number of seconds to sleep when there was no file activity */ +static int iPersistStateInterval = 0; /* how often if state file to be persisted? (default 0->never) */ static int iFacility = 128; /* local0 */ static int iSeverity = 5; /* notice, as of rfc 3164 */ @@ -153,10 +160,9 @@ openFile(fileInfo_t *pThis) CHKiRet(strm.SeekCurrOffs(pThis->pStrm)); - /* OK, we could successfully read the file, so we now can request that it be deleted. - * If we need it again, it will be written on the next shutdown. + /* note: we do not delete the state file, so that the last position remains + * known even in the case that rsyslogd aborts for some reason (like powerfail) */ - psSF->bDeleteOnClose = 1; finalize_it: if(psSF != NULL) @@ -210,6 +216,10 @@ static rsRetVal pollFile(fileInfo_t *pThis, int *pbHadFileData) *pbHadFileData = 1; /* this is just a flag, so set it and forget it */ CHKiRet(enqLine(pThis, pCStr)); /* process line */ rsCStrDestruct(&pCStr); /* discard string (must be done by us!) */ + if(pThis->iPersistStateInterval > 0 && pThis->nRecords++ >= pThis->iPersistStateInterval) { + persistStrmState(pThis); + pThis->nRecords = 0; + } } finalize_it: @@ -337,12 +347,15 @@ persistStrmState(fileInfo_t *pInfo) { DEFiRet; strm_t *psSF = NULL; /* state file (stream) */ + size_t lenDir; ASSERT(pInfo != NULL); /* TODO: create a function persistObj in obj.c? */ CHKiRet(strm.Construct(&psSF)); - CHKiRet(strm.SetDir(psSF, glbl.GetWorkDir(), strlen((char*)glbl.GetWorkDir()))); + lenDir = ustrlen(glbl.GetWorkDir()); + if(lenDir > 0) + CHKiRet(strm.SetDir(psSF, glbl.GetWorkDir(), lenDir)); CHKiRet(strm.SettOperationsMode(psSF, STREAMMODE_WRITE_TRUNC)); CHKiRet(strm.SetsType(psSF, STREAMTYPE_FILE_SINGLE)); CHKiRet(strm.SetFName(psSF, pInfo->pszStateFile, strlen((char*) pInfo->pszStateFile))); @@ -474,6 +487,9 @@ static rsRetVal addMonitor(void __attribute__((unused)) *pVal, uchar *pNewVal) pThis->iSeverity = iSeverity; pThis->iFacility = iFacility; + pThis->iPersistStateInterval = iPersistStateInterval; + pThis->nRecords = 0; + iPersistStateInterval = 0; } else { errmsg.LogError(0, RS_RET_OUT_OF_DESRIPTORS, "Too many file monitors configured - ignoring this one"); ABORT_FINALIZE(RS_RET_OUT_OF_DESRIPTORS); @@ -519,6 +535,8 @@ CODEmodInit_QueryRegCFSLineHdlr NULL, &iFacility, STD_LOADABLE_MODULE_ID)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfilepollinterval", 0, eCmdHdlrInt, NULL, &iPollInterval, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputfilepersiststateinterval", 0, eCmdHdlrInt, + NULL, &iPersistStateInterval, STD_LOADABLE_MODULE_ID)); /* that command ads a new file! */ CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputrunfilemonitor", 0, eCmdHdlrGetWord, addMonitor, NULL, STD_LOADABLE_MODULE_ID)); diff --git a/plugins/imklog/bsd.c b/plugins/imklog/bsd.c index b789935..0a4c7cd 100644 --- a/plugins/imklog/bsd.c +++ b/plugins/imklog/bsd.c @@ -86,7 +86,7 @@ static int fklog = -1; /* /dev/klog */ static uchar *GetPath(void) { - return pszPath ? pszPath : _PATH_KLOG; + return pszPath ? pszPath : (uchar*) _PATH_KLOG; } /* open the kernel log - will be called inside the willRun() imklog @@ -97,7 +97,7 @@ klogWillRun(void) { DEFiRet; - fklog = open(GetPath(), O_RDONLY, 0); + fklog = open((char*)GetPath(), O_RDONLY, 0); if (fklog < 0) { dbgprintf("can't open %s (%d)\n", GetPath(), errno); iRet = RS_RET_ERR; // TODO: better error code @@ -153,7 +153,7 @@ readklog(void) break; } - for (p = pRcv; (q = strchr(p, '\n')) != NULL; p = q + 1) { + for (p = (char*)pRcv; (q = strchr(p, '\n')) != NULL; p = q + 1) { *q = '\0'; Syslog(LOG_INFO, (uchar*) p); } diff --git a/plugins/imptcp/imptcp.c b/plugins/imptcp/imptcp.c index 9b24dbc..6449ad6 100644 --- a/plugins/imptcp/imptcp.c +++ b/plugins/imptcp/imptcp.c @@ -30,6 +30,13 @@ * A copy of the GPL can be found in the file "COPYING" in this distribution. */ #include "config.h" +#if !defined(HAVE_EPOLL_CREATE) +# error imptcp requires OS support for epoll - can not build + /* imptcp gains speed by using modern Linux capabilities. As such, + * it can only be build on platforms supporting the epoll API. + */ +#endif + #include <stdio.h> #include <stdlib.h> #include <assert.h> @@ -1039,7 +1046,18 @@ CODESTARTwillRun ABORT_FINALIZE(RS_RET_NO_RUN); } - if((epollfd = epoll_create1(EPOLL_CLOEXEC)) < 0) { +# if defined(EPOLL_CLOEXEC) && defined(HAVE_EPOLL_CREATE1) + DBGPRINTF("imptcp uses epoll_create1()\n"); + epollfd = epoll_create1(EPOLL_CLOEXEC); +# else + DBGPRINTF("imptcp uses epoll_create()\n"); + /* reading the docs, the number of epoll events passed to + * epoll_create() seems not to be used at all in kernels. So + * we just provide "a" number, happens to be 10. + */ + epollfd = epoll_create(10); +# endif + if(epollfd < 0) { errmsg.LogError(0, RS_RET_EPOLL_CR_FAILED, "error: epoll_create() failed"); ABORT_FINALIZE(RS_RET_NO_RUN); } diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 41bff4f..0eee112 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -66,6 +66,10 @@ MODULE_TYPE_INPUT #endif #endif +/* emulate struct ucred for platforms that do not have it */ +#ifndef HAVE_SCM_CREDENTIALS +struct ucred { int pid; }; +#endif /* handle some defines missing on more than one platform */ #ifndef SUN_LEN @@ -279,7 +283,7 @@ addLstnSocketName(void __attribute__((unused)) *pVal, uchar *pNewVal) } CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName)); if(ratelimitInterval > 0) { - if((listeners[nfd].ht = create_hashtable(1000, hash_from_key_fn, key_equals_fn, NULL)) == NULL) { + if((listeners[nfd].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) { /* in this case, we simply turn of rate-limiting */ dbgprintf("imuxsock: turning off rate limiting because we could not " "create hash table\n"); @@ -406,6 +410,7 @@ openLogSocket(lstn_t *pLstn) CHKiRet(createLogSocket(pLstn)); } +# if HAVE_SCM_CREDENTIALS if(pLstn->bUseCreds) { one = 1; if(setsockopt(pLstn->fd, SOL_SOCKET, SO_PASSCRED, &one, (socklen_t) sizeof(one)) != 0) { @@ -417,6 +422,9 @@ openLogSocket(lstn_t *pLstn) pLstn->bUseCreds = 0; } } +# else /* HAVE_SCM_CREDENTIALS */ + pLstn->bUseCreds = 0; +# endif /* HAVE_SCM_CREDENTIALS */ finalize_it: if(iRet != RS_RET_OK) { @@ -513,7 +521,7 @@ SubmitMsg(uchar *pRcv, int lenRcv, lstn_t *pLstn, struct ucred *cred) rs_ratelimit_state_t *ratelimiter = NULL; DEFiRet; -// TODO: handle format errors?? + /* TODO: handle format errors?? */ /* we need to parse the pri first, because we need the severity for * rate-limiting as well. */ @@ -530,8 +538,10 @@ SubmitMsg(uchar *pRcv, int lenRcv, lstn_t *pLstn, struct ucred *cred) facil = LOG_FAC(pri); sever = LOG_PRI(pri); - if(sever >= pLstn->ratelimitSev) + if(sever >= pLstn->ratelimitSev) { + /* note: if cred == NULL, then ratelimiter == NULL as well! */ findRatelimiter(pLstn, cred, &ratelimiter); /* ignore error, better so than others... */ + } datetime.getCurrTime(&st, &tt); if(ratelimiter != NULL && !withinRatelimit(ratelimiter, tt, cred->pid)) { @@ -637,6 +647,7 @@ static rsRetVal readSocket(lstn_t *pLstn) dbgprintf("Message from UNIX socket: #%d\n", pLstn->fd); if(iRcvd > 0) { cred = NULL; +# if HAVE_SCM_CREDENTIALS if(pLstn->bUseCreds) { dbgprintf("XXX: pre CM loop, length of control message %d\n", (int) msgh.msg_controllen); for (cm = CMSG_FIRSTHDR(&msgh); cm; cm = CMSG_NXTHDR(&msgh, cm)) { @@ -644,11 +655,12 @@ static rsRetVal readSocket(lstn_t *pLstn) if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_CREDENTIALS) { cred = (struct ucred*) CMSG_DATA(cm); dbgprintf("XXX: got credentials pid %d\n", (int) cred->pid); - //break; + break; } } dbgprintf("XXX: post CM loop\n"); } +# endif /* HAVE_SCM_CREDENTIALS */ CHKiRet(SubmitMsg(pRcv, iRcvd, pLstn, cred)); } else if(iRcvd < 0 && errno != EINTR) { char errStr[1024]; @@ -749,7 +761,7 @@ CODESTARTwillRun if(pLogSockName != NULL) listeners[0].sockName = pLogSockName; if(ratelimitIntervalSysSock > 0) { - if((listeners[0].ht = create_hashtable(1000, hash_from_key_fn, key_equals_fn, NULL)) == NULL) { + if((listeners[0].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) { /* in this case, we simply turn of rate-limiting */ dbgprintf("imuxsock: turning off rate limiting because we could not " "create hash table\n"); diff --git a/rsyslog.service.in b/rsyslog.service.in index ea966cc..b3c5551 100644 --- a/rsyslog.service.in +++ b/rsyslog.service.in @@ -6,3 +6,4 @@ ExecStart=@sbindir@/rsyslogd -n -c5 [Install] WantedBy=multi-user.target +Also=rsyslog.socket diff --git a/runtime/Makefile.am b/runtime/Makefile.am index 93817e7..09cb6b4 100644 --- a/runtime/Makefile.am +++ b/runtime/Makefile.am @@ -7,6 +7,7 @@ pkglib_LTLIBRARIES = librsyslog_la_SOURCES = \ rsyslog.c \ rsyslog.h \ + typedefs.h \ unicode-helper.h \ atomic.h \ batch.h \ diff --git a/runtime/Makefile.in b/runtime/Makefile.in index 108cfda..23914dc 100644 --- a/runtime/Makefile.in +++ b/runtime/Makefile.in @@ -391,6 +391,7 @@ pkglib_LTLIBRARIES = $(am__append_1) $(am__append_2) $(am__append_3) \ librsyslog_la_SOURCES = \ rsyslog.c \ rsyslog.h \ + typedefs.h \ unicode-helper.h \ atomic.h \ batch.h \ diff --git a/runtime/atomic.h b/runtime/atomic.h index da544c4..790cb1c 100644 --- a/runtime/atomic.h +++ b/runtime/atomic.h @@ -33,6 +33,8 @@ */ #ifndef INCLUDED_ATOMIC_H #define INCLUDED_ATOMIC_H +#include <time.h> +#include "typedefs.h" /* for this release, we disable atomic calls because there seem to be some * portability problems and we can not fix that without destabilizing the build. @@ -42,7 +44,9 @@ # define ATOMIC_SUB(data, val, phlpmut) __sync_fetch_and_sub(data, val) # define ATOMIC_ADD(data, val) __sync_fetch_and_add(&(data), val) # define ATOMIC_INC(data, phlpmut) ((void) __sync_fetch_and_add(data, 1)) -# define ATOMIC_INC_AND_FETCH(data, phlpmut) __sync_fetch_and_add(data, 1) +# define ATOMIC_INC_AND_FETCH_int(data, phlpmut) __sync_fetch_and_add(data, 1) +# define ATOMIC_INC_AND_FETCH_unsigned(data, phlpmut) __sync_fetch_and_add(data, 1) +# define ATOMIC_INC_AND_FETCH_uint64(data, phlpmut) __sync_fetch_and_add(data, 1) # define ATOMIC_DEC(data, phlpmut) ((void) __sync_sub_and_fetch(data, 1)) # define ATOMIC_DEC_AND_FETCH(data, phlpmut) __sync_sub_and_fetch(data, 1) # define ATOMIC_FETCH_32BIT(data, phlpmut) ((unsigned) __sync_fetch_and_and(data, 0xffffffff)) @@ -51,6 +55,7 @@ # define ATOMIC_STORE_1_TO_INT(data, phlpmut) __sync_fetch_and_or(data, 1) # define ATOMIC_STORE_INT_TO_INT(data, val) __sync_fetch_and_or(&(data), (val)) # define ATOMIC_CAS(data, oldVal, newVal, phlpmut) __sync_bool_compare_and_swap(data, (oldVal), (newVal)) +# define ATOMIC_CAS_time_t(data, oldVal, newVal, phlpmut) __sync_bool_compare_and_swap(data, (oldVal), (newVal)) # define ATOMIC_CAS_VAL(data, oldVal, newVal, phlpmut) __sync_val_compare_and_swap(data, (oldVal), (newVal)); /* functions below are not needed if we have atomics */ @@ -104,6 +109,20 @@ return(bSuccess); } + static inline int + ATOMIC_CAS_time_t(time_t *data, time_t oldVal, time_t newVal, pthread_mutex_t *phlpmut) { + int bSuccess; + pthread_mutex_lock(phlpmut); + if(*data == oldVal) { + *data = newVal; + bSuccess = 1; + } else { + bSuccess = 0; + } + pthread_mutex_unlock(phlpmut); + return(bSuccess); + } + static inline int ATOMIC_CAS_VAL(int *data, int oldVal, int newVal, pthread_mutex_t *phlpmut) { @@ -124,7 +143,7 @@ } static inline int - ATOMIC_INC_AND_FETCH(int *data, pthread_mutex_t *phlpmut) { + ATOMIC_INC_AND_FETCH_int(int *data, pthread_mutex_t *phlpmut) { int val; pthread_mutex_lock(phlpmut); val = ++(*data); @@ -132,6 +151,24 @@ return(val); } + static inline unsigned + ATOMIC_INC_AND_FETCH_unsigned(unsigned *data, pthread_mutex_t *phlpmut) { + unsigned val; + pthread_mutex_lock(phlpmut); + val = ++(*data); + pthread_mutex_unlock(phlpmut); + return(val); + } + + static inline unsigned + ATOMIC_INC_AND_FETCH_uint64(uint64 *data, pthread_mutex_t *phlpmut) { + uint64 val; + pthread_mutex_lock(phlpmut); + val = ++(*data); + pthread_mutex_unlock(phlpmut); + return(val); + } + static inline int ATOMIC_DEC_AND_FETCH(int *data, pthread_mutex_t *phlpmut) { int val; @@ -158,7 +195,9 @@ } #if 0 # warning "atomic builtins not available, using nul operations - rsyslogd will probably be racy!" -# define ATOMIC_INC_AND_FETCH(data) (++(data)) +# define ATOMIC_INC_AND_FETCH_int(data) (++(data)) +# define ATOMIC_INC_AND_FETCH_unsigned(data) (++(data)) +# define ATOMIC_INC_AND_FETCH_uint64(data) (++(data)) # define ATOMIC_STORE_1_TO_32BIT(data) (data) = 1 // TODO: del #endif # define DEF_ATOMIC_HELPER_MUT(x) pthread_mutex_t x diff --git a/runtime/hashtable.c b/runtime/hashtable.c index 41fc60f..a01fa7d 100644 --- a/runtime/hashtable.c +++ b/runtime/hashtable.c @@ -23,7 +23,17 @@ static const unsigned int primes[] = { 805306457, 1610612741 }; const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]); -const float max_load_factor = 0.65; + +#define MAX_LOAD_FACTOR 65 /* to get real factor, divide by 100! */ + +/* compute max load. We use a constant factor of 0.65, but do + * everything times 100, so that we do not need floats. + */ +static inline unsigned +getLoadLimit(unsigned size) +{ + return (unsigned int) ((unsigned long long) size * MAX_LOAD_FACTOR) / 100; +} /*****************************************************************************/ struct hashtable * @@ -50,7 +60,7 @@ create_hashtable(unsigned int minsize, h->hashfn = hashf; h->eqfn = eqf; h->dest = dest; - h->loadlimit = (unsigned int) ceil(size * max_load_factor); + h->loadlimit = getLoadLimit(size); return h; } @@ -123,7 +133,7 @@ hashtable_expand(struct hashtable *h) } } h->tablelength = newsize; - h->loadlimit = (unsigned int) ceil(newsize * max_load_factor); + h->loadlimit = getLoadLimit(newsize); return -1; } diff --git a/runtime/msg.c b/runtime/msg.c index 1b18826..82565f1 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -851,7 +851,7 @@ CODESTARTobjDestruct(msg) * that we trim too often when the counter wraps. */ static unsigned iTrimCtr = 1; - currCnt = ATOMIC_INC_AND_FETCH(&iTrimCtr, &mutTrimCtr); + currCnt = ATOMIC_INC_AND_FETCH_unsigned(&iTrimCtr, &mutTrimCtr); if(currCnt % 100000 == 0) { malloc_trim(128*1024); } @@ -2588,7 +2588,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, bFound = 1; } else { dbgprintf("regex found at offset %d, new offset %d, tries %d\n", - iOffs, iOffs + pmatch[0].rm_eo, iTry); + iOffs, (int) (iOffs + pmatch[0].rm_eo), iTry); iOffs += pmatch[0].rm_eo; ++iTry; } diff --git a/runtime/msg.h b/runtime/msg.h index d42f1de..4897959 100644 --- a/runtime/msg.h +++ b/runtime/msg.h @@ -60,8 +60,8 @@ struct msg { flowControl_t flowCtlType; /**< type of flow control we can apply, for enqueueing, needs not to be persisted because once data has entered the queue, this property is no longer needed. */ pthread_mutex_t mut; + int iRefCount; /* reference counter (0 = unused) */ sbool bDoLock; /* use the mutex? */ - short iRefCount; /* reference counter (0 = unused) */ short iSeverity; /* the severity 0..7 */ short iFacility; /* Facility code 0 .. 23*/ short offAfterPRI; /* offset, at which raw message WITHOUT PRI part starts in pszRawMsg */ diff --git a/runtime/nsdpoll_ptcp.c b/runtime/nsdpoll_ptcp.c index 5100670..bc374c6 100644 --- a/runtime/nsdpoll_ptcp.c +++ b/runtime/nsdpoll_ptcp.c @@ -42,7 +42,6 @@ #include "nspoll.h" #include "nsd_ptcp.h" #include "nsdpoll_ptcp.h" -#include "unlimited_select.h" /* static data */ DEFobjStaticHelpers diff --git a/runtime/nsdsel_gtls.c b/runtime/nsdsel_gtls.c index c3a93be..1a389a0 100644 --- a/runtime/nsdsel_gtls.c +++ b/runtime/nsdsel_gtls.c @@ -76,6 +76,9 @@ Add(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp) if(pNsdGTLS->iMode == 1) { if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) { ++pThis->iBufferRcvReady; + dbgprintf("nsdsel_gtls: data already present in buffer, initiating " + "dummy select %p->iBufferRcvReady=%d\n", + pThis, pThis->iBufferRcvReady); FINALIZE; } if(pNsdGTLS->rtryCall != gtlsRtry_None) { @@ -109,6 +112,7 @@ Select(nsdsel_t *pNsdsel, int *piNumReady) if(pThis->iBufferRcvReady > 0) { /* we still have data ready! */ *piNumReady = pThis->iBufferRcvReady; + dbgprintf("nsdsel_gtls: doing dummy select, data present\n"); } else { iRet = nsdsel_ptcp.Select(pThis->pTcp, piNumReady); } @@ -190,6 +194,9 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady) if(pNsdGTLS->iMode == 1) { if(waitOp == NSDSEL_RD && gtlsHasRcvInBuffer(pNsdGTLS)) { *pbIsReady = 1; + --pThis->iBufferRcvReady; /* one "pseudo-read" less */ + dbgprintf("nsdl_gtls: dummy read, decermenting %p->iBufRcvReady, now %d\n", + pThis, pThis->iBufferRcvReady); FINALIZE; } if(pNsdGTLS->rtryCall != gtlsRtry_None) { @@ -200,6 +207,16 @@ IsReady(nsdsel_t *pNsdsel, nsd_t *pNsd, nsdsel_waitOp_t waitOp, int *pbIsReady) *pbIsReady = 0; FINALIZE; } + /* now we must ensure that we do not fall back to PTCP if we have + * done a "dummy" select. In that case, we know when the predicate + * is not matched here, we do not have data available for this + * socket. -- rgerhards, 2010-11-20 + */ + if(pThis->iBufferRcvReady) { + dbgprintf("nsd_gtls: dummy read, buffer not available for this FD\n"); + *pbIsReady = 0; + FINALIZE; + } } CHKiRet(nsdsel_ptcp.IsReady(pThis->pTcp, pNsdGTLS->pTcp, waitOp, pbIsReady)); diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index 7ccc9cb..b47ef82 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -25,6 +25,7 @@ */ #ifndef INCLUDED_RSYSLOG_H #define INCLUDED_RSYSLOG_H +#include "typedefs.h" /* ############################################################# * * # Some constant values # * @@ -94,129 +95,6 @@ #define CORE_FEATURE_BATCHING 1 /*#define CORE_FEATURE_whatever 2 ... and so on ... */ -/* under Solaris (actually only SPARC), we need to redefine some types - * to be void, so that we get void* pointers. Otherwise, we will see - * alignment errors. - */ -/* some universal fixed size integer defines ... */ -typedef long long int64; -typedef long long unsigned uint64; -typedef int64 number_t; /* type to use for numbers - TODO: maybe an autoconf option? */ -typedef char intTiny; /* 0..127! */ -typedef unsigned char uintTiny; /* 0..255! */ - -/* define some base data types */ - -typedef unsigned char uchar;/* get rid of the unhandy "unsigned char" */ -typedef struct aUsrp_s aUsrp_t; -typedef struct thrdInfo thrdInfo_t; -typedef struct obj_s obj_t; -typedef struct ruleset_s ruleset_t; -typedef struct rule_s rule_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 struct nspoll_s nspoll_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 struct nsdpoll_ptcp_s nsdpoll_ptcp_t; -typedef struct wti_s wti_t; -typedef struct msg msg_t; -typedef struct queue_s qqueue_t; -typedef struct prop_s prop_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 permittedPeers_s permittedPeers_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */ -typedef struct permittedPeerWildcard_s permittedPeerWildcard_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */ -typedef struct tcpsrv_s tcpsrv_t; -typedef struct tcps_sess_s tcps_sess_t; -typedef struct strmsrv_s strmsrv_t; -typedef struct strms_sess_s strms_sess_t; -typedef struct vmstk_s vmstk_t; -typedef struct batch_obj_s batch_obj_t; -typedef struct batch_s batch_t; -typedef struct wtp_s wtp_t; -typedef struct modInfo_s modInfo_t; -typedef struct parser_s parser_t; -typedef struct parserList_s parserList_t; -typedef struct strgen_s strgen_t; -typedef struct strgenList_s strgenList_t; -typedef struct statsobj_s statsobj_t; -typedef struct statsctr_s statsctr_t; -typedef rsRetVal (*prsf_t)(struct vmstk_s*, int); /* pointer to a RainerScript function */ -typedef uint64 qDeqID; /* queue Dequeue order ID. 32 bits is considered dangerously few */ - -typedef struct tcpLstnPortList_s tcpLstnPortList_t; // TODO: rename? -typedef struct strmLstnPortList_s strmLstnPortList_t; // TODO: rename? - -/* under Solaris (actually only SPARC), we need to redefine some types - * to be void, so that we get void* pointers. Otherwise, we will see - * alignment errors. - */ -#ifdef OS_SOLARIS - typedef void * obj_t_ptr; - typedef void nsd_t; - typedef void nsdsel_t; - typedef void nsdpoll_t; -#else - typedef obj_t *obj_t_ptr; - typedef obj_t nsd_t; - typedef obj_t nsdsel_t; - typedef obj_t nsdpoll_t; -#endif - - -#ifdef __hpux -typedef unsigned int u_int32_t; /* TODO: is this correct? */ -typedef int socklen_t; -#endif - -typedef struct epoll_event epoll_event_t; - -typedef char sbool; /* (small bool) I intentionally use char, to keep it slim so that many fit into the CPU cache! */ - -/* settings for flow control - * TODO: is there a better place for them? -- rgerhards, 2008-03-14 - */ -typedef enum { - eFLOWCTL_NO_DELAY = 0, /**< UDP and other non-delayable sources */ - eFLOWCTL_LIGHT_DELAY = 1, /**< some light delay possible, but no extended period of time */ - eFLOWCTL_FULL_DELAY = 2 /**< delay possible for extended period of time */ -} flowControl_t; - -/* filter operations */ -typedef enum { - FIOP_NOP = 0, /* do not use - No Operation */ - FIOP_CONTAINS = 1, /* contains string? */ - FIOP_ISEQUAL = 2, /* is (exactly) equal? */ - FIOP_STARTSWITH = 3, /* starts with a string? */ - FIOP_REGEX = 4, /* matches a (BRE) regular expression? */ - FIOP_EREREGEX = 5 /* matches a ERE regular expression? */ -} fiop_t; - - -/* multi-submit support. - * This is done via a simple data structure, which holds the number of elements - * as well as an array of to-be-submitted messages. - * rgerhards, 2009-06-16 - */ -typedef struct multi_submit_s multi_submit_t; -struct multi_submit_s { - short maxElem; /* maximum number of Elements */ - short nElem; /* current number of Elements, points to the next one FREE */ - msg_t **ppMsgs; -}; - - #ifndef _PATH_CONSOLE #define _PATH_CONSOLE "/dev/console" #endif diff --git a/runtime/stream.c b/runtime/stream.c index b429576..260b59e 100644 --- a/runtime/stream.c +++ b/runtime/stream.c @@ -60,7 +60,14 @@ # include <sys/prctl.h> #endif -#define inline +/* some platforms do not have large file support :( */ +#ifndef O_LARGEFILE +# define O_LARGEFILE 0 +#endif +#ifndef HAVE_LSEEK64 + typedef off_t off64_t; +# define lseek64(fd, offset, whence) lseek(fd, offset, whence) +#endif /* static data */ DEFobjStaticHelpers @@ -214,7 +221,7 @@ doPhysOpen(strm_t *pThis) iFlags |= O_NONBLOCK; } - pThis->fd = open((char*)pThis->pszCurrFName, iFlags, pThis->tOpenMode); + pThis->fd = open((char*)pThis->pszCurrFName, iFlags | O_LARGEFILE, pThis->tOpenMode); DBGPRINTF("file '%s' opened as #%d with mode %d\n", pThis->pszCurrFName, pThis->fd, (int) pThis->tOpenMode); if(pThis->fd == -1) { @@ -1184,7 +1191,7 @@ finalize_it: * is invalidated. * rgerhards, 2008-01-12 */ -static rsRetVal strmSeek(strm_t *pThis, off_t offs) +static rsRetVal strmSeek(strm_t *pThis, off64_t offs) { DEFiRet; @@ -1194,9 +1201,9 @@ static rsRetVal strmSeek(strm_t *pThis, off_t offs) strmOpenFile(pThis); else strmFlushInternal(pThis); - int i; - DBGOPRINT((obj_t*) pThis, "file %d seek, pos %ld\n", pThis->fd, (long) offs); - i = lseek(pThis->fd, offs, SEEK_SET); // TODO: check error! + long long i; + DBGOPRINT((obj_t*) pThis, "file %d seek, pos %llu\n", pThis->fd, (long long unsigned) offs); + i = lseek64(pThis->fd, offs, SEEK_SET); // TODO: check error! pThis->iCurrOffs = offs; /* we are now at *this* offset */ pThis->iBufPtr = 0; /* buffer invalidated */ @@ -1473,7 +1480,7 @@ static rsRetVal strmSerialize(strm_t *pThis, strm_t *pStrm) { DEFiRet; int i; - long l; + int64 l; ISOBJ_TYPE_assert(pThis, strm); ISOBJ_TYPE_assert(pStrm, strm); @@ -1495,8 +1502,8 @@ static rsRetVal strmSerialize(strm_t *pThis, strm_t *pStrm) i = pThis->tOpenMode; objSerializeSCALAR_VAR(pStrm, tOpenMode, INT, i); - l = (long) pThis->iCurrOffs; - objSerializeSCALAR_VAR(pStrm, iCurrOffs, LONG, l); + l = pThis->iCurrOffs; + objSerializeSCALAR_VAR(pStrm, iCurrOffs, INT64, l); CHKiRet(obj.EndSerialize(pStrm)); diff --git a/runtime/typedefs.h b/runtime/typedefs.h new file mode 100644 index 0000000..d3da769 --- /dev/null +++ b/runtime/typedefs.h @@ -0,0 +1,148 @@ +/* This defines some types commonly used. Do NOT include any other + * rsyslog runtime file. + * + * Begun 2010-11-25 RGerhards + * + * Copyright (C) 2005-2008 by 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_TYPEDEFS_H +#define INCLUDED_TYPEDEFS_H + +/* some universal fixed size integer defines ... */ +typedef long long int64; +typedef long long unsigned uint64; +typedef int64 number_t; /* type to use for numbers - TODO: maybe an autoconf option? */ +typedef char intTiny; /* 0..127! */ +typedef unsigned char uintTiny; /* 0..255! */ + +/* define some base data types */ + +typedef unsigned char uchar;/* get rid of the unhandy "unsigned char" */ +typedef struct aUsrp_s aUsrp_t; +typedef struct thrdInfo thrdInfo_t; +typedef struct obj_s obj_t; +typedef struct ruleset_s ruleset_t; +typedef struct rule_s rule_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 struct nspoll_s nspoll_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 struct nsdpoll_ptcp_s nsdpoll_ptcp_t; +typedef struct wti_s wti_t; +typedef struct msg msg_t; +typedef struct queue_s qqueue_t; +typedef struct prop_s prop_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 permittedPeers_s permittedPeers_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */ +typedef struct permittedPeerWildcard_s permittedPeerWildcard_t; /* this should go away in the long term -- rgerhards, 2008-05-19 */ +typedef struct tcpsrv_s tcpsrv_t; +typedef struct tcps_sess_s tcps_sess_t; +typedef struct strmsrv_s strmsrv_t; +typedef struct strms_sess_s strms_sess_t; +typedef struct vmstk_s vmstk_t; +typedef struct batch_obj_s batch_obj_t; +typedef struct batch_s batch_t; +typedef struct wtp_s wtp_t; +typedef struct modInfo_s modInfo_t; +typedef struct parser_s parser_t; +typedef struct parserList_s parserList_t; +typedef struct strgen_s strgen_t; +typedef struct strgenList_s strgenList_t; +typedef struct statsobj_s statsobj_t; +typedef rsRetVal (*prsf_t)(struct vmstk_s*, int); /* pointer to a RainerScript function */ +typedef uint64 qDeqID; /* queue Dequeue order ID. 32 bits is considered dangerously few */ + +typedef struct tcpLstnPortList_s tcpLstnPortList_t; // TODO: rename? +typedef struct strmLstnPortList_s strmLstnPortList_t; // TODO: rename? + +/* under Solaris (actually only SPARC), we need to redefine some types + * to be void, so that we get void* pointers. Otherwise, we will see + * alignment errors. + */ +#ifdef OS_SOLARIS + typedef void * obj_t_ptr; + typedef void nsd_t; + typedef void nsdsel_t; + typedef void nsdpoll_t; +#else + typedef obj_t *obj_t_ptr; + typedef obj_t nsd_t; + typedef obj_t nsdsel_t; + typedef obj_t nsdpoll_t; +#endif + + +#ifdef __hpux +typedef unsigned int u_int32_t; /* TODO: is this correct? */ +typedef int socklen_t; +#endif + +typedef struct epoll_event epoll_event_t; + +typedef char sbool; /* (small bool) I intentionally use char, to keep it slim so that many fit into the CPU cache! */ + +/* settings for flow control + * TODO: is there a better place for them? -- rgerhards, 2008-03-14 + */ +typedef enum { + eFLOWCTL_NO_DELAY = 0, /**< UDP and other non-delayable sources */ + eFLOWCTL_LIGHT_DELAY = 1, /**< some light delay possible, but no extended period of time */ + eFLOWCTL_FULL_DELAY = 2 /**< delay possible for extended period of time */ +} flowControl_t; + +/* filter operations */ +typedef enum { + FIOP_NOP = 0, /* do not use - No Operation */ + FIOP_CONTAINS = 1, /* contains string? */ + FIOP_ISEQUAL = 2, /* is (exactly) equal? */ + FIOP_STARTSWITH = 3, /* starts with a string? */ + FIOP_REGEX = 4, /* matches a (BRE) regular expression? */ + FIOP_EREREGEX = 5 /* matches a ERE regular expression? */ +} fiop_t; + + +/* multi-submit support. + * This is done via a simple data structure, which holds the number of elements + * as well as an array of to-be-submitted messages. + * rgerhards, 2009-06-16 + */ +typedef struct multi_submit_s multi_submit_t; +struct multi_submit_s { + short maxElem; /* maximum number of Elements */ + short nElem; /* current number of Elements, points to the next one FREE */ + msg_t **ppMsgs; +}; + +#endif /* multi-include protection */ +/* vim:set ai: + */ diff --git a/runtime/unlimited_select.h b/runtime/unlimited_select.h index 32dadc0..3fa7eb0 100644 --- a/runtime/unlimited_select.h +++ b/runtime/unlimited_select.h @@ -23,6 +23,7 @@ */ #ifndef UNLIMITED_SELECT_H_INCLUDED +#define UNLIMITED_SELECT_H_INCLUDED #include <string.h> #include <stdlib.h> @@ -85,7 +85,7 @@ rsRetVal tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t * { DEFiRet; struct templateEntry *pTpe; - int iBuf; + size_t iBuf; unsigned short bMustBeFreed; uchar *pVal; size_t iLenVal; @@ -141,7 +141,15 @@ rsRetVal tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t * pTpe = pTpe->pNext; } - (*ppBuf)[iBuf] = '\0'; /* space was reserved above (see copy) */ + if(iBuf == *pLenBuf) { + /* in the weired case of an *empty* template, this can happen. + * it is debatable if we should really fix it here or simply + * forbid that case. However, performance toll is minimal, so + * I tend to permit it. -- 201011-05 rgerhards + */ + CHKiRet(ExtendBuf(ppBuf, pLenBuf, iBuf + 1)); + } + (*ppBuf)[iBuf] = '\0'; finalize_it: RETiRet; diff --git a/tests/Makefile.am b/tests/Makefile.am index 62d4522..25d972d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -14,9 +14,6 @@ TESTS = $(TESTRUNS) cfg.sh \ manytcp.sh \ rsf_getenv.sh \ manyptcp.sh \ - imptcp_large.sh \ - imptcp_addtlframedelim.sh \ - imptcp_conndrop.sh \ imtcp_conndrop.sh \ imtcp_addtlframedelim.sh \ sndrcv.sh \ @@ -51,6 +48,13 @@ TESTS = $(TESTRUNS) cfg.sh \ dircreate_off.sh \ queue-persist.sh +if ENABLE_IMPTCP +TESTS += \ + imptcp_large.sh \ + imptcp_addtlframedelim.sh \ + imptcp_conndrop.sh +endif + if ENABLE_OMUDPSPOOF TESTS += sndrcv_omudpspoof.sh \ sndrcv_omudpspoof_nonstdpt.sh @@ -314,11 +318,13 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/dircreate_off.conf \ cfg.sh -uxsockrcvr_SOURCES = uxsockrcvr.c ourtail_SOURCES = ourtail.c msleep_SOURCES = msleep.c chkseq_SOURCES = chkseq.c +uxsockrcvr_SOURCES = uxsockrcvr.c +uxsockrcvr_LDADD = $(SOL_LIBS) + tcpflood_SOURCES = tcpflood.c tcpflood_LDADD = $(SOL_LIBS) diff --git a/tests/Makefile.in b/tests/Makefile.in index 2b09841..5f21c8a 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -45,9 +45,7 @@ host_triplet = @host@ @ENABLE_TESTBENCH_TRUE@ daqueue-persist.sh diskqueue.sh \ @ENABLE_TESTBENCH_TRUE@ diskqueue-fsync.sh rulesetmultiqueue.sh \ @ENABLE_TESTBENCH_TRUE@ manytcp.sh rsf_getenv.sh manyptcp.sh \ -@ENABLE_TESTBENCH_TRUE@ imptcp_large.sh \ -@ENABLE_TESTBENCH_TRUE@ imptcp_addtlframedelim.sh \ -@ENABLE_TESTBENCH_TRUE@ imptcp_conndrop.sh imtcp_conndrop.sh \ +@ENABLE_TESTBENCH_TRUE@ imtcp_conndrop.sh \ @ENABLE_TESTBENCH_TRUE@ imtcp_addtlframedelim.sh sndrcv.sh \ @ENABLE_TESTBENCH_TRUE@ sndrcv_gzip.sh sndrcv_udp.sh \ @ENABLE_TESTBENCH_TRUE@ sndrcv_udp_nonstdpt.sh asynwr_simple.sh \ @@ -68,11 +66,17 @@ host_triplet = @host@ @ENABLE_TESTBENCH_TRUE@ pipe_noreader.sh dircreate_dflt.sh \ @ENABLE_TESTBENCH_TRUE@ dircreate_off.sh queue-persist.sh \ @ENABLE_TESTBENCH_TRUE@ $(am__append_1) $(am__append_2) \ -@ENABLE_TESTBENCH_TRUE@ $(am__append_3) $(am__append_4) -@ENABLE_OMUDPSPOOF_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_1 = sndrcv_omudpspoof.sh \ +@ENABLE_TESTBENCH_TRUE@ $(am__append_3) $(am__append_4) \ +@ENABLE_TESTBENCH_TRUE@ $(am__append_5) +@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_1 = \ +@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_large.sh \ +@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_addtlframedelim.sh \ +@ENABLE_IMPTCP_TRUE@@ENABLE_TESTBENCH_TRUE@ imptcp_conndrop.sh + +@ENABLE_OMUDPSPOOF_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_2 = sndrcv_omudpspoof.sh \ @ENABLE_OMUDPSPOOF_TRUE@@ENABLE_TESTBENCH_TRUE@ sndrcv_omudpspoof_nonstdpt.sh -@ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_2 = omod-if-array.sh \ +@ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_3 = omod-if-array.sh \ @ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@ proprepltest.sh \ @ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@ parsertest.sh \ @ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@ timestamp.sh \ @@ -85,10 +89,10 @@ host_triplet = @host@ @ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@ tabescape_off.sh \ @ENABLE_OMSTDOUT_TRUE@@ENABLE_TESTBENCH_TRUE@ fieldtest.sh -@ENABLE_OMRULESET_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_3 = omruleset.sh \ +@ENABLE_OMRULESET_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_4 = omruleset.sh \ @ENABLE_OMRULESET_TRUE@@ENABLE_TESTBENCH_TRUE@ omruleset-queue.sh -@ENABLE_EXTENDED_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_4 = random.sh +@ENABLE_EXTENDED_TESTS_TRUE@@ENABLE_TESTBENCH_TRUE@am__append_5 = random.sh subdir = tests DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ INSTALL @@ -153,7 +157,7 @@ tcpflood_OBJECTS = $(am_tcpflood_OBJECTS) tcpflood_DEPENDENCIES = $(am__DEPENDENCIES_1) am_uxsockrcvr_OBJECTS = uxsockrcvr.$(OBJEXT) uxsockrcvr_OBJECTS = $(am_uxsockrcvr_OBJECTS) -uxsockrcvr_LDADD = $(LDADD) +uxsockrcvr_DEPENDENCIES = $(am__DEPENDENCIES_1) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -572,10 +576,11 @@ EXTRA_DIST = 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/dircreate_off.conf \ cfg.sh -uxsockrcvr_SOURCES = uxsockrcvr.c ourtail_SOURCES = ourtail.c msleep_SOURCES = msleep.c chkseq_SOURCES = chkseq.c +uxsockrcvr_SOURCES = uxsockrcvr.c +uxsockrcvr_LDADD = $(SOL_LIBS) tcpflood_SOURCES = tcpflood.c tcpflood_LDADD = $(SOL_LIBS) syslog_caller_SOURCES = syslog_caller.c diff --git a/tests/nettester.c b/tests/nettester.c index 7c8c413..9e68ebc 100644 --- a/tests/nettester.c +++ b/tests/nettester.c @@ -401,8 +401,8 @@ processTestFile(int fd, char *pszFileName) } if(strcmp(expected, buf)) { ++iFailed; - printf("\nExpected Response:\n'%s'\nActual Response:\n'%s'\n", - expected, buf); + printf("\nFile %s:\nExpected Response:\n'%s'\nActual Response:\n'%s'\n", + pszFileName, expected, buf); ret = 1; } diff --git a/tools/Makefile.am b/tools/Makefile.am index 6541194..96657ad 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -36,7 +36,7 @@ rsyslogd_SOURCES = \ \ ../dirty.h rsyslogd_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) -rsyslogd_LDADD = $(ZLIB_LIBS) $(PTHREADS_LIBS) $(RSRT_LIBS) $(SOL_LIBS) -lm +rsyslogd_LDADD = $(ZLIB_LIBS) $(PTHREADS_LIBS) $(RSRT_LIBS) $(SOL_LIBS) rsyslogd_LDFLAGS = -export-dynamic if ENABLE_DIAGTOOLS diff --git a/tools/Makefile.in b/tools/Makefile.in index 3aca095..289e21b 100644 --- a/tools/Makefile.in +++ b/tools/Makefile.in @@ -327,7 +327,7 @@ rsyslogd_SOURCES = \ ../dirty.h rsyslogd_CPPFLAGS = $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) -rsyslogd_LDADD = $(ZLIB_LIBS) $(PTHREADS_LIBS) $(RSRT_LIBS) $(SOL_LIBS) -lm +rsyslogd_LDADD = $(ZLIB_LIBS) $(PTHREADS_LIBS) $(RSRT_LIBS) $(SOL_LIBS) rsyslogd_LDFLAGS = -export-dynamic @ENABLE_DIAGTOOLS_TRUE@rsyslog_diag_hostname_SOURCES = gethostn.c @ENABLE_DIAGTOOLS_TRUE@zpipe_SOURCES = zpipe.c diff --git a/tools/omfile.c b/tools/omfile.c index 57089cf..78f2bf8 100644 --- a/tools/omfile.c +++ b/tools/omfile.c @@ -98,7 +98,11 @@ static pthread_mutex_t mutClock; static inline uint64 getClockFileAccess(void) { - return ATOMIC_INC_AND_FETCH(&clockFileAccess, &mutClock); +#if HAVE_ATOMIC_BUILTINS_64BIT + return ATOMIC_INC_AND_FETCH_uint64(&clockFileAccess, &mutClock); +#else + return ATOMIC_INC_AND_FETCH_unsigned(&clockFileAccess, &mutClock); +#endif } diff --git a/tools/ompipe.c b/tools/ompipe.c index cf22bc8..c51a5c4 100644 --- a/tools/ompipe.c +++ b/tools/ompipe.c @@ -42,6 +42,7 @@ #include <assert.h> #include <errno.h> #include <fcntl.h> +#include <unistd.h> #include <sys/file.h> #include "syslogd.h" diff --git a/tools/omusrmsg.c b/tools/omusrmsg.c index e788a00..e61751d 100644 --- a/tools/omusrmsg.c +++ b/tools/omusrmsg.c @@ -143,7 +143,7 @@ void setutent(void) { assert(BSD_uf == NULL); if ((BSD_uf = fopen(_PATH_UTMP, "r")) == NULL) { - errmsg.LogError(NO_ERRCODE, "%s", _PATH_UTMP); + errmsg.LogError(0, NO_ERRCODE, "%s", _PATH_UTMP); return; } } |