1### fdm configuration
2### vim:ft=config
3###
4### All in one replacement for {get,fetch}mail and procmail.
5### <http://fdm.sf.net>
6###
7### Frank Terbeck <ft@bewatermyfriend.org>
8### <http://ft.bewatermyfriend.org/comp/data/fdm/fdm.conf.html>
9### Last-Modified: Thu Mar  8 17:03:05 2007
10###
11
12###########################################################################
13
14### The following strings are replaced in pipe commands and
15### maildir/mbox paths:
16###   %a: account name
17###   %h: user's home directory
18###   %n: user's uid
19###   %t: action name if performing action
20###   %u: name of user
21###   %H: current hour (00-23)
22###   %M: current minute (00-59)
23###   %S: current second (00-59)
24###   %d: current day of the month (00-31)
25###   %m: current month (01-12)
26###   %y: current year
27###   %W: current day of the week (0-6, Sunday is 0)
28###   %Y: current day of the year (000-365)
29###   %Q: current quarter (1-4)
30
31###########################################################################
32### Some macros used below.
33
34### where I keep my mail
35    $path       = "%h/Mail"
36
37### where I keep my config files
38    $cfgdir     = "%h/etc/fdm"
39
40### location of killfile
41    $killfile   = "%h/etc/mailnews/killfile"
42
43### spam filter commands
44    $com_spam_filter = "spamprobe receive"
45    $com_train_good  = "spamprobe good"
46    $com_train_spam  = "spamprobe spam"
47
48### some filters use these unix commands:
49    $com_sed        = "sed"
50    $com_awk        = "awk"
51    $com_perl       = "perl"
52
53### spam header expressions
54    $header_spam    = "X-SpamProbe"
55    $filtered_spam  = "SPAM"
56    $filtered_good  = "GOOD"
57    $filter_trained = " TRAINED"
58
59### if do_catchall is "yes", all incoming mail will be saved
60### to ${catchall_mbox}; useful for testing (so nothing gets lost).
61    $do_catchall    = "nope"
62    $catchall_mbox  = "%h/catchall.mbox"
63
64### this is used by my archive action.
65### Mails older than this (in days) are moved to the archive.
66    %max_age    = 30
67
68### zblog <http://zblog.bewatermyfriend.org>
69    $com_zblog  = "%h/bin/zblog"
70
71### print from headers (Sender, From, From:, Reply-To:)
72### used for killfiling.
73    $com_pfh = "${com_awk} '/^(From|From:|Reply-To:|Sender)/{sub(/[^ \\t]*[ \\t]*/,\"\",$0);print};/^\$/{exit 0}'"
74
75### list of headers I don't want.
76    $ill_headers = "("
77    $ill_headers = "${ill_headers}X-Qmail-Scanner.*|X-SA-Exim.*|X-CR-.*|"
78    $ill_headers = "${ill_headers}X-MIME-.*|X-Authentication-.*|"
79    $ill_headers = "${ill_headers}X-Mailman-.*|X-Spam-.*|X-MimeOLE|"
80    $ill_headers = "${ill_headers}X-Msmail-.*|X-Priority|X-MS-.*|"
81    $ill_headers = "${ill_headers}Thread-Topic|Thread-Index|"
82    $ill_headers = "${ill_headers}X-OriginalArrivalTime|"
83    $ill_headers = "${ill_headers}X-Face|DKIM-Signature|"
84    $ill_headers = "${ill_headers}X-IronPort-.*|DomainKey-Signature|"
85    $ill_headers = "${ill_headers}X-Rc-.*"
86    $ill_headers = "${ill_headers})"
87
88### perl script that filters out unwanted headers
89    $com_filter_headers = "${com_perl} -e '\$k=\$e=0;while(<>){if(\$e||m/^$/){\$e=1;print;next;}"
90    $com_filter_headers = "${com_filter_headers}if(m/^[ \\t]+/&&\$k){next;}if(m/^${ill_headers}:/i)"
91    $com_filter_headers = "${com_filter_headers}{\$k=1;next;}if(\$k){\$k=0;}print;}'"
92
93###########################################################################
94
95### This is used to set the maximum size of a mail. Mails larger than
96### this limit are dropped and, if applicable, not deleted from the
97### server.
98    set maximum-size 128M
99
100### If this option is specified, fdm(1) attempts to delete messages
101### which exceed maximum-size, and continue.If it is not specified,
102### oversize messages are a fatal error and cause fdm(1) to abort.
103   #set delete-oversized
104
105### If this option is specified, fdm(1) does not attempt to create a
106### lock file and allows multiple instances to run simultaneously.
107   #set allow-multiple
108
109### This sets an alternative lock file. The default is ~/.fdm.lock
110### for non-root users and /var/db/fdm.lock for root.
111    set lock-file "${cfgdir}/fdm.lock"
112
113### This specifies the locks to be used for mbox locking.  Possible
114### types are fcntl, flock, and dotlock. The flock and fcntl types
115### are mutually exclusive. The default is flock.
116   #set lock-types flock
117
118### This sets the default user to change to before delivering mail,
119### if fdmis running as root and no alternative user is specified as
120### part of the action or rule.
121   #set default-user "hawk"
122
123
124### This specifies the domains to be used when looking for users with
125### the from-headers keyword. The default is the computer's hostname.
126   #set domain "bewatermyfriend.org"
127
128### This allows the headers to be examined when looking for users to
129### be set. The default is to look only at the "From" and "Cc"
130### headers. The headers are case-insensitive.
131   #set header
132
133### This instructs fdm to proxy all connections through url. HTTP
134### and SOCKS5 proxies are supported at present (URLs of the form
135### http://host[:port] or socks://[user:pass@]host[:port]).
136### No authentication is supported for HTTP.
137   #set proxy
138
139### This option controls what fdm does with mail that reaches the
140### end of the ruleset (mail that matches no rules or matches only
141### rules with the continue keyword). drop will cause such mail to
142### be discarded, and keep will attempt to leave the mail on the
143### server.  The default is to keep the mail and log a warning that
144### it reached the end of the ruleset.
145    set unmatched-mail keep
146
147### This option makes fdm attempt to purge deleted mail from the
148### server (if supported) after count mails have been retrieved.
149    set purge-after none
150
151### If set, fdm will not insert a 'Received' header into each mail.
152   #set no-received
153
154### This specifies the umask(2) to use when creating files. 'user'
155### means to use the umask set when fdm is started, or umask may be
156### specified as a three-digit octal number.
157    set file-umask 077
158
159### This option allows the default group ownership of files and
160### directories created by fdm(1) to be specified. 'group' may be a
161### group name string or a numeric gid. 'user' does nothing.
162    set file-group user
163
164### This controls the maximum time to wait for a server to send data
165### before closing a connection. The default is 900 seconds.
166    set timeout 900
167
168###########################################################################
169
170### include account information from seperate file.
171### it contains lines that look like this:
172### account "name" server pop3 "pop3.serv.tld" user "uname" pass "pwd"
173    include "${cfgdir}/accounts.conf"
174
175###########################################################################
176
177### simple actions
178    action "drop" drop
179    action "keep" keep
180
181### zblog
182    action "zblog" pipe "${com_zblog} email"
183    action "zcomm" pipe "${com_zblog} commentmode"
184
185### killfiling
186    action "killfile" maildir "${path}/Trash"
187
188### a mailbox to rule them all
189    action "catchall" mbox "${catchall_mbox}"
190
191### spam actions
192    action "spam"                 maildir       "${path}/Spam"
193    action "train-spam"           pipe          "${com_train_spam}"
194    action "train-good"           pipe          "${com_train_good}"
195    action "sp-add-header"        add-header    "${header_spam}" "%[command1]"
196    action "sp-remove-header"     remove-header "${header_spam}"
197    action "sp-add-trained-good"  add-header    "${header_spam}" "${filtered_good}${filter_trained}"
198    action "sp-add-trained-spam"  add-header    "${header_spam}" "${filtered_spam}${filter_trained}"
199
200### action for adding Lines: headers
201### Current CVS versions can do this themselves.
202    action "add-lines-header" add-header "Lines" "%[body_lines]"
203
204### action to remove unneeded headers
205    action "remove-ill-headers" rewrite "${com_filter_headers}"
206
207### mark as read in maildirs. this requires /bin/sh to be somewhat POSIXly
208### correct. ash, ksh, bash etc. will do; older bourne shells (like /bin/sh
209### on OpenSolaris) will not. You'll need to use {base,dir}name with these.
210    action "maildir-mark-as-read" exec "mf=\"%[mail_file]\" ; mv \"\${mf}\" \"\${mf%%/*}\"/../cur/\"\${mf##*/}:2,S\""
211
212### archiving action
213    action "archive" mbox "${path}/archive/%[maildir]-%yq%Q" compress
214
215### handle mailinglists
216
217### path actions
218#{{{
219    action "inbox"                      maildir "${path}/Inbox"
220    action "debian-announce"            maildir "${path}/debian-announce"
221    action "debian-boot"                maildir "${path}/debian-boot"
222    action "debian-curiosa"             maildir "${path}/debian-curiosa"
223    action "debian-devel"               maildir "${path}/debian-devel"
224    action "debian-devel-announce"      maildir "${path}/debian-devel-announce"
225    action "debian-mentors"             maildir "${path}/debian-mentors"
226    action "debian-news-german"         maildir "${path}/debian-news-german"
227    action "debian-outbox"              maildir "${path}/debian-outbox"
228    action "debian-policy"              maildir "${path}/debian-policy"
229    action "debian-project"             maildir "${path}/debian-project"
230    action "debian-pts"                 maildir "${path}/debian-pts"
231    action "debian-publicity"           maildir "${path}/debian-publicity"
232    action "debian-release"             maildir "${path}/debian-release"
233    action "debian-security"            maildir "${path}/debian-security"
234    action "debian-vote"                maildir "${path}/debian-vote"
235    action "debian-women"               maildir "${path}/debian-women"
236    action "openbsd-announce"           maildir "${path}/openbsd-announce"
237    action "openbsd-ipv6"               maildir "${path}/openbsd-ipv6"
238    action "openbsd-misc"               maildir "${path}/openbsd-misc"
239    action "openbsd-ports"              maildir "${path}/openbsd-ports"
240    action "openbsd-ports-bugs"         maildir "${path}/openbsd-ports-bugs"
241    action "openbsd-ports-security"     maildir "${path}/openbsd-ports-security"
242    action "openbsd-security-announce"  maildir "${path}/openbsd-security-announce"
243    action "openbsd-tech"               maildir "${path}/openbsd-tech"
244    action "openbsd-www"                maildir "${path}/openbsd-www"
245    action "openbsd-x11"                maildir "${path}/openbsd-x11"
246    action "mutt-dev"                   maildir "${path}/mutt-dev"
247    action "mutt-users"                 maildir "${path}/mutt-users"
248    action "fvwm"                       maildir "${path}/fvwm"
249    action "fvwm-workers"               maildir "${path}/fvwm-workers"
250    action "grml"                       maildir "${path}/grml"
251    action "grml-devel"                 maildir "${path}/grml-devel"
252    action "zsh-users"                  maildir "${path}/zsh-users"
253    action "zsh-workers"                maildir "${path}/zsh-workers"
254    action "cmus-devel"                 maildir "${path}/cmus-devel"
255    action "leafnode"                   maildir "${path}/leafnode"
256    action "remind-fans"                maildir "${path}/remind-fans"
257    action "screen-users"               maildir "${path}/screen-users"
258    action "slrn-users"                 maildir "${path}/slrn-users"
259    action "tuhs"                       maildir "${path}/tuhs"
260    action "vim-users"                  maildir "${path}/vim-users"
261    action "linux-kernel"               maildir "${path}/linux-kernel"
262    action "kernelnewbies"              maildir "${path}/linux-kernel-newbies"
263    action "linux-elitists"             maildir "${path}/linux-elitists"
264    action "bugtraq"                    maildir "${path}/bugtraq"
265    action "full-disclosure"            maildir "${path}/full-disclosure"
266    action "pen-test"                   maildir "${path}/pen-test"
267    action "schopppe"                   maildir "${path}/schopppe"
268#}}}
269
270### rewrite actions (some mailinglist add tags to their subjects...)
271### '1,/^$/...' only rewrites lines in the mail _headers_.
272#{{{
273    action "strip-full-disclosure"  rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[Full-disclosure\\] /\\1/'"
274    action "strip-remind-fans"      rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[Remind-Fans\\] /\\1/'"
275    action "strip-fvwm"             rewrite "${com_sed} '1,/^$/s/^\\(Subject:\\) FVWM:/\\1/'"
276    action "strip-grml"             rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[Grml\\] /\\1/'"
277    action "strip-leafnode"         rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[leafnode-list\\] /\\1/'"
278    action "strip-linux-elitists"   rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[linux-elitists\\] /\\1/'"
279    action "strip-tuhs"             rewrite "${com_sed} '1,/^$/s/^\\(Subject:.*\\)\\[TUHS\\] /\\1/'"
280#}}}
281
282###########################################################################
283
284### accounts for spam-training
285###   -asp-train-spam
286###     trains the message from stdin as spam;
287###     moves the mail to the appropriate folder
288###   -asp-train-good
289###     trains the message from stdin as ham;
290###     continues with normal rules to sort the message
291###     to the folder it belongs to.
292    account "sp-train-spam" disabled stdin
293    account "sp-train-good" disabled stdin
294
295### sometimes you want to test new things by providing mails on stdin
296    account "stdin" disabled stdin
297
298###########################################################################
299
300### Automatic archiving.
301### This is a nice idea, I shamelessly stole from NicM's config.
302###   Mail is kept in Maildirs for 30 days. After that it is
303###   automatically moved to compressed mboxes, which in turn
304###   may by periodically removed (by cron for examples, or
305###   by hand). This (again) uses an account that is disabled,
306###   so it can be explicitly called by '-aarchive'.
307    account "archive" disabled maildirs {
308#{{{
309      "${path}/Inbox"
310      "${path}/bugtraq"
311      "${path}/cmus-devel"
312      "${path}/debian-*"
313      "${path}/full-disclosure"
314      "${path}/fvwm*"
315      "${path}/grml*"
316      "${path}/leafnode"
317      "${path}/linux-*"
318      "${path}/mutt-*"
319      "${path}/openbsd-*"
320      "${path}/pen-test"
321      "${path}/remind-fans"
322      "${path}/schopppe"
323      "${path}/screen-users"
324      "${path}/slrn-users"
325      "${path}/tuhs"
326      "${path}/vim-users"
327      "${path}/zsh-*"
328#}}}
329    }
330    match account "archive" and age > %{max_age} days action "archive"
331    match account "archive" action "keep"
332
333###########################################################################
334
335### handle mail
336
337### do catchall as early as possible.
338    match string "${do_catchall}" to "^yes$" action "catchall" continue
339
340      ########## zblog messages ##########
341### mails to blog -at- bewatermyfriend -dot- org are meant for zblog.
342    match account "blog"      action "zblog"
343    match account "comments"  action "zcomm"
344
345      ########## killfiling ##########
346### killfiling on From, From:, Reply-To: and Sender headers
347### If your killfile is rather large, this will slow down fdm
348### considerably. So do this only on people that really disturb you.
349    match pipe "${com_pfh} | grep -Eqif ${killfile}" returns ( 0, )
350      actions { "killfile" "maildir-mark-as-read" }
351
352      ########## spam handling ##########
353### force message from stdin to spamfolder and train it as spam
354    match account "sp-train-spam" {
355      match all action "train-spam" continue
356      match "^${header_spam}" in headers action "sp-remove-header" continue
357      match all action "sp-add-trained-spam" continue
358      match all action "spam"
359    }
360
361### train message from stdin as ham
362    match account "sp-train-good"
363        action "train-good"           continue
364    match account "sp-train-good" and
365	"^${header_spam}" in headers
366      	action "sp-remove-header"     continue
367    match account "sp-train-good"
368        action "sp-add-trained-good"  continue
369
370### scan for spam
371    match not "^${header_spam}" in headers {
372      match pipe "${com_spam_filter}" returns ( , "(.*)" ) {
373        match "^${header_spam}" in headers action "sp-remove-header" continue
374        match all action "sp-add-header" continue
375      }
376    }
377
378### move messages marked as spam to spamfolder
379    match "^${header_spam}:[ \t]*${filtered_spam}" in headers action "spam"
380
381      ########## modifying headers ##########
382### add Lines: header if it is missing.
383    match not "^Lines:" in headers action "add-lines-header" continue
384
385### remove headers I don't care about
386    match "^${ill_headers}:" in headers action "remove-ill-headers" continue
387
388      ########## sorting ##########
389### debian- mailinglists and pts
390    match "^List-Id:[ \t]*<debian-([a-z-]*)\\.lists\\.debian\\.org" in headers action "debian-%1"
391    match "^X-PTS-Package:.*[a-z].*" in headers action "debian-pts"
392
393### openbsd- mailinglists
394    match "^Sender:[ \t]*owner-([a-z-]*)@openbsd\\.org" in headers action "openbsd-%1"
395
396### grml mailinglists
397    match "^List-Post:[ \t]*<mailto:grml(.*)@mur\\.at" in headers {
398      match string "%1" to "^$" action "strip-grml" continue
399      match all action "grml%1"
400    }
401
402### zsh- mailinglists
403    match "^Mailing-List:.*zsh-([a-z]*)-help@" in headers {
404      match string "%1" to "announce" action "inbox"
405      match all action "zsh-%1"
406    }
407
408### mutt- mailinglists
409    match "^List-Unsubscribe:.*mutt-([a-z]*)-request@mutt\\.org" in headers {
410      match string "%1" to "announce" action "inbox"
411      match all action "mutt-%1"
412    }
413
414### fvwm mailinglists
415    match "^List-Id:.*fvwm(.*)\\.(fvwm\\.org|lists\\.math\\.uh\\.edu)" in headers {
416      match string "%1" to "announce" action "inbox"
417      match string "%1" to "^$" action "strip-fvwm" continue
418      match all action "fvwm%1"
419    }
420
421### other mailinglists
422    match "^List-Post:.*bugtraq@securityfocus\\.com" in headers action "bugtraq"
423    match "^List-Id:.*cmus-devel\\.lists\\.sourceforge\\.net" in headers action "cmus-devel"
424    match "^List-Id:.*full-disclosure\\.lists\\.grok\\.org\\.uk" in headers actions { "strip-full-disclosure" "full-disclosure" }
425    match "^List-Id:.*leafnode-list\\.dt\\.e-technik\\.uni-dortmund\\.de" in headers actions { "strip-leafnode" "leafnode" }
426    match "^X-BeenThere:.*linux-elitists@zgp\\.org" in headers actions { "strip-linux-elitists" "linux-elitists" }
427    match "^X-Mailing-List:.*linux-kernel@vger\\.kernel\\.org" in headers action "linux-kernel"
428    match "^List-Id:.*kernelnewbies\\.nl\\.linux\\.org" in headers action "kernelnewbies"
429    match "^List-Post:.*pen-test@securityfocus\\.com" in headers action "pen-test"
430    match "^List-Id:.*remind-fans\\.lists\\.whatexit\\.org" in headers actions { "strip-remind-fans" "remind-fans" }
431    match "^List-Id:.*schopppe\\.de" in headers action "schopppe"
432    match "^List-Id:.*screen-users\\.gnu\\.org" in headers action "screen-users"
433    match "^List-Id:.*slrn-user\\.lists\\.sourceforge\\.net" in headers action "slrn-users"
434    match "^List-Id:.*Unix Heritage.*tuhs\\.minnie\\.tuhs\\.org" in headers actions { "strip-tuhs" "tuhs" }
435    match "^Mailing-List:.*vim-help@vim\.org" in headers action "vim-users"
436
437### match the rest
438    match all action "inbox"
439