summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2004-12-03 11:36:07 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2004-12-03 11:36:07 +0000
commit55d5bc64dcbd38cc8e344f4c328779f3c5831f90 (patch)
tree95d4d5a63d6149697205dd067009a19137637fed
parentd9b4c8bcb732e021f11a39a3a4ba825717b42065 (diff)
downloadrsyslog-55d5bc64dcbd38cc8e344f4c328779f3c5831f90.tar.gz
rsyslog-55d5bc64dcbd38cc8e344f4c328779f3c5831f90.tar.xz
rsyslog-55d5bc64dcbd38cc8e344f4c328779f3c5831f90.zip
substring support for properties added, some fixes
-rw-r--r--INSTALL1
-rw-r--r--Makefile9
-rw-r--r--syslogd.c119
-rw-r--r--template.c69
-rw-r--r--test.conf7
5 files changed, 126 insertions, 79 deletions
diff --git a/INSTALL b/INSTALL
index 4c04611b..c07be50c 100644
--- a/INSTALL
+++ b/INSTALL
@@ -26,6 +26,7 @@
may be security concerns with running it as root. Please repeat
step 1 if you are unsure of why this may be the case.
+5.) The make file currently doe
5.) YOU NEED TO DECIDE IF YOU WOULD LIKE TO REPLACE THE STANDARD SYSLOGD OR NOT!
The is important as it influences the names used. If you call
make install
diff --git a/Makefile b/Makefile
index b96d6169..abb36daf 100644
--- a/Makefile
+++ b/Makefile
@@ -49,7 +49,8 @@ all: syslogd
test: syslog_tst ksym oops_test tsyslogd
-install: install_man install_exec
+#install: install_man install_exec
+install: install_exec
syslogd: syslogd.o pidfile.o template.o stringbuf.o srUtils.o
${CC} ${LDFLAGS} -o syslogd syslogd.o pidfile.o template.o stringbuf.o srUtils.o ${LIBS}
@@ -84,8 +85,12 @@ clean:
clobber: clean
rm -f syslogd klogd ksym syslog_tst oops_test TAGS tsyslogd tklogd
+install-replace: syslogd
+ ${INSTALL} -b -m 500 -s syslogd ${BINDIR}/syslogd
+
install_exec: syslogd
- ${INSTALL} -m 500 -s syslogd ${BINDIR}/syslogd
+ cp ${BINDIR}/syslogd ${BINDIR}/syslogd-previous
+ ${INSTALL} -b -m 500 -s syslogd ${BINDIR}/syslogd
# man not yet supported ;)
#install_man:
diff --git a/syslogd.c b/syslogd.c
index 2fd773dd..49a04dbb 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -8,6 +8,7 @@
* - make sure that syslogd handles the case that NO template
* is specified in an action line (hint: keep action type
* to F_UNUSED unless a proper template could be found)
+ * ONLY TO BE DONE FOR MySQL logging, rest is fixed rgerhards 2004-12-02
*
* \brief This is what will become the rsyslogd daemon.
*
@@ -1308,8 +1309,7 @@ int formatTimestamp(struct syslogTime *ts, char* pBuf, size_t iLenBuf)
}
if(ts->timeType == 2) {
- return(snprintf(pBuf, iLenBuf, "NOT YET IMPLEMENTED"));
- /* TODO: Implement! */
+ return(formatTimestamp3339(ts, pBuf, iLenBuf));
}
return(0);
@@ -1575,21 +1575,6 @@ char *getTimeGenerated(struct msg *pM, enum tplFormatTypes eFmt)
return "INVALID eFmt OPTION!";
}
-#if 0
-
-char *getTimeGenerated(struct msg *pM)
-{
- if(pM == NULL)
- return "";
-
- if(pM->pszRcvdAt3164 == NULL) {
- if((pM->pszRcvdAt3164 = malloc(16)) == NULL) return "";
- formatTimestamp3164(&pM->tRcvdAt, pM->pszRcvdAt3164, 16);
- }
-
- return(pM->pszRcvdAt3164);
-}
-#endif
char *getSeverity(struct msg *pM)
{
@@ -1881,9 +1866,60 @@ char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, unsigned short *p
pRes = "**INVALID PROPERTY NAME**";
}
- /* if below very quick and dirty, must be done right.
- * currently, it is only a tester!!!
- * TODO: implement!
+ /* Now check if we need to make "temporary" transformations (these
+ * are transformations that do not go back into the message -
+ * memory must be allocated for them!).
+ */
+
+ /* substring extraction */
+ if(pTpe->data.field.iFromPos != 0 || pTpe->data.field.iToPos != 0) {
+ /* we need to obtain a private copy */
+ int iLen;
+ int iFrom, iTo;
+ char *pBufStart;
+ char *pBuf;
+ iFrom = pTpe->data.field.iFromPos;
+ iTo = pTpe->data.field.iToPos;
+ /* need to zero-base to and from (they are 1-based!) */
+ if(iFrom > 0)
+ --iFrom;
+ if(iTo > 0)
+ --iTo;
+ iLen = iTo - iFrom + 1; /* the +1 is for an actual char, NOT \0! */
+ pBufStart = pBuf = malloc((iLen + 1) * sizeof(char));
+ if(pBuf == NULL) {
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ *pbMustBeFreed = 0;
+ return "**OUT OF MEMORY**";
+ }
+ if(iFrom) {
+ /* skip to the start of the substring (can't do pointer arithmetic
+ * because the whole string might be smaller!!)
+ */
+ // ++iFrom; /* nbr of chars to skip! */
+ while(*pRes && iFrom) {
+ printf("%c", *pRes);
+ --iFrom;
+ ++pRes;
+ }
+ }
+ /* OK, we are at the begin - now let's copy... */
+ while(*pRes && iLen) {
+ printf("%c", *pRes);
+ *pBuf++ = *pRes;
+ ++pRes;
+ --iLen;
+ }
+ *pBuf = '\0';
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ pRes = pBufStart;
+ *pbMustBeFreed = 1;
+ }
+
+ /* case conversations (should go last, because so we are able to
+ * work on the smalles possible buffer).
*/
if(pTpe->data.field.eCaseConv != tplCaseConvNo) {
/* we need to obtain a private copy */
@@ -1891,8 +1927,12 @@ char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, unsigned short *p
char *pBufStart;
char *pBuf;
pBufStart = pBuf = malloc((iLen + 1) * sizeof(char));
- if(pBuf == NULL)
+ if(pBuf == NULL) {
+ if(*pbMustBeFreed == 1)
+ free(pRes);
+ *pbMustBeFreed = 0;
return "**OUT OF MEMORY**";
+ }
while(*pRes) {
*pBuf++ = (pTpe->data.field.eCaseConv == tplCaseConvUpper) ?
toupper(*pRes) : tolower(*pRes);
@@ -1900,11 +1940,13 @@ char *MsgGetProp(struct msg *pMsg, struct templateEntry *pTpe, unsigned short *p
++pRes;
}
*pBuf = '\0';
+ if(*pbMustBeFreed == 1)
+ free(pRes);
pRes = pBufStart;
*pbMustBeFreed = 1;
}
- dprintf("MsgGetProp(\"%s\"): \"%s\"\n", pName, pRes);
+ /*dprintf("MsgGetProp(\"%s\"): \"%s\"\n", pName, pRes); only for verbose debug logging */
return(pRes);
}
@@ -2575,7 +2617,7 @@ void printchopped(hname, msg, len, fd, iSource)
/* Take a raw input line, decode the message, and print the message
* on the appropriate log files.
- * rgerhards 2004-11-08: TODO: change this function with decoder! Please note
+ * rgerhards 2004-11-08: Please note
* that this function does only a partial decoding. At best, it splits
* the PRI part. No further decode happens. The rest is done in
* logmsg(). Please note that printsys() calls logmsg() directly, so
@@ -2630,11 +2672,11 @@ void printline(hname, msg, iSource)
* be replaced.
*/
#if 0 /* TODO: REMOVE THIS LATER */
- q = pMsg->pszMSG;
/* we soon need to support UTF-8, so we will soon need to remove
* this. As a side-note, the current code destroys MBCS messages
* (like Japanese).
*/
+ q = pMsg->pszMSG;
pEnd = pMsg->pszMSG + pMsg->iLenMSG; /* was -4 */
while ((c = *p++) && q < pEnd) {
if (c == '\n')
@@ -2670,29 +2712,6 @@ void printline(hname, msg, iSource)
* to it.
*/
if(MsgSetUxTradMsg(pMsg, p) != 0) return;
-#if 0
- /* Oh, oh... its not that easy, because we also need the UxTradMsg
- * for further parsing. So far, code is disabled, looking for better
- * ideas. I leave it in for now so that I have a reminder item.
- * TODO: fix!
- * rgerhards 2004-11-19
- */
- if(iSource != SOURCE_INET) {
- sbStrBObj *pStrB;
- if((pStrB = sbStrBConstruct()) == NULL) {
- /* oops - no mem, let's try to set the message we have
- * most probably, this will fail, too. But at least we
- * can try... */
- if(MsgSetUxTradMsg(pMsg, p) != 0) return;
- }
- sbStrBAppendStr(pStrB, hname);
- sbStrBAppendChar(pStrB, ' ');
- sbStrBAppendStr(pStrB, p+15);
- MsgAssignUxTradMsg(pMsg, sbStrBFinish(pStrB));
- } else {
- if(MsgSetUxTradMsg(pMsg, p) != 0) return;
- }
-#endif
logmsg(pri, pMsg, SYNC_FILE);
@@ -2987,7 +3006,6 @@ void logmsg(pri, pMsg, flags)
*/
void doSQLEmergencyEscape(register char *p)
{
-printf("In doSQLEmergencyEscape '%s'\n", p);
while(*p) {
if(*p == '\'')
*p = '"';
@@ -3015,7 +3033,6 @@ void doSQLEscape(char **pp, size_t *pLen, unsigned short *pbMustBeFreed)
assert(pLen != NULL);
assert(pbMustBeFreed != NULL);
-printf("In doSQLEscape '%s'\n", *pp);
/* first check if we need to do anything at all... */
for(p = *pp ; *p && *p != '\'' ; ++p)
;
@@ -3131,7 +3148,7 @@ void iovDeleteFreeableStrings(struct filed *f)
for(i = 0 ; i < f->f_iIovUsed ; ++i) {
/* free to-be-freed strings in iovec */
if(*(f->f_bMustBeFreed + i)) {
- printf("DELETE freeable string '%s'\n", (char*)(f->f_iov + i)->iov_base);
+ dprintf("DELETE freeable string '%s'\n", (char*)(f->f_iov + i)->iov_base);
free((f->f_iov + i)->iov_base);
*(f->f_bMustBeFreed) = 0;
}
@@ -4571,7 +4588,6 @@ void cfline(line, f)
/* done, now check if we have a template name
* TODO: we need to handle the case where i >= MAXUNAME!
*/
-printf("USer, type %d\n", f->f_type);
szTemplateName[0] = '\0';
if(*p == ';') {
/* we have a template specifier! */
@@ -4582,7 +4598,6 @@ printf("USer, type %d\n", f->f_type);
if(szTemplateName[0] == '\0')
strcpy(szTemplateName, " StdUsrMsgFmt");
cflineSetTemplateAndIOV(f, szTemplateName);
-printf("OUT USer, type %d\n", f->f_type);
break;
}
return;
diff --git a/template.c b/template.c
index f4f73da5..85829c27 100644
--- a/template.c
+++ b/template.c
@@ -93,7 +93,9 @@ static int do_Constant(char **pp, struct template *pTpl)
if((pStrB = sbStrBConstruct()) == NULL)
return 1;
sbStrBSetAllocIncrement(pStrB, 32);
- /* TODO: implement escape characters! */
+ /* process the message and expand escapes
+ * (additional escapes can be added here if needed)
+ */
while(*p && *p != '%' && *p != '\"') {
if(*p == '\\') {
switch(*++p) {
@@ -143,7 +145,11 @@ static int do_Constant(char **pp, struct template *pTpl)
}
if((pTpe = tpeConstruct(pTpl)) == NULL) {
- /* TODO: add handler */
+ /* OK, we are out of luck. Let's invalidate the
+ * entry and that's it.
+ * TODO: add panic message once we have a mechanism for this
+ */
+ pTpe->eEntryType = UNDEFINED;
return 1;
}
pTpe->eEntryType = CONSTANT;
@@ -219,6 +225,7 @@ static int do_Parameter(char **pp, struct template *pTpl)
char *p;
sbStrBObj *pStrB;
struct templateEntry *pTpe;
+ int iNum; /* to compute numbers */
assert(pp != NULL);
assert(*pp != NULL);
@@ -243,12 +250,17 @@ static int do_Parameter(char **pp, struct template *pTpl)
/* got the name*/
pTpe->data.field.pPropRepl = sbStrBFinish(pStrB);
-
/* check frompos */
if(*p == ':') {
++p; /* eat ':' */
+ iNum = 0;
+ while(isdigit(*p))
+ iNum = iNum * 10 + *p++ - '0';
+ pTpe->data.field.iFromPos = iNum;
+ /* skip to next known good */
while(*p && *p != '%' && *p != ':') {
- /* for now, just skip it */
+ /* TODO: complain on extra characters */
+ dprintf("error: extra character in frompos: '%s'\n", p);
++p;
}
}
@@ -256,12 +268,25 @@ static int do_Parameter(char **pp, struct template *pTpl)
/* check topos */
if(*p == ':') {
++p; /* eat ':' */
+ iNum = 0;
+ while(isdigit(*p))
+ iNum = iNum * 10 + *p++ - '0';
+ pTpe->data.field.iToPos = iNum;
+ /* skip to next known good */
while(*p && *p != '%' && *p != ':') {
- /* for now, just skip it */
+ /* TODO: complain on extra characters */
+ dprintf("error: extra character in frompos: '%s'\n", p);
++p;
}
}
+ /* TODO: add more sanity checks. For now, we do the bare minimum */
+ if(pTpe->data.field.iToPos < pTpe->data.field.iFromPos) {
+ iNum = pTpe->data.field.iToPos;
+ pTpe->data.field.iToPos = pTpe->data.field.iFromPos;
+ pTpe->data.field.iFromPos = iNum;
+ }
+
/* check options */
if(*p == ':') {
++p; /* eat ':' */
@@ -293,7 +318,7 @@ struct template *tplAddLine(char* pName, char** ppRestOfConfLine)
return NULL;
pTpl->iLenName = strlen(pName);
- pTpl->pszName = (char*) malloc(sizeof(char) * pTpl->iLenName);
+ pTpl->pszName = (char*) malloc(sizeof(char) * (pTpl->iLenName + 1));
if(pTpl->pszName == NULL) {
dprintf("tplAddLine could not alloc memory for template name!");
pTpl->iLenName = 0;
@@ -305,20 +330,6 @@ struct template *tplAddLine(char* pName, char** ppRestOfConfLine)
}
memcpy(pTpl->pszName, pName, pTpl->iLenName + 1);
-#if 0
- pTpl->iLenTemplate = strlen(pName);
- pTpl->pszTemplate = (char*) malloc(sizeof(char) * pTpl->iLenTemplate);
- if(pTpl->pszTemplate == NULL) {
- /rintf("could not alloc memory Template"); /* TODO: change to dprintf()! */
- free(pTpl->pszName);
- pTpl->pszName = NULL;
- pTpl->iLenName = 0;
- pTpl->iLenTemplate = 0;
- return NULL;
- /* see note on leak above */
- }
-#endif
-
/* now actually parse the line */
p = *ppRestOfConfLine;
assert(p != NULL);
@@ -327,8 +338,14 @@ struct template *tplAddLine(char* pName, char** ppRestOfConfLine)
++p;
if(*p != '"') {
- dprintf("Template invalid, does not start with '\"'!\n");
- /* TODO: Free mem! */
+ dprintf("Template '%s' invalid, does not start with '\"'!\n", pTpl->pszName);
+ /* we simply make the template defunct in this case by setting
+ * its name to a zero-string. We do not free it, as this would
+ * require additional code and causes only a very small memory
+ * consumption. Memory is freed, however, in normal operation
+ * and most importantly by HUPing syslogd.
+ */
+ *pTpl->pszName = '\0';
return NULL;
}
++p;
@@ -363,7 +380,7 @@ struct template *tplAddLine(char* pName, char** ppRestOfConfLine)
++p;
if(*p != ',')
- return(pTpl);
+ break; /*return(pTpl);*/
++p; /* eat ',' */
while(isspace(*p))/* skip whitespace */
@@ -471,6 +488,12 @@ void tplPrintList(void)
dprintf("[Converted to Upper Case] ");
break;
}
+ if(pTpe->data.field.iFromPos != 0 ||
+ pTpe->data.field.iToPos != 0) {
+ dprintf("[substring, from character %d to %d] ",
+ pTpe->data.field.iFromPos,
+ pTpe->data.field.iToPos);
+ }
break;
}
dprintf("\n");
diff --git a/test.conf b/test.conf
index 16d6de6a..72c58ab8 100644
--- a/test.conf
+++ b/test.conf
@@ -15,6 +15,7 @@
# % = \%
# \ = \\
# --> '\' is used to escape (as in C)
+#$template TraditionalFormat,%timegenerated% %HOSTNAME% %syslogtag%%msg%\n"
$template TraditionalFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg%\n"
$template precise,"%syslogpriority%,%syslogfacility%,%timegenerated%,%HOSTNAME%,%syslogtag%,%msg%\n",1024
$template RFC3164fmt,"<%PRI%>%TIMESTAMP% %HOSTNAME% %syslogtag%%msg%"
@@ -23,6 +24,9 @@ $template usermsg," XXXX%syslogtag%%msg%\n\r"
#$template wallmsg,"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated% ...\r\n %syslogtag%%msg%\n\r"
$template MySQLInsert,"insert iut, message, receivedat values ('%iut%', '%msg:::UPPERCASE%', '%timegenerated:::date-mysql%') into systemevents\r\n", SQL
+# the template below emulates winsyslog format, but we need to check the time
+# stamps used. for now, it is good enough ;)
+$template WinSyslogFmt,"%timegenerated:1:10:date-rfc3339%,%timegenerated:12:19:date-rfc3339%,%timegenerated:1:10:date-rfc3339%,%timegenerated:12:19:date-rfc3339%,%syslogfacility%,%syslogpriority%,%syslogtag%%msg%\n"
#$template wallmsg,"\r\n\7Message from syslogd@%HOSTNAME% at %timegenerated:::date-rfc3339% ...\r\n %syslogtag%%msg%\n\r"
# Selector lines are now modified
@@ -32,10 +36,9 @@ $template MySQLInsert,"insert iut, message, receivedat values ('%iut%', '%msg:::
#authpriv.* /var/log/secure,precise
*.* rger
#*.* *;MySQLInsert
-#*.* /home/rger/proj/rsyslog/logfile;precise
+*.* /home/rger/proj/rsyslog/logfile;WinSyslogFmt
#*.* /home/rger/proj/rsyslog/logfile;UserMsg
#*.* /home/rger/proj/rsyslog/tradfile;TraditionalFormat
-*.* /home/rger/proj/rsyslog/tradfile
#*.* @172.19.2.16;RFC3164fmt
#*.* @172.19.2.16
#*.* >localhost,AdisconDB,root,