summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--obj-types.h30
-rw-r--r--obj.h28
-rwxr-xr-xsrUtils.c33
-rwxr-xr-xsrUtils.h4
-rw-r--r--stream.c49
-rw-r--r--stream.h5
7 files changed, 118 insertions, 33 deletions
diff --git a/Makefile.am b/Makefile.am
index 2cad2365..094a39f1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,7 @@ rfc3195d_SOURCES = rfc3195d.c rsyslog.h
rsyslogd_SOURCES = \
syslogd.c \
syslogd.h \
+ glbl.h \
pidfile.c \
pidfile.h \
template.c \
@@ -31,6 +32,7 @@ rsyslogd_SOURCES = \
net.h \
obj.c \
obj.h \
+ obj-types.h \
msg.c \
msg.h \
expr.c \
diff --git a/obj-types.h b/obj-types.h
index 005d6a4d..6da56db0 100644
--- a/obj-types.h
+++ b/obj-types.h
@@ -113,5 +113,35 @@ finalize_it: \
return iRet; \
}
+/* this defines both the constructor and initializer
+ * rgerhards, 2008-01-10
+ */
+#define BEGINobjConstruct(obj) \
+ rsRetVal obj##Initialize(obj##_t *pThis) \
+ { \
+ DEFiRet;
+
+#define ENDobjConstruct(obj) \
+ /* use finalize_it: before calling the macro (if you need it)! */ \
+ return iRet; \
+ } \
+ rsRetVal obj##Construct(obj##_t **ppThis) \
+ { \
+ DEFiRet; \
+ obj##_t *pThis; \
+ \
+ assert(ppThis != NULL); \
+ \
+ if((pThis = (obj##_t *)calloc(1, sizeof(obj##_t))) == NULL) { \
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); \
+ } \
+ \
+ obj##Initialize(pThis); \
+ \
+ finalize_it: \
+ OBJCONSTRUCT_CHECK_SUCCESS_AND_CLEANUP \
+ return iRet; \
+ }
+
#endif /* #ifndef OBJ_TYPES_H_INCLUDED */
diff --git a/obj.h b/obj.h
index 7a5b07f1..ab9470ac 100644
--- a/obj.h
+++ b/obj.h
@@ -47,6 +47,34 @@
#include "obj-types.h"
#include "stream.h"
+/* macros */
+/* the following one is a helper that prevents us from writing the
+ * ever-same code at the end of Construct()
+ */
+#define OBJCONSTRUCT_CHECK_SUCCESS_AND_CLEANUP \
+ if(iRet == RS_RET_OK) { \
+ *ppThis = pThis; \
+ } else { \
+ if(pThis != NULL) \
+ free(pThis); \
+ }
+
+#define objSerializeSCALAR(propName, propType) \
+ CHKiRet(objSerializeProp(pCStr, (uchar*) #propName, PROPTYPE_##propType, (void*) &pThis->propName));
+#define objSerializePTR(propName, propType) \
+ CHKiRet(objSerializeProp(pCStr, (uchar*) #propName, PROPTYPE_##propType, (void*) pThis->propName));
+#define DEFobjStaticHelpers static objInfo_t *pObjInfoOBJ = NULL;
+#define objGetName(pThis) (((obj_t*) (pThis))->pObjInfo->pszName)
+#define objGetObjID(pThis) (((obj_t*) (pThis))->pObjInfo->objID)
+#define objGetVersion(pThis) (((obj_t*) (pThis))->pObjInfo->iObjVers)
+/* must be called in Constructor: */
+#define objConstructSetObjInfo(pThis) ((obj_t*) (pThis))->pObjInfo = pObjInfoOBJ;
+#define objDestruct(pThis) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_DESTRUCT])(pThis)
+#define objSerialize(pThis) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_SERIALIZE])
+
+#define OBJSetMethodHandler(methodID, pHdlr) \
+ CHKiRet(objInfoSetMethod(pObjInfoOBJ, methodID, (rsRetVal (*)(void*)) pHdlr))
+
/* prototypes */
rsRetVal objInfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, int iObjVers, rsRetVal (*pConstruct)(void *), rsRetVal (*pDestruct)(void *));
rsRetVal objInfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void*));
diff --git a/srUtils.c b/srUtils.c
index fc0869be..4e363e79 100755
--- a/srUtils.c
+++ b/srUtils.c
@@ -243,25 +243,35 @@ void skipWhiteSpace(uchar **pp)
* <directory name>/<name>.<number>
* If number is negative, it is not used. If any of the strings is
* NULL, an empty string is used instead. Length must be provided.
+ * lNumDigits is the minimum number of digits that lNum should have. This
+ * is to pretty-print the file name, e.g. lNum = 3, lNumDigits= 4 will
+ * result in "0003" being used inside the file name. Set lNumDigits to 0
+ * to use as few space as possible.
* rgerhards, 2008-01-03
*/
-rsRetVal genFileName(uchar **ppName, uchar *pDirName, size_t lenDirName, uchar *pFName, size_t lenFName, long lNum)
+rsRetVal genFileName(uchar **ppName, uchar *pDirName, size_t lenDirName, uchar *pFName,
+ size_t lenFName, long lNum, int lNumDigits)
{
DEFiRet;
uchar *pName;
uchar *pNameWork;
size_t lenName;
uchar szBuf[128]; /* buffer for number */
+ char szFmtBuf[32]; /* buffer for snprintf format */
size_t lenBuf;
if(lNum < 0) {
szBuf[0] = '\0';
lenBuf = 0;
} else {
- lenBuf = snprintf((char*)szBuf, sizeof(szBuf), ".%ld", lNum);
+ if(lNumDigits > 0) {
+ snprintf(szFmtBuf, sizeof(szFmtBuf), ".%%0%dld", lNumDigits);
+ lenBuf = snprintf((char*)szBuf, sizeof(szBuf), szFmtBuf, lNum);
+ } else
+ lenBuf = snprintf((char*)szBuf, sizeof(szBuf), ".%ld", lNum);
}
- lenName = lenDirName + 1 + lenName + lenBuf + 1; /* last +1 for \0 char! */
+ lenName = lenDirName + 1 + lenFName + lenBuf + 1; /* last +1 for \0 char! */
if((pName = malloc(sizeof(uchar) * lenName)) == NULL)
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
@@ -283,6 +293,23 @@ finalize_it:
return iRet;
}
+/* get the number of digits required to represent a given number. We use an
+ * iterative approach as we do not like to draw in the floating point
+ * library just for log(). -- rgerhards, 2008-01-10
+ */
+int getNumberDigits(long lNum)
+{
+ int iDig;
+
+ if(lNum == 0)
+ iDig = 1;
+ else
+ for(iDig = 0 ; lNum != 0 ; ++iDig)
+ lNum /= 10;
+
+ return iDig;
+}
+
/*
* vi:set ai:
diff --git a/srUtils.h b/srUtils.h
index e7912907..ec18e1a5 100755
--- a/srUtils.h
+++ b/srUtils.h
@@ -64,5 +64,7 @@ int makeFileParentDirs(uchar *szFile, size_t lenFile, mode_t mode, uid_t uid, gi
int execProg(uchar *program, int wait, uchar *arg);
void skipWhiteSpace(uchar **pp);
-rsRetVal genFileName(uchar **ppName, uchar *pDirName, size_t lenDirName, uchar *pName, size_t lenName, long lNum);
+rsRetVal genFileName(uchar **ppName, uchar *pDirName, size_t lenDirName, uchar *pFName,
+ size_t lenFName, long lNum, int lNumDigits);
+int getNumberDigits(long lNum);
#endif
diff --git a/stream.c b/stream.c
index b8a85463..03431439 100644
--- a/stream.c
+++ b/stream.c
@@ -72,8 +72,14 @@ rsRetVal strmOpenFile(strm_t *pThis, int flags, mode_t mode)
if(pThis->pszFilePrefix == NULL)
ABORT_FINALIZE(RS_RET_FILE_PREFIX_MISSING);
+ if(pThis->pIOBuf == NULL) { /* allocate our io buffer in case we have not yet */
+ if((pThis->pIOBuf = (uchar*) malloc(sizeof(uchar) * pThis->sIOBufSize)) == NULL)
+ ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ pThis->iBufPtrMax = 0; /* results in immediate read request */
+ }
+
CHKiRet(genFileName(&pThis->pszCurrFName, pThis->pszDir, pThis->lenDir,
- pThis->pszFilePrefix, pThis->lenFilePrefix, pThis->iCurrFNum));
+ pThis->pszFilePrefix, pThis->lenFilePrefix, pThis->iCurrFNum, pThis->iFileNumDigits));
pThis->fd = open((char*)pThis->pszCurrFName, flags, mode); // TODO: open modes!
pThis->iCurrOffs = 0;
@@ -155,12 +161,6 @@ rsRetVal strmReadChar(strm_t *pThis, uchar *pC)
assert(pC != NULL);
/* DEV debug only: dbgprintf("strmRead index %d, max %d\n", pThis->iBufPtr, pThis->iBufPtrMax); */
- if(pThis->pIOBuf == NULL) { /* TODO: maybe we should move that to file open... */
- if((pThis->pIOBuf = (uchar*) malloc(sizeof(uchar) * STRM_IOBUF_SIZE )) == NULL)
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- pThis->iBufPtrMax = 0; /* results in immediate read request */
- }
-
if(pThis->iUngetC != -1) { /* do we have an "unread" char that we need to provide? */
*pC = pThis->iUngetC;
pThis->iUngetC = -1;
@@ -174,7 +174,7 @@ rsRetVal strmReadChar(strm_t *pThis, uchar *pC)
while(bRun) {
/* first check if we need to (re)open the file (we may have switched to a new one!) */
CHKiRet(strmOpenFile(pThis, O_RDONLY, 0600)); // TODO: open modes!
- pThis->iBufPtrMax = read(pThis->fd, pThis->pIOBuf, STRM_IOBUF_SIZE);
+ pThis->iBufPtrMax = read(pThis->fd, pThis->pIOBuf, pThis->sIOBufSize);
dbgprintf("strmReadChar read %d bytes from file %d\n", pThis->iBufPtrMax, pThis->fd);
if(pThis->iBufPtrMax == 0) {
if(pThis->iMaxFiles == 0)
@@ -261,30 +261,15 @@ finalize_it:
/* --------------- end type-specific handlers -------------------- */
-/* Constructor for the strm object
+/* Standard-Constructor for the strm object
*/
-rsRetVal strmConstruct(strm_t **ppThis)
-{
- DEFiRet;
- strm_t *pThis;
-dbgprintf("strmConstruct\n");
-
- assert(ppThis != NULL);
-
- if((pThis = (strm_t *)calloc(1, sizeof(strm_t))) == NULL) {
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- }
-
- /* we have an object, so let's fill all properties that must not be 0 (we did calloc()!) */
+BEGINobjConstruct(strm)
pThis->iCurrFNum = 1;
pThis->fd = -1;
pThis->iUngetC = -1;
pThis->sType = STREAMTYPE_FILE;
-
-finalize_it:
- OBJCONSTRUCT_CHECK_SUCCESS_AND_CLEANUP
- return iRet;
-}
+ pThis->sIOBufSize = glblGetIOBufSize();
+ENDobjConstruct(strm)
/* ConstructionFinalizer - currently provided just to comply to the interface
@@ -352,7 +337,15 @@ finalize_it:
/* simple ones first */
DEFpropSetMeth(strm, bDeleteOnClose, int)
DEFpropSetMeth(strm, iMaxFileSize, int)
-DEFpropSetMeth(strm, iMaxFiles, int)
+DEFpropSetMeth(strm, iFileNumDigits, int)
+
+rsRetVal strmSetiMaxFiles(strm_t *pThis, int iNewVal)
+{
+ pThis->iMaxFiles = iNewVal;
+ pThis->iFileNumDigits = getNumberDigits(iNewVal);
+ return RS_RET_OK;
+}
+
/* set the stream's file prefix
* The passed-in string is duplicated. So if the caller does not need
diff --git a/stream.h b/stream.h
index f31be44e..1c6ad44a 100644
--- a/stream.h
+++ b/stream.h
@@ -44,6 +44,7 @@
#include <pthread.h>
#include "obj-types.h"
+#include "glbl.h"
#include "stream.h"
/* stream types */
@@ -72,8 +73,9 @@ typedef struct strm_s {
size_t iMaxFileSize;/* maximum size a file may grow to */
int bDeleteOnClose; /* set to 1 to auto-delete on close -- be careful with that setting! */
int iMaxFiles; /* maximum number of files if a circular mode is in use */
+ int iFileNumDigits;/* min number of digits to use in file number (only in circular mode) */
+ size_t sIOBufSize;/* size of IO buffer */
} strm_t;
-#define STRM_IOBUF_SIZE 4096 /* size of the IO buffer */
/* prototypes */
rsRetVal strmConstruct(strm_t **ppThis);
@@ -92,5 +94,6 @@ PROTOTYPEObjClassInit(strm);
PROTOTYPEpropSetMeth(strm, bDeleteOnClose, int);
PROTOTYPEpropSetMeth(strm, iMaxFileSize, int);
PROTOTYPEpropSetMeth(strm, iMaxFiles, int);
+PROTOTYPEpropSetMeth(strm, iFileNumDigits, int);
#endif /* #ifndef STREAM_H_INCLUDED */