summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-06-14 13:07:32 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-06-14 13:07:32 +0000
commit2112ef22ae40b421279221f77140f90e09308c39 (patch)
tree1e704e1ca6784ddd436963f39f71746e75253278
parentf925aba4ad669c6b96b348c0761ed0531c6f41b4 (diff)
downloadrsyslog-2112ef22ae40b421279221f77140f90e09308c39.tar.gz
rsyslog-2112ef22ae40b421279221f77140f90e09308c39.tar.xz
rsyslog-2112ef22ae40b421279221f77140f90e09308c39.zip
re-wrote syslog.c from scratch to solve a license compatibility issue,
provide some bug fixes and performance enhancemnts. Also required changes to klogd.c to support the new interface.
-rw-r--r--NEWS11
-rw-r--r--klogd.c200
-rw-r--r--klogd.h1
-rw-r--r--syslog.c322
-rw-r--r--syslogd.c3
-rw-r--r--version.h2
6 files changed, 203 insertions, 336 deletions
diff --git a/NEWS b/NEWS
index fde3a931..47fec761 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,15 @@
---------------------------------------------------------------------------
+Version 1.13.3 (RGer), 2007-??-??
+- create a version of syslog.c from scratch. This is now
+ - highly optimized for rsyslog
+ - removes an incompatible license problem as the original
+ version had a BSD license with advertising clause
+ - fixed in the regard that rklogd will continue to work when
+ rsysogd has been restarted (the original version, as well
+ as sysklogd, will remain silent then)
+ - solved an issue with an extra NUL char at message end that the
+ original version had
+---------------------------------------------------------------------------
Version 1.13.2 (RGer), 2007-06-13
- lib order in makefile patched to facilitate static linking - thanks
to Bennett Todd for providing the patch
diff --git a/klogd.c b/klogd.c
index 50f8538b..ee2ba4aa 100644
--- a/klogd.c
+++ b/klogd.c
@@ -275,6 +275,8 @@ _syscall3(int,ksyslog,int, type, char *, buf, int, len);
#include <sys/klog.h>
#define ksyslog klogctl
#endif
+extern int writeSyslogV(int pri, const char *szFmt, va_list va);
+extern int writeSyslog(int iPri, const char *szFmt, ...);
#ifndef _PATH_KLOG
#define _PATH_KLOG "/proc/kmsg"
@@ -332,8 +334,84 @@ static void LogProcLine(void);
extern int main(int argc, char *argv[]);
-static void CloseLogSrc()
+extern void Syslog(int priority, char *fmt, ...)
+{
+ va_list ap;
+ char *argl;
+
+ if ( debugging )
+ {
+ fputs("Logging line:\n", stderr);
+ fprintf(stderr, "\tLine: %s\n", fmt);
+ fprintf(stderr, "\tPriority: %d\n", priority);
+ }
+ /* Handle output to a file. */
+ if ( output_file != (FILE *) 0 ) {
+ va_start(ap, fmt);
+ vfprintf(output_file, fmt, ap);
+ va_end(ap);
+ fputc('\n', output_file);
+ fflush(output_file);
+ if (!one_shot)
+ fsync(fileno(output_file));
+ return;
+ }
+
+ /* Output using syslog. */
+ if (!strcmp(fmt, "%s")) {
+ va_start(ap, fmt);
+ argl = va_arg(ap, char *);
+ if (argl[0] == '<' && argl[1] && argl[2] == '>') {
+ switch ( argl[1] )
+ {
+ case '0':
+ priority = LOG_EMERG;
+ break;
+ case '1':
+ priority = LOG_ALERT;
+ break;
+ case '2':
+ priority = LOG_CRIT;
+ break;
+ case '3':
+ priority = LOG_ERR;
+ break;
+ case '4':
+ priority = LOG_WARNING;
+ break;
+ case '5':
+ priority = LOG_NOTICE;
+ break;
+ case '6':
+ priority = LOG_INFO;
+ break;
+ case '7':
+ default:
+ priority = LOG_DEBUG;
+ }
+ argl += 3;
+ }
+ writeSyslog(priority, fmt, argl);
+ va_end(ap);
+#ifdef TESTING
+ putchar('\n');
+#endif
+ return;
+ }
+
+ va_start(ap, fmt);
+ writeSyslogV(priority, fmt, ap);
+ va_end(ap);
+#ifdef TESTING
+ printf ("\n");
+#endif
+
+ return;
+}
+
+
+static void CloseLogSrc(void)
{
/* Turn on logging of messages to console. */
ksyslog(7, NULL, 0);
@@ -371,10 +449,7 @@ void restart(sig)
}
-void stop_logging(sig)
-
- int sig;
-
+void stop_logging(int sig)
{
signal(SIGTSTP, stop_logging);
change_state = 1;
@@ -383,20 +458,14 @@ void stop_logging(sig)
}
-void stop_daemon(sig)
-
- int sig;
-
+void stop_daemon(int sig)
{
Terminate();
return;
}
-void reload_daemon(sig)
-
- int sig;
-
+void reload_daemon(int sig)
{
change_state = 1;
reload_symbols = 1;
@@ -415,7 +484,6 @@ void reload_daemon(sig)
static void Terminate()
-
{
CloseLogSrc();
Syslog(LOG_INFO, "Kernel log daemon terminating.");
@@ -429,10 +497,7 @@ static void Terminate()
exit(1);
}
-static void SignalDaemon(sig)
-
- int sig;
-
+static void SignalDaemon(int sig)
{
#ifndef TESTING
auto int pid = check_pid(PidFile);
@@ -445,8 +510,7 @@ static void SignalDaemon(sig)
}
-static void ReloadSymbols()
-
+static void ReloadSymbols(void)
{
if (symbol_lookup) {
if ( reload_symbols > 1 )
@@ -459,7 +523,6 @@ static void ReloadSymbols()
static void ChangeLogging(void)
-
{
/* Terminate kernel logging. */
if ( terminate == 1 )
@@ -508,11 +571,9 @@ static void ChangeLogging(void)
static enum LOGSRC GetKernelLogSrc(void)
-
{
auto struct stat sb;
-
/* Set level of kernel console messaging.. */
if ( (ksyslog(8, NULL, console_log_level) < 0) && \
(errno == EINVAL) )
@@ -570,87 +631,6 @@ static enum LOGSRC GetKernelLogSrc(void)
}
-extern void Syslog(int priority, char *fmt, ...)
-
-{
- va_list ap;
- char *argl;
-
- if ( debugging )
- {
- fputs("Logging line:\n", stderr);
- fprintf(stderr, "\tLine: %s\n", fmt);
- fprintf(stderr, "\tPriority: %d\n", priority);
- }
-
- /* Handle output to a file. */
- if ( output_file != (FILE *) 0 )
- {
- va_start(ap, fmt);
- vfprintf(output_file, fmt, ap);
- va_end(ap);
- fputc('\n', output_file);
- fflush(output_file);
- if (!one_shot)
- fsync(fileno(output_file));
- return;
- }
-
- /* Output using syslog. */
- if (!strcmp(fmt, "%s"))
- {
- va_start(ap, fmt);
- argl = va_arg(ap, char *);
- if (argl[0] == '<' && argl[1] && argl[2] == '>')
- {
- switch ( argl[1] )
- {
- case '0':
- priority = LOG_EMERG;
- break;
- case '1':
- priority = LOG_ALERT;
- break;
- case '2':
- priority = LOG_CRIT;
- break;
- case '3':
- priority = LOG_ERR;
- break;
- case '4':
- priority = LOG_WARNING;
- break;
- case '5':
- priority = LOG_NOTICE;
- break;
- case '6':
- priority = LOG_INFO;
- break;
- case '7':
- default:
- priority = LOG_DEBUG;
- }
- argl += 3;
- }
- syslog(priority, fmt, argl);
- va_end(ap);
-#ifdef TESTING
- putchar('\n');
-#endif
- return;
- }
-
- va_start(ap, fmt);
- vsyslog(priority, fmt, ap);
- va_end(ap);
-#ifdef TESTING
- printf ("\n");
-#endif
-
- return;
-}
-
-
/*
* Copy characters from ptr to line until a char in the delim
* string is encountered or until min( space, len ) chars have
@@ -909,7 +889,6 @@ static void LogLine(char *ptr, int len)
static void LogKernelLine(void)
-
{
auto int rdcnt;
@@ -934,7 +913,6 @@ static void LogKernelLine(void)
static void LogProcLine(void)
-
{
auto int rdcnt;
@@ -959,12 +937,7 @@ static void LogProcLine(void)
}
-int main(argc, argv)
-
- int argc;
-
- char *argv[];
-
+int main(int argc, char *argv[])
{
auto int ch,
use_output = 0;
@@ -1117,9 +1090,6 @@ int main(argc, argv)
return(1);
}
}
- else
- openlog("kernel", 0, LOG_KERN);
-
/* Handle one-shot logging. */
if ( one_shot )
diff --git a/klogd.h b/klogd.h
index f3ad3e5d..1343f401 100644
--- a/klogd.h
+++ b/klogd.h
@@ -40,6 +40,5 @@ extern int InitMsyms(void);
extern char * ExpandKadds(char *, char *);
extern void SetParanoiaLevel(int);
extern void Syslog(int priority, char *fmt, ...);
-extern void syslog(int pri, const char *fmt, ...);
extern void vsyslog(int pri, const char *fmt, va_list ap);
extern void openlog(const char *ident, int logstat, int logfac);
diff --git a/syslog.c b/syslog.c
index 59822220..889b0057 100644
--- a/syslog.c
+++ b/syslog.c
@@ -1,252 +1,138 @@
-/*
- * Copyright (c) 1983, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted provided
- * that: (1) source distributions retain this entire copyright notice and
- * comment, and (2) distributions including binaries display the following
- * acknowledgement: ``This product includes software developed by the
- * University of California, Berkeley and its contributors'' in the
- * documentation or other materials provided with the distribution and in
- * all advertising materials mentioning features or use of this software.
- * Neither the name of the University nor the names of its contributors may
- * be used to endorse or promote products derived from this software without
- * specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * SYSLOG -- print message on log file
- *
- * This routine looks a lot like printf, except that it outputs to the
- * log file instead of the standard output. Also:
- * adds a timestamp,
- * prints the module name in front of the message,
- * has some other formatting types (or will sometime),
- * adds a newline on the end of the message.
+/* logger.c
+ * Helper routines for klogd. It replaces the regular glibc syslog()
+ * call. The reason is that the glibc version does not support
+ * logging with the kernel facility. This file is a re-implementation
+ * of the functions with only the functionality required for klogd.
+ * So it can NOT be used as a general-purpose replacment.
+ * Thanks to being special, this version is deemed to be considerable
+ * faster than its glibc counterpart.
+ * To avoid confusion, the syslog() replacement is named writeSyslog().
+ * all other functions are just helpers to it.
+ * RGerhards, 2007-06-14
*
- * The output of this routine is intended to be read by syslogd(8).
+ * Copyright (C) 2007 Rainer Gerhards
*
- * Author: Eric Allman
- * Modified to use UNIX domain IPC by Ralph Campbell
+ * This program 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 2
+ * of the License, or (at your option) any later version.
*
- * Sat Dec 11 11:58:31 CST 1993: Dr. Wettstein
- * Changes to allow compilation with no complains under -Wall.
+ * This program 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.
*
- * Thu Jan 18 11:16:11 CST 1996: Dr. Wettstein
- * Added patch to close potential security hole. This is the same
- * patch which was announced in the linux-security mailing lists
- * and incorporated into the libc version of syslog.c.
- *
- * Sun Mar 11 20:23:44 CET 2001: Martin Schulze <joey@infodrom.ffis.de>
- * Use SOCK_DGRAM for loggin, renables it to work.
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
*/
-
-#include <sys/types.h>
+#include <stdio.h>
+#include <assert.h>
#include <sys/socket.h>
-#include <sys/file.h>
-#include <sys/signal.h>
-#include <sys/syslog.h>
-#undef syslog
-#undef vsyslog
-#if 0
-#include "syslog.h"
-#include "pathnames.h"
-#endif
-
-#include <sys/uio.h>
-#include <sys/wait.h>
-#include <netdb.h>
#include <string.h>
#include <time.h>
-#include <unistd.h>
-#include <errno.h>
#include <stdarg.h>
-#include <paths.h>
-#include <stdio.h>
+#include <unistd.h>
-#define _PATH_LOGNAME "/dev/log"
+#define PATH_LOGNAME "/dev/log" /* be sure you know what you do if you change this! */
-static int LogFile = -1; /* fd for log */
-static int connected; /* have done connect */
-static int LogStat = 0; /* status bits, set by openlog() */
-static const char *LogTag = "syslog"; /* string to tag the entry with */
-static int LogFacility = LOG_USER; /* default facility code */
+static struct sockaddr LoggerAddr; /* AF_UNIX address of local logger */
+static int connected; /* have done connect */
+static int fdLog = -1; /* fd for log - -1 if closed */
-void
-syslog(int pri, const char *fmt, ...)
+/* klogOpenLog
+ * opens the system log for writing. The log is opened immediately.
+ * If it is already open, no action is taken)
+ */
+static void klogOpenlog(void)
{
- va_list ap;
-
- va_start(ap, fmt);
- vsyslog(pri, fmt, ap);
- va_end(ap);
+ if (fdLog == -1) {
+ LoggerAddr.sa_family = AF_UNIX;
+ strncpy(LoggerAddr.sa_data, PATH_LOGNAME, sizeof(LoggerAddr.sa_data));
+ fdLog = socket(AF_UNIX, SOCK_DGRAM, 0);
+ }
+ if (fdLog != -1 && !connected)
+ if(connect(fdLog, &LoggerAddr, sizeof(LoggerAddr.sa_family) +
+ sizeof(PATH_LOGNAME) - 1 /* for \0 byte!*/ ) != -1)
+ connected = 1;
}
-void
-vsyslog(pri, fmt, ap)
- int pri;
- const char *fmt;
- va_list ap;
+/* Close the log file if it is currently open.
+ */
+static void klogCloselog(void)
{
- register int cnt;
- register char *p;
- time_t now;
- int fd, saved_errno;
- char tbuf[2048], fmt_cpy[1024], *stdp = (char *) 0;
+ if(fdLog != -1)
+ close(fdLog);
+ fdLog = -1;
+ connected = 0;
+}
- saved_errno = errno;
+/* Write a message to the syslogd.
+ * returns -1 if it fails, something else otherwise
+ */
+int writeSyslogV(int iPRI, const char *szFmt, va_list va)
+{
+ int iChars;
+ int iLen;
+ time_t tNow;
+ int iWritten; /* number of bytes written */
+ char msgBuf[2048]; /* we use the same size as sysklogd to remain compatible */
- /* see if we should just throw out this message */
- if (!LOG_MASK(LOG_PRI(pri)) || (pri &~ (LOG_PRIMASK|LOG_FACMASK)))
- return;
- if (LogFile < 0 || !connected)
- openlog(LogTag, LogStat | LOG_NDELAY, LogFacility);
+ assert(szFmt != NULL);
- /* set default facility if none specified */
- if ((pri & LOG_FACMASK) == 0)
- pri |= LogFacility;
+ if (fdLog < 0 || !connected)
+ klogOpenlog();
/* build the message */
- (void)time(&now);
- (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4);
- for (p = tbuf; *p; ++p);
- if (LogStat & LOG_PERROR)
- stdp = p;
- if (LogTag) {
- (void)strcpy(p, LogTag);
- for (; *p; ++p);
- }
- if (LogStat & LOG_PID) {
- (void)sprintf(p, "[%d]", getpid());
- for (; *p; ++p);
- }
- if (LogTag) {
- *p++ = ':';
- *p++ = ' ';
- }
-
- /* substitute error message for %m */
- {
- register char ch, *t1, *t2;
- char *strerror();
-
- for (t1 = fmt_cpy;
- (ch = *fmt) != '\0' && t1<fmt_cpy+sizeof(fmt_cpy);
- ++fmt)
- if (ch == '%' && fmt[1] == 'm') {
- ++fmt;
- for (t2 = strerror(saved_errno);
- (*t1 = *t2++); ++t1);
- }
- else
- *t1++ = ch;
- *t1 = '\0';
- }
-
- (void)vsprintf(p, fmt_cpy, ap);
-
- cnt = strlen(tbuf);
-
- /* output to stderr if requested */
- if (LogStat & LOG_PERROR) {
- struct iovec iov[2];
- register struct iovec *v = iov;
+ time(&tNow);
+ /* we can use sprintf safely below, because we know the size of the constants.
+ * By doing so, we save some cpu cycles and code complexity (for unnecessary
+ * error checking).
+ */
+ iLen = sprintf(msgBuf, "<%d>%.15s kernel: ", iPRI, ctime(&tNow) + 4);
- v->iov_base = stdp;
- v->iov_len = cnt - (stdp - tbuf);
- ++v;
- v->iov_base = "\n";
- v->iov_len = 1;
- (void)writev(2, iov, 2);
- }
+ iChars = vsnprintf(msgBuf + iLen, sizeof(msgBuf) / sizeof(char) - iLen, szFmt, va);
+ if(iChars > sizeof(msgBuf) / sizeof(char) - iLen)
+ iLen = sizeof(msgBuf) / sizeof(char) - 1; /* full buffer siz minus \0 byte */
+ else
+ iLen += iChars;
/* output the message to the local logger */
- if (write(LogFile, tbuf, cnt + 1) >= 0 || !(LogStat&LOG_CONS))
- return;
+ iWritten = write(fdLog, msgBuf, iLen);
+ /* Debug aid below - uncomment to use
+ printf("wrote to log(%d): '%s'\n", iWritten, msgBuf); */
+
+ if(iWritten == -1) {
+ /* retry */
+ klogCloselog();
+ klogOpenlog();
+ iWritten = write(fdLog, msgBuf, iLen);
+ }
- /*
- * output the message to the console; don't worry about
- * blocking, if console blocks everything will.
- */
- if ((fd = open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) < 0)
- return;
- (void)strcat(tbuf, "\r\n");
- cnt += 2;
- p = index(tbuf, '>') + 1;
- (void)write(fd, p, cnt - (p - tbuf));
- (void)close(fd);
+ return(iWritten);
}
-#ifndef TESTING
-static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */
-#endif
-/*
- * OPENLOG -- open system log
- */
-void
-openlog(ident, logstat, logfac)
- const char *ident;
- int logstat, logfac;
+/* And now the same with variable arguments */
+int writeSyslog(int iPRI, const char *szFmt, ...)
{
- if (ident != NULL)
- LogTag = ident;
- LogStat = logstat;
-
-#ifdef ALLOW_KERNEL_LOGGING
- if ((logfac &~ LOG_FACMASK) == 0)
-#else
- if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
-#endif
- LogFacility = logfac;
-
-#ifndef TESTING
- if (LogFile == -1) {
- SyslogAddr.sa_family = AF_UNIX;
- strncpy(SyslogAddr.sa_data, _PATH_LOGNAME,
- sizeof(SyslogAddr.sa_data));
- if (LogStat & LOG_NDELAY) {
- LogFile = socket(AF_UNIX, SOCK_DGRAM, 0);
-/* fcntl(LogFile, F_SETFD, 1); */
- }
- }
- if (LogFile != -1 && !connected &&
- connect(LogFile, &SyslogAddr, sizeof(SyslogAddr.sa_family)+
- strlen(SyslogAddr.sa_data)) != -1)
-#else
- LogFile = fileno(stdout);
-#endif
- connected = 1;
-}
+ int iRet;
+ va_list va;
-/*
- * CLOSELOG -- close the system log
- */
-void
-closelog()
-{
-#ifndef TESTING
- (void) close(LogFile);
-#endif
- LogFile = -1;
- connected = 0;
+ assert(szFmt != NULL);
+ va_start(va, szFmt);
+ iRet = writeSyslogV(iPRI, szFmt, va);
+ va_end(va);
+
+ return(iRet);
}
-static int LogMask = 0xff; /* mask of priorities to be logged */
/*
- * SETLOGMASK -- set the log mask level
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vi:set ai:
*/
-int
-setlogmask(pmask)
- int pmask;
-{
- int omask;
-
- omask = LogMask;
- if (pmask != 0)
- LogMask = pmask;
- return (omask);
-}
diff --git a/syslogd.c b/syslogd.c
index 938f7c3a..f42c16b3 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -1442,12 +1442,13 @@ static int TCPSessDataRcvd(int iTCPSess, char *pData, int iLen)
* rgerhards, 2006-12-19
*/
if(isdigit(*pData)) {
+ int iCnt; /* the frame count specified */
TCPSessions[iTCPSess].eFraming = TCP_FRAMING_OCTET_COUNTING;
/* in this mode, we have OCTET-COUNT SP MSG - so we now need
* to extract the OCTET-COUNT and the SP and then extract
* the msg.
*/
- int iCnt = 0; /* the frame count specified */
+ iCnt = 0;
/* IETF20061218 int iNbrOctets = 0; / * number of octets already consumed */
while(isdigit(*pData)) {
iCnt = iCnt * 10 + *pData - '0';
diff --git a/version.h b/version.h
index 115cb0e2..d3dfe68e 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
#define VERSION "1.13"
-#define PATCHLEVEL "2"
+#define PATCHLEVEL "3"