From dd7e91f35dd70f0bbf657f0dc21ddc2afdcb0602 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 16 Apr 2008 08:12:11 +0200 Subject: more or less finished im3195 but need changes in liblogging to complete this work - does not compile yet --- plugins/im3195/im3195.c | 313 +++++++++++++++--------------------------------- 1 file changed, 95 insertions(+), 218 deletions(-) (limited to 'plugins/im3195') diff --git a/plugins/im3195/im3195.c b/plugins/im3195/im3195.c index f79ec949..6bc2c4e9 100644 --- a/plugins/im3195/im3195.c +++ b/plugins/im3195/im3195.c @@ -1,12 +1,21 @@ /** - * rfc3195d.c - * This is an RFC 3195 listener. All data received is forwarded to - * local UNIX domain socket, where it can be picked up by a - * syslog daemon (like rsyslogd ;)). + * The rfc3195 input module. + * + * Please note that this file replaces the rfc3195d daemon that was + * also present in pre-v3 versions of rsyslog. + * + * WARNING: due to no demand at all for RFC3195, we have converted rfc3195d + * to this input module, but we have NOT conducted any testing. Also, + * the module does not yet properly handle the recovery case. If someone + * intends to put this module into production, good testing should be + * made and it also is a good idea to notify me that you intend to use + * it in production. In this case, I'll probably give the module another + * cleanup. I don't do this now because so far it looks just like a big + * waste of time. -- rgerhards, 2008-04-16 * * \author Rainer Gerhards * - * Copyright 2003-2005 Rainer Gerhards and Adiscon GmbH. + * Copyright 2003-2008 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -28,30 +37,25 @@ #include "config.h" #include -#ifndef FEATURE_RFC3195 -/* this is a trick: if RFC3195 is not to be supported, we just do an - * error message. - */ -int main() -{ - fprintf(stderr, "error: not compiled with FEATURE_RFC3195 - terminating.\n"); - return(1); -} -#else #include -#include -#include #include +#include #include "rsyslog.h" +#include "syslogd.h" #include "liblogging.h" #include "srAPI.h" #include "syslogmessage.h" +#include "module-template.h" +#include "cfsysline.h" +#include "errmsg.h" + +MODULE_TYPE_INPUT -/* configurable params! */ -static char* pPathLogname = "/dev/log3195"; -static char *PidFile; -static int NoFork = 0; -static int Debug = 0; +/* Module static data */ +DEF_IMOD_STATIC_DATA +DEFobjCurrIf(errmsg) + +/* configuration settings */ static int listenPort = 601; /* we use a global API object below, because this listener is @@ -60,230 +64,103 @@ static int listenPort = 601; */ static srAPIObj* pAPI; -static int LogFile = -1; /* fd for log */ -static int connected; /* have done connect */ -static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ - -/* small usage info */ -static int usage() -{ - /* The following usage line is what we intend to have - it - * is commented out as a reminder. The one below is what we - * currently actually do... - fprintf(stderr, "usage: rfc3195d [-dv] [-i pidfile] [-n] [-p path]\n"); - */ - fprintf(stderr, "usage: rfc3195d [-dv] [-r port] [-p path]\n"); - exit(1); -} - -/* CLOSELOG -- close the system log - */ -static void closelog(void) -{ - close(LogFile); - LogFile = -1; - connected = 0; -} - -/* OPENLOG -- open system log - */ -static void openlog() -{ - if (LogFile == -1) { - SyslogAddr.sa_family = AF_UNIX; - strncpy(SyslogAddr.sa_data, pPathLogname, - sizeof(SyslogAddr.sa_data)); - LogFile = socket(AF_UNIX, SOCK_DGRAM, 0); - if(LogFile < 0) { - char errStr[1024]; - printf("error opening '%s': %s\n", - pPathLogname, rs_strerror_r(errno, errStr, sizeof(errStr))); - } - } - if (LogFile != -1 && !connected && - connect(LogFile, &SyslogAddr, sizeof(SyslogAddr.sa_family)+ - strlen(SyslogAddr.sa_data)) != -1) - connected = 1; - else { - char errStr[1024]; - printf("error connecting '%s': %s\n", - pPathLogname, rs_strerror_r(errno, errStr, sizeof(errStr))); - } -} - /* This method is called when a message has been fully received. - * It passes the received message to the specified unix domain - * socket. Please note that this callback is synchronous, thus + * It passes the received message to the rsyslog main message + * queue. Please note that this callback is synchronous, thus * liblogging will be on hold until it returns. This is important * to note because in an error case we might stay in this code * for an extended amount of time. So far, we think this is the * best solution, but real-world experience might tell us a * different truth ;) - * rgerhards 2005-10-12 */ -void OnReceive(srAPIObj* pAPI, srSLMGObj* pSLMG) +void OnReceive(srAPIObj* __attribute__((unused)) pMyAPI, srSLMGObj* pSLMG) { - unsigned char *pszRawMsg; - int iRetries; /* number of retries connecting to log socket */ - int iSleep; - int iWriteOffset; - ssize_t nToWrite; - ssize_t nWritten; + uchar *pszRawMsg; + uchar *fromHost = (uchar*) "[unset]"; /* TODO: get hostname */ srSLMGGetRawMSG(pSLMG, &pszRawMsg); - /* we need to loop writing the message. At least in - * theory, a single write might not send all data to the - * syslogd. So we need to continue until everything is written. - * Also, we need to check if there are any socket erros, in - * which case we reconect. We will re-try indefinitely, if this - * is not acceptable, you need to change the code. - * rgerhards 2005-10-12 + parseAndSubmitMessage((char*)fromHost, (char*) pszRawMsg, strlen((char*)pszRawMsg), + MSG_PARSE_HOSTNAME, NOFLAG, eFLOWCTL_FULL_DELAY); +} + + +BEGINrunInput +CODESTARTrunInput + /* this is an endless loop - it is terminated when the thread is + * signalled to do so. This, however, is handled by the framework, + * right into the sleep below. */ - iRetries = 0; - nToWrite = strlen(pszRawMsg); - iWriteOffset = 0; - while(nToWrite != 0) { - if(LogFile < 0 || !connected) - openlog(); - if(LogFile < 0 || !connected) { - /* still not connected, retry */ - if(iRetries > 0) { - iSleep = (iRetries < 30) ? iRetries : 30; - /* we sleep a little to prevent a thight loop */ - if(Debug) - printf("multiple retries connecting to log socket" - " - doing sleep(%d)\n", iSleep); - sleep(iSleep); - } - ++iRetries; - } else { - nWritten = write(LogFile, pszRawMsg, strlen(pszRawMsg)); - if(nWritten < 0) { - /* error, recover! */ - char errStr[1024]; - printf("error writing to domain socket: %s\r\n", rs_strerror_r(errno, errStr, sizeof(errStr))); - closelog(); - } else { - /* prepare for (potential) next write */ - nToWrite -= nWritten; - iWriteOffset += nWritten; - } + while(!pThrd->bShallStop) { + /* now move the listener to running state. Control will only + * return after SIGUSR1. + */ + if((iRet = srAPIRunListener(pAPI)) != SR_RET_OK) { + errmsg.LogError(NO_ERRCODE, "error %d running liblogging listener - im3195 is defunct", iRet); + FINALIZE; /* this causes im3195 to become defunct; TODO: recovery handling */ } } +finalize_it: +ENDrunInput + - if(Debug) { - static int largest = 0; - int sz = strlen(pszRawMsg); - if(sz > largest) - largest = sz; - printf("Msg(%d/%d):%s\n\n", largest, sz, pszRawMsg); +BEGINwillRun +CODESTARTwillRun + if((pAPI = srAPIInitLib()) == NULL) { + errmsg.LogError(NO_ERRCODE, "error initializing liblogging - im3195 is defunct"); + ABORT_FINALIZE(RS_RET_ERR); } -} + if((iRet = srAPISetOption(pAPI, srOPTION_BEEP_LISTENPORT, listenPort)) != SR_RET_OK) { + errmsg.LogError(NO_ERRCODE, "error %d setting liblogging listen port - im3195 is defunct", iRet); + FINALIZE; + } -/* As we are single-threaded in this example, we need - * one way to shut down the listener running on this - * single thread. We use SIG_INT to do so - it effectively - * provides a short-lived second thread ;-) - */ -void doShutdown(int i) -{ - printf("Shutting down rfc3195d. Be patient, this can take up to 30 seconds...\n"); - srAPIShutdownListener(pAPI); -} + if((iRet = srAPISetupListener(pAPI, OnReceive)) != SR_RET_OK) { + errmsg.LogError(NO_ERRCODE, "error %d setting up liblogging listener - im3195 is defunct", iRet); + FINALIZE; + } +finalize_it: +ENDwillRun -/* on the the real program ;) */ -int main(int argc, char* argv[]) -{ - srRetVal iRet; - int ch; - struct sigaction sigAct; - while ((ch = getopt(argc, argv, "di:np:r:v")) != EOF) - switch((char)ch) { - case 'd': /* debug */ - Debug = 1; - break; - case 'i': /* pid file name */ - PidFile = optarg; - break; - case 'n': /* don't fork */ - NoFork = 1; - break; - case 'p': /* path to regular log socket */ - pPathLogname = optarg; - break; - case 'r': /* listen port */ - listenPort = atoi(optarg); - if(listenPort < 1 || listenPort > 65535) { - printf("Error: invalid listen port '%s', using 601 instead\n", - optarg); - listenPort = 601; - } - break; - case 'v': - printf("rfc3195d %s.%s (using liblogging version %d.%d.%d).\n", - VERSION, PATCHLEVEL, - LIBLOGGING_VERSION_MAJOR, LIBLOGGING_VERSION_MINOR, - LIBLOGGING_VERSION_SUBMINOR); - printf("See http://www.rsyslog.com for more information.\n"); - exit(0); - case '?': - default: - usage(); - } - if ((argc -= optind)) - usage(); - - memset(&sigAct, 0, sizeof(sigAct)); - sigemptyset(&sigAct.sa_mask); - sigAct.sa_handler = doShutdown; - sigaction(SIGUSR1, &sigAct, NULL); - sigaction(SIGTERM, &sigAct, NULL); +BEGINafterRun +CODESTARTafterRun + dbgprintf("Shutting down rfc3195d. Be patient, this can take up to 30 seconds...\n"); + srAPIShutdownListener(pAPI); +ENDafterRun - if(!Debug) - { - sigAct.sa_handler = SIG_IGN; - sigaction(SIGINT, &sigAct, NULL); - } - if((pAPI = srAPIInitLib()) == NULL) - { - printf("Error initializing liblogging - aborting!\n"); - exit(1); - } +BEGINmodExit +CODESTARTmodExit + srAPIExitLib(pAPI); /* terminate liblogging */ + /* release objects we used */ + objRelease(errmsg, CORE_COMPONENT); +ENDmodExit - if((iRet = srAPISetOption(pAPI, srOPTION_BEEP_LISTENPORT, listenPort)) != SR_RET_OK) - { - printf("Error %d setting listen port - aborting\n", iRet); - exit(100); - } - if((iRet = srAPISetupListener(pAPI, OnReceive)) != SR_RET_OK) - { - printf("Error %d setting up listener - aborting\n", iRet); - exit(101); - } +BEGINqueryEtryPt +CODESTARTqueryEtryPt +CODEqueryEtryPt_STD_IMOD_QUERIES +ENDqueryEtryPt - /* now move the listener to running state. Control will only - * return after SIGUSR1. - */ - if((iRet = srAPIRunListener(pAPI)) != SR_RET_OK) - { - printf("Error %d running the listener - aborting\n", iRet); - exit(102); - } +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + listenPort = 601; + return RS_RET_OK; +} - /** control will reach this point after shutdown */ - srAPIExitLib(pAPI); - return 0; -} -#endif /* #ifndef FEATURE_RFC3195 - main wrapper */ +BEGINmodInit() +CODESTARTmodInit + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ +CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(errmsg, CORE_COMPONENT)); -/* - * vi:set ai: + CHKiRet(omsdRegCFSLineHdlr((uchar *)"input3195listenport", 0, eCmdHdlrInt, NULL, &listenPort, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); +ENDmodInit +/* vim:set ai: */ -- cgit