<?xml version="1.0" encoding="utf-8"?><!DOCTYPE article  PUBLIC '-//OASIS//DTD DocBook XML V4.4//EN'  'http://www.docbook.org/xml/4.4/docbookx.dtd'><article><articleinfo><title>MemberManual/Email/EximFilter</title><revhistory><revision><revnumber>25</revnumber><date>2020-09-03 21:58:33</date><authorinitials>StephenMichel</authorinitials><revremark>Remove excessive admonition box</revremark></revision><revision><revnumber>24</revnumber><date>2020-09-03 21:57:29</date><authorinitials>StephenMichel</authorinitials><revremark>Reorganize in order of usefulness</revremark></revision><revision><revnumber>23</revnumber><date>2020-08-09 21:59:54</date><authorinitials>StephenMichel</authorinitials><revremark>Added Sieve filter example</revremark></revision><revision><revnumber>22</revnumber><date>2019-02-02 03:42:48</date><authorinitials>BjörnLindström</authorinitials></revision><revision><revnumber>21</revnumber><date>2019-02-02 03:42:22</date><authorinitials>BjörnLindström</authorinitials></revision><revision><revnumber>20</revnumber><date>2019-02-02 03:42:01</date><authorinitials>BjörnLindström</authorinitials><revremark>Added my .forward for some more complicated examples using 'matches' regexps.</revremark></revision><revision><revnumber>19</revnumber><date>2016-04-24 03:23:52</date><authorinitials>StephenMichel</authorinitials><revremark>oops, syntax</revremark></revision><revision><revnumber>18</revnumber><date>2016-04-24 03:13:21</date><authorinitials>StephenMichel</authorinitials><revremark>Better solution</revremark></revision><revision><revnumber>17</revnumber><date>2016-04-24 02:35:53</date><authorinitials>c-71-192-154-186.hsd1.ma.comcast.net</authorinitials><revremark>Added a new template</revremark></revision><revision><revnumber>16</revnumber><date>2013-01-14 09:10:39</date><authorinitials>ClintonEbadi</authorinitials><revremark>cat / needs work</revremark></revision><revision><revnumber>15</revnumber><date>2013-01-08 20:33:20</date><authorinitials>ClintonEbadi</authorinitials><revremark>update link to documentation isn't hopelessly obsolete</revremark></revision><revision><revnumber>14</revnumber><date>2008-07-07 04:28:16</date><authorinitials>localhost</authorinitials><revremark>converted to 1.6 markup</revremark></revision><revision><revnumber>13</revnumber><date>2008-04-24 17:51:29</date><authorinitials>NathanKennedy</authorinitials></revision><revision><revnumber>12</revnumber><date>2008-04-22 03:37:37</date><authorinitials>MichaelOlson</authorinitials><revremark>Explain credentials</revremark></revision><revision><revnumber>11</revnumber><date>2008-04-15 01:45:28</date><authorinitials>AdamChlipala</authorinitials><revremark>Kerberos principals?</revremark></revision><revision><revnumber>10</revnumber><date>2008-02-23 01:09:11</date><authorinitials>cpe-76-172-126-78.socal.res.rr.com</authorinitials></revision><revision><revnumber>9</revnumber><date>2008-02-23 00:45:38</date><authorinitials>cpe-76-172-126-78.socal.res.rr.com</authorinitials></revision><revision><revnumber>8</revnumber><date>2008-02-23 00:32:46</date><authorinitials>FrankBynum</authorinitials></revision><revision><revnumber>7</revnumber><date>2008-02-23 00:26:25</date><authorinitials>FrankBynum</authorinitials></revision><revision><revnumber>6</revnumber><date>2008-02-23 00:25:39</date><authorinitials>FrankBynum</authorinitials></revision><revision><revnumber>5</revnumber><date>2008-02-23 00:23:31</date><authorinitials>FrankBynum</authorinitials></revision><revision><revnumber>4</revnumber><date>2008-02-22 23:52:31</date><authorinitials>FrankBynum</authorinitials></revision><revision><revnumber>3</revnumber><date>2008-02-22 23:51:47</date><authorinitials>FrankBynum</authorinitials><revremark>Old ac.uk page does not exist anymore! Found a substitute.</revremark></revision><revision><revnumber>2</revnumber><date>2007-12-05 09:42:14</date><authorinitials>66-234-51-139.nyc.cable.nyct.net</authorinitials><revremark>First line of exim filters MUST be &quot;# Exim filter&quot;</revremark></revision><revision><revnumber>1</revnumber><date>2007-11-01 21:44:45</date><authorinitials>MichaelOlson</authorinitials><revremark>Initial contents</revremark></revision></revhistory></articleinfo><para>This page explains how to use Exim's built-in per-user filtering system to sort your mail into different folders or deliver it elsewhere. </para><section><title>Introduction</title><para>We use Exim as our mail daemon.  It has a built-in filtering system that allows people to write a &quot;.forward file&quot; to give it custom instructions.  Normally this is stored at <code>~/.forward</code>, but at HCoop we store it at <emphasis role="strong"><code>~/.public/.forward</code></emphasis> to make it easier to keep the rest of your home directory private.  So when we say &quot;.forward&quot; on the rest of this page, we mean <emphasis role="strong"><code>~/.public/.forward</code></emphasis>. </para><para>When email is delivered, the delivery process will run as the <code>USER.daemon</code> user, where <code>USER</code> is your HCoop username. </para><section><title>Delivering all mail to a different address</title><para>If you want email sent to your HCoop email address to be forwarded elsewhere, you can do that as follows. </para><itemizedlist><listitem><para>Make a <code>.public/.forward</code> file in your home directory. </para></listitem><listitem><para>It should contain only one line, consisting of just the e-mail address to which mail should be forwarded. </para></listitem></itemizedlist><para>(This is a standard UNIX <code>.forward</code> file.) </para></section><section><title>Putting mail into separate folders</title><para>For anything more complicated, you have two options: sieve and exim filters. In <ulink url="https://wiki.hcoop.net/MemberManual/Email/EximFilter/StephenMichel#">StephenMichel</ulink>'s opinion, sieve filters have the saner syntax, although exim filters are slightly more powerful. To use them, start your <code>.public/.forward</code> file with one of these special lines for identifying the type of filter: </para><itemizedlist><listitem><para><code># Exim filter</code> </para></listitem><listitem><para><code># Sieve filter</code> </para></listitem></itemizedlist><para><emphasis role="strong">The line above is not an ordinary comment.</emphasis> Any other values will cause Exim to attempt to treat the file as a list of forward addresses instead of a filter file. </para><para><emphasis role="strong">Create folders before adding rules for them.</emphasis> Exim is not able to create new folders, only sort mail into existing ones. You should create and subscribe to any folders mentioned in these filters from within your IMAP client before adding them to your filter. </para></section></section><section><title>Sieve Filter Examples</title><section><title>StephenMichel</title><important><para><emphasis role="strong">Lessons learned the hard way</emphasis> </para><itemizedlist><listitem><para>If your script has a syntax error, and parsing reaches that point in the script, mail will simply not be delivered. <emphasis role="strong">Always send yourself a test email after making changes.</emphasis> </para></listitem><listitem><para>Probably due to our AFS setup, the only filing syntax that seems to work is <emphasis role="strong">fileinto</emphasis>, <emphasis>using an absolute path</emphasis>. <emphasis role="strong">keep</emphasis> does not work, including automatic/implicit keep, so you must explicitly <emphasis role="strong">fileinto</emphasis> your inbox. </para></listitem><listitem><para>If you just want quick examples, use the section below, <ulink url="https://www.fastmail.com/help/technical/sieve-howto.html">fastmail's guide</ulink>, or <ulink url="https://protonmail.com/support/knowledge-base/sieve-advanced-custom-filters/">ProtonMail's guide</ulink>. However, if you want to actually understand what you're doing &amp; what's possible, all the various articles out there really suck; fortunately (and surprisingly) <ulink url="https://tools.ietf.org/html/rfc5228">rfc 5228 itself</ulink> is relatively light reading and you'll save yourself a lot of time starting there instead of searching for a more &quot;consumer-facing&quot; explanation. </para></listitem></itemizedlist></important><para>This is my current filter, with two changes: </para><itemizedlist><listitem><para>Removed rules that were identical in syntax, just with different values </para></listitem><listitem><para>Changed all domains to <code>example.com</code>, to prevent spambots picking up anyone's email address off this page. </para></listitem></itemizedlist><screen><![CDATA[# Sieve filter
]]><![CDATA[
require ["fileinto"]; 
]]><![CDATA[
if address :contains ["to", "cc", "bcc"] ["admin@example.com", "community@example.com", "privacy@example.com"] {
    fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/.snowdrift.aliases/";
}
elsif address :contains :domain "to" "lists.example.com" {
    fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/.hcoop/";
}
# elsif address :matches ["to", "cc", "bcc"] ["snowdrift@example.com", "snowdrift+*@example.com"] {
#     fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/.snowdrift/";
# }
elsif address :contains ["to", "from", "cc", "bcc"] "board@example.com" {
    fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/.Board/";
}
elsif address :contains "from" "notifications@example.com" {
    fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/.notifications.GitHub/";
}
elsif header :matches "Reply-To" "*@boards.example.com" {
    fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/.notifications.Trello/";
}
elsif address :contains "to" "hnreplies.com@example.com" {
    fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/.notifications.HN/";
}
elsif allof (
    address :contains "from" "admin@example.com",
    header :contains "subject" "[Lutris]  Your daily moderator mail"
) {
    fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/.lutris/";
}
else {
    fileinto "/afs/hcoop.net/user/s/sm/smichel17/Maildir/";
}
stop;]]></screen></section></section><section><title>Exim Filter Examples</title><para>The exim project website has some good examples <ulink url="http://www.exim.org/exim-html-current/doc/html/spec_html/filter_ch-exim_filter_files.html"/>. </para><para>We also have example <code>.public.forward</code> files in the following section. </para><section><title>NathanKennedy</title><para>It is possible to set up custom filters to do fancy things based on the X-Spam-Level: header.  Here is <ulink url="https://wiki.hcoop.net/MemberManual/Email/EximFilter/NathanKennedy#">NathanKennedy</ulink>'s <code>~/.public/.forward</code> file.  He finds that the default setting of 5.0 is too wimpy, and lets too much spam into his inbox.  Virtually no ham that he gets scores less than 3.0, whereas a lot of spam scores less than 5.0, so he'd rather have anything over 3.0 go to his Junk folder.  At the same time, he doesn't want to waste time, cycles, disk space or bandwidth with spam over 9.0.  Most of his spam does score 9.0, and this goes straight to /dev/null (immediately disposed of) with this filter. </para><para>Finally, he has all HCoop list email go into a special HCoop folder. </para><para>Without further ado: </para><screen><![CDATA[# Exim filter
logfile $home/.logs/mail/spamlog
if $header_subject contains "[HCoop"
then
    save $home/Maildir/.HCoop/
    finish
