[vox-tech] procmail question
Chanoch (Ken) Bloom
kbloom at gmail.com
Sat Oct 23 18:01:35 PDT 2010
On Sat, 2010-10-23 at 14:07 -0700, Tony Cratz wrote:
> On 10/21/2010 11:21 AM, Ken Bloom wrote:
> > That's why I suggested GNU mailutils. It has a "sieve" command that
> > looks like it's a standalone filter (procmail replacement).
>
>
> I would like to come back to this and ask a question just
> in case I did not see what I should have.
>
> Do you know if Sieve can rewrite headers. For example can I
> change the To: header, or the Subject: header.
A quick googling suggests it doesn't know how to do it in-process, but
you could use the GNU mailutils pipe extension to do such things (in
conjunction with a program like formail or reformail, or of course a
spam filter like spamassassin). You can look in /usr/lib/mailutils/ to
see what extensions are available, and you can write your own as a
shared library.
> And if the
> answer is yeas, then can I take the new message and send it
> to my SMTP server (such as Sendmail) to redeliver the message
> to the new list?
> Maildrop was also mention, I only took a quick and dirty look
> at it. Can it also solve the above questions?
I don't actually use Sieve for my email. I suggested it because it was a
standard.
I've used maildrop in the past (rewriting headers, and running spam
filters with its xfilter command), and my mail filters looked like (for
example)
if (/Mailing-List: list some.mailinglist.org; contact/:h || \
/From:.*foo at bar.com/ || \
/From:.*bar at foo.com/ || \
/From:.*baz at bar.com/ || \
/From:.*@some.domain.org/ || \
/Mailing-List: list some-other-mailinglist at yahoogroups.com; / || \
/From:.*afinal at email.org/ )
{
to $MAILBOX/.util.probably-spam
}
# spam filtering
if ($SIZE < 1048576)
{
xfilter 'spamassassin'
}
if (/^X-Spam-Status: Yes/)
{
xfilter 'reformail -I"Status: RO"'
to '| $HOME/bin/maildir-deliverread $MAILBOX/.util.probably-spam'
}
I didn't like this (I didn't find it concise enough), and the
backslashes as line continuations and mandatory braces annoyed me. (I
was always forgetting them when I made changes, and it would break my
email for days on end.)
So I changed to a solution in Ruby. I tried Perl first, but Perl
performs variable interpolation with the @ sigil, so you can't put email
addresses in a regular expression in Perl without escaping them. You'll
notice that I don't bother to escape the period metacharacter in my
regular expressions. Though technically, it can match any character,
that possibility for false positives doesn't seem to matter much.
First, here's the skeleton that you need to write your own version.
(You'll probably want to redefine the saveread function so that it
doesn't depend on an external script.)
#!/usr/bin/env ruby
require 'rfilter/delivery_agent'
class RFilter::DeliveryAgent
def myfilter
#RULES GO IN HERE
end
#SUPPORT CODE FOLLOWS
def self.header_accessor name,field
class_eval <<-"end;"
def #{name}
header["#{field}"] || ""
end
end;
end
header_accessor :from, "From"
header_accessor :to, "To"
header_accessor :listid, "List-Id"
header_accessor :spam, "X-Spam-Status"
header_accessor :subject, "Subject"
header_accessor :msgid, "Message-id"
header_accessor :cc, "CC"
def isto? pattern
not [to,cc].grep(pattern).empty?
end
def involves? pattern
not [from,to,cc].grep(pattern).empty?
end
def ignore mailbox
saveread ".ignored-summer"
end
alias_method :internal_save, :save
def saveto mailbox
internal_save "#{ENV['HOME']}/Maildir/#{mailbox}/"
end
alias_method :save, :saveto
def saveread mailbox
pipe "#{ENV['HOME']}/bin/maildir-deliverread #{ENV['HOME']}/Maildir/#{mailbox}/"
end
def discard
pipe "true"
end
def main
myfilter
end
end
begin
RFilter::DeliveryAgent.process(STDIN,nil) { |agent| agent.main }
rescue RFilter::DeliveryAgent::DeliverySuccess
end
Then you can write really concise rules that look like this. (Any call
to a save function or discard function stops the filter right there.)
discard if from =~ /noreply at studygroup.com/
discard if from =~ /Walgreens at email.walgreens.com/
saveto ".computer" if header["Return-Path"] =~ /cat-in-the-hat/
saveto ".computer" if header["Return-Path"] =~ /little-cat-a/
saveto ".computer" if from =~ /cat-in-the-hat/
saveto ".computer" if from =~ /little-cat-a/
#this is on multiple lines only because the test is so long that
#it would have wrapped badly otherwise
if involves?(/someparticularperson at somedomain.com/)
saveto ".somefolder"
end
saveto ".lists.linux" if listid =~ /.*vox.*lugod/
if from =~ /messages at frumster.com/
saveto ".shidduchim" if subject =~ /sent you a message/i
saveto ".shidduchim" if subject =~ /I want to communicate with you/i
saveread ".shidduchim"
end
if message.to_s.length < 1048576
filter "spamassassin"
end
if spam =~ /^Yes/
saveread ".util.probably-spam"
end
You can even modify headers in process:
if from =~ /acl at aclweb.org/ or from =~ /portal at aclweb.org/
#Can't use sub! because the original string is frozen.
message.header.subject=subject.sub('[na_members at aclweb.org] ','')
saveto ".lists.ACL"
end
How are you rewriting headers in procmail? Is this done by piping, or
in-process?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.lugod.org/pipermail/vox-tech/attachments/20101023/df18b884/attachment.html
More information about the vox-tech
mailing list