1 #ifndef SIEVE_EXT_VARIABLES_H
2 #define SIEVE_EXT_VARIABLES_H
3 
4 #include "lib.h"
5 
6 #include "sieve-common.h"
7 #include "sieve-extensions.h"
8 #include "sieve-objects.h"
9 #include "sieve-code.h"
10 
11 /* Public interface for other extensions to use
12  */
13 
14 /*
15  * Limits
16  */
17 
18 unsigned int
19 sieve_variables_get_max_scope_size(const struct sieve_extension *var_ext);
20 size_t
21 sieve_variables_get_max_variable_size(const struct sieve_extension *var_ext);
22 
23 /*
24  * Variable extension
25  */
26 
27 /* FIXME: this is not suitable for future plugin support */
28 
29 extern const struct sieve_extension_def variables_extension;
30 
sieve_ext_variables_get_extension(struct sieve_instance * svinst)31 static inline const struct sieve_extension *sieve_ext_variables_get_extension
32 (struct sieve_instance *svinst)
33 {
34 	return sieve_extension_register(svinst, &variables_extension, FALSE);
35 }
36 
37 /*
38  * Variable name
39  */
40 
41 struct sieve_variable_name {
42 	string_t *identifier;
43 	int num_variable;
44 };
45 
46 ARRAY_DEFINE_TYPE(sieve_variable_name, struct sieve_variable_name);
47 
48 bool sieve_variable_identifier_is_valid(const char *identifier);
49 
50 /*
51  * Variable scope
52  */
53 
54 struct sieve_variable {
55 	const char *identifier;
56 	unsigned int index;
57 
58 	const struct sieve_extension *ext;
59 	void *context;
60 };
61 
62 struct sieve_variable_scope;
63 
64 struct sieve_variable_scope *sieve_variable_scope_create
65 	(struct sieve_instance *svinst, const struct sieve_extension *var_ext,
66 		const struct sieve_extension *ext);
67 void sieve_variable_scope_ref
68 	(struct sieve_variable_scope *scope);
69 void sieve_variable_scope_unref
70 	(struct sieve_variable_scope **scope);
71 pool_t sieve_variable_scope_pool
72 	(struct sieve_variable_scope *scope);
73 
74 struct sieve_variable *sieve_variable_scope_declare
75 	(struct sieve_variable_scope *scope, const char *identifier);
76 struct sieve_variable *sieve_variable_scope_import
77 	(struct sieve_variable_scope *scope, struct sieve_variable *var);
78 struct sieve_variable *sieve_variable_scope_get_variable
79 	(struct sieve_variable_scope *scope, const char *identifier);
80 struct sieve_variable *sieve_variable_scope_get_indexed
81 	(struct sieve_variable_scope *scope, unsigned int index);
82 
83 /* Binary */
84 
85 struct sieve_variable_scope_binary *sieve_variable_scope_binary_create
86 	(struct sieve_variable_scope *scope);
87 
88 void sieve_variable_scope_binary_ref
89 	(struct sieve_variable_scope_binary *scpbin);
90 void sieve_variable_scope_binary_unref
91 	(struct sieve_variable_scope_binary **scpbin);
92 
93 struct sieve_variable_scope *sieve_variable_scope_binary_dump
94 	(struct sieve_instance *svinst,
95 		const struct sieve_extension *var_ext,
96 		const struct sieve_extension *ext,
97 		const struct sieve_dumptime_env *denv, sieve_size_t *address);
98 struct sieve_variable_scope_binary *sieve_variable_scope_binary_read
99 	(struct sieve_instance *svinst,
100 		const struct sieve_extension *var_ext,
101 		const struct sieve_extension *ext,
102 		struct sieve_binary_block *sblock, sieve_size_t *address);
103 
104 struct sieve_variable_scope *sieve_variable_scope_binary_get
105 	(struct sieve_variable_scope_binary *scpbin);
106 unsigned int sieve_variable_scope_binary_get_size
107 	(struct sieve_variable_scope_binary *scpbin);
108 
109 /*
110  * Variable namespaces
111  */
112 
113 struct sieve_variables_namespace;
114 
115 struct sieve_variables_namespace_def {
116 	struct sieve_object_def obj_def;
117 
118 	bool (*validate)
119 		(struct sieve_validator *valdtr,
120 			const struct sieve_variables_namespace *nspc,
121 			struct sieve_ast_argument *arg, struct sieve_command *cmd,
122 			ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data,
123 			bool assignment);
124 	bool (*generate)
125 		(const struct sieve_codegen_env *cgenv,
126 			const struct sieve_variables_namespace *nspc,
127 			struct sieve_ast_argument *arg, struct sieve_command *cmd,
128 			void *var_data);
129 
130 	bool (*dump_variable)
131 		(const struct sieve_dumptime_env *denv,
132 			const struct sieve_variables_namespace *nspc,
133 			const struct sieve_operand *oprnd, sieve_size_t *address);
134 	int (*read_variable)
135 		(const struct sieve_runtime_env *renv,
136 			const struct sieve_variables_namespace *nspc,
137 			const struct sieve_operand *oprnd, sieve_size_t *address, string_t **str);
138 };
139 
140 #define SIEVE_VARIABLES_DEFINE_NAMESPACE(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
141 #define SIEVE_VARIABLES_DEFINE_NAMESPACES(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
142 
143 struct sieve_variables_namespace {
144 	struct sieve_object object;
145 
146 	const struct sieve_variables_namespace_def *def;
147 };
148 
149 void sieve_variables_namespace_register
150 (const struct sieve_extension *var_ext, struct sieve_validator *valdtr,
151 	const struct sieve_extension *ext,
152 	const struct sieve_variables_namespace_def *nspc_def);
153 
154 extern const struct sieve_operand_class sieve_variables_namespace_operand_class;
155 
156 void sieve_variables_opr_namespace_variable_emit
157 	(struct sieve_binary_block *sblock, const struct sieve_extension *var_ext,
158     const struct sieve_extension *ext,
159     const struct sieve_variables_namespace_def *nspc_def);
160 
161 /* Iteration over all declared variables */
162 
163 struct sieve_variable_scope_iter;
164 
165 struct sieve_variable_scope_iter *sieve_variable_scope_iterate_init
166 	(struct sieve_variable_scope *scope);
167 bool sieve_variable_scope_iterate
168 	(struct sieve_variable_scope_iter *iter, struct sieve_variable **var_r);
169 void sieve_variable_scope_iterate_deinit
170 	(struct sieve_variable_scope_iter **iter);
171 
172 /* Statistics */
173 
174 unsigned int sieve_variable_scope_declarations
175 	(struct sieve_variable_scope *scope);
176 unsigned int sieve_variable_scope_size
177 	(struct sieve_variable_scope *scope);
178 
179 /* Get all native variables */
180 
181 struct sieve_variable * const *sieve_variable_scope_get_variables
182 	(struct sieve_variable_scope *scope, unsigned int *size_r);
183 
184 /*
185  * Variable storage
186  */
187 
188 struct sieve_variable_storage;
189 
190 struct sieve_variable_storage *sieve_variable_storage_create
191 	(const struct sieve_extension *var_ext, pool_t pool,
192 		struct sieve_variable_scope_binary *scpbin);
193 bool sieve_variable_get
194 	(struct sieve_variable_storage *storage, unsigned int index,
195 		string_t **value);
196 bool sieve_variable_get_modifiable
197 	(struct sieve_variable_storage *storage, unsigned int index,
198 		string_t **value);
199 bool sieve_variable_assign
200 	(struct sieve_variable_storage *storage, unsigned int index,
201 		const string_t *value);
202 bool sieve_variable_assign_cstr
203 	(struct sieve_variable_storage *storage, unsigned int index,
204 		const char *value);
205 bool sieve_variable_get_identifier
206 	(struct sieve_variable_storage *storage, unsigned int index,
207 		const char **identifier);
208 const char *sieve_variable_get_varid
209 	(struct sieve_variable_storage *storage, unsigned int index);
210 
211 /*
212  * Variables access
213  */
214 
215 bool sieve_ext_variables_is_active
216 	(const struct sieve_extension *var_ext, struct sieve_validator *valdtr);
217 
218 struct sieve_variable_scope *sieve_ext_variables_get_local_scope
219 	(const struct sieve_extension *var_ext, struct sieve_validator *valdtr);
220 
221 /* Runtime */
222 
sieve_ext_variables_get_varid(const struct sieve_extension * ext,unsigned int index)223 static inline const char *sieve_ext_variables_get_varid
224 (const struct sieve_extension *ext, unsigned int index)
225 {
226 	if ( ext == NULL )
227 		return t_strdup_printf("%ld", (long) index);
228 
229 	return t_strdup_printf("%s:%ld", sieve_extension_name(ext), (long) index);
230 }
231 
232 struct sieve_variable_storage *sieve_ext_variables_runtime_get_storage
233 	(const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv,
234 		const struct sieve_extension *ext);
235 void sieve_ext_variables_runtime_set_storage
236 	(const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv,
237 		const struct sieve_extension *ext, struct sieve_variable_storage *storage);
238 
239 const char *sieve_ext_variables_runtime_get_identifier
240 (const struct sieve_extension *var_ext, const struct sieve_runtime_env *renv,
241 	const struct sieve_extension *ext, unsigned int index);
242 
243 /*
244  * Variable arguments
245  */
246 
247 bool sieve_variable_argument_activate
248 	(const struct sieve_extension *var_ext,
249 		const struct sieve_extension *this_ext,
250 		struct sieve_validator *valdtr, struct sieve_command *cmd,
251 		struct sieve_ast_argument *arg, bool assignment);
252 
253 /*
254  * Variable operands
255  */
256 
257 extern const struct sieve_operand_def variable_operand;
258 
259 void sieve_variables_opr_variable_emit
260 	(struct sieve_binary_block *sblock, const struct sieve_extension *var_ext,
261 		struct sieve_variable *var);
262 void sieve_variables_opr_match_value_emit
263 	(struct sieve_binary_block *sblock, const struct sieve_extension *var_ext,
264 		unsigned int index);
265 
266 int sieve_variable_operand_read_data
267 	(const struct sieve_runtime_env *renv, struct sieve_operand *operand,
268 		sieve_size_t *address, const char *field_name,
269 		struct sieve_variable_storage **storage_r, unsigned int *var_index_r);
270 int sieve_variable_operand_read
271 	(const struct sieve_runtime_env *renv, sieve_size_t *address,
272 		const char *field_name, struct sieve_variable_storage **storage_r,
273 		unsigned int *var_index_r);
274 
sieve_operand_is_variable(const struct sieve_operand * operand)275 static inline bool sieve_operand_is_variable
276 (const struct sieve_operand *operand)
277 {
278 	return ( operand != NULL && operand->def != NULL &&
279 		operand->def == &variable_operand );
280 }
281 
282 /*
283  * Modifiers
284  */
285 
286 /* Definition */
287 
288 struct sieve_variables_modifier;
289 
290 struct sieve_variables_modifier_def {
291 	struct sieve_object_def obj_def;
292 
293 	unsigned int precedence;
294 
295 	bool (*modify)(const struct sieve_variables_modifier *modf,
296 		       string_t *in, string_t **result);
297 };
298 
299 struct sieve_variables_modifier {
300 	struct sieve_object object;
301 	const struct sieve_extension *var_ext;
302 
303 	const struct sieve_variables_modifier_def *def;
304 };
305 
306 #define SIEVE_VARIABLES_DEFINE_MODIFIER(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
307 #define SIEVE_VARIABLES_DEFINE_MODIFIERS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)
308 
309 #define sieve_variables_modifier_name(smodf) \
310 	( (smodf)->object.def->identifier )
311 
312 ARRAY_DEFINE_TYPE(sieve_variables_modifier,
313 	struct sieve_variables_modifier);
314 
315 /* Registry */
316 
317 void sieve_variables_modifier_register
318 	(const struct sieve_extension *var_ext, struct sieve_validator *valdtr,
319 		const struct sieve_extension *ext,
320 		const struct sieve_variables_modifier_def *smodf);
321 
322 /* Tagged argument */
323 
324 void sieve_variables_modifiers_link_tag
325 	(struct sieve_validator *valdtr, const struct sieve_extension *var_ext,
326 		struct sieve_command_registration *cmd_reg);
327 
328 bool sieve_variables_modifiers_validate
329 	(struct sieve_validator *valdtr, struct sieve_command *cmd,
330 		ARRAY_TYPE(sieve_variables_modifier) *modifiers);
331 
332 bool sieve_variables_modifiers_generate
333 	(const struct sieve_codegen_env *cgenv,
334 		ARRAY_TYPE(sieve_variables_modifier) *modifiers);
335 
336 /* Coding */
337 
338 extern const struct sieve_operand_class
339 	sieve_variables_modifier_operand_class;
340 
341 bool sieve_variables_modifiers_code_dump
342 	(const struct sieve_dumptime_env *denv, sieve_size_t *address);
343 int sieve_variables_modifiers_code_read(
344 	const struct sieve_runtime_env *renv,
345 	const struct sieve_extension *var_ext, sieve_size_t *address,
346 	ARRAY_TYPE(sieve_variables_modifier) *modifiers);
347 
348 /* Application */
349 
350 int sieve_variables_modifiers_apply
351 (const struct sieve_runtime_env *renv,
352 	const struct sieve_extension *var_ext,
353 	ARRAY_TYPE(sieve_variables_modifier) *modifiers,
354 	string_t **value);
355 
356 /*
357  * Code dumping
358  */
359 
360 void sieve_ext_variables_dump_set_scope
361 (const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv,
362 	const struct sieve_extension *ext, struct sieve_variable_scope *scope);
363 
364 #endif
365