From 19b8d9e239f150127d8af15694f88c20ed88bd25 Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Fri, 11 Jan 2008 15:15:08 +0000 Subject: added function to de-serialize a property bag (untested as other code is yet missing) --- obj-types.h | 4 +-- obj.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++------------ obj.h | 1 + queue.c | 2 -- rsyslog.h | 1 + 5 files changed, 84 insertions(+), 23 deletions(-) diff --git a/obj-types.h b/obj-types.h index e712f5fd..e3f33a4c 100644 --- a/obj-types.h +++ b/obj-types.h @@ -58,9 +58,9 @@ typedef enum { /* IDs of known object "types/classes" */ OBJNull = 0, /* no valid object (we do not start at zero so we can detect calloc()) */ OBJMsg = 1, OBJstrm = 2, - OBJqueue = 3 + OBJqueue = 3 /* remeber to UPDATE OBJ_NUM_IDS (below) if you add one! */ } objID_t; -#define OBJ_NUM_IDS 3 +#define OBJ_NUM_IDS 4 typedef enum { /* IDs of base methods supported by all objects - used for jump table, so * they must start at zero and be incremented. -- rgerahrds, 2008-01-04 diff --git a/obj.c b/obj.c index 5f5adc8c..e345a5d8 100644 --- a/obj.c +++ b/obj.c @@ -407,7 +407,7 @@ finalize_it: /* de-serialize an object header * rgerhards, 2008-01-07 */ -static rsRetVal objDeserializeHeader(objID_t *poID, int* poVers, strm_t *pStrm) +static rsRetVal objDeserializeHeader(uchar *pszRecType, objID_t *poID, int* poVers, strm_t *pStrm) { DEFiRet; long ioID; @@ -416,12 +416,13 @@ static rsRetVal objDeserializeHeader(objID_t *poID, int* poVers, strm_t *pStrm) assert(poID != NULL); assert(poVers != NULL); + assert(!strcmp((char*) pszRecType, "Obj") || !strcmp((char*) pszRecType, "OPB")); /* check header cookie */ NEXTC; if(c != COOKIE_OBJLINE) ABORT_FINALIZE(RS_RET_INVALID_HEADER); - NEXTC; if(c != 'O') ABORT_FINALIZE(RS_RET_INVALID_HEADER); - NEXTC; if(c != 'b') ABORT_FINALIZE(RS_RET_INVALID_HEADER); - NEXTC; if(c != 'j') ABORT_FINALIZE(RS_RET_INVALID_HEADER); + NEXTC; if(c != pszRecType[0]) ABORT_FINALIZE(RS_RET_INVALID_HEADER_RECTYPE); + NEXTC; if(c != pszRecType[1]) ABORT_FINALIZE(RS_RET_INVALID_HEADER_RECTYPE); + NEXTC; if(c != pszRecType[2]) ABORT_FINALIZE(RS_RET_INVALID_HEADER_RECTYPE); NEXTC; if(c != ':') ABORT_FINALIZE(RS_RET_INVALID_HEADER); NEXTC; if(c != '1') ABORT_FINALIZE(RS_RET_INVALID_HEADER_VERS); NEXTC; if(c != ':') ABORT_FINALIZE(RS_RET_INVALID_HEADER_VERS); @@ -581,11 +582,38 @@ finalize_it: } +/* De-serialize the properties of an object. This includes processing + * of the trailer. Header must already have been processed. + * rgerhards, 2008-01-11 + */ +rsRetVal objDeserializeProperties(obj_t *pObj, objID_t oID, strm_t *pStrm) +{ + DEFiRet; + property_t propBuf; + + ISOBJ_assert(pObj); + ISOBJ_TYPE_assert(pStrm, strm); + + iRet = objDeserializeProperty(&propBuf, pStrm); + while(iRet == RS_RET_OK) { + CHKiRet(arrObjInfo[oID]->objMethods[objMethod_SETPROPERTY](pObj, &propBuf)); + iRet = objDeserializeProperty(&propBuf, pStrm); + } + rsCStrDestruct(propBuf.pcsName); /* todo: a destructor would be nice here... -- rger, 2008-01-07 */ + // TODO: do we have a mem leak for the other CStr in this struct? + + if(iRet != RS_RET_NO_PROPLINE) + FINALIZE; + + CHKiRet(objDeserializeTrailer(pStrm)); /* do trailer checks */ +finalize_it: + return iRet; +} + + /* De-Serialize an object. * Params: Pointer to object Pointer (pObj) (like a obj_t**, but can not do that due to compiler warning) * expected object ID (to check against) - * Function that returns the next character from the serialized object (from file, memory, whatever) - * Pointer to be passed to the function * The caller must destruct the created object. * rgerhards, 2008-01-07 */ @@ -594,7 +622,6 @@ rsRetVal objDeserialize(void *ppObj, objID_t objTypeExpected, strm_t *pStrm) DEFiRet; rsRetVal iRetLocal; obj_t *pObj = NULL; - property_t propBuf; objID_t oID = 0; /* this assignment is just to supress a compiler warning - this saddens me */ int oVers = 0; /* after all, it is totally useless but takes up some execution time... */ @@ -610,7 +637,7 @@ rsRetVal objDeserialize(void *ppObj, objID_t objTypeExpected, strm_t *pStrm) * rgerhards, 2008-07-08 */ do { - iRetLocal = objDeserializeHeader(&oID, &oVers, pStrm); + iRetLocal = objDeserializeHeader((uchar*) "Obj", &oID, &oVers, pStrm); if(iRetLocal != RS_RET_OK) { dbgprintf("objDeserialize error %d during header processing - trying to recover\n", iRetLocal); CHKiRet(objDeserializeTryRecover(pStrm)); @@ -622,17 +649,7 @@ rsRetVal objDeserialize(void *ppObj, objID_t objTypeExpected, strm_t *pStrm) CHKiRet(arrObjInfo[oID]->objMethods[objMethod_CONSTRUCT](&pObj)); /* we got the object, now we need to fill the properties */ - iRet = objDeserializeProperty(&propBuf, pStrm); - while(iRet == RS_RET_OK) { - CHKiRet(arrObjInfo[oID]->objMethods[objMethod_SETPROPERTY](pObj, &propBuf)); - iRet = objDeserializeProperty(&propBuf, pStrm); - } - rsCStrDestruct(propBuf.pcsName); /* todo: a destructor would be nice here... -- rger, 2008-01-07 */ - - if(iRet != RS_RET_NO_PROPLINE) - FINALIZE; - - CHKiRet(objDeserializeTrailer(pStrm)); /* do trailer checks */ + CHKiRet(objDeserializeProperties(pObj, oID, pStrm)); /* we have a valid object, let's finalize our work and return */ if(objInfoIsImplemented(arrObjInfo[oID], objMethod_CONSTRUCTION_FINALIZER)) @@ -644,6 +661,50 @@ finalize_it: return iRet; } + +/* De-Serialize an object property bag. As a property bag contains only partial properties, + * it is not instanciable. Thus, the caller must provide a pointer of an already-instanciated + * object of the correct type. + * Params: Pointer to object (pObj) + * Pointer to be passed to the function + * The caller must destruct the created object. + * rgerhards, 2008-01-07 + */ +rsRetVal objDeserializePropBag(obj_t *pObj, strm_t *pStrm) +{ + DEFiRet; + rsRetVal iRetLocal; + objID_t oID = 0; /* this assignment is just to supress a compiler warning - this saddens me */ + int oVers = 0; /* after all, it is totally useless but takes up some execution time... */ + + ISOBJ_assert(pObj); + ISOBJ_TYPE_assert(pStrm, strm); + + /* we de-serialize the header. if all goes well, we are happy. However, if + * we experience a problem, we try to recover. We do this by skipping to + * the next object header. This is defined via the line-start cookies. In + * worst case, we exhaust the queue, but then we receive EOF return state + * from objDeserializeTryRecover(), what will cause us to ultimately give up. + * rgerhards, 2008-07-08 + */ + do { + iRetLocal = objDeserializeHeader((uchar*) "OPB", &oID, &oVers, pStrm); + if(iRetLocal != RS_RET_OK) { + dbgprintf("objDeserializePropBag error %d during header - trying to recover\n", iRetLocal); + CHKiRet(objDeserializeTryRecover(pStrm)); + } + } while(iRetLocal != RS_RET_OK); + + if(oID != objGetObjID(pObj)) + ABORT_FINALIZE(RS_RET_INVALID_OID); + + /* we got the object, now we need to fill the properties */ + CHKiRet(objDeserializeProperties(pObj, oID, pStrm)); + +finalize_it: + return iRet; +} + #undef NEXTC /* undef helper macro */ diff --git a/obj.h b/obj.h index 0caf1306..43f531b0 100644 --- a/obj.h +++ b/obj.h @@ -92,6 +92,7 @@ rsRetVal objSerializeProp(strm_t *pStrm, uchar *pszPropName, propertyType_t prop rsRetVal objEndSerialize(strm_t *pStrm); rsRetVal objRegisterObj(objID_t oID, objInfo_t *pInfo); rsRetVal objDeserialize(void *ppObj, objID_t objTypeExpected, strm_t *pSerStore); +rsRetVal objDeserializePropBag(obj_t *pObj, strm_t *pStrm); PROTOTYPEObjClassInit(obj); #endif /* #ifndef OBJ_H_INCLUDED */ diff --git a/queue.c b/queue.c index 91ffe18d..116b6ab1 100644 --- a/queue.c +++ b/queue.c @@ -646,8 +646,6 @@ static rsRetVal queuePersist(queue_t *pThis) * we know when somebody has changed the queue type... -- rgerhards, 2008-01-11 */ CHKiRet(objBeginSerializePropBag(psQIF, (obj_t*) pThis)); - i = 2; /* we serialize the number of properties, so that we know when we read the propbag */ - objSerializeSCALAR_VAR(psQIF, NumberPropertyBagRecrods, INT, i); i = pThis->qType; objSerializeSCALAR_VAR(psQIF, qType, INT, i); objSerializeSCALAR(psQIF, iQueueSize, INT); diff --git a/rsyslog.h b/rsyslog.h index a3ea9bb8..4608b947 100644 --- a/rsyslog.h +++ b/rsyslog.h @@ -105,6 +105,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth RS_RET_INVALID_TRAILER = -2034, /**< invalid trailer */ RS_RET_VALUE_TOO_LOW = -2035, /**< a provided value is too low */ RS_RET_FILE_PREFIX_MISSING = -2036, /**< a required file prefix (parameter?) is missing */ + RS_RET_INVALID_HEADER_RECTYPE = -2037, /**< invalid record type in header or invalid header */ RS_RET_OK_DELETE_LISTENTRY = 1, /**< operation successful, but callee requested the deletion of an entry (special state) */ RS_RET_TERMINATE_NOW = 2, /**< operation successful, function is requested to terminate (mostly used with threads) */ RS_RET_NO_RUN = 3, /**< operation successful, but function does not like to be executed */ -- cgit