From 24c5e87b82a655ac7556f66f4d1cec8c3fe9ee2a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 2 Apr 2008 12:34:20 +0000 Subject: added more meaningful error messages to rsyslogd (when some errors happens during startup) --- syslogd.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index 1c31fb61..8c71f57d 100644 --- a/syslogd.c +++ b/syslogd.c @@ -2828,11 +2828,15 @@ static rsRetVal InitGlobalClasses(void) { DEFiRet; + char *pErrObj; /* tells us which object failed if that happens (useful for troubleshooting!) */ + pErrObj = "obj"; CHKiRet(objClassInit(NULL)); /* *THIS* *MUST* always be the first class initilizer being called! */ CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ /* the following classes were intialized by objClassInit() */ + pErrObj = "errmsg"; CHKiRet(objUse(errmsg, CORE_COMPONENT)); + pErrObj = "module"; CHKiRet(objUse(module, CORE_COMPONENT)); /* initialize and use classes. We must be very careful with the order of events. Some @@ -2843,35 +2847,61 @@ InitGlobalClasses(void) * class immediately after it is initialized. And, of course, we load those classes * first that we use ourselfs... -- rgerhards, 2008-03-07 */ + pErrObj = "datetime"; CHKiRet(datetimeClassInit(NULL)); CHKiRet(objUse(datetime, CORE_COMPONENT)); + pErrObj = "msg"; CHKiRet(msgClassInit(NULL)); + pErrObj = "str,"; CHKiRet(strmClassInit(NULL)); + pErrObj = "wti"; CHKiRet(wtiClassInit(NULL)); + pErrObj = "wtp"; CHKiRet(wtpClassInit(NULL)); + pErrObj = "queue"; CHKiRet(queueClassInit(NULL)); + pErrObj = "vmstk"; CHKiRet(vmstkClassInit(NULL)); + pErrObj = "sysvar"; CHKiRet(sysvarClassInit(NULL)); + pErrObj = "vm"; CHKiRet(vmClassInit(NULL)); CHKiRet(objUse(vm, CORE_COMPONENT)); + pErrObj = "vmop"; CHKiRet(vmopClassInit(NULL)); + pErrObj = "vmprg"; CHKiRet(vmprgClassInit(NULL)); + pErrObj = "ctok_token"; CHKiRet(ctok_tokenClassInit(NULL)); + pErrObj = "ctok"; CHKiRet(ctokClassInit(NULL)); + pErrObj = "expr"; CHKiRet(exprClassInit(NULL)); CHKiRet(objUse(expr, CORE_COMPONENT)); + pErrObj = "conf"; CHKiRet(confClassInit(NULL)); CHKiRet(objUse(conf, CORE_COMPONENT)); /* dummy "classes" */ + pErrObj = "action"; CHKiRet(actionClassInit()); + pErrObj = "template"; CHKiRet(templateInit()); + pErrObj = "str"; CHKiRet(strInit()); /* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ + pErrObj = "net"; CHKiRet(objUse(net, LM_NET_FILENAME)); finalize_it: + if(iRet != RS_RET_OK) { + /* we know we are inside the init sequence, so we can safely emit + * messages to stderr. -- rgerhards, 2008-04-02 + */ + fprintf(stderr, "Error during class init for object '%s' - failing...\n", pErrObj); + } + RETiRet; } @@ -2957,7 +2987,14 @@ int realMain(int argc, char **argv) int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ uchar legacyConfLine[80]; - CHKiRet(InitGlobalClasses()); + + CHKiRet_Hdlr(InitGlobalClasses()) { + fprintf(stderr, "rsyslogd initializiation failed - global classes could not be initialized.\n" + "Did you do a \"make install\"?\n" + "Suggested action: run rsyslogd with -d -n options to see what exactly " + "fails.\n"); + FINALIZE; + } /* doing some core initializations */ if((iRet = modInitIminternal()) != RS_RET_OK) { @@ -3298,7 +3335,8 @@ int realMain(int argc, char **argv) finalize_it: if(iRet != RS_RET_OK) - fprintf(stderr, "rsyslogd run failed with error %d.\n", iRet); + fprintf(stderr, "rsyslogd run failed with error %d\n(see rsyslog.h " + "or http://www.rsyslog.com/errcode to learn what that number means)\n", iRet); ENDfunc return 0; -- cgit v1.2.3 From 11461ad9c6de62556df79a35ff0c4902e2881f57 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 3 Apr 2008 08:47:35 +0000 Subject: bugfix: memory leaks in script engine --- syslogd.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index 8c71f57d..b5554e5f 100644 --- a/syslogd.c +++ b/syslogd.c @@ -170,6 +170,7 @@ DEFobjCurrIf(datetime) DEFobjCurrIf(conf) DEFobjCurrIf(expr) DEFobjCurrIf(vm) +DEFobjCurrIf(var) DEFobjCurrIf(module) DEFobjCurrIf(errmsg) DEFobjCurrIf(net) /* TODO: make go away! */ @@ -928,8 +929,8 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce unsigned short pbMustBeFreed; char *pszPropVal; int bRet = 0; - vm_t *pVM; - var_t *pResult; + vm_t *pVM = NULL; + var_t *pResult = NULL; assert(f != NULL); assert(pMsg != NULL); @@ -995,7 +996,7 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce CHKiRet(vm.ExecProg(pVM, f->f_filterData.f_expr->pVmprg)); CHKiRet(vm.PopBoolFromStack(pVM, &pResult)); dbgprintf("result of expression evaluation: %lld\n", pResult->val.num); - CHKiRet(vm.Destruct(&pVM)); + /* VM is destructed on function exit */ bRet = (pResult->val.num) ? 1 : 0; } else { assert(f->f_filter_type == FILTER_PROP); /* assert() just in case... */ @@ -1051,6 +1052,12 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce } finalize_it: + /* destruct in any case, not just on error, but it makes error handling much easier */ + if(pVM != NULL) { + var.Destruct(&pResult); + vm.Destruct(&pVM); + } + *bProcessMsg = bRet; RETiRet; } @@ -2838,6 +2845,8 @@ InitGlobalClasses(void) CHKiRet(objUse(errmsg, CORE_COMPONENT)); pErrObj = "module"; CHKiRet(objUse(module, CORE_COMPONENT)); + pErrObj = "var"; + CHKiRet(objUse(var, CORE_COMPONENT)); /* initialize and use classes. We must be very careful with the order of events. Some * classes use others and if we do not initialize them in the right order, we may end -- cgit v1.2.3 From 46fbfee41e88034135725beb4136d44b94388ede Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 3 Apr 2008 13:19:48 +0000 Subject: added the capability to specify a processing (actually dequeue) timeframe with queues - so things can be configured to be done at off-peak hours --- syslogd.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index b5554e5f..e6dae301 100644 --- a/syslogd.c +++ b/syslogd.c @@ -338,8 +338,10 @@ static int iMainMsgQtoEnq = 2000; /* timeout for queue enque */ static int iMainMsgQtoWrkShutdown = 60000; /* timeout for worker thread shutdown */ static int iMainMsgQWrkMinMsgs = 100; /* minimum messages per worker needed to start a new one */ static int iMainMsgQDeqSlowdown = 0; /* dequeue slowdown (simple rate limiting) */ -static int bMainMsgQSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ static int64 iMainMsgQueMaxDiskSpace = 0; /* max disk space allocated 0 ==> unlimited */ +static int bMainMsgQSaveOnShutdown = 1; /* save queue on shutdown (when DA enabled)? */ +static int iMainMsgQueueDeqtWinFromHr = 0; /* hour begin of time frame when queue is to be dequeued */ +static int iMainMsgQueueDeqtWinToHr = 25; /* hour begin of time frame when queue is to be dequeued */ /* support for simple textual representation of FIOP names @@ -2323,6 +2325,8 @@ init(void) setQPROP(queueSetiMinMsgsPerWrkr, "$MainMsgQueueWorkerThreadMinimumMessages", iMainMsgQWrkMinMsgs); setQPROP(queueSetbSaveOnShutdown, "$MainMsgQueueSaveOnShutdown", bMainMsgQSaveOnShutdown); setQPROP(queueSetiDeqSlowdown, "$MainMsgQueueDequeueSlowdown", iMainMsgQDeqSlowdown); + setQPROP(queueSetiDeqtWinFromHr, "$MainMsgQueueDequeueTimeBegin", iMainMsgQueueDeqtWinFromHr); + setQPROP(queueSetiDeqtWinToHr, "$MainMsgQueueDequeueTimeEnd", iMainMsgQueueDeqtWinToHr); # undef setQPROP # undef setQPROPstr @@ -2687,6 +2691,8 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxfilesize", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxFileSize, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuemaxdiskspace", 0, eCmdHdlrSize, NULL, &iMainMsgQueMaxDiskSpace, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuesaveonshutdown", 0, eCmdHdlrBinary, NULL, &bMainMsgQSaveOnShutdown, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinFromHr, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinToHr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); @@ -2766,21 +2772,6 @@ static void mainThread() BEGINfunc uchar *pTmp; -#if 0 // code moved back to main() - /* doing some core initializations */ - if((iRet = modInitIminternal()) != RS_RET_OK) { - fprintf(stderr, "fatal error: could not initialize errbuf object (error code %d).\n", - iRet); - exit(1); /* "good" exit, leaving at init for fatal error */ - } - - if((iRet = loadBuildInModules()) != RS_RET_OK) { - fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", - iRet); - exit(1); /* "good" exit, leaving at init for fatal error */ - } -#endif - /* Note: signals MUST be processed by the thread this code is running in. The reason * is that we need to interrupt the select() system call. -- rgerhards, 2007-10-17 */ -- cgit v1.2.3 From 54751c7e6e374c130d6d6d5cee5db493f7919fef Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 Apr 2008 06:58:48 +0000 Subject: removed the 32 character size limit (from RFC3164) on the tag. This had bad effects on existing envrionments, as sysklogd didn't obey it either (probably another bug in RFC3164...). We now receive the full size, but will modify the outputs so that only 32 characters max are used by default. If you need large tags in the output, you need to provide custom templates. --- syslogd.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index e6dae301..0a786c1f 100644 --- a/syslogd.c +++ b/syslogd.c @@ -424,8 +424,8 @@ static uchar template_SyslogProtocol23Format[] = "\"<%PRI%>1 %TIMESTAMP:::date-r static uchar template_TraditionalFileFormat[] = "\"%TIMESTAMP% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\""; static uchar template_FileFormat[] = "\"%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n\""; static uchar template_WallFmt[] = "\"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r\""; -static uchar template_ForwardFormat[] = "\"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg%\""; -static uchar template_TraditionalForwardFormat[] = "\"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%\""; +static uchar template_ForwardFormat[] = "\"<%PRI%>%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag:1:32%%msg%\""; +static uchar template_TraditionalForwardFormat[] = "\"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag:1:32%%msg%\""; static uchar template_StdUsrMsgFmt[] = "\" %syslogtag%%msg%\n\r\""; static uchar template_StdDBFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-mysql%', '%timegenerated:::date-mysql%', %iut%, '%syslogtag%')\",SQL"; static uchar template_StdPgSQLFmt[] = "\"insert into SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%')\",STDSQL"; @@ -1410,7 +1410,6 @@ static int parseLegacySyslogMsg(msg_t *pMsg, int flags) * machine that we received the message from and the tag will be empty. This * is meant to be an interim solution, but for now it is in the code. */ - if(bParseHOSTNAMEandTAG && !(flags & INTERNAL_MSG)) { /* parse HOSTNAME - but only if this is network-received! * rger, 2005-11-14: we still have a problem with BSD messages. These messages @@ -1468,16 +1467,18 @@ static int parseLegacySyslogMsg(msg_t *pMsg, int flags) MsgSetHOSTNAME(pMsg, getRcvFrom(pMsg)); } - /* now parse TAG - that should be present in message from - * all sources. + /* now parse TAG - that should be present in message from all sources. * This code is somewhat not compliant with RFC 3164. As of 3164, * the TAG field is ended by any non-alphanumeric character. In * practice, however, the TAG often contains dashes and other things, * which would end the TAG. So it is not desirable. As such, we only * accept colon and SP to be terminators. Even there is a slight difference: * a colon is PART of the TAG, while a SP is NOT part of the tag - * (it is CONTENT). Finally, we allow only up to 32 characters for - * TAG, as it is specified in RFC 3164. + * (it is CONTENT). Starting 2008-04-04, we have removed the 32 character + * size limit (from RFC3164) on the tag. This had bad effects on existing + * envrionments, as sysklogd didn't obey it either (probably another bug + * in RFC3164...). We now receive the full size, but will modify the + * outputs so that only 32 characters max are used by default. */ /* The following code in general is quick & dirty - I need to get * it going for a test, rgerhards 2004-11-16 */ @@ -1491,15 +1492,10 @@ static int parseLegacySyslogMsg(msg_t *pMsg, int flags) rsCStrSetAllocIncrement(pStrB, 33); pWork = pBuf; iCnt = 0; - while(*p2parse && *p2parse != ':' && *p2parse != ' ' && iCnt < 32) { + while(*p2parse && *p2parse != ':' && *p2parse != ' ') { rsCStrAppendChar(pStrB, *p2parse++); ++iCnt; } - if (iCnt == 32) { - while(*p2parse && *p2parse != ':' && *p2parse != ' ') { - ++p2parse; - } - } if(*p2parse == ':') { ++p2parse; rsCStrAppendChar(pStrB, ':'); -- cgit v1.2.3 From f5250a3a92ec4c1738556f3cc5139dbc15579add Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 Apr 2008 08:34:31 +0000 Subject: changed command line processing. -v, -M, -c options are now parsed and processed before all other options. Inter-option dependencies have been relieved. Among others, permits to specify intial module load path via -M only (not the environment) which makes it much easier to work with non-standard module library locations. Thanks to varmojfekoj for suggesting this change. Matches bugzilla bug 55. --- syslogd.c | 251 ++++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 186 insertions(+), 65 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index 0a786c1f..bb161528 100644 --- a/syslogd.c +++ b/syslogd.c @@ -302,6 +302,7 @@ static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - n int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing slash) */ +extern uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ /* end global config file state variables */ char LocalHostName[MAXHOSTNAMELEN+1];/* our hostname - read-only after startup */ @@ -2197,8 +2198,7 @@ init(void) pDfltProgNameCmp = NULL; eDfltHostnameCmpMode = HN_NO_COMP; - dbgprintf("rsyslog %s.\n", VERSION); - dbgprintf("Called init.\n"); + dbgprintf("rsyslog %s - called init()\n", VERSION); /* delete the message queue, which also flushes all messages left over */ if(pMsgQueue != NULL) { @@ -2792,7 +2792,6 @@ static void mainThread() pTmp = template_StdPgSQLFmt; tplLastStaticInit(tplAddLine(" StdPgSQLFmt", &pTmp)); - dbgprintf("Starting.\n"); init(); if(Debug) { dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); @@ -2809,6 +2808,7 @@ static void mainThread() * do the init() and then restart things. * rgerhards, 2005-10-24 */ + dbgprintf("initialization completed, transitioning to regular run mode\n"); mainloop(); ENDfunc @@ -2962,6 +2962,72 @@ dbgprintf("post strExit()\n"); } +/* some support for command line option parsing. Any non-trivial options must be + * buffered until the complete command line has been parsed. This is necessary to + * prevent dependencies between the options. That, in turn, means we need to have + * something that is capable of buffering options and there values. The follwing + * functions handle that. + * rgerhards, 2008-04-04 + */ +typedef struct bufOpt { + struct bufOpt *pNext; + char optchar; + char *arg; +} bufOpt_t; +static bufOpt_t *bufOptRoot = NULL; +static bufOpt_t *bufOptLast = NULL; + +/* add option buffer */ +static rsRetVal +bufOptAdd(char opt, char *arg) +{ + DEFiRet; + bufOpt_t *pBuf; + + if((pBuf = malloc(sizeof(bufOpt_t))) == NULL) + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + + pBuf->optchar = opt; + pBuf->arg = arg; + pBuf->pNext = NULL; + + if(bufOptLast == NULL) { + bufOptRoot = pBuf; /* then there is also no root! */ + } else { + bufOptLast->pNext = pBuf; + } + bufOptLast = pBuf; + +finalize_it: + RETiRet; +} + + + +/* remove option buffer from top of list, return values and destruct buffer itself. + * returns RS_RET_END_OF_LINKEDLIST when no more options are present. + * (we use int *opt instead of char *opt to keep consistent with getopt()) + */ +static rsRetVal +bufOptRemove(int *opt, char **arg) +{ + DEFiRet; + bufOpt_t *pBuf; + + if(bufOptRoot == NULL) + ABORT_FINALIZE(RS_RET_END_OF_LINKEDLIST); + pBuf = bufOptRoot; + + *opt = pBuf->optchar; + *arg = pBuf->arg; + + bufOptRoot = pBuf->pNext; + free(pBuf); + +finalize_it: + RETiRet; +} + /* This is the main entry point into rsyslogd. Over time, we should try to * modularize it a bit more... @@ -2981,8 +3047,106 @@ int realMain(int argc, char **argv) int bIsFirstOption = 1; int bEOptionWasGiven = 0; int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ + char *arg; /* for command line option processing */ uchar legacyConfLine[80]; + /* first, parse the command line options. We do not carry out any actual work, just + * see what we should do. This relieves us from certain anomalies and we can process + * the parameters down below in the correct order. For example, we must know the + * value of -M before we can do the init, but at the same time we need to have + * the base classes init before we can process most of the options. Now, with the + * split of functionality, this is no longer a problem. Thanks to varmofekoj for + * suggesting this algo. + * Note: where we just need to set some flags and can do so without knowledge + * of other options, we do this during the inital option processing. With later + * versions (if a dependency on -c option is introduced), we must move that code + * to other places, but I think it is quite appropriate and saves code to do this + * only when actually neeeded. + * rgerhards, 2008-04-04 + */ + while ((ch = getopt(argc, argv, "46Ac:dehi:f:g:l:m:M:nqQr::s:t:u:vwx")) != EOF) { + switch((char)ch) { + case '4': + case '6': + case 'A': + case 'a': + case 'f': /* configuration file */ + case 'h': + case 'i': /* pid file name */ + case 'l': + case 'm': /* mark interval */ + case 'n': /* don't fork */ + case 'o': + case 'p': + case 'q': /* add hostname if DNS resolving has failed */ + case 'Q': /* dont resolve hostnames in ACL to IPs */ + case 's': + case 'u': /* misc user settings */ + case 'w': /* disable disallowed host warnigs */ + case 'x': /* disable dns for remote messages */ + CHKiRet(bufOptAdd(ch, optarg)); + break; + case 'c': /* compatibility mode */ + if(!bIsFirstOption) { + fprintf(stderr, "-c option MUST be specified as the first option - aborting...\n"); + usage(); + exit(1); + } + iCompatibilityMode = atoi(optarg); + break; + case 'd': /* debug - must be handled now, so that debug is active during init! */ + Debug = 1; + break; + case 'e': /* log every message (no repeat message supression) */ + fprintf(stderr, "note: -e option is no longer supported, every message is now logged by default\n"); + bEOptionWasGiven = 1; + break; + case 'g': /* enable tcp gssapi logging */ +#if defined(SYSLOG_INET) && defined(USE_GSSAPI) + CHKiRet(bufOptAdd('g', optarg)); +#else + fprintf(stderr, "rsyslogd: -g not valid - not compiled with gssapi support"); +#endif + break; + case 'M': /* default module load path -- this MUST be carried out immediately! */ + glblModPath = (uchar*) optarg; + break; + case 'r': /* accept remote messages */ +#ifdef SYSLOG_INET + CHKiRet(bufOptAdd(ch, optarg)); +#else + fprintf(stderr, "rsyslogd: -r not valid - not compiled with network support\n"); +#endif + break; + case 't': /* enable tcp logging */ +#ifdef SYSLOG_INET + CHKiRet(bufOptAdd(ch, optarg)); +#else + fprintf(stderr, "rsyslogd: -t not valid - not compiled with network support\n"); +#endif + break; + case 'v': /* MUST be carried out immediately! */ + printVersion(); + exit(0); /* exit for -v option - so this is a "good one" */ + case '?': + default: + usage(); + } + bIsFirstOption = 0; /* we already saw an option character */ + } + + if ((argc -= optind)) + usage(); + + dbgprintf("rsyslogd %s startup, compatibility mode %d, module path '%s'\n", + VERSION, iCompatibilityMode, glblModPath == NULL ? "" : (char*)glblModPath); + + /* we are done with the initial option parsing and processing. Now we init the system. */ + + ppid = getpid(); + + if(chdir ("/") != 0) + fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); CHKiRet_Hdlr(InitGlobalClasses()) { fprintf(stderr, "rsyslogd initializiation failed - global classes could not be initialized.\n" @@ -3005,14 +3169,10 @@ int realMain(int argc, char **argv) exit(1); /* "good" exit, leaving at init for fatal error */ } - ppid = getpid(); - - if(chdir ("/") != 0) - fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); + /* END core initializations - we now come back to carrying out command line options*/ - /* END core initializations */ - - while ((ch = getopt(argc, argv, "46Ac:dehi:f:g:l:m:M:nqQr::s:t:u:vwx")) != EOF) { + while((iRet = bufOptRemove(&ch, &arg)) == RS_RET_OK) { +dbgprintf("deque option %c, optarg '%s'\n", ch, arg); switch((char)ch) { case '4': family = PF_INET; @@ -3029,39 +3189,20 @@ int realMain(int argc, char **argv) legacyOptsEnq((uchar *) "ModLoad imuxsock"); bImUxSockLoaded = 1; } - snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "addunixlistensocket %s", optarg); + snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "addunixlistensocket %s", arg); legacyOptsEnq(legacyConfLine); } else { fprintf(stderr, "error -a is no longer supported, use module imuxsock instead"); } break; - case 'c': /* compatibility mode */ - if(!bIsFirstOption) { - fprintf(stderr, "-c option MUST be specified as the first option - aborting...\n"); - usage(); - exit(1); - } - iCompatibilityMode = atoi(optarg); - break; - case 'd': /* debug */ - Debug = 1; - break; - case 'e': /* log every message (no repeat message supression) */ - fprintf(stderr, "note: -e option is no longer supported, every message is now logged by default\n"); - bEOptionWasGiven = 1; - break; case 'f': /* configuration file */ - ConfFile = (uchar*) optarg; + ConfFile = (uchar*) arg; break; case 'g': /* enable tcp gssapi logging */ -#if defined(SYSLOG_INET) && defined(USE_GSSAPI) if(iCompatibilityMode < 3) { - legacyOptsParseTCP(ch, optarg); + legacyOptsParseTCP(ch, arg); } else fprintf(stderr, "-g option only supported in compatibility modes 0 to 2 - ignored\n"); -#else - fprintf(stderr, "rsyslogd: -g not valid - not compiled with gssapi support"); -#endif break; case 'h': if(iCompatibilityMode < 3) { @@ -3071,25 +3212,22 @@ int realMain(int argc, char **argv) } break; case 'i': /* pid file name */ - PidFile = optarg; + PidFile = arg; break; case 'l': if (LocalHosts) { fprintf (stderr, "rsyslogd: Only one -l argument allowed, the first one is taken.\n"); } else { - LocalHosts = crunch_list(optarg); + LocalHosts = crunch_list(arg); } break; case 'm': /* mark interval */ if(iCompatibilityMode < 3) { - MarkInterval = atoi(optarg) * 60; + MarkInterval = atoi(arg) * 60; } else fprintf(stderr, "-m option only supported in compatibility modes 0 to 2 - ignored\n"); break; - case 'M': /* default module load path */ - module.SetModDir((uchar*)optarg); - break; case 'n': /* don't fork */ NoFork = 1; break; @@ -3110,7 +3248,7 @@ int realMain(int argc, char **argv) legacyOptsEnq((uchar *) "ModLoad imuxsock"); bImUxSockLoaded = 1; } - snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "SystemLogSocketName %s", optarg); + snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "SystemLogSocketName %s", arg); legacyOptsEnq(legacyConfLine); } else { fprintf(stderr, "error -p is no longer supported, use module imuxsock instead"); @@ -3122,42 +3260,30 @@ int realMain(int argc, char **argv) *net.pACLDontResolve = 1; break; case 'r': /* accept remote messages */ -#ifdef SYSLOG_INET if(iCompatibilityMode < 3) { legacyOptsEnq((uchar *) "ModLoad imudp"); - snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "UDPServerRun %s", optarg); + snprintf((char *) legacyConfLine, sizeof(legacyConfLine), "UDPServerRun %s", arg); legacyOptsEnq(legacyConfLine); } else - fprintf(stderr, - "-r option only supported in compatibility modes 0 to 2 - ignored\n"); -#else - fprintf(stderr, "rsyslogd: -r not valid - not compiled with network support\n"); -#endif + fprintf(stderr, "-r option only supported in compatibility modes 0 to 2 - ignored\n"); break; case 's': if (StripDomains) { fprintf (stderr, "rsyslogd: Only one -s argument allowed, the first one is taken.\n"); } else { - StripDomains = crunch_list(optarg); + StripDomains = crunch_list(arg); } break; case 't': /* enable tcp logging */ -#ifdef SYSLOG_INET if(iCompatibilityMode < 3) { - legacyOptsParseTCP(ch, optarg); + legacyOptsParseTCP(ch, arg); } else fprintf(stderr, "-t option only supported in compatibility modes 0 to 2 - ignored\n"); -#else - fprintf(stderr, "rsyslogd: -t not valid - not compiled with network support\n"); -#endif break; case 'u': /* misc user settings */ - if(atoi(optarg) == 1) + if(atoi(arg) == 1) bParseHOSTNAMEandTAG = 0; break; - case 'v': - printVersion(); - exit(0); /* exit for -v option - so this is a "good one" */ case 'w': /* disable disallowed host warnigs */ option_DisallowWarning = 0; break; @@ -3168,15 +3294,12 @@ int realMain(int argc, char **argv) default: usage(); } - bIsFirstOption = 0; /* we already saw an option character */ } - if ((argc -= optind)) - usage(); + if(iRet != RS_RET_END_OF_LINKEDLIST) + FINALIZE; - /* TODO: this should go away at a reasonable stage of v3 development. - * rgerhards, 2007-12-19 - */ + /* process compatibility mode settings */ if(iCompatibilityMode < 3) { errmsg.LogError(NO_ERRCODE, "WARNING: rsyslogd is running in compatibility mode. Automatically " "generated config directives may interfer with your rsyslog.conf settings. " @@ -3202,7 +3325,7 @@ int realMain(int argc, char **argv) checkPermissions(); thrdInit(); - if ( !(Debug || NoFork) ) + if( !(Debug || NoFork) ) { dbgprintf("Checking pidfile.\n"); if (!check_pid(PidFile)) @@ -3241,8 +3364,6 @@ int realMain(int argc, char **argv) else debugging_on = 1; - dbgprintf("Compatibility Mode: %d\n", iCompatibilityMode); - /* tuck my process id away */ dbgprintf("Writing pidfile %s.\n", PidFile); if (!check_pid(PidFile)) -- cgit v1.2.3 From cee20af583a19ee2eb7db4664678a41dd6de11d4 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 Apr 2008 12:31:01 +0000 Subject: bugfix: some messages were emited without hostname --- syslogd.c | 86 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 44 insertions(+), 42 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index bb161528..d2f3e3b6 100644 --- a/syslogd.c +++ b/syslogd.c @@ -302,7 +302,7 @@ static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - n int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing slash) */ -extern uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ +uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ /* end global config file state variables */ char LocalHostName[MAXHOSTNAMELEN+1];/* our hostname - read-only after startup */ @@ -3157,6 +3157,49 @@ int realMain(int argc, char **argv) } /* doing some core initializations */ + + /* get our host and domain names - we need to do this early as we may emit + * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 + */ + gethostname(LocalHostName, sizeof(LocalHostName)); + if((p = strchr(LocalHostName, '.'))) { + *p++ = '\0'; + LocalDomain = p; + } else { + LocalDomain = ""; + + /* It's not clearly defined whether gethostname() + * should return the simple hostname or the fqdn. A + * good piece of software should be aware of both and + * we want to distribute good software. Joey + * + * Good software also always checks its return values... + * If syslogd starts up before DNS is up & /etc/hosts + * doesn't have LocalHostName listed, gethostbyname will + * return NULL. + */ + /* TODO: gethostbyname() is not thread-safe, but replacing it is + * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 + */ + hent = gethostbyname(LocalHostName); + if(hent) { + snprintf(LocalHostName, sizeof(LocalHostName), "%s", hent->h_name); + + if ( (p = strchr(LocalHostName, '.')) ) + { + *p++ = '\0'; + LocalDomain = p; + } + } + } + + /* Convert to lower case to recognize the correct domain laterly + */ + for (p = (char *)LocalDomain; *p ; p++) + if (isupper((int) *p)) + *p = (char)tolower((int)*p); + + /* initialize the objects */ if((iRet = modInitIminternal()) != RS_RET_OK) { fprintf(stderr, "fatal error: could not initialize errbuf object (error code %d).\n", iRet); @@ -3381,47 +3424,6 @@ dbgprintf("deque option %c, optarg '%s'\n", ch, arg); } myPid = getpid(); /* save our pid for further testing (also used for messages) */ - - gethostname(LocalHostName, sizeof(LocalHostName)); - if ( (p = strchr(LocalHostName, '.')) ) { - *p++ = '\0'; - LocalDomain = p; - } - else - { - LocalDomain = ""; - - /* It's not clearly defined whether gethostname() - * should return the simple hostname or the fqdn. A - * good piece of software should be aware of both and - * we want to distribute good software. Joey - * - * Good software also always checks its return values... - * If syslogd starts up before DNS is up & /etc/hosts - * doesn't have LocalHostName listed, gethostbyname will - * return NULL. - */ - /* TODO: gethostbyname() is not thread-safe, but replacing it is - * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 - */ - hent = gethostbyname(LocalHostName); - if(hent) { - snprintf(LocalHostName, sizeof(LocalHostName), "%s", hent->h_name); - - if ( (p = strchr(LocalHostName, '.')) ) - { - *p++ = '\0'; - LocalDomain = p; - } - } - } - - /* Convert to lower case to recognize the correct domain laterly - */ - for (p = (char *)LocalDomain; *p ; p++) - if (isupper((int) *p)) - *p = (char)tolower((int)*p); - memset(&sigAct, 0, sizeof (sigAct)); sigemptyset(&sigAct.sa_mask); -- cgit v1.2.3 From 5ba8b2c77c3971a69bde54f3dd0ede81e641d798 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 Apr 2008 12:35:28 +0000 Subject: cleanup --- syslogd.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index d2f3e3b6..904bdbd3 100644 --- a/syslogd.c +++ b/syslogd.c @@ -3193,11 +3193,9 @@ int realMain(int argc, char **argv) } } - /* Convert to lower case to recognize the correct domain laterly - */ - for (p = (char *)LocalDomain; *p ; p++) - if (isupper((int) *p)) - *p = (char)tolower((int)*p); + /* Convert to lower case to recognize the correct domain laterly */ + for (p = (char *)LocalDomain ; *p ; p++) + *p = (char)tolower((int)*p); /* initialize the objects */ if((iRet = modInitIminternal()) != RS_RET_OK) { @@ -3215,7 +3213,7 @@ int realMain(int argc, char **argv) /* END core initializations - we now come back to carrying out command line options*/ while((iRet = bufOptRemove(&ch, &arg)) == RS_RET_OK) { -dbgprintf("deque option %c, optarg '%s'\n", ch, arg); + dbgprintf("deque option %c, optarg '%s'\n", ch, arg); switch((char)ch) { case '4': family = PF_INET; -- cgit v1.2.3 From f4803196d7e215b26b29dd68e7d309792c104844 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 4 Apr 2008 17:09:15 +0000 Subject: bugfix: segfault in expression-based filter - so far untested --- syslogd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index 904bdbd3..cd8476d4 100644 --- a/syslogd.c +++ b/syslogd.c @@ -1056,10 +1056,11 @@ static rsRetVal shouldProcessThisMessage(selector_t *f, msg_t *pMsg, int *bProce finalize_it: /* destruct in any case, not just on error, but it makes error handling much easier */ - if(pVM != NULL) { - var.Destruct(&pResult); + if(pVM != NULL) vm.Destruct(&pVM); - } + + if(pResult != NULL) + var.Destruct(&pResult); *bProcessMsg = bRet; RETiRet; -- cgit v1.2.3 From 185bc5f8e1bacb43cfd7f0fa555aa61577157602 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 8 Apr 2008 12:54:09 +0200 Subject: implemented $ActionExecOnlyOnceEveryInterval config directive --- syslogd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index 778fd713..b56c2f39 100644 --- a/syslogd.c +++ b/syslogd.c @@ -301,6 +301,7 @@ static uchar cCCEscapeChar = '\\';/* character to be used to start an escape seq static int bEscapeCCOnRcv = 1; /* escape control characters on reception: 0 - no, 1 - yes */ int bReduceRepeatMsgs; /* reduce repeated message - 0 - no, 1 - yes */ int bActExecWhenPrevSusp; /* execute action only when previous one was suspended? */ +int iActExecOnceInterval = 0; /* execute action once every nn seconds */ uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing slash) */ uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ /* end global config file state variables */ @@ -379,6 +380,7 @@ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __a { cCCEscapeChar = '#'; bActExecWhenPrevSusp = 0; + iActExecOnceInterval = 0; bDebugPrintTemplateList = 1; bDebugPrintCfSysLineHandlerList = 1; bDebugPrintModuleList = 1; @@ -2692,6 +2694,7 @@ static rsRetVal loadBuildInModules(void) CHKiRet(regCfSysLineHdlr((uchar *)"mainmsgqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iMainMsgQueueDeqtWinToHr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"repeatedmsgreduction", 0, eCmdHdlrBinary, NULL, &bReduceRepeatMsgs, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlywhenpreviousissuspended", 0, eCmdHdlrBinary, NULL, &bActExecWhenPrevSusp, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyonceeveryinterval", 0, eCmdHdlrInt, NULL, &iActExecOnceInterval, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionresumeinterval", 0, eCmdHdlrInt, setActionResumeInterval, NULL, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"controlcharacterescapeprefix", 0, eCmdHdlrGetChar, NULL, &cCCEscapeChar, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"escapecontrolcharactersonreceive", 0, eCmdHdlrBinary, NULL, &bEscapeCCOnRcv, NULL)); -- cgit v1.2.3 From a61f8543ff89a9eef1bef1686fff1035f5f79249 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 9 Apr 2008 08:11:22 +0200 Subject: our BSD define conflicted with a BSD system define renamed to OS_BSD --- syslogd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index 59fbbc29..8f5aa5ef 100644 --- a/syslogd.c +++ b/syslogd.c @@ -216,7 +216,7 @@ static rsRetVal GlobalClassExit(void); #if defined(SYSLOGD_PIDNAME) # undef _PATH_LOGPID # if defined(FSSTND) -# ifdef BSD +# ifdef OS_BSD # define _PATH_VARRUN "/var/run/" # endif # if defined(__sun) || defined(__hpux) -- cgit v1.2.3 From a7860f4dab1afcf94698bc2f52413e94eed64b52 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 10 Apr 2008 09:31:35 +0200 Subject: removed dependency on MAXHOSTNAMELEN as much as it made sense. GNU/Hurd does not define it (because it has no limit), and we have taken care for cases where it is undefined now. However, some very few places remain where IMHO it currently is not worth fixing the code. If it is not defined, we have used a generous value of 1K, which is above IETF RFC's on hostname length at all. The memory consumption is no issue, as there are only a handful of this buffers allocated *per run* -- that's also the main reason why we consider it not worth to be fixed any further. --- syslogd.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index 59fbbc29..65f93c78 100644 --- a/syslogd.c +++ b/syslogd.c @@ -306,7 +306,7 @@ uchar *pszWorkDir = NULL;/* name of rsyslog's spool directory (without trailing uchar *glblModPath = NULL; /* module load path - only used during initial init, only settable via -M command line option */ /* end global config file state variables */ -char LocalHostName[MAXHOSTNAMELEN+1];/* our hostname - read-only after startup */ +uchar *LocalHostName;/* our hostname - read-only after startup */ char *LocalDomain; /* our local domain name - read-only after startup */ int MarkInterval = 20 * 60; /* interval between marks in seconds - read-only after startup */ int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both), set via cmdline */ @@ -897,8 +897,8 @@ logmsgInternal(int pri, char *msg, int flags) CHKiRet(msgConstruct(&pMsg)); MsgSetUxTradMsg(pMsg, msg); MsgSetRawMsg(pMsg, msg); - MsgSetHOSTNAME(pMsg, LocalHostName); - MsgSetRcvFrom(pMsg, LocalHostName); + MsgSetHOSTNAME(pMsg, (char*)LocalHostName); + MsgSetRcvFrom(pMsg, (char*)LocalHostName); MsgSetTAG(pMsg, "rsyslogd:"); pMsg->iFacility = LOG_FAC(pri); pMsg->iSeverity = LOG_PRI(pri); @@ -1863,6 +1863,8 @@ freeAllDynMemForTermination(void) free(pszMainMsgQFName); if(pModDir != NULL) free(pModDir); + if(LocalHostName != NULL) + free(LocalHostName); } @@ -3164,8 +3166,8 @@ int realMain(int argc, char **argv) /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ - gethostname(LocalHostName, sizeof(LocalHostName)); - if((p = strchr(LocalHostName, '.'))) { + net.getLocalHostname(&LocalHostName); + if((p = strchr((char*)LocalHostName, '.'))) { *p++ = '\0'; LocalDomain = p; } else { @@ -3184,17 +3186,19 @@ int realMain(int argc, char **argv) /* TODO: gethostbyname() is not thread-safe, but replacing it is * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 */ - hent = gethostbyname(LocalHostName); + hent = gethostbyname((char*)LocalHostName); if(hent) { - snprintf(LocalHostName, sizeof(LocalHostName), "%s", hent->h_name); + free(LocalHostName); + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - if ( (p = strchr(LocalHostName, '.')) ) + if((p = strchr((char*)LocalHostName, '.'))) { *p++ = '\0'; LocalDomain = p; } } } +dbgprintf("LocalHostname: '%s'\n", LocalHostName); /* Convert to lower case to recognize the correct domain laterly */ for (p = (char *)LocalDomain ; *p ; p++) -- cgit v1.2.3 From 890f782323849b2ae01cd705312d54a4a0e348fe Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 11 Apr 2008 17:33:13 +0200 Subject: some cleanup --- syslogd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index 65f93c78..aee945f5 100644 --- a/syslogd.c +++ b/syslogd.c @@ -3198,7 +3198,6 @@ int realMain(int argc, char **argv) } } } -dbgprintf("LocalHostname: '%s'\n", LocalHostName); /* Convert to lower case to recognize the correct domain laterly */ for (p = (char *)LocalDomain ; *p ; p++) -- cgit v1.2.3 From 63d4de81ec485425231676d53813ff465249e800 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 11 Apr 2008 20:21:02 +0200 Subject: enhanced legacy syslog parser to handle slightly malformed messages Those with a space in front of the timestamp - at least HP procurve is known to do that and I won't outrule that others also do it. The change looks quite unintrusive and so we added it to the parser. --- syslogd.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'syslogd.c') diff --git a/syslogd.c b/syslogd.c index aee945f5..9bd852bb 100644 --- a/syslogd.c +++ b/syslogd.c @@ -1390,11 +1390,18 @@ static int parseLegacySyslogMsg(msg_t *pMsg, int flags) /* Check to see if msg contains a timestamp. We stary trying with a * high-precision one... */ - if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == TRUE) + if(datetime.ParseTIMESTAMP3339(&(pMsg->tTIMESTAMP), &p2parse) == TRUE) { /* we are done - parse pointer is moved by ParseTIMESTAMP3339 */; - else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), p2parse) == TRUE) + } else if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), p2parse) == TRUE) { p2parse += 16; - else { + } else if(*p2parse == ' ') { /* try to see if it is slighly malformed - HP procurve seems to do that sometimes */ + if(datetime.ParseTIMESTAMP3164(&(pMsg->tTIMESTAMP), p2parse+1) == TRUE) { + /* indeed, we got it! */ + p2parse += 17; + } else { + flags |= ADDDATE; + } + } else { flags |= ADDDATE; } -- cgit v1.2.3