diff options
Diffstat (limited to 'omfwd.c')
-rw-r--r-- | omfwd.c | 492 |
1 files changed, 216 insertions, 276 deletions
@@ -12,19 +12,20 @@ * * Copyright 2007 Rainer Gerhards and Adiscon GmbH. * - * 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 file is part of rsyslog. * - * This program is distributed in the hope that it will be useful, + * 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * 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. */ @@ -46,11 +47,7 @@ #ifdef USE_NETZIP #include <zlib.h> #endif -#ifdef USE_PTHREADS #include <pthread.h> -#else -#include <fcntl.h> -#endif #include "syslogd.h" #include "syslogd-types.h" #include "srUtils.h" @@ -59,60 +56,58 @@ #include "template.h" #include "msg.h" #include "tcpsyslog.h" +#include "tcpclt.h" #include "cfsysline.h" #include "module-template.h" +#include "errmsg.h" -#ifdef SYSLOG_INET -#define INET_SUSPEND_TIME 60 /* equal to 1 minute - * rgerhards, 2005-07-26: This was 3 minutes. As the - * same timer is used for tcp based syslog, we have - * reduced it. However, it might actually be worth - * thinking about a buffered tcp sender, which would be - * a much better alternative. When that happens, this - * time here can be re-adjusted to 3 minutes (or, - * even better, made configurable). - */ -#define INET_RETRY_MAX 30 /* maximum of retries for gethostbyname() */ - /* was 10, changed to 30 because we reduced INET_SUSPEND_TIME by one third. So - * this "fixes" some of implications of it (see comment on INET_SUSPEND_TIME). - * rgerhards, 2005-07-26 - */ -#endif +MODULE_TYPE_OUTPUT /* internal structures */ DEF_OMOD_STATIC_DATA +DEFobjCurrIf(errmsg) +DEFobjCurrIf(net) +DEFobjCurrIf(tcpclt) typedef struct _instanceData { - char f_hname[MAXHOSTNAMELEN+1]; + char *f_hname; short sock; /* file descriptor */ + int *pSockArray; /* sockets to use for UDP */ enum { /* TODO: we shoud revisit these definitions */ eDestFORW, eDestFORW_SUSP, eDestFORW_UNKN } eDestState; - int iRtryCnt; struct addrinfo *f_addr; int compressionLevel; /* 0 - no compression, else level for zlib */ char *port; int protocol; - TCPFRAMINGMODE tcp_framing; # define FORW_UDP 0 # define FORW_TCP 1 /* following fields for TCP-based delivery */ - enum TCPSendStatus { - TCP_SEND_NOTCONNECTED = 0, - TCP_SEND_CONNECTING = 1, - TCP_SEND_READY = 2 - } status; - char *savedMsg; - int savedMsgLen; /* length of savedMsg in octets */ time_t ttSuspend; /* time selector was suspended */ -# ifdef USE_PTHREADS - pthread_mutex_t mtxTCPSend; -# endif + tcpclt_t *pTCPClt; /* our tcpclt object */ } instanceData; +/* config data */ +static uchar *pszTplName = NULL; /* name of the default template to use */ + + +/* get the syslog forward port from selector_t. The passed in + * struct must be one that is setup for forwarding. + * rgerhards, 2007-06-28 + * We may change the implementation to try to lookup the port + * if it is unspecified. So far, we use the IANA default auf 514. + */ +static char *getFwdSyslogPt(instanceData *pData) +{ + assert(pData != NULL); + if(pData->port == NULL) + return("514"); + else + return(pData->port); +} BEGINcreateInstance CODESTARTcreateInstance @@ -139,15 +134,20 @@ CODESTARTfreeInstance free(pData->port); break; } -# ifdef USE_PTHREADS - /* delete any mutex objects, if present */ - if(pData->protocol == FORW_TCP) { - pthread_mutex_destroy(&pData->mtxTCPSend); - } -# endif + /* final cleanup */ if(pData->sock >= 0) close(pData->sock); + if(pData->pSockArray != NULL) + net.closeUDPListenSockets(pData->pSockArray); + + if(pData->protocol == FORW_TCP) { + tcpclt.Destruct(&pData->pTCPClt); + } + + if(pData->f_hname != NULL) + free(pData->f_hname); + ENDfreeInstance @@ -156,66 +156,56 @@ CODESTARTdbgPrintInstInfo printf("%s", pData->f_hname); ENDdbgPrintInstInfo -/* CODE FOR SENDING TCP MESSAGES */ -/* set send status - * rgerhards, 2005-10-24 +/* Send a message via UDP + * rgehards, 2007-12-20 */ -static void TCPSendSetStatus(instanceData *pData, enum TCPSendStatus iNewState) +static rsRetVal UDPSend(instanceData *pData, char *msg, size_t len) { - assert(pData != NULL); - assert(pData->protocol == FORW_TCP); - assert( (iNewState == TCP_SEND_NOTCONNECTED) - || (iNewState == TCP_SEND_CONNECTING) - || (iNewState == TCP_SEND_READY)); - - /* there can potentially be a race condition, so guard by mutex */ -# ifdef USE_PTHREADS - pthread_mutex_lock(&pData->mtxTCPSend); -# endif - pData->status = iNewState; -# ifdef USE_PTHREADS - pthread_mutex_unlock(&pData->mtxTCPSend); -# endif -} + DEFiRet; + struct addrinfo *r; + int i; + unsigned lsent = 0; + int bSendSuccess; + if(pData->pSockArray != NULL) { + /* we need to track if we have success sending to the remote + * peer. Success is indicated by at least one sendto() call + * succeeding. We track this be bSendSuccess. We can not simply + * rely on lsent, as a call might initially work, but a later + * call fails. Then, lsent has the error status, even though + * the sendto() succeeded. + * rgerhards, 2007-06-22 + */ + bSendSuccess = FALSE; + for (r = pData->f_addr; r; r = r->ai_next) { + for (i = 0; i < *pData->pSockArray; i++) { + lsent = sendto(pData->pSockArray[i+1], msg, len, 0, r->ai_addr, r->ai_addrlen); + if (lsent == len) { + bSendSuccess = TRUE; + break; + } else { + int eno = errno; + char errStr[1024]; + dbgprintf("sendto() error: %d = %s.\n", + eno, rs_strerror_r(eno, errStr, sizeof(errStr))); + } + } + if (lsent == len && !send_to_all) + break; + } + /* finished looping */ + if (bSendSuccess == FALSE) { + dbgprintf("error forwarding via udp, suspending\n"); + iRet = RS_RET_SUSPENDED; + } + } -/* get send status - * rgerhards, 2005-10-24 - */ -static enum TCPSendStatus TCPSendGetStatus(instanceData *pData) -{ - enum TCPSendStatus eState; - assert(pData != NULL); - assert(pData->protocol == FORW_TCP); - - /* there can potentially be a race condition, so guard by mutex */ -# ifdef USE_PTHREADS - pthread_mutex_lock(&pData->mtxTCPSend); -# endif - eState = pData->status; -# ifdef USE_PTHREADS - pthread_mutex_unlock(&pData->mtxTCPSend); -# endif - - return eState; + RETiRet; } +/* CODE FOR SENDING TCP MESSAGES */ -/* get the syslog forward port from selector_t. The passed in - * struct must be one that is setup for forwarding. - * rgerhards, 2007-06-28 - * We may change the implementation to try to lookup the port - * if it is unspecified. So far, we use the IANA default auf 514. - */ -static char *getFwdSyslogPt(instanceData *pData) -{ - assert(pData != NULL); - if(pData->port == NULL) - return("514"); - else - return(pData->port); -} /* Send a frame via plain TCP protocol * rgerhards, 2007-12-28 @@ -246,12 +236,12 @@ static rsRetVal TCPSendFrame(void *pvData, char *msg, size_t len) * For the time being, we ignore this... * rgerhards, 2005-10-25 */ - dbgprintf("message not completely (tcp)send, ignoring %ld\n", lenSend); + dbgprintf("message not completely (tcp)send, ignoring %ld\n", (long) lenSend); usleep(1000); /* experimental - might be benefitial in this situation */ /* TODO: we need to revisit this code -- rgerhards, 2007-12-28 */ } - return iRet; + RETiRet; } @@ -261,12 +251,13 @@ static rsRetVal TCPSendFrame(void *pvData, char *msg, size_t len) */ static rsRetVal TCPSendPrepRetry(void *pvData) { + DEFiRet; instanceData *pData = (instanceData *) pvData; assert(pData != NULL); close(pData->sock); pData->sock = -1; - return RS_RET_OK; + RETiRet; } @@ -280,15 +271,14 @@ static rsRetVal TCPSendInit(void *pvData) assert(pData != NULL); if(pData->sock < 0) { - if((pData->sock = TCPSendCreateSocket(pData->f_addr)) < 0) + if((pData->sock = tcpclt.CreateSocket(pData->f_addr)) < 0) iRet = RS_RET_TCP_SOCKCREATE_ERR; } - return iRet; + RETiRet; } - /* try to resume connection if it is not ready * rgerhards, 2007-08-02 */ @@ -320,7 +310,6 @@ static rsRetVal doTryResume(instanceData *pData) getFwdSyslogPt(pData), &hints, &res)) == 0) { dbgprintf("%s found, resuming.\n", pData->f_hname); pData->f_addr = res; - pData->iRtryCnt = 0; pData->eDestState = eDestFORW; } else { iRet = RS_RET_SUSPENDED; @@ -333,7 +322,7 @@ static rsRetVal doTryResume(instanceData *pData) break; } - return iRet; + RETiRet; } @@ -345,10 +334,6 @@ ENDtryResume BEGINdoAction char *psz; /* temporary buffering */ register unsigned l; - struct addrinfo *r; - int i; - unsigned lsent = 0; - int bSendSuccess; CODESTARTdoAction switch (pData->eDestState) { case eDestFORW_SUSP: @@ -364,108 +349,75 @@ CODESTARTdoAction case eDestFORW: dbgprintf(" %s:%s/%s\n", pData->f_hname, getFwdSyslogPt(pData), pData->protocol == FORW_UDP ? "udp" : "tcp"); - if ( 0) // TODO: think about this strcmp(getHOSTNAME(f->f_pMsg), LocalHostName) && NoHops ) - /* what we need to do is get the hostname as an additonal string (during parseSe..). Then, - * we can compare that string to LocalHostName. That way, we do not need to access the - * msgobject, and everything is clean. The question remains, though, if that functionality - * here actually makes sense or not. If we really need it, it might make more sense to compare - * the target IP address to the IP addresses of the local machene - that is a far better way of - * handling things than to relay on the error-prone hostname property. - * rgerhards, 2007-07-27 - */ - dbgprintf("Not sending message to remote.\n"); - else { - pData->ttSuspend = time(NULL); - psz = (char*) ppString[0]; - l = strlen((char*) psz); - if (l > MAXLINE) - l = MAXLINE; + /* with UDP, check if the socket is there and, if not, alloc + * it. TODO: there should be a better place for that code. + * rgerhards, 2007-12-26 + */ + if(pData->protocol == FORW_UDP) { + if(pData->pSockArray == NULL) { + pData->pSockArray = net.create_udp_socket((uchar*)pData->f_hname, NULL, 0); + } + } + pData->ttSuspend = time(NULL); + psz = (char*) ppString[0]; + l = strlen((char*) psz); + if (l > MAXLINE) + l = MAXLINE; # ifdef USE_NETZIP - /* Check if we should compress and, if so, do it. We also - * check if the message is large enough to justify compression. - * The smaller the message, the less likely is a gain in compression. - * To save CPU cycles, we do not try to compress very small messages. - * What "very small" means needs to be configured. Currently, it is - * hard-coded but this may be changed to a config parameter. - * rgerhards, 2006-11-30 - */ - if(pData->compressionLevel && (l > MIN_SIZE_FOR_COMPRESS)) { - Bytef out[MAXLINE+MAXLINE/100+12] = "z"; - uLongf destLen = sizeof(out) / sizeof(Bytef); - uLong srcLen = l; - int ret; - ret = compress2((Bytef*) out+1, &destLen, (Bytef*) psz, - srcLen, pData->compressionLevel); - dbgprintf("Compressing message, length was %d now %d, return state %d.\n", - l, (int) destLen, ret); - if(ret != Z_OK) { - /* if we fail, we complain, but only in debug mode - * Otherwise, we are silent. In any case, we ignore the - * failed compression and just sent the uncompressed - * data, which is still valid. So this is probably the - * best course of action. - * rgerhards, 2006-11-30 - */ - dbgprintf("Compression failed, sending uncompressed message\n"); - } 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! */ - } - ++destLen; + /* Check if we should compress and, if so, do it. We also + * check if the message is large enough to justify compression. + * The smaller the message, the less likely is a gain in compression. + * To save CPU cycles, we do not try to compress very small messages. + * What "very small" means needs to be configured. Currently, it is + * hard-coded but this may be changed to a config parameter. + * rgerhards, 2006-11-30 + */ + if(pData->compressionLevel && (l > MIN_SIZE_FOR_COMPRESS)) { + Bytef out[MAXLINE+MAXLINE/100+12] = "z"; + uLongf destLen = sizeof(out) / sizeof(Bytef); + uLong srcLen = l; + int ret; + ret = compress2((Bytef*) out+1, &destLen, (Bytef*) psz, + srcLen, pData->compressionLevel); + dbgprintf("Compressing message, length was %d now %d, return state %d.\n", + l, (int) destLen, ret); + if(ret != Z_OK) { + /* if we fail, we complain, but only in debug mode + * Otherwise, we are silent. In any case, we ignore the + * failed compression and just sent the uncompressed + * data, which is still valid. So this is probably the + * best course of action. + * rgerhards, 2006-11-30 + */ + dbgprintf("Compression failed, sending uncompressed message\n"); + } 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! */ } + ++destLen; + } # endif - if(pData->protocol == FORW_UDP) { - /* forward via UDP */ - if(finet != NULL) { - /* we need to track if we have success sending to the remote - * peer. Success is indicated by at least one sendto() call - * succeeding. We track this be bSendSuccess. We can not simply - * rely on lsent, as a call might initially work, but a later - * call fails. Then, lsent has the error status, even though - * the sendto() succeeded. - * rgerhards, 2007-06-22 - */ - bSendSuccess = FALSE; - for (r = pData->f_addr; r; r = r->ai_next) { - for (i = 0; i < *finet; i++) { - lsent = sendto(finet[i+1], psz, l, 0, - r->ai_addr, r->ai_addrlen); - if (lsent == l) { - bSendSuccess = TRUE; - break; - } else { - int eno = errno; - char errStr[1024]; - dbgprintf("sendto() error: %d = %s.\n", - eno, rs_strerror_r(eno, errStr, sizeof(errStr))); - } - } - if (lsent == l && !send_to_all) - break; - } - /* finished looping */ - if (bSendSuccess == FALSE) { - dbgprintf("error forwarding via udp, suspending\n"); - iRet = RS_RET_SUSPENDED; - } - } - } else { - int ret; - ret = TCPSend(pData, psz, l, pData->tcp_framing, TCPSendInit, TCPSendFrame, TCPSendPrepRetry); - if(ret != RS_RET_OK) { - /* error! */ - dbgprintf("error forwarding via tcp, suspending\n"); - pData->eDestState = eDestFORW_SUSP; - iRet = RS_RET_SUSPENDED; - } + if(pData->protocol == FORW_UDP) { + /* forward via UDP */ + CHKiRet(UDPSend(pData, psz, l)); + } else { + /* forward via TCP */ + rsRetVal ret; + ret = tcpclt.Send(pData->pTCPClt, pData, psz, l); + if(ret != RS_RET_OK) { + /* error! */ + dbgprintf("error forwarding via tcp, suspending\n"); + pData->eDestState = eDestFORW_SUSP; + iRet = RS_RET_SUSPENDED; } } break; } +finalize_it: ENDdoAction @@ -475,6 +427,7 @@ BEGINparseSelectorAct int error; int bErr; struct addrinfo hints, *res; + TCPFRAMINGMODE tcp_framing = TCP_FRAMING_OCTET_STUFFING; CODESTARTparseSelectorAct CODE_STD_STRING_REQUESTparseSelectorAct(1) if(*p == '@') { @@ -484,10 +437,6 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) if(*p == '@') { /* indicator for TCP! */ pData->protocol = FORW_TCP; ++p; /* eat this '@', too */ - /* in this case, we also need a mutex... */ -# ifdef USE_PTHREADS - pthread_mutex_init(&pData->mtxTCPSend, 0); -# endif } else { pData->protocol = FORW_UDP; } @@ -519,20 +468,20 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) ++p; /* eat */ pData->compressionLevel = iLevel; } else { - logerrorInt("Invalid compression level '%c' specified in " + errmsg.LogError(NO_ERRCODE, "Invalid compression level '%c' specified in " "forwardig action - NOT turning on compression.", *p); } # else - logerror("Compression requested, but rsyslogd is not compiled " + errmsg.LogError(NO_ERRCODE, "Compression requested, but rsyslogd is not compiled " "with compression support - request ignored."); # endif /* #ifdef USE_NETZIP */ } else if(*p == 'o') { /* octet-couting based TCP framing? */ ++p; /* eat */ /* no further options settable */ - pData->tcp_framing = TCP_FRAMING_OCTET_COUNTING; + tcp_framing = TCP_FRAMING_OCTET_COUNTING; } else { /* invalid option! Just skip it... */ - logerrorInt("Invalid option %c in forwarding action - ignoring.", *p); + errmsg.LogError(NO_ERRCODE, "Invalid option %c in forwarding action - ignoring.", *p); ++p; /* eat invalid option */ } /* the option processing is done. We now do a generic skip @@ -548,7 +497,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) /* we probably have end of string - leave it for the rest * of the code to handle it (but warn the user) */ - logerror("Option block not terminated in forwarding action."); + errmsg.LogError(NO_ERRCODE, "Option block not terminated in forwarding action."); } /* extract the host first (we do a trick - we replace the ';' or ':' with a '\0') * now skip to port and then template name. rgerhards 2005-07-06 @@ -576,7 +525,7 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) /* SKIP AND COUNT */; pData->port = malloc(i + 1); if(pData->port == NULL) { - logerror("Could not get memory to store syslog forwarding port, " + errmsg.LogError(NO_ERRCODE, "Could not get memory to store syslog forwarding port, " "using default port, results may not be what you intend\n"); /* we leave f_forw.port set to NULL, this is then handled by * getFwdSyslogPt(). @@ -589,30 +538,22 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) /* now skip to template */ bErr = 0; - while(*p && *p != ';') { - if(*p && *p != ';' && !isspace((int) *p)) { - if(bErr == 0) { /* only 1 error msg! */ - bErr = 1; - errno = 0; - logerror("invalid selector line (port), probably not doing " - "what was intended"); - } - } - ++p; - } - + while(*p && *p != ';' && *p != '#' && !isspace((int) *p)) + ++p; /*JUST SKIP*/ + /* TODO: make this if go away! */ - if(*p == ';') { + if(*p == ';' || *p == '#' || isspace(*p)) { + uchar cTmp = *p; *p = '\0'; /* trick to obtain hostname (later)! */ - strcpy(pData->f_hname, (char*) q); - *p = ';'; - } else - strcpy(pData->f_hname, (char*) q); + CHKmalloc(pData->f_hname = strdup((char*) q)); + *p = cTmp; + } else { + CHKmalloc(pData->f_hname = strdup((char*) q)); + } /* process template */ - if((iRet = cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, (uchar*) " StdFwdFmt")) - != RS_RET_OK) - goto finalize_it; + CHKiRet(cflineParseTemplateName(&p, *ppOMSR, 0, OMSR_NO_RQD_TPL_OPTS, + (pszTplName == NULL) ? (uchar*)"RSYSLOG_TraditionalForwardFormat" : pszTplName)); /* first set the pData->eDestState */ memset(&hints, 0, sizeof(hints)); @@ -622,19 +563,26 @@ CODE_STD_STRING_REQUESTparseSelectorAct(1) hints.ai_socktype = pData->protocol == FORW_UDP ? SOCK_DGRAM : SOCK_STREAM; if( (error = getaddrinfo(pData->f_hname, getFwdSyslogPt(pData), &hints, &res)) != 0) { pData->eDestState = eDestFORW_UNKN; - pData->iRtryCnt = INET_RETRY_MAX; pData->ttSuspend = time(NULL); } else { pData->eDestState = eDestFORW; pData->f_addr = res; } - - /* - * Otherwise the host might be unknown due to an + /* Otherwise the host might be unknown due to an * inaccessible nameserver (perhaps on the same * host). We try to get the ip number later, like * FORW_SUSP. */ + if(pData->protocol == FORW_TCP) { + /* create our tcpclt */ + CHKiRet(tcpclt.Construct(&pData->pTCPClt)); + /* and set callbacks */ + CHKiRet(tcpclt.SetSendInit(pData->pTCPClt, TCPSendInit)); + CHKiRet(tcpclt.SetSendFrame(pData->pTCPClt, TCPSendFrame)); + CHKiRet(tcpclt.SetSendPrepRetry(pData->pTCPClt, TCPSendPrepRetry)); + CHKiRet(tcpclt.SetFraming(pData->pTCPClt, tcp_framing)); + } + } else { iRet = RS_RET_CONFLINE_UNPROCESSED; } @@ -646,44 +594,17 @@ CODE_STD_FINALIZERparseSelectorAct ENDparseSelectorAct -BEGINneedUDPSocket -CODESTARTneedUDPSocket - iRet = RS_RET_TRUE; -ENDneedUDPSocket - - -BEGINonSelectReadyWrite -CODESTARTonSelectReadyWrite - dbgprintf("tcp send socket %d ready for writing.\n", pData->sock); - TCPSendSetStatus(pData, TCP_SEND_READY); - /* Send stored message (if any) */ - if(pData->savedMsg != NULL) { - if(TCPSend(pData, pData->savedMsg, pData->savedMsgLen, pData->tcp_framing, - TCPSendInit, TCPSendFrame, TCPSendPrepRetry) != RS_RET_OK) { - /* error! */ - pData->eDestState = eDestFORW_SUSP; - errno = 0; - logerror("error forwarding via tcp, suspending..."); - } - free(pData->savedMsg); - pData->savedMsg = NULL; - } -ENDonSelectReadyWrite - - -BEGINgetWriteFDForSelect -CODESTARTgetWriteFDForSelect - if( (pData->eDestState == eDestFORW) - && (pData->protocol == FORW_TCP) - && TCPSendGetStatus(pData) == TCP_SEND_CONNECTING) { - *fd = pData->sock; - iRet = RS_RET_OK; - } -ENDgetWriteFDForSelect - - BEGINmodExit CODESTARTmodExit + /* release what we no longer need */ + objRelease(errmsg, CORE_COMPONENT); + objRelease(net, LM_NET_FILENAME); + objRelease(tcpclt, LM_TCPCLT_FILENAME); + + if(pszTplName != NULL) { + free(pszTplName); + pszTplName = NULL; + } ENDmodExit @@ -693,13 +614,32 @@ CODEqueryEtryPt_STD_OMOD_QUERIES ENDqueryEtryPt +/* Reset config variables for this module to default values. + * rgerhards, 2008-03-28 + */ +static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) +{ + if(pszTplName != NULL) { + free(pszTplName); + pszTplName = NULL; + } + + return RS_RET_OK; +} + + BEGINmodInit(Fwd) CODESTARTmodInit - *ipIFVersProvided = 1; /* so far, we only support the initial definition */ + *ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */ CODEmodInit_QueryRegCFSLineHdlr + CHKiRet(objUse(errmsg, CORE_COMPONENT)); + CHKiRet(objUse(net, LM_NET_FILENAME)); + CHKiRet(objUse(tcpclt, LM_TCPCLT_FILENAME)); + + CHKiRet(regCfSysLineHdlr((uchar *)"actionforwarddefaulttemplate", 0, eCmdHdlrGetWord, NULL, &pszTplName, NULL)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID)); ENDmodInit #endif /* #ifdef SYSLOG_INET */ -/* - * vi:set ai: +/* vim:set ai: */ |