File Coverage

blib/lib/Log/Accounting/Sendmail.pm
Criterion Covered Total %
statement 88 101 87.1
branch 14 24 58.3
condition 8 18 44.4
subroutine 9 10 90.0
pod 0 8 0.0
total 119 161 73.9


line stmt bran cond sub pod time code
1             package Log::Accounting::Sendmail;
2              
3 1     1   814 use strict;
  1         2  
  1         40  
4 1     1   4 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  1         2  
  1         1719  
5              
6             require Exporter;
7             require AutoLoader;
8              
9             @ISA = qw(Exporter AutoLoader);
10             # Items to export into callers namespace by default. Note: do not export
11             # names by default without a very good reason. Use EXPORT_OK instead.
12             # Do not simply export all your public functions/methods/constants.
13             @EXPORT = qw(
14            
15             );
16             $VERSION = '0.2';
17              
18             sub new {
19 1     1 0 453 my $that = shift;
20 1   33     10 my $class = ref($that) || $that;
21 1         2 my $self = {};
22 1         4 bless $self, $class;
23 1         5 $self->reset();
24 1         2 $self
25             }
26              
27             sub reset {
28 2     2 0 4 my $self = shift;
29 2         9 delete $self->{_data};
30 2         3 delete $self->{filter};
31 2         4 delete $self->{group};
32 2         6 $self
33             }
34              
35             sub add {
36 2     2 0 7 my $self = shift;
37 2         9 $self->{_data} .= $_[0];
38 2         10 $self
39             }
40              
41             sub addfile {
42 0     0 0 0 my ($self,$fh) = @_;
43 0 0 0     0 if (!ref($fh) && ref(\$fh) ne "GLOB") {
44 0         0 require Symbol;
45 0         0 $fh = Symbol::qualify($fh, scalar caller);
46             }
47             # $self->{_data} .= do{local$/;<$fh>};
48 0         0 my $read = 0;
49 0         0 my $buffer = '';
50 0         0 $self->add($buffer) while $read = read $fh, $buffer, 8192;
51 0 0       0 die __PACKAGE__, " read failed: $!" unless defined $read;
52             }
53              
54             sub group {
55 1     1 0 4 my $self = shift;
56 1         2 push @{$self->{group}}, @_;
  1         4  
57 1         4 $self
58             }
59              
60             sub filter {
61 1     1 0 2 my $self = shift;
62 1         1 push @{$self->{filter}}, @_;
  1         4  
63 1         4 $self
64             }
65              
66             sub map {
67 1     1 0 2 my $self = shift;
68 1         3 my %params = @_;
69 1         4 foreach my $k (keys %params) {
70 1         1 push @{$self->{map}->{$k}}, @{$params{$k}}
  1         4  
  1         3  
71             }
72             $self
73 1         5 }
74              
75             sub calc {
76 2     2 0 4 my $self = shift;
77 2         3 my (%MSGFROM, %MSGTO, %MSGREC, %MSGREC2, %MSGSIZE);
78             # parse
79 2         184 foreach(split /\n/, $self->{_data}) {
80 7 100       65 if (/sm-mta\[\d+\]\: (.+)\: from=(.+), size=(\d+), class=-?\d+, (?:pri=\d+, )?nrcpts=(\d+), msgid/) {
    100          
81 2         5 my $id=$1;
82 2         13 my $from=lc $2;
83 2         4 my $size=$3;
84 2         5 my $nr=$4;
85 2         11 $from=~s/[<>]//g;
86              
87 2 50       8 if ($from ne "") {
88             #print STDERR "id=$id, from=$from, rcp=$nr, size=$size\n";
89 2         6 $MSGFROM{$id}=$from;
90 2         5 $MSGREC{$id}=$nr;
91 2         5 $MSGREC2{$id}=$nr;
92 2         5 $MSGSIZE{$id}=$size;
93             }
94             } elsif (/sm-mta\[\d+\]\: (.+)\: to=(.+?), /) {
95 3         6 my $id=$1;
96 3         6 my $to=lc $2;
97 3         13 $to =~ s/[<>]//g;
98              
99 3         7 my @tos = split(/,/,$to);
100 3         5 foreach my $to (@tos) {
101 3 50       8 if (defined($MSGFROM{$id})) {
102             #print STDERR "id=$id, to=$to\n";
103 3         11 $MSGTO{$id." ".$MSGREC{$id}}=$to;
104 3         12 $MSGREC{$id}--;
105             }
106             }
107             }
108             }
109              
110 2         4 my %revmap;
111 2         4 foreach my $k (keys %{$self->{map}}) {
  2         7  
112 1         3 map {$revmap{$_}=$k} @{$self->{map}->{$k}}
  1         5  
  1         3  
113             }
114              
115             # calc
116 2         3 my %out;
117 2         5 foreach my $id (keys %MSGTO) {
118 3         12 $id =~ /(\w+) \d+/;
119 3         6 my $sid=$1;
120             #print STDERR "sid=$sid, id=$id\n";
121              
122             #print STDERR "MSGFROM{$sid}=$MSGFROM{$sid}, MSGTO{$id}=$MSGTO{$id}\n";
123 2         147 next if (ref($self->{filter}) eq 'ARRAY' &&
124 0         0 !grep($MSGFROM{$sid} =~ /^$_$/i, @{$self->{filter}}) &&
125 3 50 66     13 !grep($MSGTO{$id} =~ /^$_$/i, @{$self->{filter}}));
      33        
126              
127 3         19 my $tokey = $MSGTO{$id};
128 3 50       24 if (grep($MSGTO{$id} =~ /^$_$/i, keys %revmap)) {
129 0         0 $tokey = $revmap{(grep($MSGTO{$id} =~ /^$_$/i, keys %revmap))[0]};
130             }
131 3         7 my $fromkey = $MSGFROM{$sid};
132 3 100       47 if (grep($MSGFROM{$sid} =~ /^$_$/i, keys %revmap)) {
133 2         20 $fromkey = $revmap{(grep($MSGFROM{$sid} =~ /^$_$/i, keys %revmap))[0]};
134             }
135              
136 3 100 66     16 if (ref($self->{group}) eq 'ARRAY' &&
  2   66     24  
137 1         6 grep($fromkey =~ /^$_$/i, @{$self->{group}}) ||
138             grep($tokey =~ /^$_$/i, @{$self->{group}})) {
139 2         3 my @key;
140 2 50       3 if (@key=grep($tokey =~ /^$_$/i, @{$self->{group}})) {
  2         16  
141 0         0 foreach my $key (@key) {
142 0         0 $out{$key}->[0]++;
143 0         0 $out{$key}->[1] += $MSGSIZE{$sid};
144             }
145             }
146 2 50       5 if (@key=grep($fromkey =~ /^$_$/, @{$self->{group}})) {
  2         19  
147 2         3 foreach my $key (@key) {
148 2         6 $out{$key}->[0]++;
149 2         10 $out{$key}->[1] += $MSGSIZE{$sid};
150             }
151             }
152             } else {
153 1         1 push @{$out{$fromkey}}, [$MSGTO{$id}, $MSGSIZE{$sid}];
  1         7  
154             }
155             }
156              
157 2         21 %out;
158             }
159              
160              
161             1;
162             __END__