endif
if
    "${if def:h_X-Spam-Level {def}{undef}}" is "def"
then
    if $h_X-Spam-Level: begins "\*\*\*\*\*\*\*\*\*"
    then save "/dev/null" 660
    else
      if $h_X-Spam-Level: begins "\*\*\*"
      then save $home/Maildir/.Junk/
      endif
    endif
    finish
endif
if
    "${if def:h_X-Spam-Flag {def}{undef}}" is "def"
then
    save $home/Maildir/.Junk/
    finish
endif]]></screen></section><section><title>FrankBynum</title><screen><![CDATA[# Exim filter
# Lists
if $h_to: contains "lists.hcoop.net"
        then save $home/Maildir/.Causes.Hcoop/
elif $h_to: contains "groups.barackobama.com"
        then save $home/Maildir/.Causes.Obama/
elif $h_X-Generated-By: CONTAINS "Launchpad"
        then save $home/Maildir/.Causes.Floss/
# Junk
elif $h_X-Spam-Level: begins "\*\*\*\*\*\*\*\*\*"
        then save "/dev/null" 660
elif $h_X-Spam-Level: begins "\*\*\*\*"
        then save $home/Maildir/.Junk.Spam/
elif $h_X-Spam-Status: contains "BAYES_99"
        then save $home/Maildir/.Junk.Bayes_99/
endif]]></screen></section><section><title>StephenMichel</title><para>This template filters anything sent to <code>me@example.com</code> <emphasis>or</emphasis> to <code>me+$anything@example.com</code> into the sub-folder <code>me</code>. This is useful if you have one or more aliases set up, to filter mail for each alias into its own subfolder. </para><screen><![CDATA[if "$h_to:, $h_cc:, $h_bcc:" matches "me(\\\\+[\\^@]\\*)\\?@example\\\\.com"
        then save $home/Maildir/.me/
endif]]></screen></section><section><title>Björn Lindström</title><para>Some rules using <code>matches</code> which allows PCRE style regular expressions. </para><screen><![CDATA[# Exim filter
]]><![CDATA[
# Log
logfile $home/.logs/mail/exim.log
]]><![CDATA[
# Don't do any filtering on delivery failure messages from Exim.
if error_message then finish endif
]]><![CDATA[
# Spam
if "${if def:h_X-Spam-Level {def}{undef}}" is "def" then
    # Drops mail with a spam level above 9
    if $h_X-Spam-Level: matches "^\\\\*{9}" then
        seen
        finish
    # Puts other mail with a spam level above 3 into "Spam"
    elif $h_X-Spam-Level: matches "^\\\\*{3}" then
        save $home/Maildir/.Spam/
        finish
    endif
elif "${if def:h_X-Spam-Flag {def}{undef}}" is "def" then
    # Puts other mail with spam flag set into "Spam" also.
    save $home/Maildir/.Spam/
    finish
endif
]]><![CDATA[
# Filter into folders
if "$h_to:, $h_cc:, $h_bcc:" matches "\\\\b((bkhl|upp?sala|relax)@fandom\\\\.se|upp?salafandom@dang\\\\.se|fanac@lists\\\\.lysator\\\\.liu\\\\.se)\\\\b" then
    save $home/Maildir/.Fandom/
elif "$h_to:, $h_cc:, $h_bcc:" matches "@(\\.*\\\\.)?hcoop\\\\.net\\\\b" then
    save $home/Maildir/.HCoop/
endif]]></screen></section><section><title>Filtering out bogus bounce messages</title><para><ulink url="https://wiki.hcoop.net/MemberManual/Email/EximFilter/AdamChlipala#">AdamChlipala</ulink> found a trick a while back that allows you to filter out bogus bounce messages.  <ulink url="https://lists.hcoop.net/pipermail/hcoop-discuss/2007-January/000745.html"/> </para><!--rule (<hr>) is not applicable to DocBook--><para> <ulink url="https://wiki.hcoop.net/MemberManual/Email/EximFilter/CategoryMemberManual#">CategoryMemberManual</ulink> <ulink url="https://wiki.hcoop.net/MemberManual/Email/EximFilter/CategoryNeedsWork#">CategoryNeedsWork</ulink> </para></section></section></article>