1 /* modules.h
2  *
3  * Definition for build-in and plug-ins module handler. This file is the base
4  * for all dynamically loadable module support. In theory, in v3 all modules
5  * are dynamically loaded, in practice we currently do have a few build-in
6  * once. This may become removed.
7  *
8  * The loader keeps track of what is loaded. For library modules, it is also
9  * used to find objects (libraries) and to obtain the queryInterface function
10  * for them. A reference count is maintened for libraries, so that they are
11  * unloaded only when nobody still accesses them.
12  *
13  * File begun on 2007-07-22 by RGerhards
14  *
15  * Copyright 2007-2018 Rainer Gerhards and Adiscon GmbH.
16  *
17  * This file is part of the rsyslog runtime library.
18  *
19  * The rsyslog runtime library is free software: you can redistribute it and/or modify
20  * it under the terms of the GNU Lesser General Public License as published by
21  * the Free Software Foundation, either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * The rsyslog runtime library is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU Lesser General Public License for more details.
28  *
29  * You should have received a copy of the GNU Lesser General Public License
30  * along with the rsyslog runtime library.  If not, see <http://www.gnu.org/licenses/>.
31  *
32  * A copy of the GPL can be found in the file "COPYING" in this distribution.
33  * A copy of the LGPL can be found in the file "COPYING.LESSER" in this distribution.
34  */
35 #ifndef	MODULES_H_INCLUDED
36 #define	MODULES_H_INCLUDED 1
37 
38 #include "objomsr.h"
39 #include "rainerscript.h"
40 
41 
42 /* the following define defines the current version of the module interface.
43  * It can be used by any module which want's to simply prevent version conflicts
44  * and does not intend to do specific old-version emulations.
45  * rgerhards, 2008-03-04
46  * version 3 adds modInfo_t ptr to call of modInit -- rgerhards, 2008-03-10
47  * version 4 removes needUDPSocket OM callback -- rgerhards, 2008-03-22
48  * version 5 changes the way parsing works for input modules. This is
49  *           an important change, parseAndSubmitMessage() goes away. Other
50  *           module types are not affected. -- rgerhards, 2008-10-09
51  * version 6 introduces scoping support (starting with the output
52  *           modules) -- rgerhards, 2010-07-27
53  */
54 #define CURR_MOD_IF_VERSION 6
55 
56 typedef enum eModType_ {
57 	eMOD_IN = 0,	/* input module */
58 	eMOD_OUT = 1,	/* output module */
59 	eMOD_LIB = 2,	/* library module */
60 	eMOD_PARSER = 3,/* parser module */
61 	eMOD_STRGEN = 4,/* strgen module */
62 	eMOD_FUNCTION = 5, /*rscript function module*/
63 	eMOD_ANY = 6	/* meta-name for "any type of module" -- to be used in function calls */
64 } eModType_t;
65 
66 
67 #ifdef DEBUG
68 typedef struct modUsr_s {
69 	struct modUsr_s *pNext;
70 	char *pszFile;
71 } modUsr_t;
72 #endif
73 
74 
75 /* how is this module linked? */
76 typedef enum eModLinkType_ {
77 	eMOD_LINK_STATIC,
78 	eMOD_LINK_DYNAMIC_UNLOADED,	/* dynalink module, currently not loaded */
79 	eMOD_LINK_DYNAMIC_LOADED,	/* dynalink module, currently loaded */
80 	eMOD_LINK_ALL			/* special: all linkage types, e.g. for unload */
81 } eModLinkType_t;
82 
83 /* remember which shared libs we dlopen()-ed */
84 struct dlhandle_s {
85 	uchar	*pszName;
86 	void	*pModHdlr;
87 	struct	dlhandle_s *next;
88 };
89 
90 /* should this module be kept linked? */
91 typedef enum eModKeepType_ {
92 	eMOD_NOKEEP,
93 	eMOD_KEEP
94 } eModKeepType_t;
95 
96 struct modInfo_s {
97 	struct modInfo_s *pPrev;	/* support for creating a double linked module list */
98 	struct modInfo_s *pNext;	/* support for creating a linked module list */
99 	int		iIFVers;	/* Interface version of module */
100 	eModType_t	eType;		/* type of this module */
101 	eModLinkType_t	eLinkType;
102 	eModKeepType_t	eKeepType;	/* keep the module dynamically linked on unload */
103 	uchar*		pszName;	/* printable module name, e.g. for dbgprintf */
104 	uchar*		cnfName;	/* name to be used in config statements (e.g. 'name="omusrmsg"') */
105 	unsigned	uRefCnt;	/* reference count for this module; 0 -> may be unloaded */
106 	sbool		bSetModCnfCalled;/* is setModCnf already called? Needed for built-in modules */
107 	/* functions supported by all types of modules */
108 	rsRetVal (*modInit)(int, int*, rsRetVal(**)(void*));		/* initialize the module */
109 		/* be sure to support version handshake! */
110 	rsRetVal (*modQueryEtryPt)(uchar *name, rsRetVal (**EtryPoint)()); /* query entry point addresses */
111 	rsRetVal (*isCompatibleWithFeature)(syslogFeature);
112 	rsRetVal (*freeInstance)(void*);/* called before termination or module unload */
113 	rsRetVal (*dbgPrintInstInfo)(void*);/* called before termination or module unload */
114 	rsRetVal (*tryResume)(void*);/* called to see if module actin can be resumed now */
115 	rsRetVal (*modExit)(void);		/* called before termination or module unload */
116 	rsRetVal (*modGetID)(void **);		/* get its unique ID from module */
117 	rsRetVal (*doHUP)(void *);		/* HUP handler, action level */
118 	rsRetVal (*doHUPWrkr)(void *);		/* HUP handler, wrkr instance level */
119 	/* v2 config system specific */
120 	rsRetVal (*beginCnfLoad)(void*newCnf, rsconf_t *pConf);
121 	rsRetVal (*setModCnf)(struct nvlst *lst);
122 	rsRetVal (*endCnfLoad)(void*Cnf);
123 	rsRetVal (*checkCnf)(void*Cnf);
124 	rsRetVal (*activateCnfPrePrivDrop)(void*Cnf);
125 	rsRetVal (*activateCnf)(void*Cnf);	/* make provided config the running conf */
126 	rsRetVal (*freeCnf)(void*Cnf);
127 	/* end v2 config system specific */
128 	union	{
129 		struct {/* data for input modules */
130 /* TODO: remove? */rsRetVal (*willRun)(void); 		/* check if the current config will be able to run*/
131 			rsRetVal (*runInput)(thrdInfo_t*);	/* function to gather input and submit to queue */
132 			rsRetVal (*afterRun)(thrdInfo_t*);	/* function to gather input and submit to queue */
133 			rsRetVal (*newInpInst)(struct nvlst *lst);
134 			int bCanRun;	/* cached value of whether willRun() succeeded */
135 		} im;
136 		struct {/* data for output modules */
137 			/* below: perform the configured action
138 			 */
139 			rsRetVal (*beginTransaction)(void*);
140 			rsRetVal (*commitTransaction)(void *const, actWrkrIParams_t *const, const unsigned);
141 			rsRetVal (*doAction)(void** params, void*pWrkrData);
142 			rsRetVal (*endTransaction)(void*);
143 			rsRetVal (*parseSelectorAct)(uchar**, void**,omodStringRequest_t**);
144 			rsRetVal (*newActInst)(uchar *modName, struct nvlst *lst, void **, omodStringRequest_t **);
145 			rsRetVal (*SetShutdownImmdtPtr)(void *pData, void *pPtr);
146 			rsRetVal (*createWrkrInstance)(void*ppWrkrData, void*pData);
147 			rsRetVal (*freeWrkrInstance)(void*pWrkrData);
148 			sbool supportsTX;	/* set if the module supports transactions */
149 		} om;
150 		struct { /* data for library modules */
151 		    	char dummy;
152 		} lm;
153 		struct { /* data for parser modules */
154 			rsRetVal (*newParserInst)(struct nvlst *lst, void *pinst);
155 			rsRetVal (*freeParserInst)(void *pinst);
156 			rsRetVal (*parse2)(instanceConf_t *const, smsg_t*);
157 			rsRetVal (*parse)(smsg_t*);
158 		} pm;
159 		struct { /* data for strgen modules */
160 			rsRetVal (*strgen)(const smsg_t*const, actWrkrIParams_t *const iparam);
161 		} sm;
162 		struct { /* data for rscript modules */
163 			rsRetVal (*getFunctArray)(int *const, struct scriptFunct**);
164 		} fm;
165 	} mod;
166 	void *pModHdlr; /* handler to the dynamic library holding the module */
167 #	ifdef DEBUG
168 	/* we add some home-grown support to track our users (and detect who does not free us). */
169 	modUsr_t *pModUsrRoot;
170 #	endif
171 };
172 
173 
174 /* interfaces */
175 BEGINinterface(module) /* name must also be changed in ENDinterface macro! */
176 	modInfo_t *(*GetNxt)(modInfo_t *pThis);
177 	cfgmodules_etry_t *(*GetNxtCnfType)(rsconf_t *cnf, cfgmodules_etry_t *pThis, eModType_t rqtdType);
178 	uchar *(*GetName)(modInfo_t *pThis);
179 	uchar *(*GetStateName)(modInfo_t *pThis);
180 	rsRetVal (*Use)(const char *srcFile, modInfo_t *pThis);
181 	/**< must be called before a module is used (ref counting) */
182 	rsRetVal (*Release)(const char *srcFile, modInfo_t **ppThis);	/**< release a module (ref counting) */
183 	void (*PrintList)(void);
184 	rsRetVal (*UnloadAndDestructAll)(eModLinkType_t modLinkTypesToUnload);
185 	rsRetVal (*doModInit)(rsRetVal (*modInit)(), uchar *name, void *pModHdlr, modInfo_t **pNew);
186 	rsRetVal (*Load)(uchar *name, sbool bConfLoad, struct nvlst *lst);
187 	rsRetVal (*SetModDir)(uchar *name);
188 	modInfo_t *(*FindWithCnfName)(rsconf_t *cnf, uchar *name, eModType_t rqtdType); /* added v3, 2011-07-19 */
189 ENDinterface(module)
190 #define moduleCURR_IF_VERSION 5 /* increment whenever you change the interface structure! */
191 /* Changes:
192  * v2
193  * - added param bCondLoad to Load call - 2011-04-27
194  * - removed GetNxtType, added GetNxtCnfType - 2011-04-27
195  * v3 (see above)
196  * v4
197  * - added third parameter to Load() - 2012-06-20
198  */
199 
200 /* prototypes */
201 PROTOTYPEObj(module);
202 /* in v6, we go back to in-core static link for core objects, at least those
203  * that are not called from plugins.
204  * ... and we need to know that none of the module functions are called from plugins!
205  * rgerhards, 2012-09-24
206  */
207 rsRetVal modulesProcessCnf(struct cnfobj *o);
208 uchar *modGetName(modInfo_t *pThis);
209 rsRetVal ATTR_NONNULL(1) addModToCnfList(cfgmodules_etry_t **pNew, cfgmodules_etry_t *pLast);
210 rsRetVal readyModForCnf(modInfo_t *pThis, cfgmodules_etry_t **ppNew, cfgmodules_etry_t **ppLast);
211 void modDoHUP(void);
212 
213 #endif /* #ifndef MODULES_H_INCLUDED */
214