------------------------------------------------------------------------------- Procmail Bugs.... 0 HB * \>word\> { ... } Will NOT work. \> may be equivelent to [^a-zA-Z0-9_] but will not work on a RE where it is given first. Presumably the \> is being thought of as some special flags. The correct solution is... 0 HB * ()\>word\> { ... } ------------------------------------------------------------------------------- Procmail to MH folder delivery... The MH library program "rcvstore" is used to append mail to MH folders so that the unseen lists are properly updated. Procmail does NOT update the unseen caches, silently added mail to the folders. EG :0 :_Lists/$LOCKEXT # Rejected as from daemon or spam *$ ^Subject:$s*Reject: | rcvstore +_Lists/--REJECT-- ------------------------------------------------------------------------------- Procmail Vacation Call Replace the address with your normal mail address # VACATION = yes # Uncomment to turn on vacation # Vacation Message # Ignore: bulk email lists, bounce mail, and mail from myself :0 c * VACATION ?? yes * ! ^FROM_DAEMON * ! ^From.+ anthony@[^ ]*cit\.gu\.edu\.au | /usr/bin/vacation -j anthony Other things to check for for vacation mail * !^FROM_DAEMON * !^Precedence: +bulk * !^From +[^ ]*(postmaster|Mailer) * $^To:.*$LOGNAME * !^[^:]*List[^:]*: * !^Approved-By: * !^BestServHost: * !^Resent-Message-ID: * !^Resent-Sender: * !^Sender: .*-errors@ * !^Sender: owner- * !^X-Authentication-Warning: * !^X-Loop: * !^X-Mailman-Version: * !^X-Sent-To: ------------------------------------------------------------------------------- Get the senders address The canonical way to get the sender's trimmed-down address is For the reply-to address.. :0 h REPLYTO=| formail -rt -zxTo: For the envelop from address :0 h ORGADDR=| formail -r -zxTo: ------------------------------------------------------------------------------- Page me with the Message Subject Given a separate program called "pager" when sends a small text message to the callers ("ME" flag) pager. Note pager could be replaced by other programs such as a X window "popup" to notify the user of this special mail. :ch ^From: afactor@ozemail.com.au | pager -q ME ']'`formail -x Subject | sed 's/^ *//;s/Re: *//'` # Alturnative (using sed to extract subject) #| pager -q ME ']'`sed -n '/Subject: */{s///;s/Re: *//g;p;q}'` ------------------------------------------------------------------------------- Play a sound when mail is delivered... Add the following definitions on your linux box.. SOUND_PLAY = rplay SOUND_DIR = $HOME/store/sounds/beeps NORMAL_SND = $SOUND_DIR/drip.au JUNK_SND = $SOUND_DIR/snotplop.wav Then as the last item (or for mail delivery into a mail folder) play the sound with... # SPAM = yes if a mail was found to be spam.. :0 * SPAM ?? . { :0 :_Junk/$LOCKEXT *$ ? $SOUND_PLAY $JUNK_SND | rcvstore +spam } :0 *$ ? $SOUND_PLAY $NORMAL_SND { } ------------------------------------------------------------------------------- Add a banner to the end of the mail (if "Unverified") :hf * ^X-Sender:.*\(Unverified\) | cat - ;\ echo " ######################################################";\ echo " ### WARNING! THIS MAIL SENT BY AN UNVERIFIED USER! ###";\ echo " ### READER BEWARE!!! ###";\ echo " ######################################################";\ echo "" ------------------------------------------------------------------------------- Automated response :0 h c * ^TOinfo@2gen.net * ! ^FROM_DAEMON * ! ^X-Loop: info@2gen.net | ( formail -rt -I "Precedence: Junk" \ -I "X-Loop: info@2gen.net" \ -I "From: 2Gen.Inc. " \ -I "Reply-To: Ed Kopas " \ ; cat /usr/home/mike/autores/info.txt ) \ | $SENDMAIL $SENDMAILFLAGS -t ------------------------------------------------------------------------------- Reply to a email -- in toto, including headers We need to get the header in there twice: once inverted as a reply header (via formail) and once as part of the . Here's my suggestion: : # 'c' is implicit in assignment recipes * ^Subject: testing RETURNHEAD=| formail -r -A"Precedence: junk" # no -k, loses body :A # 'hb' is the default | (echo "$RETURNHEAD"; sed 's/^/>/'; echo Mail received) | $SENDMAIL -t David W. Tamkin ------------------------------------------------------------------------------- Number of lines in Body :0 Bfh * H ?? ! ^Lines: * -1^0 * 1^1 ^.*$ |formail -A "Lines: $=" This uses the `score' method to count the number of lines in the body and add an appropraite header. For that matter :0 * B ?? 1^1 > 1 { } SIZE = $= Gets you the size of the body but then so would a "Content-Length" header item. This is probably more accrate though. ------------------------------------------------------------------------------- Mailbox over quota? :0 * !? mailquota $LOGNAME { # Exit here and bounce the message if the mailbox was full. LOGFILE = /dev/fd/2 LOG = "mailbox quota exceeded by $LOGNAME" EXITCODE = 69 HOST } ------------------------------------------------------------------------------- Multiple mailing list handling If you subscribe to a lot of mailing lists and each one has its own recipe like this: :0: * ^TO_vim@vim.org in-l-vim You can speed up processing by combining all your mailing list recipes into a single recipe like this: :0: * ^TO_\/(list1|list2) * MATCH ?? ()\/[^@]+ in-l-$MATCH The \/ has special meaning in procmail:- if there is a match after the extraction operator \/, put it into a variable named MATCH. Also \/ with nothing to the left of it means "one foreslash". To start a condition with the extraction operator, use ()\/ or \\/; the latter looks counter intuitively like "literal backslash and literal foreslash" (as it would mean if it appeared farther along in the regexp), so most of us prefer the former. The second condition removes the trailing domain name from MATCH and re-assigns the result back to match. However the variable may contain different cases for the same mailing list, depending on what case is used in the address people mail to and if the mail list re-wrote the address or not. To fix this we need to select a folder name based on the listname!! :0: * ^TO_\/(list1|list2|list3|list4|list5) * MATCH ?? ()\/[^@]+ { LISTNAME=`echo "$MATCH" | tr [A-Z] [a-z]` # select a folder for these lists, else use the listname itself list_folders="list1%folder1!list2%folder2!list3%folder3" :0: * $ list_folders ?? ()$LISTNAME%\/[^!]+ $MATCH :0E: $LISTNAME } NOTE: if you specify a folder for all lists which could have case problems then you can avoid the need for the "tr" command. This technique can also reference more things... regexp-to-match-extracted-text%folder_name@some-other-item ------------------------------------------------------------------------------- Using a External program to test mail. For the AcctDB mailing lists I needed to test if the mail at any point in time handled by an external mail server. IE: any "Received:" line contains a non-local domain or non-local IP address in it. This is NOT and easy test and requird a perl program to parse and test the "Received:" lines in the mail. The test program returned a shell status of true or false on if it was external or not. NOTE false is also returned IF filter fails completely. The main problem was the procmail receipe! After lots of trials, this was the result.... The `W' flag was the most important part. =======8<-------- # LIST = supplied at part of procmail call # EG: maillist in the sendmail /etc/aliases file... # maillist !"/usr/bin/procmail -m LIST=maillist /etc/mail/pmrc.init bounce = # Restrict toplevel mailing lists to within GU # NOTE: mail header is send to a external program to test it. :0 DWhic * ! LIST ?? ^^[a-z][a-z][a-z]$d$d$d$d(l|)^^ | /etc/mail/mailtest_non_gu :0 a { bounce = yes reason = "Only GU mail allowed" } #... if bounce set, bounce the mail ... #... otherwise pass mail to some sort of bulk mailer to "LIST" addresses ... =======8<-------- ------------------------------------------------------------------------------- Handling Spam... One of my spam checks is for certain attachments.... The following extensions are denied for mail sent to me or to the Academic support mailing lists (procmail bounce filtered). These represent posible virus "executable" attachments, the ones I have found in any case... exe vbs bat com scr pif lnk The following is from my own .procmailrc filter... NOTE: It plays a sound on my machine which is called "snot-plop" adds a header to inform me the reason it was junked, then saves it directing in my JUNK MH mail folder. when it detects "junk" ;-) =======8<--------CUT HERE---------- # procmailrc control file... # ... # -- Executable in Mail (10) -- :0 B * ^Content-.*\>+\/name=.*\.(exe|vbs|bat|com|scr|pif|lnk)"?$ { JUNK = "$MATCH (10)" } # ... # ------- Junk any spam mail found ----------- # Junk the mail in the Junk mail folder WARNING: you can NOT update a mail # folder that is uploaded/downloaded directly to/from my laptop! The `_' # prefix removes the folder form this cycle. # # Include a header of the matched string causing this classification # # NOTE: the `echo $JUNK` convertes any newlines to spaces. # An alturnative is to use a `joiner.pmrc' recursive procmailrc # from "Jan's Procmail Resources" archive. # # The rcvstore command is used to save in MH folder to ensure that # the unseen list of MH is properly updated # :0: * JUNK ?? . *$ ? $SOUND_PLAY $JUNK_SND | formail -i "X-spam-match: `echo $JUNK`" | rcvstore +_Junk =======8<--------CUT HERE---------- Regardless mail sent to me is saves in a "junk" folder for later scan and delete, while those for the mail list is archived and bounced with the message. -------------------------------------------------------------------------------