procmail
[Top] [All Lists]

Re: Adding custom mail headers via a filter?

2002-10-17 09:08:21
Ok I understand that clarification. I agree David's suggestion will work.

However, for now I shall make the following comments in order to provide context for reproducing this problem.

I have two filters in my procmailrc

#:0 fw:$HOME/strip.lock
#* ^Content-type:.*boundary
#| $HOME/perlscripts/strip_attachments.pl

#* ^Subject:.*isbn #\/([0-9a-z ])*

...

and

#:0 Wf:$HOME/filtmail.lock
#| $HOME/.filtmail/filtmail
#
#:0 a:$HOME/copy.lock
#$MAILDIR/copy

Up until recently I was only running strip_attachments.pl which looks like this.

Please note that the exit status is usually consistent.

#! /usr/bin/perl5 -w

use lib "$ENV{HOME}/lib/perl5/site_perl";

use IO::Scalar;
use MIME::Parser;
use MIME::Entity;

my $parser = MIME::Parser->new;

$parser->output_to_core(1);
$parser->tmp_to_core(1);

#$envelope = <STDIN>;

my $ent = $parser->parse(\*STDIN);

if ($ent->effective_type eq "multipart/mixed" &&
        $ent->parts == 2 &&
        $ent->parts(0)->effective_type eq "text/plain" &&
        $ent->parts(1)->effective_type eq "application/ms-tnef") {

        my $newent = MIME::Entity->build(Data =>
                        $ent->parts(0)->body_as_string .
                        "\n\n[[WINMAIL.DAT removed]]\n");

        $ent->parts([$newent]);
        $ent->make_singlepart;
        $ent->sync_headers(Length => 'COMPUTE', Nonstandard => 'ERASE');
        #$ent->dump_skeleton(\*STDERR);
}
if ($ent->effective_type eq "multipart/alternative" &&
        $ent->parts == 2 &&
        $ent->parts(0)->effective_type eq "text/plain" &&
        $ent->parts(1)->effective_type eq "text/html") {

        my $newent = MIME::Entity->build(Data =>
                        $ent->parts(0)->body_as_string .
                        "\n\n[[HTML alternate version deleted]]\n");

        $ent->parts([$newent]);
        $ent->make_singlepart;
        $ent->sync_headers(Length => 'COMPUTE', Nonstandard => 'ERASE');
        #$ent->dump_skeleton(\*STDERR);
}

#print $envelope;
$ent->print;

This is to remove content that outlook added to my messages and to remove the HTML that some web browser send. These days it's irrelevant as I use Mac OS 10.2 and no longer own a PC but I still run it to strip out incoming HTML "parts" from MIME messages.

The other filter is Paul J Lucas's Filtmail package which allows you to run custom filters. Because I have a lot of code my main filter I shall not post that here but suffice it to say it accesses files and either exits with zero on non zero status. The idea is the filter in perl decides whether to send the message through to the default folder or archive the message in a designated folder.

Here is the Filtmail code for those interested.

Yesterday I disabled the strip_attachments filter and enabled filtmail as a filter instead of using the ? expression syntax. The consequence of that was that every new message I received today which went through the exact same path of my custom filter ended up having it's "F" stripped off.

