2 # spamassassin handling split from spamscan
5 # unfortunatly we can't use strict;
7 use lib qw(/usr/lib/debbugs);
8 use Mail::CrossAssassin;
9 use Mail::SpamAssassin;
11 my $config_path = '/etc/debbugs';
12 require "$config_path/config";
13 # New versions of debbugs will not allow use in /etc/debbugs/config
14 use POSIX qw(strftime);
15 $gSpamMailbox = strftime($gSpamMailbox,gmtime);
16 $gCrossMailbox = strftime($gCrossMailbox,gmtime);
22 sub header_or_empty ($$) {
23 my ($mail, $hdr) = @_;
24 my $value = $mail->get_header($hdr);
33 my $user_prefs = "$ENV{HOME}/.spamassassin/user_prefs";
35 my $spam = Mail::SpamAssassin->new({
37 site_rules_filename => $gSpamRulesDir,
38 userprefs_filename => $user_prefs,
39 local_tests_only => ($gSpamLocalTestsOnly || 0),
40 debug => ($ENV{DEBBUGS_SPAM_DEBUG} || 0),
42 $spam->compile_now(1); # use all user preferences
44 while (my $id = <STDIN>) {
46 my $nf = <STDIN> or die "Could not read nf: $!";
48 unless (rename "incoming/S$id", "incoming/R$id") {
49 die "Could not rename incoming/S$id: $!";
51 my $out = "[$nf] $id scanning ...\n";
52 open MESSAGE, "< incoming/R$id" or die "open incoming/R$id: $!";
53 # Kludge to work around Received: then From_ weirdness in receive;
54 # remove when receive is fixed? We may continue to need it for
55 # reprocessing old messages.
56 my @textarray = <MESSAGE>;
57 if ($textarray[0] !~ /^From /) {
58 ($textarray[0], $textarray[1]) = ($textarray[1], $textarray[0]);
61 my $mail = $spam->parse(\@textarray);
63 my $messageid = header_or_empty($mail, 'Message-Id');
64 $out .= " From: " . header_or_empty($mail, 'From') . "\n";
65 $out .= " Subject: ". header_or_empty($mail, 'Subject') . "\n";
66 $out .= " Date: " . header_or_empty($mail, 'Date') . "\n";
67 $out .= " Message-Id: $messageid\n";
68 my $keys = ca_keys($mail->get_body);
69 print "$keys\n$messageid\n"
70 or die "Could not send keys: $!";
71 my $ca_score = <STDIN> or die "Could not read ca_score: $!";
75 my $seen = <STDIN> or die "Child could not read seen: $!";
81 $headers = join('',$mail->get_all_headers());
82 $body = join('', @{$mail->get_body()});
83 $out .= " spam $seen duplicate\n";
85 $status = $spam->check($mail);
86 ($headers, $body) = split /\n\n/, $status->rewrite_mail(), 2;
90 if ($status->is_spam()) {
92 my $score = sprintf "%.1f/%.1f %d",
93 $status->get_score(), $status->get_required_score(),
95 $out .= " spam $score\n";
97 } elsif ($status->get_score() > 0 && $ca_score >= $gMaxCross) {
99 my $score = sprintf "%.1f/%.1f %d",
100 $status->get_score(), $status->get_required_score(), $ca_score;
101 $out .= " spam $score\n";
104 open OUT, "> incoming/I$id" or die "open incoming/I$id: $!";
105 my ($received, $from, $other_headers) =
106 split(/\n/, $headers, 3);
107 if ($recevied =~ /^From /) {
108 ($received, $from) = ($from, $received);
110 print OUT "$received\n$from\n$other_headers"
111 or die "print incoming/I$id: $!";
113 print OUT "X-CrossAssassin-Score: $ca_score\n"
114 or die "print incoming/I$id: $!";
116 print OUT "\n" or die "print incoming/I$id: $!";
117 print OUT $body or die "print incoming/I$id: $!";
118 close OUT or die "close incoming/I$id: $!";
119 unlink "incoming/R$id" or warn "unlink incoming/R$id: $!";
120 $out .= sprintf " ok %.1f/%.1f %d\n",
121 $status->get_score(), $status->get_required_score(),
128 open OUT, '>>', ($todo == 1) ? $gSpamMailbox : $gCrossMailbox
129 or die "Could not open assassinated: $!";
130 print OUT $headers or die "print assassinated: $!";
132 print OUT "X-CrossAssassin-Score: $ca_score\n"
133 or die "print assassinated: $!";
135 print OUT "\n" or die "print assassinated: $!";
136 $body =~ s/^From />From /gm;
137 print OUT $body or die "print assassinated: $!";
138 close OUT or die "Close assassinated: $!";
139 unlink "incoming/R$id" or warn "unlink incoming/R$id: $!";
142 print "$nseen\n$out\n";
143 $status->finish() unless($seen);