2
* This header contains macros that can be used to implement the
5
* File begun on 2007-07-25 by RGerhards
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,
15
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
* GNU General Public License for more details.
19
* 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.
23
* A copy of the GPL can be found in the file "COPYING" in this distribution.
25
#ifndef MODULE_TEMPLATE_H_INCLUDED
26
#define MODULE_TEMPLATE_H_INCLUDED 1
30
/* macro to define standard output-module static data members
32
#define DEF_OMOD_STATIC_DATA \
33
static rsRetVal (*omsdRegCFSLineHdlr)();
35
/* to following macros are used to generate function headers and standard
36
* functionality. It works as follows (described on the sample case of
40
* ... custom variable definitions (on stack) ... (if any)
41
* CODESTARTcreateInstance
42
* ... custom code ... (if any)
48
#define BEGINcreateInstance \
49
static rsRetVal createInstance(instanceData **ppData)\
51
DEFiRet; /* store error code here */\
52
instanceData *pData; /* use this to point to data elements */
54
#define CODESTARTcreateInstance \
55
if((pData = calloc(1, sizeof(instanceData))) == NULL) {\
57
return RS_RET_OUT_OF_MEMORY;\
60
#define ENDcreateInstance \
67
#define BEGINfreeInstance \
68
static rsRetVal freeInstance(void* pModData)\
73
#define CODESTARTfreeInstance \
74
pData = (instanceData*) pModData;
76
#define ENDfreeInstance \
78
free(pData); /* we need to free this in any case */\
82
/* isCompatibleWithFeature()
84
#define BEGINisCompatibleWithFeature \
85
static rsRetVal isCompatibleWithFeature(syslogFeature __attribute__((unused)) eFeat)\
87
rsRetVal iRet = RS_RET_INCOMPATIBLE;
89
#define CODESTARTisCompatibleWithFeature
91
#define ENDisCompatibleWithFeature \
97
#define BEGINdoAction \
98
static rsRetVal doAction(uchar __attribute__((unused)) **ppString, unsigned __attribute__((unused)) iMsgOpts, instanceData __attribute__((unused)) *pData)\
102
#define CODESTARTdoAction \
103
/* ppString may be NULL if the output module requested no strings */
105
#define ENDdoAction \
110
/* dbgPrintInstInfo()
112
* Print debug information about this instance.
114
#define BEGINdbgPrintInstInfo \
115
static rsRetVal dbgPrintInstInfo(void *pModData)\
118
instanceData *pData = NULL;
120
#define CODESTARTdbgPrintInstInfo \
121
pData = (instanceData*) pModData;
123
#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 \
192
/* parseSelectorAct()
194
* try to process a selector action line. Checks if the action
195
* applies to this module and, if so, processed it. If not, it
196
* is left untouched. The driver will then call another module.
197
* On exit, ppModData must point to instance data. Also, a string
198
* request object must be created and filled. A macro is defined
200
* For the most usual case, we have defined a macro below.
201
* If more than one string is requested, the macro can be used together
202
* with own code that overwrites the entry count. In this case, the
203
* macro must come before the own code. It is recommended to be
204
* placed right after CODESTARTparseSelectorAct.
206
#define BEGINparseSelectorAct \
207
static rsRetVal parseSelectorAct(uchar **pp, void **ppModData, omodStringRequest_t **ppOMSR)\
211
instanceData *pData = NULL;
213
#define CODESTARTparseSelectorAct \
215
assert(ppModData != NULL);\
216
assert(ppOMSR != NULL);\
219
#define CODE_STD_STRING_REQUESTparseSelectorAct(NumStrReqEntries) \
220
CHKiRet(OMSRconstruct(ppOMSR, NumStrReqEntries));
222
#define CODE_STD_FINALIZERparseSelectorAct \
224
if(iRet == RS_RET_OK || iRet == RS_RET_SUSPENDED) {\
228
/* cleanup, we failed */\
229
if(*ppOMSR != NULL) {\
230
OMSRdestruct(*ppOMSR);\
234
freeInstance(&pData);\
237
#define ENDparseSelectorAct \
243
* This entry point is called to check if a module can resume operations. This
244
* happens when a module requested that it be suspended. In suspended state,
245
* the engine periodically tries to resume the module. If that succeeds, normal
246
* processing continues. If not, the module will not be called unless a
247
* tryResume() call succeeds.
248
* Returns RS_RET_OK, if resumption succeeded, RS_RET_SUSPENDED otherwise
249
* rgerhard, 2007-08-02
251
#define BEGINtryResume \
252
static rsRetVal tryResume(instanceData __attribute__((unused)) *pData)\
256
#define CODESTARTtryResume \
257
assert(pData != NULL);
259
#define ENDtryResume \
267
#define BEGINqueryEtryPt \
268
static rsRetVal queryEtryPt(uchar *name, rsRetVal (**pEtryPoint)())\
272
#define CODESTARTqueryEtryPt \
273
if((name == NULL) || (pEtryPoint == NULL))\
274
return RS_RET_PARAM_ERROR;\
277
#define ENDqueryEtryPt \
278
if(iRet == RS_RET_OK)\
279
iRet = (*pEtryPoint == NULL) ? RS_RET_NOT_FOUND : RS_RET_OK;\
283
/* the following definition is the standard block for queryEtryPt for output
284
* modules. This can be used if no specific handling (e.g. to cover version
285
* differences) is needed.
287
#define CODEqueryEtryPt_STD_OMOD_QUERIES\
288
if(!strcmp((char*) name, "doAction")) {\
289
*pEtryPoint = doAction;\
290
} else if(!strcmp((char*) name, "parseSelectorAct")) {\
291
*pEtryPoint = parseSelectorAct;\
292
} else if(!strcmp((char*) name, "isCompatibleWithFeature")) {\
293
*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
} else if(!strcmp((char*) name, "tryResume")) {\
305
*pEtryPoint = tryResume;\
309
* This has an extra parameter, which is the specific name of the modInit
310
* function. That is needed for built-in modules, which must have unique
311
* names in order to link statically.
314
* initialize the module
316
* Later, much more must be done. So far, we only return a pointer
317
* to the queryEtryPt() function
318
* TODO: do interface version checking & handshaking
319
* iIfVersRequeted is the version of the interface specification that the
320
* caller would like to see being used. ipIFVersProvided is what we
323
#define BEGINmodInit(uniqName) \
324
rsRetVal modInit##uniqName(int iIFVersRequested __attribute__((unused)), int *ipIFVersProvided, rsRetVal (**pQueryEtryPt)(), rsRetVal (*pHostQueryEtryPt)(uchar*, rsRetVal (**)()))\
328
#define CODESTARTmodInit \
329
assert(pHostQueryEtryPt != NULL);\
330
if((pQueryEtryPt == NULL) || (ipIFVersProvided == NULL))\
331
return RS_RET_PARAM_ERROR;
335
*pQueryEtryPt = queryEtryPt;\
340
/* definitions for host API queries */
341
#define CODEmodInit_QueryRegCFSLineHdlr \
342
CHKiRet(pHostQueryEtryPt((uchar*)"regCfSysLineHdlr", &omsdRegCFSLineHdlr));
344
#endif /* #ifndef MODULE_TEMPLATE_H_INCLUDED */