GNU Mailutils Manual (split by section):   Section:   Chapter:FastBack: Sieve Language   Up: Sieve Language   FastForward: Reporting Bugs   Contents: Table of ContentsIndex: Function Index

5.8 Extensions

The following extensions are implemented

5.8.1 The encoded-character extension

The ‘encoded-character’ extension complies with RFC 5228, part 2.4.2.4. It provides a way of incorporating multibyte sequences in a Sieve script using only ASCII characters. This is a built-in extension. It is enabled using the following statement:

require "encoded-character";

When this extension is enabled, the sequences ‘${hex: ...}’, and ‘${unicode: ...}’ can appear inside of quoted strings.

The sequence

${hex: XX}

where XX is a sequence of one or two-digit hex numbers separated by any amount of whitespace, is replaced with the octets with the hexadecimal values given by each hex number. For example,

"${hex: 24 24}" ⇒ "$$"

Thus, the following script will discard any message containing three contiguous dollar signs in its ‘Subject’ header:

require "encoded-character";

if header :contains "Subject" "$${hex:24 24}" {
     discard;
}

The ‘hex:’ keyword is case-insensitive. If XX contains invalid hex numbers, the entire sequence is left verbatim. This is illustrated by the following example:

"$${hex:40}"         ⇒ "$@"
"${hex: 40 }"        ⇒ "@"
"${HEX: 40}"         ⇒ "@"
"${hex:40"             ⇒ "${hex:40"
"${hex:400}"         ⇒ "${hex:400}"
"${hex:4${hex:30}}"  ⇒ "${hex:40}"

The sequence

${unicode: HEXNUM}

where HEXNUM is a list of hexadecimal numbers separated with whitespace, will be replaced by the UTF-8 encoding of the specified Unicode characters, which are identified by the hexadecimal value of HEXNUM. For example, the following string represents a single ‘@’ sign:

"${UNICODE:40}"

Similarly to ‘hex:’, the ‘unicode:’ indicator is case insensitive. The following examples demonstrate the handling of several valid and invalid encodings:

"${unicode:40}"      ⇒ "@"
"${ unicode:40}"     ⇒ "${ unicode:40}"
"${UNICODE:40}"      ⇒ "@"
"${UnICoDE:0000040}" ⇒ "@"
"${Unicode:40}"      ⇒ "@"
"${Unicode:Cool}"    ⇒ "${Unicode:Cool}"
"${unicode:200000}"  ⇒ error
"${Unicode:DF01}     ⇒ error

5.8.2 The relational extension

The ‘relational’ extension complies with RFC 3431. It is a built-in extension. When enabled, the two new match types become available: :count and :value. Both keywords take a single argument defining the relational operator to use:

"gt"greater than (‘>’)
"ge"greater than or equal (‘>=’)
"lt"less than (‘<’)
"le"less than or equal (‘<=’)
"eq"equal to (‘==’)
"ne"not equal to (‘!=’)

The :value keyword requires a relational comparison between strings. The left side of the relation is formed by the value from the message. The right side of the relation is the value from the test expression. If there are multiple values on either side or both sides, the test is considered true if any pair is true. For example,

require ["relational", "fileinto"];

if header :value "gt" :comparator "i;ascii-numeric"
                ["x-spam-level] ["5"]
{
  fileinto "spam";
}  

The :count keyword counts the specified entities in the message and compares their number with the value given in the test expression. The latter must be a list of one element. This match type can only be used with numeric comparators. For example, the following script will discard any message with 10 or more recipient addresses in the ‘To’ and ‘Cc’ headers:

require "relational";

if address :count "ge" :comparator "i;ascii-numeric"
                      ["to", "cc"] ["10"]
{
    discard;
}

5.8.3 The variables extension

The ‘variables’ extension is defined in RFC 5229. It is a built-in extension. It introduces support for variables in Sieve scripts.

There are two kind of variables: user-defined and match variables.

A user-defined variable is initialized using the set action:

Action: set [modifiers] name(string) value(string)

Stores the specified value in the variable identified by name. Optional modifiers are applied on value before it is stored in the variable.

The following modifiers are available:

:lower

Convert value to lower case letters.

:upper

Convert value to upper case letters.

:lowerfirst

Convert the first character in value to lower case.

:upperfirst

Convert the first character in value to upper case.

:quotewildcard

Quote wildcard characters (‘*’, ‘?’, ‘\’) by prefixing each occurrence with a backslash (‘\’). This can be used to ensure that the variable will only match a literal occurrence if used as a parameter to :matches.

:length

The value is the decimal number of characters in the expansion, converted to a string.

When several modifiers are present, they are applied in the following order of precedence (largest value first):

precedencemodifiers
40:lower or :upper
30:lowerfirst or :upperfirst
20:quotewildcard
10:length

Modifiers having the same precedence (i.e. listed on the same row in the above table) cannot be used together.

Variables are referenced within text strings using the construct ‘${name}’, where name is the name of the variable as it appeared in the first parameter to the set statement. For example:

require "variables";

set "sender" "root
":

if envelope :matches "${sender}"
{
   ...
}

Match variables refer to parts of the most recently evaluated successful match of type :matches or :regex. They have names consisting entirely of decimal digits. The variable ‘${0}’ refers to the entire matched expression. The variable ‘${1}’ refers to the substring matching the first occurrence of the wildcard (‘?’ and ‘*’), ‘${2}’ refers to the second occurrence and so on. The wildcards match as little as possible (non-greedy matching). For example:

require ["variables", "fileinto"];

if header :matches "List-ID" "*<*
" {
   fileinto "INBOX.lists.${2}";
   stop;
}

