5 use vars qw#%DATAFIELDS#;
8 use Yaala::Data::Persistent qw#init#;
9 use Yaala::Parser::WebserverTools qw#%MONTH_NUMBERS#;
11 @Yaala::Parser::EXPORT_OK = qw(parse extra %DATAFIELDS);
12 @Yaala::Parser::ISA = ('Exporter');
14 our $LASTDATE = init ('$LASTDATE', 'scalar');
15 our $EXTRA = init ('$EXTRA', 'hash');
16 our $MAILS = init ('$MAILS', 'hash');
18 if (!$$LASTDATE) { $$LASTDATE = 0; }
19 if (!defined ($EXTRA->{'relay_denied'})) { $EXTRA->{'relay_denied'} = 0; }
20 if (!defined ($EXTRA->{'tls_hosts'} )) { $EXTRA->{'tls_hosts'} = {}; }
30 defer_count => 'key:numeric',
33 incoming_host => 'key:host',
34 outgoing_host => 'key:host',
40 # This needs to be done at runtime, since Data uses Setup which relies on
41 # %DATAFIELDS to be defined -octo
42 require Yaala::Data::Core;
43 import Yaala::Data::Core qw#store#;
45 my $VERSION = '$Id: Postfix.pm,v 1.6 2003/12/07 15:42:22 octo Exp $';
46 print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);
54 if ($line =~ m#^(\w{3})\s+(\d+) (\d\d):(\d\d):(\d\d) (\S+) postfix/([^\[]+)[^:]+: ([A-F0-9]+): (.+)$#)
56 my ($month, $day, $hour, $minute, $second,
57 $hostname, $service, $id, $line_end) =
58 ($1, $2, $3, $4, $5, $6, $7, $8, $9);
59 my $year = (localtime ())[5] + 1900;
60 $month = $MONTH_NUMBERS{$month};
63 my $tmp = int (sprintf ("%04u%02u%02u%02u%02u%02u",
64 $year, $month, $day, $hour, $minute, $second));
66 if ($tmp < $$LASTDATE)
68 print STDERR $/, __FILE__, ": Skipping.. ($tmp <= $$LASTDATE)" if ($::DEBUG & 0x0200);
71 else { $$LASTDATE = $tmp; }
74 my $date = sprintf ("%04u-%02u-%02u", $year, $month, $day);
76 if (!defined ($MAILS->{$id}))
82 sender => '*UNKNOWN*',
83 recipient => '*UNKNOWN*',
86 incoming_host => '*UNKNOWN*',
87 outgoing_host => '*UNKNOWN*',
93 $MAILS->{$id}{'date'} = $date;
94 $MAILS->{$id}{'hour'} = $hour;
96 if ($line_end =~ m/^to=<([^>]+)>, relay=([^,]+), delay=(\d+), status=(\w+)/)
98 my ($to, $relay, $delay, $status) = ($1, $2, $3, $4);
100 $MAILS->{$id}{'recipient'} = $to;
101 if ($MAILS->{$id}{'delay'} < $delay)
103 $MAILS->{$id}{'delay'} = $delay;
106 if ($relay =~ m/^([^\[]+)\[([\d\.]+)\]$/)
111 if ($host eq 'unknown')
113 $MAILS->{$id}{'outgoing_host'} = $ip;
117 $MAILS->{$id}{'outgoing_host'} = $host;
120 elsif ($relay eq 'local')
122 $MAILS->{$id}{'outgoing_host'} = 'localhost';
125 if ($status eq 'sent')
129 elsif ($status eq 'deferred')
131 $MAILS->{$id}{'defer_count'}++;
133 elsif ($status eq 'bounced')
135 $MAILS->{$id}{'recipient_count'}--;
136 if ($MAILS->{$id}{'recipient_count'} < 1)
138 delete ($MAILS->{$id});
143 print STDERR $/, __FILE__, ": Unknown status: $status";
146 elsif ($line_end =~ m/^from=<([^>]*)>, size=(\d+), nrcpt=(\d+)/)
148 my ($from, $size, $nrcpt) = ($1, $2, $3, $4);
150 $MAILS->{$id}{'sender'} = $from if ($from);
151 $MAILS->{$id}{'bytes'} = $size;
153 $MAILS->{$id}{'recipient_count'} = $nrcpt;
155 elsif ($line_end =~ m/client=([^ ,]+)/)
159 if ($client =~ m/^([^\[]+)\[([\d\.]+)\]$/)
164 if ($host eq 'unknown')
166 $MAILS->{$id}{'incoming_host'} = $ip;
170 $MAILS->{$id}{'incoming_host'} = $host;
175 print STDERR $/, __FILE__,
176 ": Unable to parse client string: $client";
180 elsif ($line =~ m/Relay access denied/i)
182 $EXTRA->{'relay_denied'}++;
184 elsif ($line =~ m/TLS connection established (?:to|from) ([^\[]+)\[([^\]]+)\]/i)
189 my $ident = ($host eq 'unknown' ? $ip : $host);
191 $EXTRA->{'tls_hosts'}{$ident} = 1;
193 elsif ($::DEBUG and 0)
196 print STDERR $/, __FILE__, ": Unable to parse line: $line";
203 my $mail = $MAILS->{$id};
207 $mail->{'recipient_count'}--;
208 if ($mail->{'recipient_count'} < 1)
210 delete ($MAILS->{$id});
216 if ($EXTRA->{'relay_denied'})
218 $::EXTRA->{'Relay access denied'} = sprintf ("%u times", $EXTRA->{'relay_denied'});
221 my $tls_hosts = scalar (keys (%{$EXTRA->{'tls_hosts'}}));
224 $::EXTRA->{'TLS connections'} = sprintf ("%u hosts", $tls_hosts);