1@c This is part of the GNU Mailutils manual.
2@c Copyright (C) 1999--2021 Free Software Foundation, Inc.
3@c See file mailutils.texi for copying conditions.
4@comment *******************************************************************
5
6The input language understood by the GNU Sieve Library
7is a superset of the Sieve language as described in RFC 3028.
8
9@menu
10* Lexical Structure::
11* Syntax::
12* Preprocessor::
13* Require Statement::
14* Comparators::
15* Tests::
16* Actions::
17* Extensions::
18* GNU Extensions::
19@end menu
20
21@node Lexical Structure
22@section Lexical Structure
23
24@subheading Whitespace and Comments
25
26Comments are semantically equivalent to whitespace and can be used
27anyplace that whitespace is (with one exception in multi-line strings,
28as described below).
29
30There are two kinds of comments: hash comments, that begin with a
31@samp{#} character that is not contained within a string and continue
32until the next newline, and C-style or bracketed comments, that are
33delimited by @samp{/*} and @samp{*/} tokens.  The bracketed comments
34may span multiple lines.  E.g.:
35
36@smallexample
37if size :over 100K
38  @{ # this is a comment
39    discard;
40  @}
41
42if size :over 100K
43  @{ /* this is a comment
44       this is still a comment */ discard /* this is a comment again
45     */ ;
46  @}
47@end smallexample
48
49Like in C, bracketed comments do not nest.
50
51@subheading Lexical Tokens
52
53The basic lexical entities are @dfn{identifiers} and @dfn{literals}.
54
55An @dfn{identifier} is a sequence of letters, digits and underscores,
56that begins with a letter or underscore.  For example, @code{header} and
57@code{check_822_again} are valid identifiers, whereas @code{1st} is not.
58A special form of identifier is @dfn{tag}: it is an identifier prefixed
59with a colon (@samp{:}), e.g.: @code{:comparator}.
60
61A @dfn{literal} is a data that is not executed, merely evaluated ``as
62is'', to be used as arguments to commands.  There are four kinds of
63literals:
64
65@itemize
66@item Number
67@cindex numbers, sieve
68
69@dfn{Numbers} are given as ordinary unsigned decimal numbers.  An
70optional suffix may be used to indicate a multiple of a power of two.
71The suffixes are: @samp{K} specifying ``kibi-'', or 1,024 (2^10) times
72the value of the number; @samp{M} specifying ``mebi-'', or 1,048,576
73(2^20) times the value of the number; and @samp{G} specifying ``tebi-'',
74or 1,073,741,824 (2^30) times the value of the number.
75
76The numbers have 32 bits of magnitude.
77
78@item String
79@cindex strings, sieve
80A @dfn{string} is any sequence of characters enclosed in double quotes
81(@samp{"}).  A string cannot contain newlines and double quote
82characters.  This limitation will disappear in future releases.
83
84@item Multiline Strings
85@cindex multiline strings, sieve
86@kwindex text:
87A @dfn{multiline string} is used to represent large blocks of text
88with embedded newlines and special characters.  It starts with the
89keyword @code{text:} followed by a newline and ends with a dot
90(@samp{.}) on a newline by itself.  Any characters between these two
91markers are taken verbatim.  For example:
92
93@smallexample
94text:
95** This is an automatic response from my message **
96** filtering program.                            **
97
98I can not attend your message right now.  However it
99will be saved, and I will read it as soon as I am back.
100
101Regards,
102Fred
103.
104@end smallexample
105
106Notice that a hashed comment or whitespace may occur between
107@code{text:} and the newline.  However, when used inside the multiline
108string a hash sign looses its special meaning (except in one case, see
109below) and is taken as is, as well as bracketed comment delimiters.
110In other words, no comments are allowed within a multiline string.  E.g.:
111
112@smallexample
113text: # This is a comment
114
115Sample text
116# This line is taken verbatim
117/* And this line too */
118.
119@end smallexample
120
121The only exception to this rule is that preprocessor @code{include}
122statement is expanded as usual when found within a multiline string
123(@pxref{Preprocessor}), e.g.:
124
125@smallexample
126text:
127#include <myresponse.txt>
128.
129@end smallexample
130
131This results in the contents of file @file{myresponse.txt} being read
132and interpreted as the contents of the multiline string.
133
134GNU libmu_sieve extends the described syntax as follows.  If the keyword
135@code{text:} is immediately followed by a dash (@samp{-}), then all
136leading tab characters are stripped from input lines and the line
137containing delimiter (@samp{.}).  This allows multiline strings within
138scripts to be indented in a natural fashion.
139
140Furthermore, if the @code{text:} (optionally followed by @samp{-}) is
141immediately followed by a word, this word will be used as ending
142delimiter of multiline string instead of the default dot.  For
143example:
144
145@smallexample
146@group
147if header "from" "me@@example.com"
148  @{
149    reject text:-EOT
150        I do not accept messages from
151        this address.
152        .
153        .
154        EOT
155     # Notice that this the multiline string ends here.
156     # The single dots above will be part of it.
157    ;
158  @}
159@end group
160@end smallexample
161@noindent
162
163@item String Lists
164@cindex string list, sieve
165
166A @dfn{string list} is a comma-delimited list of quoted strings, enclosed
167in a pair of square brackets, e.g.:
168
169@smallexample
170["me@@example.com", "me00@@landru.example.edu"]
171@end smallexample
172
173For convenience, in any context where a list of strings is appropriate,
174a single string is allowed without being a member of a list: it is
175equivalent to a list with a single member.  For example, the following
176two statements are equivalent:
177
178@smallexample
179exists "To";
180exists ["To"];
181@end smallexample
182
183@end itemize
184
185@node Syntax
186@section Syntax
187
188Being designed for the sole purpose of filtering mail, Sieve has a very
189simple syntax.
190
191@menu
192* Commands::
193* Actions Described::
194* Control Flow::
195* Tests and Conditions::
196@end menu
197
198@node Commands
199@subsection Commands
200
201The basic syntax element is a @dfn{command}.  It is defined as follows:
202
203@smallexample
204@var{command-name} [@var{tags}] @var{args}
205@end smallexample
206@noindent
207where @var{command-name} is an identifier representing the name of the
208command, @var{tags} is an optional list of @dfn{optional} or
209@dfn{tagged arguments} and @var{args} is a list of @dfn{required} or
210@dfn{positional arguments}.
211
212Positional arguments are literals delimited with whitespace.  They
213provide the command with the information necessary to its proper
214functioning.  Each command has a fixed number of positional arguments.  It
215is an error to supply more arguments to the command or to give it fewer
216arguments than it accepts.
217
218Optional arguments allow to modify the behaviour of the command, like
219command line options in UNIX do.  They are a list of @dfn{tags}
220(@pxref{Lexical Structure}) separated by whitespace.  An optional
221argument may have at most one parameter.
222
223Each command understands a set of optional arguments.  Supplying it tags
224that it does not understand results in an error.
225
226For example, consider the following command
227
228@smallexample
229header :mime :comparator "i;octet" ["to", "from"] "bug-mailutils@@gnu.org"
230@end smallexample
231
232@noindent
233Here, given that @code{header} takes two positional arguments:
234@code{header} is command name, the list @code{["to", "from"]} is first
235positional argument and the string @code{"bug-mailutils@@gnu.org"} is second
236positional argument.  There are two optional arguments: @code{:mime} and
237@code{:comparator}.  The latter has a string @code{"i;octet"} as its
238parameter.
239
240@node Actions Described
241@subsection Actions Described
242@cindex action, sieve
243
244An @dfn{action} is a Sieve command that performs some operation over
245a message.  Actions do the main job in any Sieve
246program.  Syntactically, an action is a command terminated with
247semicolon, e.g.:
248
249@smallexample
250keep;
251
252fileinto "mbox";
253@end smallexample
254
255GNU Sieve provides the full set of actions described in RFC 3028.
256It also allows to extend this set using loadable
257actions.  @xref{Actions}, for detailed discussion of actions.
258
259@node Control Flow
260@subsection Control Flow
261@kwindex if, sieve
262
263The only control flow statement Sieve has is @code{if} statement.  In its
264simplest form it is:
265
266@smallexample
267if @code{condition} @{ @dots{} @}
268@end smallexample
269
270The effect of this statement is that the sequence of actions between the
271curly braces is executed only if the @code{condition} evaluates to
272@code{true}.
273
274A more elaborate form of this statement allows to execute two
275different sets of actions depending on whether the condition is
276true or not:
277
278@smallexample
279if @code{condition} @{ @dots{} @} else @{ @dots{} @}
280@end smallexample
281
282The most advanced form of the ``if'' statement allows to select an
283action depending on what condition from the set of conditions is met.
284
285@smallexample
286if @code{cond1} @{ @dots{} @} elsif @code{cond2} @{ @dots{} @} else @{ @dots{} @}
287@end smallexample
288
289There may be any number of ``elsif'' branches in an ``if''
290statement.  However it may have at most one ``else'' branch.
291Notes for C programmers:
292
293@enumerate
294@item The braces surrounding each branch of an ``if'' statement are
295required.
296@item The ``else if'' construct is disallowed.  Use ``elsif'' keyword
297instead.
298@end enumerate
299
300Here's an example of ``if'' statement:
301
302@smallexample
303if header :contains "from" "coyote"
304  @{
305    discard;
306  @}
307elsif header :contains ["subject"] ["$$$"]
308  @{
309    discard;
310  @}
311else
312  @{
313    fileinto "INBOX";
314  @}
315@end smallexample
316
317The following section describes in detail conditions used in ``if''
318statements.
319
320@node Tests and Conditions
321@subsection Tests and Conditions
322@cindex test, sieve
323
324@dfn{Tests} are Sieve commands that return boolean value.  E.g. the
325test
326
327@smallexample
328header :contains "from" "coyote"
329@end smallexample
330
331@noindent
332returns true only if the header ``From'' of the current message contains
333substring ``coyote''.
334
335The tests shipped with the GNU Sieve are described in @ref{Tests}.
336
337@cindex condition, sieve
338@dfn{Condition} is a Sieve expression that evaluates to @code{true} or
339@code{false}.  In its simplest form, condition is just a Sieve test.
340
341@kwindex not, sieve
342To reverse the sense of a condition use keyword @code{not}, e.g.:
343
344@smallexample
345not header :contains "from" "coyote"
346@end smallexample
347
348@kwindex and, sieve
349@kwindex or, sieve
350@kwindex allof
351@kwindex anyof
352The results of several conditions may be joined together by logical
353@code{and} and @code{or} operations.  The special form @code{allof}
354takes several tests as its arguments and computes the logical @code{and}
355of their results.  Similarly, the form @code{anyof} performs logical
356@code{or} over the results of its arguments.  E.g.:
357
358@smallexample
359if anyof (not exists ["From", "Date"],
360          header :contains "from" "fool@@example.edu")
361  @{
362    discard;
363  @}
364@end smallexample
365
366@node Preprocessor
367@section Preprocessor
368@cindex preprocessor, sieve
369@cindex Sieve preprocessor statements
370
371Preprocessor statements are a GNU extension to the Sieve language.
372The syntax for a preprocessor statement is similar to that used in
373@code{C} programming language, i.e. a pound character (@samp{#})
374followed by a preprocessor directive and its arguments.  Any amount of
375whitespace can be inserted between the @samp{#} and the directive.
376Currently implemented directives are @code{include} and @code{searchpath}.
377
378@menu
379* #include::        Include the contents of a file.
380* #searchpath::     Modify the current search path.
381@end menu
382
383@node #include
384@subsection Sieve #include directive
385@kwindex #include, sieve
386
387The @code{#include} directive reads in the contents of the given file.
388The contents is ``inserted'' into the text being parsed starting at the
389line where the directive appears.  The directive takes two forms:
390
391@table @code
392@item #include "@var{filename}"
393The @var{filename} is taken relative to the current directory.
394
395@item #include <@var{filename}>"
396The @var{filename} is searched in the list of include directories
397as specified by the @option{-I} command line options.
398@end table
399
400If @var{filename} starts with a directory separator character
401(@samp{/}) both forms have the same effect.
402
403@node #searchpath
404@subsection Sieve #searchpath directive
405@kwindex #searchpath, sieve
406
407The @code{#searchpath} directive adds its argument to the list of
408directories searched for loadable modules.  It has the same effect
409as @command{library-path} Sieve configuration statement
410(@pxref{Sieve Configuration, library-path}).
411
412@node Require Statement
413@section Require Statement
414@kwindex require, sieve
415
416@smallexample
417Syntax:   require @var{string};
418          require @var{string-list};
419@end smallexample
420
421The require statement informs the parser that a script makes use of a certain
422extension.  Multiple capabilities can be declared using the second form
423of the statement.  The actual handling of a capability name depends on
424its suffix.
425
426If the name starts with @samp{comparator-}, it is understood
427as a request to use the specified comparator.  The comparator name
428consists of the characters following the suffix.
429
430If the name starts with @samp{test-}, it means a request to use
431the given test.  The test name consists of the characters following
432the suffix.
433
434Otherwise, the capability is understood as a name of an action to be
435used.
436
437The @code{require} statement, if present, must be used before any other
438statement that is using the required capability.  As an extension, the GNU
439sieve allows the @code{require} and any other statements to be
440interspersed.
441
442By default the following actions and comparators need not be
443explicitly required:
444
445@itemize
446@item stop
447@item keep
448@item discard
449@item i;octet
450@item i;ascii-casemap
451@end itemize
452
453Example:
454
455@smallexample
456require ["fileinto", "reject"];
457
458require "fileinto";
459
460require "comparator-i;ascii-numeric";
461@end smallexample
462
463When processing arguments for @code{require} statement, GNU libmu_sieve
464uses the following algorithm:
465
466@enumerate 1
467@item Look up the name in a symbol table.  If the name begins with
468@samp{comparator-} it is looked up in the comparator table.  If it
469begins with @samp{test-}, the test table is used instead.  Otherwise
470the name is looked up in the action table.
471
472@item If the name is found, the search is terminated.
473
474@item Otherwise, transform the name.  First, any @samp{comparator-} or
475@samp{test-} prefix is stripped.  Then, any character other than
476alphanumeric characters, @samp{.} and @samp{,} is replaced with
477dash (@samp{-}).  The name thus obtained is used as a file name
478of an external loadable module.
479
480@item Try to load the module.  The module is searched in the
481following search paths (in the order given):
482
483@enumerate 1
484@item Mailutils module directory.  By default it is
485@file{$prefix/lib/mailutils}.
486
487@item Sieve library path as given with the @option{-L} options in
488the command line
489
490@item Additional search directories specified with the
491@code{#searchpath} directive.
492
493@item The value of the environment variable @env{LTDL_LIBRARY_PATH}.
494
495@item System library search path: The system dependent library
496search path (e.g. on Linux it is set by the contents of the file
497@file{/etc/ld.so.conf} and the value of the environment variable
498@env{LD_LIBRARY_PATH}).
499@end enumerate
500
501@vindex LTDL_LIBRARY_PATH
502@vindex LD_LIBRARY_PATH
503The value of @env{LTDL_LIBRARY_PATH} and @env{LD_LIBRARY_PATH} must be a
504colon-separated list of absolute directories, for example,
505@samp{"/usr/lib/mypkg:/lib/foo"}.
506
507In any of these directories, @command{libmu_sieve} first attempts to find
508and load the given filename.  If this fails, it tries to append the
509following suffixes to the file name:
510
511@enumerate 1
512@item the libtool archive extension @samp{.la}
513
514@item the extension used for native dynamic libraries on the host
515platform, e.g., @samp{.so}, @samp{.sl}, etc.
516@end enumerate
517
518@item If the module is found, @command{libmu_sieve} executes its
519initialization function (see below) and again looks up the name
520in the symbol table.  If found, search terminates successfully.
521
522@item If either the module is not found, or the symbol wasn't
523found after execution of the module initialization function,
524search is terminated with an error status.  @command{libmu_sieve} then
525issues the following diagnostic message:
526
527@smallexample
528source for the required action NAME is not available
529@end smallexample
530@end enumerate
531
532@node Comparators
533@section Comparators
534@cindex comparator, sieve
535
536GNU libmu_sieve supports the following built-in comparators:
537
538@table @code
539@item i;octet
540This comparator simply compares the two arguments octet by octet
541
542@item i;ascii-casemap
543It treats uppercase and lowercase characters in the @sc{ascii} subset of
544@sc{utf-8} as the same.  This is the default comparator.
545
546@item i;ascii-numeric
547Treats the two arguments as @sc{ascii} representation of decimal
548numbers and compares their numeric values.  This comparator must
549be explicitly required prior to use.
550@end table
551
552@node Tests
553@section Tests
554@cindex test, sieve
555
556This section describes the built-in tests supported by GNU libmu_sieve.
557In the discussion below the following macro-notations are used:
558
559@table @var
560@item match-type
561This tag specifies the matching type to be used with the test.  It can
562be one of the following:
563
564@table @code
565@kwindex :is, sieve
566@kwindex is, sieve
567@item :is
568The @code{:is} match type describes an absolute match; if the contents of
569the first string are absolutely the same as the contents of the
570second string, they match.  Only the string ``frobnitzm'' is the string
571``frobnitzm''.  The null key ``:is'' and only ``:is'' the null value.
572This is the default match-type.
573
574@kwindex :contains, sieve
575@kwindex contains, sieve
576@item :contains
577The @code{:contains} match type describes a substring match.  If the value
578argument contains the key argument as a substring, the match is true.
579For instance, the string ``frobnitzm'' contains ``frob'' and ``nit'', but
580not ``fbm''.  The null key ``'' is contained in all values.
581
582@kwindex :matches, sieve
583@kwindex matches, sieve
584@item :matches
585The @code{:matches} version specifies a wildcard match using the
586characters @samp{*} and @samp{?}.  @samp{*} matches zero or more
587characters, and @samp{?} matches a single character.  @samp{?} and
588@samp{*} may be escaped as @samp{\\?} and @samp{\\*} in strings to match
589against themselves.  The first backslash escapes the second backslash;
590together, they escape the @samp{*}.
591
592@kwindex :regex, sieve
593@kwindex regex, sieve
594@item :regex
595The @code{:regex} version specifies a match using POSIX Extended Regular
596Expressions.
597
598@kwindex :value, sieve
599@kwindex value, sieve
600@item :value @var{relation}
601The @code{:value} match type does a relational comparison between
602strings.  Valid values for @var{relation} are:
603
604@table @asis
605@item "eq"
606Equal
607
608@item "ne"
609Not Equal
610
611@item "gt"
612Greater Than
613
614@item "ge"
615Greater than or Equal
616
617@item "lt"
618Less Than
619
620@item "le"
621Less than or Equal
622@end table
623
624@kwindex :count, sieve
625@kwindex count, sieve
626@item :count @var{relation}
627This match type first determines the number of the specified entities
628(headers, addresses, etc.) in the message and does a relational
629comparison of the number of entities to the values specified in the
630test expression.  The test expression must be a list of one element.
631@end table
632
633@kwindex :comparator, sieve
634@kwindex comparator, sieve
635@item comparator
636A @var{comparator} syntax item is defined as follows:
637
638@smallexample
639:comparator "@var{comparator-name}"
640@end smallexample
641@noindent
642It instructs sieve to use the given comparator with the test.
643If @var{comparator-name} is not one of @samp{i;octet},
644@samp{i;ascii-casemap} it must be required prior to using it.
645For example:
646
647@smallexample
648require "comparator-i;ascii-numeric";
649
650if header :comparator "i;ascii-numeric" :is "X-Num" "10"
651  @{
652    ...
653@end smallexample
654
655@item address-part
656This syntax item is used when testing structured Internet addresses.  It
657specifies which part of an address must be used in comparisons.
658Exactly one of the following tags may be used:
659
660@table @code
661@kwindex :all, sieve
662@kwindex all, sieve
663@item :all
664Use the whole address.  This is the default.
665
666@kwindex :localpart, sieve
667@kwindex localpart, sieve
668@item :localpart
669Use local part of the address.
670
671@kwindex :domain, sieve
672@kwindex domain, sieve
673@item :domain
674Use domain part of the address.
675@end table
676
677@end table
678
679@emph{Notice}, that @var{match-type} modifiers interact with
680comparators.  Some comparators are not suitable for matching with
681@code{:contains} or @code{:matches}.  If this occurs, sieve issues
682an appropriate error message.  For example, the statement:
683
684@smallexample
685if header :matches :comparator "i;ascii-numeric"
686@end smallexample
687@noindent
688would result in the following error message:
689
690@smallexample
691comparator `i;ascii-numeric' is incompatible with match type `:matches'
692in call to `header'
693@end smallexample
694
695GNU Sieve supports two kinds of tests.  @dfn{Built-in tests} are
696defined within the library and do not require any external files.
697@dfn{External tests} are loadable modules that can be linked in at run
698time using the @code{require} statement (@pxref{Require Statement}).
699
700@menu
701* Built-in Tests::
702* External Tests::
703@end menu
704
705@node Built-in Tests
706@subsection Built-in Tests
707
708@deffn Test false
709
710This test always evaluates to ``false''.
711@end deffn
712
713@deffn Test true
714
715This test always evaluates to ``true''.
716@end deffn
717
718@deftypefn Test {} address [@var{address-part}] @
719                           [@var{comparator}] @
720                           [@var{match-type}] @
721                           @var{header-names} @var{key-list}
722
723@noindent
724Tagged arguments:
725
726@table @var
727@item address-part
728Selects the address part to compare.  Default is the whole email address
729(@code{:all}).
730
731@item comparator
732Specifies the comparator to be used instead of the default @code{i;ascii-casemap}.
733
734@item match-type
735Specifies the match type to be used instead of the default @code{:is}.
736@end table
737
738@noindent
739Required arguments:
740
741@table @var
742@item header-names
743A list of header names.
744
745@item key-list
746A list of address values.
747@end table
748@noindent
749
750The @code{address} test matches Internet addresses in structured headers
751that contain addresses.  It returns @code{true} if any header contains any
752key in the specified part of the address, as modified by
753@var{comparator} and @var{match-type} optional arguments.
754
755This test returns @code{true} if any combination of the
756@var{header-names} and @var{key-list} arguments match.
757
758The @code{address} primitive never acts on the phrase part of an email
759address, nor on comments within that address.  Use the @code{header} test
760instead.  It also never acts on group names, although it does act on the
761addresses within the group construct.
762
763Example:
764
765@smallexample
766if address :is :all "from" "tim@@example.com"
767  @{
768     discard;
769  @}
770@end smallexample
771@end deftypefn
772
773@deftypefn Test {} size [:over | :under] @var{limit}(number)
774The @code{size} test deals with the size of a message.  The required
775argument @var{limit} represents the size of the message in bytes.  It
776may be suffixed with the following quantifiers:
777
778@table @samp
779@item k
780@itemx K
781The number is expressed in kilobytes.
782@item m
783@itemx M
784The number is expressed in megabytes.
785@item g
786@itemx G
787The number is expressed in gigabytes.
788@end table
789
790@kwindex :over
791If the tagged argument is @samp{:over}, and the size of the message is greater
792than @var{number}, the test is true; otherwise, it is false.
793
794@kwindex :under
795If the argument is @samp{:under}, and the size of the message is less than
796the @var{number}, the test is true; otherwise, it is false.
797
798Otherwise, the test is true only if the size of the message equals
799exactly @var{number}.  This is a GNU extension.
800
801The size of a message is defined to be the number of octets from the
802initial header until the last character in the message body.
803@end deftypefn
804
805@deftypefn Test {} envelope [@var{address-part}] @
806                            [@var{comparator}] @
807                            [@var{match-type}] @
808                            @var{envelope-part}(string-list) @
809                            @var{key-list}(string-list)
810@noindent
811
812Tagged arguments:
813
814@table @var
815@item address-part
816Selects the address part to compare.  Default is the whole email address
817(@code{:all}).
818
819@item comparator
820Specifies the comparator to be used instead of the default @code{i;ascii-casemap}.
821
822@item match-type
823Specifies the match type to be used instead of the default @code{:is}.
824@end table
825@noindent
826Required arguments:
827
828@table @var
829@item envelope-parts
830A list of envelope parts to operate upon.
831
832@item key-list
833A list of address values.
834@end table
835@noindent
836
837The @code{envelope} test is true if the specified part of the @sc{smtp}
838envelope matches the specified key.
839
840If the envelope-part strings is (case insensitive) @samp{from},
841then matching occurs against the FROM address used in the
842@command{SMTP MAIL} command.
843
844@emph{Notice}, that due to the limitations imposed by @sc{smtp} envelope
845structure the use of any other values in @var{envelope-parts} header is
846meaningless.
847@end deftypefn
848
849@deftypefn Test {} exists @var{header-names}(string-list)
850@noindent
851
852Required arguments:
853
854@table @var
855@item header-names
856List of message header names.
857@end table
858
859@sp 1
860@noindent
861The @code{exists} test is @code{true} if the headers listed in
862@var{header-names} argument exist within the message.  All of the headers
863must exist or the test is false.
864
865The following example throws out mail that doesn't have a From header
866and a Date header:
867
868@smallexample
869if not exists ["From","Date"]
870  @{
871     discard;
872  @}
873@end smallexample
874@end deftypefn
875
876@deftypefn Test {} header [@var{comparator}] @
877                          [@var{match-type}] @
878                          [:mime] @
879                          @var{header-names}(string-list) @
880                          @var{key-list}(string-list)
881@sp 1
882@noindent
883Tagged arguments:
884
885@table @asis
886@item @var{comparator}
887Specifies the comparator to be used instead of the default @code{i;ascii-casemap}.
888
889@item @var{match-type}
890Specifies the match type to be used instead of the default @code{:is}.
891
892@kwindex :mime
893@item :mime
894This tag instructs @code{header} to search through the mime headers in
895multipart messages as well.
896
897@end table
898@sp 1
899@noindent
900Required arguments:
901
902@table @var
903@item header-names
904A list of header names.
905
906@item key-list
907A list of header values.
908@end table
909@sp 1
910@noindent
911The @code{header} test evaluates to true if any header name matches any
912key.  The type of match is specified by the optional match argument,
913which defaults to ":is" if not explicitly given.
914
915The test returns @code{true} if any combination of the @var{header-names}
916and @var{key-list} arguments match.
917
918If a header listed in @var{header-names} exists, it contains the null
919key (@samp{""}).  However, if the named header is not present, it
920does not contain the null key.  So if a message contained the header
921
922@smallexample
923X-Caffeine: C8H10N4O2
924@end smallexample
925@sp 1
926@noindent
927these tests on that header evaluate as follows:
928
929@smallexample
930header :is ["X-Caffeine"] [""] @result{} false
931header :contains ["X-Caffeine"] [""] @result{} true
932@end smallexample
933@end deftypefn
934
935@node External Tests
936@subsection External Tests
937
938@deftypefn Test {} numaddr [:over | :under] @
939                           @var{header-names}(string-list) @
940                           @var{count}(number)
941@noindent
942@*Synopsis:
943@smallexample
944require "test-numaddr";
945@dots{}
946if numaddr @var{args}
947  @{
948    @dots{}
949  @}
950@end smallexample
951@*Description:
952This test is provided as an example of loadable extension tests.  You
953must use @samp{require "test-numaddr"} statement before actually using
954it.
955
956The @code{numaddr} test counts Internet addresses in structured headers
957that contain addresses.  It returns true if the total number of
958addresses satisfies the requested relation.
959
960@kwindex :over
961If the tagged argument is @samp{:over} and the number of addresses is
962greater than @var{count}, the test is true; otherwise, it is false.
963
964@kwindex :under
965If the tagged argument is @samp{:under} and the number of addresses is
966less than @var{count}, the test is true; otherwise, it is false.
967
968If the tagged argument is not given, @samp{:over} is assumed.
969@end deftypefn
970
971@deftypefn Test {} pipe [:envelope] [:header] [:body] @
972                        [:exit @var{code}(number)] @
973                        [:signal @var{code}(number)] @
974                        @var{command}(string)
975@*Synopsis:
976@smallexample
977require "test-pipe";
978
979if pipe @var{command}
980  @{
981    @dots{}
982  @}
983@end smallexample
984@*Description:
985The @code{pipe} test executes a shell command specified by its
986argument and pipes the entire message (including envelope) to its
987standard input.  When given, tags @code{:envelope}, @code{:header},
988and @code{:body} control what parts of the message to pipe to the command.
989
990In the absence of the @code{:exit} tag, the test returns true if
991the command exits with code 0.  If @code{:exit} is given, the test returns
992true if the command exits with code equal to its argument.
993
994The @code{:signal} tag determines the result of the test in case if the program
995exits on signal.  By default, the test returns false.  If @code{:signal}
996is given and the number of signal which caused the program to terminate
997matches its argument, the test returns true.
998@end deftypefn
999
1000@deftypefn Test {} spamd [:host @var{tcp-host}(string)] @
1001                         [:port @var{tcp-port}(number)] @
1002                         [:socket @var{unix-socket}(string)] @
1003                         [:user @var{name}(string)] @
1004                         [:over | :under @var{limit}(string)]
1005@*Synopsis:
1006@smallexample
1007require "test-spamd";
1008@dots{}
1009if spamd @var{args}
1010  @{
1011    # @r{This is spam}
1012    @dots{}
1013  @}
1014@end smallexample
1015
1016@*Description:
1017This test is an interface to SpamAssassin filter.  It connects to the
1018@command{spamd} daemon using connection parameters specified by tagged
1019arguments @code{:host} and @code{:port} (if the daemon is listening on
1020an INET socket), or @code{:socket} (if the daemon is listening on a
1021UNIX socket) and returns true, if SpamAssassin qualifies the message
1022as spam.  Tagged argument @var{limit} alters the default behavior.  Its
1023value is a string representation of a floating point number.  If
1024the tag @code{:over} is used, then the test returns true if the spam
1025score returned from SpamAssassin is greater than @var{limit}.
1026Otherwise, if @code{:under} is used, the test returns true if the spam
1027score is less than @var{limit}.  The comparison takes into account
1028three decimal digits.
1029
1030Tagged argument @code{:user} allows to select a specific user profile.
1031If it is not given, the user name is determined using the effective
1032UID.
1033
1034Before returning, the @code{spamd} test adds the following headers to
1035the message:
1036
1037@table @asis
1038@item X-Spamd-Status
1039@samp{YES} or @samp{NO}, depending on whether the message is qualified
1040as spam or ham.
1041
1042@item X-Spamd-Score
1043Actual spam score value.
1044
1045@item X-Spamd-Threshold
1046Spam score threshold, as configured in SpamAssassin settings.
1047
1048@item X-Spamd-Keywords
1049Comma-separated list of keywords, describing the spam checks that
1050succeeded for this message.
1051@end table
1052
1053Example:
1054
1055@smallexample
1056request "test-spamd";
1057
1058if spamd :host 127.0.0.1 :port 3333
1059  @{
1060     discard;
1061  @}
1062@end smallexample
1063
1064@end deftypefn
1065
1066@deftypefn Test {} list [@var{comparator}] [@var{match-type}] @
1067                        [ :delim @var{delimiters}(string) ] @
1068                @var{headers}(string-list) @var{keys}(string-list)
1069@*Synopsis:
1070@smallexample
1071require "test-list";
1072if list @var{args}
1073  @{
1074     @dots{}
1075  @}
1076@end smallexample
1077@*Description:
1078The @code{list} test evaluates to true if any of @var{headers} matches any
1079key from @var{keys}.  Each header is regarded as containing a list of
1080keywords.  By default, comma is assumed as list separator.  This can be
1081overridden by specifying the @code{:delim} tag, whose value is a
1082string consisting of valid list delimiter characters.
1083
1084Example:
1085
1086This test can be used in conjunction with the @code{spamd} test
1087described above:
1088
1089@smallexample
1090require ["fileinto", "test-spamd", "test-list"];
1091
1092if spamd :host 127.0.0.1 :port 3333
1093  @{
1094     if list :matches :delim " ,"
1095             "X-Spamd-Keywords" [ "HTML_*", "FORGED_*" ]
1096       @{
1097          fileinto "~/mail/spam";
1098       @}
1099     else
1100       @{
1101          discard;
1102       @}
1103  @}
1104@end smallexample
1105@end deftypefn
1106
1107@deftypefn Test {} timestamp  [:before | :after] @
1108                   @var{header}(string) @var{date}(string)
1109@*Synopsis:
1110@smallexample
1111require "test-timestamp";
1112
1113if timestamp @var{arg}
1114  @{
1115     @dots{}
1116  @}
1117@end smallexample
1118@*Description:
1119The @code{timestamp} test compares the value of a structured date header
1120field (@var{header}) with the given date (@var{date}).
1121
1122If the tagged argument is @code{:after} and the date from the header is
1123after the specified date the result is true, otherwise, if the header
1124date is before the given date, the result is false.
1125
1126If the tagged argument is @code{:before} and the date from the header is
1127before the specified date the result is true, otherwise, if the header
1128date is after the given date, the result is false.
1129
1130If no tagged argument is supplied, @code{:after} is assumed.
1131
1132Almost any date format is understood.  @xref{Date Input Formats}, for
1133a detailed information on date formats.
1134
1135Example:
1136
1137The test below succeeds if the date in @samp{X-Expire-Timestamp}
1138header is more than 5 days older than the current date:
1139
1140@smallexample
1141require "test-timestamp";
1142
1143if timestamp :before "X-Expire-Timestamp" "now - 5 days"
1144  @{
1145     discard;
1146  @}
1147@end smallexample
1148@end deftypefn
1149
1150@node Actions
1151@section Actions
1152There are two groups of GNU Sieve actions: @dfn{built-in actions},
1153which are defined within the library, and @dfn{external actions}, i.e.
1154loadable modules that can be linked in at run time using the
1155@code{require} statement (@pxref{Require Statement}).
1156
1157@menu
1158* Built-in Actions::
1159* External Actions::
1160@end menu
1161
1162@node Built-in Actions
1163@subsection Built-in Actions
1164
1165The GNU libmu_sieve supports the following built-in actions:
1166
1167@itemize
1168@item stop
1169@item keep
1170@item discard
1171@item fileinto
1172@item reject
1173@item redirect
1174@end itemize
1175
1176Among them the first three actions do not need to be explicitly required
1177by a @code{require} statement, while the others do.
1178
1179These actions are described in detail below.
1180
1181@deffn Action stop
1182
1183The @code{stop} action ends all processing.  If no actions have been
1184executed, then the @code{keep} action is taken.
1185@end deffn
1186
1187@deffn Action keep
1188
1189The effect of this action is to preserve the current message in the
1190mailbox.  This action is executed if no other action has been executed.
1191@end deffn
1192
1193@deffn Action discard
1194
1195@code{Discard} silently throws away the current message.  No notification
1196is returned to the sender, the message is deleted from the mailbox.
1197
1198Example:
1199@smallexample
1200if header :contains ["from"] ["idiot@@example.edu"]
1201  @{
1202    discard;
1203  @}
1204@end smallexample
1205@end deffn
1206
1207@anchor{fileinto}
1208@deffn Action fileinto [:permissions @var{mode}] @var{folder}
1209@noindent
1210
1211Required arguments:
1212
1213@table @var
1214@item folder
1215A string representing the folder name
1216@end table
1217
1218@noindent
1219Tagged arguments:
1220
1221@table @code
1222@item :permissions @var{mode}
1223Specifies the permissions to use, if the mailbox is created.
1224@end table
1225
1226The @code{fileinto} action delivers the message into the specified
1227folder.  If the folder is local, it is created using permissions
1228@samp{0600}, for regular files, and @samp{0700} for directories.  This
1229default can be changed by using the @code{:permissions} tag.  Its
1230argument is a mode specification, similar to that used by
1231@command{chmod} shell utility.  It is a list of permissions settings
1232separated by commas.  Each setting begins with one of the following
1233letters:
1234
1235@table @asis
1236@item g
1237Set permissions for the users in the file group.
1238
1239@item o
1240Set permissions for users not in the file's group.
1241@end table
1242
1243This letter must be followed by either @samp{+} or @samp{=} and the
1244list of permissions to be set.  This latter list is a string
1245containing any one or both of the following characters:
1246
1247@table @asis
1248@item r
1249Grant permission to read.
1250
1251@item w
1252Grant permission to write.
1253@end table
1254
1255For example, the following instruction creates the mailbox
1256@file{~/shared} which will be world readable and writable
1257for the group:
1258
1259@smallexample
1260  fileinto :permissions "g=rw,o=r" "~/shared"
1261@end smallexample
1262
1263Notice that:
1264
1265@enumerate 1
1266@item
1267The @code{:permissions} setting are affected by the current umask
1268value.
1269
1270@item
1271Only @code{r} and @code{w} permissions can be set, since other
1272permissions do not seem to be useful for mailboxes.  However, for
1273mailboxes that have a directory structure (such as maildir and MH),
1274any settings in @samp{g} and @samp{o} sets imply setting the
1275executable bit.
1276
1277@item
1278Owner's permissions cannot be set.  The owner always has all
1279permissions on the mailbox he created.
1280
1281@item
1282The @code{:permissions} settings apply only to local mailboxes.  They
1283are ignored for remote mailboxes.
1284@end enumerate
1285
1286@end deffn
1287
1288@deffn Action reject @var{reason}
1289
1290The optional @code{reject} action refuses delivery of a message by sending
1291back a message delivery notification to the sender.  It resends the
1292message to the sender, wrapping it in a ``reject'' form, noting that it
1293was rejected by the recipient.  The required argument @var{reason} is
1294a string specifying the reason for rejecting the message.
1295
1296Example:
1297
1298If the message contained
1299@smallexample
1300Date: Tue, 1 Apr 1997 09:06:31 -0800 (PST)
1301From: coyote@@desert.example.org
1302To: roadrunner@@acme.example.com
1303Subject: I have a present for you
1304
1305I've got some great birdseed over here at my place.
1306Want to buy it?
1307@end smallexample
1308@noindent
1309@sp 1
1310and the user's script contained:
1311
1312@smallexample
1313if header :contains "from" "coyote@@desert.example.org"
1314  @{
1315    reject "I am not taking mail from you, and I don't want
1316            your birdseed, either!";
1317  @}
1318@end smallexample
1319@noindent
1320then the original sender <coyote@@desert.example.org> would receive the
1321following notification:
1322
1323@smallexample
1324To: <coyote@@desert.example.org>
1325X-Authentication-Warning: roadrunner set sender using -f flag
1326Content-Type: multipart/mixed; boundary=----- =_aaaaaaaaaa0
1327MIME-Version: 1.0
1328----- =_aaaaaaaaaa0
1329The original message was received at
1330Tue, 1 Apr 1997 09:07:15 -0800 from
1331coyote@@desert.example.org.
1332Message was refused by recipient's mail filtering program.
1333Reason given was as follows:
1334
1335I am not taking mail from you, and I don't want your
1336birdseed, either!
1337
1338----- =_aaaaaaaaaa0
1339Content-Type: message/delivery-status
1340
1341Reporting-UA: sieve; GNU Mailutils 0.1.3
1342Arrival-Date: Tue, 1 Apr 1997 09:07:15 -0800
1343Final-Recipient: RFC822; roadrunner@@acme.example.com
1344Action: deleted
1345Disposition: automatic-action/MDN-sent-automatically;deleted
1346Last-Attempt-Date: Tue, 1 Apr 1997 09:07:15 -0800
1347
1348----- =_aaaaaaaaaa0
1349Content-Type: message/rfc822
1350
1351From: coyote@@desert.example.org
1352To: roadrunner@@acme.example.com
1353Subject: I have a present for you
1354
1355I've got some great birdseed over here at my place.
1356Want to buy it?
1357----- =_aaaaaaaaaa0
1358@end smallexample
1359
1360If the @var{reason} argument is rather long, the common approach is
1361to use the combination of the @code{text:} and @code{#include} keywords,
1362e.g.:
1363
1364@smallexample
1365if header :mime :matches "Content-Type"
1366          [ "*application/msword;*", "*audio/x-midi*" ]
1367  @{
1368    reject text:
1369#include "nomsword.txt"
1370    .
1371    ;
1372  @}
1373@end smallexample
1374
1375@end deffn
1376
1377@deffn Action redirect @var{address}
1378The @code{redirect} action is used to send the message to another user at
1379a supplied @var{address}, as a mail forwarding feature does.  This action
1380makes no changes to the message body or existing headers, but it may add
1381new headers.  It also modifies the envelope recipient.
1382
1383The @code{redirect} command performs an MTA-style ``forward'' --- that
1384is, what you get from a @file{.forward} file using @code{sendmail} under
1385@sc{unix}.  The address on the SMTP envelope is replaced with the one on
1386the @code{redirect} command and the message is sent back
1387out.  @emph{Notice}, that it differs from the MUA-style forward, which
1388creates a new message with a different sender and message ID, wrapping
1389the old message in a new one.
1390@end deffn
1391
1392@node External Actions
1393@subsection External Actions
1394  GNU Mailutils is shipped with a set of external Sieve
1395actions.  These actions are compiled as loadable modules and must be
1396required prior to use (@pxref{Require Statement}).
1397
1398@deftypefn Action {}  moderator [:keep] [:address @var{address}(string)] @
1399                                [:source @var{sieve-file}(string)] @
1400                                [:program @var{sieve-text}(string)]
1401@*Synopsis:
1402@smallexample
1403require "moderator"
1404moderator @var{args};
1405@end smallexample
1406@*Description:
1407@cindex mailman
1408This action is a moderator robot for Mailman-driven mail archives.
1409A Mailman moderation request is a MIME message consisting of the
1410following three parts:
1411
1412@multitable @columnfractions 0.2 0.4 0.4
1413@headitem N @tab Content-Type @tab Description
1414@item 1 @tab  text/plain      @tab Introduction for the human reader.
1415@item 2 @tab  message/rfc822  @tab Original submission.
1416@item 3 @tab  message/rfc822  @tab Mailman control message.
1417@end multitable
1418
1419Replying to part 3 (keeping the subject intact) instructs Mailman to
1420discard the original submission.
1421
1422Replying to part 3 while adding an `Approved:' header with the list
1423password in it approves the submission.
1424
1425The @code{moderator} action spawns an inferior Sieve machine and
1426filters the original submission (part 2) through it.  If the inferior
1427machine marks the message as deleted, the action replies to the
1428control message, thereby causing the submission to be discarded.  The
1429@samp{From:} address of the reply can be modified using
1430@code{:address} tag.  After discarding the message, @code{moderator}
1431marks it as deleted, unless it is given @code{:keep} tag.
1432
1433If the @code{:source} tag is given, its argument specifies a Sieve
1434source file to be used on the message.  Otherwise, if @code{:program}
1435is given, its argument supplies a Sieve program to be used on this
1436message.  At most one of these tags may be specified.  Supplying them
1437both, or supplying several instances of the same tag, is an error. The
1438behavior of the action in this case is undefined.
1439
1440If neither @code{:program} nor @code{:source} is given,
1441@code{moderator} will create a copy of the existing Sieve machine and
1442use it on the message.
1443
1444The action checks the message structure: it will bail out if the message
1445does not have exactly 3 MIME parts, or if parts 2 and 3 are not of
1446@samp{message/rfc822} type.  It is the responsibility of the caller to
1447make sure the message is actually a valid Mailman moderation request
1448(see the example below).
1449
1450@*Example:
1451@smallexample
1452if allof(header :is "Sender" "mailman-bounces@@gnu.org",
1453         header :is "X-List-Administrivia" "yes")
1454  @{
1455     moderator :source "~/.sieve/mailman.sv";
1456  @}
1457@end smallexample
1458@end deftypefn
1459
1460@deftypefn Action {} pipe [:envelope] [:header] [:body] @var{command}(string)
1461@*Synopsis:
1462@smallexample
1463require "pipe";
1464
1465pipe @var{command}
1466@end smallexample
1467@*Description:
1468The @code{pipe} action executes a shell command specified by its
1469argument and pipes the entire message (including envelope) to its
1470standard input.  When given, tags @code{:envelope}, @code{:header},
1471and @code{:body} control what parts of the message to pipe to the
1472command.
1473
1474@*Example:
1475The example below uses the @command{putmail} utility
1476(@pxref{putmail}) to forward the message to user @samp{gray} on
1477the machine @samp{mail.gnu.org}.
1478
1479@smallexample
1480require "pipe";
1481
1482pipe "/usr/bin/putmail smtp://gray@@mail.gnu.org"
1483@end smallexample
1484@end deftypefn
1485
1486@deftypefn Action {} vacation [:days @var{ndays}(number)] @
1487                          [:subject @var{subject}(string)] @
1488                          [:aliases @var{addrlist}(string-list)] @
1489                          [:noreply @var{noreply-address}(string-list)] @
1490                          [:reply_regex @var{expr}(string)] @
1491                          [:reply_prefix @var{prefix}(string)] @
1492                          [:sender @var{email}(string)] @
1493                          [:database @var{path}(string)] @
1494                          [:return_address @var{email}(string)] @
1495                          [:header @var{headers}(string-list)] @
1496                          [:mime] @
1497                          [:always_reply] @
1498                          [:rfc2822] @
1499                          [:file] @
1500                          @var{text}(string)
1501@*Syntax:
1502@smallexample
1503require "vacation";
1504vacation @var{args};
1505@end smallexample
1506@*Description:
1507The @code{vacation} action returns a message with @var{text} to
1508the sender.  It is intended to inform the sender that the recipient is
1509not currently reading his mail.
1510
1511If the @code{:file} tag is present, @var{text} is treated as the name
1512of the file to read the body of the reply message from.  When used together
1513with tag @code{:rfc2822}, the file should be formatted as a valid RFC
15142822 message, i.e. headers followed by empty line and body.  Headers
1515may not contain @samp{To}, @samp{From}, and @samp{Subject}, as these
1516will be generated automatically.
1517
1518If the @code{:subject} tag is given, its argument sets the subject of
1519the message.  Otherwise, the subject is formed by prefixing original
1520subject with @samp{Re:}, or the @var{prefix} given with the
1521@code{:reply_prefix} tag.  Before prefixing, any original prefixes
1522matching extended regular expression @var{expr} (@code{:reply_regex}
1523tag) are stripped from the subject line.  If @code{:reply_regex} is not
1524specified, the default regexp is @samp{^re: *}.
1525
1526Another headers can be added using the @code{:header} tag.  Its
1527argument is a list of header strings, each one having the form
1528@samp{"@var{name}:@var{value}"}.  Additional whitespace is allowed on
1529both sides of the colon.
1530
1531The @code{:aliases} tag instructs @code{vacation} to handle messages
1532for any address in @var{addrlist} in the same manner as those received
1533for the user's principal email.
1534
1535Before processing, @code{vacation} compares the sender address with
1536its @dfn{address exclusion list}.  Elements of this list are extended
1537case-insensitive regular expressions.  If the sender address matches
1538any of these expressions, the message will not be replied.  The default
1539exclusion list is:
1540
1541@smallexample
1542    .*-REQUEST@@.*
1543    .*-RELAY@@.*
1544    .*-OWNER@@.*
1545    ^OWNER-.*
1546    ^postmaster@@.*
1547    ^UUCP@@.*
1548    ^MAILER@@.*
1549    ^MAILER-DAEMON@@.*
1550@end smallexample
1551
1552New entries can be added to this list using @code{:noreply} tag.
1553
1554The @code{:days} tag sets the @dfn{reply interval}.  A reply is sent to
1555each sender once in @var{ndays} days.  GNU Sieve keeps track of
1556sender addresses and dates in file @file{.vacation} stored in
1557the user's home directory.  The file name can be changed using the
1558@code{:database} tag.
1559
1560The tag @code{:always_reply} instructs vacation to respond to the
1561message regardless of whether the user email is listed as a recipient
1562for the message.
1563@end deftypefn
1564
1565@node Extensions
1566@section Extensions
1567
1568The following extensions are implemented
1569
1570@menu
1571* encoded-character::
1572* relational::
1573* variables::
1574* environment::
1575* numaddr::
1576* editheader::
1577* list::
1578* moderator::
1579* pipe::
1580* spamd::
1581* timestamp::
1582* vacation::
1583@end menu
1584
1585@node encoded-character
1586@subsection The encoded-character extension
1587
1588The @samp{encoded-character} extension complies with @cite{RFC 5228},
1589part 2.4.2.4.  It provides a way of incorporating multibyte sequences
1590in a Sieve script using only ASCII characters.  This is a built-in
1591extension.  It is enabled using the following statement:
1592
1593@example
1594require "encoded-character";
1595@end example
1596
1597When this extension is enabled, the sequences @samp{$@{hex: ...@}},
1598and @samp{$@{unicode: ...@}} can appear inside of quoted strings.
1599
1600The sequence
1601
1602@example
1603$@{hex: @var{XX}@}
1604@end example
1605
1606@noindent
1607where @var{XX} is a sequence of one or two-digit hex numbers separated
1608by any amount of whitespace, is replaced with the octets with the
1609hexadecimal values given by each hex number.  For example,
1610
1611@example
1612"$@{hex: 24 24@}" @result{} "$$"
1613@end example
1614
1615Thus, the following script will discard any message containing three
1616contiguous dollar signs in its @samp{Subject} header:
1617
1618@example
1619require "encoded-character";
1620
1621if header :contains "Subject" "$$@{hex:24 24@}" @{
1622     discard;
1623@}
1624@end example
1625
1626The @samp{hex:} keyword is case-insensitive.  If @var{XX} contains
1627invalid hex numbers, the entire sequence is left verbatim.  This is
1628illustrated by the following example:
1629
1630@example
1631"$$@{hex:40@}"         @result{} "$@@"
1632"$@{hex: 40 @}"        @result{} "@@"
1633"$@{HEX: 40@}"         @result{} "@@"
1634"$@{hex:40"             @result{} "$@{hex:40"
1635"$@{hex:400@}"         @result{} "$@{hex:400@}"
1636"$@{hex:4$@{hex:30@}@}"  @result{} "$@{hex:40@}"
1637@end example
1638
1639The sequence
1640
1641@example
1642$@{unicode: @var{HEXNUM}@}
1643@end example
1644
1645@noindent
1646where @var{HEXNUM} is a list of hexadecimal numbers separated with
1647whitespace, will be replaced by the UTF-8 encoding of the specified
1648Unicode characters, which are identified by the hexadecimal value of
1649@var{HEXNUM}.  For example, the following string represents a single
1650@samp{@@} sign:
1651
1652@example
1653"$@{UNICODE:40@}"
1654@end example
1655
1656Similarly to @samp{hex:}, the @samp{unicode:} indicator is case
1657insensitive.  The following examples demonstrate the handling of
1658several valid and invalid encodings:
1659
1660@example
1661"$@{unicode:40@}"      @result{} "@@"
1662"$@{ unicode:40@}"     @result{} "$@{ unicode:40@}"
1663"$@{UNICODE:40@}"      @result{} "@@"
1664"$@{UnICoDE:0000040@}" @result{} "@@"
1665"$@{Unicode:40@}"      @result{} "@@"
1666"$@{Unicode:Cool@}"    @result{} "$@{Unicode:Cool@}"
1667"$@{unicode:200000@}"  @result{} error
1668"$@{Unicode:DF01@}     @result{} error
1669@end example
1670
1671@node relational
1672@subsection The relational extension
1673
1674The @samp{relational} extension complies with @cite{RFC 3431}.  It is
1675a built-in extension.  When enabled, the two new match types become
1676available: @code{:count} and @code{:value}.  Both keywords take a
1677single argument defining the relational operator to use:
1678
1679@multitable @columnfractions 0.2 0.8
1680@item @samp{"gt"} @tab greater than (@samp{>})
1681@item @samp{"ge"} @tab greater than or equal (@samp{>=})
1682@item @samp{"lt"} @tab less than (@samp{<})
1683@item @samp{"le"} @tab less than or equal (@samp{<=})
1684@item @samp{"eq"} @tab equal to (@samp{==})
1685@item @samp{"ne"} @tab not equal to (@samp{!=})
1686@end multitable
1687
1688The @code{:value} keyword requires a relational comparison between
1689strings.  The left side of the relation is formed by the value from
1690the message.  The right side of the relation is the value from the
1691test expression.  If there are multiple values on either side or both
1692sides, the test is considered true if any pair is true.  For example,
1693
1694@example
1695require ["relational", "fileinto"];
1696
1697if header :value "gt" :comparator "i;ascii-numeric"
1698                ["x-spam-level] ["5"]
1699@{
1700  fileinto "spam";
1701@}
1702@end example
1703
1704The @code{:count} keyword counts the specified entities in the message
1705and compares their number with the value given in the test
1706expression.  The latter must be a list of one element.  This match
1707type can only be used with numeric comparators.  For example, the
1708following script will discard any message with 10 or more recipient
1709addresses in the @samp{To} and @samp{Cc} headers:
1710
1711@example
1712require "relational";
1713
1714if address :count "ge" :comparator "i;ascii-numeric"
1715                      ["to", "cc"] ["10"]
1716@{
1717    discard;
1718@}
1719@end example
1720
1721@node variables
1722@subsection The variables extension
1723
1724The @samp{variables} extension is defined in @cite{RFC 5229}.  It is
1725a built-in extension.  It introduces support for variables in Sieve
1726scripts.
1727
1728There are two kind of variables: user-defined and match variables.
1729
1730A @dfn{user-defined} variable is initialized using the @code{set}
1731action:
1732
1733@deftypefn Action {} set [@var{modifiers}] @var{name}(string) @var{value}(string)
1734Stores the specified @var{value} in the variable identified by
1735@var{name}.  Optional @var{modifiers} are applied on @var{value} before it
1736is stored in the variable.
1737
1738The following modifiers are available:
1739
1740@table @code
1741@item :lower
1742Convert value to lower case letters.
1743@item :upper
1744Convert value to upper case letters.
1745
1746@item :lowerfirst
1747Convert the first character in value to lower case.
1748
1749@item :upperfirst
1750Convert the first character in value to upper case.
1751
1752@item :quotewildcard
1753Quote wildcard characters (@samp{*}, @samp{?}, @samp{\}) by prefixing
1754each occurrence with a backslash (@samp{\}).  This can be used to
1755ensure that the variable will only match a literal occurrence if used
1756as a parameter to @code{:matches}.
1757
1758@item :length
1759The value is the decimal number of characters in the expansion,
1760converted to a string.
1761@end table
1762
1763When several modifiers are present, they are applied in the following
1764order of precedence (largest value first):
1765
1766@multitable @columnfractions 0.2 0.8
1767@headitem precedence @tab modifiers
1768@item 40 @tab @code{:lower} or @code{:upper}
1769@item 30 @tab @code{:lowerfirst} or @code{:upperfirst}
1770@item 20 @tab @code{:quotewildcard}
1771@item 10 @tab @code{:length}
1772@end multitable
1773
1774Modifiers having the same precedence (i.e. listed on the same row in
1775the above table) cannot be used together.
1776@end deftypefn
1777
1778Variables are referenced within text strings using the construct
1779@samp{$@{@var{name}@}}, where @var{name} is the name of the variable
1780as it appeared in the first parameter to the @code{set} statement.
1781For example:
1782
1783@example
1784require "variables";
1785
1786set "sender" "root@*":
1787
1788if envelope :matches "$@{sender@}"
1789@{
1790   ...
1791@}
1792@end example
1793
1794@dfn{Match variables} refer to parts of the most recently evaluated
1795successful match of type @code{:matches} or @code{:regex}.  They have
1796names consisting entirely of decimal digits.  The variable
1797@samp{$@{0@}} refers to the entire matched expression.  The variable
1798@samp{$@{1@}} refers to the substring matching the first occurrence of
1799the wildcard (@samp{?} and @samp{*}), @samp{$@{2@}} refers to the
1800second occurrence and so on.  The wildcards match as little as possible
1801(non-greedy matching).  For example:
1802
1803@example
1804require ["variables", "fileinto"];
1805
1806if header :matches "List-ID" "*<*@*" @{
1807   fileinto "INBOX.lists.$@{2@}";
1808   stop;
1809@}
1810@end example
1811
1812If @code{:regex} match is used, the match variables starting from
1813@samp{$@{1@}} refer to the substrings of the argument value matching
1814subsequent parenthesized groups of the regular expression.
1815
1816@deftypefn Test {} string [@var{comparator}] @
1817                          [@var{match-type}] @
1818                          @var{source}(string-list) @var{keys}(string-list)
1819The @code{string} test compares two strings according to the selected
1820comparator and match type.   The test evaluates to @samp{true} if any
1821two strings from @var{source} and @var{keys} match.
1822
1823The @samp{:count} match used in @samp{string} counts each empty string
1824as 0, and each non-empty one as 1.  The count of a string list is the
1825sum of the counts of the member strings.
1826@end deftypefn
1827
1828@node environment
1829@subsection environment
1830
1831The @samp{environment} extension complies with @cite{RFC 5183}.  It is
1832a built-in extension.  It introduces the following test:
1833
1834@deftypefn Test {} environment [@var{comparator}] @
1835                               [@var{match-type}] @
1836                               @var{name}(string) @var{keys}(string-list)
1837The @code{environment} test evaluates to @samp{true} if the value of
1838the environment items @var{name} matches any string from @var{keys}.
1839@end deftypefn
1840
1841The following environment items are defined:
1842
1843@table @asis
1844@item domain
1845The primary DNS domain of the machine where the Sieve script is
1846executing.
1847
1848@item host
1849The fully-qualified domain name of the host where the Sieve script is
1850executing.
1851
1852@item location
1853Type of service that is evaluating the script.   Depending on the
1854utility that is evaluating the script it is:
1855
1856@multitable @columnfractions 0.6 0.4
1857@headitem Utility @tab Location
1858@item sieve @tab @samp{"MUA"}, or set with the @option{--environment} option.
1859@item maidag @tab @samp{"MDA"}
1860@item inc @tab @samp{"MUA"}
1861@end multitable
1862
1863@item name
1864The string @samp{GNU Mailutils}
1865
1866@item phase
1867The point relative to final delivery where the Sieve script is being
1868evaluated.  Depending on the utility that is evaluating the script it is:
1869
1870@multitable @columnfractions 0.6 0.4
1871@headitem Utility @tab Location
1872@item sieve @tab @samp{post} unless set with the @option{--environment} option.
1873@item maidag @tab @samp{"during"}
1874@item inc @tab @samp{"post"}
1875@end multitable
1876
1877@item version
1878Mailutils version string (e.g. @samp{@value{VERSION}}).
1879@end table
1880
1881@node numaddr
1882@subsection The numaddr extension
1883
1884This is an example loadable extension.  @ref{External Tests, numaddr}.
1885
1886@node editheader
1887@subsection The editheader extension
1888
1889The @code{editheader} extension complies with @cite{RFC 5293}.  It
1890provides the following actions:
1891
1892@deftypefn Action {} addheader [:last] @var{field-name}(string) @var{value}(string)
1893Adds a header field to the existing message header.  By default the
1894header is inserted at the beginning of the header list.  If the tag
1895@code{:last} is specified, it is appended at the end.
1896@end deftypefn
1897
1898@deftypefn Action {} deleteheader" [:index @var{fieldno}(number) :last] @
1899                                   [@var{comparator}] @
1900                                   [@var{match-type}] @
1901                                   @var{field-name}(string) @
1902                                   [@var{value-patterns}(string-list)]
1903
1904Deletes occurrences of the header field matching the criteria.
1905
1906The @var{value-patterns}, if specified, determines which occurrences
1907of the header fielde to delete.  If not supplied, @var{comparator} and
1908@var{match-type} are silently ignored.
1909
1910If @samp{:index @var{fieldno}} is specified, only the numbered
1911occurrence of the named header field will be matched (header numbering
1912begins at 1),  If @code{:last} is specified, the count is backwards; 1
1913denotes the last named header field, 2 the second to last, and so on.
1914The counting happens before the @var{value-patterns} match, if any.
1915Thus, e.g. the action
1916
1917@example
1918deleteheader :index 1 :contains "Delivered-To" "bob@@example.com";
1919@end example
1920
1921@noindent
1922would delete the first @samp{Delivered-To} header field if it contains
1923the string @samp{bob@@example.com}.
1924@end deftypefn
1925
1926@node list
1927@subsection The list extension
1928
1929@ref{External Tests, list}.
1930
1931@node moderator
1932@subsection The moderator extension
1933
1934A loadable extension implementing a moderator robot for Mailman-driven
1935mail archives.  @ref{External Actions, moderator}.
1936
1937@node pipe
1938@subsection The pipe extension
1939
1940A loadable extension for external command execution.  It provides the
1941@code{pipe} action (@pxref{External Actions, pipe}) and test
1942(@pxref{External Tests, pipe}).
1943
1944@node spamd
1945@subsection The spamd extension
1946
1947Implements a test which interfaces to SpamAssassin filter.  This is a
1948loadable extension.  @pxref{External Tests, spamd}.
1949
1950@node timestamp
1951@subsection The timestamp extension
1952
1953The loadable extension @code{timestamp} implements a test for
1954comparing the value of a structured date header field with the given
1955date.
1956
1957Note: this extension will probably phase away in favor of the
1958@code{date} Sieve extension (@cite{RFC 5260}).
1959
1960@node vacation
1961@subsection The vacation extension
1962
1963The loadable extension @code{vacation} provides the action intended to
1964inform the sender that the recipient is not currently reading his mail.
1965
1966@xref{External Actions,vacation}.
1967
1968@node GNU Extensions
1969@section GNU Extensions
1970
1971This section summarizes the GNU extensions to the sieve language
1972
1973@enumerate 1
1974@item Multiline strings syntax
1975
1976GNU libmu_sieve understands the following multiline string syntax:
1977
1978@smallexample
1979@group
1980text:[-][@var{delimiter}]
1981....
1982@var{delimiter}
1983@end group
1984@end smallexample
1985
1986The meaning of optional flags is the same as in shell ``here document''
1987construct: the dash strips all leading tab characters from the string body,
1988thus allowing it to be indented in a natural fashion; @var{delimiter}
1989introduces the new end-of-text delimiter instead of the default
1990dot.  If @var{delimiter} starts with a backslash, no preprocessing will
1991be performed within a string.
1992
1993@item Handling of the @code{require} statement.
1994
1995@itemize
1996@item According to the RFC an error must occur if a @code{require} appears
1997after a command other than @code{require}.  The GNU sieve library allows
1998interspersing the @code{require} and other statements.  The only
1999requirement is that @code{require} must occur before a statement that is
2000using the required capability (@pxref{Require Statement}).
2001
2002@item Prefixing the required capability with ``test'' requires the use
2003of an extension test.
2004@end itemize
2005
2006@item @code{header} test
2007
2008The @code{header} takes an optional argument @code{:mime}, meaning to
2009scan the headers from each part of a multipart message.
2010
2011@item @code{size} test
2012
2013The @code{size} test allows to omit the optional argument
2014(:over|:under).  In this case exact equality is assumed.
2015
2016@item @code{envelope} test
2017
2018The only value that can be meaningfully used as the first required
2019argument of an @code{envelope} test is @samp{from}.  This limitation
2020may disappear from the subsequent releases.
2021
2022@item @code{fileinto} action
2023
2024The @code{fileinto} action allows to specify permissions on the mailbox,
2025in case it will be created (@pxref{fileinto}).
2026
2027@item Match type optional argument.
2028
2029Along with the usual @code{:is}, @code{:matches} and @code{:contains}
2030matching type, GNU sieve library understands @code{:regex} type.  This
2031matching type toggles POSIX Extended Regular Expression matching.
2032@end enumerate
2033
2034