mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-20 07:20:41 +01:00
provide some bug fixes and performance enhancemnts. Also required
changes to klogd.c to support the new interface.
139 lines
4.0 KiB
C
139 lines
4.0 KiB
C
/* 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
|
|
*
|
|
* Copyright (C) 2007 Rainer Gerhards
|
|
*
|
|
* 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.
|
|
*
|
|
* 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.
|
|
*
|
|
* 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 <stdio.h>
|
|
#include <assert.h>
|
|
#include <sys/socket.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <stdarg.h>
|
|
#include <unistd.h>
|
|
|
|
#define PATH_LOGNAME "/dev/log" /* be sure you know what you do if you change this! */
|
|
|
|
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 */
|
|
|
|
/* 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)
|
|
{
|
|
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;
|
|
}
|
|
|
|
/* Close the log file if it is currently open.
|
|
*/
|
|
static void klogCloselog(void)
|
|
{
|
|
if(fdLog != -1)
|
|
close(fdLog);
|
|
fdLog = -1;
|
|
connected = 0;
|
|
}
|
|
|
|
/* 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 */
|
|
|
|
assert(szFmt != NULL);
|
|
|
|
if (fdLog < 0 || !connected)
|
|
klogOpenlog();
|
|
|
|
/* build the message */
|
|
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);
|
|
|
|
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 */
|
|
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);
|
|
}
|
|
|
|
return(iWritten);
|
|
}
|
|
|
|
/* And now the same with variable arguments */
|
|
int writeSyslog(int iPRI, const char *szFmt, ...)
|
|
{
|
|
int iRet;
|
|
va_list va;
|
|
|
|
assert(szFmt != NULL);
|
|
va_start(va, szFmt);
|
|
iRet = writeSyslogV(iPRI, szFmt, va);
|
|
va_end(va);
|
|
|
|
return(iRet);
|
|
}
|
|
|
|
/*
|
|
* Local variables:
|
|
* c-indent-level: 4
|
|
* c-basic-offset: 4
|
|
* tab-width: 4
|
|
* End:
|
|
* vi:set ai:
|
|
*/
|