#! /usr/local/bin/perl5 use Mail::IMAPClient; use Email::Find; =head1 NAME find-email-in-sentmail - checks your imap folders for an address =head1 SYNOPSIS find-email-in-sentmail emailaddress find-email-in-sentmail is a perl script that is designed to check imap folders, using the imap query langauge, for a given address. The primary purpose of this was written for a whitelisting rulein procmail. The search argument may be given either on the command line or on stdin, so it may be fed as part of a pipe. This action I if you run an imap server that sucks. This is because the commands given will tell imap to scan the headers for email addresses. If your imap folder precaches the headers into a database, like B does, this script will run very very fast. On my machine, it costs .35 seconds to start up and connect to imap, and then 0.01 seconds to actually search as many mail folders as I want. Configuration is done in the script. Look for I, I, and look for I to set the mailboxes up. If you are not running B your mailbox names may be different. In procmail: # Scan INBOX, INBOX.sent-mail, and INBOX.whitelist # - Do we know this person? # - If not, store it with the $DELIVER program # into the "defer" mailbox. :0 * ! ? formail -XFrom: -XSender: | /home/username/bin/find-email-in-sentmail | $DELIVER -m defer username =head1 BUGS This script assumes you have knowledge of how your imap server works. =head1 AUTHOR This script is Copyright (C) 2001 by Jason Fesler. All rights reserved. You may use this script in any setting; please keep the above notice intact. Tech support is not available; bug fixes and enhancements are gladly appreciated. Please send those to I. =cut $DEBUG=0; @check = split(/\n/,<<'EOF'); INBOX.sent-mail TO CC BCC INBOX.whitelist FROM TO CC BCC HEADER_Sender INBOX FROM CC BCC EOF if ($DEBUG) { select(STDERR); $|=1; select(STDOUT); $|=1; } if (@ARGV) { foreach (@ARGV) { find_emails($_,sub { my($e,$o) = @_; $find{$e->format}++; }); } unless (keys %find) { %find = map { $_ => $_ } @ARGV; } } else { while () { find_emails($_,sub { my($e,$o) = @_; $find{$e->format}++; }); } } my $imap = Mail::IMAPClient->new( Server => 'localhost', User => 'USERNAME', Password => 'PASSWORD', Clear => 5, ) or die "Cannot connect: $@"; my @uids = (); my ($folder,$header) = (); my (%found); foreach $check (@check) { ($folder,@headers) = split(/\s+/,$check); foreach(@headers){s/_/ /g;} $imap->select($folder); $imap->Uid(1); foreach $find (sort keys %find) { $find = lc $find; foreach $header (@headers) { $DEBUG && print STDERR "Checking $folder $find $header\n"; $hashref = $imap->parse_headers( scalar($imap->search( $header, $find )), $header); $header =~ s/HEADER //; while( ($l,$r) = each %{$hashref} ) { $DEBUG && print STDERR "."; @list = @ { ${$r}{$header} } ; foreach $l (@list) { find_emails($l,sub { my($e,$o) = @_; $found{$e->format}++; }); } } $DEBUG && print STDERR "\n"; @found = grep(lc $_ eq $find, keys %found); if (scalar @found) { print "Found\n"; exit 0; } } # end of @headers } # end of %find } # end of @check print STDERR "ERROR: No matches\n"; exit 1;