summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--Makefile.am2
-rw-r--r--msg.c1041
-rw-r--r--msg.h150
-rw-r--r--syslogd-types.h81
-rw-r--r--syslogd.c1059
-rw-r--r--syslogd.h36
7 files changed, 1269 insertions, 1102 deletions
diff --git a/ChangeLog b/ChangeLog
index 486d735f..cde1323b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,6 +9,8 @@ Version 1.17.1 (RGer), 2007-07-??
- fixed minimal memory leak on HUP (caused by templates)
thanks to varmojfekoj <varmojfekoj@gmail.com> for the patch
- code cleanup (removed compiler warnings)
+- fixed portability bug in configure.ac - thanks to Bartosz Kuźma for patch
+- moved msg object into its own file set
---------------------------------------------------------------------------
Version 1.17.0 (RGer), 2007-07-17
- added $RepeatedLineReduction config parameter
diff --git a/Makefile.am b/Makefile.am
index e85307dd..e4d7ff24 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -7,7 +7,7 @@ rfc3195d_SOURCES=rfc3195d.c rsyslog.h
man_MANS = rfc3195d.8 rklogd.8 rsyslogd.8 rsyslog.conf.5
-rsyslogd_SOURCES=syslogd.c pidfile.c template.c outchannel.c stringbuf.c srUtils.c parse.c syslogd-types.h template.h outchannel.h syslogd.h stringbuf.h parse.h srUtils.h liblogging-stub.h net.h
+rsyslogd_SOURCES=syslogd.c pidfile.c template.c outchannel.c stringbuf.c srUtils.c parse.c syslogd-types.h template.h outchannel.h syslogd.h stringbuf.h parse.h srUtils.h liblogging-stub.h net.h msg.c msg.h
rsyslogd_CPPFLAGS=$(mysql_includes)
rsyslogd_LDADD=$(mysql_libs) $(zlib_libs) $(pthreads_libs)
diff --git a/msg.c b/msg.c
new file mode 100644
index 00000000..6dd4094b
--- /dev/null
+++ b/msg.c
@@ -0,0 +1,1041 @@
+/* msg.c
+ * The msg object. Implementation of all msg-related functions
+ *
+ * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c)
+ * This file is under development and has not yet arrived at being fully
+ * self-contained and a real object. So far, it is mostly an excerpt
+ * of the "old" message code without any modifications. However, it
+ * helps to have things at the right place one we go to the meat of it.
+ *
+ * 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 program 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.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#include "config.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#define SYSLOG_NAMES
+#include <sys/syslog.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+#include "rsyslog.h"
+#include "syslogd.h"
+#include "template.h"
+#include "srUtils.h"
+#include "msg.h"
+
+/* rgerhards 2004-11-09: helper routines for handling the
+ * message object. We do only the most important things. It
+ * is our firm hope that this will sooner or later be
+ * obsoleted by liblogging.
+ */
+
+
+/* "Constructor" for a msg "object". Returns a pointer to
+ * the new object or NULL if no such object could be allocated.
+ * An object constructed via this function should only be destroyed
+ * via "MsgDestruct()".
+ */
+msg_t* MsgConstruct(void)
+{
+ msg_t *pM;
+
+ if((pM = calloc(1, sizeof(msg_t))) != NULL)
+ { /* initialize members that are non-zero */
+ pM->iRefCount = 1;
+ pM->iSyslogVers = -1;
+ pM->iSeverity = -1;
+ pM->iFacility = -1;
+ getCurrTime(&(pM->tRcvdAt));
+ }
+
+ /* DEV debugging only! dprintf("MsgConstruct\t0x%x, ref 1\n", (int)pM);*/
+
+ return(pM);
+}
+
+
+/* Destructor for a msg "object". Must be called to dispose
+ * of a msg object.
+ */
+void MsgDestruct(msg_t * pM)
+{
+ assert(pM != NULL);
+ /* DEV Debugging only ! dprintf("MsgDestruct\t0x%x, Ref now: %d\n", (int)pM, pM->iRefCount - 1); */
+ if(--pM->iRefCount == 0)
+ {
+ /* DEV Debugging Only! dprintf("MsgDestruct\t0x%x, RefCount now 0, doing DESTROY\n", (int)pM); */
+ if(pM->pszUxTradMsg != NULL)
+ free(pM->pszUxTradMsg);
+ if(pM->pszRawMsg != NULL)
+ free(pM->pszRawMsg);
+ if(pM->pszTAG != NULL)
+ free(pM->pszTAG);
+ if(pM->pszHOSTNAME != NULL)
+ free(pM->pszHOSTNAME);
+ if(pM->pszRcvFrom != NULL)
+ free(pM->pszRcvFrom);
+ if(pM->pszMSG != NULL)
+ free(pM->pszMSG);
+ if(pM->pszFacility != NULL)
+ free(pM->pszFacility);
+ if(pM->pszFacilityStr != NULL)
+ free(pM->pszFacilityStr);
+ if(pM->pszSeverity != NULL)
+ free(pM->pszSeverity);
+ if(pM->pszSeverityStr != NULL)
+ free(pM->pszSeverityStr);
+ if(pM->pszRcvdAt3164 != NULL)
+ free(pM->pszRcvdAt3164);
+ if(pM->pszRcvdAt3339 != NULL)
+ free(pM->pszRcvdAt3339);
+ if(pM->pszRcvdAt_MySQL != NULL)
+ free(pM->pszRcvdAt_MySQL);
+ if(pM->pszTIMESTAMP3164 != NULL)
+ free(pM->pszTIMESTAMP3164);
+ if(pM->pszTIMESTAMP3339 != NULL)
+ free(pM->pszTIMESTAMP3339);
+ if(pM->pszTIMESTAMP_MySQL != NULL)
+ free(pM->pszTIMESTAMP_MySQL);
+ if(pM->pszPRI != NULL)
+ free(pM->pszPRI);
+ free(pM);
+ }
+}
+
+
+/* The macros below are used in MsgDup(). I use macros
+ * to keep the fuction code somewhat more readyble. It is my
+ * replacement for inline functions in CPP
+ */
+#define tmpCOPYSZ(name) \
+ if(pOld->psz##name != NULL) { \
+ if((pNew->psz##name = srUtilStrDup(pOld->psz##name, pOld->iLen##name)) == NULL) {\
+ MsgDestruct(pNew);\
+ return NULL;\
+ }\
+ pNew->iLen##name = pOld->iLen##name;\
+ }
+
+/* copy the CStr objects.
+ * if the old value is NULL, we do not need to do anything because we
+ * initialized the new value to NULL via calloc().
+ */
+#define tmpCOPYCSTR(name) \
+ if(pOld->pCS##name != NULL) {\
+ if(rsCStrConstructFromCStr(&(pNew->pCS##name), pOld->pCS##name) != RS_RET_OK) {\
+ MsgDestruct(pNew);\
+ return NULL;\
+ }\
+ }
+/* Constructs a message object by duplicating another one.
+ * Returns NULL if duplication failed.
+ * rgerhards, 2007-07-10
+ */
+msg_t* MsgDup(msg_t* pOld)
+{
+ msg_t* pNew;
+
+ assert(pOld != NULL);
+
+ if((pNew = (msg_t*) calloc(1, sizeof(msg_t))) == NULL) {
+ glblHadMemShortage = 1;
+ return NULL;
+ }
+
+ /* now copy the message properties */
+ pNew->iRefCount = 1;
+ pNew->iSyslogVers = pOld->iSyslogVers;
+ pNew->bParseHOSTNAME = pOld->bParseHOSTNAME;
+ pNew->iSeverity = pOld->iSeverity;
+ pNew->iFacility = pOld->iFacility;
+ pNew->bParseHOSTNAME = pOld->bParseHOSTNAME;
+ pNew->msgFlags = pOld->msgFlags;
+ pNew->iProtocolVersion = pOld->iProtocolVersion;
+ memcpy(&pNew->tRcvdAt, &pOld->tRcvdAt, sizeof(struct syslogTime));
+ memcpy(&pNew->tTIMESTAMP, &pOld->tTIMESTAMP, sizeof(struct syslogTime));
+ tmpCOPYSZ(Severity);
+ tmpCOPYSZ(SeverityStr);
+ tmpCOPYSZ(Facility);
+ tmpCOPYSZ(FacilityStr);
+ tmpCOPYSZ(PRI);
+ tmpCOPYSZ(RawMsg);
+ tmpCOPYSZ(MSG);
+ tmpCOPYSZ(UxTradMsg);
+ tmpCOPYSZ(TAG);
+ tmpCOPYSZ(HOSTNAME);
+ tmpCOPYSZ(RcvFrom);
+
+ tmpCOPYCSTR(ProgName);
+ tmpCOPYCSTR(StrucData);
+ tmpCOPYCSTR(APPNAME);
+ tmpCOPYCSTR(PROCID);
+ tmpCOPYCSTR(MSGID);
+
+ /* we do not copy all other cache properties, as we do not even know
+ * if they are needed once again. So we let them re-create if needed.
+ */
+
+ return pNew;
+}
+#undef tmpCOPYSZ
+#undef tmpCOPYCSTR
+
+
+/* Increment reference count - see description of the "msg"
+ * structure for details. As a convenience to developers,
+ * this method returns the msg pointer that is passed to it.
+ * It is recommended that it is called as follows:
+ *
+ * pSecondMsgPointer = MsgAddRef(pOrgMsgPointer);
+ */
+msg_t *MsgAddRef(msg_t *pM)
+{
+ assert(pM != NULL);
+ pM->iRefCount++;
+ /* DEV debugging only! dprintf("MsgAddRef\t0x%x done, Ref now: %d\n", (int)pM, pM->iRefCount);*/
+ return(pM);
+}
+
+
+/* This functions tries to aquire the PROCID from TAG. Its primary use is
+ * when a legacy syslog message has been received and should be forwarded as
+ * syslog-protocol (or the PROCID is requested for any other reason).
+ * In legacy syslog, the PROCID is considered to be the character sequence
+ * between the first [ and the first ]. This usually are digits only, but we
+ * do not check that. However, if there is no closing ], we do not assume we
+ * can obtain a PROCID. Take in mind that not every legacy syslog message
+ * actually has a PROCID.
+ * rgerhards, 2005-11-24
+ */
+static rsRetVal aquirePROCIDFromTAG(msg_t *pM)
+{
+ register int i;
+ int iRet;
+
+ assert(pM != NULL);
+ if(pM->pCSPROCID != NULL)
+ return RS_RET_OK; /* we are already done ;) */
+
+ if(getProtocolVersion(pM) != 0)
+ return RS_RET_OK; /* we can only emulate if we have legacy format */
+
+ /* find first '['... */
+ i = 0;
+ while((i < pM->iLenTAG) && (pM->pszTAG[i] != '['))
+ ++i;
+ if(!(i < pM->iLenTAG))
+ return RS_RET_OK; /* no [, so can not emulate... */
+
+ ++i; /* skip '[' */
+
+ /* now obtain the PROCID string... */
+ if((pM->pCSPROCID = rsCStrConstruct()) == NULL)
+ return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
+ rsCStrSetAllocIncrement(pM->pCSPROCID, 16);
+ while((i < pM->iLenTAG) && (pM->pszTAG[i] != ']')) {
+ if((iRet = rsCStrAppendChar(pM->pCSPROCID, pM->pszTAG[i])) != RS_RET_OK)
+ return iRet;
+ ++i;
+ }
+
+ if(!(i < pM->iLenTAG)) {
+ /* oops... it looked like we had a PROCID, but now it has
+ * turned out this is not true. In this case, we need to free
+ * the buffer and simply return. Note that this is NOT an error
+ * case!
+ */
+ rsCStrDestruct(pM->pCSPROCID);
+ pM->pCSPROCID = NULL;
+ return RS_RET_OK;
+ }
+
+ /* OK, finaally we could obtain a PROCID. So let's use it ;) */
+ if((iRet = rsCStrFinish(pM->pCSPROCID)) != RS_RET_OK)
+ return iRet;
+
+ return RS_RET_OK;
+}
+
+
+/* Parse and set the "programname" for a given MSG object. Programname
+ * is a BSD concept, it is the tag without any instance-specific information.
+ * Precisely, the programname is terminated by either (whichever occurs first):
+ * - end of tag
+ * - nonprintable character
+ * - ':'
+ * - '['
+ * - '/'
+ * The above definition has been taken from the FreeBSD syslogd sources.
+ *
+ * The program name is not parsed by default, because it is infrequently-used.
+ * If it is needed, this function should be called first. It checks if it is
+ * already set and extracts it, if not.
+ * A message object must be provided, else a crash will occur.
+ * rgerhards, 2005-10-19
+ */
+static rsRetVal aquireProgramName(msg_t *pM)
+{
+ register int i;
+ int iRet;
+
+ assert(pM != NULL);
+ if(pM->pCSProgName == NULL) {
+ /* ok, we do not yet have it. So let's parse the TAG
+ * to obtain it.
+ */
+ if((pM->pCSProgName = rsCStrConstruct()) == NULL)
+ return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
+ rsCStrSetAllocIncrement(pM->pCSProgName, 33);
+ for( i = 0
+ ; (i < pM->iLenTAG) && isprint((int) pM->pszTAG[i])
+ && (pM->pszTAG[i] != '\0') && (pM->pszTAG[i] != ':')
+ && (pM->pszTAG[i] != '[') && (pM->pszTAG[i] != '/')
+ ; ++i) {
+ if((iRet = rsCStrAppendChar(pM->pCSProgName, pM->pszTAG[i])) != RS_RET_OK)
+ return iRet;
+ }
+ if((iRet = rsCStrFinish(pM->pCSProgName)) != RS_RET_OK)
+ return iRet;
+ }
+ return RS_RET_OK;
+}
+
+
+/* This function moves the HOSTNAME inside the message object to the
+ * TAG. It is a specialised function used to handle the condition when
+ * a message without HOSTNAME is being processed. The missing HOSTNAME
+ * is only detected at a later stage, during TAG processing, so that
+ * we already had set the HOSTNAME property and now need to move it to
+ * the TAG. Of course, we could do this via a couple of get/set methods,
+ * but it is far more efficient to do it via this specialised method.
+ * This is especially important as this can be a very common case, e.g.
+ * when BSD syslog is acting as a sender.
+ * rgerhards, 2005-11-10.
+ */
+void moveHOSTNAMEtoTAG(msg_t *pM)
+{
+ assert(pM != NULL);
+ if(pM->pszTAG != NULL)
+ free(pM->pszTAG);
+ pM->pszTAG = pM->pszHOSTNAME;
+ pM->iLenTAG = pM->iLenHOSTNAME;
+ pM->pszHOSTNAME = NULL;
+ pM->iLenHOSTNAME = 0;
+}
+
+/* Access methods - dumb & easy, not a comment for each ;)
+ */
+void setProtocolVersion(msg_t *pM, int iNewVersion)
+{
+ assert(pM != NULL);
+ if(iNewVersion != 0 && iNewVersion != 1) {
+ dprintf("Tried to set unsupported protocol version %d - changed to 0.\n", iNewVersion);
+ iNewVersion = 0;
+ }
+ pM->iProtocolVersion = iNewVersion;
+}
+
+int getProtocolVersion(msg_t *pM)
+{
+ assert(pM != NULL);
+ return(pM->iProtocolVersion);
+}
+
+/* note: string is taken from constant pool, do NOT free */
+char *getProtocolVersionString(msg_t *pM)
+{
+ assert(pM != NULL);
+ return(pM->iProtocolVersion ? "1" : "0");
+}
+
+int getMSGLen(msg_t *pM)
+{
+ return((pM == NULL) ? 0 : pM->iLenMSG);
+}
+
+
+char *getRawMsg(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+ else
+ if(pM->pszRawMsg == NULL)
+ return "";
+ else
+ return (char*)pM->pszRawMsg;
+}
+
+char *getUxTradMsg(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+ else
+ if(pM->pszUxTradMsg == NULL)
+ return "";
+ else
+ return (char*)pM->pszUxTradMsg;
+}
+
+char *getMSG(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+ else
+ if(pM->pszMSG == NULL)
+ return "";
+ else
+ return (char*)pM->pszMSG;
+}
+
+
+/* Get PRI value in text form */
+char *getPRI(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+
+ if(pM->pszPRI == NULL) {
+ /* OK, we need to construct it...
+ * we use a 5 byte buffer - as of
+ * RFC 3164, it can't be longer. Should it
+ * still be, snprintf will truncate...
+ */
+ if((pM->pszPRI = malloc(5)) == NULL) return "";
+ pM->iLenPRI = snprintf((char*)pM->pszPRI, 5, "%d",
+ LOG_MAKEPRI(pM->iFacility, pM->iSeverity));
+ }
+
+ return (char*)pM->pszPRI;
+}
+
+
+/* Get PRI value as integer */
+int getPRIi(msg_t *pM)
+{
+ assert(pM != NULL);
+ return (pM->iFacility << 3) + (pM->iSeverity);
+}
+
+
+char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
+{
+ if(pM == NULL)
+ return "";
+
+ switch(eFmt) {
+ case tplFmtDefault:
+ if(pM->pszTIMESTAMP3164 == NULL) {
+ if((pM->pszTIMESTAMP3164 = malloc(16)) == NULL) return "";
+ formatTimestamp3164(&pM->tTIMESTAMP, pM->pszTIMESTAMP3164, 16);
+ }
+ return(pM->pszTIMESTAMP3164);
+ case tplFmtMySQLDate:
+ if(pM->pszTIMESTAMP_MySQL == NULL) {
+ if((pM->pszTIMESTAMP_MySQL = malloc(15)) == NULL) return "";
+ formatTimestampToMySQL(&pM->tTIMESTAMP, pM->pszTIMESTAMP_MySQL, 15);
+ }
+ return(pM->pszTIMESTAMP_MySQL);
+ case tplFmtRFC3164Date:
+ if(pM->pszTIMESTAMP3164 == NULL) {
+ if((pM->pszTIMESTAMP3164 = malloc(16)) == NULL) return "";
+ formatTimestamp3164(&pM->tTIMESTAMP, pM->pszTIMESTAMP3164, 16);
+ }
+ return(pM->pszTIMESTAMP3164);
+ case tplFmtRFC3339Date:
+ if(pM->pszTIMESTAMP3339 == NULL) {
+ if((pM->pszTIMESTAMP3339 = malloc(33)) == NULL) return "";
+ formatTimestamp3339(&pM->tTIMESTAMP, pM->pszTIMESTAMP3339, 33);
+ }
+ return(pM->pszTIMESTAMP3339);
+ }
+ return "INVALID eFmt OPTION!";
+}
+
+char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt)
+{
+ if(pM == NULL)
+ return "";
+
+ switch(eFmt) {
+ case tplFmtDefault:
+ if(pM->pszRcvdAt3164 == NULL) {
+ if((pM->pszRcvdAt3164 = malloc(16)) == NULL) return "";
+ formatTimestamp3164(&pM->tRcvdAt, pM->pszRcvdAt3164, 16);
+ }
+ return(pM->pszRcvdAt3164);
+ case tplFmtMySQLDate:
+ if(pM->pszRcvdAt_MySQL == NULL) {
+ if((pM->pszRcvdAt_MySQL = malloc(15)) == NULL) return "";
+ formatTimestampToMySQL(&pM->tRcvdAt, pM->pszRcvdAt_MySQL, 15);
+ }
+ return(pM->pszRcvdAt_MySQL);
+ case tplFmtRFC3164Date:
+ if((pM->pszRcvdAt3164 = malloc(16)) == NULL) return "";
+ formatTimestamp3164(&pM->tRcvdAt, pM->pszRcvdAt3164, 16);
+ return(pM->pszRcvdAt3164);
+ case tplFmtRFC3339Date:
+ if(pM->pszRcvdAt3339 == NULL) {
+ if((pM->pszRcvdAt3339 = malloc(33)) == NULL) return "";
+ formatTimestamp3339(&pM->tRcvdAt, pM->pszRcvdAt3339, 33);
+ }
+ return(pM->pszRcvdAt3339);
+ }
+ return "INVALID eFmt OPTION!";
+}
+
+
+char *getSeverity(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+
+ if(pM->pszSeverity == NULL) {
+ /* we use a 2 byte buffer - can only be one digit */
+ if((pM->pszSeverity = malloc(2)) == NULL) return "";
+ pM->iLenSeverity =
+ snprintf((char*)pM->pszSeverity, 2, "%d", pM->iSeverity);
+ }
+ return((char*)pM->pszSeverity);
+}
+
+
+char *getSeverityStr(msg_t *pM)
+{
+ syslogCODE *c;
+ int val;
+ char *name = NULL;
+
+ if(pM == NULL)
+ return "";
+
+ if(pM->pszSeverityStr == NULL) {
+ for(c = rs_prioritynames, val = pM->iSeverity; c->c_name; c++)
+ if(c->c_val == val) {
+ name = c->c_name;
+ break;
+ }
+ if(name == NULL) {
+ /* we use a 2 byte buffer - can only be one digit */
+ if((pM->pszSeverityStr = malloc(2)) == NULL) return "";
+ pM->iLenSeverityStr =
+ snprintf((char*)pM->pszSeverityStr, 2, "%d", pM->iSeverity);
+ } else {
+ if((pM->pszSeverityStr = (uchar*) strdup(name)) == NULL) return "";
+ pM->iLenSeverityStr = strlen((char*)name);
+ }
+ }
+ return((char*)pM->pszSeverityStr);
+}
+
+char *getFacility(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+
+ if(pM->pszFacility == NULL) {
+ /* we use a 12 byte buffer - as of
+ * syslog-protocol, facility can go
+ * up to 2^32 -1
+ */
+ if((pM->pszFacility = malloc(12)) == NULL) return "";
+ pM->iLenFacility =
+ snprintf((char*)pM->pszFacility, 12, "%d", pM->iFacility);
+ }
+ return((char*)pM->pszFacility);
+}
+
+char *getFacilityStr(msg_t *pM)
+{
+ syslogCODE *c;
+ int val;
+ char *name = NULL;
+
+ if(pM == NULL)
+ return "";
+
+ if(pM->pszFacilityStr == NULL) {
+ for(c = rs_facilitynames, val = pM->iFacility << 3; c->c_name; c++)
+ if(c->c_val == val) {
+ name = c->c_name;
+ break;
+ }
+ if(name == NULL) {
+ /* we use a 12 byte buffer - as of
+ * syslog-protocol, facility can go
+ * up to 2^32 -1
+ */
+ if((pM->pszFacilityStr = malloc(12)) == NULL) return "";
+ pM->iLenFacilityStr =
+ snprintf((char*)pM->pszFacilityStr, 12, "%d", val >> 3);
+ } else {
+ if((pM->pszFacilityStr = (uchar*)strdup(name)) == NULL) return "";
+ pM->iLenFacilityStr = strlen((char*)name);
+ }
+ }
+ return((char*)pM->pszFacilityStr);
+}
+
+
+/* rgerhards 2004-11-24: set APP-NAME in msg object
+ */
+rsRetVal MsgSetAPPNAME(msg_t *pMsg, char* pszAPPNAME)
+{
+ assert(pMsg != NULL);
+ if(pMsg->pCSAPPNAME == NULL) {
+ /* we need to obtain the object first */
+ if((pMsg->pCSAPPNAME = rsCStrConstruct()) == NULL)
+ return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
+ rsCStrSetAllocIncrement(pMsg->pCSAPPNAME, 128);
+ }
+ /* if we reach this point, we have the object */
+ return rsCStrSetSzStr(pMsg->pCSAPPNAME, (uchar*) pszAPPNAME);
+}
+
+
+/* This function tries to emulate APPNAME if it is not present. Its
+ * main use is when we have received a log record via legacy syslog and
+ * now would like to send out the same one via syslog-protocol.
+ */
+static void tryEmulateAPPNAME(msg_t *pM)
+{
+ assert(pM != NULL);
+ if(pM->pCSAPPNAME != NULL)
+ return; /* we are already done */
+
+ if(getProtocolVersion(pM) == 0) {
+ /* only then it makes sense to emulate */
+ MsgSetAPPNAME(pM, getProgramName(pM));
+ }
+}
+
+
+/* rgerhards, 2005-11-24
+ */
+int getAPPNAMELen(msg_t *pM)
+{
+ assert(pM != NULL);
+ if(pM->pCSAPPNAME == NULL)
+ tryEmulateAPPNAME(pM);
+ return (pM->pCSAPPNAME == NULL) ? 0 : rsCStrLen(pM->pCSAPPNAME);
+}
+
+
+/* rgerhards, 2005-11-24
+ */
+char *getAPPNAME(msg_t *pM)
+{
+ assert(pM != NULL);
+ if(pM->pCSAPPNAME == NULL)
+ tryEmulateAPPNAME(pM);
+ return (pM->pCSAPPNAME == NULL) ? "" : (char*) rsCStrGetSzStrNoNULL(pM->pCSAPPNAME);
+}
+
+
+
+
+/* rgerhards 2004-11-24: set PROCID in msg object
+ */
+rsRetVal MsgSetPROCID(msg_t *pMsg, char* pszPROCID)
+{
+ assert(pMsg != NULL);
+ if(pMsg->pCSPROCID == NULL) {
+ /* we need to obtain the object first */
+ if((pMsg->pCSPROCID = rsCStrConstruct()) == NULL)
+ return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
+ rsCStrSetAllocIncrement(pMsg->pCSPROCID, 128);
+ }
+ /* if we reach this point, we have the object */
+ return rsCStrSetSzStr(pMsg->pCSPROCID, (uchar*) pszPROCID);
+}
+
+/* rgerhards, 2005-11-24
+ */
+int getPROCIDLen(msg_t *pM)
+{
+ assert(pM != NULL);
+ if(pM->pCSPROCID == NULL)
+ aquirePROCIDFromTAG(pM);
+ return (pM->pCSPROCID == NULL) ? 1 : rsCStrLen(pM->pCSPROCID);
+}
+
+
+/* rgerhards, 2005-11-24
+ */
+char *getPROCID(msg_t *pM)
+{
+ assert(pM != NULL);
+ if(pM->pCSPROCID == NULL)
+ aquirePROCIDFromTAG(pM);
+ return (pM->pCSPROCID == NULL) ? "-" : (char*) rsCStrGetSzStrNoNULL(pM->pCSPROCID);
+}
+
+
+/* rgerhards 2004-11-24: set MSGID in msg object
+ */
+rsRetVal MsgSetMSGID(msg_t *pMsg, char* pszMSGID)
+{
+ assert(pMsg != NULL);
+ if(pMsg->pCSMSGID == NULL) {
+ /* we need to obtain the object first */
+ if((pMsg->pCSMSGID = rsCStrConstruct()) == NULL)
+ return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
+ rsCStrSetAllocIncrement(pMsg->pCSMSGID, 128);
+ }
+ /* if we reach this point, we have the object */
+ return rsCStrSetSzStr(pMsg->pCSMSGID, (uchar*) pszMSGID);
+}
+
+/* rgerhards, 2005-11-24
+ */
+#if 0 /* This method is currently not called, be we like to preserve it */
+static int getMSGIDLen(msg_t *pM)
+{
+ return (pM->pCSMSGID == NULL) ? 1 : rsCStrLen(pM->pCSMSGID);
+}
+#endif
+
+
+/* rgerhards, 2005-11-24
+ */
+char *getMSGID(msg_t *pM)
+{
+ return (pM->pCSMSGID == NULL) ? "-" : (char*) rsCStrGetSzStrNoNULL(pM->pCSMSGID);
+}
+
+
+/* Set the TAG to a caller-provided string. This is thought
+ * to be a heap buffer that the caller will no longer use. This
+ * function is a performance optimization over MsgSetTAG().
+ * rgerhards 2004-11-19
+ */
+void MsgAssignTAG(msg_t *pMsg, char *pBuf)
+{
+ assert(pMsg != NULL);
+ pMsg->iLenTAG = (pBuf == NULL) ? 0 : strlen(pBuf);
+ pMsg->pszTAG = (uchar*) pBuf;
+}
+
+
+/* rgerhards 2004-11-16: set TAG in msg object
+ */
+void MsgSetTAG(msg_t *pMsg, char* pszTAG)
+{
+ assert(pMsg != NULL);
+ if(pMsg->pszTAG != NULL)
+ free(pMsg->pszTAG);
+ pMsg->iLenTAG = strlen(pszTAG);
+ if((pMsg->pszTAG = malloc(pMsg->iLenTAG + 1)) != NULL)
+ memcpy(pMsg->pszTAG, pszTAG, pMsg->iLenTAG + 1);
+ else
+ dprintf("Could not allocate memory in MsgSetTAG()\n");
+}
+
+
+/* This function tries to emulate the TAG if none is
+ * set. Its primary purpose is to provide an old-style TAG
+ * when a syslog-protocol message has been received. Then,
+ * the tag is APP-NAME "[" PROCID "]". The function first checks
+ * if there is a TAG and, if not, if it can emulate it.
+ * rgerhards, 2005-11-24
+ */
+static void tryEmulateTAG(msg_t *pM)
+{
+ int iTAGLen;
+ char *pBuf;
+ assert(pM != NULL);
+
+ if(pM->pszTAG != NULL)
+ return; /* done, no need to emulate */
+
+ if(getProtocolVersion(pM) == 1) {
+ if(!strcmp(getPROCID(pM), "-")) {
+ /* no process ID, use APP-NAME only */
+ MsgSetTAG(pM, getAPPNAME(pM));
+ } else {
+ /* now we can try to emulate */
+ iTAGLen = getAPPNAMELen(pM) + getPROCIDLen(pM) + 3;
+ if((pBuf = malloc(iTAGLen * sizeof(char))) == NULL)
+ return; /* nothing we can do */
+ snprintf(pBuf, iTAGLen, "%s[%s]", getAPPNAME(pM), getPROCID(pM));
+ MsgAssignTAG(pM, pBuf);
+ }
+ }
+}
+
+
+#if 0 /* This method is currently not called, be we like to preserve it */
+static int getTAGLen(msg_t *pM)
+{
+ if(pM == NULL)
+ return 0;
+ else {
+ tryEmulateTAG(pM);
+ if(pM->pszTAG == NULL)
+ return 0;
+ else
+ return pM->iLenTAG;
+ }
+}
+#endif
+
+
+char *getTAG(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+ else {
+ tryEmulateTAG(pM);
+ if(pM->pszTAG == NULL)
+ return "";
+ else
+ return (char*) pM->pszTAG;
+ }
+}
+
+
+int getHOSTNAMELen(msg_t *pM)
+{
+ if(pM == NULL)
+ return 0;
+ else
+ if(pM->pszHOSTNAME == NULL)
+ return 0;
+ else
+ return pM->iLenHOSTNAME;
+}
+
+
+char *getHOSTNAME(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+ else
+ if(pM->pszHOSTNAME == NULL)
+ return "";
+ else
+ return (char*) pM->pszHOSTNAME;
+}
+
+
+char *getRcvFrom(msg_t *pM)
+{
+ if(pM == NULL)
+ return "";
+ else
+ if(pM->pszRcvFrom == NULL)
+ return "";
+ else
+ return (char*) pM->pszRcvFrom;
+}
+/* rgerhards 2004-11-24: set STRUCTURED DATA in msg object
+ */
+rsRetVal MsgSetStructuredData(msg_t *pMsg, char* pszStrucData)
+{
+ assert(pMsg != NULL);
+ if(pMsg->pCSStrucData == NULL) {
+ /* we need to obtain the object first */
+ if((pMsg->pCSStrucData = rsCStrConstruct()) == NULL)
+ return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
+ rsCStrSetAllocIncrement(pMsg->pCSStrucData, 128);
+ }
+ /* if we reach this point, we have the object */
+ return rsCStrSetSzStr(pMsg->pCSStrucData, (uchar*) pszStrucData);
+}
+
+/* get the length of the "STRUCTURED-DATA" sz string
+ * rgerhards, 2005-11-24
+ */
+#if 0 /* This method is currently not called, be we like to preserve it */
+static int getStructuredDataLen(msg_t *pM)
+{
+ return (pM->pCSStrucData == NULL) ? 1 : rsCStrLen(pM->pCSStrucData);
+}
+#endif
+
+
+/* get the "STRUCTURED-DATA" as sz string
+ * rgerhards, 2005-11-24
+ */
+char *getStructuredData(msg_t *pM)
+{
+ return (pM->pCSStrucData == NULL) ? "-" : (char*) rsCStrGetSzStrNoNULL(pM->pCSStrucData);
+}
+
+
+
+/* get the length of the "programname" sz string
+ * rgerhards, 2005-10-19
+ */
+int getProgramNameLen(msg_t *pM)
+{
+ int iRet;
+
+ assert(pM != NULL);
+ if((iRet = aquireProgramName(pM)) != RS_RET_OK) {
+ dprintf("error %d returned by aquireProgramName() in getProgramNameLen()\n", iRet);
+ return 0; /* best we can do (consistent wiht what getProgramName() returns) */
+ }
+
+ return (pM->pCSProgName == NULL) ? 0 : rsCStrLen(pM->pCSProgName);
+}
+
+
+/* get the "programname" as sz string
+ * rgerhards, 2005-10-19
+ */
+char *getProgramName(msg_t *pM)
+{
+ int iRet;
+
+ assert(pM != NULL);
+ if((iRet = aquireProgramName(pM)) != RS_RET_OK) {
+ dprintf("error %d returned by aquireProgramName() in getProgramName()\n", iRet);
+ return ""; /* best we can do */
+ }
+
+ return (pM->pCSProgName == NULL) ? "" : (char*) rsCStrGetSzStrNoNULL(pM->pCSProgName);
+}
+
+
+/* rgerhards 2004-11-16: set pszRcvFrom in msg object
+ */
+void MsgSetRcvFrom(msg_t *pMsg, char* pszRcvFrom)
+{
+ assert(pMsg != NULL);
+ if(pMsg->pszRcvFrom != NULL)
+ free(pMsg->pszRcvFrom);
+
+ pMsg->iLenRcvFrom = strlen(pszRcvFrom);
+ if((pMsg->pszRcvFrom = malloc(pMsg->iLenRcvFrom + 1)) != NULL) {
+ memcpy(pMsg->pszRcvFrom, pszRcvFrom, pMsg->iLenRcvFrom + 1);
+ }
+}
+
+
+/* Set the HOSTNAME to a caller-provided string. This is thought
+ * to be a heap buffer that the caller will no longer use. This
+ * function is a performance optimization over MsgSetHOSTNAME().
+ * rgerhards 2004-11-19
+ */
+void MsgAssignHOSTNAME(msg_t *pMsg, char *pBuf)
+{
+ assert(pMsg != NULL);
+ assert(pBuf != NULL);
+ pMsg->iLenHOSTNAME = strlen(pBuf);
+ pMsg->pszHOSTNAME = (uchar*) pBuf;
+}
+
+
+/* rgerhards 2004-11-09: set HOSTNAME in msg object
+ * rgerhards, 2007-06-21:
+ * Does not return anything. If an error occurs, the hostname is
+ * simply not set. I have changed this behaviour. The only problem
+ * we can run into is memory shortage. If we have such, it is better
+ * to loose the hostname than the full message. So we silently ignore
+ * that problem and hope that memory will be available the next time
+ * we need it. The rest of the code already knows how to handle an
+ * unset HOSTNAME.
+ */
+void MsgSetHOSTNAME(msg_t *pMsg, char* pszHOSTNAME)
+{
+ assert(pMsg != NULL);
+ if(pMsg->pszHOSTNAME != NULL)
+ free(pMsg->pszHOSTNAME);
+
+ pMsg->iLenHOSTNAME = strlen(pszHOSTNAME);
+ if((pMsg->pszHOSTNAME = malloc(pMsg->iLenHOSTNAME + 1)) != NULL)
+ memcpy(pMsg->pszHOSTNAME, pszHOSTNAME, pMsg->iLenHOSTNAME + 1);
+ else
+ dprintf("Could not allocate memory in MsgSetHOSTNAME()\n");
+}
+
+
+/* Set the UxTradMsg to a caller-provided string. This is thought
+ * to be a heap buffer that the caller will no longer use. This
+ * function is a performance optimization over MsgSetUxTradMsg().
+ * rgerhards 2004-11-19
+ */
+#if 0 /* This method is currently not called, be we like to preserve it */
+static void MsgAssignUxTradMsg(msg_t *pMsg, char *pBuf)
+{
+ assert(pMsg != NULL);
+ assert(pBuf != NULL);
+ pMsg->iLenUxTradMsg = strlen(pBuf);
+ pMsg->pszUxTradMsg = pBuf;
+}
+#endif
+
+
+/* rgerhards 2004-11-17: set the traditional Unix message in msg object
+ */
+int MsgSetUxTradMsg(msg_t *pMsg, char* pszUxTradMsg)
+{
+ assert(pMsg != NULL);
+ assert(pszUxTradMsg != NULL);
+ pMsg->iLenUxTradMsg = strlen(pszUxTradMsg);
+ if(pMsg->pszUxTradMsg != NULL)
+ free(pMsg->pszUxTradMsg);
+ if((pMsg->pszUxTradMsg = malloc(pMsg->iLenUxTradMsg + 1)) != NULL)
+ memcpy(pMsg->pszUxTradMsg, pszUxTradMsg, pMsg->iLenUxTradMsg + 1);
+ else
+ dprintf("Could not allocate memory for pszUxTradMsg buffer.");
+
+ return(0);
+}
+
+
+/* rgerhards 2004-11-09: set MSG in msg object
+ */
+void MsgSetMSG(msg_t *pMsg, char* pszMSG)
+{
+ assert(pMsg != NULL);
+ assert(pszMSG != NULL);
+
+ if(pMsg->pszMSG != NULL)
+ free(pMsg->pszMSG);
+
+ pMsg->iLenMSG = strlen(pszMSG);
+ if((pMsg->pszMSG = malloc(pMsg->iLenMSG + 1)) != NULL)
+ memcpy(pMsg->pszMSG, pszMSG, pMsg->iLenMSG + 1);
+ else
+ dprintf("MsgSetMSG could not allocate memory for pszMSG buffer.");
+}
+
+/* rgerhards 2004-11-11: set RawMsg in msg object
+ */
+void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg)
+{
+ assert(pMsg != NULL);
+ if(pMsg->pszRawMsg != NULL)
+ free(pMsg->pszRawMsg);
+
+ pMsg->iLenRawMsg = strlen(pszRawMsg);
+ if((pMsg->pszRawMsg = malloc(pMsg->iLenRawMsg + 1)) != NULL)
+ memcpy(pMsg->pszRawMsg, pszRawMsg, pMsg->iLenRawMsg + 1);
+ else
+ dprintf("Could not allocate memory for pszRawMsg buffer.");
+}
+
+
+
+
+/*
+ * vi:set ai:
+ */
diff --git a/msg.h b/msg.h
new file mode 100644
index 00000000..1a54a86c
--- /dev/null
+++ b/msg.h
@@ -0,0 +1,150 @@
+/* msg.h
+ * Header file for all msg-related functions.
+ *
+ * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c)
+ *
+ * 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 program 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.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#ifndef MSG_H_INCLUDED
+#define MSG_H_INCLUDED 1
+
+/* rgerhards 2004-11-08: The following structure represents a
+ * syslog message.
+ *
+ * Important Note:
+ * The message object is used for multiple purposes (once it
+ * has been created). Once created, it actully is a read-only
+ * object (though we do not specifically express this). In order
+ * to avoid multiple copies of the same object, we use a
+ * reference counter. This counter is set to 1 by the constructer
+ * and increased by 1 with a call to MsgAddRef(). The destructor
+ * checks the reference count. If it is more than 1, only the counter
+ * will be decremented. If it is 1, however, the object is actually
+ * destroyed. To make this work, it is vital that MsgAddRef() is
+ * called each time a "copy" is stored somewhere.
+ */
+struct msg {
+ int iRefCount; /* reference counter (0 = unused) */
+ short iSyslogVers; /* version of syslog protocol
+ * 0 - RFC 3164
+ * 1 - RFC draft-protocol-08 */
+ short bParseHOSTNAME; /* should the hostname be parsed from the message? */
+ /* background: the hostname is not present on "regular" messages
+ * received via UNIX domain sockets from the same machine. However,
+ * it is available when we have a forwarder (e.g. rfc3195d) using local
+ * sockets. All in all, the parser would need parse templates, that would
+ * resolve all these issues... rgerhards, 2005-10-06
+ */
+ short iSeverity; /* the severity 0..7 */
+ uchar *pszSeverity; /* severity as string... */
+ int iLenSeverity; /* ... and its length. */
+ uchar *pszSeverityStr; /* severity name... */
+ int iLenSeverityStr; /* ... and its length. */
+ int iFacility; /* Facility code (up to 2^32-1) */
+ uchar *pszFacility; /* Facility as string... */
+ int iLenFacility; /* ... and its length. */
+ uchar *pszFacilityStr; /* facility name... */
+ int iLenFacilityStr; /* ... and its length. */
+ uchar *pszPRI; /* the PRI as a string */
+ int iLenPRI; /* and its length */
+ uchar *pszRawMsg; /* message as it was received on the
+ * wire. This is important in case we
+ * need to preserve cryptographic verifiers.
+ */
+ int iLenRawMsg; /* length of raw message */
+ uchar *pszMSG; /* the MSG part itself */
+ int iLenMSG; /* Length of the MSG part */
+ uchar *pszUxTradMsg; /* the traditional UNIX message */
+ int iLenUxTradMsg;/* Length of the traditional UNIX message */
+ uchar *pszTAG; /* pointer to tag value */
+ int iLenTAG; /* Length of the TAG part */
+ uchar *pszHOSTNAME; /* HOSTNAME from syslog message */
+ int iLenHOSTNAME; /* Length of HOSTNAME */
+ uchar *pszRcvFrom; /* System message was received from */
+ int iLenRcvFrom; /* Length of pszRcvFrom */
+ int iProtocolVersion;/* protocol version of message received 0 - legacy, 1 syslog-protocol) */
+ rsCStrObj *pCSProgName; /* the (BSD) program name */
+ rsCStrObj *pCSStrucData;/* STRUCTURED-DATA */
+ rsCStrObj *pCSAPPNAME; /* APP-NAME */
+ rsCStrObj *pCSPROCID; /* PROCID */
+ rsCStrObj *pCSMSGID; /* MSGID */
+ struct syslogTime tRcvdAt;/* time the message entered this program */
+ char *pszRcvdAt3164; /* time as RFC3164 formatted string (always 15 charcters) */
+ char *pszRcvdAt3339; /* time as RFC3164 formatted string (32 charcters at most) */
+ char *pszRcvdAt_MySQL; /* rcvdAt as MySQL formatted string (always 14 charcters) */
+ struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */
+ char *pszTIMESTAMP3164; /* TIMESTAMP as RFC3164 formatted string (always 15 charcters) */
+ char *pszTIMESTAMP3339; /* TIMESTAMP as RFC3339 formatted string (32 charcters at most) */
+ char *pszTIMESTAMP_MySQL;/* TIMESTAMP as MySQL formatted string (always 14 charcters) */
+ int msgFlags; /* flags associated with this message */
+};
+typedef struct msg msg_t; /* new name */
+
+/* function prototypes
+ */
+char* getProgramName(msg_t*);
+msg_t* MsgConstruct(void);
+void MsgDestruct(msg_t * pM);
+msg_t* MsgDup(msg_t* pOld);
+msg_t *MsgAddRef(msg_t *pM);
+void setProtocolVersion(msg_t *pM, int iNewVersion);
+int getProtocolVersion(msg_t *pM);
+char *getProtocolVersionString(msg_t *pM);
+int getMSGLen(msg_t *pM);
+char *getRawMsg(msg_t *pM);
+char *getUxTradMsg(msg_t *pM);
+char *getMSG(msg_t *pM);
+char *getPRI(msg_t *pM);
+int getPRIi(msg_t *pM);
+char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt);
+char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt);
+char *getSeverity(msg_t *pM);
+char *getSeverityStr(msg_t *pM);
+char *getFacility(msg_t *pM);
+char *getFacilityStr(msg_t *pM);
+rsRetVal MsgSetAPPNAME(msg_t *pMsg, char* pszAPPNAME);
+int getAPPNAMELen(msg_t *pM);
+char *getAPPNAME(msg_t *pM);
+rsRetVal MsgSetPROCID(msg_t *pMsg, char* pszPROCID);
+int getPROCIDLen(msg_t *pM);
+char *getPROCID(msg_t *pM);
+rsRetVal MsgSetMSGID(msg_t *pMsg, char* pszMSGID);
+void MsgAssignTAG(msg_t *pMsg, char *pBuf);
+void MsgSetTAG(msg_t *pMsg, char* pszTAG);
+char *getTAG(msg_t *pM);
+int getHOSTNAMELen(msg_t *pM);
+char *getHOSTNAME(msg_t *pM);
+char *getRcvFrom(msg_t *pM);
+rsRetVal MsgSetStructuredData(msg_t *pMsg, char* pszStrucData);
+char *getStructuredData(msg_t *pM);
+int getProgramNameLen(msg_t *pM);
+char *getProgramName(msg_t *pM);
+void MsgSetRcvFrom(msg_t *pMsg, char* pszRcvFrom);
+void MsgAssignHOSTNAME(msg_t *pMsg, char *pBuf);
+void MsgSetHOSTNAME(msg_t *pMsg, char* pszHOSTNAME);
+int MsgSetUxTradMsg(msg_t *pMsg, char* pszUxTradMsg);
+void MsgSetMSG(msg_t *pMsg, char* pszMSG);
+void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg);
+void moveHOSTNAMEtoTAG(msg_t *pM);
+char *getMSGID(msg_t *pM);
+
+#endif /* #ifndef MSG_H_INCLUDED */
+/*
+ * vi:set ai:
+ */
diff --git a/syslogd-types.h b/syslogd-types.h
index f15acfee..3428db2a 100644
--- a/syslogd-types.h
+++ b/syslogd-types.h
@@ -27,6 +27,8 @@
#include "config.h" /* make sure we have autoconf macros */
#include "stringbuf.h"
+#include <sys/param.h>
+#include <sys/syslog.h>
#ifdef UT_NAMESIZE
# define UNAMESZ UT_NAMESIZE /* length of a login name */
@@ -37,6 +39,13 @@
#define MAXFNAME 200 /* max file pathname length */
+/* we define our own facility and severities */
+/* facility and severity codes */
+typedef struct _syslogCode {
+ char *c_name;
+ int c_val;
+} syslogCODE;
+
typedef enum _TCPFRAMINGMODE {
TCP_FRAMING_OCTET_STUFFING = 0, /* traditional LF-delimited */
TCP_FRAMING_OCTET_COUNTING = 1 /* -transport-tls like octet count */
@@ -82,78 +91,6 @@ struct syslogTime {
*/
};
-/* rgerhards 2004-11-08: The following structure represents a
- * syslog message.
- *
- * Important Note:
- * The message object is used for multiple purposes (once it
- * has been created). Once created, it actully is a read-only
- * object (though we do not specifically express this). In order
- * to avoid multiple copies of the same object, we use a
- * reference counter. This counter is set to 1 by the constructer
- * and increased by 1 with a call to MsgAddRef(). The destructor
- * checks the reference count. If it is more than 1, only the counter
- * will be decremented. If it is 1, however, the object is actually
- * destroyed. To make this work, it is vital that MsgAddRef() is
- * called each time a "copy" is stored somewhere.
- */
-struct msg {
- int iRefCount; /* reference counter (0 = unused) */
- short iSyslogVers; /* version of syslog protocol
- * 0 - RFC 3164
- * 1 - RFC draft-protocol-08 */
- short bParseHOSTNAME; /* should the hostname be parsed from the message? */
- /* background: the hostname is not present on "regular" messages
- * received via UNIX domain sockets from the same machine. However,
- * it is available when we have a forwarder (e.g. rfc3195d) using local
- * sockets. All in all, the parser would need parse templates, that would
- * resolve all these issues... rgerhards, 2005-10-06
- */
- short iSeverity; /* the severity 0..7 */
- uchar *pszSeverity; /* severity as string... */
- int iLenSeverity; /* ... and its length. */
- uchar *pszSeverityStr; /* severity name... */
- int iLenSeverityStr; /* ... and its length. */
- int iFacility; /* Facility code (up to 2^32-1) */
- uchar *pszFacility; /* Facility as string... */
- int iLenFacility; /* ... and its length. */
- uchar *pszFacilityStr; /* facility name... */
- int iLenFacilityStr; /* ... and its length. */
- uchar *pszPRI; /* the PRI as a string */
- int iLenPRI; /* and its length */
- uchar *pszRawMsg; /* message as it was received on the
- * wire. This is important in case we
- * need to preserve cryptographic verifiers.
- */
- int iLenRawMsg; /* length of raw message */
- uchar *pszMSG; /* the MSG part itself */
- int iLenMSG; /* Length of the MSG part */
- uchar *pszUxTradMsg; /* the traditional UNIX message */
- int iLenUxTradMsg;/* Length of the traditional UNIX message */
- uchar *pszTAG; /* pointer to tag value */
- int iLenTAG; /* Length of the TAG part */
- uchar *pszHOSTNAME; /* HOSTNAME from syslog message */
- int iLenHOSTNAME; /* Length of HOSTNAME */
- uchar *pszRcvFrom; /* System message was received from */
- int iLenRcvFrom; /* Length of pszRcvFrom */
- int iProtocolVersion;/* protocol version of message received 0 - legacy, 1 syslog-protocol) */
- rsCStrObj *pCSProgName; /* the (BSD) program name */
- rsCStrObj *pCSStrucData;/* STRUCTURED-DATA */
- rsCStrObj *pCSAPPNAME; /* APP-NAME */
- rsCStrObj *pCSPROCID; /* PROCID */
- rsCStrObj *pCSMSGID; /* MSGID */
- struct syslogTime tRcvdAt;/* time the message entered this program */
- char *pszRcvdAt3164; /* time as RFC3164 formatted string (always 15 charcters) */
- char *pszRcvdAt3339; /* time as RFC3164 formatted string (32 charcters at most) */
- char *pszRcvdAt_MySQL; /* rcvdAt as MySQL formatted string (always 14 charcters) */
- struct syslogTime tTIMESTAMP;/* (parsed) value of the timestamp */
- char *pszTIMESTAMP3164; /* TIMESTAMP as RFC3164 formatted string (always 15 charcters) */
- char *pszTIMESTAMP3339; /* TIMESTAMP as RFC3339 formatted string (32 charcters at most) */
- char *pszTIMESTAMP_MySQL;/* TIMESTAMP as MySQL formatted string (always 14 charcters) */
- int msgFlags; /* flags associated with this message */
-};
-typedef struct msg msg_t; /* new name */
-
/* values for f_type in struct filed below*/
#define F_UNUSED 0 /* unused entry */
diff --git a/syslogd.c b/syslogd.c
index d2bc5028..61388841 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -156,7 +156,6 @@
#include <pwd.h>
#include <grp.h>
-#define SYSLOG_NAMES
#include <sys/syslog.h>
#include <sys/param.h>
#ifdef __sun
@@ -201,6 +200,10 @@
#include "mysql/errmsg.h"
#endif
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif
+
#if HAVE_PATHS_H
#include <paths.h>
#endif
@@ -227,23 +230,34 @@
(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif
+#include "rsyslog.h"
+#include "template.h"
+#include "outchannel.h"
+#include "syslogd.h"
+
+#include "stringbuf.h"
+#include "parse.h"
+#include "srUtils.h"
+#include "msg.h"
+
+/* We define our own set of syslog defintions so that we
+ * do not need to rely on (possibly different) implementations.
+ * 2007-07-19 rgerhards
+ */
/* missing definitions for solaris
* 2006-02-16 Rger
*/
#ifdef __sun
-#define LOG_AUTHPRIV LOG_AUTH
+# define LOG_AUTHPRIV LOG_AUTH
+#endif
#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
#define LOG_PRI(p) ((p) & LOG_PRIMASK)
#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */
#define LOG_FTP (11<<3) /* ftp daemon */
#define INTERNAL_MARK LOG_MAKEPRI((LOG_NFACILITIES<<3), 0)
-typedef struct _code {
- char *c_name;
- int c_val;
-} CODE;
-
-CODE prioritynames[] =
+
+syslogCODE rs_prioritynames[] =
{
{ "alert", LOG_ALERT },
{ "crit", LOG_CRIT },
@@ -260,7 +274,7 @@ CODE prioritynames[] =
{ NULL, -1 }
};
-CODE facilitynames[] =
+syslogCODE rs_facilitynames[] =
{
{ "auth", LOG_AUTH },
{ "authpriv", LOG_AUTHPRIV },
@@ -286,22 +300,6 @@ CODE facilitynames[] =
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
-#endif
-
-#include "rsyslog.h"
-#include "template.h"
-#include "outchannel.h"
-#include "syslogd.h"
-#include "syslogd-types.h"
-
-
-#include "stringbuf.h"
-#include "parse.h"
-#include "srUtils.h"
-
-#ifdef USE_PTHREADS
-#include <pthread.h>
-#endif
#ifdef WITH_DB
#define _DB_MAXDBLEN 128 /* maximum number of db */
@@ -443,7 +441,7 @@ static int restart = 0; /* do restart (config read) - multithread safe */
static int bRequestDoMark = 0; /* do mark processing? (multithread safe) */
#define MAXFUNIX 20
-static int glblHadMemShortage = 0; /* indicates if we had memory shortage some time during the run */
+int glblHadMemShortage = 0; /* indicates if we had memory shortage some time during the run */
static int iDynaFileCacheSize = 10; /* max cache for dynamic files */
static int fCreateMode = 0644; /* mode to use when creating files */
static int fDirCreateMode = 0644; /* mode to use when creating files */
@@ -775,8 +773,6 @@ static msgQueue *queueInit (void);
static void *singleWorker(); /* REMOVEME later 2005-10-24 */
#endif
/* Function prototypes. */
-static rsRetVal aquirePROCIDFromTAG(msg_t *pM);
-static char* getProgramName(msg_t*);
static char **crunch_list(char *list);
static void printchopped(char *hname, char *msg, int len, int fd, int iSourceType);
static void printline(char *hname, char *msg, int iSource);
@@ -800,7 +796,6 @@ static void DBErrorHandler(register selector_t *f);
#endif
static int getSubString(uchar **pSrc, char *pDst, size_t DstSize, char cSep);
-static void getCurrTime(struct syslogTime *t);
static void cflineSetTemplateAndIOV(selector_t *f, char *pTemplateName);
/* Access functions for the selector_t. These functions are primarily
@@ -2591,7 +2586,7 @@ static int srSLMGParseTIMESTAMP3164(struct syslogTime *pTime, char* pszTS)
* returns the size of the timestamp written in bytes (without
* the string terminator). If 0 is returend, an error occured.
*/
-static int formatTimestampToMySQL(struct syslogTime *ts, char* pDst, size_t iLenDst)
+int formatTimestampToMySQL(struct syslogTime *ts, char* pDst, size_t iLenDst)
{
/* currently we do not consider localtime/utc. This may later be
* added. If so, I recommend using a property replacer option
@@ -2619,7 +2614,7 @@ static int formatTimestampToMySQL(struct syslogTime *ts, char* pDst, size_t iLen
* returns the size of the timestamp written in bytes (without
* the string terminator). If 0 is returend, an error occured.
*/
-static int formatTimestamp3339(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
+int formatTimestamp3339(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
{
int iRet;
char szTZ[7]; /* buffer for TZ information */
@@ -2670,7 +2665,7 @@ static int formatTimestamp3339(struct syslogTime *ts, char* pBuf, size_t iLenBuf
* returns the size of the timestamp written in bytes (without
* the string termnator). If 0 is returend, an error occured.
*/
-static int formatTimestamp3164(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
+int formatTimestamp3164(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
{
static char* monthNames[13] = {"ERR", "Jan", "Feb", "Mar",
"Apr", "May", "Jun", "Jul",
@@ -2723,7 +2718,7 @@ static int formatTimestamp(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
*
* Obviously, all caller-provided pointers must not be NULL...
*/
-static void getCurrTime(struct syslogTime *t)
+void getCurrTime(struct syslogTime *t)
{
struct timeval tp;
struct tm *tm;
@@ -2771,13 +2766,13 @@ static void getCurrTime(struct syslogTime *t)
*/
char *textpri(char *pRes, size_t pResLen, int pri)
{
- CODE *c_pri, *c_fac;
+ syslogCODE *c_pri, *c_fac;
assert(pRes != NULL);
assert(pResLen > 0);
- for (c_fac = facilitynames; c_fac->c_name && !(c_fac->c_val == LOG_FAC(pri)<<3); c_fac++);
- for (c_pri = prioritynames; c_pri->c_name && !(c_pri->c_val == LOG_PRI(pri)); c_pri++);
+ for (c_fac = rs_facilitynames; c_fac->c_name && !(c_fac->c_val == LOG_FAC(pri)<<3); c_fac++);
+ for (c_pri = rs_prioritynames; c_pri->c_name && !(c_pri->c_val == LOG_PRI(pri)); c_pri++);
snprintf (pRes, pResLen, "%s.%s<%d>", c_fac->c_name, c_pri->c_name, pri);
@@ -2785,998 +2780,6 @@ char *textpri(char *pRes, size_t pResLen, int pri)
}
-/* rgerhards 2004-11-09: helper routines for handling the
- * message object. We do only the most important things. It
- * is our firm hope that this will sooner or later be
- * obsoleted by liblogging.
- */
-
-
-/* "Constructor" for a msg "object". Returns a pointer to
- * the new object or NULL if no such object could be allocated.
- * An object constructed via this function should only be destroyed
- * via "MsgDestruct()".
- */
-static msg_t* MsgConstruct()
-{
- msg_t *pM;
-
- if((pM = calloc(1, sizeof(msg_t))) != NULL)
- { /* initialize members that are non-zero */
- pM->iRefCount = 1;
- pM->iSyslogVers = -1;
- pM->iSeverity = -1;
- pM->iFacility = -1;
- getCurrTime(&(pM->tRcvdAt));
- }
-
- /* DEV debugging only! dprintf("MsgConstruct\t0x%x, ref 1\n", (int)pM);*/
-
- return(pM);
-}
-
-
-/* Destructor for a msg "object". Must be called to dispose
- * of a msg object.
- */
-static void MsgDestruct(msg_t * pM)
-{
- assert(pM != NULL);
- /* DEV Debugging only ! dprintf("MsgDestruct\t0x%x, Ref now: %d\n", (int)pM, pM->iRefCount - 1); */
- if(--pM->iRefCount == 0)
- {
- /* DEV Debugging Only! dprintf("MsgDestruct\t0x%x, RefCount now 0, doing DESTROY\n", (int)pM); */
- if(pM->pszUxTradMsg != NULL)
- free(pM->pszUxTradMsg);
- if(pM->pszRawMsg != NULL)
- free(pM->pszRawMsg);
- if(pM->pszTAG != NULL)
- free(pM->pszTAG);
- if(pM->pszHOSTNAME != NULL)
- free(pM->pszHOSTNAME);
- if(pM->pszRcvFrom != NULL)
- free(pM->pszRcvFrom);
- if(pM->pszMSG != NULL)
- free(pM->pszMSG);
- if(pM->pszFacility != NULL)
- free(pM->pszFacility);
- if(pM->pszFacilityStr != NULL)
- free(pM->pszFacilityStr);
- if(pM->pszSeverity != NULL)
- free(pM->pszSeverity);
- if(pM->pszSeverityStr != NULL)
- free(pM->pszSeverityStr);
- if(pM->pszRcvdAt3164 != NULL)
- free(pM->pszRcvdAt3164);
- if(pM->pszRcvdAt3339 != NULL)
- free(pM->pszRcvdAt3339);
- if(pM->pszRcvdAt_MySQL != NULL)
- free(pM->pszRcvdAt_MySQL);
- if(pM->pszTIMESTAMP3164 != NULL)
- free(pM->pszTIMESTAMP3164);
- if(pM->pszTIMESTAMP3339 != NULL)
- free(pM->pszTIMESTAMP3339);
- if(pM->pszTIMESTAMP_MySQL != NULL)
- free(pM->pszTIMESTAMP_MySQL);
- if(pM->pszPRI != NULL)
- free(pM->pszPRI);
- free(pM);
- }
-}
-
-
-/* The macros below are used in MsgDup(). I use macros
- * to keep the fuction code somewhat more readyble. It is my
- * replacement for inline functions in CPP
- */
-#define tmpCOPYSZ(name) \
- if(pOld->psz##name != NULL) { \
- if((pNew->psz##name = srUtilStrDup(pOld->psz##name, pOld->iLen##name)) == NULL) {\
- MsgDestruct(pNew);\
- return NULL;\
- }\
- pNew->iLen##name = pOld->iLen##name;\
- }
-
-/* copy the CStr objects.
- * if the old value is NULL, we do not need to do anything because we
- * initialized the new value to NULL via calloc().
- */
-#define tmpCOPYCSTR(name) \
- if(pOld->pCS##name != NULL) {\
- if(rsCStrConstructFromCStr(&(pNew->pCS##name), pOld->pCS##name) != RS_RET_OK) {\
- MsgDestruct(pNew);\
- return NULL;\
- }\
- }
-/* Constructs a message object by duplicating another one.
- * Returns NULL if duplication failed.
- * rgerhards, 2007-07-10
- */
-static msg_t* MsgDup(msg_t* pOld)
-{
- msg_t* pNew;
-
- assert(pOld != NULL);
-
- if((pNew = (msg_t*) calloc(1, sizeof(msg_t))) == NULL) {
- glblHadMemShortage = 1;
- return NULL;
- }
-
- /* now copy the message properties */
- pNew->iRefCount = 1;
- pNew->iSyslogVers = pOld->iSyslogVers;
- pNew->bParseHOSTNAME = pOld->bParseHOSTNAME;
- pNew->iSeverity = pOld->iSeverity;
- pNew->iFacility = pOld->iFacility;
- pNew->bParseHOSTNAME = pOld->bParseHOSTNAME;
- pNew->msgFlags = pOld->msgFlags;
- pNew->iProtocolVersion = pOld->iProtocolVersion;
- memcpy(&pNew->tRcvdAt, &pOld->tRcvdAt, sizeof(struct syslogTime));
- memcpy(&pNew->tTIMESTAMP, &pOld->tTIMESTAMP, sizeof(struct syslogTime));
- tmpCOPYSZ(Severity);
- tmpCOPYSZ(SeverityStr);
- tmpCOPYSZ(Facility);
- tmpCOPYSZ(FacilityStr);
- tmpCOPYSZ(PRI);
- tmpCOPYSZ(RawMsg);
- tmpCOPYSZ(MSG);
- tmpCOPYSZ(UxTradMsg);
- tmpCOPYSZ(TAG);
- tmpCOPYSZ(HOSTNAME);
- tmpCOPYSZ(RcvFrom);
-
- tmpCOPYCSTR(ProgName);
- tmpCOPYCSTR(StrucData);
- tmpCOPYCSTR(APPNAME);
- tmpCOPYCSTR(PROCID);
- tmpCOPYCSTR(MSGID);
-
- /* we do not copy all other cache properties, as we do not even know
- * if they are needed once again. So we let them re-create if needed.
- */
-
- return pNew;
-}
-#undef tmpCOPYSZ
-#undef tmpCOPYCSTR
-
-
-/* Increment reference count - see description of the "msg"
- * structure for details. As a convenience to developers,
- * this method returns the msg pointer that is passed to it.
- * It is recommended that it is called as follows:
- *
- * pSecondMsgPointer = MsgAddRef(pOrgMsgPointer);
- */
-static msg_t *MsgAddRef(msg_t *pM)
-{
- assert(pM != NULL);
- pM->iRefCount++;
- /* DEV debugging only! dprintf("MsgAddRef\t0x%x done, Ref now: %d\n", (int)pM, pM->iRefCount);*/
- return(pM);
-}
-
-/* Access methods - dumb & easy, not a comment for each ;)
- */
-static void setProtocolVersion(msg_t *pM, int iNewVersion)
-{
- assert(pM != NULL);
- if(iNewVersion != 0 && iNewVersion != 1) {
- dprintf("Tried to set unsupported protocol version %d - changed to 0.\n", iNewVersion);
- iNewVersion = 0;
- }
- pM->iProtocolVersion = iNewVersion;
-}
-
-static int getProtocolVersion(msg_t *pM)
-{
- assert(pM != NULL);
- return(pM->iProtocolVersion);
-}
-
-/* note: string is taken from constant pool, do NOT free */
-static char *getProtocolVersionString(msg_t *pM)
-{
- assert(pM != NULL);
- return(pM->iProtocolVersion ? "1" : "0");
-}
-
-static int getMSGLen(msg_t *pM)
-{
- return((pM == NULL) ? 0 : pM->iLenMSG);
-}
-
-
-static char *getRawMsg(msg_t *pM)
-{
- if(pM == NULL)
- return "";
- else
- if(pM->pszRawMsg == NULL)
- return "";
- else
- return (char*)pM->pszRawMsg;
-}
-
-static char *getUxTradMsg(msg_t *pM)
-{
- if(pM == NULL)
- return "";
- else
- if(pM->pszUxTradMsg == NULL)
- return "";
- else
- return (char*)pM->pszUxTradMsg;
-}
-
-static char *getMSG(msg_t *pM)
-{
- if(pM == NULL)
- return "";
- else
- if(pM->pszMSG == NULL)
- return "";
- else
- return (char*)pM->pszMSG;
-}
-
-
-/* Get PRI value in text form */
-static char *getPRI(msg_t *pM)
-{
- if(pM == NULL)
- return "";
-
- if(pM->pszPRI == NULL) {
- /* OK, we need to construct it...
- * we use a 5 byte buffer - as of
- * RFC 3164, it can't be longer. Should it
- * still be, snprintf will truncate...
- */
- if((pM->pszPRI = malloc(5)) == NULL) return "";
- pM->iLenPRI = snprintf((char*)pM->pszPRI, 5, "%d",
- LOG_MAKEPRI(pM->iFacility, pM->iSeverity));
- }
-
- return (char*)pM->pszPRI;
-}
-
-
-/* Get PRI value as integer */
-static int getPRIi(msg_t *pM)
-{
- assert(pM != NULL);
- return (pM->iFacility << 3) + (pM->iSeverity);
-}
-
-
-static char *getTimeReported(msg_t *pM, enum tplFormatTypes eFmt)
-{
- if(pM == NULL)
- return "";
-
- switch(eFmt) {
- case tplFmtDefault:
- if(pM->pszTIMESTAMP3164 == NULL) {
- if((pM->pszTIMESTAMP3164 = malloc(16)) == NULL) return "";
- formatTimestamp3164(&pM->tTIMESTAMP, pM->pszTIMESTAMP3164, 16);
- }
- return(pM->pszTIMESTAMP3164);
- case tplFmtMySQLDate:
- if(pM->pszTIMESTAMP_MySQL == NULL) {
- if((pM->pszTIMESTAMP_MySQL = malloc(15)) == NULL) return "";
- formatTimestampToMySQL(&pM->tTIMESTAMP, pM->pszTIMESTAMP_MySQL, 15);
- }
- return(pM->pszTIMESTAMP_MySQL);
- case tplFmtRFC3164Date:
- if(pM->pszTIMESTAMP3164 == NULL) {
- if((pM->pszTIMESTAMP3164 = malloc(16)) == NULL) return "";
- formatTimestamp3164(&pM->tTIMESTAMP, pM->pszTIMESTAMP3164, 16);
- }
- return(pM->pszTIMESTAMP3164);
- case tplFmtRFC3339Date:
- if(pM->pszTIMESTAMP3339 == NULL) {
- if((pM->pszTIMESTAMP3339 = malloc(33)) == NULL) return "";
- formatTimestamp3339(&pM->tTIMESTAMP, pM->pszTIMESTAMP3339, 33);
- }
- return(pM->pszTIMESTAMP3339);
- }
- return "INVALID eFmt OPTION!";
-}
-
-static char *getTimeGenerated(msg_t *pM, enum tplFormatTypes eFmt)
-{
- if(pM == NULL)
- return "";
-
- switch(eFmt) {
- case tplFmtDefault:
- if(pM->pszRcvdAt3164 == NULL) {
- if((pM->pszRcvdAt3164 = malloc(16)) == NULL) return "";
- formatTimestamp3164(&pM->tRcvdAt, pM->pszRcvdAt3164, 16);
- }
- return(pM->pszRcvdAt3164);
- case tplFmtMySQLDate:
- if(pM->pszRcvdAt_MySQL == NULL) {
- if((pM->pszRcvdAt_MySQL = malloc(15)) == NULL) return "";
- formatTimestampToMySQL(&pM->tRcvdAt, pM->pszRcvdAt_MySQL, 15);
- }
- return(pM->pszRcvdAt_MySQL);
- case tplFmtRFC3164Date:
- if((pM->pszRcvdAt3164 = malloc(16)) == NULL) return "";
- formatTimestamp3164(&pM->tRcvdAt, pM->pszRcvdAt3164, 16);
- return(pM->pszRcvdAt3164);
- case tplFmtRFC3339Date:
- if(pM->pszRcvdAt3339 == NULL) {
- if((pM->pszRcvdAt3339 = malloc(33)) == NULL) return "";
- formatTimestamp3339(&pM->tRcvdAt, pM->pszRcvdAt3339, 33);
- }
- return(pM->pszRcvdAt3339);
- }
- return "INVALID eFmt OPTION!";
-}
-
-
-char *getSeverity(msg_t *pM)
-{
- if(pM == NULL)
- return "";
-
- if(pM->pszSeverity == NULL) {
- /* we use a 2 byte buffer - can only be one digit */
- if((pM->pszSeverity = malloc(2)) == NULL) return "";
- pM->iLenSeverity =
- snprintf((char*)pM->pszSeverity, 2, "%d", pM->iSeverity);
- }
- return((char*)pM->pszSeverity);
-}
-
-static char *getSeverityStr(msg_t *pM)
-{
- CODE *c;
- int val;
- char *name = NULL;
-
- if(pM == NULL)
- return "";
-
- if(pM->pszSeverityStr == NULL) {
- for(c = prioritynames, val = pM->iSeverity; c->c_name; c++)
- if(c->c_val == val) {
- name = c->c_name;
- break;
- }
- if(name == NULL) {
- /* we use a 2 byte buffer - can only be one digit */
- if((pM->pszSeverityStr = malloc(2)) == NULL) return "";
- pM->iLenSeverityStr =
- snprintf((char*)pM->pszSeverityStr, 2, "%d", pM->iSeverity);
- } else {
- if((pM->pszSeverityStr = (uchar*) strdup(name)) == NULL) return "";
- pM->iLenSeverityStr = strlen((char*)name);
- }
- }
- return((char*)pM->pszSeverityStr);
-}
-
-static char *getFacility(msg_t *pM)
-{
- if(pM == NULL)
- return "";
-
- if(pM->pszFacility == NULL) {
- /* we use a 12 byte buffer - as of
- * syslog-protocol, facility can go
- * up to 2^32 -1
- */
- if((pM->pszFacility = malloc(12)) == NULL) return "";
- pM->iLenFacility =
- snprintf((char*)pM->pszFacility, 12, "%d", pM->iFacility);
- }
- return((char*)pM->pszFacility);
-}
-
-static char *getFacilityStr(msg_t *pM)
-{
- CODE *c;
- int val;
- char *name = NULL;
-
- if(pM == NULL)
- return "";
-
- if(pM->pszFacilityStr == NULL) {
- for(c = facilitynames, val = pM->iFacility << 3; c->c_name; c++)
- if(c->c_val == val) {
- name = c->c_name;
- break;
- }
- if(name == NULL) {
- /* we use a 12 byte buffer - as of
- * syslog-protocol, facility can go
- * up to 2^32 -1
- */
- if((pM->pszFacilityStr = malloc(12)) == NULL) return "";
- pM->iLenFacilityStr =
- snprintf((char*)pM->pszFacilityStr, 12, "%d", val >> 3);
- } else {
- if((pM->pszFacilityStr = (uchar*)strdup(name)) == NULL) return "";
- pM->iLenFacilityStr = strlen((char*)name);
- }
- }
- return((char*)pM->pszFacilityStr);
-}
-
-
-/* rgerhards 2004-11-24: set APP-NAME in msg object
- */
-static rsRetVal MsgSetAPPNAME(msg_t *pMsg, char* pszAPPNAME)
-{
- assert(pMsg != NULL);
- if(pMsg->pCSAPPNAME == NULL) {
- /* we need to obtain the object first */
- if((pMsg->pCSAPPNAME = rsCStrConstruct()) == NULL)
- return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
- rsCStrSetAllocIncrement(pMsg->pCSAPPNAME, 128);
- }
- /* if we reach this point, we have the object */
- return rsCStrSetSzStr(pMsg->pCSAPPNAME, (uchar*) pszAPPNAME);
-}
-
-
-/* This function tries to emulate APPNAME if it is not present. Its
- * main use is when we have received a log record via legacy syslog and
- * now would like to send out the same one via syslog-protocol.
- */
-static void tryEmulateAPPNAME(msg_t *pM)
-{
- assert(pM != NULL);
- if(pM->pCSAPPNAME != NULL)
- return; /* we are already done */
-
- if(getProtocolVersion(pM) == 0) {
- /* only then it makes sense to emulate */
- MsgSetAPPNAME(pM, getProgramName(pM));
- }
-}
-
-
-/* rgerhards, 2005-11-24
- */
-static int getAPPNAMELen(msg_t *pM)
-{
- assert(pM != NULL);
- if(pM->pCSAPPNAME == NULL)
- tryEmulateAPPNAME(pM);
- return (pM->pCSAPPNAME == NULL) ? 0 : rsCStrLen(pM->pCSAPPNAME);
-}
-
-
-/* rgerhards, 2005-11-24
- */
-static char *getAPPNAME(msg_t *pM)
-{
- assert(pM != NULL);
- if(pM->pCSAPPNAME == NULL)
- tryEmulateAPPNAME(pM);
- return (pM->pCSAPPNAME == NULL) ? "" : (char*) rsCStrGetSzStrNoNULL(pM->pCSAPPNAME);
-}
-
-
-
-
-/* rgerhards 2004-11-24: set PROCID in msg object
- */
-static rsRetVal MsgSetPROCID(msg_t *pMsg, char* pszPROCID)
-{
- assert(pMsg != NULL);
- if(pMsg->pCSPROCID == NULL) {
- /* we need to obtain the object first */
- if((pMsg->pCSPROCID = rsCStrConstruct()) == NULL)
- return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
- rsCStrSetAllocIncrement(pMsg->pCSPROCID, 128);
- }
- /* if we reach this point, we have the object */
- return rsCStrSetSzStr(pMsg->pCSPROCID, (uchar*) pszPROCID);
-}
-
-/* rgerhards, 2005-11-24
- */
-static int getPROCIDLen(msg_t *pM)
-{
- assert(pM != NULL);
- if(pM->pCSPROCID == NULL)
- aquirePROCIDFromTAG(pM);
- return (pM->pCSPROCID == NULL) ? 1 : rsCStrLen(pM->pCSPROCID);
-}
-
-
-/* rgerhards, 2005-11-24
- */
-static char *getPROCID(msg_t *pM)
-{
- assert(pM != NULL);
- if(pM->pCSPROCID == NULL)
- aquirePROCIDFromTAG(pM);
- return (pM->pCSPROCID == NULL) ? "-" : (char*) rsCStrGetSzStrNoNULL(pM->pCSPROCID);
-}
-
-
-/* rgerhards 2004-11-24: set MSGID in msg object
- */
-static rsRetVal MsgSetMSGID(msg_t *pMsg, char* pszMSGID)
-{
- assert(pMsg != NULL);
- if(pMsg->pCSMSGID == NULL) {
- /* we need to obtain the object first */
- if((pMsg->pCSMSGID = rsCStrConstruct()) == NULL)
- return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
- rsCStrSetAllocIncrement(pMsg->pCSMSGID, 128);
- }
- /* if we reach this point, we have the object */
- return rsCStrSetSzStr(pMsg->pCSMSGID, (uchar*) pszMSGID);
-}
-
-/* rgerhards, 2005-11-24
- */
-#if 0 /* This method is currently not called, be we like to preserve it */
-static int getMSGIDLen(msg_t *pM)
-{
- return (pM->pCSMSGID == NULL) ? 1 : rsCStrLen(pM->pCSMSGID);
-}
-#endif
-
-
-/* rgerhards, 2005-11-24
- */
-static char *getMSGID(msg_t *pM)
-{
- return (pM->pCSMSGID == NULL) ? "-" : (char*) rsCStrGetSzStrNoNULL(pM->pCSMSGID);
-}
-
-
-/* Set the TAG to a caller-provided string. This is thought
- * to be a heap buffer that the caller will no longer use. This
- * function is a performance optimization over MsgSetTAG().
- * rgerhards 2004-11-19
- */
-static void MsgAssignTAG(msg_t *pMsg, char *pBuf)
-{
- assert(pMsg != NULL);
- pMsg->iLenTAG = (pBuf == NULL) ? 0 : strlen(pBuf);
- pMsg->pszTAG = (uchar*) pBuf;
-}
-
-
-/* rgerhards 2004-11-16: set TAG in msg object
- */
-static void MsgSetTAG(msg_t *pMsg, char* pszTAG)
-{
- assert(pMsg != NULL);
- if(pMsg->pszTAG != NULL)
- free(pMsg->pszTAG);
- pMsg->iLenTAG = strlen(pszTAG);
- if((pMsg->pszTAG = malloc(pMsg->iLenTAG + 1)) != NULL)
- memcpy(pMsg->pszTAG, pszTAG, pMsg->iLenTAG + 1);
- else
- dprintf("Could not allocate memory in MsgSetTAG()\n");
-}
-
-
-/* This function tries to emulate the TAG if none is
- * set. Its primary purpose is to provide an old-style TAG
- * when a syslog-protocol message has been received. Then,
- * the tag is APP-NAME "[" PROCID "]". The function first checks
- * if there is a TAG and, if not, if it can emulate it.
- * rgerhards, 2005-11-24
- */
-static void tryEmulateTAG(msg_t *pM)
-{
- int iTAGLen;
- char *pBuf;
- assert(pM != NULL);
-
- if(pM->pszTAG != NULL)
- return; /* done, no need to emulate */
-
- if(getProtocolVersion(pM) == 1) {
- if(!strcmp(getPROCID(pM), "-")) {
- /* no process ID, use APP-NAME only */
- MsgSetTAG(pM, getAPPNAME(pM));
- } else {
- /* now we can try to emulate */
- iTAGLen = getAPPNAMELen(pM) + getPROCIDLen(pM) + 3;
- if((pBuf = malloc(iTAGLen * sizeof(char))) == NULL)
- return; /* nothing we can do */
- snprintf(pBuf, iTAGLen, "%s[%s]", getAPPNAME(pM), getPROCID(pM));
- MsgAssignTAG(pM, pBuf);
- }
- }
-}
-
-
-#if 0 /* This method is currently not called, be we like to preserve it */
-static int getTAGLen(msg_t *pM)
-{
- if(pM == NULL)
- return 0;
- else {
- tryEmulateTAG(pM);
- if(pM->pszTAG == NULL)
- return 0;
- else
- return pM->iLenTAG;
- }
-}
-#endif
-
-
-static char *getTAG(msg_t *pM)
-{
- if(pM == NULL)
- return "";
- else {
- tryEmulateTAG(pM);
- if(pM->pszTAG == NULL)
- return "";
- else
- return (char*) pM->pszTAG;
- }
-}
-
-
-static int getHOSTNAMELen(msg_t *pM)
-{
- if(pM == NULL)
- return 0;
- else
- if(pM->pszHOSTNAME == NULL)
- return 0;
- else
- return pM->iLenHOSTNAME;
-}
-
-
-static char *getHOSTNAME(msg_t *pM)
-{
- if(pM == NULL)
- return "";
- else
- if(pM->pszHOSTNAME == NULL)
- return "";
- else
- return (char*) pM->pszHOSTNAME;
-}
-
-
-static char *getRcvFrom(msg_t *pM)
-{
- if(pM == NULL)
- return "";
- else
- if(pM->pszRcvFrom == NULL)
- return "";
- else
- return (char*) pM->pszRcvFrom;
-}
-/* rgerhards 2004-11-24: set STRUCTURED DATA in msg object
- */
-static rsRetVal MsgSetStructuredData(msg_t *pMsg, char* pszStrucData)
-{
- assert(pMsg != NULL);
- if(pMsg->pCSStrucData == NULL) {
- /* we need to obtain the object first */
- if((pMsg->pCSStrucData = rsCStrConstruct()) == NULL)
- return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
- rsCStrSetAllocIncrement(pMsg->pCSStrucData, 128);
- }
- /* if we reach this point, we have the object */
- return rsCStrSetSzStr(pMsg->pCSStrucData, (uchar*) pszStrucData);
-}
-
-/* get the length of the "STRUCTURED-DATA" sz string
- * rgerhards, 2005-11-24
- */
-#if 0 /* This method is currently not called, be we like to preserve it */
-static int getStructuredDataLen(msg_t *pM)
-{
- return (pM->pCSStrucData == NULL) ? 1 : rsCStrLen(pM->pCSStrucData);
-}
-#endif
-
-
-/* get the "STRUCTURED-DATA" as sz string
- * rgerhards, 2005-11-24
- */
-static char *getStructuredData(msg_t *pM)
-{
- return (pM->pCSStrucData == NULL) ? "-" : (char*) rsCStrGetSzStrNoNULL(pM->pCSStrucData);
-}
-
-
-/* This function moves the HOSTNAME inside the message object to the
- * TAG. It is a specialised function used to handle the condition when
- * a message without HOSTNAME is being processed. The missing HOSTNAME
- * is only detected at a later stage, during TAG processing, so that
- * we already had set the HOSTNAME property and now need to move it to
- * the TAG. Of course, we could do this via a couple of get/set methods,
- * but it is far more efficient to do it via this specialised method.
- * This is especially important as this can be a very common case, e.g.
- * when BSD syslog is acting as a sender.
- * rgerhards, 2005-11-10.
- */
-static void moveHOSTNAMEtoTAG(msg_t *pM)
-{
- assert(pM != NULL);
- if(pM->pszTAG != NULL)
- free(pM->pszTAG);
- pM->pszTAG = pM->pszHOSTNAME;
- pM->iLenTAG = pM->iLenHOSTNAME;
- pM->pszHOSTNAME = NULL;
- pM->iLenHOSTNAME = 0;
-}
-
-
-/* This functions tries to aquire the PROCID from TAG. Its primary use is
- * when a legacy syslog message has been received and should be forwarded as
- * syslog-protocol (or the PROCID is requested for any other reason).
- * In legacy syslog, the PROCID is considered to be the character sequence
- * between the first [ and the first ]. This usually are digits only, but we
- * do not check that. However, if there is no closing ], we do not assume we
- * can obtain a PROCID. Take in mind that not every legacy syslog message
- * actually has a PROCID.
- * rgerhards, 2005-11-24
- */
-static rsRetVal aquirePROCIDFromTAG(msg_t *pM)
-{
- register int i;
- int iRet;
-
- assert(pM != NULL);
- if(pM->pCSPROCID != NULL)
- return RS_RET_OK; /* we are already done ;) */
-
- if(getProtocolVersion(pM) != 0)
- return RS_RET_OK; /* we can only emulate if we have legacy format */
-
- /* find first '['... */
- i = 0;
- while((i < pM->iLenTAG) && (pM->pszTAG[i] != '['))
- ++i;
- if(!(i < pM->iLenTAG))
- return RS_RET_OK; /* no [, so can not emulate... */
-
- ++i; /* skip '[' */
-
- /* now obtain the PROCID string... */
- if((pM->pCSPROCID = rsCStrConstruct()) == NULL)
- return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
- rsCStrSetAllocIncrement(pM->pCSPROCID, 16);
- while((i < pM->iLenTAG) && (pM->pszTAG[i] != ']')) {
- if((iRet = rsCStrAppendChar(pM->pCSPROCID, pM->pszTAG[i])) != RS_RET_OK)
- return iRet;
- ++i;
- }
-
- if(!(i < pM->iLenTAG)) {
- /* oops... it looked like we had a PROCID, but now it has
- * turned out this is not true. In this case, we need to free
- * the buffer and simply return. Note that this is NOT an error
- * case!
- */
- rsCStrDestruct(pM->pCSPROCID);
- pM->pCSPROCID = NULL;
- return RS_RET_OK;
- }
-
- /* OK, finaally we could obtain a PROCID. So let's use it ;) */
- if((iRet = rsCStrFinish(pM->pCSPROCID)) != RS_RET_OK)
- return iRet;
-
- return RS_RET_OK;
-}
-
-
-/* Parse and set the "programname" for a given MSG object. Programname
- * is a BSD concept, it is the tag without any instance-specific information.
- * Precisely, the programname is terminated by either (whichever occurs first):
- * - end of tag
- * - nonprintable character
- * - ':'
- * - '['
- * - '/'
- * The above definition has been taken from the FreeBSD syslogd sources.
- *
- * The program name is not parsed by default, because it is infrequently-used.
- * If it is needed, this function should be called first. It checks if it is
- * already set and extracts it, if not.
- * A message object must be provided, else a crash will occur.
- * rgerhards, 2005-10-19
- */
-static rsRetVal aquireProgramName(msg_t *pM)
-{
- register int i;
- int iRet;
-
- assert(pM != NULL);
- if(pM->pCSProgName == NULL) {
- /* ok, we do not yet have it. So let's parse the TAG
- * to obtain it.
- */
- if((pM->pCSProgName = rsCStrConstruct()) == NULL)
- return RS_RET_OBJ_CREATION_FAILED; /* best we can do... */
- rsCStrSetAllocIncrement(pM->pCSProgName, 33);
- for( i = 0
- ; (i < pM->iLenTAG) && isprint((int) pM->pszTAG[i])
- && (pM->pszTAG[i] != '\0') && (pM->pszTAG[i] != ':')
- && (pM->pszTAG[i] != '[') && (pM->pszTAG[i] != '/')
- ; ++i) {
- if((iRet = rsCStrAppendChar(pM->pCSProgName, pM->pszTAG[i])) != RS_RET_OK)
- return iRet;
- }
- if((iRet = rsCStrFinish(pM->pCSProgName)) != RS_RET_OK)
- return iRet;
- }
- return RS_RET_OK;
-}
-
-
-/* get the length of the "programname" sz string
- * rgerhards, 2005-10-19
- */
-static int getProgramNameLen(msg_t *pM)
-{
- int iRet;
-
- assert(pM != NULL);
- if((iRet = aquireProgramName(pM)) != RS_RET_OK) {
- dprintf("error %d returned by aquireProgramName() in getProgramNameLen()\n", iRet);
- return 0; /* best we can do (consistent wiht what getProgramName() returns) */
- }
-
- return (pM->pCSProgName == NULL) ? 0 : rsCStrLen(pM->pCSProgName);
-}
-
-
-/* get the "programname" as sz string
- * rgerhards, 2005-10-19
- */
-static char *getProgramName(msg_t *pM)
-{
- int iRet;
-
- assert(pM != NULL);
- if((iRet = aquireProgramName(pM)) != RS_RET_OK) {
- dprintf("error %d returned by aquireProgramName() in getProgramName()\n", iRet);
- return ""; /* best we can do */
- }
-
- return (pM->pCSProgName == NULL) ? "" : (char*) rsCStrGetSzStrNoNULL(pM->pCSProgName);
-}
-
-
-/* rgerhards 2004-11-16: set pszRcvFrom in msg object
- */
-static void MsgSetRcvFrom(msg_t *pMsg, char* pszRcvFrom)
-{
- assert(pMsg != NULL);
- if(pMsg->pszRcvFrom != NULL)
- free(pMsg->pszRcvFrom);
-
- pMsg->iLenRcvFrom = strlen(pszRcvFrom);
- if((pMsg->pszRcvFrom = malloc(pMsg->iLenRcvFrom + 1)) != NULL) {
- memcpy(pMsg->pszRcvFrom, pszRcvFrom, pMsg->iLenRcvFrom + 1);
- }
-}
-
-
-/* Set the HOSTNAME to a caller-provided string. This is thought
- * to be a heap buffer that the caller will no longer use. This
- * function is a performance optimization over MsgSetHOSTNAME().
- * rgerhards 2004-11-19
- */
-static void MsgAssignHOSTNAME(msg_t *pMsg, char *pBuf)
-{
- assert(pMsg != NULL);
- assert(pBuf != NULL);
- pMsg->iLenHOSTNAME = strlen(pBuf);
- pMsg->pszHOSTNAME = (uchar*) pBuf;
-}
-
-
-/* rgerhards 2004-11-09: set HOSTNAME in msg object
- * rgerhards, 2007-06-21:
- * Does not return anything. If an error occurs, the hostname is
- * simply not set. I have changed this behaviour. The only problem
- * we can run into is memory shortage. If we have such, it is better
- * to loose the hostname than the full message. So we silently ignore
- * that problem and hope that memory will be available the next time
- * we need it. The rest of the code already knows how to handle an
- * unset HOSTNAME.
- */
-static void MsgSetHOSTNAME(msg_t *pMsg, char* pszHOSTNAME)
-{
- assert(pMsg != NULL);
- if(pMsg->pszHOSTNAME != NULL)
- free(pMsg->pszHOSTNAME);
-
- pMsg->iLenHOSTNAME = strlen(pszHOSTNAME);
- if((pMsg->pszHOSTNAME = malloc(pMsg->iLenHOSTNAME + 1)) != NULL)
- memcpy(pMsg->pszHOSTNAME, pszHOSTNAME, pMsg->iLenHOSTNAME + 1);
- else
- dprintf("Could not allocate memory in MsgSetHOSTNAME()\n");
-}
-
-
-/* Set the UxTradMsg to a caller-provided string. This is thought
- * to be a heap buffer that the caller will no longer use. This
- * function is a performance optimization over MsgSetUxTradMsg().
- * rgerhards 2004-11-19
- */
-#if 0 /* This method is currently not called, be we like to preserve it */
-static void MsgAssignUxTradMsg(msg_t *pMsg, char *pBuf)
-{
- assert(pMsg != NULL);
- assert(pBuf != NULL);
- pMsg->iLenUxTradMsg = strlen(pBuf);
- pMsg->pszUxTradMsg = pBuf;
-}
-#endif
-
-
-/* rgerhards 2004-11-17: set the traditional Unix message in msg object
- */
-static int MsgSetUxTradMsg(msg_t *pMsg, char* pszUxTradMsg)
-{
- assert(pMsg != NULL);
- assert(pszUxTradMsg != NULL);
- pMsg->iLenUxTradMsg = strlen(pszUxTradMsg);
- if(pMsg->pszUxTradMsg != NULL)
- free(pMsg->pszUxTradMsg);
- if((pMsg->pszUxTradMsg = malloc(pMsg->iLenUxTradMsg + 1)) != NULL)
- memcpy(pMsg->pszUxTradMsg, pszUxTradMsg, pMsg->iLenUxTradMsg + 1);
- else
- dprintf("Could not allocate memory for pszUxTradMsg buffer.");
-
- return(0);
-}
-
-
-/* rgerhards 2004-11-09: set MSG in msg object
- */
-static void MsgSetMSG(msg_t *pMsg, char* pszMSG)
-{
- assert(pMsg != NULL);
- assert(pszMSG != NULL);
-
- if(pMsg->pszMSG != NULL)
- free(pMsg->pszMSG);
-
- pMsg->iLenMSG = strlen(pszMSG);
- if((pMsg->pszMSG = malloc(pMsg->iLenMSG + 1)) != NULL)
- memcpy(pMsg->pszMSG, pszMSG, pMsg->iLenMSG + 1);
- else
- dprintf("MsgSetMSG could not allocate memory for pszMSG buffer.");
-}
-
-/* rgerhards 2004-11-11: set RawMsg in msg object
- */
-static void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg)
-{
- assert(pMsg != NULL);
- if(pMsg->pszRawMsg != NULL)
- free(pMsg->pszRawMsg);
-
- pMsg->iLenRawMsg = strlen(pszRawMsg);
- if((pMsg->pszRawMsg = malloc(pMsg->iLenRawMsg + 1)) != NULL)
- memcpy(pMsg->pszRawMsg, pszRawMsg, pMsg->iLenRawMsg + 1);
- else
- dprintf("Could not allocate memory for pszRawMsg buffer.");
-}
-
-
/* This function returns the current date in different
* variants. It is used to construct the $NOW series of
* system properties. The returned buffer must be freed
diff --git a/syslogd.h b/syslogd.h
index b4bfa05c..c07e9b86 100644
--- a/syslogd.h
+++ b/syslogd.h
@@ -1,10 +1,44 @@
-/* common header for syslogd */
+/* common header for syslogd
+ * 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 program 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.
+ *
+ * A copy of the GPL can be found in the file "COPYING" in this distribution.
+ */
+#ifndef SYSLOGD_H_INCLUDED
+#define SYSLOGD_H_INCLUDED 1
+
+#include "syslogd-types.h"
+
#if defined(__GLIBC__)
#define dprintf mydprintf
#endif /* __GLIBC__ */
+
void dprintf(char *, ...);
void logerror(char *type);
void logerrorSz(char *type, char *errMsg);
void logerrorInt(char *type, int iErr);
+void getCurrTime(struct syslogTime *t);
+int formatTimestampToMySQL(struct syslogTime *ts, char* pDst, size_t iLenDst);
+int formatTimestamp3339(struct syslogTime *ts, char* pBuf, size_t iLenBuf);
+int formatTimestamp3164(struct syslogTime *ts, char* pBuf, size_t iLenBuf);
+
+extern int glblHadMemShortage; /* indicates if we had memory shortage some time during the run */
+extern syslogCODE rs_prioritynames[];
+extern syslogCODE rs_facilitynames[];
+
#include "rsyslog.h"
+#endif /* #ifndef SYSLOGD_H_INCLUDED */