~ubuntu-branches/ubuntu/lucid/rsyslog/lucid-updates

1.1.2 by Michael Biebl
Import upstream version 3.14.2
1
/* Some type definitions and macros for the obj object.
2
 * I needed to move them out of the main obj.h, because obj.h's
3
 * prototypes use other data types. However, their .h's rely
4
 * on some of the obj.h data types and macros. So I needed to break
5
 * that loop somehow and I've done that by moving the typedefs
6
 * into this file here.
7
 *
8
 * Copyright 2008 Rainer Gerhards and Adiscon GmbH.
9
 *
10
 * This file is part of rsyslog.
11
 *
12
 * Rsyslog is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU General Public License as published by
14
 * the Free Software Foundation, either version 3 of the License, or
15
 * (at your option) any later version.
16
 *
17
 * Rsyslog is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU General Public License
23
 * along with Rsyslog.  If not, see <http://www.gnu.org/licenses/>.
24
 *
25
 * A copy of the GPL can be found in the file "COPYING" in this distribution.
26
 */
27
28
#ifndef OBJ_TYPES_H_INCLUDED
29
#define OBJ_TYPES_H_INCLUDED
30
31
#include "stringbuf.h"
32
#include "syslogd-types.h"
33
34
/* property types for obj[De]Serialize() */
35
typedef enum {
36
	PROPTYPE_NONE = 0, /* currently no value set */
37
	PROPTYPE_PSZ = 1,
38
	PROPTYPE_SHORT = 2,
39
	PROPTYPE_INT = 3,
40
	PROPTYPE_LONG = 4,
41
	PROPTYPE_INT64 = 5,
42
	PROPTYPE_CSTR = 6,
43
	PROPTYPE_SYSLOGTIME = 7
44
} propType_t;
45
46
typedef unsigned objID_t;
47
48
typedef enum {	/* IDs of base methods supported by all objects - used for jump table, so
49
		 * they must start at zero and be incremented. -- rgerhards, 2008-01-04
50
		 */
51
	objMethod_CONSTRUCT = 0,
52
	objMethod_DESTRUCT = 1,
53
	objMethod_SERIALIZE = 2,
54
	objMethod_DESERIALIZE = 3,
55
	objMethod_SETPROPERTY = 4,
56
	objMethod_CONSTRUCTION_FINALIZER = 5,
57
	objMethod_GETSEVERITY = 6,
58
	objMethod_DEBUGPRINT = 7
59
} objMethod_t;
60
#define OBJ_NUM_METHODS 8	/* must be updated to contain the max number of methods supported */
61
62
63
/* the base data type for interfaces
64
 * This MUST be in sync with the ifBEGIN macro
65
 */
66
typedef struct interface_s {
67
	int ifVersion;	/* must be set to version requested */ 
68
	int ifIsLoaded; /* is the interface loaded? (0-no, 1-yes, 2-load failed; if not 1, functions can NOT be called! */
69
} interface_t;
70
71
72
typedef struct objInfo_s {
73
	uchar *pszID; /* the object ID as a string */
74
	size_t lenID; /* length of the ID string */
75
	int iObjVers;
76
	uchar *pszName;
77
	rsRetVal (*objMethods[OBJ_NUM_METHODS])();
78
	rsRetVal (*QueryIF)(interface_t*);
79
	struct modInfo_s *pModInfo;
80
} objInfo_t;
81
82
83
typedef struct obj {	/* the dummy struct that each derived class can be casted to */
84
	objInfo_t *pObjInfo;
85
#ifndef NDEBUG /* this means if debug... */
86
	unsigned int iObjCooCKiE; /* must always be 0xBADEFEE for a valid object */
87
#endif
88
	uchar *pszName;		/* the name of *this* specific object instance */
89
} obj_t;
90
91
92
/* macros which must be gloablly-visible (because they are used during definition of
93
 * other objects.
94
 */
95
#ifndef NDEBUG /* this means if debug... */
96
#include <string.h>
97
#	define BEGINobjInstance \
98
		obj_t objData
99
#	define ISOBJ_assert(pObj) \
100
		do { \
101
		ASSERT((pObj) != NULL); \
102
		ASSERT((unsigned) ((obj_t*)(pObj))->iObjCooCKiE == (unsigned) 0xBADEFEE); \
103
		} while(0);
