diff options
Diffstat (limited to 'syslogd.c')
-rw-r--r-- | syslogd.c | 1059 |
1 files changed, 31 insertions, 1028 deletions
@@ -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 |