1 |
#!/usr/bin/perl |
2 |
# False Positive |
3 |
# |
4 |
# Douglas Thrift |
5 |
# |
6 |
# $Id$ |
7 |
|
8 |
use strict; |
9 |
use warnings; |
10 |
|
11 |
use IO::Socket::SSL; |
12 |
use Mail::IMAPClient; |
13 |
use Mail::SpamAssassin; |
14 |
use MIME::Base64; |
15 |
|
16 |
my $debug = 0; |
17 |
|
18 |
for my $arg (@ARGV) |
19 |
{ |
20 |
if ($arg eq "-debug") |
21 |
{ |
22 |
$debug = 1; |
23 |
} |
24 |
else |
25 |
{ |
26 |
print "Usage: $0 [-debug]\n"; |
27 |
|
28 |
exit 1; |
29 |
} |
30 |
} |
31 |
|
32 |
my $socket = new IO::Socket::SSL(Proto => 'tcp', PeerAddr => 'mail.douglasthrift.net', PeerPort => 993) or die "$0: $@\n"; |
33 |
my $imap = new Mail::IMAPClient(Debug => $debug, Socket => $socket); |
34 |
|
35 |
{ |
36 |
my $user = getpwuid $<; |
37 |
|
38 |
open PASS, "$ENV{HOME}/.SpamUpdate.pass" or die "$0: $!\n"; |
39 |
|
40 |
my $pass = <PASS>; |
41 |
|
42 |
chomp $pass; |
43 |
close PASS; |
44 |
|
45 |
$pass =~ tr/A-Za-z/N-ZA-Mn-za-m/; |
46 |
|
47 |
$imap->User($user); |
48 |
$imap->Password(decode_base64($pass)); |
49 |
} |
50 |
|
51 |
sub error |
52 |
{ |
53 |
die "$0: " . $imap->LastError; |
54 |
} |
55 |
|
56 |
$imap->login or error; |
57 |
$imap->select('Spam.False Positive') or error; |
58 |
|
59 |
my @messages = $imap->search('UNFLAGGED'); |
60 |
|
61 |
error if ($@); |
62 |
|
63 |
if ($#messages != -1) |
64 |
{ |
65 |
my $assassin = new Mail::SpamAssassin($debug ? {debug => 'all'} : {}); |
66 |
|
67 |
for my $message (@messages) |
68 |
{ |
69 |
my @result = $imap->fetch($message, '(INTERNALDATE BODY[])') or error; |
70 |
|
71 |
die "$0: no message $message\n" if ($result[0] !~ /UID $message/); |
72 |
|
73 |
$result[0] =~ /INTERNALDATE "([^"]+)"/; |
74 |
|
75 |
$imap->append_string('INBOX', $assassin->remove_spamassassin_markup($assassin->parse($result[1])), undef, $1) or error; |
76 |
$imap->mark($message) or error; |
77 |
} |
78 |
} |
79 |
|
80 |
$imap->logout; |