diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2007-07-26 12:47:09 +0000 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2007-07-26 12:47:09 +0000 |
commit | 6e2c5057684a191c565220e6e41e561305b3a6ba (patch) | |
tree | 59ebc9ca6e9952db513c9f65bc39a2a4c5ff239e | |
parent | 54669873b0469aa69a4c9f88bcf88470218082f8 (diff) | |
download | rsyslog-6e2c5057684a191c565220e6e41e561305b3a6ba.tar.gz rsyslog-6e2c5057684a191c565220e6e41e561305b3a6ba.tar.xz rsyslog-6e2c5057684a191c565220e6e41e561305b3a6ba.zip |
- changed doAction() interface to contain the full message string
- f_iov and its handling has been removed
-rw-r--r-- | module-template.h | 5 | ||||
-rw-r--r-- | modules.h | 2 | ||||
-rw-r--r-- | omfile.c | 7 | ||||
-rw-r--r-- | omfwd.c | 6 | ||||
-rw-r--r-- | ommysql.c | 9 | ||||
-rw-r--r-- | omshell.c | 5 | ||||
-rw-r--r-- | omusrmsg.c | 9 | ||||
-rw-r--r-- | syslogd-types.h | 5 | ||||
-rw-r--r-- | syslogd.c | 193 |
9 files changed, 28 insertions, 213 deletions
diff --git a/module-template.h b/module-template.h index c8f1e79e..2d34893e 100644 --- a/module-template.h +++ b/module-template.h @@ -89,12 +89,13 @@ static rsRetVal isCompatibleWithFeature(syslogFeature __attribute__((unused)) eF /* doAction() */ #define BEGINdoAction \ -static rsRetVal doAction(selector_t *f, instanceData __attribute__((unused)) *pData)\ +static rsRetVal doAction(selector_t *f, uchar __attribute__((unused)) *pMsg, instanceData __attribute__((unused)) *pData)\ {\ rsRetVal iRet = RS_RET_OK; #define CODESTARTdoAction \ - assert(f != NULL); + assert(f != NULL);\ + assert(pMsg != NULL); #define ENDdoAction \ return iRet;\ @@ -77,7 +77,7 @@ typedef struct moduleInfo { struct {/* data for output modules */ /* below: perform the configured action */ - rsRetVal (*doAction)(); + rsRetVal (*doAction)(selector_t*, uchar*, void*); rsRetVal (*parseSelectorAct)(uchar**, selector_t*, void**); } om; } mod; @@ -467,7 +467,7 @@ static int prepareDynFile(selector_t *f, instanceData *pData) * will be called for all outputs using file semantics, * for example also for pipes. */ -static rsRetVal writeFile(selector_t *f, instanceData *pData) +static rsRetVal writeFile(selector_t *f, uchar *pMsg, instanceData *pData) { off_t actualFileSize; rsRetVal iRet = RS_RET_OK; @@ -484,7 +484,6 @@ static rsRetVal writeFile(selector_t *f, instanceData *pData) } /* create the message based on format specified */ - iovCreate(f); again: /* check if we have a file size limit and, if so, * obey to it. @@ -517,7 +516,7 @@ again: } } - if (writev(pData->fd, f->f_iov, f->f_iIovUsed) < 0) { + if (write(pData->fd, pMsg, strlen((char*)pMsg)) < 0) { int e = errno; /* If a named pipe is full, just ignore it for now @@ -599,7 +598,7 @@ CODESTARTdoAction * all others are doomed. */ if(pData->bDynamicName || (pData->fd != -1)) - iRet = writeFile(f, pData); + iRet = writeFile(f, pMsg, pData); ENDdoAction @@ -523,6 +523,7 @@ static char *getFwdSyslogPt(instanceData *pData) return(pData->port); } + BEGINdoAction char *psz; /* temporary buffering */ register unsigned l; @@ -597,13 +598,12 @@ CODESTARTdoAction f_forw: dprintf(" %s:%s/%s\n", pData->f_hname, getFwdSyslogPt(pData), pData->protocol == FORW_UDP ? "udp" : "tcp"); - iovCreate(f); if ( strcmp(getHOSTNAME(f->f_pMsg), LocalHostName) && NoHops ) dprintf("Not sending message to remote.\n"); else { pData->ttSuspend = time(NULL); - psz = iovAsString(f); - l = f->f_iLenpsziov; + psz = (char*) pMsg; + l = strlen((char*) psz); if (l > MAXLINE) l = MAXLINE; @@ -286,16 +286,13 @@ static rsRetVal reInitMySQL(instanceData *pData) * to an established MySQL session. * Initially added 2004-10-28 mmeckelein */ -rsRetVal writeMySQL(register selector_t *f, instanceData *pData) +rsRetVal writeMySQL(register selector_t *f, uchar *psz, instanceData *pData) { - char *psz; int iCounter=0; rsRetVal iRet = RS_RET_OK; assert(f != NULL); assert(pData != NULL); - iovCreate(f); - psz = iovAsString(f); if((iRet = checkDBErrorState(pData)) != RS_RET_OK) return iRet; @@ -306,7 +303,7 @@ rsRetVal writeMySQL(register selector_t *f, instanceData *pData) */ do { /* query */ - if(mysql_query(pData->f_hmysql, psz)) { + if(mysql_query(pData->f_hmysql, (char*)psz)) { /* if the second attempt fails we call the error handler */ if(iCounter) @@ -324,7 +321,7 @@ rsRetVal writeMySQL(register selector_t *f, instanceData *pData) BEGINdoAction CODESTARTdoAction dprintf("\n"); - iRet = writeMySQL(f, pData); + iRet = writeMySQL(f, pMsg, pData); ENDdoAction @@ -75,16 +75,13 @@ ENDdbgPrintInstInfo BEGINdoAction - uchar *psz; CODESTARTdoAction /* TODO: using pData->progName is not clean from the point of * modularization. We'll change that as we go ahead with modularization. * rgerhards, 2007-07-20 */ dprintf("\n"); - iovCreate(f); - psz = (uchar*) iovAsString(f); - if(execProg((uchar*) pData->progName, 1, (uchar*) psz) == 0) + if(execProg((uchar*) pData->progName, 1, pMsg) == 0) logerrorSz("Executing program '%s' failed", (char*)pData->progName); ENDdoAction @@ -147,7 +147,7 @@ void endutent(void) * Adjust the size of a variable to prevent a buffer overflow * should _PATH_DEV ever contain something different than "/dev/". */ -static void wallmsg(selector_t *f, instanceData *pData) +static void wallmsg(selector_t *f, uchar* pMsg, instanceData *pData) { char p[sizeof(_PATH_DEV) + UNAMESZ]; @@ -158,12 +158,11 @@ static void wallmsg(selector_t *f, instanceData *pData) struct utmp *uptr; assert(f != NULL); + assert(pMsg != NULL); if (reenter++) return; - iovCreate(f); /* init the iovec */ - /* open the user login file */ setutent(); @@ -228,7 +227,7 @@ static void wallmsg(selector_t *f, instanceData *pData) if (fstat(ttyf, &statb) == 0 && (statb.st_mode & S_IWRITE)) { - (void) writev(ttyf, f->f_iov, f->f_iIovUsed); + (void) write(ttyf, pMsg, strlen((char*)pMsg)); } close(ttyf); ttyf = -1; @@ -248,7 +247,7 @@ BEGINdoAction CODESTARTdoAction dprintf("\n"); /* TODO: change wallmsg so that it returns iRet */ - wallmsg(f, pData); + wallmsg(f, pMsg, pData); ENDdoAction diff --git a/syslogd-types.h b/syslogd-types.h index f986cb33..5e4d262a 100644 --- a/syslogd-types.h +++ b/syslogd-types.h @@ -159,11 +159,6 @@ struct filed { int f_prevcount; /* repetition cnt of prevline */ int f_repeatcount; /* number of "repeated" msgs */ struct template *f_pTpl; /* pointer to template to use */ - struct iovec *f_iov; /* dyn allocated depinding on template */ - unsigned short *f_bMustBeFreed; /* indicator, if iov_base must be freed to destruct */ - int f_iIovUsed; /* nbr of elements used in IOV */ - char *f_psziov; /* iov as string */ - int f_iLenpsziov; /* length of iov as string */ struct msg* f_pMsg; /* pointer to the message (this will * replace the other vars with msg * content later). This is preserved after @@ -3047,162 +3047,6 @@ void logmsg(int pri, msg_t *pMsg, int flags) } - -/* create a string from the provided iovec. This can - * be called by all functions who need the template - * text in a single string. The function takes an - * entry of the filed structure. It uses all data - * from there. It returns a pointer to the generated - * string if it succeeded, or NULL otherwise. - * rgerhards 2004-11-22 - */ -char *iovAsString(selector_t *f) -{ - struct iovec *v; - int i; - rsCStrObj *pStrB; - - assert(f != NULL); - - if(f->f_psziov != NULL) { - /* for now, we always free a previous buffer. - * The idea, however, is to keep a copy of the - * buffer until we know we no longer can re-use it. - */ - free(f->f_psziov); - } - - if((pStrB = rsCStrConstruct()) == 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... */ - return NULL; - } - - i = 0; - f->f_iLenpsziov = 0; - v = f->f_iov; - while(i++ < f->f_iIovUsed) { - if(v->iov_len > 0) { - if(rsCStrAppendStr(pStrB, v->iov_base) != RS_RET_OK) { - /* most probably out of memory... */ - rsCStrDestruct(pStrB); - return NULL; - } - f->f_iLenpsziov += v->iov_len; - } - ++v; - } - - rsCStrFinish(pStrB); - f->f_psziov = (char*) rsCStrConvSzStrAndDestruct(pStrB); - return f->f_psziov; -} - - -/* rgerhards 2004-11-24: free the to-be-freed string in - * iovec. Some strings point to read-only constants in the - * msg object, these must not be taken care of. But some - * are specifically created for this instance and those - * must be freed before the next is created. This is done - * here. After this method has been called, the iovec - * string array is invalid and must either be totally - * discarded or e-initialized! - */ -void iovDeleteFreeableStrings(selector_t *f) -{ - register int i; - - assert(f != NULL); - - for(i = 0 ; i < f->f_iIovUsed ; ++i) { - /* free to-be-freed strings in iovec */ - if(*(f->f_bMustBeFreed + i)) { - free((f->f_iov + i)->iov_base); - *(f->f_bMustBeFreed) = 0; - } - } -} - - -/* rgerhards 2004-11-19: create the iovec for - * a given message. This is called by all methods - * using iovec's for their output. Returns the number - * of iovecs used (might be different from max if the - * template contains an invalid entry). - */ -void iovCreate(selector_t *f) -{ - register struct iovec *v; - int iIOVused; - struct template *pTpl; - struct templateEntry *pTpe; - msg_t *pMsg; - char *pVal; /* This variable must be introduced to keep with strict aliasing rules */ - size_t iLenVal; /* This variable must be introduced to keep with strict aliasing rules */ - - assert(f != NULL); - - /* discard previous memory buffers */ - iovDeleteFreeableStrings(f); - - pMsg = f->f_pMsg; - pTpl = f->f_pTpl; - v = f->f_iov; - - iIOVused = 0; - pTpe = pTpl->pEntryRoot; - while(pTpe != NULL) { - if(pTpe->eEntryType == CONSTANT) { - v->iov_base = pTpe->data.constant.pConstant; - v->iov_len = pTpe->data.constant.iLenConstant; - ++v; - ++iIOVused; - } else if(pTpe->eEntryType == FIELD) { - /* Just for the records and because I needed some time to look it up again: - * f->f_bMustBeFreed + iIOVused is a pointer to the "must be freed" indicator - * for the entry in question. So, yes, we are passing in a pointer and it gets - * updated by the called procedures. The address of operator (&) must NOT be used - * because it already is a pointer. Actually, f->f_bMustBeFreed is the base address - * of an array of unsigned shorts. This array is allocated when the configuration - * file is read. rgerhards, 2007-06-26 - */ - pVal = MsgGetProp(pMsg, pTpe, NULL, f->f_bMustBeFreed + iIOVused); - iLenVal = strlen(pVal); - /* we now need to check if we should use SQL option. In this case, - * we must go over the generated string and escape '\'' characters. - * rgerhards, 2005-09-22: the option values below look somewhat misplaced, - * but they are handled in this way because of legacy (don't break any - * existing thing). - */ - if(f->f_pTpl->optFormatForSQL == 1) - doSQLEscape(&pVal, &iLenVal, f->f_bMustBeFreed + iIOVused, 1); - else if(f->f_pTpl->optFormatForSQL == 2) - doSQLEscape(&pVal, &iLenVal, f->f_bMustBeFreed + iIOVused, 0); - v->iov_base = pVal; - v->iov_len = iLenVal; - ++v; - ++iIOVused; - } - pTpe = pTpe->pNext; - } - - f->f_iIovUsed = iIOVused; - -#if 0 /* debug aid */ -{ - int i; - v = f->f_iov; - for(i = 0 ; i < iIOVused ; ++i, ++v) { - printf("iovCreate(%d), string '%s', mustbeFreed %d\n", i, - v->iov_base, *(f->f_bMustBeFreed + i)); - } -} -#endif /* debug aid */ - return; -} - - /* rgerhards 2004-11-09: fprintlog() is the actual driver for * the output channel. It receives the channel description (f) as * well as the message and outputs them according to the channel @@ -3216,6 +3060,7 @@ rsRetVal fprintlog(register selector_t *f) msg_t *pMsgSave; /* to save current message pointer, necessary to restore it in case it needs to be updated (e.g. repeated msgs) */ pMsgSave = NULL; /* indicate message poiner not saved */ + uchar *pszMsg; rsRetVal iRet = RS_RET_OK; /* first check if this is a regular message or the repeation of @@ -3258,7 +3103,15 @@ rsRetVal fprintlog(register selector_t *f) /* When we reach this point, we have a valid, non-disabled action. * So let's execute it. -- rgerhards, 2007-07-24 */ - iRet = f->pMod->mod.om.doAction(f, f->pModData); /* call configured action */ + if((pszMsg = tplToString(f->f_pTpl, f->f_pMsg)) == NULL) { + dprintf("memory alloc failed while generating message string - message ignored\n"); + glblHadMemShortage = 1; + iRet = RS_RET_OUT_OF_MEMORY; + } else { + iRet = f->pMod->mod.om.doAction(f, pszMsg, f->pModData); /* call configured action */ + free(pszMsg); + } + if(iRet == RS_RET_DISABLE_ACTION) f->bEnabled = 0; /* that's it... */ @@ -4045,19 +3898,6 @@ static void freeSelectors(void) /* free the action instances */ f->pMod->freeInstance(f, f->pModData); - /* free iovec if it was allocated */ - if(f->f_iov != NULL) { - if(f->f_bMustBeFreed != NULL) { - iovDeleteFreeableStrings(f); - free(f->f_bMustBeFreed); - } - free(f->f_iov); - } - - /* free iov string */ - if (f->f_psziov != NULL) - free(f->f_psziov); - if(f->f_pMsg != NULL) MsgDestruct(f->f_pMsg); /* done with this entry, we now need to delete itself */ @@ -4424,19 +4264,6 @@ rsRetVal cflineSetTemplateAndIOV(selector_t *f, char *pTemplateName) errno = 0; logerror(errMsg); iRet = RS_RET_NOT_FOUND; - } else { - if((f->f_iov = calloc(tplGetEntryCount(f->f_pTpl), - sizeof(struct iovec))) == NULL) { - errno = 0; - logerror("Could not allocate iovec memory - 1 selector line disabled\n"); - iRet = RS_RET_ERR; - } - if((f->f_bMustBeFreed = calloc(tplGetEntryCount(f->f_pTpl), - sizeof(unsigned short))) == NULL) { - errno = 0; - logerror("Could not allocate bMustBeFreed memory - 1 selector line disabled\n"); - iRet = RS_RET_ERR; - } } return iRet; } |