File Coverage

blib/lib/Mail/SendEasy/SMTP.pm
Criterion Covered Total %
statement 27 189 14.2
branch 0 120 0.0
condition 0 82 0.0
subroutine 9 31 29.0
pod 11 22 50.0
total 47 444 10.5


line stmt bran cond sub pod time code
1             #############################################################################
2             ## This file was generated automatically by Class::HPLOO/0.12
3             ##
4             ## Original file: ./lib/Mail/SendEasy/SMTP.hploo
5             ## Generation date: 2004-04-09 04:49:29
6             ##
7             ## ** Do not change this file, use the original HPLOO source! **
8             #############################################################################
9            
10             #############################################################################
11             ## Name: SMTP.pm
12             ## Purpose: Mail::SendEasy::SMTP
13             ## Author: Graciliano M. P.
14             ## Modified by:
15             ## Created: 2004-01-23
16             ## RCS-ID:
17             ## Copyright: (c) 2004 Graciliano M. P.
18             ## Licence: This program is free software; you can redistribute it and/or
19             ## modify it under the same terms as Perl itself
20             #############################################################################
21            
22            
23             { package Mail::SendEasy::SMTP ;
24            
25 1     1   5 use strict qw(vars) ; no warnings ;
  1     1   2  
  1         33  
  1         6  
  1         2  
  1         55  
26            
27             my (%CLASS_HPLOO) ;
28            
29             sub new {
30 0     0 1   my $class = shift ;
31 0           my $this = bless({} , $class) ;
32 1     1   5 no warnings ;
  1         1  
  1         285  
33 0           my $undef = \'' ;
34 0     0 0   sub UNDEF {$undef} ;
35 0 0         if ( $CLASS_HPLOO{ATTR} ) {
36 0           foreach my $Key ( keys %{$CLASS_HPLOO{ATTR}} ) {
  0            
37 0 0         tie( $this->{$Key} => 'Class::HPLOO::TIESCALAR' , $CLASS_HPLOO{ATTR}{$Key}{tp} , $CLASS_HPLOO{ATTR}{$Key}{pr} , \$this->{CLASS_HPLOO_ATTR}{$Key} ) if !exists $this->{$Key} ;
38 0 0         } } my $ret_this = defined &SMTP ? $this->SMTP(@_) : undef ;
39 0 0 0       if ( ref($ret_this) && UNIVERSAL::isa($ret_this,$class) ) {
    0          
40 0           $this = $ret_this ;
41 0 0 0       if ( $CLASS_HPLOO{ATTR} && UNIVERSAL::isa($this,'HASH') ) {
42 0           foreach my $Key ( keys %{$CLASS_HPLOO{ATTR}} ) {
  0            
43 0 0         tie( $this->{$Key} => 'Class::HPLOO::TIESCALAR' , $CLASS_HPLOO{ATTR}{$Key}{tp} , $CLASS_HPLOO{ATTR}{$Key}{pr} , \$this->{CLASS_HPLOO_ATTR}{$Key} ) if !exists $this->{$Key} ;
44             } } } elsif ( $ret_this == $undef ) {
45 0           $this = undef ;
46 0           } return $this ;
47             }
48            
49            
50 1     1   824 use IO::Socket ;
  1         25186  
  1         4  
51 1     1   3572 use IO::Select ;
  1         9169  
  1         105  
52            
53 1     1   1153 use Mail::SendEasy::AUTH ;
  1         4  
  1         62  
54 1     1   934 use Mail::SendEasy::Base64 ;
  1         3  
  1         66  
55            
56 1     1   6 no warnings ;
  1         2  
  1         32  
57            
58 1     1   3 use vars qw($VERSION) ;
  1         2  
  1         3751  
59             $VERSION = '0.01' ;
60            
61             sub SMTP {
62 0 0 0 0 0   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
63 0           my $host = shift(@_) ;
64 0           my $port = shift(@_) ;
65 0           my $timeout = shift(@_) ;
66 0           my $user = shift(@_) ;
67 0           my $pass = shift(@_) ;
68 0           my $from_sendeasy = shift(@_) ;
69            
70 0           $this->{HOST} = $host ;
71 0   0       $this->{PORT} = $port || 25 ;
72 0   0       $this->{TIMEOUT} = $timeout || 120 ;
73 0           $this->{USER} = $user ;
74 0           $this->{PASS} = $pass ;
75            
76 0 0         $this->{SENDEASY} = 1 if $from_sendeasy ;
77            
78 0 0         for (1..2) { last if $this->connect($_) ;}
  0            
79            
80 0 0         return UNDEF if !$this->{SOCKET} ;
81             }
82            
83             sub connect {
84 0 0 0 0 1   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
85 0           my $n = shift(@_) ;
86            
87 0           my $sock = new IO::Socket::INET(
88             PeerAddr => $this->{HOST} ,
89             PeerPort => $this->{PORT} ,
90             Proto => 'tcp' ,
91             Timeout => $this->{TIMEOUT} ,
92             ) ;
93            
94 0 0         if (!$sock) {
95 0 0 0       $this->warn("ERROR: Can't connect to $this->{HOST}:$this->{PORT}\n") if (!$n || $n > 1) ;
96 0           return ;
97             }
98            
99 0           $sock->autoflush(1) ;
100 0           $this->{SOCKET} = $sock ;
101            
102 0 0         if ( $this->response !~ /^2/ ) {
103 0 0 0       $this->close("ERROR: Connection error on host $this->{HOST}:$this->{PORT}\n") if (!$n || $n > 1) ;
104 0           return ;
105             }
106            
107 0 0         if ( $this->EHLO('main') !~ /^2/ ) {
108 0           $this->close("ERROR: Error on EHLO") ;
109 0           return ;
110             }
111             else {
112 0           my @response = $this->last_response ;
113 0           foreach my $response_i ( @response ) {
114 0 0         next if $$response_i[0] !~ /^2/ ;
115 0           my ($key , $val) = ( $$response_i[1] =~ /^(\S+)\s*(.*)/s );
116 0           $this->{INF}{$key} = $val ;
117             }
118             }
119            
120 0           return 1 ;
121             }
122            
123             sub is_connected {
124 0 0 0 0 0   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
125            
126 0 0 0       return 1 if $this->{SOCKET} && $this->{SOCKET}->connected ;
127 0           return undef ;
128             }
129            
130             sub auth_types {
131 0 0 0 0 1   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
132            
133 0           my @types = split(/\s+/s , $this->{INF}{AUTH}) ;
134 0           return @types ;
135             }
136            
137             sub auth {
138 0 0 0 0 1   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
139 0           my $user = shift(@_) ;
140 0           my $pass = shift(@_) ;
141 0           my @types = @_ ;
142 0           @_ = () ;
143            
144 0 0         $user = $this->{USER} if $user eq '' ;
145 0 0         $pass = $this->{PASS} if $pass eq '' ;
146 0 0         @types = $this->auth_types if !@types ;
147            
148 0           my $auth = Mail::SendEasy::AUTH->new($user , $pass , @types) ;
149            
150 0 0 0       if ( $auth && $this->AUTH( $auth->type ) =~ /^3/ ) {
151 0 0         if ( my $init = $auth->start ) {
152 0           $this->cmd(encode_base64($init, '')) ;
153 0 0         return 1 if $this->response == 235 ;
154             }
155            
156 0           my @response = $this->last_response ;
157            
158 0           while ( $response[0][0] == 334 ) {
159 0           my $message = decode_base64( $response[0][1] ) ;
160 0           my $return = $auth->step($message) ;
161 0           $this->cmd(encode_base64($return, '')) ;
162 0           @response = $this->response ;
163 0 0         return 1 if $response[0][0] == 235 ;
164 0 0         last if $response[0][0] == 535 ;
165             }
166             }
167            
168 0           $this->warn("Authentication error!\n") ;
169            
170 0           return undef ;
171             }
172            
173 0 0 0 0 0   sub EHLO { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; $this->cmd("EHLO",@_) ; $this->response ;}
  0            
  0            
174 0 0 0 0 0   sub AUTH { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; $this->cmd("AUTH",@_) ; $this->response ;}
  0            
  0            
175            
176 0 0 0 0 0   sub MAIL { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; $this->cmd("MAIL",@_) ; $this->response ;}
  0            
  0            
177 0 0 0 0 0   sub RCPT { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; $this->cmd("RCPT",@_) ; $this->response ;}
  0            
  0            
178            
179 0 0 0 0 0   sub DATA { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; $this->cmd("DATA") ; $this->response ;}
  0            
  0            
180 0 0 0 0 0   sub DATAEND { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; $this->cmd(".") ; $this->response ;}
  0            
  0            
181            
182 0 0 0 0 0   sub QUIT { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; $this->cmd("QUIT") ; return wantarray ? [200,''] : 200 ;}
  0 0          
  0            
183            
184             sub close {
185 0 0 0 0 1   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
186 0           my $error = shift(@_) ;
187            
188 0 0         $this->warn($error) if $error ;
189 0 0         return if !$this->{SOCKET} ;
190 0           $this->QUIT ;
191 0           close( delete $this->{SOCKET} ) ;
192             }
193            
194             sub warn {
195 0 0 0 0 0   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
196 0           my $error = shift(@_) ;
197            
198 0 0         return if !$error ;
199 0 0         if ( $this->{SENDEASY} ) { Mail::SendEasy::warn($error) ;}
  0            
200 0           else { warn($error) ;}
201             }
202            
203             sub print {
204 0 0 0 0 1   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
205 0           my $data = shift(@_) ;
206            
207 0 0         $this->connect if !$this->is_connected ;
208 0 0         return if !$this->{SOCKET} ;
209 0           my $sock = $this->{SOCKET} ;
210 0           print $sock $data ;
211             }
212            
213             sub cmd {
214 0 0 0 0 1   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
215 0           my @cmds = @_ ;
216 0           @_ = () ;
217            
218 0 0         $this->connect if !$this->is_connected ;
219 0 0         return if !$this->{SOCKET} ;
220 0           my $sock = $this->{SOCKET} ;
221 0           my $cmd = join(" ", @cmds) ;
222 0           $cmd =~ s/[\r\n]+$//s ;
223 0           $cmd =~ s/(?:\r\n?|\n)/ /gs ;
224 0           $cmd .= "\015\012" ;
225 0           print $sock $cmd ;
226             }
227            
228             sub response {
229 0 0 0 0 1   my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ;
230            
231 0 0         $this->connect if !$this->is_connected ;
232 0 0         return if !$this->{SOCKET} ;
233 0           local($/) ; $/ = "\n" ;
  0            
234 0           my $sock = $this->{SOCKET} ;
235            
236 0           my $sel = IO::Select->new($sock) ;
237            
238            
239 0           my ($line , @lines) ;
240            
241 0 0         if ( $sel->can_read( $this->{TIMEOUT} ) ) {
242 0           while(1) {
243 0           chomp($line = <$sock>) ;
244 0           my ($code , $more , $msg) = ( $line =~ /^(\d+)(.?)(.*)/s ) ;
245 0           $msg =~ s/\s+$//s ;
246 0           push(@lines , [$code , $msg]) ;
247 0 0         last if $more ne '-' ;
248             }
249             }
250            
251 0           $this->{LAST_RESPONSE} = \@lines ;
252            
253 0 0         return( @lines ) if wantarray ;
254 0           return $lines[0][0] ;
255            
256 0           return ;
257             }
258            
259 0 0 0 0 1   sub last_response { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; return wantarray ? @{$this->{LAST_RESPONSE}} : @{$this->{LAST_RESPONSE}}[0]->[0] } ;
  0 0          
  0            
  0            
260            
261 0 0 0 0 1   sub last_response_msg { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; @{$this->{LAST_RESPONSE}}[0]->[1] } ;
  0            
  0            
262            
263 0 0 0 0 1   sub last_response_line { my $this = ref($_[0]) && UNIVERSAL::isa($_[0],'UNIVERSAL') ? shift : undef ; @{$this->{LAST_RESPONSE}}[0]->[0] . " " . @{$this->{LAST_RESPONSE}}[0]->[1] } ;
  0            
  0            
  0            
264            
265            
266             }
267            
268            
269            
270             1;
271            
272             __END__