File Coverage

lib/Mail/Toaster/Base.pm
Criterion Covered Total %
statement 104 131 79.3
branch 44 68 64.7
condition 4 8 50.0
subroutine 18 23 78.2
pod 0 19 0.0
total 170 249 68.2


line stmt bran cond sub pod time code
1             package Mail::Toaster::Base;
2 13     13   4670 use strict;
  13         18  
  13         296  
3 13     13   42 use warnings;
  13         12  
  13         492  
4              
5             our $VERSION = '5.50';
6              
7 13     13   48 use Carp;
  13         14  
  13         601  
8 13     13   915 use Params::Validate ':all';
  13         12151  
  13         17323  
9              
10             our $verbose = our $last_audit = our $last_error = 0; # package variables
11             our (@audit, @errors); # package wide message stacks
12             our ($conf, $log);
13             our ($darwin, $dns, $freebsd, $qmail, $logs, $mysql, $setup, $toaster, $util);
14              
15             our %std_opts = (
16             test_ok => { type => BOOLEAN, optional => 1 },
17             verbose => { type => BOOLEAN, optional => 1, default => $verbose },
18             fatal => { type => BOOLEAN, optional => 1, default => 1 },
19             );
20              
21             sub new {
22 33     33 0 8345 my $class = shift;
23 33         927 my %p = validate( @_, { %std_opts } );
24 33         243 my @caller = caller;
25             # warn sprintf( "Base.pm loaded by %s, %s, %s\n", @caller ) if $caller[0] ne 'main';
26 33         240 return bless {}, $class;
27             }
28              
29             sub darwin {
30 0     0 0 0 my $self = shift;
31 0 0       0 return $darwin if ref $darwin;
32 0         0 require Mail::Toaster::Darwin;
33 0         0 return $darwin = Mail::Toaster::Darwin->new();
34             }
35              
36             sub dns {
37 3     3 0 5 my $self = shift;
38 3 100       15 return $dns if ref $dns;
39 1         698 require Mail::Toaster::DNS;
40 1         11 return $dns = Mail::Toaster::DNS->new();
41             }
42              
43             sub freebsd {
44 0     0 0 0 my $self = shift;
45 0 0       0 return $freebsd if ref $freebsd;
46 0         0 require Mail::Toaster::FreeBSD;
47 0         0 return $freebsd = Mail::Toaster::FreeBSD->new();
48             }
49              
50             sub logs {
51 0     0 0 0 my $self = shift;
52 0 0       0 return $logs if ref $logs;
53 0         0 require Mail::Toaster::Logs;
54 0         0 return $logs = Mail::Toaster::Logs->new();
55             }
56              
57             sub mysql {
58 0     0 0 0 my $self = shift;
59 0 0       0 return $mysql if ref $mysql;
60 0         0 require Mail::Toaster::Mysql;
61 0         0 return $mysql = Mail::Toaster::Mysql->new();
62             }
63              
64             sub qmail {
65 7     7 0 36 my $self = shift;
66 7 100       30 return $qmail if ref $qmail;
67 2         1723 require Mail::Toaster::Qmail;
68 2         31 return $qmail = Mail::Toaster::Qmail->new();
69             }
70              
71             sub setup {
72 3     3 0 5 my $self = shift;
73 3 100       11 return $setup if ref $setup;
74 2         2026 require Mail::Toaster::Setup;
75 2         35 return $setup = Mail::Toaster::Setup->new();
76             }
77              
78             sub toaster {
79 12     12 0 23 my $self = shift;
80 12 100       397 return $toaster if ref $toaster;
81 2         718 require Mail::Toaster;
82 2         21 return $toaster = Mail::Toaster->new();
83             }
84              
85             sub util {
86 39     39 0 3434 my $self = shift;
87 39 100       326 return $util if ref $util;
88 9         5815 require Mail::Toaster::Utility;
89 9         137 return $util = Mail::Toaster::Utility->new();
90             }
91              
92             sub verbose {
93 47 100   47 0 699 return $verbose if 1 == scalar @_;
94 1         4 return $verbose = $std_opts{verbose}{default} = $_[1];
95             };
96              
97             sub conf {
98 214 100   214 0 8935 $conf = $_[1] if $_[1];
99 214 100       906 return $conf if $conf;
100 5         64 $conf = $_[0]->util->parse_config( "toaster-watcher.conf" );
101             };
102              
103             sub audit {
104 363     363 0 1413 my $self = shift;
105 363         432 my $mess = shift;
106              
107 363         5421 my %p = validate( @_, { %std_opts } );
108              
109 363 100       1440 if ($mess) {
110 361         575 push @audit, $mess;
111 361 100 66     1401 print "$mess\n" if $verbose || $p{verbose};
112             }
113              
114 363         968 return \@audit;
115             }
116              
117             sub dump_audit {
118 10     10 0 1265 my $self = shift;
119 10         183 my %p = validate( @_, {
120             quiet => { type => BOOLEAN, optional => 1, default => 0 },
121             %std_opts,
122             }
123             );
124              
125 10 50       58 if ( 0 == scalar @audit ) {
126 0 0       0 print "dump_audit: no audit messages\n" if $p{verbose};
127 0         0 return 1;
128             };
129              
130 10 100       26 if ( $last_audit == scalar @audit ) {
131 1 50       5 print "dump_audit: all messages dumped\n" if $p{verbose};
132 1         2 return 1;
133             };
134              
135 9 100       24 if ( $p{quiet} ) { # hide/mask unreported messages
136 7         13 $last_audit = scalar @audit;
137 7         21 $last_error = scalar @errors;
138 7         25 return 1;
139             };
140              
141 2         8 print "\n\t\t\tAudit History Report \n\n";
142 2         5 for( my $i = $last_audit; $i < scalar @audit; $i++ ) {
143 2         6 print " $audit[$i]\n";
144 2         5 $last_audit++;
145             };
146 2         15 return 1;
147             };
148              
149             sub error {
150 33     33 0 96163 my $self = shift;
151 33 50       178 my $message = shift or carp "why call error w/o message?";
152 33         996 my %p = validate( @_,
153             { location => { type => SCALAR, optional => 1 },
154             frames => { type => SCALAR, optional => 1, default => 0 },
155             %std_opts,
156             },
157             );
158              
159 33 50       229 if ( $message ) {
160             # append message and location to the error stack
161 33         366 my @call = caller $p{frames};
162 33         77 my $location = $p{location};
163 33 50 100     275 if ( ! $location && scalar @call ) {
164 29         132 $location = join( ', ', $call[0], $call[2] );
165             };
166 33         201 push @errors, { errmsg => $message, errloc => $location };
167             }
168             else {
169 0         0 $message = $errors[-1];
170             }
171              
172 33 100       137 $self->dump_audit if $self->verbose;
173 33 100       117 $self->dump_errors if $p{fatal};
174              
175 33 100       411 exit 1 if $p{fatal};
176 30         351 return;
177             }
178              
179             sub dump_errors {
180 6     6 0 20 my $self = shift;
181              
182 6 100       36 if ( $last_error == scalar @errors ) {
183 2 50       9 print "all error messages dumped!\n" if $verbose;
184 2         3 return 1;
185             };
186              
187 4         452 print "\n\t\t\t Error History Report \n\n";
188 4         13 my $i = 0;
189 4         12 foreach ( @errors ) {
190 8         12 $i++;
191 8 100       20 next if $i < $last_error;
192 5         12 my $msg = $_->{errmsg};
193 5 50       28 my $loc = $_->{errloc} ? " at $_->{errloc}" : '';
194 5         204 print $msg;
195 5         28 for (my $j=length($msg); $j < 90-length($loc); $j++) { print '.'; };
  91         136  
196 5         228 print " $loc\n";
197             };
198 4         69 print "\n";
199 4         12 $last_error = $i;
200 4         7 return 1;
201             };
202              
203             sub get_std_args {
204 189     189 0 252 my $self = shift;
205 189         399 my %p = @_;
206 189         219 my %args;
207 189         432 foreach ( qw/ verbose fatal test_ok / ) {
208 567 100       996 if ( defined $p{$_} ) {
209 392         513 $args{$_} = $p{$_};
210 392         380 next;
211             };
212 175 50       474 if ( $self->{$_} ) {
213 0         0 $args{$_} = $self->{$_};
214             };
215             };
216 189         706 return %args;
217             };
218              
219 336     336 0 7126 sub get_std_opts { return %std_opts };
220              
221             sub log {
222 0     0 0   my $self = shift;
223 0 0         my $mess = shift or return;
224              
225 0 0         my $logfile = $conf->{'toaster_watcher_log'} or do {
226 0           warn "ERROR: no log file defined!\n";
227 0           return;
228             };
229 0 0 0       return if ( -e $logfile && ! -w $logfile );
230              
231 0           $self->util->logfile_append( $logfile, lines => [$mess], fatal => 0 );
232             };
233              
234             1;