7
7
* Copyright 2007 Rainer Gerhards and Adiscon GmbH.
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License
11
* as published by the Free Software Foundation; either version 2
12
* of the License, or (at your option) any later version.
14
* This program is distributed in the hope that it will be useful,
9
* This file is part of rsyslog.
11
* Rsyslog is free software: you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation, either version 3 of the License, or
14
* (at your option) any later version.
16
* Rsyslog is distributed in the hope that it will be useful,
15
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
19
* GNU General Public License for more details.
19
21
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
* along with Rsyslog. If not, see <http://www.gnu.org/licenses/>.
23
24
* A copy of the GPL can be found in the file "COPYING" in this distribution.
25
26
#ifndef MODULE_TEMPLATE_H_INCLUDED
26
27
#define MODULE_TEMPLATE_H_INCLUDED 1
28
31
#include "objomsr.h"
30
34
/* macro to define standard output-module static data members
36
#define DEF_MOD_STATIC_DATA \
37
static __attribute__((unused)) rsRetVal (*omsdRegCFSLineHdlr)();
32
39
#define DEF_OMOD_STATIC_DATA \
33
static rsRetVal (*omsdRegCFSLineHdlr)();
42
#define DEF_IMOD_STATIC_DATA \
45
#define DEF_LMOD_STATIC_DATA \
49
/* Macro to define the module type. Each module can only have a single type. If
50
* a module provides multiple types, several separate modules must be created which
51
* then should share a single library containing the majority of code. This macro
52
* must be present in each module. -- rgerhards, 2007-12-14
54
#define MODULE_TYPE(x)\
55
static rsRetVal modGetType(eModType_t *modType) \
61
#define MODULE_TYPE_INPUT MODULE_TYPE(eMOD_IN)
62
#define MODULE_TYPE_OUTPUT MODULE_TYPE(eMOD_OUT)
63
#define MODULE_TYPE_LIB \
64
DEF_LMOD_STATIC_DATA \
67
/* macro to define a unique module id. This must be able to fit in a void*. The
68
* module id must be unique inside a running rsyslogd application. It is used to
69
* track ownership of several objects. Most importantly, when the module is
70
* unloaded the module id value is used to find what needs to be destroyed.
71
* We currently use a pointer to modExit() as the module id. This sounds to be
72
* reasonable save, as each module must have this entry point AND there is no valid
73
* reason for twice this entry point being in memory.
74
* rgerhards, 2007-11-21
76
#define STD_LOADABLE_MODULE_ID ((void*) modExit)
79
/* macro to implement the "modGetID()" interface function
80
* rgerhards 2007-11-21
83
static rsRetVal modGetID(void **pID) \
85
*pID = STD_LOADABLE_MODULE_ID;\
35
89
/* to following macros are used to generate function headers and standard
36
90
* functionality. It works as follows (described on the sample case of
54
108
#define CODESTARTcreateInstance \
55
109
if((pData = calloc(1, sizeof(instanceData))) == NULL) {\
57
112
return RS_RET_OUT_OF_MEMORY;\
60
115
#define ENDcreateInstance \
121
* This is the cleanup function for the module instance. It is called immediately before
122
* the module instance is destroyed (unloaded). The module should do any cleanup
123
* here, e.g. close file, free instantance heap memory and the like. Control will
124
* not be passed back to the module once this function is finished. Keep in mind,
125
* however, that other instances may still be loaded and used. So do not destroy
126
* anything that may be used by another instance. If you have such a ressource, you
127
* currently need to do the instance counting yourself.
67
129
#define BEGINfreeInstance \
68
130
static rsRetVal freeInstance(void* pModData)\
121
184
pData = (instanceData*) pModData;
123
186
#define ENDdbgPrintInstInfo \
129
* Talks back to syslogd if the global UDP syslog socket is needed for
130
* sending. Returns 0 if not, 1 if needed. This interface hopefully goes
131
* away at some time, because it is kind of a hack. However, currently
132
* there is no way around it, so we need to support it.
133
* rgerhards, 2007-07-26
135
#define BEGINneedUDPSocket \
136
static rsRetVal needUDPSocket(void *pModData)\
138
rsRetVal iRet = RS_RET_FALSE;\
139
instanceData *pData = NULL;
141
#define CODESTARTneedUDPSocket \
142
pData = (instanceData*) pModData;
144
#define ENDneedUDPSocket \
149
/* onSelectReadyWrite()
151
* This is called when select() returned with a writable file descriptor
152
* for this module. The fd was most probably obtained by getWriteFDForSelect()
155
#define BEGINonSelectReadyWrite \
156
static rsRetVal onSelectReadyWrite(void *pModData)\
158
rsRetVal iRet = RS_RET_NONE;\
159
instanceData *pData = NULL;
161
#define CODESTARTonSelectReadyWrite \
162
pData = (instanceData*) pModData;
164
#define ENDonSelectReadyWrite \
169
/* getWriteFDForSelect()
171
* Gets writefd for select call. Must only be returned when the selector must
172
* be written to. If the module has no such fds, it must return RS_RET_NONE.
173
* In this case, the default implementation is sufficient.
174
* This interface will probably go away over time, but we need it now to
175
* continue modularization.
177
#define BEGINgetWriteFDForSelect \
178
static rsRetVal getWriteFDForSelect(void *pModData, short __attribute__((unused)) *fd)\
180
rsRetVal iRet = RS_RET_NONE;\
181
instanceData *pData = NULL;
183
#define CODESTARTgetWriteFDForSelect \
185
pData = (instanceData*) pModData;
187
#define ENDgetWriteFDForSelect \
267
267
#define BEGINqueryEtryPt \
268
269
static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\
272
273
#define CODESTARTqueryEtryPt \
273
if((name == NULL) || (pEtryPoint == NULL))\
274
if((name == NULL) || (pEtryPoint == NULL)) {\
274
276
return RS_RET_PARAM_ERROR;\
275
278
*pEtryPoint = NULL;
277
280
#define ENDqueryEtryPt \
278
281
if(iRet == RS_RET_OK)\
279
iRet = (*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;\
282
if(*pEtryPoint == NULL) { \
283
dbgprintf("entry point '%s' not present in module\n", name); \
284
iRet = RS_RET_MODULE_ENTRY_POINT_NOT_FOUND;\
289
/* the following definition is the standard block for queryEtryPt for all types
290
* of modules. It should be included in any module, and typically is so by calling
291
* the module-type specific macros.
293
#define CODEqueryEtryPt_STD_MOD_QUERIES \
294
if(!strcmp((char*) name, "modExit")) {\
295
*pEtryPoint = modExit;\
296
} else if(!strcmp((char*) name, "modGetID")) {\
297
*pEtryPoint = modGetID;\
298
} else if(!strcmp((char*) name, "getType")) {\
299
*pEtryPoint = modGetType;\
283
302
/* the following definition is the standard block for queryEtryPt for output
284
303
* modules. This can be used if no specific handling (e.g. to cover version
285
304
* differences) is needed.
287
#define CODEqueryEtryPt_STD_OMOD_QUERIES\
288
if(!strcmp((char*) name, "doAction")) {\
306
#define CODEqueryEtryPt_STD_OMOD_QUERIES \
307
CODEqueryEtryPt_STD_MOD_QUERIES \
308
else if(!strcmp((char*) name, "doAction")) {\
289
309
*pEtryPoint = doAction;\
310
} else if(!strcmp((char*) name, "dbgPrintInstInfo")) {\
311
*pEtryPoint = dbgPrintInstInfo;\
312
} else if(!strcmp((char*) name, "freeInstance")) {\
313
*pEtryPoint = freeInstance;\
290
314
} else if(!strcmp((char*) name, "parseSelectorAct")) {\
291
315
*pEtryPoint = parseSelectorAct;\
292
316
} else if(!strcmp((char*) name, "isCompatibleWithFeature")) {\
293
317
*pEtryPoint = isCompatibleWithFeature;\
294
} else if(!strcmp((char*) name, "dbgPrintInstInfo")) {\
295
*pEtryPoint = dbgPrintInstInfo;\
296
} else if(!strcmp((char*) name, "freeInstance")) {\
297
*pEtryPoint = freeInstance;\
298
} else if(!strcmp((char*) name, "getWriteFDForSelect")) {\
299
*pEtryPoint = getWriteFDForSelect;\
300
} else if(!strcmp((char*) name, "onSelectReadyWrite")) {\
301
*pEtryPoint = onSelectReadyWrite;\
302
} else if(!strcmp((char*) name, "needUDPSocket")) {\
303
*pEtryPoint = needUDPSocket;\
304
318
} else if(!strcmp((char*) name, "tryResume")) {\
305
319
*pEtryPoint = tryResume;\
322
/* the following definition is the standard block for queryEtryPt for INPUT
323
* modules. This can be used if no specific handling (e.g. to cover version
324
* differences) is needed.
326
#define CODEqueryEtryPt_STD_IMOD_QUERIES \
327
CODEqueryEtryPt_STD_MOD_QUERIES \
328
else if(!strcmp((char*) name, "runInput")) {\
329
*pEtryPoint = runInput;\
330
} else if(!strcmp((char*) name, "willRun")) {\
331
*pEtryPoint = willRun;\
332
} else if(!strcmp((char*) name, "afterRun")) {\
333
*pEtryPoint = afterRun;\
336
/* the following definition is the standard block for queryEtryPt for LIBRARY
337
* modules. This can be used if no specific handling (e.g. to cover version
338
* differences) is needed.
340
#define CODEqueryEtryPt_STD_LIB_QUERIES \
341
CODEqueryEtryPt_STD_MOD_QUERIES
309
344
* This has an extra parameter, which is the specific name of the modInit
310
345
* function. That is needed for built-in modules, which must have unique
311
* names in order to link statically.
346
* names in order to link statically. Please note that this is alwaysy only
347
* the case with modInit() and NO other entry point. The reason is that only
348
* modInit() is visible form a linker/loader point of view. All other entry
349
* points are passed via rsyslog-internal query functions and are defined
350
* static inside the modules source. This is an important concept, as it allows
351
* us to support different interface versions within a single module. (Granted,
352
* we do not currently have different interface versions, so we can not put
353
* it to a test - but our firm believe is that we can do all abstraction needed...)
313
355
* Extra Comments:
314
356
* initialize the module
316
358
* Later, much more must be done. So far, we only return a pointer
317
359
* to the queryEtryPt() function
318
360
* TODO: do interface version checking & handshaking
319
* iIfVersRequeted is the version of the interface specification that the
361
* iIfVersRequetsed is the version of the interface specification that the
320
362
* caller would like to see being used. ipIFVersProvided is what we
321
363
* decide to provide.
364
* rgerhards, 2007-11-21: see modExit() comment below for important information
365
* on the need to initialize static data with code. modInit() may be called on a
366
* cached, left-in-memory copy of a previous incarnation.
323
368
#define BEGINmodInit(uniqName) \
324
rsRetVal modInit##uniqName(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar*, rsRetVal (**)()))\
369
rsRetVal modInit##uniqName(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar*, rsRetVal (**)()), modInfo_t __attribute__((unused)) *pModInfo)\
372
rsRetVal (*pObjGetObjInterface)(obj_if_t *pIf);
328
374
#define CODESTARTmodInit \
329
375
assert(pHostQueryEtryPt != NULL);\
330
if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))\
331
return RS_RET_PARAM_ERROR;
376
iRet = pHostQueryEtryPt((uchar*)"objGetObjInterface", &pObjGetObjInterface); \
377
if((iRet != RS_RET_OK) || (pQueryEtryPt == NULL) || (ipIFVersProvided == NULL) || (pObjGetObjInterface == NULL)) { \
379
return (iRet == RS_RET_OK) ? RS_RET_PARAM_ERROR : iRet; \
381
/* now get the obj interface so that we can access other objects */ \
382
CHKiRet(pObjGetObjInterface(&obj));
333
384
#define ENDmodInit \
335
386
*pQueryEtryPt = queryEtryPt;\
342
393
CHKiRet(pHostQueryEtryPt((uchar*)"regCfSysLineHdlr", &omsdRegCFSLineHdlr));
344
395
#endif /* #ifndef MODULE_TEMPLATE_H_INCLUDED */
398
* This is the counterpart to modInit(). It destroys a module and makes it ready for
399
* unloading. It is similiar to freeInstance() for the instance data. Please note that
400
* this entry point needs to free any module-globale data structures and registrations.
401
* For example, the CfSysLineHandlers a module has registered need to be unregistered
402
* here. This entry point is only called immediately before unloading of the module. So
403
* it is likely to be destroyed. HOWEVER, the caller may decide to keep the module cached.
404
* So a module must never assume that it is actually destroyed. A call to modInit() may
405
* happen immediately after modExit(). So a module can NOT assume that static data elements
406
* are being re-initialized by the loader - this must always be done by module code itself.
407
* It is suggested to do this in modInit(). - rgerhards, 2007-11-21
409
#define BEGINmodExit \
410
static rsRetVal modExit(void)\
414
#define CODESTARTmodExit
422
* This is the main function for input modules. It is used to gather data from the
423
* input source and submit it to the message queue. Each runInput() instance has its own
424
* thread. This is handled by the rsyslog engine. It needs to spawn off new threads only
425
* if there is a module-internal need to do so.
427
#define BEGINrunInput \
428
static rsRetVal runInput(thrdInfo_t __attribute__((unused)) *pThrd)\
432
#define CODESTARTrunInput \
433
dbgSetThrdName((uchar*)__FILE__); /* we need to provide something better later */
435
#define ENDrunInput \
441
* This is a function that will be replaced in the longer term. It is used so
442
* that a module can tell the caller if it will run or not. This is to be replaced
443
* when we introduce input module instances. However, these require config syntax
444
* changes and I may (or may not... ;)) hold that until another config file
445
* format is available. -- rgerhards, 2007-12-17
446
* returns RS_RET_NO_RUN if it will not run (RS_RET_OK or error otherwise)
448
#define BEGINwillRun \
449
static rsRetVal willRun(void)\
453
#define CODESTARTwillRun
461
* This function is called after an input module has been run and its thread has
462
* been terminated. It shall do any necessary cleanup.
463
* This is expected to evolve into a freeInstance type of call once the input module
464
* interface evolves to support multiple instances.
465
* rgerhards, 2007-12-17
467
#define BEGINafterRun \
468
static rsRetVal afterRun(void)\
472
#define CODESTARTafterRun
474
#define ENDafterRun \