Document changes to Sieve
* NEWS: Update. * doc/texinfo/libmu_sieve.texi: Update. * doc/texinfo/sieve.texi: Document extensions * libmu_sieve/comparator.c (mu_sieve_match_part_checker): Check the type of the 2nd argument. * sieve/sieve.c: Define "location" and "phase" environment items. * sieve/tests/pipetest.at: Use "pipe" as the capability string.
Showing
6 changed files
with
654 additions
and
259 deletions
1 | GNU mailutils NEWS -- history of user-visible changes. 2016-12-07 | 1 | GNU mailutils NEWS -- history of user-visible changes. 2016-12-13 |
2 | Copyright (C) 2002-2016 Free Software Foundation, Inc. | 2 | Copyright (C) 2002-2016 Free Software Foundation, Inc. |
3 | See the end of file for copying conditions. | 3 | See the end of file for copying conditions. |
4 | 4 | ||
... | @@ -7,8 +7,34 @@ Please send mailutils bug reports to <bug-mailutils@gnu.org>. | ... | @@ -7,8 +7,34 @@ Please send mailutils bug reports to <bug-mailutils@gnu.org>. |
7 | 7 | ||
8 | Version 3.0.90 (Git) | 8 | Version 3.0.90 (Git) |
9 | 9 | ||
10 | Sieve library essentially rewritten. It now inludes support for | 10 | * Sieve |
11 | the "variables" extension (RFC 5229). | 11 | |
12 | The Sieve library essentially rewritten. The following new extensions | ||
13 | are implemented: | ||
14 | |||
15 | encoded-character - RFC 5228, 2.4.2.4 | ||
16 | variables - RFC 5229 | ||
17 | environment - RFC 5183 | ||
18 | |||
19 | The tools define the Sieve environment "location", and | ||
20 | "phase" as follows: | ||
21 | |||
22 | Utility | "location" | "phase" | ||
23 | --------+-------------+-------- | ||
24 | maidag | "MDA" | "during" | ||
25 | inc | "MUA" | "post" | ||
26 | sieve | "MS" | "post" | ||
27 | |||
28 | The "sieve" utility provides new option: --environment, for | ||
29 | manipulating the environment. | ||
30 | |||
31 | * Bugfixes | ||
32 | ** Fix program name duplicate in the output of "mailutils help COMMAND" | ||
33 | ** Fix several bugs in mhn | ||
34 | ** Fix expansion of #, &, %, etc. in mail "copy" and "file" commands. | ||
35 | ** Fix improper permissions after delivery to MH and Maildir mailboxes. | ||
36 | ** Fix stream flushing code | ||
37 | ** Fix the implementation of -nowhatnowproc option in mh | ||
12 | 38 | ||
13 | 39 | ||
14 | Version 3.0 - 2016-11-06 | 40 | Version 3.0 - 2016-11-06 | ... | ... |
... | @@ -44,6 +44,8 @@ Sieve Library. | ... | @@ -44,6 +44,8 @@ Sieve Library. |
44 | * Sieve Data Types:: | 44 | * Sieve Data Types:: |
45 | * Manipulating the Sieve Machine:: | 45 | * Manipulating the Sieve Machine:: |
46 | * Logging and Diagnostic Functions:: | 46 | * Logging and Diagnostic Functions:: |
47 | * String Accessors:: | ||
48 | * Argument Accessors:: | ||
47 | * Symbol Space Functions:: | 49 | * Symbol Space Functions:: |
48 | * Memory Allocation:: | 50 | * Memory Allocation:: |
49 | * Compiling and Executing the Script:: | 51 | * Compiling and Executing the Script:: |
... | @@ -53,13 +55,13 @@ Sieve Library. | ... | @@ -53,13 +55,13 @@ Sieve Library. |
53 | @node Sieve Data Types | 55 | @node Sieve Data Types |
54 | @subsection Sieve Data Types | 56 | @subsection Sieve Data Types |
55 | 57 | ||
56 | @deftp {Data Type} sieve_machine_t | 58 | @deftp {Data Type} mu_sieve_machine_t |
57 | This is an opaque data type representing a pointer to an instance of | 59 | This is an opaque data type representing a pointer to an instance of |
58 | sieve machine. The @code{sieve_machine_t} keeps all information necessary | 60 | sieve machine. The @code{mu_sieve_machine_t} keeps all information necessary |
59 | for compiling and executing the script. | 61 | for compiling and executing the script. |
60 | 62 | ||
61 | It is created by @code{sieve_machine_create()} and destroyed by | 63 | It is created by @code{mu_sieve_machine_create()} and destroyed by |
62 | @code{sieve_machine_destroy()}. The functions for manipulating this data | 64 | @code{mu_sieve_machine_destroy()}. The functions for manipulating this data |
63 | type are described in @ref{Manipulating the Sieve Machine}. | 65 | type are described in @ref{Manipulating the Sieve Machine}. |
64 | @end deftp | 66 | @end deftp |
65 | 67 | ||
... | @@ -77,16 +79,13 @@ Numeric type. | ... | @@ -77,16 +79,13 @@ Numeric type. |
77 | Character string. | 79 | Character string. |
78 | 80 | ||
79 | @item SVT_STRING_LIST | 81 | @item SVT_STRING_LIST |
80 | A @code{mu_list_t}. Each item in this list represents a character string. | 82 | A list of strings. |
81 | 83 | ||
82 | @item SVT_TAG | 84 | @item SVT_TAG |
83 | A sieve tag. See @code{mu_sieve_runtime_tag_t} below. | 85 | A sieve tag. This data type is available only during the |
84 | 86 | compilation. On runtime, all tags are converted to one of the above | |
85 | @item SVT_IDENT | 87 | types, depending on their arguments. Tags without arguments are |
86 | A character string representing an identifier. | 88 | converted to SVT_VOID. |
87 | |||
88 | @item SVT_POINTER | ||
89 | An opaque pointer. | ||
90 | @end table | 89 | @end table |
91 | @end deftp | 90 | @end deftp |
92 | 91 | ||
... | @@ -96,18 +95,23 @@ as follows: | ... | @@ -96,18 +95,23 @@ as follows: |
96 | 95 | ||
97 | @smallexample | 96 | @smallexample |
98 | @group | 97 | @group |
99 | typedef struct | 98 | typedef struct |
100 | @{ | 99 | @{ |
101 | mu_sieve_data_type type; /* Type of the data */ | 100 | union mu_sieve_value_storage |
102 | union @{ | 101 | @{ |
103 | char *string; /* String value or identifier */ | 102 | char *string; |
104 | size_t number; /* Numeric value */ | 103 | size_t number; |
105 | mu_list_t list; /* List value */ | 104 | struct mu_sieve_slice list; |
106 | mu_sieve_runtime_tag_t *tag; /* Tag value */ | 105 | @}; |
107 | void *ptr; /* Pointer value */ | 106 | |
108 | @} v; | 107 | typedef struct |
109 | @} | 108 | @{ |
110 | mu_sieve_value_t; | 109 | mu_sieve_data_type type; |
110 | char *tag; | ||
111 | union mu_sieve_value_storage v; | ||
112 | @} mu_sieve_value_t; | ||
113 | @} | ||
114 | mu_sieve_value_t; | ||
111 | @end group | 115 | @end group |
112 | @end smallexample | 116 | @end smallexample |
113 | 117 | ||
... | @@ -116,25 +120,48 @@ union @code{v} keep the actual value: | ... | @@ -116,25 +120,48 @@ union @code{v} keep the actual value: |
116 | 120 | ||
117 | @table @code | 121 | @table @code |
118 | @item SVT_VOID | 122 | @item SVT_VOID |
119 | Never appears. | 123 | No associated value. |
120 | 124 | ||
121 | @item SVT_NUMBER | 125 | @item SVT_NUMBER |
122 | The numeric value is kept in @code{number} member. | 126 | The numeric value is kept in the @code{number} member. |
123 | |||
124 | @item SVT_STRING | ||
125 | The string is kept in @code{string} member. | ||
126 | 127 | ||
127 | @item SVT_STRING_LIST | 128 | @item SVT_STRING_LIST |
128 | The list itself is pointed to by @code{list} member | 129 | @itemx SVT_STRING |
130 | The list is identified by the @code{list} member of the union | ||
131 | @code{mu_sieve_value_storage}. This member is defined as follows: | ||
129 | 132 | ||
130 | @item SVT_TAG | 133 | @example |
131 | The tag value is pointed to by @code{tag} member. | 134 | struct mu_sieve_slice |
135 | @{ | ||
136 | size_t first; /* Index of the first string */ | ||
137 | size_t count; /* Number of strings */ | ||
138 | @}; | ||
139 | @end example | ||
140 | |||
141 | The @code{first} member identifies the first string in the list. | ||
142 | The @code{count} member gives the number of strings in the list. If | ||
143 | the data type is @code{SVT_STRING}, @code{count} is guaranteed to be | ||
144 | 1. | ||
132 | 145 | ||
133 | @item SVT_IDENT | 146 | The string itself can be accessed using the @code{mu_sieve_string} |
134 | The @code{string} member points to the identifier name. | 147 | function (@pxref{String Accessors}). For example, the following code |
148 | fragment iterates over all strings in the list: | ||
135 | 149 | ||
136 | @item SVT_POINTER | 150 | @example |
137 | The data are pointed to by @code{ptr} member. | 151 | size_t i; |
152 | mu_sieve_value_t *val; | ||
153 | |||
154 | for (i = 0; i < val->v.list.count; i++) | ||
155 | @{ | ||
156 | char *string; | ||
157 | |||
158 | string = mu_sieve_string (mach, &val->v.list, i); | ||
159 | ... | ||
160 | @} | ||
161 | @end example | ||
162 | |||
163 | @item SVT_TAG | ||
164 | Never appears. | ||
138 | @end table | 165 | @end table |
139 | 166 | ||
140 | @end deftp | 167 | @end deftp |
... | @@ -159,131 +186,39 @@ colon}. The @code{argtype} is set to @code{SVT_VOID} if the tag does | ... | @@ -159,131 +186,39 @@ colon}. The @code{argtype} is set to @code{SVT_VOID} if the tag does |
159 | not take argument, or to the type of the argument otherwise. | 186 | not take argument, or to the type of the argument otherwise. |
160 | @end deftp | 187 | @end deftp |
161 | 188 | ||
162 | @deftp {Data Type} mu_sieve_runtime_tag_t | ||
163 | This structure represents the tagged (optional) argument at a runtime. | ||
164 | It is defined as: | ||
165 | |||
166 | @smallexample | ||
167 | @group | ||
168 | struct mu_sieve_runtime_tag | ||
169 | @{ | ||
170 | char *tag; /* Tag name */ | ||
171 | mu_sieve_value_t *arg; /* Tag argument (if any) */ | ||
172 | @}; | ||
173 | @end group | ||
174 | @end smallexample | ||
175 | |||
176 | The @code{arg} member is @code{NULL} if the tag does not take an argument. | ||
177 | @end deftp | ||
178 | |||
179 | @deftp {Data Type} mu_sieve_locus_t | ||
180 | Objects of this type represent a location in the Sieve source file: | ||
181 | |||
182 | @smallexample | ||
183 | @group | ||
184 | typedef struct | ||
185 | @{ | ||
186 | const char *source_file; | ||
187 | size_t source_line; | ||
188 | @} | ||
189 | mu_sieve_locus_t; | ||
190 | @end group | ||
191 | @end smallexample | ||
192 | @end deftp | ||
193 | |||
194 | @deftp {Data Type} mu_sieve_handler_t | 189 | @deftp {Data Type} mu_sieve_handler_t |
195 | 190 | ||
196 | This is a pointer to function handler for a sieve action or test. | 191 | This is a pointer to function handler for a sieve action or test. |
197 | It is defined as follows: | 192 | It is defined as follows: |
198 | @smallexample | 193 | @smallexample |
199 | typedef int (*mu_sieve_handler_t) (mu_sieve_machine_t @var{mach}, | 194 | typedef int (*mu_sieve_handler_t) (mu_sieve_machine_t @var{mach}); |
200 | mu_list_t @var{args}, | ||
201 | mu_list_t @var{tags}); | ||
202 | @end smallexample | ||
203 | |||
204 | The arguments to the handler have the following meaning: | ||
205 | |||
206 | @table @var | ||
207 | @item mach | ||
208 | Sieve machine being processed. | ||
209 | @item args | ||
210 | A list of required arguments to the handler | ||
211 | @item tags | ||
212 | A list of optional arguments (tags). | ||
213 | @end table | ||
214 | @end deftp | ||
215 | |||
216 | @deftp {Data Type} mu_sieve_printf_t | ||
217 | A pointer to a diagnostic output function. It is defined as follows: | ||
218 | @smallexample | ||
219 | typedef int (*mu_sieve_printf_t) (void *@var{data}, | ||
220 | const char *@var{fmt}, va_list @var{ap}); | ||
221 | @end smallexample | 195 | @end smallexample |
222 | 196 | ||
223 | @table @var | 197 | The @var{mach} argument is the machine being worked upon. The rest of |
224 | @item data | 198 | data can be obtained from it. |
225 | A pointer to application specific data. It is set using | ||
226 | the @code{mu_sieve_set_data} call. | ||
227 | @item fmt | ||
228 | Printf-like format string. | ||
229 | @item ap | ||
230 | Other arguments. | ||
231 | @end table | ||
232 | @end deftp | ||
233 | |||
234 | @deftp {Data Type} mu_sieve_parse_error_t | ||
235 | This data type is declared as follows: | ||
236 | @smallexample | ||
237 | typedef int (*mu_sieve_parse_error_t) (void *@var{data}, | ||
238 | const char *@var{filename}, | ||
239 | int @var{lineno}, | ||
240 | const char *@var{fmt}, | ||
241 | va_list @var{ap}); | ||
242 | @end smallexample | ||
243 | |||
244 | It is used to declare error handlers for parsing errors. The | ||
245 | application-specific data are passed in the @var{data} | ||
246 | argument. Arguments @var{filename} and @var{line} indicate the location | ||
247 | of the error in the source text, while @var{fmt} and @var{ap} give | ||
248 | verbose description of the error. | ||
249 | @end deftp | ||
250 | 199 | ||
251 | @deftp {Data Type} mu_sieve_action_log_t | 200 | @deftp {Data Type} mu_sieve_action_log_t |
252 | A pointer to the application-specific logging function: | 201 | A pointer to the application-specific logging function: |
253 | 202 | ||
254 | @smallexample | 203 | @smallexample |
255 | typedef void (*mu_sieve_action_log_t) (void *@var{data}, | 204 | typedef void (*mu_sieve_action_log_t) (mu_sieve_machine_t @var{mach}, |
256 | const mu_sieve_locus_t *@var{locus}, | 205 | const char *@var{action}, |
257 | size_t @var{msgno}, | 206 | const char *@var{fmt}, |
258 | mu_message_t @var{msg}, | ||
259 | const char *@var{action}, | ||
260 | const char *@var{fmt}, | ||
261 | va_list @var{ap}); | 207 | va_list @var{ap}); |
262 | @end smallexample | 208 | @end smallexample |
263 | 209 | ||
264 | @table @var | 210 | @table @var |
265 | @item data | 211 | @item nach |
266 | Application-specific data. | 212 | The sieve machine. |
267 | |||
268 | @item locus | ||
269 | Location in the Sieve source file. | ||
270 | |||
271 | @item script | ||
272 | Name of the sieve script being executed. | ||
273 | |||
274 | @item msgno | ||
275 | Ordinal number of the message in mailbox, if appropriate. When execution | ||
276 | is started using @code{sieve_message()}, this argument is zero. | ||
277 | |||
278 | @item msg | ||
279 | The message this action is executed upon. | ||
280 | 213 | ||
281 | @item action | 214 | @item action |
282 | The name of the action. | 215 | The name of the action. |
283 | 216 | ||
284 | @item fmt | 217 | @item fmt |
285 | @itemx var | 218 | A @code{printf}-style format string. |
286 | These two arguments give the detailed description of the action. | 219 | |
220 | @item ap | ||
221 | Arguments for the format. | ||
287 | @end table | 222 | @end table |
288 | @end deftp | 223 | @end deftp |
289 | 224 | ||
... | @@ -329,25 +264,11 @@ associated with @code{data}. See the description of | ... | @@ -329,25 +264,11 @@ associated with @code{data}. See the description of |
329 | 264 | ||
330 | @deftp {Data Type} mu_sieve_tag_checker_t | 265 | @deftp {Data Type} mu_sieve_tag_checker_t |
331 | @smallexample | 266 | @smallexample |
332 | typedef int (*mu_sieve_tag_checker_t) (const char *@var{name}, | 267 | typedef int (*mu_sieve_tag_checker_t) (const char *@var{name}) |
333 | mu_list_t @var{tags}, | ||
334 | mu_list_t @var{args}) | ||
335 | @end smallexample | 268 | @end smallexample |
336 | 269 | ||
337 | A pointer to tag checker function. The purpose of the function is to | 270 | A pointer to tag checker function. The purpose of the function is to |
338 | perform compilation-time consistency test on tags. Its arguments are: | 271 | perform compilation-time consistency test on tags. |
339 | |||
340 | @table @var | ||
341 | @item name | ||
342 | Name of the test or action whose tags are being checked. | ||
343 | |||
344 | @item tags | ||
345 | A list of @code{mu_sieve_runtime_tag_t} representing tags. | ||
346 | |||
347 | @item args | ||
348 | A list of @code{mu_sieve_value_t} representing required arguments to | ||
349 | @var{name}. | ||
350 | @end table | ||
351 | 272 | ||
352 | The function is allowed to make any changes in @var{tags} and | 273 | The function is allowed to make any changes in @var{tags} and |
353 | @var{args}. It should return 0 if the syntax is correct and non-zero | 274 | @var{args}. It should return 0 if the syntax is correct and non-zero |
... | @@ -386,33 +307,7 @@ of the destructor is to free any resources associated with the item | ... | @@ -386,33 +307,7 @@ of the destructor is to free any resources associated with the item |
386 | @var{ptr}. The destructor function takes a single argument --- a | 307 | @var{ptr}. The destructor function takes a single argument --- a |
387 | pointer to the data being destroyed. All registered destructors are | 308 | pointer to the data being destroyed. All registered destructors are |
388 | called in reverse order upon execution of | 309 | called in reverse order upon execution of |
389 | @code{mu_sieve_machine_destroy()}. Here's a short example of the use | 310 | @code{mu_sieve_machine_destroy()}. |
390 | of this function: | ||
391 | |||
392 | @smallexample | ||
393 | @group | ||
394 | static void | ||
395 | free_regex (void *data) | ||
396 | @{ | ||
397 | regfree ((regex_t*)data); | ||
398 | @} | ||
399 | |||
400 | int | ||
401 | match_part_checker (const char *name, list_t tags, list_t args) | ||
402 | @{ | ||
403 | regex_t *regex; | ||
404 | |||
405 | /* Initialise the regex: */ | ||
406 | regex = mu_sieve_malloc (mach, sizeof (*regex)); | ||
407 | /* Make sure it will be freed when necessary */ | ||
408 | mu_sieve_machine_add_destructor (sieve_machine, free_regex, regex); | ||
409 | . | ||
410 | . | ||
411 | . | ||
412 | @} | ||
413 | @end group | ||
414 | @end smallexample | ||
415 | @end deftypefun | ||
416 | 311 | ||
417 | @deftypefun {void *} mu_sieve_get_data (mu_sieve_machine_t @var{mach}) | 312 | @deftypefun {void *} mu_sieve_get_data (mu_sieve_machine_t @var{mach}) |
418 | This function returns the application-specific data associated with | 313 | This function returns the application-specific data associated with |
... | @@ -433,15 +328,12 @@ with @code{mu_sieve_message}, this function returns 1. | ... | @@ -433,15 +328,12 @@ with @code{mu_sieve_message}, this function returns 1. |
433 | Returns the debug level set for this instance of sieve machine. | 328 | Returns the debug level set for this instance of sieve machine. |
434 | @end deftypefun | 329 | @end deftypefun |
435 | 330 | ||
436 | @deftypefun mu_ticket_t mu_sieve_get_ticket (mu_sieve_machine_t @var{mach}) | ||
437 | Returns the authentication ticket for this machine. | ||
438 | @end deftypefun | ||
439 | |||
440 | @deftypefun mu_mailer_t mu_sieve_get_mailer (mu_sieve_machine_t @var{mach}) | 331 | @deftypefun mu_mailer_t mu_sieve_get_mailer (mu_sieve_machine_t @var{mach}) |
441 | Returns the mailer. | 332 | Returns the mailer. |
442 | @end deftypefun | 333 | @end deftypefun |
443 | 334 | ||
444 | @deftypefun int mu_sieve_get_locus (mu_sieve_machine_t @var{mach}, mu_sieve_locus_t *@var{locus}) | 335 | @deftypefun int mu_sieve_get_locus (mu_sieve_machine_t @var{mach}, @ |
336 | struct mu_locus *@var{locus}) | ||
445 | Returns the locus in the Sieve source file corresponding to the code pointer | 337 | Returns the locus in the Sieve source file corresponding to the code pointer |
446 | where the Sieve machine currently is. | 338 | where the Sieve machine currently is. |
447 | @end deftypefun | 339 | @end deftypefun |
... | @@ -453,70 +345,30 @@ envelope from addresses of automatic reply messages. By default its local | ... | @@ -453,70 +345,30 @@ envelope from addresses of automatic reply messages. By default its local |
453 | part is @samp{<MAILER-DAEMON>} and the domain part is the machine name. | 345 | part is @samp{<MAILER-DAEMON>} and the domain part is the machine name. |
454 | @end deftypefun | 346 | @end deftypefun |
455 | 347 | ||
456 | 348 | @deftypefun void mu_sieve_get_diag_stream (mu_sieve_machine_t @var{mach}, @ | |
457 | @deftypefun void mu_sieve_set_error (mu_sieve_machine_t @var{mach}, mu_sieve_printf_t @var{error_printer}) | 349 | mu_stream_t *@var{pstr}) |
458 | This function sets the error printer function for the machine. If it is | 350 | Get a reference to the machine's diagnostic stream. The obtained |
459 | not set, the default error printer will be used. It is defined as | 351 | stream must be dereferenced by using @code{mu_stream_unref} or |
460 | follows: | 352 | @code{mu_stream_destroy}, when no longer needed. |
461 | |||
462 | @smallexample | ||
463 | int | ||
464 | _sieve_default_error_printer (void *unused, const char *fmt, | ||
465 | va_list ap) | ||
466 | @{ | ||
467 | return mu_verror (fmt, ap); | ||
468 | @} | ||
469 | @end smallexample | ||
470 | @end deftypefun | 353 | @end deftypefun |
471 | 354 | ||
472 | @deftypefun void mu_sieve_set_parse_error (mu_sieve_machine_t @var{mach}, mu_sieve_parse_error_t @var{p}) | 355 | @deftypefun void mu_sieve_set_diag_stream (mu_sieve_machine_t @var{mach}, |
473 | This function sets the parse error printer function for the machine. If it is | 356 | mu_stream_t @var{stream} |
474 | not set, the default parse error printer will be used. It is defined as | 357 | Register @var{stream} as the diagnostic stream for this machine. The |
475 | follows: | 358 | reference count of @var{stream} is increased. |
476 | |||
477 | @smallexample | ||
478 | @group | ||
479 | int | ||
480 | _sieve_default_parse_error (void *unused, | ||
481 | const char *filename, int lineno, | ||
482 | const char *fmt, va_list ap) | ||
483 | @{ | ||
484 | if (filename) | ||
485 | fprintf (stderr, "%s:%d: ", filename, lineno); | ||
486 | vfprintf (stderr, fmt, ap); | ||
487 | fprintf (stderr, "\n"); | ||
488 | return 0; | ||
489 | @} | ||
490 | @end group | ||
491 | @end smallexample | ||
492 | @end deftypefun | 359 | @end deftypefun |
493 | 360 | ||
494 | @deftypefun void mu_sieve_set_debug (mu_sieve_machine_t @var{mach}, mu_sieve_printf_t @var{debug}); | 361 | @deftypefun void mu_sieve_get_dbg_stream (mu_sieve_machine_t @var{mach}, @ |
495 | This function sets the debug printer function for the machine. If it is | 362 | mu_stream_t *@var{pstr}) |
496 | not set, the default debug printer is @code{NULL} which means no | 363 | Get a reference to the machine's debug output stream. The obtained |
497 | debugging information will be displayed. | 364 | stream must be dereferenced by using @code{mu_stream_unref} or |
365 | @code{mu_stream_destroy}, when no longer needed. | ||
498 | @end deftypefun | 366 | @end deftypefun |
499 | 367 | ||
500 | @deftypefun void mu_sieve_set_debug_level (mu_sieve_machine_t @var{mach}, mu_debug_t @var{dbg}, int @var{level}) | 368 | @deftypefun void mu_sieve_set_dbg_stream (mu_sieve_machine_t @var{mach}, |
501 | This function sets the debug level for the given instance of sieve | 369 | mu_stream_t @var{stream}) |
502 | machine. The @var{dbg} argument is the @code{mu_debug_t} object to be | 370 | Register @var{stream} as the debug output stream for this machine. The |
503 | used with mailutils library, the @var{level} argument specifies the | 371 | reference count of @var{stream} is increased. |
504 | debugging level for the sieve library itself. It is a bitwise or of | ||
505 | the following values: | ||
506 | |||
507 | @table @code | ||
508 | @item MU_SIEVE_DEBUG_TRACE | ||
509 | Trace the execution of the sieve script. | ||
510 | |||
511 | @item MU_SIEVE_DEBUG_INSTR | ||
512 | Print the sieve machine instructions as they are executed. | ||
513 | |||
514 | @item MU_SIEVE_DEBUG_DISAS | ||
515 | Dump the disassembled code of the sieve machine. Do not run it. | ||
516 | |||
517 | @item MU_SIEVE_DRY_RUN | ||
518 | Do not executed the actions, only show what would have been done. | ||
519 | @end table | ||
520 | @end deftypefun | 372 | @end deftypefun |
521 | 373 | ||
522 | @deftypefun void mu_sieve_set_logger (mu_sieve_machine_t @var{mach}, mu_sieve_action_log_t @var{logger}) | 374 | @deftypefun void mu_sieve_set_logger (mu_sieve_machine_t @var{mach}, mu_sieve_action_log_t @var{logger}) |
... | @@ -524,10 +376,6 @@ This function sets the logger function. By default the logger function | ... | @@ -524,10 +376,6 @@ This function sets the logger function. By default the logger function |
524 | is @code{NULL}, which means that the executed actions are not logged. | 376 | is @code{NULL}, which means that the executed actions are not logged. |
525 | @end deftypefun | 377 | @end deftypefun |
526 | 378 | ||
527 | @deftypefun void mu_sieve_set_ticket (mu_sieve_machine_t @var{mach}, mu_ticket_t @var{ticket}) | ||
528 | This function sets the authentication ticket to be used with this machine. | ||
529 | @end deftypefun | ||
530 | |||
531 | @deftypefun void mu_sieve_set_mailer (mu_sieve_machine_t @var{mach}, mu_mailer_t @var{mailer}) | 379 | @deftypefun void mu_sieve_set_mailer (mu_sieve_machine_t @var{mach}, mu_mailer_t @var{mailer}) |
532 | This function sets the mailer. The default mailer is @code{"sendmail:"}. | 380 | This function sets the mailer. The default mailer is @code{"sendmail:"}. |
533 | @end deftypefun | 381 | @end deftypefun |
... | @@ -569,6 +417,115 @@ Log a sieve action using logger function associated with the machine @var{mach}. | ... | @@ -569,6 +417,115 @@ Log a sieve action using logger function associated with the machine @var{mach}. |
569 | Immediately abort the execution of the script. | 417 | Immediately abort the execution of the script. |
570 | @end deftypefun | 418 | @end deftypefun |
571 | 419 | ||
420 | @node String Accessors | ||
421 | @subsection String Accessors | ||
422 | Strings are stored in a special memory area within the Sieve machine, | ||
423 | which is called @dfn{string space}. A string is identified by its | ||
424 | index in the string space. Array of strings is represented internally | ||
425 | as a contiguous area within the string space that holds one or more | ||
426 | strings. An array is identified by the index of its first element and | ||
427 | number of elements in it: | ||
428 | |||
429 | @example | ||
430 | struct mu_sieve_slice | ||
431 | @{ | ||
432 | size_t first; /* Index of the first object */ | ||
433 | size_t count; /* Number of objects */ | ||
434 | @}; | ||
435 | @end example | ||
436 | |||
437 | A single sieve string is represented by an array of strings with | ||
438 | zero @code{count}. | ||
439 | |||
440 | To obtain actual value of a string, use the @code{mu_sieve_string} | ||
441 | function: | ||
442 | |||
443 | @deftypefun {char *} mu_sieve_string (mu_sieve_machine_t @var{mach}, @ | ||
444 | mu_sieve_slice_t @var{slice}, @ | ||
445 | size_t @var{n}) | ||
446 | Return actual textual value of the @var{n}th string in the array | ||
447 | @var{slice} of the Sieve machine @var{mach}. | ||
448 | |||
449 | If the @code{variables} extension is required, the returned value will | ||
450 | have variables expanded. | ||
451 | @end deftypefun | ||
452 | |||
453 | Two functions are provided for manipulating raw string values. Each | ||
454 | string in the string space is kept in the following structure: | ||
455 | |||
456 | @example | ||
457 | typedef struct mu_sieve_string | ||
458 | @{ | ||
459 | unsigned constant:1; /* String is constant */ | ||
460 | unsigned changed:1; /* String value has changed */ | ||
461 | char *orig; /* String original value */ | ||
462 | char *exp; /* Actual string value after expansion */ | ||
463 | void *rx; /* Pointer to the corresponding regular expr */ | ||
464 | @} mu_sieve_string_t; | ||
465 | @end example | ||
466 | |||
467 | All fields in this structure shall be deemed constant. Sieve code | ||
468 | (such as new actions or tests) should never try to change any of them. | ||
469 | |||
470 | The meaning of its fields is: | ||
471 | |||
472 | @deftypecv Field {struct mu_sieve_string} unsigned constant | ||
473 | Zero if the string is subject to variable expansion and 1 otherwise. | ||
474 | |||
475 | This field is defined when compiling the Sieve script. | ||
476 | @end deftypecv | ||
477 | |||
478 | @deftypecv Field {struct mu_sieve_string} unsigned changed | ||
479 | This field is @samp{1} if the expanded value of the string has changed | ||
480 | since it was retrieved for the last time. This is used by the Sieve | ||
481 | machine to determine whether the associated regular expression (if | ||
482 | any) needs to be recompiled. | ||
483 | |||
484 | This field is modified by the string accessor functions. Obviously, | ||
485 | if @code{constant == 1}, then @code{changed == 0}. | ||
486 | @end deftypecv | ||
487 | |||
488 | @deftypecv Field {struct mu_sieve_string} {char *} orig | ||
489 | A pointer to the original string value, as it appeared in the Sieve | ||
490 | script source file. | ||
491 | @end deftypecv | ||
492 | |||
493 | @deftypecv Field {struct mu_sieve_string} {char *} exp | ||
494 | A pointer to the string value after expansion. Valid only if | ||
495 | @code{constant == 0}. | ||
496 | @end deftypecv | ||
497 | |||
498 | @deftypecv Field {struct mu_sieve_string} {void *} rx | ||
499 | Points to the memory area containig the compiled regular expression | ||
500 | corresponding to that string. This member is valid, e.g. if the | ||
501 | string represents the second argument of a test used with | ||
502 | @code{:match} or @code{:regex} tag. | ||
503 | @end deftypecv | ||
504 | |||
505 | The raw string values are accessed via the following two functions: | ||
506 | |||
507 | @deftypefun {mu_sieve_string_t *} mu_sieve_string_raw (mu_sieve_machine_t @var{mach}, @ | ||
508 | mu_sieve_slice_t @var{slice}, @ | ||
509 | size_t @var{n}) | ||
510 | Returns pointer to the structure representing @var{n}th string in | ||
511 | slice @var{slice}. A runtime exception is raised if @var{n} is out of | ||
512 | range represented by @var{slice}. | ||
513 | |||
514 | Extension writers should treat this as a constant object. | ||
515 | @end deftypefun | ||
516 | |||
517 | @deftypefun {char *} mu_sieve_string_get (mu_sieve_machine_t @var{mach}, @ | ||
518 | mu_sieve_string_t *@var{string}) | ||
519 | Evaluate @var{string} and return its textual representation. If the | ||
520 | @code{variables} extension is required, this function performs | ||
521 | variable substitution. | ||
522 | @end deftypefun | ||
523 | |||
524 | @node Argument Accessors | ||
525 | @subsection Argument Accessors | ||
526 | |||
527 | |||
528 | |||
572 | @node Symbol Space Functions | 529 | @node Symbol Space Functions |
573 | @subsection Symbol Space Functions | 530 | @subsection Symbol Space Functions |
574 | 531 | ... | ... |
... | @@ -15,6 +15,7 @@ is a superset of the Sieve language as described in RFC 3028. | ... | @@ -15,6 +15,7 @@ is a superset of the Sieve language as described in RFC 3028. |
15 | * Comparators:: | 15 | * Comparators:: |
16 | * Tests:: | 16 | * Tests:: |
17 | * Actions:: | 17 | * Actions:: |
18 | * Extensions:: | ||
18 | * GNU Extensions:: | 19 | * GNU Extensions:: |
19 | @end menu | 20 | @end menu |
20 | 21 | ||
... | @@ -1562,6 +1563,409 @@ message regardless of whether the user email is listed as a recipient | ... | @@ -1562,6 +1563,409 @@ message regardless of whether the user email is listed as a recipient |
1562 | for the message. | 1563 | for the message. |
1563 | @end deftypefn | 1564 | @end deftypefn |
1564 | 1565 | ||
1566 | @node Extensions | ||
1567 | @section Extensions | ||
1568 | |||
1569 | The following extensions are implemented | ||
1570 | |||
1571 | @menu | ||
1572 | * encoded-character:: | ||
1573 | * relational:: | ||
1574 | * variables:: | ||
1575 | * environment:: | ||
1576 | * numaddr:: | ||
1577 | * editheader:: | ||
1578 | * list:: | ||
1579 | * moderator:: | ||
1580 | * pipe:: | ||
1581 | * spamd:: | ||
1582 | * timestamp:: | ||
1583 | * vacation:: | ||
1584 | @end menu | ||
1585 | |||
1586 | @node encoded-character | ||
1587 | @subsection The encoded-character extension | ||
1588 | |||
1589 | The @samp{encoded-character} extension complies with @cite{RFC 5228}, | ||
1590 | part 2.4.2.4. It provides a way of incorporating multibyte sequences | ||
1591 | in a Sieve script using only ASCII characters. This is a built-in | ||
1592 | extension. It is enabled using the following statement: | ||
1593 | |||
1594 | @example | ||
1595 | require "encoded-character"; | ||
1596 | @end example | ||
1597 | |||
1598 | When this extension is enabled, the sequences @samp{$@{hex: ...@}}, | ||
1599 | and @samp{$@{unicode: ...@}} can appear inside of quoted strings. | ||
1600 | |||
1601 | The sequence | ||
1602 | |||
1603 | @example | ||
1604 | $@{hex: @var{XX}@} | ||
1605 | @end example | ||
1606 | |||
1607 | @noindent | ||
1608 | where @var{XX} is a sequence of one or two-digit hex numbers separated | ||
1609 | by any amount of whitespace, is replaced with the octets with the | ||
1610 | hexadecimal values given by each hex number. For example, | ||
1611 | |||
1612 | @example | ||
1613 | "$@{hex: 24 24@}" @result{} "$$" | ||
1614 | @end example | ||
1615 | |||
1616 | Thus, the following script will discard any message containing three | ||
1617 | contiguous dollar signs in its @samp{Subject} header: | ||
1618 | |||
1619 | @example | ||
1620 | require "encoded-character"; | ||
1621 | |||
1622 | if header :contains "Subject" "$$@{hex:24 24@}" @{ | ||
1623 | discard; | ||
1624 | @} | ||
1625 | @end example | ||
1626 | |||
1627 | The @samp{hex:} keyword is case-insensitive. If @var{XX} contains | ||
1628 | invalid hex numbers, the entire sequence is left verbatim. This is | ||
1629 | illustrated by the following example: | ||
1630 | |||
1631 | @example | ||
1632 | "$$@{hex:40@}" @result{} "$@@" | ||
1633 | "$@{hex: 40 @}" @result{} "@@" | ||
1634 | "$@{HEX: 40@}" @result{} "@@" | ||
1635 | "$@{hex:40" @result{} "$@{hex:40" | ||
1636 | "$@{hex:400@}" @result{} "$@{hex:400@}" | ||
1637 | "$@{hex:4$@{hex:30@}@}" @result{} "$@{hex:40@}" | ||
1638 | @end example | ||
1639 | |||
1640 | The sequence | ||
1641 | |||
1642 | @example | ||
1643 | $@{unicode: @var{HEXNUM}@} | ||
1644 | @end example | ||
1645 | |||
1646 | @noindent | ||
1647 | where @var{HEXNUM} is a list of hexadecimal numbers separated with | ||
1648 | whitespace, will be replaced by the UTF-8 encoding of the specified | ||
1649 | Unicode characters, which are identified by the hexadecimal value of | ||
1650 | @var{HEXNUM}. For example, the following string represents a single | ||
1651 | @samp{@@} sign: | ||
1652 | |||
1653 | @example | ||
1654 | "$@{UNICODE:40@}" | ||
1655 | @end example | ||
1656 | |||
1657 | Similarly to @samp{hex:}, the @samp{unicode:} indicator is case | ||
1658 | insensitive. The following examples demonstrate the handling of | ||
1659 | several valid and invalid encodings: | ||
1660 | |||
1661 | @example | ||
1662 | "$@{unicode:40@}" @result{} "@@" | ||
1663 | "$@{ unicode:40@}" @result{} "$@{ unicode:40@}" | ||
1664 | "$@{UNICODE:40@}" @result{} "@@" | ||
1665 | "$@{UnICoDE:0000040@}" @result{} "@@" | ||
1666 | "$@{Unicode:40@}" @result{} "@@" | ||
1667 | "$@{Unicode:Cool@}" @result{} "$@{Unicode:Cool@}" | ||
1668 | "$@{unicode:200000@}" @result{} error | ||
1669 | "$@{Unicode:DF01@} @result{} error | ||
1670 | @end example | ||
1671 | |||
1672 | @node relational | ||
1673 | @subsection The relational extension | ||
1674 | |||
1675 | The @samp{relational} extension complies with @cite{RFC 3431}. It is | ||
1676 | a built-in extension. When enabled, the two new match types become | ||
1677 | available: @code{:count} and @code{:value}. Both keywords take a | ||
1678 | single argument defining the relational operator to use: | ||
1679 | |||
1680 | @multitable @columnfractions 0.2 0.8 | ||
1681 | @item @samp{"gt"} @tab greater than (@samp{>}) | ||
1682 | @item @samp{"ge"} @tab greater than or equal (@samp{>=}) | ||
1683 | @item @samp{"lt"} @tab less than (@samp{<}) | ||
1684 | @item @samp{"le"} @tab less than or equal (@samp{<=}) | ||
1685 | @item @samp{"eq"} @tab equal to (@samp{==}) | ||
1686 | @item @samp{"ne"} @tab not equal to (@samp{!=}) | ||
1687 | @end multitable | ||
1688 | |||
1689 | The @code{:value} keyword requires a relational comparison between | ||
1690 | strings. The left side of the relation is formed by the value from | ||
1691 | the message. The right side of the relation is the value from the | ||
1692 | test expression. If there are multiple values on either side or both | ||
1693 | sides, the test is considered true if any pair is true. For example, | ||
1694 | |||
1695 | @example | ||
1696 | require ["relational", "fileinto"]; | ||
1697 | |||
1698 | if header :value "gt" :comparator "i;ascii-numeric" | ||
1699 | ["x-spam-level] ["5"] | ||
1700 | @{ | ||
1701 | fileinto "spam"; | ||
1702 | @} | ||
1703 | @end example | ||
1704 | |||
1705 | The @code{:count} keyword counts the specified entities in the message | ||
1706 | and compares their number with the value given in the test | ||
1707 | expression. The latter must be a list of one element. This match | ||
1708 | type can only be used with numeric comparators. For example, the | ||
1709 | following script will discard any message with 10 or more recipient | ||
1710 | addresses in the @samp{To} and @samp{Cc} headers: | ||
1711 | |||
1712 | @example | ||
1713 | require "relational"; | ||
1714 | |||
1715 | if address :count "ge" :comparator "i;ascii-numeric" | ||
1716 | ["to", "cc"] ["10"] | ||
1717 | @{ | ||
1718 | discard; | ||
1719 | @} | ||
1720 | @end example | ||
1721 | |||
1722 | @node variables | ||
1723 | @subsection The variables extension | ||
1724 | |||
1725 | The @samp{variables} extension is defined in @cite{RFC 5229}. It is | ||
1726 | a built-in extension. It introduces support for variables in Sieve | ||
1727 | scripts. | ||
1728 | |||
1729 | There are two kind of variables: user-defined and match variables. | ||
1730 | |||
1731 | A @dfn{user-defined} variable is initialized using the @code{set} | ||
1732 | action: | ||
1733 | |||
1734 | @deftypefn Action {} set [@var{modifiers}] @var{name}(string) @var{value}(string) | ||
1735 | Stores the specified @var{value} in the variable identified by | ||
1736 | @var{name}. Optional @var{modifiers} are applied on @var{value} before it | ||
1737 | is stored in the variable. | ||
1738 | |||
1739 | The following modifiers are available: | ||
1740 | |||
1741 | @table @code | ||
1742 | @item :lower | ||
1743 | Convert value to lower case letters. | ||
1744 | @item :upper | ||
1745 | Convert value to upper case letters. | ||
1746 | |||
1747 | @item :lowerfirst | ||
1748 | Convert the first character in value to lower case. | ||
1749 | |||
1750 | @item :upperfirst | ||
1751 | Convert the first character in value to upper case. | ||
1752 | |||
1753 | @item :quotewildcard | ||
1754 | Quote wildcard characters (@samp{*}, @samp{?}, @samp{\}) by prefixing | ||
1755 | each occurrence with a backslash (@samp{\}). This can be used to | ||
1756 | ensure that the variable will only match a literal occurrence if used | ||
1757 | as a parameter to @code{:matches}. | ||
1758 | |||
1759 | @item :length | ||
1760 | The value is the decimal number of characters in the expansion, | ||
1761 | converted to a string. | ||
1762 | @end table | ||
1763 | |||
1764 | When several modifiers are present, they are applied in the following | ||
1765 | order of precedence (largest value first): | ||
1766 | |||
1767 | @multitable @columnfractions 0.2 0.8 | ||
1768 | @headitem precedence @tab modifiers | ||
1769 | @item 40 @tab @code{:lower} or @code{:upper} | ||
1770 | @item 30 @tab @code{:lowerfirst} or @code{:upperfirst} | ||
1771 | @item 20 @tab @code{:quotewildcard} | ||
1772 | @item 10 @tab @code{:length} | ||
1773 | @end multitable | ||
1774 | |||
1775 | Modifiers having the same precedence (i.e. listed on the same row in | ||
1776 | the above table) cannot be used together. | ||
1777 | @end deftypefn | ||
1778 | |||
1779 | Variables are referenced within text strings using the construct | ||
1780 | @samp{$@{@var{name}@}}, where @var{name} is the name of the variable | ||
1781 | as it appeared in the first parameter to the @code{set} statement. | ||
1782 | For example: | ||
1783 | |||
1784 | @example | ||
1785 | require "variables"; | ||
1786 | |||
1787 | set "sender" "root@*": | ||
1788 | |||
1789 | if envelope :matches "$@{sender@}" | ||
1790 | @{ | ||
1791 | ... | ||
1792 | @} | ||
1793 | @end example | ||
1794 | |||
1795 | @dfn{Match variables} refer to parts of the most recently evaluated | ||
1796 | successful match of type @code{:matches} or @code{:regex}. They have | ||
1797 | names consisting entirely of decimal digits. The variable | ||
1798 | @samp{$@{0@}} refers to the entire matched expression. The variable | ||
1799 | @samp{$@{1@}} refers to the substring matching the first occurrence of | ||
1800 | the wildcard (@samp{?} and @samp{*}), @samp{$@{2@}} refers to the | ||
1801 | second occurrence and so on. The wildcards match as little as possible | ||
1802 | (non-greedy matching). For example: | ||
1803 | |||
1804 | @example | ||
1805 | require ["variables", "fileinto"]; | ||
1806 | |||
1807 | if header :matches "List-ID" "*<*@*" @{ | ||
1808 | fileinto "INBOX.lists.$@{2@}"; | ||
1809 | stop; | ||
1810 | @} | ||
1811 | @end example | ||
1812 | |||
1813 | If @code{:regex} match is used, the match variables starting from | ||
1814 | @samp{$@{1@}} refer to the substrings of the argument value matching | ||
1815 | subsequent parenthesized groups of the regular expression. | ||
1816 | |||
1817 | @deftypefn Test {} string [@var{comparator}] @ | ||
1818 | [@var{match-type}] @ | ||
1819 | @var{source}(string-list) @var{keys}(string-list) | ||
1820 | The @code{string} test compares two strings according to the selected | ||
1821 | comparator and match type. The test evaluates to @samp{true} if any | ||
1822 | two strings from @var{source} and @var{keys} match. | ||
1823 | |||
1824 | The @samp{:count} match used in @samp{string} counts each empty string | ||
1825 | as 0, and each non-empty one as 1. The count of a string list is the | ||
1826 | sum of the counts of the member strings. | ||
1827 | @end deftypefn | ||
1828 | |||
1829 | @node environment | ||
1830 | @subsection environment | ||
1831 | |||
1832 | The @samp{environment} extension complies with @cite{RFC 5183}. It is | ||
1833 | a built-in extension. It introduces the following test: | ||
1834 | |||
1835 | @deftypefn Test {} environment [@var{comparator}] @ | ||
1836 | [@var{match-type}] @ | ||
1837 | @var{name}(string) @var{keys}(string-list) | ||
1838 | The @code{environment} test evaluates to @samp{true} if the value of | ||
1839 | the environment items @var{name} matches any string from @var{keys}. | ||
1840 | @end deftypefn | ||
1841 | |||
1842 | The following environment items are defined: | ||
1843 | |||
1844 | @table @asis | ||
1845 | @item domain | ||
1846 | The primary DNS domain of the machine where the Sieve script is | ||
1847 | executing. | ||
1848 | |||
1849 | @item host | ||
1850 | The fully-qualified domain name of the host where the Sieve script is | ||
1851 | executing. | ||
1852 | |||
1853 | @item location | ||
1854 | Type of service that is evaluating the script. Depending on the | ||
1855 | utility that is evaluating the script it is: | ||
1856 | |||
1857 | @multitable @columnfractions 0.6 0.4 | ||
1858 | @headitem Utility @tab Location | ||
1859 | @item sieve @tab @samp{"MUA"}, or set with the @option{--environment} option. | ||
1860 | @item maidag @tab @samp{"MDA"} | ||
1861 | @item inc @tab @samp{"MUA"} | ||
1862 | @end multitable | ||
1863 | |||
1864 | @item name | ||
1865 | The string @samp{GNU Mailutils} | ||
1866 | |||
1867 | @item phase | ||
1868 | The point relative to final delivery where the Sieve script is being | ||
1869 | evaluated. Depending on the utility that is evaluating the script it is: | ||
1870 | |||
1871 | @multitable @columnfractions 0.6 0.4 | ||
1872 | @headitem Utility @tab Location | ||
1873 | @item sieve @tab @samp{post} unless set with the @option{--environment} option. | ||
1874 | @item maidag @tab @samp{"during"} | ||
1875 | @item inc @tab @samp{"post"} | ||
1876 | @end multitable | ||
1877 | |||
1878 | @item version | ||
1879 | Mailutils version string (e.g. @samp{@value{VERSION}}). | ||
1880 | @end table | ||
1881 | |||
1882 | @node numaddr | ||
1883 | @subsection The numaddr extension | ||
1884 | |||
1885 | This is an example loadable extension. @ref{External Tests, numaddr}. | ||
1886 | |||
1887 | @node editheader | ||
1888 | @subsection The editheader extension | ||
1889 | |||
1890 | The @code{editheader} extension complies with @cite{RFC 5293}. It | ||
1891 | provides the following actions: | ||
1892 | |||
1893 | @deftypefn Action {} addheader [:last] @var{field-name}(string) @var{value}(string | ||
1894 | Adds a header field to the existing message header. By default the | ||
1895 | header is inserted at the beginning of the header list. If the tag | ||
1896 | @code{:last} is specified, it is appended at the end. | ||
1897 | @end deftypefn | ||
1898 | |||
1899 | @deftypefn Action {} deleteheader" [:index @var{fieldno}(number) :last] @ | ||
1900 | [@var{comparator}] @ | ||
1901 | [@var{match-type}] @ | ||
1902 | @var{field-name}(string) @ | ||
1903 | [@var{value-patterns}(string-list)] | ||
1904 | |||
1905 | Deletes occurrences of the header field matching the criteria. | ||
1906 | |||
1907 | The @var{value-patterns}, if specified, determines which occurrences | ||
1908 | of the header fielde to delete. If not supplied, @var{comparator} and | ||
1909 | @var{match-type} are silently ignored. | ||
1910 | |||
1911 | If @samp{:index @var{fieldno}} is specified, only the numbered | ||
1912 | occurrence of the named header field will be matched (header numbering | ||
1913 | begins at 1), If @code{:last} is specified, the count is backwards; 1 | ||
1914 | denotes the last named header field, 2 the second to last, and so on. | ||
1915 | The counting happens before the @var{value-patterns} match, if any. | ||
1916 | Thus, e.g. the action | ||
1917 | |||
1918 | @example | ||
1919 | deleteheader :index 1 :contains "Delivered-To" "bob@@example.com"; | ||
1920 | @end example | ||
1921 | |||
1922 | @noindent | ||
1923 | would delete the first @samp{Delivered-To} header field if it contains | ||
1924 | the string @samp{bob@@example.com}. | ||
1925 | @end deftypefn | ||
1926 | |||
1927 | @node list | ||
1928 | @subsection The list extension | ||
1929 | |||
1930 | @ref{External Tests, list}. | ||
1931 | |||
1932 | @node moderator | ||
1933 | @subsection The moderator extension | ||
1934 | |||
1935 | A loadable extension implementing a moderator robot for Mailman-driven | ||
1936 | mail archives. @ref{External Actions, moderator}. | ||
1937 | |||
1938 | @node pipe | ||
1939 | @subsection The pipe extension | ||
1940 | |||
1941 | A loadable extension for external command execution. It provides the | ||
1942 | @code{pipe} action (@pxref{External Actions, pipe}) and test | ||
1943 | (@pxref{External Tests, pipe}). | ||
1944 | |||
1945 | @node spamd | ||
1946 | @subsection The spamd extension | ||
1947 | |||
1948 | Implements a test which interfaces to SpamAssassin filter. This is a | ||
1949 | loadable extension. @pxref{External Tests, spamd}. | ||
1950 | |||
1951 | @node timestamp | ||
1952 | @subsection The timestamp extension | ||
1953 | |||
1954 | The loadable extension @code{timestamp} implements a test for | ||
1955 | comparing the value of a structured date header field with the given | ||
1956 | date. | ||
1957 | |||
1958 | Note: this extension will probably phase away in favor of the | ||
1959 | @code{date} Sieve extension (@cite{RFC 5260}). | ||
1960 | |||
1961 | @node vacation | ||
1962 | @subsection The vacation extension | ||
1963 | |||
1964 | The loadable extension @code{vacation} provides the action intended to | ||
1965 | inform the sender that the recipient is not currently reading his mail. | ||
1966 | |||
1967 | @xref{External Actions,vacation}. | ||
1968 | |||
1565 | @node GNU Extensions | 1969 | @node GNU Extensions |
1566 | @section GNU Extensions | 1970 | @section GNU Extensions |
1567 | 1971 | ... | ... |
... | @@ -225,12 +225,18 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach) | ... | @@ -225,12 +225,18 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach) |
225 | compfun = comp_false; | 225 | compfun = comp_false; |
226 | val = mu_sieve_get_arg_untyped (mach, 1); | 226 | val = mu_sieve_get_arg_untyped (mach, 1); |
227 | /* NOTE: Type of val is always SVT_STRING_LIST */ | 227 | /* NOTE: Type of val is always SVT_STRING_LIST */ |
228 | if (val->type != SVT_STRING_LIST) | 228 | switch (val->type) |
229 | abort (); | ||
230 | if (val->v.list.count > 1) | ||
231 | { | 229 | { |
230 | case SVT_STRING: | ||
231 | break; | ||
232 | |||
233 | case SVT_STRING_LIST: | ||
234 | if (val->v.list.count == 1) | ||
235 | break; | ||
236 | /* fall through */ | ||
237 | default: | ||
232 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, | 238 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, |
233 | _("second argument must be a list of one element")); | 239 | _(":count requires second argument to be a list of one element")); |
234 | mu_i_sv_error (mach); | 240 | mu_i_sv_error (mach); |
235 | return 1; | 241 | return 1; |
236 | } | 242 | } | ... | ... |
... | @@ -484,6 +484,8 @@ main (int argc, char *argv[]) | ... | @@ -484,6 +484,8 @@ main (int argc, char *argv[]) |
484 | mu_error (_("cannot initialize sieve machine: %s"), mu_strerror (rc)); | 484 | mu_error (_("cannot initialize sieve machine: %s"), mu_strerror (rc)); |
485 | return EX_SOFTWARE; | 485 | return EX_SOFTWARE; |
486 | } | 486 | } |
487 | |||
488 | sieve_setenv ("phase=post", mach); | ||
487 | mu_list_foreach (env_list, sieve_setenv, mach); | 489 | mu_list_foreach (env_list, sieve_setenv, mach); |
488 | mu_list_destroy (&env_list); | 490 | mu_list_destroy (&env_list); |
489 | 491 | ... | ... |
... | @@ -17,7 +17,7 @@ | ... | @@ -17,7 +17,7 @@ |
17 | m4_pushdef([MUT_SIEVE_EXT_NAME],[pipe test]) | 17 | m4_pushdef([MUT_SIEVE_EXT_NAME],[pipe test]) |
18 | 18 | ||
19 | MUT_SIEVE_EXT_TEST([],[pipetest00], | 19 | MUT_SIEVE_EXT_TEST([],[pipetest00], |
20 | [require "test-pipe"; | 20 | [require "pipe"; |
21 | if pipe :header "$cwd/ckmsg" | 21 | if pipe :header "$cwd/ckmsg" |
22 | { | 22 | { |
23 | discard; | 23 | discard; | ... | ... |
-
Please register or sign in to post a comment