diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/imdoor/Makefile.am | 6 | ||||
-rw-r--r-- | plugins/imdoor/imdoor.c | 430 | ||||
-rw-r--r-- | plugins/imdoor/sun_cddl.c | 592 | ||||
-rw-r--r-- | plugins/imklog/Makefile.am | 4 | ||||
-rw-r--r-- | plugins/imklog/solaris.c | 181 | ||||
-rw-r--r-- | plugins/imklog/solaris_cddl.c | 323 | ||||
-rw-r--r-- | plugins/imklog/solaris_cddl.h | 1 | ||||
-rw-r--r-- | plugins/imudp/imudp.c | 2 | ||||
-rw-r--r-- | plugins/imuxsock/imuxsock.c | 17 | ||||
-rw-r--r-- | plugins/omgssapi/omgssapi.c | 11 | ||||
-rw-r--r-- | plugins/ompgsql/createDB.sql | 2 |
11 files changed, 1562 insertions, 7 deletions
diff --git a/plugins/imdoor/Makefile.am b/plugins/imdoor/Makefile.am new file mode 100644 index 00000000..6ad7a904 --- /dev/null +++ b/plugins/imdoor/Makefile.am @@ -0,0 +1,6 @@ +pkglib_LTLIBRARIES = imdoor.la + +imdoor_la_SOURCES = imdoor.c sun_cddl.c +imdoor_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) +imdoor_la_LDFLAGS = -module -avoid-version +imdoor_la_LIBADD = diff --git a/plugins/imdoor/imdoor.c b/plugins/imdoor/imdoor.c new file mode 100644 index 00000000..83890d03 --- /dev/null +++ b/plugins/imdoor/imdoor.c @@ -0,0 +1,430 @@ +/* imdoor.c + * This input module is used to receive syslog messages via the Solaris + * door mechanism. Not surprisingly, it most probably can not be built + * on other platforms. + * + * NOTE: read comments in module-template.h to understand how this file + * works! + * + * File begun on 2010-03-26 by RGerhards + * + * Copyright 2010 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 <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/un.h> +#include "dirty.h" +#include "cfsysline.h" +#include "unicode-helper.h" +#include "module-template.h" +#include "srUtils.h" +#include "errmsg.h" +#include "net.h" +#include "glbl.h" +#include "msg.h" +#include "prop.h" + +MODULE_TYPE_INPUT + +/* defines */ +#define MAXFUNIX 20 +#ifndef _PATH_LOG +#ifdef BSD +#define _PATH_LOG "/var/run/log" +#else +#define _PATH_LOG "/dev/log" +#endif +#endif + + +/* handle some defines missing on more than one platform */ +#ifndef SUN_LEN +#define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) +#endif +/* Module static data */ +DEF_IMOD_STATIC_DATA +DEFobjCurrIf(errmsg) +DEFobjCurrIf(glbl) +DEFobjCurrIf(prop) + +static prop_t *pInputName = NULL; /* our inputName currently is always "imuxsock", and this will hold it */ +static int startIndexUxLocalSockets; /* process funix from that index on (used to + * suppress local logging. rgerhards 2005-08-01 + * read-only after startup + */ +static int funixParseHost[MAXFUNIX] = { 0, }; /* should parser parse host name? read-only after startup */ +static int funixFlags[MAXFUNIX] = { IGNDATE, }; /* should parser parse host name? read-only after startup */ +static uchar *funixn[MAXFUNIX] = { (uchar*) _PATH_LOG }; /* read-only after startup */ +static uchar *funixHName[MAXFUNIX] = { NULL, }; /* host-name override - if set, use this instead of actual name */ +static int funixFlowCtl[MAXFUNIX] = { eFLOWCTL_NO_DELAY, }; /* flow control settings for this socket */ +static int funix[MAXFUNIX] = { -1, }; /* read-only after startup */ +static int nfunix = 1; /* number of Unix sockets open / read-only after startup */ + +/* config settings */ +static int bOmitLocalLogging = 0; +static uchar *pLogSockName = NULL; +static uchar *pLogHostName = NULL; /* host name to use with this socket */ +static int bUseFlowCtl = 0; /* use flow control or not (if yes, only LIGHT is used! */ +static int bIgnoreTimestamp = 1; /* ignore timestamps present in the incoming message? */ + + +/* set the timestamp ignore / not ignore option for the system + * log socket. This must be done separtely, as it is not added via a command + * but present by default. -- rgerhards, 2008-03-06 + */ +static rsRetVal setSystemLogTimestampIgnore(void __attribute__((unused)) *pVal, int iNewVal) +{ + DEFiRet; + funixFlags[0] = iNewVal ? IGNDATE : NOFLAG; + RETiRet; +} + +/* set flowcontrol for the system log socket + */ +static rsRetVal setSystemLogFlowControl(void __attribute__((unused)) *pVal, int iNewVal) +{ + DEFiRet; + funixFlowCtl[0] = iNewVal ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY; + RETiRet; +} + +/* add an additional listen socket. Socket names are added + * until the array is filled up. It is never reset, only at + * module unload. + * TODO: we should change the array to a list so that we + * can support any number of listen socket names. + * rgerhards, 2007-12-20 + * added capability to specify hostname for socket -- rgerhards, 2008-08-01 + */ +static rsRetVal addLstnSocketName(void __attribute__((unused)) *pVal, uchar *pNewVal) +{ + if(nfunix < MAXFUNIX) { + if(*pNewVal == ':') { + funixParseHost[nfunix] = 1; + } + else { + funixParseHost[nfunix] = 0; + } + funixHName[nfunix] = pLogHostName; + pLogHostName = NULL; /* re-init for next, not freed because funixHName[] now owns it */ + funixFlowCtl[nfunix] = bUseFlowCtl ? eFLOWCTL_LIGHT_DELAY : eFLOWCTL_NO_DELAY; + funixFlags[nfunix] = bIgnoreTimestamp ? IGNDATE : NOFLAG; + funixn[nfunix++] = pNewVal; + } + else { + errmsg.LogError(0, NO_ERRCODE, "Out of unix socket name descriptors, ignoring %s\n", + pNewVal); + } + + return RS_RET_OK; +} + +/* free the funixn[] socket names - needed as cleanup on several places + * note that nfunix is NOT reset! funixn[0] is never freed, as it comes from + * the constant memory pool - and if not, it is freeed via some other pointer. + */ +static rsRetVal discardFunixn(void) +{ + int i; + + for (i = 1; i < nfunix; i++) { + if(funixn[i] != NULL) { + free(funixn[i]); + funixn[i] = NULL; + } + if(funixHName[i] != NULL) { + free(funixHName[i]); + funixHName[i] = NULL; + } + } + + return RS_RET_OK; +} + + +static int create_unix_socket(const char *path) +{ + struct sockaddr_un sunx; + int fd; + + if (path[0] == '\0') + return -1; + + unlink(path); + + memset(&sunx, 0, sizeof(sunx)); + sunx.sun_family = AF_UNIX; + (void) strncpy(sunx.sun_path, path, sizeof(sunx.sun_path)); + fd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (fd < 0 || bind(fd, (struct sockaddr *) &sunx, SUN_LEN(&sunx)) < 0 || + chmod(path, 0666) < 0) { + errmsg.LogError(errno, NO_ERRCODE, "connot create '%s'", path); + dbgprintf("cannot create %s (%d).\n", path, errno); + close(fd); + return -1; + } + return fd; +} + + +/* This function receives data from a socket indicated to be ready + * to receive and submits the message received for processing. + * rgerhards, 2007-12-20 + * Interface changed so that this function is passed the array index + * of the socket which is to be processed. This eases access to the + * growing number of properties. -- rgerhards, 2008-08-01 + */ +static rsRetVal readSocket(int fd, int iSock) +{ + DEFiRet; + int iRcvd; + int iMaxLine; + uchar bufRcv[4096+1]; + uchar *pRcv = NULL; /* receive buffer */ + + assert(iSock >= 0); + + iMaxLine = glbl.GetMaxLine(); + + /* we optimize performance: if iMaxLine is below 4K (which it is in almost all + * cases, we use a fixed buffer on the stack. Only if it is higher, heap memory + * is used. We could use alloca() to achive a similar aspect, but there are so + * many issues with alloca() that I do not want to take that route. + * rgerhards, 2008-09-02 + */ + if((size_t) iMaxLine < sizeof(bufRcv) - 1) { + pRcv = bufRcv; + } else { + CHKmalloc(pRcv = (uchar*) malloc(sizeof(uchar) * (iMaxLine + 1))); + } + + iRcvd = recv(fd, pRcv, iMaxLine, 0); + dbgprintf("Message from UNIX socket: #%d\n", fd); + if (iRcvd > 0) { + parseAndSubmitMessage(funixHName[iSock] == NULL ? glbl.GetLocalHostName() : funixHName[iSock], + (uchar*)"127.0.0.1", pRcv, + iRcvd, funixParseHost[iSock] ? (funixFlags[iSock] | PARSE_HOSTNAME) : funixFlags[iSock], + funixFlowCtl[iSock], pInputName, NULL, 0); + } else if (iRcvd < 0 && errno != EINTR) { + char errStr[1024]; + rs_strerror_r(errno, errStr, sizeof(errStr)); + dbgprintf("UNIX socket error: %d = %s.\n", errno, errStr); + errmsg.LogError(errno, NO_ERRCODE, "recvfrom UNIX"); + } + +finalize_it: + if(pRcv != NULL && (size_t) iMaxLine >= sizeof(bufRcv) - 1) + free(pRcv); + + RETiRet; +} + + +/* This function is called to gather input. */ +BEGINrunInput + int maxfds; + int nfds; + int i; + int fd; + fd_set readfds; +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(1) { + /* Add the Unix Domain Sockets to the list of read + * descriptors. + * rgerhards 2005-08-01: we must now check if there are + * any local sockets to listen to at all. If the -o option + * is given without -a, we do not need to listen at all.. + */ + maxfds = 0; + FD_ZERO (&readfds); + /* Copy master connections */ + for (i = startIndexUxLocalSockets; i < nfunix; i++) { + if (funix[i] != -1) { + FD_SET(funix[i], &readfds); + if (funix[i]>maxfds) maxfds=funix[i]; + } + } + + if(Debug) { + dbgprintf("--------imuxsock calling select, active file descriptors (max %d): ", maxfds); + for (nfds= 0; nfds <= maxfds; ++nfds) + if ( FD_ISSET(nfds, &readfds) ) + dbgprintf("%d ", nfds); + dbgprintf("\n"); + } + + /* wait for io to become ready */ + nfds = select(maxfds+1, (fd_set *) &readfds, NULL, NULL, NULL); + + for (i = 0; i < nfunix && nfds > 0; i++) { + if ((fd = funix[i]) != -1 && FD_ISSET(fd, &readfds)) { + readSocket(fd, i); + --nfds; /* indicate we have processed one */ + } + } + } + + RETiRet; +ENDrunInput + + +BEGINwillRun +CODESTARTwillRun + register int i; + + /* first apply some config settings */ + startIndexUxLocalSockets = bOmitLocalLogging ? 1 : 0; + if(pLogSockName != NULL) + funixn[0] = pLogSockName; + + /* initialize and return if will run or not */ + for (i = startIndexUxLocalSockets ; i < nfunix ; i++) { + if ((funix[i] = create_unix_socket((char*) funixn[i])) != -1) + dbgprintf("Opened UNIX socket '%s' (fd %d).\n", funixn[i], funix[i]); + } + + /* we need to create the inputName property (only once during our lifetime) */ + CHKiRet(prop.Construct(&pInputName)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imuxsock"), sizeof("imuxsock") - 1)); + CHKiRet(prop.ConstructFinalize(pInputName)); + +finalize_it: +ENDwillRun + + +BEGINafterRun +CODESTARTafterRun + int i; + /* do cleanup here */ + /* Close the UNIX sockets. */ + for (i = 0; i < nfunix; i++) + if (funix[i] != -1) + close(funix[i]); + + /* Clean-up files. */ + for (i = 0; i < nfunix; i++) + if (funixn[i] && funix[i] != -1) + unlink((char*) funixn[i]); + /* free no longer needed string */ + if(pLogSockName != NULL) + free(pLogSockName); + if(pLogHostName != NULL) { + free(pLogHostName); + } + + discardFunixn(); + nfunix = 1; + + if(pInputName != NULL) + prop.Destruct(&pInputName); +ENDafterRun + + +BEGINmodExit +CODESTARTmodExit + objRelease(glbl, CORE_COMPONENT); + objRelease(errmsg, CORE_COMPONENT); + objRelease(prop, CORE_COMPONENT); +ENDmodExit + + +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +ENDqueryEtryPt + +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + bOmitLocalLogging = 0; + if(pLogSockName != NULL) { + free(pLogSockName); + pLogSockName = NULL; + } + if(pLogHostName != NULL) { + free(pLogHostName); + pLogHostName = NULL; + } + + discardFunixn(); + nfunix = 1; + bIgnoreTimestamp = 1; + bUseFlowCtl = 0; + + return RS_RET_OK; +} + + +BEGINmodInit() + int i; +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(prop, CORE_COMPONENT)); + + dbgprintf("imuxsock version %s initializing\n", PACKAGE_VERSION); + + /* initialize funixn[] array */ + for(i = 1 ; i < MAXFUNIX ; ++i) { + funixn[i] = NULL; + funix[i] = -1; + } + + /* register config file handlers */ + CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary, + NULL, &bOmitLocalLogging, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketignoremsgtimestamp", 0, eCmdHdlrBinary, + NULL, &bIgnoreTimestamp, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogsocketname", 0, eCmdHdlrGetWord, + NULL, &pLogSockName, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensockethostname", 0, eCmdHdlrGetWord, + NULL, &pLogHostName, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"inputunixlistensocketflowcontrol", 0, eCmdHdlrBinary, + NULL, &bUseFlowCtl, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"addunixlistensocket", 0, eCmdHdlrGetWord, + addLstnSocketName, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, + resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); + /* the following one is a (dirty) trick: the system log socket is not added via + * an "addUnixListenSocket" config format. As such, it's properties can not be modified + * via $InputUnixListenSocket*". So we need to add a special directive + * for that. We should revisit all of that once we have the new config format... + * rgerhards, 2008-03-06 + */ + CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogsocketignoremsgtimestamp", 0, eCmdHdlrBinary, + setSystemLogTimestampIgnore, NULL, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"systemlogsocketflowcontrol", 0, eCmdHdlrBinary, + setSystemLogFlowControl, NULL, STD_LOADABLE_MODULE_ID)); +ENDmodInit +/* vim:set ai: + */ diff --git a/plugins/imdoor/sun_cddl.c b/plugins/imdoor/sun_cddl.c new file mode 100644 index 00000000..8e9714d9 --- /dev/null +++ b/plugins/imdoor/sun_cddl.c @@ -0,0 +1,592 @@ +#define MAXLINE 4096 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* Portions Copyright 2010 by Rainer Gerhards and Adiscon + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T + * All Rights Reserved + */ + +/* + * University Copyright- Copyright (c) 1982, 1986, 1988 + * The Regents of the University of California + * All Rights Reserved + * + * University Acknowledgment- Portions of this document are derived from + * software developed by the University of California, Berkeley, and its + * contributors. + */ +#include <unistd.h> +#include <note.h> +#include <errno.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdio_ext.h> +#include <stdlib.h> +#include <ctype.h> +#include <signal.h> +#include <string.h> +#include <strings.h> +#include <libscf.h> +#include <netconfig.h> +#include <netdir.h> +#include <pwd.h> +#include <sys/socket.h> +#include <tiuser.h> +#include <utmpx.h> +#include <limits.h> +#include <pthread.h> +#include <fcntl.h> +#include <stropts.h> +#include <assert.h> +#include <sys/statvfs.h> + +#include <sys/param.h> +#include <sys/sysmacros.h> +#include <sys/syslog.h> +#include <sys/strlog.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/utsname.h> +#include <sys/poll.h> +#include <sys/wait.h> +#include <sys/resource.h> +#include <sys/mman.h> +#include <sys/note.h> +#include <door.h> +#include <sys/door.h> + +#include "rsyslog.h" +#include "debug.h" + +#define DOORFILE "/var/run/syslog_door" +#define RELATIVE_DOORFILE "../var/run/syslog_door" +#define OLD_DOORFILE "/etc/.syslog_door" + +static int DoorFd = -1; +static int DoorCreated = 0; +static char *DoorFileName = DOORFILE; + +/* for managing door server threads */ +static pthread_mutex_t door_server_cnt_lock = PTHREAD_MUTEX_INITIALIZER; +static uint_t door_server_cnt = 0; +static pthread_attr_t door_thr_attr; + +/* + * the 'server' function that we export via the door. It does + * nothing but return. + */ +/*ARGSUSED*/ +static void +server(void *cookie, char *argp, size_t arg_size, + door_desc_t *dp, uint_t n) +{ + (void) door_return(NULL, 0, NULL, 0); + /* NOTREACHED */ +} + +/*ARGSUSED*/ +static void * +create_door_thr(void *arg) +{ + (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + (void) door_return(NULL, 0, NULL, 0); + + /* + * If there is an error in door_return(), it will return here and + * the thread will exit. Hence we need to decrement door_server_cnt. + */ + (void) pthread_mutex_lock(&door_server_cnt_lock); + door_server_cnt--; + (void) pthread_mutex_unlock(&door_server_cnt_lock); + return (NULL); +} + +/* + * Max number of door server threads for syslogd. Since door is used + * to check the health of syslogd, we don't need large number of + * server threads. + */ +#define MAX_DOOR_SERVER_THR 3 + +/* + * Manage door server thread pool. + */ +/*ARGSUSED*/ +static void +door_server_pool(door_info_t *dip) +{ + (void) pthread_mutex_lock(&door_server_cnt_lock); + if (door_server_cnt <= MAX_DOOR_SERVER_THR && + pthread_create(NULL, &door_thr_attr, create_door_thr, NULL) == 0) { + door_server_cnt++; + (void) pthread_mutex_unlock(&door_server_cnt_lock); + return; + } + + (void) pthread_mutex_unlock(&door_server_cnt_lock); +} + +static void +delete_doorfiles(void) +{ + pthread_t mythreadno; + struct stat sb; + int err; + char line[MAXLINE+1]; + + if (Debug) { + mythreadno = pthread_self(); + } + + + if (lstat(DoorFileName, &sb) == 0 && !S_ISDIR(sb.st_mode)) { + if (unlink(DoorFileName) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "unlink() of %s failed - fatal", DoorFileName); + errno = err; + DBGPRINTF("%s", line);//logerror(line); + DBGPRINTF("delete_doorfiles(%u): error: %s, " + "errno=%d\n", mythreadno, line, err); + exit(1); + } + + DBGPRINTF("delete_doorfiles(%u): deleted %s\n", + mythreadno, DoorFileName); + } + + if (strcmp(DoorFileName, DOORFILE) == 0) { + if (lstat(OLD_DOORFILE, &sb) == 0 && !S_ISDIR(sb.st_mode)) { + if (unlink(OLD_DOORFILE) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "unlink() of %s failed", OLD_DOORFILE); + DBGPRINTF("delete_doorfiles(%u): %s\n", + mythreadno, line); + + if (err != EROFS) { + errno = err; + (void) strlcat(line, " - fatal", + sizeof (line)); + logerror(line); + DBGPRINTF("delete_doorfiles(%u): " + "error: %s, errno=%d\n", + mythreadno, line, err); + exit(1); + } + + DBGPRINTF("delete_doorfiles(%u): unlink() " + "failure OK on RO file system\n", + mythreadno); + } + + DBGPRINTF("delete_doorfiles(%u): deleted %s\n", + mythreadno, OLD_DOORFILE); + } + } + +#if 0 + if (lstat(PidFileName, &sb) == 0 && !S_ISDIR(sb.st_mode)) { + if (unlink(PidFileName) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "unlink() of %s failed - fatal", PidFileName); + errno = err; + logerror(line); + DBGPRINTF("delete_doorfiles(%u): error: %s, " + "errno=%d\n", mythreadno, line, err); + exit(1); + } + + DBGPRINTF("delete_doorfiles(%u): deleted %s\n", mythreadno, + PidFileName); + } + + if (strcmp(PidFileName, PIDFILE) == 0) { + if (lstat(OLD_PIDFILE, &sb) == 0 && !S_ISDIR(sb.st_mode)) { + if (unlink(OLD_PIDFILE) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "unlink() of %s failed", OLD_PIDFILE); + DBGPRINTF(5, "delete_doorfiles(%u): %s, \n", + mythreadno, line); + + if (err != EROFS) { + errno = err; + (void) strlcat(line, " - fatal", + sizeof (line)); + logerror(line); + DBGPRINTF(1, "delete_doorfiles(%u): " + "error: %s, errno=%d\n", + mythreadno, line, err); + exit(1); + } + + DBGPRINTF(5, "delete_doorfiles(%u): unlink " + "failure OK on RO file system\n", + mythreadno); + } + + DBGPRINTF(5, "delete_doorfiles(%u): deleted %s\n", + mythreadno, OLD_PIDFILE); + } + } +#endif + + if (DoorFd != -1) { + (void) door_revoke(DoorFd); + } + + DBGPRINTF("delete_doorfiles(%u): revoked door: DoorFd=%d\n", + mythreadno, DoorFd); +} + + +/* + * Create the door file and the pid file in /var/run. If the filesystem + * containing /etc is writable, create symlinks /etc/.syslog_door and + * /etc/syslog.pid to them. On systems that do not support /var/run, create + * /etc/.syslog_door and /etc/syslog.pid directly. + * + * Note: it is not considered fatal to fail to create the pid file or its + * symlink. Attempts to use them in the usual way will fail, of course, but + * syslogd will function nicely without it (not so for the door file). + */ + +static void +sun_open_door(void) +{ + struct stat buf; + door_info_t info; + char line[MAXLINE+1]; + pthread_t mythreadno; + int err; + + if (Debug) { + mythreadno = pthread_self(); + } + + /* + * first see if another syslogd is running by trying + * a door call - if it succeeds, there is already + * a syslogd process active + */ + + if (!DoorCreated) { + int door; + + if ((door = open(DoorFileName, O_RDONLY)) >= 0) { + DBGPRINTF("open_door(%u): %s opened " + "successfully\n", mythreadno, DoorFileName); + + if (door_info(door, &info) >= 0) { + DBGPRINTF("open_door(%u): " + "door_info:info.di_target = %ld\n", + mythreadno, info.di_target); + + if (info.di_target > 0) { + (void) sprintf(line, "syslogd pid %ld" + " already running. Cannot " + "start another syslogd pid %ld", + info.di_target, getpid()); + DBGPRINTF("open_door(%u): error: " + "%s\n", mythreadno, line); + errno = 0; + //logerror(line); + exit(1); + } + } + + (void) close(door); + } else { + if (lstat(DoorFileName, &buf) < 0) { + err = errno; + + DBGPRINTF("open_door(%u): lstat() of %s " + "failed, errno=%d\n", + mythreadno, DoorFileName, err); + + if ((door = creat(DoorFileName, 0644)) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "creat() of %s failed - fatal", + DoorFileName); + DBGPRINTF("open_door(%u): error: %s, " + "errno=%d\n", mythreadno, line, + err); + errno = err; + //logerror(line); + delete_doorfiles(); + exit(1); + } + + (void) fchmod(door, + S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + + DBGPRINTF("open_door(%u): creat() of %s " + "succeeded\n", mythreadno, + DoorFileName); + + (void) close(door); + } + } + + if (strcmp(DoorFileName, DOORFILE) == 0) { + if (lstat(OLD_DOORFILE, &buf) == 0) { + DBGPRINTF("open_door(%u): lstat() of %s " + "succeeded\n", mythreadno, + OLD_DOORFILE); + + if (S_ISDIR(buf.st_mode)) { + (void) snprintf(line, sizeof (line), + "%s is a directory - fatal", + OLD_DOORFILE); + DBGPRINTF("open_door(%u): error: " + "%s\n", mythreadno, line); + errno = 0; + //logerror(line); + delete_doorfiles(); + exit(1); + } + + DBGPRINTF("open_door(%u): %s is not a " + "directory\n", + mythreadno, OLD_DOORFILE); + + if (unlink(OLD_DOORFILE) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "unlink() of %s failed", + OLD_DOORFILE); + DBGPRINTF("open_door(%u): %s\n", + mythreadno, line); + + if (err != EROFS) { + DBGPRINTF("open_door(%u): " + "error: %s, " + "errno=%d\n", + mythreadno, line, err); + (void) strcat(line, " - fatal"); + errno = err; + //logerror(line); + delete_doorfiles(); + exit(1); + } + + DBGPRINTF("open_door(%u): unlink " + "failure OK on RO file " + "system\n", mythreadno); + } + } else { + DBGPRINTF("open_door(%u): file %s doesn't " + "exist\n", mythreadno, OLD_DOORFILE); + } + + if (symlink(RELATIVE_DOORFILE, OLD_DOORFILE) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "symlink %s -> %s failed", OLD_DOORFILE, + RELATIVE_DOORFILE); + DBGPRINTF("open_door(%u): %s\n", mythreadno, + line); + + if (err != EROFS) { + DBGPRINTF("open_door(%u): error: %s, " + "errno=%d\n", mythreadno, line, + err); + errno = err; + (void) strcat(line, " - fatal"); + //logerror(line); + delete_doorfiles(); + exit(1); + } + + DBGPRINTF("open_door(%u): symlink failure OK " + "on RO file system\n", mythreadno); + } else { + DBGPRINTF("open_door(%u): symlink %s -> %s " + "succeeded\n", mythreadno, + OLD_DOORFILE, RELATIVE_DOORFILE); + } + } + + if ((DoorFd = door_create(server, 0, + DOOR_REFUSE_DESC)) < 0) { + //???? DOOR_NO_CANEL requires newer libs??? DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) < 0) { + err = errno; + (void) sprintf(line, "door_create() failed - fatal"); + DBGPRINTF("open_door(%u): error: %s, errno=%d\n", + mythreadno, line, err); + errno = err; + //logerror(line); + delete_doorfiles(); + exit(1); + } + //???? (void) door_setparam(DoorFd, DOOR_PARAM_DATA_MAX, 0); + DBGPRINTF("open_door(%u): door_create() succeeded, " + "DoorFd=%d\n", mythreadno, DoorFd); + + DoorCreated = 1; + } + + (void) fdetach(DoorFileName); /* just in case... */ + + (void) door_server_create(door_server_pool); + + if (fattach(DoorFd, DoorFileName) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), "fattach() of fd" + " %d to %s failed - fatal", DoorFd, DoorFileName); + DBGPRINTF("open_door(%u): error: %s, errno=%d\n", mythreadno, + line, err); + errno = err; + //logerror(line); + delete_doorfiles(); + exit(1); + } + + DBGPRINTF("open_door(%u): attached server() to %s\n", mythreadno, + DoorFileName); + +#if 0 + /* + * create pidfile anyway, so those using it to control + * syslogd (with kill `cat /etc/syslog.pid` perhaps) + * don't get broken. + */ + + if (!PidfileCreated) { + int pidfd; + + PidfileCreated = 1; + + if ((pidfd = open(PidFileName, O_RDWR|O_CREAT|O_TRUNC, 0644)) + < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "open() of %s failed", PidFileName); + DBGPRINTF(1, "open_door(%u): warning: %s, errno=%d\n", + mythreadno, line, err); + errno = err; + //logerror(line); + return; + } + + (void) fchmod(pidfd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); + (void) sprintf(line, "%ld\n", getpid()); + + if (write(pidfd, line, strlen(line)) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "write to %s on fd %d failed", PidFileName, pidfd); + DBGPRINTF(1, "open_door(%u): warning: %s, errno=%d\n", + mythreadno, line, err); + errno = err; + //logerror(line); + return; + } + + (void) close(pidfd); + + DBGPRINTF("open_door(%u): %s created\n", + mythreadno, PidFileName); + + if (strcmp(PidFileName, PIDFILE) == 0) { + if (lstat(OLD_PIDFILE, &buf) == 0) { + DBGPRINTF("open_door(%u): lstat() of %s " + "succeded\n", mythreadno, OLD_PIDFILE); + + if (S_ISDIR(buf.st_mode)) { + (void) snprintf(line, sizeof (line), + "file %s is a directory", + OLD_PIDFILE); + DBGPRINTF("open_door(%u): warning: " + "%s\n", mythreadno, line); + errno = 0; + //logerror(line); + return; + } + + if (unlink(OLD_PIDFILE) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "unlink() of %s failed", + OLD_PIDFILE); + DBGPRINTF("open_door(%u): %s\n", + mythreadno, line); + + if (err != EROFS) { + DBGPRINTF(1, "open_door (%u): " + "warning: %s, " + "errno=%d\n", + mythreadno, line, err); + errno = err; + //logerror(line); + return; + } + + DBGPRINTF(5, "open_door(%u): unlink " + "failure OK on RO file " + "system\n", mythreadno); + } + } else { + DBGPRINTF("open_door(%u): file %s doesn't " + "exist\n", mythreadno, OLD_PIDFILE); + } + + if (symlink(RELATIVE_PIDFILE, OLD_PIDFILE) < 0) { + err = errno; + (void) snprintf(line, sizeof (line), + "symlink %s -> %s failed", OLD_PIDFILE, + RELATIVE_PIDFILE); + DBGPRINTF("open_door(%u): %s\n", mythreadno, + line); + + if (err != EROFS) { + DBGPRINTF(1, "open_door(%u): warning: " + "%s, errno=%d\n", mythreadno, + line, err); + errno = err; + //logerror(line); + return; + } + + DBGPRINTF(5, "open_door(%u): symlink failure OK " + "on RO file system\n", mythreadno); + return; + } + + DBGPRINTF(5, "open_door(%u): symlink %s -> %s " + "succeeded\n", mythreadno, OLD_PIDFILE, + RELATIVE_PIDFILE); + } + } +#endif +} + + diff --git a/plugins/imklog/Makefile.am b/plugins/imklog/Makefile.am index 5d4d0465..06d4013c 100644 --- a/plugins/imklog/Makefile.am +++ b/plugins/imklog/Makefile.am @@ -11,6 +11,10 @@ if ENABLE_IMKLOG_LINUX imklog_la_SOURCES += linux.c module.h ksym.c ksyms.h ksym_mod.c endif +if ENABLE_IMKLOG_SOLARIS +imklog_la_SOURCES += solaris.c solaris_cddl.c +endif + imklog_la_CPPFLAGS = -I$(top_srcdir) $(PTHREADS_CFLAGS) $(RSRT_CFLAGS) imklog_la_LDFLAGS = -module -avoid-version imklog_la_LIBADD = diff --git a/plugins/imklog/solaris.c b/plugins/imklog/solaris.c new file mode 100644 index 00000000..c2aec30a --- /dev/null +++ b/plugins/imklog/solaris.c @@ -0,0 +1,181 @@ +/* klog driver for solaris + * + * This contains OS-specific functionality to read the + * kernel log. For a general overview, see head comment in + * imklog.c. + * + * This file relies on Sun code in solaris_cddl.c. We have split + * it from Sun's code to keep the copyright issue as simple as possible. + * + * 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. + * + * If that may be required, an exception is granted to permit linking + * this code to the code in solaris_cddl.c that is under the cddl license. + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <sys/socket.h> + + + +#include "rsyslog.h" +#include "imklog.h" +#include "unicode-helper.h" +#include "solaris_cddl.h" + +/* globals */ +static int fklog; // TODO: remove +#ifndef _PATH_KLOG +# define _PATH_KLOG "/dev/log" +#endif + + +static uchar *GetPath(void) +{ + return pszPath ? pszPath : UCHAR_CONSTANT(_PATH_KLOG); +} + +/* open the kernel log - will be called inside the willRun() imklog + * entry point. -- rgerhards, 2008-04-09 + */ +rsRetVal +klogWillRun(void) +{ + DEFiRet; + + fklog = sun_openklog((char*) GetPath(), O_RDONLY); + if (fklog < 0) { + char errStr[1024]; + int err = errno; + rs_strerror_r(err, errStr, sizeof(errStr)); + DBGPRINTF("error %d opening log socket: %s\n", + GetPath(), errStr); + iRet = RS_RET_ERR; // TODO: better error code + } + + RETiRet; +} + + +/* Read /dev/klog while data are available, split into lines. + * Contrary to standard BSD syslogd, we do a blocking read. We can + * afford this as imklog is running on its own threads. So if we have + * a single file, it really doesn't matter if we wait inside a 1-file + * select or the read() directly. + */ +static void +readklog(void) +{ + char *p, *q; + int len, i; + int iMaxLine; + uchar bufRcv[4096+1]; + uchar *pRcv = NULL; /* receive buffer */ + + iMaxLine = klog_getMaxLine(); + + /* we optimize performance: if iMaxLine is below 4K (which it is in almost all + * cases, we use a fixed buffer on the stack. Only if it is higher, heap memory + * is used. We could use alloca() to achive a similar aspect, but there are so + * many issues with alloca() that I do not want to take that route. + * rgerhards, 2008-09-02 + */ + if((size_t) iMaxLine < sizeof(bufRcv) - 1) { + pRcv = bufRcv; + } else { + if((pRcv = (uchar*) malloc(sizeof(uchar) * (iMaxLine + 1))) == NULL) + iMaxLine = sizeof(bufRcv) - 1; /* better this than noting */ + } + + len = 0; + for (;;) { + dbgprintf("----------imklog(BSD) waiting for kernel log line\n"); + i = read(fklog, pRcv + len, iMaxLine - len); + if (i > 0) { + pRcv[i + len] = '\0'; + } else { + if (i < 0 && errno != EINTR && errno != EAGAIN) { + imklogLogIntMsg(LOG_ERR, + "imklog error %d reading kernel log - shutting down imklog", + errno); + fklog = -1; + } + break; + } + + for (p = pRcv; (q = strchr(p, '\n')) != NULL; p = q + 1) { + *q = '\0'; + Syslog(LOG_INFO, (uchar*) p); + } + len = strlen(p); + if (len >= iMaxLine - 1) { + Syslog(LOG_INFO, (uchar*)p); + len = 0; + } + if (len > 0) + memmove(pRcv, p, len + 1); + } + if (len > 0) + Syslog(LOG_INFO, pRcv); + + if(pRcv != NULL && (size_t) iMaxLine >= sizeof(bufRcv) - 1) + free(pRcv); +} + + +/* to be called in the module's AfterRun entry point + * rgerhards, 2008-04-09 + */ +rsRetVal klogAfterRun(void) +{ + DEFiRet; + if(fklog != -1) + close(fklog); + RETiRet; +} + + + +/* to be called in the module's WillRun entry point, this is the main + * "message pull" mechanism. + * rgerhards, 2008-04-09 + */ +rsRetVal klogLogKMsg(void) +{ + DEFiRet; + sun_sys_poll(); + RETiRet; +} + + +/* provide the (system-specific) default facility for internal messages + * rgerhards, 2008-04-14 + */ +int +klogFacilIntMsg(void) +{ + return LOG_SYSLOG; +} + diff --git a/plugins/imklog/solaris_cddl.c b/plugins/imklog/solaris_cddl.c new file mode 100644 index 00000000..1053de66 --- /dev/null +++ b/plugins/imklog/solaris_cddl.c @@ -0,0 +1,323 @@ +#define MAXLINE 4096 +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* Portions Copyright 2010 by Rainer Gerhards and Adiscon + */ +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T + * All Rights Reserved + */ + +/* + * University Copyright- Copyright (c) 1982, 1986, 1988 + * The Regents of the University of California + * All Rights Reserved + * + * University Acknowledgment- Portions of this document are derived from + * software developed by the University of California, Berkeley, and its + * contributors. + */ +#include "config.h" +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <pthread.h> +#include <sys/poll.h> +#include <pthread.h> +#include <fcntl.h> +#include <stropts.h> +#include <assert.h> +#include <sys/strlog.h> + +#include "rsyslog.h" + +static struct pollfd Pfd; /* Pollfd for local the log device */ + + +/* findnl_bkwd: + * Scans each character in buf until it finds the last newline in buf, + * or the scanned character becomes the last COMPLETE character in buf. + * Returns the number of scanned bytes. + * + * buf - pointer to a buffer containing the message string + * len - the length of the buffer + */ +size_t +findnl_bkwd(const char *buf, const size_t len) +{ + const char *p; + size_t mb_cur_max; + pthread_t mythreadno; + + if (Debug) { + mythreadno = pthread_self(); + } + + if (len == 0) { + return (0); + } + + mb_cur_max = MB_CUR_MAX; + + if (mb_cur_max == 1) { + /* single-byte locale */ + for (p = buf + len - 1; p != buf; p--) { + if (*p == '\n') { + return ((size_t)(p - buf)); + } + } + return ((size_t)len); + } else { + /* multi-byte locale */ + int mlen; + const char *nl; + size_t rem; + + p = buf; + nl = NULL; + for (rem = len; rem >= mb_cur_max; ) { + mlen = mblen(p, mb_cur_max); + if (mlen == -1) { + /* + * Invalid character found. + */ + dbgprintf("klog:findnl_bkwd(%u): Invalid MB " + "sequence\n", mythreadno); + /* + * handle as a single byte character. + */ + p++; + rem--; + } else { + /* + * It's guaranteed that *p points to + * the 1st byte of a multibyte character. + */ + if (*p == '\n') { + nl = p; + } + p += mlen; + rem -= mlen; + } + } + if (nl) { + return ((size_t)(nl - buf)); + } + /* + * no newline nor null byte found. + * Also it's guaranteed that *p points to + * the 1st byte of a (multibyte) character + * at this point. + */ + return (len - rem); + } +} +//___ end + + +/* Attempts to open the local log device + * and return a file descriptor. + */ +int +sun_openklog(char *name, int mode) +{ + int fd; + struct strioctl str; + + if ((fd = open(name, mode)) < 0) { + //logerror("cannot open %s", name); + dbgprintf("klog:openklog: cannot open %s (%d)\n", + name, errno); + return (-1); + } + str.ic_cmd = I_CONSLOG; + str.ic_timout = 0; + str.ic_len = 0; + str.ic_dp = NULL; + if (ioctl(fd, I_STR, &str) < 0) { + //logerror("cannot register to log console messages"); + dbgprintf("klog:openklog: cannot register to log " + "console messages (%d)\n", errno); + return (-1); + } + Pfd.fd = fd; + Pfd.events = POLLIN; + return (fd); +} + + +/* + * Pull up one message from log driver. + */ +void +sun_getkmsg() +{ + int flags = 0, i; + char *lastline; + struct strbuf ctl, dat; + struct log_ctl hdr; + char buf[MAXLINE+1]; + size_t buflen; + size_t len; + char tmpbuf[MAXLINE+1]; + + dat.maxlen = MAXLINE; + dat.buf = buf; + ctl.maxlen = sizeof (struct log_ctl); + ctl.buf = (caddr_t)&hdr; + + while ((i = getmsg(Pfd.fd, &ctl, &dat, &flags)) == MOREDATA) { + lastline = &dat.buf[dat.len]; + *lastline = '\0'; + + dbgprintf("klog:sys_poll: getmsg: dat.len = %d\n", dat.len); + buflen = strlen(buf); + len = findnl_bkwd(buf, buflen); + + (void) memcpy(tmpbuf, buf, len); + tmpbuf[len] = '\0'; + + /* Format sys will enqueue the log message. + * Set the sync flag if timeout != 0, which + * means that we're done handling all the + * initial messages ready during startup. + */ + Syslog(LOG_INFO, buf); + /*if (timeout == 0) { + formatsys(&hdr, tmpbuf, 0); + //sys_init_msg_count++; + } else { + formatsys(&hdr, tmpbuf, 1); + }*/ + + if (len != buflen) { + /* If anything remains in buf */ + size_t remlen; + + if (buf[len] == '\n') { + /* skip newline */ + len++; + } + + /* Move the remaining bytes to + * the beginnning of buf. + */ + + remlen = buflen - len; + (void) memcpy(buf, &buf[len], remlen); + dat.maxlen = MAXLINE - remlen; + dat.buf = &buf[remlen]; + } else { + dat.maxlen = MAXLINE; + dat.buf = buf; + } + } + + if (i == 0 && dat.len > 0) { + dat.buf[dat.len] = '\0'; + /* + * Format sys will enqueue the log message. + * Set the sync flag if timeout != 0, which + * means that we're done handling all the + * initial messages ready during startup. + */ + dbgprintf("klog:getkmsg: getmsg: dat.maxlen = %d\n", dat.maxlen); + dbgprintf("klog:getkmsg: getmsg: dat.len = %d\n", dat.len); + dbgprintf("klog:getkmsg: getmsg: strlen(dat.buf) = %d\n", strlen(dat.buf)); + dbgprintf("klog:getkmsg: getmsg: dat.buf = \"%s\"\n", dat.buf); + dbgprintf("klog:getkmsg: buf len = %d\n", strlen(buf)); + //if (timeout == 0) { + //formatsys(&hdr, buf, 0); + //--sys_init_msg_count++; + //} else { + //formatsys(&hdr, buf, 1); + //} + Syslog(LOG_INFO, buf); + } else if (i < 0 && errno != EINTR) { + if(1){ // (!shutting_down) { + dbgprintf("klog:kernel log driver read error"); + } + // TODO trigger retry logic + //(void) close(Pfd.fd); + //Pfd.fd = -1; + } +} + + +/* this thread listens to the local stream log driver for log messages + * generated by this host, formats them, and queues them to the logger + * thread. + */ +/*ARGSUSED*/ +void * +sun_sys_poll() +{ + int nfds; + + dbgprintf("klog:sys_poll: sys_thread started\n"); + + /* + * Try to process as many messages as we can without blocking on poll. + * We count such "initial" messages with sys_init_msg_count and + * enqueue them without the SYNC_FILE flag. When no more data is + * waiting on the local log device, we set timeout to INFTIM, + * clear sys_init_msg_count, and generate a flush message to sync + * the previously counted initial messages out to disk. + */ + + for (;;) { + errno = 0; + + nfds = poll(&Pfd, 1, INFTIM); + + if (nfds == 0) + continue; + + if (nfds < 0) { + if (errno != EINTR) + dbgprintf("klog:poll error");// logerror("poll"); + continue; + } + if (Pfd.revents & POLLIN) { + sun_getkmsg(); + } else { + // TODO: shutdown, the rsyslog way (in v5!) + //if (shutting_down) { + //pthread_exit(0); + //} + if (Pfd.revents & (POLLNVAL|POLLHUP|POLLERR)) { + // TODO: trigger retry logic +/* logerror("kernel log driver poll error"); + (void) close(Pfd.fd); + Pfd.fd = -1; + */ + } + } + + } + /*NOTREACHED*/ + return (NULL); +} diff --git a/plugins/imklog/solaris_cddl.h b/plugins/imklog/solaris_cddl.h new file mode 100644 index 00000000..22295658 --- /dev/null +++ b/plugins/imklog/solaris_cddl.h @@ -0,0 +1 @@ +int sun_openklog(char *name, int mode); diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c index ecc36c28..d76f3544 100644 --- a/plugins/imudp/imudp.c +++ b/plugins/imudp/imudp.c @@ -242,7 +242,7 @@ processSocket(int fd, struct sockaddr_storage *frominetPrev, int *pbIsPermitted, } } - DBGPRINTF("recv(%d,%d)/%s,acl:%d,msg:%.80s\n", fd, (int) lenRcvBuf, fromHost, *pbIsPermitted, pRcvBuf); + DBGPRINTF("recv(%d,%d)/%s,acl:%d,msg:%s\n", fd, (int) lenRcvBuf, fromHost, *pbIsPermitted, pRcvBuf); if(*pbIsPermitted) { if((iTimeRequery == 0) || (iNbrTimeUsed++ % iTimeRequery) == 0) { diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 5aa3c25b..daa3bb47 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -71,7 +71,7 @@ DEFobjCurrIf(errmsg) DEFobjCurrIf(glbl) DEFobjCurrIf(prop) -static prop_t *pInputName = NULL; /* our inputName currently is always "imudp", and this will hold it */ +static prop_t *pInputName = NULL; /* our inputName currently is always "imuxsock", and this will hold it */ static int startIndexUxLocalSockets; /* process funix from that index on (used to * suppress local logging. rgerhards 2005-08-01 * read-only after startup @@ -315,7 +315,16 @@ CODESTARTwillRun register int i; /* first apply some config settings */ - startIndexUxLocalSockets = bOmitLocalLogging ? 1 : 0; +# ifdef OS_SOLARIS + /* under solaris, we must NEVER process the local log socket, because + * it is implemented there differently. If we used it, we would actually + * delete it and render the system partly unusable. So don't do that. + * rgerhards, 2010-03-26 + */ + startIndexUxLocalSockets = 1; +# else + startIndexUxLocalSockets = bOmitLocalLogging ? 1 : 0; +# endif if(pLogSockName != NULL) funixn[0] = pLogSockName; @@ -327,7 +336,7 @@ CODESTARTwillRun /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInputName)); - CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imudp"), sizeof("imudp") - 1)); + CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("imuxsock"), sizeof("imuxsock") - 1)); CHKiRet(prop.ConstructFinalize(pInputName)); finalize_it: @@ -344,7 +353,7 @@ CODESTARTafterRun close(funix[i]); /* Clean-up files. */ - for (i = 0; i < nfunix; i++) + for(i = startIndexUxLocalSockets; i < nfunix; i++) if (funixn[i] && funix[i] != -1) unlink((char*) funixn[i]); /* free no longer needed string */ diff --git a/plugins/omgssapi/omgssapi.c b/plugins/omgssapi/omgssapi.c index 7b5a46e1..782ac22f 100644 --- a/plugins/omgssapi/omgssapi.c +++ b/plugins/omgssapi/omgssapi.c @@ -377,7 +377,7 @@ CODESTARTtryResume ENDtryResume BEGINdoAction - char *psz; /* temporary buffering */ + char *psz = NULL; /* temporary buffering */ register unsigned l; int iMaxLine; CODESTARTdoAction @@ -431,11 +431,14 @@ CODESTARTdoAction * rgerhards, 2006-11-30 */ dbgprintf("Compression failed, sending uncompressed message\n"); + free(out); } 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! */ + } else { + free(out); } ++destLen; } @@ -450,6 +453,12 @@ CODESTARTdoAction break; } finalize_it: +# ifdef USE_NETZIP + if((psz != NULL) && (psz != (char*) ppString[0])) { + /* we need to free temporary buffer, alloced above - Naoya Nakazawa, 2010-01-11 */ + free(psz); + } +# endif ENDdoAction diff --git a/plugins/ompgsql/createDB.sql b/plugins/ompgsql/createDB.sql index facdcaa0..2f72a0a6 100644 --- a/plugins/ompgsql/createDB.sql +++ b/plugins/ompgsql/createDB.sql @@ -1,4 +1,4 @@ -CREATE DATABASE "Syslog"; +CREATE DATABASE 'Syslog' WITH ENCODING 'SQL_ASCII'; \c Syslog; CREATE TABLE SystemEvents ( |