104
#	define ISOBJ_TYPE_assert(pObj, objType) \
105
		do { \
106
		ASSERT(pObj != NULL); \
107
		ASSERT((unsigned) ((obj_t*) (pObj))->iObjCooCKiE == (unsigned) 0xBADEFEE); \
108
		ASSERT(!strcmp((char*)(((obj_t*)pObj)->pObjInfo->pszID), #objType)); \
109
		} while(0);
110
#else /* non-debug mode, no checks but much faster */
111
#	define BEGINobjInstance obj_t objData
112
#	define ISOBJ_TYPE_assert(pObj, objType)
113
#	define ISOBJ_assert(pObj)
114
#endif
115
116
#define DEFpropSetMethPTR(obj, prop, dataType)\
117
	rsRetVal obj##Set##prop(obj##_t *pThis, dataType *pVal)\
118
	{ \
119
		/* DEV debug: dbgprintf("%sSet%s()\n", #obj, #prop); */\
120
		pThis->prop = pVal; \
121
		return RS_RET_OK; \
122
	}
123
#define PROTOTYPEpropSetMethPTR(obj, prop, dataType)\
124
	rsRetVal obj##Set##prop(obj##_t *pThis, dataType*)
125
#define DEFpropSetMeth(obj, prop, dataType)\
126
	rsRetVal obj##Set##prop(obj##_t *pThis, dataType pVal)\
127
	{ \
128
		/* DEV debug: dbgprintf("%sSet%s()\n", #obj, #prop); */\
129
		pThis->prop = pVal; \
130
		return RS_RET_OK; \
131
	}
132
#define DEFpropSetMethFP(obj, prop, dataType)\
133
	rsRetVal obj##Set##prop(obj##_t *pThis, dataType)\
134
	{ \
135
		/* DEV debug: dbgprintf("%sSet%s()\n", #obj, #prop); */\
136
		pThis->prop = pVal; \
137
		return RS_RET_OK; \
138
	}
139
#define PROTOTYPEpropSetMethFP(obj, prop, dataType)\
140
	rsRetVal obj##Set##prop(obj##_t *pThis, dataType)
141
#define DEFpropSetMeth(obj, prop, dataType)\
142
	rsRetVal obj##Set##prop(obj##_t *pThis, dataType pVal)\
143
	{ \
144
		/* DEV debug: dbgprintf("%sSet%s()\n", #obj, #prop); */\
145
		pThis->prop = pVal; \
146
		return RS_RET_OK; \
147
	}
148
#define PROTOTYPEpropSetMeth(obj, prop, dataType)\
149
	rsRetVal obj##Set##prop(obj##_t *pThis, dataType pVal)
150
#define INTERFACEpropSetMeth(obj, prop, dataType)\
151
	rsRetVal (*Set##prop)(obj##_t *pThis, dataType)
152
/* class initializer */
153
#define PROTOTYPEObjClassInit(objName) rsRetVal objName##ClassInit(struct modInfo_s*)
154
/* below: objName must be the object name (e.g. vm, strm, ...) and ISCORE must be
155
 * 1 if the module is a statically linked core module and 0 if it is a
156
 * dynamically loaded one. -- rgerhards, 2008-02-29
157
 */
158
#define OBJ_IS_CORE_MODULE 1 /* This should better be renamed to something like "OBJ_IS_NOT_LIBHEAD" or so... ;) */
159
#define OBJ_IS_LOADABLE_MODULE 0
160
#define BEGINObjClassInit(objName, objVers, objType) \
161
rsRetVal objName##ClassInit(struct modInfo_s *pModInfo) \
162
{ \
163
	DEFiRet; \
164
	if(objType == OBJ_IS_CORE_MODULE) { /* are we a core module? */ \
165
		CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ \
166
	} \
167
	CHKiRet(obj.InfoConstruct(&pObjInfoOBJ, (uchar*) #objName, objVers, \
168
	                         (rsRetVal (*)(void*))objName##Construct,\
169
				 (rsRetVal (*)(void*))objName##Destruct,\
170
				 (rsRetVal (*)(interface_t*))objName##QueryInterface, pModInfo)); \
171
172
#define ENDObjClassInit(objName) \
173
	iRet = obj.RegisterObj((uchar*)#objName, pObjInfoOBJ); \
174
finalize_it: \
175
	RETiRet; \
176
}
177
178
/* ... and now the same for abstract classes.
179
 * TODO: consolidate the two -- rgerhards, 2008-02-29
180
 */
181
#define BEGINAbstractObjClassInit(objName, objVers, objType) \
182
rsRetVal objName##ClassInit(struct modInfo_s *pModInfo) \
183
{ \
184
	DEFiRet; \
185
	if(objType == OBJ_IS_CORE_MODULE) { /* are we a core module? */ \
186
		CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ \
187
	} \
188
	CHKiRet(obj.InfoConstruct(&pObjInfoOBJ, (uchar*) #objName, objVers, \
189
	                         NULL,\
190
				 NULL,\
191
				 (rsRetVal (*)(interface_t*))objName##QueryInterface, pModInfo)); 
192
193
#define ENDObjClassInit(objName) \
194
	iRet = obj.RegisterObj((uchar*)#objName, pObjInfoOBJ); \
195
finalize_it: \
196
	RETiRet; \
197
}
198
199
200
/* now come the class exit. This is to be called immediately before the class is 
201
 * unloaded (actual unload for plugins, program termination for core modules)
202
 * gerhards, 2008-03-10
203
 */
204
#define PROTOTYPEObjClassExit(objName) rsRetVal objName##ClassExit(void)
205
#define BEGINObjClassExit(objName, objType) \
206
rsRetVal objName##ClassExit(void) \
207
{ \
208
	DEFiRet;
209
210
#define CODESTARTObjClassExit(objName)
211
212
#define ENDObjClassExit(objName) \
1.1.5 by Michael Biebl
Import upstream version 3.18.1
213
	iRet = obj.UnregisterObj((uchar*)#objName); \
1.1.2 by Michael Biebl
Import upstream version 3.14.2
214
	RETiRet; \
215
}
216
217
/* this defines both the constructor and initializer
218
 * rgerhards, 2008-01-10
219
 */
220
#define BEGINobjConstruct(obj) \
221
	rsRetVal obj##Initialize(obj##_t __attribute__((unused)) *pThis) \
222
	{ \
223
		DEFiRet;
224
225
#define ENDobjConstruct(obj) \
226
		/* use finalize_it: before calling the macro (if you need it)! */ \
227
		RETiRet; \
228
	} \
229
	rsRetVal obj##Construct(obj##_t **ppThis) \
230
	{ \
231
		DEFiRet; \
232
		obj##_t *pThis; \
233
	 \
234
		ASSERT(ppThis != NULL); \
235
	 \
236
		if((pThis = (obj##_t *)calloc(1, sizeof(obj##_t))) == NULL) { \
237
			ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); \
238
		} \
239
		objConstructSetObjInfo(pThis); \
240
	 \
241
		obj##Initialize(pThis); \
242
	\
243
	finalize_it: \
244
		OBJCONSTRUCT_CHECK_SUCCESS_AND_CLEANUP \
245
		RETiRet; \
246
	} 
247
248
249
/* this defines the destructor. The important point is that the base object
250
 * destructor is called. The upper-level class shall destruct all of its
251
 * properties, but not the instance itself. This is freed here by the 
252
 * framework (we need an intact pointer because we need to free the
253
 * obj_t structures inside it). A pointer to the object pointer must be
254
 * parse, because it is re-set to NULL (this, for example, is important in
255
 * cancellation handlers). The object pointer is always named pThis.
256
 * The object is always freed, even if there is some error while
257
 * Cancellation is blocked during destructors, as this could have fatal
258
 * side-effects. However, this also means the upper-level object should
259
 * not perform any lenghty processing.
260
 * IMPORTANT: if the upper level object requires some situations where the
261
 * object shall not be destructed (e.g. via reference counting), then
262
 * it shall set pThis to NULL, which prevents destruction of the
263
 * object.
264
 * processing.
265
 * rgerhards, 2008-01-30
266
 */
267
#define BEGINobjDestruct(OBJ) \
268
	rsRetVal OBJ##Destruct(OBJ##_t **ppThis) \
269
	{ \
270
		DEFiRet; \
271
		int iCancelStateSave; \
272
		OBJ##_t *pThis; 
273
274
#define CODESTARTobjDestruct(OBJ) \
275
		ASSERT(ppThis != NULL); \
276
		pThis = *ppThis; \
277
		ISOBJ_TYPE_assert(pThis, OBJ); \
278
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &iCancelStateSave);
279
280
#define ENDobjDestruct(OBJ) \
281
	 	goto finalize_it; /* prevent compiler warning ;) */ \
282
	 	/* no more code here! */ \
283
	finalize_it: \
284
		if(pThis != NULL) { \
285
			obj.DestructObjSelf((obj_t*) pThis); \
286
			free(pThis); \
287
			*ppThis = NULL; \
288
		} \
289
		pthread_setcancelstate(iCancelStateSave, NULL); \
290
		RETiRet; \
291
	} 
292
293
294
/* this defines the debug print entry point. DebugPrint is optional. If
295
 * it is provided, the object should output some meaningful information
296
 * via the debug system.
297
 * rgerhards, 2008-02-20
298
 */
299
#define PROTOTYPEObjDebugPrint(obj) rsRetVal obj##DebugPrint(obj##_t *pThis)
300
#define INTERFACEObjDebugPrint(obj) rsRetVal (*DebugPrint)(obj##_t *pThis)
301
#define BEGINobjDebugPrint(obj) \
302
	rsRetVal obj##DebugPrint(obj##_t *pThis) \
303
	{ \
304
		DEFiRet; \
305
306
#define CODESTARTobjDebugPrint(obj) \
307
		ASSERT(pThis != NULL); \
308
		ISOBJ_TYPE_assert(pThis, obj); \
309
310
#define ENDobjDebugPrint(obj) \
311
		RETiRet; \
312
	} 
313
314
/* ------------------------------ object loader system ------------------------------ *
315
 * The following code is the early beginning of a dynamic object loader system. The 
316
 * root idea is that all objects will become dynamically loadable libraries over time,
317
 * which is necessary to get a clean plug-in interface where every plugin can access
318
 * rsyslog's rich object model via simple and quite portable methods.
319
 *
320
 * To do so, each object defines one or more interfaces. They are essentially structures
321
 * with function (method) pointers. Anyone interested in calling an object must first
322
 * obtain the interface and can then call through it.
323
 *
324
 * The interface data type must always be called <obj>_if_t, as this is expected
325
 * by the macros. Having consitent naming is also easier for the programmer. By default,
326
 * macros create a static variable named like the object in each calling objects
327
 * static data block.
328
 *
329
 * To facilitate moving to this system, I begin to implement some hooks, which
330
 * allows to use interfaces today (when the rest of the infrastructure is not yet
331
 * there). This is in the hope that it will ease migration to the full-fledged system
332
 * once we are ready to work on that.
333
 * rgerhards, 2008-02-21
334
 */
335
336
/* this defines the QueryInterface print entry point. Over time, it should be
337
 * present in all objects.
338
 */
339
//#define PROTOTYPEObjQueryInterface(obj) rsRetVal obj##QueryInterface(obj##_if_t *pThis)
340
#define BEGINobjQueryInterface(obj) \
341
	rsRetVal obj##QueryInterface(obj##_if_t *pIf) \
342
	{ \
343
		DEFiRet; \
344
345
#define CODESTARTobjQueryInterface(obj) \
346
		ASSERT(pIf != NULL);
347
348
#define ENDobjQueryInterface(obj) \
349
		RETiRet; \
350
	} 
351
352
353
/* the following macros should be used to define interfaces inside the
354
 * header files.
355
 */
356
#define BEGINinterface(obj) \
357
	typedef struct obj##_if_s {\
358
		ifBEGIN;		/* This MUST always be the first interface member */
359
#define ENDinterface(obj) \
360
	} obj##_if_t;
361
	
362
/* the following macro is used to get access to an object (not an instance,
363
 * just the class itself!). It must be called before any of the object's
364
 * methods can be accessed. The MYLIB part is the name of my library, or NULL if
365
 * the caller is a core module. Using the right value here is important to get
366
 * the reference counting correct (object accesses from the same library must
367
 * not be counted because that would cause a library plugin to never unload, as
368
 * its ClassExit() entry points are only called if no object is referenced, which
369
 * would never happen as the library references itself.
370
 * rgerhards, 2008-03-11
371
 */
372
#define CORE_COMPONENT NULL /* use this to indicate this is a core component */
373
#define DONT_LOAD_LIB NULL /* do not load a library to obtain object interface (currently same as CORE_COMPONENT) */
374
/*#define objUse(objName, MYLIB, FILENAME) \
375
	obj.UseObj(__FILE__, (uchar*)#objName, MYLIB, (uchar*)FILENAME, (void*) &objName)
376
*/
377
#define objUse(objName, FILENAME) \
378
	obj.UseObj(__FILE__, (uchar*)#objName, (uchar*)FILENAME, (void*) &objName)
379
#define objRelease(objName, FILENAME) \
380
	obj.ReleaseObj(__FILE__, (uchar*)#objName, (uchar*) FILENAME, (void*) &objName)
381
382
/* defines data that must always be present at the very begin of the interface structure */
383
#define ifBEGIN \
384
	int ifVersion;	/* must be set to version requested */ \
385
	int ifIsLoaded; /* is the interface loaded? (0-no, 1-yes; if no, functions can NOT be called! */
386
387
388
/* use the following define some place in your static data (suggested right at
389
 * the beginning
390
 */
391
#define DEFobjCurrIf(obj) \
392
		static obj##_if_t obj = { .ifVersion = obj##CURR_IF_VERSION, .ifIsLoaded = 0 };
393
 
394
/* define the prototypes for a class - when we use interfaces, we just have few
395
 * functions that actually need to be non-static.
396
 */
397
#define PROTOTYPEObj(obj) \
398
	PROTOTYPEObjClassInit(obj); \
399
	PROTOTYPEObjClassExit(obj);
400
401
/* ------------------------------ end object loader system ------------------------------ */
402
403
404
#include "modules.h"
405
#endif /* #ifndef OBJ_TYPES_H_INCLUDED */