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