1 #ifndef SIEVE_EXTENSIONS_H
2 #define SIEVE_EXTENSIONS_H
3 
4 #include "lib.h"
5 #include "sieve-common.h"
6 
7 /*
8  * Per-extension object registry
9  */
10 
11 struct sieve_extension_objects {
12 	const void *objects;
13 	unsigned int count;
14 };
15 
16 /*
17  * Extension definition
18  */
19 
20 struct sieve_extension_def {
21 	const char *name;
22 
23 	/* Version */
24 	unsigned int version;
25 
26 	/* Registration */
27 	bool (*load)(const struct sieve_extension *ext, void **context);
28 	void (*unload)(const struct sieve_extension *ext);
29 
30 	/* Compilation */
31 	bool (*validator_load)
32 		(const struct sieve_extension *ext, struct sieve_validator *validator);
33 	bool (*generator_load)
34 		(const struct sieve_extension *ext, const struct sieve_codegen_env *cgenv);
35 	bool (*interpreter_load)
36 		(const struct sieve_extension *ext, const struct sieve_runtime_env *renv,
37 			sieve_size_t *address);
38 	bool (*binary_load)
39 		(const struct sieve_extension *ext, struct sieve_binary *binary);
40 
41 	/* Code dump */
42 	bool (*binary_dump)
43 		(const struct sieve_extension *ext, struct sieve_dumptime_env *denv);
44 	bool (*code_dump)
45 		(const struct sieve_extension *ext, const struct sieve_dumptime_env *denv,
46 			sieve_size_t *address);
47 
48 	/* Objects */
49 	struct sieve_extension_objects operations;
50 	struct sieve_extension_objects operands;
51 };
52 
53 /* Defining opcodes and operands */
54 
55 #define SIEVE_EXT_DEFINE_NO_OBJECTS \
56 	{ NULL, 0 }
57 #define SIEVE_EXT_DEFINE_OBJECT(OBJ) \
58 	{ &OBJ, 1 }
59 #define SIEVE_EXT_DEFINE_OBJECTS(OBJS) \
60 	{ OBJS, N_ELEMENTS(OBJS) }
61 
62 #define SIEVE_EXT_GET_OBJECTS_COUNT(ext, field) \
63 	ext->field->count;
64 
65 #define SIEVE_EXT_DEFINE_NO_OPERATIONS \
66 	.operations = SIEVE_EXT_DEFINE_NO_OBJECTS
67 #define SIEVE_EXT_DEFINE_OPERATION(OP) \
68 	.operations = SIEVE_EXT_DEFINE_OBJECT(OP)
69 #define SIEVE_EXT_DEFINE_OPERATIONS(OPS) \
70 	.operations = SIEVE_EXT_DEFINE_OBJECTS(OPS)
71 
72 #define SIEVE_EXT_DEFINE_NO_OPERANDS \
73 	.operands = SIEVE_EXT_DEFINE_NO_OBJECTS
74 #define SIEVE_EXT_DEFINE_OPERAND(OP) \
75 	.operands = SIEVE_EXT_DEFINE_OBJECT(OP)
76 #define SIEVE_EXT_DEFINE_OPERANDS(OPS) \
77 	.operands = SIEVE_EXT_DEFINE_OBJECTS(OPS)
78 
79 /*
80  * Extension instance
81  */
82 
83 struct sieve_extension {
84 	const struct sieve_extension_def *def;
85 	int id;
86 
87 	struct sieve_instance *svinst;
88 	void *context;
89 
90 	bool required:1;
91 	bool loaded:1;
92 	bool enabled:1;
93 	bool dummy:1;
94 	bool global:1;
95 	bool implicit:1;
96 	bool overridden:1;
97 };
98 
99 #define sieve_extension_is(ext, definition) \
100 	( (ext)->def == &(definition) )
101 #define sieve_extension_name(ext) \
102 	((ext)->def->name)
103 #define sieve_extension_name_is(ext, _name) \
104 	( strcmp((ext)->def->name, (_name)) == 0 )
105 #define sieve_extension_version(ext) \
106 	((ext)->def->version)
107 #define sieve_extension_version_is(ext, _version) \
108 	((ext)->def->version == (_version))
109 
110 /*
111  * Extensions init/deinit
112  */
113 
114 bool sieve_extensions_init(struct sieve_instance *svinst);
115 void sieve_extensions_configure(struct sieve_instance *svinst);
116 void sieve_extensions_deinit(struct sieve_instance *svinst);
117 
118 /*
119  * Pre-loaded extensions
120  */
121 
122 const struct sieve_extension *const *sieve_extensions_get_preloaded
123 	(struct sieve_instance *svinst, unsigned int *count_r);
124 
125 /*
126  * Extension registry
127  */
128 
129 const struct sieve_extension *sieve_extension_register
130 	(struct sieve_instance *svinst, const struct sieve_extension_def *extension,
131 		bool load);
132 const struct sieve_extension *sieve_extension_require
133 	(struct sieve_instance *svinst, const struct sieve_extension_def *extension,
134 		bool load);
135 bool sieve_extension_reload(const struct sieve_extension *ext);
136 
137 void sieve_extension_unregister(const struct sieve_extension *ext);
138 
139 const struct sieve_extension *sieve_extension_replace
140 	(struct sieve_instance *svinst,
141 		const struct sieve_extension_def *extdef,
142 		bool load);
143 void sieve_extension_override
144 	(struct sieve_instance *svinst, const char *name,
145 		const struct sieve_extension *ext);
146 
147 unsigned int sieve_extensions_get_count(struct sieve_instance *svinst);
148 const struct sieve_extension *const *
149 sieve_extensions_get_all(struct sieve_instance *svinst,
150 	unsigned int *count_r);
151 
152 const struct sieve_extension *sieve_extension_get_by_id
153 	(struct sieve_instance *svinst, unsigned int ext_id);
154 const struct sieve_extension *sieve_extension_get_by_name
155 	(struct sieve_instance *svinst, const char *name);
156 
157 const char *sieve_extensions_get_string
158 	(struct sieve_instance *svinst);
159 void sieve_extensions_set_string
160 	(struct sieve_instance *svinst, const char *ext_string,
161 		bool global, bool implicit);
162 
163 const struct sieve_extension *sieve_get_match_type_extension
164 	(struct sieve_instance *svinst);
165 const struct sieve_extension *sieve_get_comparator_extension
166 	(struct sieve_instance *svinst);
167 const struct sieve_extension *sieve_get_address_part_extension
168 	(struct sieve_instance *svinst);
169 
170 void sieve_enable_debug_extension(struct sieve_instance *svinst);
171 
172 /*
173  * Capability registries
174  */
175 
176 struct sieve_extension_capabilities {
177 	const char *name;
178 
179 	const char *(*get_string)(const struct sieve_extension *ext);
180 };
181 
182 void sieve_extension_capabilities_register
183 	(const struct sieve_extension *ext,
184 		const struct sieve_extension_capabilities *cap);
185 void sieve_extension_capabilities_unregister
186 	(const struct sieve_extension *ext);
187 
188 const char *sieve_extension_capabilities_get_string
189 	(struct sieve_instance *svinst, const char *cap_name);
190 
191 #endif
192