1PROCMAILEX(5) File Formats Manual PROCMAILEX(5)
2
3
4
6 procmailex - procmail rcfile examples
7
9 $HOME/.procmailrc examples
10
12 For a description of the rcfile format see procmailrc(5).
13
14 The weighted scoring technique is described in detail in the proc‐
15 mailsc(5) man page.
16
17 This man page shows several example recipes. For examples of complete
18 rcfiles you can check the NOTES section in procmail(1), or look at the
19 example rcfiles in /usr/share/doc/procmail/examples.
20
22 Sort out all mail coming from the scuba-dive mailing list into the
23 mailfolder scubafile (uses the locallockfile scubafile.lock).
24
25 :0:
26 * ^TOscuba
27 scubafile
28
29 Forward all mail from peter about compilers to william (and keep a copy
30 of it here in petcompil).
31
32 :0
33 * ^From.*peter
34 * ^Subject:.*compilers
35 {
36 :0 c
37 ! william@somewhere.edu
38
39 :0
40 petcompil
41 }
42
43 An equivalent solution that accomplishes the same:
44
45 :0 c
46 * ^From.*peter
47 * ^Subject:.*compilers
48 ! william@somewhere.edu
49
50 :0 A
51 petcompil
52
53 An equivalent, but slightly slower solution that accomplishes the same:
54
55 :0 c
56 * ^From.*peter
57 * ^Subject:.*compilers
58 ! william@somewhere.edu
59
60 :0
61 * ^From.*peter
62 * ^Subject:.*compilers
63 petcompil
64
65 If you are fairly new to procmail and plan to experiment a little bit
66 it often helps to have a safety net of some sort. Inserting the fol‐
67 lowing two recipes above all other recipes will make sure that of all
68 arriving mail always the last 32 messages will be preserved. In order
69 for it to work as intended, you have to create a directory named
70 `backup' in $MAILDIR prior to inserting these two recipes.
71
72 :0 c
73 backup
74
75 :0 ic
76 | cd backup && rm -f dummy `ls -t msg.* | sed -e 1,32d`
77
78 If your system doesn't generate or generates incorrect leading `From '
79 lines on every mail, you can fix this by calling up procmail with the
80 -f- option. To fix the same problem by different means, you could have
81 inserted the following recipe above all other recipes in your rcfile.
82 They will filter the header of any mail through formail which will
83 strip any leading `From ', and automatically regenerates it subse‐
84 quently.
85
86 :0 fhw
87 | formail -I "From " -a "From "
88
89 Add the headers of all messages that didn't come from the postmaster to
90 your private header collection (for statistics or mail debugging); and
91 use the lockfile `headc.lock'. In order to make sure the lockfile is
92 not removed until the pipe has finished, you have to specify option
93 `w'; otherwise the lockfile would be removed as soon as the pipe has
94 accepted the mail.
95
96 :0 hwc:
97 * !^FROM_MAILER
98 | uncompress headc.Z; cat >>headc; compress headc
99
100 Or, if you would use the more efficient gzip instead of compress:
101
102 :0 hwc:
103 * !^FROM_MAILER
104 | gzip >>headc.gz
105
106 Forward all mails shorter than 1000 bytes to my home address (no lock‐
107 file needed on this recipe).
108
109 :0
110 * < 1000
111 ! myname@home
112
113 Split up incoming digests from the surfing mailing list into their in‐
114 dividual messages, and store them into surfing, using surfing.lock as
115 the locallockfile.
116
117 :0:
118 * ^Subject:.*surfing.*Digest
119 | formail +1 -ds >>surfing
120
121 Store everything coming from the postmaster or mailer-daemon (like
122 bounced mail) into the file postm, using postm.lock as the locallock‐
123 file.
124
125 :0:
126 * ^FROM_MAILER
127 postm
128
129 A simple autoreply recipe. It makes sure that neither mail from any
130 daemon (like bouncing mail or mail from mailing-lists), nor autoreplies
131 coming from yourself will be autoreplied to. If this precaution would
132 not be taken, disaster could result (`ringing' mail). In order for
133 this recipe to autoreply to all the incoming mail, you should of course
134 insert it before all other recipes in your rcfile. However, it is ad‐
135 visable to put it after any recipes that process the mails from sub‐
136 scribed mailinglists; it generally is not a good idea to generate au‐
137 toreplies to mailinglists (yes, the !^FROM_DAEMON regexp should already
138 catch those, but if the mailinglist doesn't follow accepted conven‐
139 tions, this might not be enough).
140
141 :0 h c
142 * !^FROM_DAEMON
143 * !^X-Loop: your@own.mail.address
144 | (formail -r -I"Precedence: junk" \
145 -A"X-Loop: your@own.mail.address" ; \
146 echo "Mail received.") | $SENDMAIL -t
147
148 A more complicated autoreply recipe that implements the functional
149 equivalent of the well known vacation(1) program. This recipe is based
150 on the same principles as the last one (prevent `ringing' mail). In
151 addition to that however, it maintains a vacation database by extract‐
152 ing the name of the sender and inserting it in the vacation.cache file
153 if the name was new (the vacation.cache file is maintained by formail
154 which will make sure that it always contains the most recent names, the
155 size of the file is limited to a maximum of approximately 8192 bytes).
156 If the name was new, an autoreply will be sent.
157
158 As you can see, the following recipe has comments between the condi‐
159 tions. This is allowed. Do not put comments on the same line as a
160 condition though.
161
162 SHELL=/bin/sh # only needed for older versions of procmail
163
164 :0 Whc: vacation.lock
165 # Perform a quick check to see if the mail was addressed to us
166 * $^To:.*\<$\LOGNAME\>
167 # Don't reply to daemons and mailinglists
168 * !^FROM_DAEMON
169 # Mail loops are evil
170 * !^X-Loop: your@own.mail.address
171 | formail -rD 8192 vacation.cache
172
173 :0 ehc # if the name was not in the cache
174 | (formail -rI"Precedence: junk" \
175 -A"X-Loop: your@own.mail.address" ; \
176 echo "I received your mail,"; \
177 echo "but I won't be back until Monday."; \
178 echo "-- "; cat $HOME/.signature \
179 ) | $SENDMAIL -oi -t
180
181 Store all messages concerning TeX in separate, unique filenames, in a
182 directory named texmail (this directory has to exist); there is no need
183 to use lockfiles in this case, so we won't.
184
185 :0
186 * (^TO|^Subject:.*)TeX[^t]
187 texmail
188
189 The same as above, except now we store the mails in numbered files (MH
190 mail folder).
191
192 :0
193 * (^TO|^Subject:.*)TeX[^t]
194 texmail/.
195
196 Or you could file the mail in several directory folders at the same
197 time. The following recipe will deliver the mail to two MH-folders and
198 one directory folder. It is actually only one file with two extra
199 hardlinks.
200
201 :0
202 * (^TO|^Subject:.*)TeX[^t]
203 texmail/. wordprocessing dtp/.
204
205 Store all the messages about meetings in a folder that is in a direc‐
206 tory that changes every month. E.g. if it were January 1994, the
207 folder would have the name `94-01/meeting' and the locallockfile would
208 be `94-01/meeting.lock'.
209
210 :0:
211 * meeting
212 `date +%y-%m`/meeting
213
214 The same as above, but, if the `94-01' directory wouldn't have existed,
215 it is created automatically:
216
217 MONTHFOLDER=`date +%y-%m`
218
219 :0 Wic
220 * ? test ! -d $MONTHFOLDER
221 | mkdir $MONTHFOLDER
222
223 :0:
224 * meeting
225 ${MONTHFOLDER}/meeting
226
227 The same as above, but now by slightly different means:
228
229 MONTHFOLDER=`date +%y-%m`
230 DUMMY=`test -d $MONTHFOLDER || mkdir $MONTHFOLDER`
231
232 :0:
233 * meeting
234 ${MONTHFOLDER}/meeting
235
236 If you are subscribed to several mailinglists and people cross-post to
237 some of them, you usually receive several duplicate mails (one from ev‐
238 ery list). The following simple recipe eliminates duplicate mails. It
239 tells formail to keep an 8KB cache file in which it will store the Mes‐
240 sage-IDs of the most recent mails you received. Since Message-IDs are
241 guaranteed to be unique for every new mail, they are ideally suited to
242 weed out duplicate mails. Simply put the following recipe at the top
243 of your rcfile, and no duplicate mail will get past it.
244
245 :0 Wh: msgid.lock
246 | formail -D 8192 msgid.cache
247
248 Beware if you have delivery problems in recipes below this one and
249 procmail tries to requeue the mail, then on the next queue run, this
250 mail will be considered a duplicate and will be thrown away. For those
251 not quite so confident in their own scripting capabilities, you can use
252 the following recipe instead. It puts duplicates in a separate folder
253 instead of throwing them away. It is up to you to periodically empty
254 the folder of course.
255
256 :0 Whc: msgid.lock
257 | formail -D 8192 msgid.cache
258
259 :0 a:
260 duplicates
261
262 Procmail can deliver to MH folders directly, but, it does not update
263 the unseen sequences the real MH manages. If you want procmail to up‐
264 date those as well, use a recipe like the following which will file ev‐
265 erything that contains the word spam in the body of the mail into an MH
266 folder called spamfold. Note the local lockfile, which is needed be‐
267 cause MH programs do not lock the sequences file. Asynchronous invoca‐
268 tions of MH programs that change the sequences file may therefore cor‐
269 rupt it or silently lose changes. Unfortunately, the lockfile doesn't
270 completely solve the problem as rcvstore could be invoked while `show'
271 or `mark' or some other MH program is running. This problem is ex‐
272 pected to be fixed in some future version of MH, but until then, you'll
273 have to balance the risk of lost or corrupt sequences against the bene‐
274 fits of the unseen sequence.
275
276 :0 :spamfold/$LOCKEXT
277 * B ?? spam
278 | rcvstore +spamfold
279
280 When delivering to emacs folders (i.e., mailfolders managed by any
281 emacs mail package, e.g., RMAIL or VM) directly, you should use emacs-
282 compatible lockfiles. The emacs mailers are a bit braindamaged in that
283 respect, they get very upset if someone delivers to mailfolders which
284 they already have in their internal buffers. The following recipe as‐
285 sumes that $HOME equals /home/john.
286
287 MAILDIR=Mail
288
289 :0:/usr/local/lib/emacs/lock/!home!john!Mail!mailbox
290 * ^Subject:.*whatever
291 mailbox
292
293 Alternatively, you can have procmail deliver into its own set of mail‐
294 boxes, which you then periodically empty and copy over to your emacs
295 files using movemail. Movemail uses mailbox.lock local lockfiles per
296 mailbox. This actually is the preferred mode of operation in conjunc‐
297 tion with procmail.
298
299 To extract certain headers from a mail and put them into environment
300 variables you can use any of the following constructs:
301
302 SUBJECT=`formail -xSubject:` # regular field
303 FROM=`formail -rt -xTo:` # special case
304
305 :0 h # alternate method
306 KEYWORDS=| formail -xKeywords:
307
308 If you are using temporary files in a procmailrc file, and want to make
309 sure that they are removed just before procmail exits, you could use
310 something along the lines of:
311
312 TEMPORARY=$HOME/tmp/pmail.$$
313 TRAP="/bin/rm -f $TEMPORARY"
314
315 The TRAP keyword can also be used to change the exitcode of procmail.
316 I.e. if you want procmail to return an exitcode of `1' instead of its
317 regular exitcodes, you could use:
318
319 EXITCODE=""
320 TRAP="exit 1;" # The trailing semi-colon is important
321 # since exit is not a standalone program
322
323 Or, if the exitcode does not need to depend on the programs run from
324 the TRAP, you can use a mere:
325
326 EXITCODE=1
327
328 The following recipe prints every incoming mail that looks like a post‐
329 script file.
330
331 :0 Bb
332 * ^^%!
333 | lpr
334
335 The following recipe does the same, but is a bit more selective. It
336 only prints the postscript file if it comes from the print-server. The
337 first condition matches only if it is found in the header. The second
338 condition only matches at the start of the body.
339
340 :0 b
341 * ^From[ :].*print-server
342 * B ?? ^^%!
343 | lpr
344
345 The same as above, but now by slightly different means:
346
347 :0
348 * ^From[ :].*print-server
349 {
350 :0 B b
351 * ^^%!
352 | lpr
353 }
354
355 Likewise:
356
357 :0 HB b
358 * ^^(.+$)*From[ :].*print-server
359 * ^^(.+$)*^%!
360 | lpr
361
362 Suppose you have two accounts, you use both accounts regularly, but
363 they are in very distinct places (i.e., you can only read mail that ar‐
364 rived at either one of the accounts). You would like to forward mail
365 arriving at account one to account two, and the other way around. The
366 first thing that comes to mind is using .forward files at both sites;
367 this won't work of course, since you will be creating a mail loop.
368 This mail loop can be avoided by inserting the following recipe in
369 front of all other recipes in the $HOME/.procmailrc files on both
370 sites. If you make sure that you add the same X-Loop: field at both
371 sites, mail can now safely be forwarded to the other account from ei‐
372 ther of them.
373
374 :0 c
375 * !^X-Loop: yourname@your.main.mail.address
376 | formail -A "X-Loop: yourname@your.main.mail.address" | \
377 $SENDMAIL -oi yourname@the.other.account
378
379 If someone sends you a mail with the word `retrieve' in the subject,
380 the following will automatically send back the contents of info_file to
381 the sender. Like in all recipes where we send mail, we watch out for
382 mail loops.
383
384 :0
385 * !^From +YOUR_USERNAME
386 * !^Subject:.*Re:
387 * !^FROM_DAEMON
388 * ^Subject:.*retrieve
389 | (formail -r ; cat info_file) | $SENDMAIL -oi -t
390
391 Now follows an example for a very simple fileserver accessible by mail.
392 For more demanding applications, I suggest you take a look at SmartList
393 (available from the same place as the procmail distribution). As
394 listed, this fileserver sends back at most one file per request, it ig‐
395 nores the body of incoming mails, the Subject: line has to look like
396 "Subject: send file the_file_you_want" (the blanks are significant), it
397 does not return files that have names starting with a dot, nor does it
398 allow files to be retrieved that are outside the fileserver directory
399 tree (if you decide to munge this example, make sure you do not inad‐
400 vertently loosen this last restriction).
401
402 :0
403 * ^Subject: send file [0-9a-z]
404 * !^X-Loop: yourname@your.main.mail.address
405 * !^Subject:.*Re:
406 * !^FROM_DAEMON
407 * !^Subject: send file .*[/.]\.
408 {
409 MAILDIR=$HOME/fileserver # chdir to the fileserver directory
410
411 :0 fhw # reverse mailheader and extract name
412 * ^Subject: send file \/[^ ]*
413 | formail -rA "X-Loop: yourname@your.main.mail.address"
414
415 FILE="$MATCH" # the requested filename
416
417 :0 ah
418 | cat - ./$FILE 2>&1 | $SENDMAIL -oi -t
419 }
420
421 The following example preconverts all plain-text mail arriving in cer‐
422 tain encoded MIME formats into a more compact 8-bit format which can be
423 used and displayed more easily by most programs. The mimencode(1) pro‐
424 gram is part of Nathaniel Borenstein's metamail package.
425
426 :0
427 * ^Content-Type: *text/plain
428 {
429 :0 fbw
430 * ^Content-Transfer-Encoding: *quoted-printable
431 | mimencode -u -q
432
433 :0 Afhw
434 | formail -I "Content-Transfer-Encoding: 8bit"
435
436 :0 fbw
437 * ^Content-Transfer-Encoding: *base64
438 | mimencode -u -b
439
440 :0 Afhw
441 | formail -I "Content-Transfer-Encoding: 8bit"
442 }
443
444 The following one is rather exotic, but it only serves to demonstrate a
445 feature. Suppose you have a file in your HOME directory called ".ur‐
446 gent", and the (one) person named in that file is the sender of an in‐
447 coming mail, you'd like that mail to be stored in $MAILDIR/urgent in‐
448 stead of in any of the normal mailfolders it would have been sorted in.
449 Then this is what you could do (beware, the filelength of $HOME/.urgent
450 should be well below $LINEBUF, increase LINEBUF if necessary):
451
452 URGMATCH=`cat $HOME/.urgent`
453
454 :0:
455 * $^From.*${URGMATCH}
456 urgent
457
458 An entirely different application for procmail would be to condition‐
459 ally apply filters to a certain (outgoing) text or mail. A typical ex‐
460 ample would be a filter through which you pipe all outgoing mail, in
461 order to make sure that it will be MIME encoded only if it needs to be.
462 I.e. in this case you could start procmail in the middle of a pipe
463 like:
464
465 cat newtext | procmail ./mimeconvert | mail chris@where.ever
466
467 The mimeconvert rcfile could contain something like (the =0x80= and
468 =0xff= should be substituted with the real 8-bit characters):
469
470 DEFAULT=| # pipe to stdout instead of
471 # delivering mail as usual
472 :0 Bfbw
473 * [=0x80=-=0xff=]
474 | mimencode -q
475
476 :0 Afhw
477 | formail -I 'MIME-Version: 1.0' \
478 -I 'Content-Type: text/plain; charset=ISO-8859-1' \
479 -I 'Content-Transfer-Encoding: quoted-printable'
480
482 procmail(1), procmailrc(5), procmailsc(5), sh(1), csh(1), mail(1),
483 mailx(1), uucp(1), aliases(5), sendmail(8), egrep(1), grep(1), biff(1),
484 comsat(8), mimencode(1), lockfile(1), formail(1)
485
487 Stephen R. van den Berg
488 <srb@cuci.nl>
489
490
491
492 BuGless PROCMAILEX(5)