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