summaryrefslogtreecommitdiffstats
path: root/runtime/datetime.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/datetime.c')
-rw-r--r--runtime/datetime.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/runtime/datetime.c b/runtime/datetime.c
index 20ca6191..40ab4e9c 100644
--- a/runtime/datetime.c
+++ b/runtime/datetime.c
@@ -62,9 +62,14 @@ DEFobjCurrIf(errmsg)
* most portable and removes the need for additional structures
* (but I have to admit it is somewhat "bulky";)).
*
- * Obviously, all caller-provided pointers must not be NULL...
+ * Obviously, *t must not be NULL...
+ *
+ * rgerhards, 2008-10-07: added ttSeconds to provide a way to
+ * obtain the second-resolution UNIX timestamp. This is needed
+ * in some situations to minimize time() calls (namely when doing
+ * output processing). This can be left NULL if not needed.
*/
-static void getCurrTime(struct syslogTime *t)
+static void getCurrTime(struct syslogTime *t, time_t *ttSeconds)
{
struct timeval tp;
struct tm *tm;
@@ -83,6 +88,9 @@ static void getCurrTime(struct syslogTime *t)
# else
gettimeofday(&tp, NULL);
# endif
+ if(ttSeconds != NULL)
+ *ttSeconds = tp.tv_sec;
+
tm = localtime_r((time_t*) &(tp.tv_sec), &tmBuf);
t->year = tm->tm_year + 1900;
@@ -142,13 +150,12 @@ static void getCurrTime(struct syslogTime *t)
* \retval The number parsed.
*/
-static int srSLMGParseInt32(char** ppsz)
+static int srSLMGParseInt32(uchar** ppsz)
{
- int i;
+ register int i;
i = 0;
- while(isdigit((int) **ppsz))
- {
+ while(isdigit((int) **ppsz)) {
i = i * 10 + **ppsz - '0';
++(*ppsz);
}
@@ -164,9 +171,9 @@ static int srSLMGParseInt32(char** ppsz)
* could be obtained (restriction added 2008-09-16 by rgerhards).
*/
static rsRetVal
-ParseTIMESTAMP3339(struct syslogTime *pTime, char** ppszTS)
+ParseTIMESTAMP3339(struct syslogTime *pTime, uchar** ppszTS)
{
- char *pszTS = *ppszTS;
+ uchar *pszTS = *ppszTS;
/* variables to temporarily hold time information while we parse */
int year;
int month;
@@ -226,7 +233,7 @@ ParseTIMESTAMP3339(struct syslogTime *pTime, char** ppszTS)
/* Now let's see if we have secfrac */
if(*pszTS == '.') {
- char *pszStart = ++pszTS;
+ uchar *pszStart = ++pszTS;
secfrac = srSLMGParseInt32(&pszTS);
secfracPrecision = (int) (pszTS - pszStart);
} else {
@@ -299,16 +306,17 @@ finalize_it:
* time() call reduction ;).
*/
static rsRetVal
-ParseTIMESTAMP3164(struct syslogTime *pTime, char** ppszTS)
+ParseTIMESTAMP3164(struct syslogTime *pTime, uchar** ppszTS)
{
/* variables to temporarily hold time information while we parse */
int month;
int day;
+ int year = 0; /* 0 means no year provided */
int hour; /* 24 hour clock */
int minute;
int second;
/* end variables to temporarily hold time information while we parse */
- char *pszTS;
+ uchar *pszTS;
DEFiRet;
assert(ppszTS != NULL);
@@ -464,7 +472,23 @@ ParseTIMESTAMP3164(struct syslogTime *pTime, char** ppszTS)
if(*pszTS++ != ' ')
ABORT_FINALIZE(RS_RET_INVLD_TIME);
+
+ /* time part */
hour = srSLMGParseInt32(&pszTS);
+ if(hour > 1970 && hour < 2100) {
+ /* if so, we assume this actually is a year. This is a format found
+ * e.g. in Cisco devices.
+ * (if you read this 2100+ trying to fix a bug, congratulate me
+ * to how long the code survived - me no longer ;)) -- rgerhards, 2008-11-18
+ */
+ year = hour;
+
+ /* re-query the hour, this time it must be valid */
+ if(*pszTS++ != ' ')
+ ABORT_FINALIZE(RS_RET_INVLD_TIME);
+ hour = srSLMGParseInt32(&pszTS);
+ }
+
if(hour < 0 || hour > 23)
ABORT_FINALIZE(RS_RET_INVLD_TIME);
@@ -494,6 +518,8 @@ ParseTIMESTAMP3164(struct syslogTime *pTime, char** ppszTS)
*ppszTS = pszTS; /* provide updated parse position back to caller */
pTime->timeType = 1;
pTime->month = month;
+ if(year > 0)
+ pTime->year = year; /* persist year if detected */
pTime->day = day;
pTime->hour = hour;
pTime->minute = minute;