If :regex match is used, the match variables starting from ‘${1}’ refer to the substrings of the argument value matching subsequent parenthesized groups of the regular expression.

Test: string [comparator] [match-type] source(string-list) keys(string-list)

The string test compares two strings according to the selected comparator and match type. The test evaluates to ‘true’ if any two strings from source and keys match.

The ‘:count’ match used in ‘string’ counts each empty string as 0, and each non-empty one as 1. The count of a string list is the sum of the counts of the member strings.

5.8.4 environment

The ‘environment’ extension complies with RFC 5183. It is a built-in extension. It introduces the following test:

Test: environment [comparator] [match-type] name(string) keys(string-list)

The environment test evaluates to ‘true’ if the value of the environment items name matches any string from keys.

The following environment items are defined:

domain

The primary DNS domain of the machine where the Sieve script is executing.

host

The fully-qualified domain name of the host where the Sieve script is executing.

location

Type of service that is evaluating the script. Depending on the utility that is evaluating the script it is:

UtilityLocation
sieve"MUA"’, or set with the --environment option.
maidag"MDA"
inc"MUA"
name

The string ‘GNU Mailutils

phase

The point relative to final delivery where the Sieve script is being evaluated. Depending on the utility that is evaluating the script it is:

UtilityLocation
sievepost’ unless set with the --environment option.
maidag"during"
inc"post"
version

Mailutils version string (e.g. ‘3.14’).

5.8.5 The numaddr extension

This is an example loadable extension. numaddr.

5.8.6 The editheader extension

The editheader extension complies with RFC 5293. It provides the following actions:

Action: addheader [:last] field-name(string) value(string)

Adds a header field to the existing message header. By default the header is inserted at the beginning of the header list. If the tag :last is specified, it is appended at the end.

Action: deleteheader" [:index fieldno(number) :last] [comparator] [match-type] field-name(string) [value-patterns(string-list)]

Deletes occurrences of the header field matching the criteria.

The value-patterns, if specified, determines which occurrences of the header fielde to delete. If not supplied, comparator and match-type are silently ignored.

If ‘:index fieldno’ is specified, only the numbered occurrence of the named header field will be matched (header numbering begins at 1), If :last is specified, the count is backwards; 1 denotes the last named header field, 2 the second to last, and so on. The counting happens before the value-patterns match, if any. Thus, e.g. the action

deleteheader :index 1 :contains "Delivered-To" "bob@example.com";

would delete the first ‘Delivered-To’ header field if it contains the string ‘bob@example.com’.

5.8.7 The list extension

list.

5.8.8 The moderator extension

A loadable extension implementing a moderator robot for Mailman-driven mail archives. moderator.

5.8.9 The pipe extension

A loadable extension for external command execution. It provides the pipe action (see pipe) and test (see pipe).

5.8.10 The spamd extension

Implements a test which interfaces to SpamAssassin filter. This is a loadable extension. see spamd.

5.8.11 The timestamp extension

The loadable extension timestamp implements a test for comparing the value of a structured date header field with the given date.

Note: this extension will probably phase away in favor of the date Sieve extension (RFC 5260).

5.8.12 The vacation extension

The loadable extension vacation provides the action intended to inform the sender that the recipient is not currently reading his mail.

See vacation.

GNU Mailutils Manual (split by section):   Section:   Chapter:FastBack: Sieve Language   Up: Extensions   FastForward: Reporting Bugs   Contents: Table of ContentsIndex: Function Index