1 /* GNU Mailutils -- a suite of utilities for electronic mail
2    Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 3 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General
15    Public License along with this library.  If not, see
16    <http://www.gnu.org/licenses/>. */
17 
18 #ifndef _MAILUTILS_LIBSIEVE_H
19 #define _MAILUTILS_LIBSIEVE_H
20 
21 #include <sys/types.h>
22 #include <stdarg.h>
23 #include <mailutils/mailutils.h>
24 #include <mailutils/cli.h>
25 #include <mailutils/locus.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 #define __s_cat3__(a,b,c) a ## b ## c
32 #define SIEVE_EXPORT(module,name) __s_cat3__(module,_LTX_,name)
33 
34 typedef struct mu_sieve_machine *mu_sieve_machine_t;
35 
36 typedef struct mu_sieve_string
37 {
38   unsigned constant:1;       /* String is constant */
39   unsigned changed:1;        /* String value has changed */
40   char *orig;                /* String original value */
41   char *exp;                 /* Actual string value after expansion */
42   void *rx;                  /* Pointer to the corresponding regular expr */
43 } mu_sieve_string_t;
44 
45 typedef int (*mu_sieve_handler_t) (mu_sieve_machine_t mach);
46 typedef void (*mu_sieve_action_log_t) (mu_sieve_machine_t mach,
47 				       const char *action,
48 				       const char *fmt, va_list ap);
49 
50 typedef int (*mu_sieve_relcmp_t) (int, int);
51 typedef int (*mu_sieve_relcmpn_t) (size_t, size_t);
52 typedef int (*mu_sieve_comparator_t) (mu_sieve_machine_t mach,
53 				      mu_sieve_string_t *, const char *);
54 typedef int (*mu_sieve_retrieve_t) (void *item, void *data, size_t idx,
55 				    char **pval);
56 typedef void (*mu_sieve_destructor_t) (void *data);
57 typedef int (*mu_sieve_tag_checker_t) (mu_sieve_machine_t mach);
58 
59 typedef enum
60 {
61   SVT_VOID,
62   SVT_NUMBER,
63   SVT_STRING,
64   SVT_STRING_LIST,
65   SVT_TAG,
66 }
67 mu_sieve_data_type;
68 
69 /* Struct mu_sieve_slice represents a contiguous slice of an array of strings
70    or variables */
71 struct mu_sieve_slice
72 {
73   size_t first;            /* Index of the first object */
74   size_t count;            /* Number of objects */
75 };
76 
77 typedef struct mu_sieve_slice *mu_sieve_slice_t;
78 
79 union mu_sieve_value_storage
80 {
81   char *string;
82   size_t number;
83   struct mu_sieve_slice list;
84 };
85 
86 typedef struct
87 {
88   mu_sieve_data_type type;
89   char *tag;
90   struct mu_locus_range locus;
91   union mu_sieve_value_storage v;
92 } mu_sieve_value_t;
93 
94 typedef struct
95 {
96   char *name;
97   mu_sieve_data_type argtype;
98 } mu_sieve_tag_def_t;
99 
100 typedef struct
101 {
102   mu_sieve_tag_def_t *tags;
103   mu_sieve_tag_checker_t checker;
104 } mu_sieve_tag_group_t;
105 
106 struct mu_sieve_command          /* test or action */
107 {
108   mu_sieve_handler_t handler;
109   mu_sieve_data_type *req_args;
110   mu_sieve_data_type *opt_args;
111   mu_sieve_tag_group_t *tags;
112 };
113 
114 #define MU_SIEVE_MATCH_IS        1
115 #define MU_SIEVE_MATCH_CONTAINS  2
116 #define MU_SIEVE_MATCH_MATCHES   3
117 #define MU_SIEVE_MATCH_REGEX     4
118 #define MU_SIEVE_MATCH_EQ        5
119 #define MU_SIEVE_MATCH_LAST      6
120 
121 enum mu_sieve_record
122   {
123     mu_sieve_record_action,
124     mu_sieve_record_test,
125     mu_sieve_record_comparator
126   };
127 
128 typedef struct
129 {
130   const char *name;
131   int required;
132   void *handle;
133   enum mu_sieve_record type;
134   union
135   {
136     struct mu_sieve_command command;
137     mu_sieve_comparator_t comp[MU_SIEVE_MATCH_LAST];
138   } v;
139 } mu_sieve_registry_t;
140 
141 #define MU_SIEVE_CHARSET "UTF-8"
142 
143 extern mu_debug_handle_t mu_sieve_debug_handle;
144 extern mu_list_t mu_sieve_include_path;
145 extern mu_list_t mu_sieve_library_path;
146 extern mu_list_t mu_sieve_library_path_prefix;
147 
148 extern mu_sieve_tag_def_t mu_sieve_match_part_tags[];
149 
150 /* Memory allocation functions */
151 typedef void (*mu_sieve_reclaim_t) (void *);
152 void mu_sieve_register_memory (mu_sieve_machine_t mach, void *ptr,
153 			       mu_sieve_reclaim_t reclaim);
154 void *mu_sieve_alloc_memory (mu_sieve_machine_t mach, size_t size,
155 			     mu_sieve_reclaim_t recfun);
156 void mu_sieve_free (mu_sieve_machine_t mach, void *ptr);
157 void *mu_sieve_malloc (mu_sieve_machine_t mach, size_t size);
158 void *mu_sieve_calloc (mu_sieve_machine_t mach, size_t nmemb, size_t size);
159 char *mu_sieve_strdup (mu_sieve_machine_t mach, char const *str);
160 void *mu_sieve_realloc (mu_sieve_machine_t mach, void *ptr, size_t size);
161 
162 void mu_sieve_reclaim_default (void *p);
163 void mu_sieve_reclaim_value (void *p);
164 
165 size_t mu_sieve_value_create (mu_sieve_machine_t mach,
166 			      mu_sieve_data_type type,
167 			      struct mu_locus_range const *locus,
168 			      void *data);
169 
170 /* Symbol space functions */
171 mu_sieve_registry_t *mu_sieve_registry_add (mu_sieve_machine_t mach,
172 					    const char *name);
173 mu_sieve_registry_t *mu_sieve_registry_lookup (mu_sieve_machine_t mach,
174 					       const char *name,
175 					       enum mu_sieve_record type);
176 int mu_sieve_registry_require (mu_sieve_machine_t mach, const char *name,
177 			       enum mu_sieve_record type);
178 
179 void mu_sieve_register_test_ext (mu_sieve_machine_t mach,
180 				 const char *name, mu_sieve_handler_t handler,
181 				 mu_sieve_data_type *req_args,
182 				 mu_sieve_data_type *opt_args,
183 				 mu_sieve_tag_group_t *tags, int required);
184 void mu_sieve_register_test (mu_sieve_machine_t mach,
185 			     const char *name, mu_sieve_handler_t handler,
186 			     mu_sieve_data_type *arg_types,
187 			     mu_sieve_tag_group_t *tags, int required);
188 
189 void mu_sieve_register_action_ext (mu_sieve_machine_t mach,
190 				   const char *name, mu_sieve_handler_t handler,
191 				   mu_sieve_data_type *req_args,
192 				   mu_sieve_data_type *opt_args,
193 				   mu_sieve_tag_group_t *tags, int required);
194 void mu_sieve_register_action (mu_sieve_machine_t mach,
195 			       const char *name, mu_sieve_handler_t handler,
196 			       mu_sieve_data_type *arg_types,
197 			       mu_sieve_tag_group_t *tags, int required);
198 
199 void mu_sieve_register_comparator (mu_sieve_machine_t mach, const char *name,
200 				   int required, mu_sieve_comparator_t is,
201 				   mu_sieve_comparator_t contains,
202 				   mu_sieve_comparator_t matches,
203 				   mu_sieve_comparator_t regex,
204 				   mu_sieve_comparator_t eq);
205 
206 int mu_sieve_require_relational (mu_sieve_machine_t mach, const char *name);
207 
208 int mu_sieve_require_variables (mu_sieve_machine_t mach);
209 int mu_sieve_has_variables (mu_sieve_machine_t mach);
210 int mu_sieve_variable_initialize (mu_sieve_machine_t mach,
211 				  char const *name, char const *value);
212 
213 int mu_sieve_require_environment (mu_sieve_machine_t mach);
214 
215 void *mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name);
216 void mu_sieve_unload_ext (void *handle);
217 
218 int mu_sieve_match_part_checker (mu_sieve_machine_t mach);
219 
220 mu_sieve_comparator_t mu_sieve_comparator_lookup (mu_sieve_machine_t mach,
221 						  const char *name,
222 						  int matchtype);
223 
224 mu_sieve_comparator_t mu_sieve_get_comparator (mu_sieve_machine_t mach);
225 int mu_sieve_str_to_relcmp (const char *str, mu_sieve_relcmp_t *test,
226 			    mu_sieve_relcmpn_t *stest);
227 mu_sieve_relcmp_t mu_sieve_get_relcmp (mu_sieve_machine_t mach);
228 
229 void mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t list);
230 
231 void mu_sieve_value_get (mu_sieve_machine_t mach, mu_sieve_value_t *val,
232 			 mu_sieve_data_type type, void *ret);
233 /* Tagged argument accessors */
234 int mu_sieve_get_tag (mu_sieve_machine_t mach, char *name,
235 		      mu_sieve_data_type type, void *ret);
236 mu_sieve_value_t *mu_sieve_get_tag_untyped (mu_sieve_machine_t mach,
237 					    char const *name);
238 mu_sieve_value_t *mu_sieve_get_tag_n (mu_sieve_machine_t mach, size_t n);
239 
240 /* Positional argument accessors */
241 mu_sieve_value_t *mu_sieve_get_arg_optional (mu_sieve_machine_t mach,
242 					     size_t index);
243 mu_sieve_value_t *mu_sieve_get_arg_untyped (mu_sieve_machine_t mach,
244 					    size_t index);
245 void mu_sieve_get_arg (mu_sieve_machine_t mach, size_t index,
246 		       mu_sieve_data_type type, void *ret);
247 /* String and string list accessors */
248 char *mu_sieve_string (mu_sieve_machine_t mach,
249 		       mu_sieve_slice_t slice,
250 		       size_t i);
251 mu_sieve_string_t *mu_sieve_string_raw (mu_sieve_machine_t mach,
252 					mu_sieve_slice_t slice,
253 					size_t i);
254 char *mu_sieve_string_get (mu_sieve_machine_t mach, mu_sieve_string_t *string);
255 
256 /* Operations on value lists */
257 int mu_sieve_vlist_do (mu_sieve_machine_t mach,
258 		       mu_sieve_value_t *val, mu_list_action_t ac,
259 		       void *data);
260 int mu_sieve_vlist_compare (mu_sieve_machine_t mach,
261 			    mu_sieve_value_t *a, mu_sieve_value_t *b,
262 			    mu_sieve_retrieve_t ac, mu_list_folder_t fold,
263 			    void *data);
264 
265 /* Functions to create and destroy sieve machine */
266 int mu_sieve_machine_create (mu_sieve_machine_t *mach);
267 int mu_sieve_machine_dup (mu_sieve_machine_t const in,
268 			  mu_sieve_machine_t *out);
269 int mu_sieve_machine_clone (mu_sieve_machine_t const in,
270 			      mu_sieve_machine_t *out);
271 void mu_sieve_machine_destroy (mu_sieve_machine_t *pmach);
272 void mu_sieve_machine_add_destructor (mu_sieve_machine_t mach,
273 				      mu_sieve_destructor_t destr, void *ptr);
274 
275 /* Functions for accessing sieve machine internals */
276 void mu_sieve_get_diag_stream (mu_sieve_machine_t mach, mu_stream_t *pstr);
277 void mu_sieve_set_diag_stream (mu_sieve_machine_t mach, mu_stream_t str);
278 
279 void mu_sieve_set_dbg_stream (mu_sieve_machine_t mach, mu_stream_t str);
280 void mu_sieve_get_dbg_stream (mu_sieve_machine_t mach, mu_stream_t *pstr);
281 
282 void *mu_sieve_get_data (mu_sieve_machine_t mach);
283 void mu_sieve_set_data (mu_sieve_machine_t mach, void *);
284 mu_message_t mu_sieve_get_message (mu_sieve_machine_t mach);
285 size_t mu_sieve_get_message_num (mu_sieve_machine_t mach);
286 
287 mu_mailbox_t mu_sieve_get_mailbox (mu_sieve_machine_t mach);
288 
289 int mu_sieve_is_dry_run (mu_sieve_machine_t mach);
290 int mu_sieve_set_dry_run (mu_sieve_machine_t mach, int val);
291 
292 void mu_sieve_get_argc (mu_sieve_machine_t mach, size_t *args, size_t *tags);
293 
294 mu_mailer_t mu_sieve_get_mailer (mu_sieve_machine_t mach);
295 int mu_sieve_get_locus (mu_sieve_machine_t mach, struct mu_locus_range *);
296 char *mu_sieve_get_daemon_email (mu_sieve_machine_t mach);
297 const char *mu_sieve_get_identifier (mu_sieve_machine_t mach);
298 
299 void mu_sieve_set_logger (mu_sieve_machine_t mach,
300 			  mu_sieve_action_log_t logger);
301 void mu_sieve_set_mailer (mu_sieve_machine_t mach, mu_mailer_t mailer);
302 void mu_sieve_set_daemon_email (mu_sieve_machine_t mach, const char *email);
303 
304 int mu_sieve_get_message_sender (mu_message_t msg, char **ptext);
305 
306 int mu_sieve_get_environ (mu_sieve_machine_t mach, char const *name,
307 			  char **retval);
308 int mu_sieve_set_environ (mu_sieve_machine_t mach, char const *name,
309 			  char const *value);
310 
311 /* Stream state saving & restoring */
312 void mu_sieve_stream_save (mu_sieve_machine_t mach);
313 void mu_sieve_stream_restore (mu_sieve_machine_t mach);
314 
315 /* Logging and diagnostic functions */
316 
317 void mu_sieve_debug_init (void);
318 void mu_sieve_error (mu_sieve_machine_t mach, const char *fmt, ...)
319                      MU_PRINTFLIKE(2,3);
320 void mu_sieve_log_action (mu_sieve_machine_t mach, const char *action,
321 			  const char *fmt, ...)
322 			  MU_PRINTFLIKE(3,4);
323 void mu_sieve_abort (mu_sieve_machine_t mach);
324 
325 const char *mu_sieve_type_str (mu_sieve_data_type type);
326 
327 /* Principal entry points */
328 
329 int mu_sieve_compile (mu_sieve_machine_t mach, const char *name);
330 int mu_sieve_compile_text (mu_sieve_machine_t mach,
331 			   const char *buf, size_t bufsize,
332 			   struct mu_locus_point const *pt);
333 int mu_sieve_mailbox (mu_sieve_machine_t mach, mu_mailbox_t mbox);
334 int mu_sieve_message (mu_sieve_machine_t mach, mu_message_t message);
335 int mu_sieve_disass (mu_sieve_machine_t mach);
336 
337 /* Configuration functions */
338 
339 #define MU_SIEVE_CLEAR_INCLUDE_PATH 0x1
340 #define MU_SIEVE_CLEAR_LIBRARY_PATH 0x2
341 
342 extern struct mu_cli_capa mu_cli_capa_sieve;
343 
344 #ifdef __cplusplus
345 }
346 #endif
347 
348 #endif
349