File Coverage

lib/What/MTA.pm
Criterion Covered Total %
statement 32 101 31.6
branch 4 26 15.3
condition 6 14 42.8
subroutine 7 14 50.0
pod 4 4 100.0
total 53 159 33.3


line stmt bran cond sub pod time code
1             #$ Id: $;
2             package What::MTA;
3 2     2   7 use strict;
  2         3  
  2         61  
4 2     2   8 use vars qw($VERSION @ISA);
  2         3  
  2         93  
5 2     2   2692 use Socket 1.3;
  2         14429  
  2         1219  
6 2     2   20 use Carp;
  2         4  
  2         112  
7 2     2   2154 use IO::Socket;
  2         44429  
  2         11  
8 2     2   4163 use Net::Cmd;
  2         10890  
  2         3351  
9            
10             $VERSION = "1.00";
11              
12             @ISA = qw(Net::Cmd IO::Socket::INET);
13              
14             =head1 NAME
15              
16             What::MTA - Find out about running MTA
17              
18             =head1 SYNOPSIS
19              
20             $what = What->new(
21             Host => my.domain.org,
22             Port => 25,
23             );
24              
25             $what->mta;
26             $what->mta_version;
27             $what->mta_banner;
28            
29             =head1 DESCRIPTION
30              
31             What::MTA is a part of C package. It provides basic information
32             about running MTA: name, version and banner that MTA prints out upon
33             connection to it. It is not meant to be used directly, but via its
34             interface, class C. MTA's supported are: Exim, Postfix (version
35             only on localhost), Sendmail, Courier (name only), XMail, MaswMail.
36              
37             The What::MTA class is a subclass of Net::Cmd and IO::Socket::INET.
38              
39             =head1 CONSTRUCTOR
40              
41             =over
42              
43             =item new ( OPTIONS )
44              
45             This is the constructor for a new What object.
46              
47             C are passed in a hash like fashion, using key and value pairs.
48             Possible options are:
49              
50             =back
51              
52             =over 4
53              
54             B - is the name, or address, of the remote host to which a
55             connection to a running service is required to. It may be a single
56             scalar, as defined for the C option in L.
57             C is optional, default value is C.
58              
59             B and B - These parameters are passed directly
60             to IO::Socket to allow binding the socket to a local port.
61              
62             B - Maximum time, in seconds, to wait for a response from the
63             server (default: 120)
64              
65             B - Port to which to connect to (default: 25)
66              
67             B - Enable debugging information
68              
69             =back
70              
71             Example:
72              
73             $what = What->new(
74             Host => 'my.mail.domain'
75             Timeout => 30,
76             Debug => 1,
77             );
78              
79             $what = What->new(
80             Host => '10.10.10.1',
81             Port => 25,
82             );
83              
84             =cut
85              
86             sub new {
87 2     2 1 5 my $self = shift;
88 2   33     10 my $type = ref($self) || $self;
89 2         6 my %arg = @_;
90              
91 2   50     10 my $PeerAddr = $arg{Host} || 'localhost';
92 2   100     9 my $PeerPort = $arg{Port} || 'smtp(25)';
93 2 50       7 my $Timeout = defined $arg{Timeout} ? $arg{Timeout} : 120;
94 2   50     9 my $LocalAddr = $arg{LocalAddr} || undef;
95 2   50     10 my $LocalPort = $arg{LocalPort} || undef;
96              
97 2         23 my $obj = $type->SUPER::new(PeerAddr => $PeerAddr,
98             PeerPort => $PeerPort,
99             LocalAddr => $LocalAddr,
100             LocalPort => $LocalPort,
101             Proto => 'tcp',
102             Timeout => $Timeout,
103             );
104            
105 2 50       4651 if (not defined($obj)) {
106 2         10 my $msg = "Couldn't create What::MTA object with\n" .
107             "PeerAddr=$PeerAddr,\nPeerPort=$PeerPort,\n" .
108             "Proto=tcp,\nTimeout=$Timeout";
109 2 50       5 $msg .= "LocalAddr=$LocalAddr,\n" if defined $LocalAddr;
110 2 50       3 $msg .= "LocalPort=$LocalPort,\n" if defined $LocalPort;
111 2         32 croak $msg;
112             }
113            
114 0           $obj->autoflush(1);
115 0 0         $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
116              
117 0 0         unless ($obj->response() == CMD_OK) {
118 0           $obj->close();
119 0           return undef;
120             }
121              
122 0   0       (${*$obj}{'mta_banner'}) = $arg{Banner} || $obj->message;
  0            
123 0           (${*$obj}{'mta_banner'}) =~ s/\n$//;
  0            
124              
125 0           $obj->_extract_name_version();
126            
127 0           $obj;
128             }
129              
130 0     0     sub _EHLO { shift->command("EHLO", @_)->response() == CMD_OK }
131 0     0     sub _HELO { shift->command("HELO", @_)->response() == CMD_OK }
132 0     0     sub _HELP { shift->command("HELP", @_)->response() == CMD_OK }
133              
134             =head1 METHODS
135              
136             =over
137              
138             =item mta()
139              
140             Returns the name of the MTA running.
141              
142             =back
143              
144             =cut
145              
146             sub mta {
147 0     0 1   my $self = shift;
148 0           return ${*$self}{'mta_name'};
  0            
149             };
150              
151             =over
152              
153             =item mta_version()
154              
155             Returns the version of the MTA running.
156              
157             =back
158              
159             =cut
160              
161             sub mta_version {
162 0     0 1   my $self = shift;
163 0           return ${*$self}{'mta_version'};
  0            
164             };
165              
166             =over
167              
168             =item mta_banner()
169              
170             Returns the banner message which the server replied with when the
171             initial connection was made.
172              
173             =back
174              
175             =head1 EXAMPLES OF MTA BANNERS
176              
177             =over 4
178              
179             =item Exim
180              
181             localhost ESMTP Exim 4.60 Mon, 20 Feb 2006 22:38:53 +0000
182              
183             =item Postfix
184              
185             localhost ESMTP Postfix (Debian/GNU)
186              
187             =item Sendmail
188              
189             galeb.somedomain.org ESMTP Sendmail 8.13.5/8.13.5/Debian-3; Mon, 20
190             Feb 2006 22:41:04 GMT; (No UCE/UBE) logging access from:
191             localhost(OK)-localhost [127.0.0.1]
192              
193             =item XMail
194              
195             <1140475332.2874633136@mast> [XMail 1.22 ESMTP Server] service ready;
196             Mon, 20 Feb 2006 22:42:12 -0000
197              
198             =item MasqMail
199              
200             mast MasqMail 0.2.21 ESMTP
201              
202             =back
203              
204             =cut
205              
206             sub mta_banner {
207 0     0 1   my $self = shift;
208 0           return ${*$self}{'mta_banner'};
  0            
209             };
210              
211             =head1 DIAGNOSTICS
212              
213             =over
214              
215             =item Can not connect to the serice host/port specified
216              
217             Couldn't create What::MTA object with
218             PeerAddr=localhost,
219             PeerPort=26,
220             Proto=tcp,
221             Timeout=120 at lib/What.pm line 68
222              
223             =back
224              
225             =head1 DEPENDENCIES
226              
227             Class::Std depends on the following modules:
228              
229             =over
230              
231             =item *
232              
233             L
234              
235             =item *
236              
237             L
238              
239             =item *
240              
241             L
242              
243             =back
244              
245              
246              
247             =cut
248              
249             sub _extract_name_version {
250 0     0     my $self = shift;
251              
252 0 0         if ( (${*$self}{'mta_banner'}) =~ m/Exim/ ) {
  0 0          
  0 0          
    0          
    0          
    0          
253             ### Exim ###
254              
255 0           (${*$self}{'mta_version'}) =
  0            
256 0           (${*$self}{'mta_banner'}) =~ m/^.+ESMTP Exim (\d+\.\d+) .+/;
257              
258 0           (${*$self}{'mta_name'}) = "Exim";
  0            
259              
260 0           } elsif ( (${*$self}{'mta_banner'}) =~ m/Postfix/ ) {
261             ### Postfix ###
262              
263 0           my $v;
264 0           eval {
265 0           $v = `postconf mail_version`;
266             };
267 0 0         if (defined($@)) {
268 0           (${*$self}{'mta_version'}) = "unknown";
  0            
269             } else {
270 0           (${*$self}{'mta_version'}) = $v =~ m/.+ = (.+)/;
  0            
271             }
272 0           (${*$self}{'mta_name'}) = "Postfix";
  0            
273              
274 0           } elsif ( (${*$self}{'mta_banner'}) =~ m/Sendmail/ ) {
275             ### Sendmail ###
276              
277 0           (${*$self}{'mta_version'}) =
  0            
278 0           (${*$self}{'mta_banner'}) =~ m/^.+Sendmail (\d+\.\d+?.\d+)\/.+/;
279              
280 0           (${*$self}{'mta_name'}) = "Sendmail";
  0            
281            
282 0           } elsif ( (${*$self}{'mta_banner'}) =~ m/XMail/ ) {
283             ### XMail ###
284              
285 0           (${*$self}{'mta_version'}) =
  0            
286 0           (${*$self}{'mta_banner'}) =~ m/^.+XMail (.+) ESMTP.+/;
287              
288 0           (${*$self}{'mta_name'}) = "XMail";
  0            
289              
290 0           } elsif ( (${*$self}{'mta_banner'}) =~ m/MasqMail/ ) {
291             ### MasqMail ###
292              
293 0           (${*$self}{'mta_version'}) =
  0            
294 0           (${*$self}{'mta_banner'}) =~ m/^.+MasqMail (.+) ESMTP?.+/;
295              
296 0           (${*$self}{'mta_name'}) = "MasqMail";
  0            
297              
298             } elsif ( (${*$self}{'mta_banner'}) =~ m/\w ESMTP$/ ) {
299             ### Courier? ###
300              
301 0           (${*$self}{'mta_version'}) = "see syslog";
  0            
302 0           (${*$self}{'mta_name'}) = "Courier";
  0            
303              
304             } else {
305             ### unkown ###
306              
307 0           (${*$self}{'mta_version'}) = "unknown";
  0            
308 0           (${*$self}{'mta_name'}) = "unknown";
  0            
309              
310             };
311             };
312              
313              
314             1;
315              
316             =head1 BUGS
317              
318             Please report any bugs or feature requests to
319             C, or through the web interface at
320             L.
321              
322             =head1 ACKNOWLEDGEMENTS
323              
324             Lot of code taken from Net::Cmd, without which this class probably
325             wouldn't have been written.
326              
327             =head1 AUTHOR
328              
329             Toni Prug
330              
331             =head1 COPYRIGHT
332              
333             Copyright (c) 2006. Toni Prug. All rights reserved.
334              
335             This program is free software; you can redistribute it and/or modify
336             it under the terms of the GNU General Public License as published by
337             the Free Software Foundation; either version 2 of the License, or (at
338             your option) any later version.
339              
340             This program is distributed in the hope that it will be useful, but
341             WITHOUT ANY WARRANTY; without even the implied warranty of
342             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
343             General Public License for more details.
344              
345             You should have received a copy of the GNU General Public License
346             along with this program; if not, write to the Free Software
347             Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
348             USA
349              
350             See L
351              
352             =cut