It was changed to a filter so that I could also add custom headers onto the message. (In order to explain why the message was rejected and why it's in that "junk" folder)

My custom filter performs a number of tasks.

Basically I keep a list of "known senders" and any message that comes in gets check against that. Also, I have a special token that folks have to sent me in order to become a known sender and it also checks again that. Does things like maintain the "known senders" list. Currently accepts replies as a known sender even if the sender isn't in that list. That's so when I initiate a coversation with somebody I don't reject their reply if they are replying to a usenet post.

I currently Bcc myself the outgoing message and I process that in my filter by adding the recipient to the "known senders" list. Because if they are not in this list folks will get an autoreply from me explaining how to become a known sender.

My filter also logs to a text file and uses flock in order to maintain concurrency of all text files it accesses and it uses LWP to Login with SSL and HTTP POST to a web site in order to send some message details to my cell phone. Thinks like Sender, Subject, Date etc.

So my filter does quite a lot. All of this enables me to manage my incoming mail in a way that I'm comfortable with.

!/usr/bin/perl
##
#       filtmail -- e-mail filtering package
#
#       Copyright (C) 1997  Paul J. Lucas
#
# This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##

$DIR = "$ENV{ HOME }/.filtmail";
$SENDMAIL = '/usr/sbin/sendmail';

########## You shouldn't have to change anything below this line. ############

$Message = join( '', <STDIN> );
( $Headers, $Body ) = split( /\n\n/s, $Message, 2 );
#
# The following 2 lines are adapted from "Programming Perl," 2nd ed., by
# Larry Wall, Tom Christiansen, and Randal L. Schwartz, O'Reilly & Associates,
# Inc., Sebastopol, CA, 1996, http://www.ora.com/, p. 222.
#
#$Headers =~ s/\n\s+/ /g;
#$Headers =~ s/\n\r$//g;
%Header = ( 'FRONTSTUFF', split( /^(\w[-\w]+):\s+/m, $Headers ) );

# strip off the newline at the end of each line
foreach $key (keys %Header) {
        $Header{$key} =~ s/\n//;
}

sub parse_address {
        my ( $key, $h ) = @_;
        ( $h->{ address } ) = $Header{ $key } =~ 
/([-\w(_dot_)]*(_at_)\w[-\w(_dot_)]+)/;
#( $h->{ address } ) = $Header{ $key } =~ /([-\w(_dot_)]*(_at_)?\w[-\w(_dot_)]*)/; ( $h->{ login }, $h->{ domain } ) = split( /@/, $h->{ address } );
        $h->{ domain } =~ s/(?:[-\w]+\.)?(\w[-\w]+\.[a-z]{2,3})/$1/ix;
}

parse_address( 'From', \%From );
parse_address( 'FROM', \%FROM );
parse_address( 'Reply-To', \%ReplyTo );
parse_address( 'To', \%To );

@To = split( /,\s*/, $Header{ To } );
@Cc = split( /,\s*/, $Header{ Cc } );
@CC = split( /,\s*/, $Header{ CC } );

@Recipients = ( @To, @Cc , @CC);

######################################################################## ######

$FILES = "$DIR/files";
$FILTERS = "$DIR/filters";

@FILTERS = grep { -f } <$FILTERS/*>;
eval `cat @FILTERS`;

exit 1;

At the end of my custom "FILTER" I have this code.

if ($result = grep /$fsender/i, `cat $acceptFile`) {
        &logText("      Sender recognised in accept file");
        &pageSubjectWithDTAC();
        exit 1;
}

#temporarily email subject for anybody
#&emailSubject();

#reject mail
#&draftAutoReply if !$result;

&reason("Sender not recognized");

exit 0;

The reason function looks like this

sub reason {
        my $reason = $_[0];

        print $Headers;
        print "\n";
        print "X-Challenge-Reason: $reason\n";
        print "\n";
        print $Body;
}

Yesterday whenever I enabled the strip_attachments filter and the filtmail filter together and send myself a message that would match the strip_attachments rule. By the time the message had come out of the strip_attachments rule it was missing the _entire_ From_ line. Not just the first character.

Tomorrow I may have some time to test that again but losing the entire From_ line is a bit more problematic than just the first "F"... so I'm reluctant to try that in "peak hours"



On Thursday, October 17, 2002, at 09:26 PM, David W. Tamkin wrote:

When I suggested,

| >  :0hf
| >  * ^^rom( )
| >  | sed '1s/^rom/From/' # or heck, sed 1s/^/F/

Robert objected,


| I had an email that had body text
|
| asdljflkasdfjalsfjasfljasflkjaskfljasdf;jasdfkF=
| rom asldfjasklfjaslkfjaslkfjaslkfjaslkfjasdflkj
|
| so I don't think that rule is 100% reliable.

So what? What does the body have to do with it? Your problem is with the first line of the head, my recommended code examines only the first line of the head, and it affects only the first line of the head. The content of the body is as irrelevant as the color of your eyes or the direction of the wind.



_______________________________________________
procmail mailing list
procmail(_at_)lists(_dot_)RWTH-Aachen(_dot_)DE
http://MailMan.RWTH-Aachen.DE/mailman/listinfo/procmail