Reference: File MailFilt.hst

Purpose:

The rules in file "MailFilt.hst" determine, which mails are loaded from POP3-servers (1.) and what to do with them after they have been loaded (2.):

1.) To load or not to load ...

If the filter-file contains "ignore"- or "kill"-rules, Hamster first tries to load the headers of the available mails, and only if the rules finally say "yes, it's ok to load them", the mails will be loaded completely and will be delivered to their final destination.

- Each mail starts with "yes, it's ok to load it".

- If a "ignore"-rule matches, the mail will not be loaded and will not be deleted.

- If a "kill"-rule matches, the mail will not be loaded but will be deleted.

- If a "load"-rule matches, a previous matching "ignore" or "kill" is revoked.

By default, "ignore" and "kill" work silent, so only Hamster knows, if and which messages were really ignored or killed. To enable notification-messages for each mail that was ignored or killed, add a "notify"-line.

Note: The "[X] Leave mails on server, i.e. do not delete them"-setting has a higher priority than the rules given here in the filter-file, so even if a rule says "delete this mail", it won't be deleted if this setting is activated.

2.) Recipient wanted, dead or alive ...

After a mail was loaded, it has to be delivered to its final destination. The second group of rules determine, in which local account-mailbox(es) or in which local newsgroup(s) the mail is stored.

- Each mail starts with an empty recipient- and newsgroups-list.

- If an "add"-rule matches, the given recipient(s) will be added to the recipient-list.

- If a "del"-rule matches, the given recipient(s) will be removed from the recipient-list.

- If a "set"-rule matches, the recipient-list will be replaced by the given recipient(s).

- If a "postto"-rule matches, the given newsgroup(s) will be added to the newsgroups-list.

The "addaccounts"-rule checks the given header-field, if it contains mail-addresses known by Hamster. If a local mail-address is recognized (especially one of the "Local mail addresses"), the corresponding account is added to the recipient-list.

If both the recipient-list and the newsgroups-list is still empty after all rules have been tested, the mail is not lost but always sent to a default-account. This default-account is always "admin" unless another default-user is given by the last parameter of a fetchmail/ControlRunFetchMail-scriptcommand or with a "default"-line in the filter-file.

Syntax-Overview:

	MFilterFile     =  *( MFilterBlock / cEOL )
	MFilterBlock    =  MFilterScope *( MFilterRule / cEOL )
	MFilterScope    =  "[" ScopePattern *( 1*WSP ScopePattern ) "]" cEOL
	MFilterRule     =  ["="] ( MRuleLoad / MRuleDeliver ) cEOL

	MRuleLoad       =  "load"   [ "("             ")" ] 1*WSP MSelection
	MRuleLoad       =/ "ignore" [ "("             ")" ] 1*WSP MSelection
	MRuleLoad       =/ "kill"   [ "("             ")" ] 1*WSP MSelection
	MRuleLoad       =/ "notify" [ "(" AccountList ")" ]
	MRuleLoad       =/ "notifyoff"

	MRuleDeliver    =  "default"       "(" AccountList   ")"
	MRuleDeliver    =/ "addaccounts" [ "("               ")" ] 1*WSP MDefaultField
	MRuleDeliver    =/ "add"           "(" AccountList   ")"   1*WSP MSelection
	MRuleDeliver    =/ "set"           "(" AccountList   ")"   1*WSP MSelection
	MRuleDeliver    =/ "del"           "(" AccountList   ")"   1*WSP MSelection
	MRuleDeliver    =/ "postto"        "(" NewsgroupList ")"   1*WSP MSelection

	MSelection      = [MSpecial] MDefaultField 1*( 1*WHSP MSelectPattern )
        MSpecial        = "unless" 1*WSP
	MDefaultField   = *( "~" / "*" ) ( MSingleField / MGroupedField )
	MSingleField    = ( <Name of any header-field> / "Bytes" ) [ ":" ]
	MGroupedField   = ( "Any-Sender" / "Any-Recipient" ) [ ":" ]
	MSelectPattern  = [ "+" / "-" ] [ "@" MSingleField ":" ] Pattern

	AccountList     =  <account-name>   *( "," <account-name>   )
	NewsgroupList   =  <newsgroup-name> *( "," <newsgroup-name> )

	ScopePattern    = [ "+" / "-" ] Pattern

	Pattern         = ( PatRegExp / PatSimple )
	PatRegExp       = "{" <PCRE-style regex-pattern> "}"
	PatSimple       = ( PatSimpleAll / PatSimpleText / PatSimpleNumber )
	PatSimpleAll    = "*"
	PatSimpleText   = """ <Text> """
	PatSimpleNumber = "%" ( "<" / "=" / ">" ) <Number>

	cEOL            = [ "#" <Comment> ] CRLF

Filter-Scope:

Each block starts with a "[...]"-header describing the identifiers, for which the following filter-rules should be tested.

The only way to set such an identifier is the last parameter of a fetchmail/ControlRunFetchMail-scriptcommand, e.g.: fetchmail "pop3.serv.er" "pop3" "$7" "" "admin,identifier"

	[*]
	# filter-rules for all mails, regardless of identifier used

	[private]
	# filter-rules for all mails fetched with identifier "private"

	[* -private]
	# filter-rules for all mails except those fetched with identifier "private"

Filter-Rules:

Note: The following description only covers the main differences between mail- and news-filters. For details on selection and patterns see Scores.hst.

Unlike news-filters, each rule starts with a specific keyword followed by its parameters within parenthesis:

	kill()                   From: "well.known@spamm.er"
	add(john)                To:   "john@mail.serv.er"
	postto(hamster.ehamster) To:   "ehamster@onelist.com"

The special field-name "Bytes" allows testing based on the size of the mail:

	ignore() Bytes: %>100000

The special field-name "Any-Sender" checks all of the following headers: "From:", "Apparently-From:", "Sender:", "Reply-To:", "X-Sender:", "Envelope-From:" and "X-Envelope-From:":

	load() Any-Sender: "boss@compa.ny" -@Subject:"You are fired!"

The special field-name "Any-Recipient" checks all of the following headers: "To:", "Apparently-To:", "CC:", "BCC:", "Envelope-To:", "X-Envelope-To:", "Original-Recipient:", "X-Resent-For:", "X-Resent-To:", "Resent-To:" and "Delivered-To:".

	add(john) Any-Recipient: "john@mail.serv.er"
	add(jane) Any-Recipient: "jane@mail.serv.er"
	addaccounts() Any-Recipient:

If a fieldname is preceded with "~", the value of the field is MIME-decoded before testing. If given, this decoding is also done for any additional "@"-fields in this line:

	load() ~To: "jürgen"
	load() ~Subject: "Hämstér" +@To:"jürgen"

By default, only the first header-line with the given name is tested. If a fieldname is preceded with "*", all header-lines with this name are tested:

	add(john) *Received: "john@"

If the filter rules are preceded by keyword "unless", the result of the filter is inverted, i. e. the line matches, if the given rule does NOT match::

	ignore() unless Any-Recipient: "my@address"

 

Examples:

Deliver mails based on known local mail-addresses:

	[*]
	addaccounts() Any-Recipient:
	addaccounts() *Received:

Send mails of Hamster-mailinglists to local newsgroups - and a copy of each mail to "admin", until you know if it works as expected ...:

	[*]
	postto(hamster.ml.usehamsternet) To: "usehamsternet@onelist.com"
	add(admin)                       To: "usehamsternet@onelist.com"
	postto(hamster.ml.ehamster) To: "ehamster@onelist.com"
	add(admin)                  To: "ehamster@onelist.com"

[www.elbiah.de Hamster Playground Documentation]