l i n u x - u s e r s - g r o u p - o f - d a v i s
L U G O D
 
Next Meeting:
August 5: Social gathering
Next Installfest:
TBD
Latest News:
Jul. 4: July, August and September: Security, Photography and Programming for Kids
Page last updated:
2010 Oct 23 18:29

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
Re: [vox-tech] procmail question
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [vox-tech] procmail question



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@bar.com/ || \
    /From:.*bar@foo.com/ || \
    /From:.*baz@bar.com/ || \
    /From:.*@some.domain.org/ || \
    /Mailing-List: list some-other-mailinglist@yahoogroups.com; / || \
    /From:.*afinal@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@studygroup.com/
      discard if from =~ /Walgreens@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@somedomain.com/)
        saveto ".somefolder"
      end

      saveto ".lists.linux" if listid =~ /.*vox.*lugod/

      if from =~ /messages@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@aclweb.org/ or from =~ /portal@aclweb.org/
        #Can't use sub! because the original string is frozen.
        message.header.subject=subject.sub('[na_members@aclweb.org] ','')
        saveto ".lists.ACL"
     end



How are you rewriting headers in procmail? Is this done by piping, or in-process?
_______________________________________________
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech


LinkedIn
LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
facebook
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
Appahost Applications
For a significant contribution towards our projector, and a generous donation to allow us to continue meeting at the Davis Library.