This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Add a note about the dangers of bad UTF-8.
[perl5.git] / lib / Net / SMTP.pm
CommitLineData
406c51ee
JH
1# Net::SMTP.pm
2#
3# Copyright (c) 1995-1997 Graham Barr <gbarr@pobox.com>. All rights reserved.
4# This program is free software; you can redistribute it and/or
5# modify it under the same terms as Perl itself.
6
7package Net::SMTP;
8
9require 5.001;
10
11use strict;
12use vars qw($VERSION @ISA);
13use Socket 1.3;
14use Carp;
15use IO::Socket;
16use Net::Cmd;
17use Net::Config;
18
302c2e6b 19$VERSION = "2.17"; # $Id: //depot/libnet/Net/SMTP.pm#17 $
406c51ee
JH
20
21@ISA = qw(Net::Cmd IO::Socket::INET);
22
23sub new
24{
25 my $self = shift;
26 my $type = ref($self) || $self;
27 my $host = shift if @_ % 2;
28 my %arg = @_;
29 my $hosts = defined $host ? [ $host ] : $NetConfig{smtp_hosts};
30 my $obj;
31
32 my $h;
33 foreach $h (@{$hosts})
34 {
35 $obj = $type->SUPER::new(PeerAddr => ($host = $h),
36 PeerPort => $arg{Port} || 'smtp(25)',
37 Proto => 'tcp',
38 Timeout => defined $arg{Timeout}
39 ? $arg{Timeout}
40 : 120
41 ) and last;
42 }
43
44 return undef
45 unless defined $obj;
46
47 $obj->autoflush(1);
48
49 $obj->debug(exists $arg{Debug} ? $arg{Debug} : undef);
50
51 unless ($obj->response() == CMD_OK)
52 {
53 $obj->close();
54 return undef;
55 }
56
57 ${*$obj}{'net_smtp_host'} = $host;
58
59 (${*$obj}{'net_smtp_banner'}) = $obj->message;
60 (${*$obj}{'net_smtp_domain'}) = $obj->message =~ /\A\s*(\S+)/;
61
62 unless($obj->hello($arg{Hello} || ""))
63 {
64 $obj->close();
65 return undef;
66 }
67
68 $obj;
69}
70
71##
72## User interface methods
73##
74
75sub banner
76{
77 my $me = shift;
78
79 return ${*$me}{'net_smtp_banner'} || undef;
80}
81
82sub domain
83{
84 my $me = shift;
85
86 return ${*$me}{'net_smtp_domain'} || undef;
87}
88
89sub etrn {
90 my $self = shift;
91 defined($self->supports('ETRN',500,["Command unknown: 'ETRN'"])) &&
92 $self->_ETRN(@_);
93}
94
95sub hello
96{
97 my $me = shift;
98 my $domain = shift ||
99 eval {
100 require Net::Domain;
101 Net::Domain::hostfqdn();
102 } ||
103 "";
104 my $ok = $me->_EHLO($domain);
105 my @msg = $me->message;
106
107 if($ok)
108 {
109 my $h = ${*$me}{'net_smtp_esmtp'} = {};
110 my $ln;
111 foreach $ln (@msg) {
686337f3 112 $h->{uc $1} = $2
406c51ee
JH
113 if $ln =~ /(\S+)\b[ \t]*([^\n]*)/;
114 }
115 }
116 elsif($me->status == CMD_ERROR)
117 {
118 @msg = $me->message
119 if $ok = $me->_HELO($domain);
120 }
121
302c2e6b 122 $ok && $msg[0] =~ /\A\s*(\S+)/
406c51ee
JH
123 ? $1
124 : undef;
125}
126
127sub supports {
128 my $self = shift;
129 my $cmd = uc shift;
130 return ${*$self}{'net_smtp_esmtp'}->{$cmd}
131 if exists ${*$self}{'net_smtp_esmtp'}->{$cmd};
132 $self->set_status(@_)
133 if @_;
134 return;
135}
136
137sub _addr
138{
139 my $addr = shift || "";
140
141 return $1
142 if $addr =~ /(<[^>]+>)/so;
143
144 $addr =~ s/\n/ /sog;
145 $addr =~ s/(\A\s+|\s+\Z)//sog;
146
147 return "<" . $addr . ">";
148}
149
150
151sub mail
152{
153 my $me = shift;
154 my $addr = _addr(shift);
155 my $opts = "";
156
157 if(@_)
158 {
159 my %opt = @_;
160 my($k,$v);
161
162 if(exists ${*$me}{'net_smtp_esmtp'})
163 {
164 my $esmtp = ${*$me}{'net_smtp_esmtp'};
165
166 if(defined($v = delete $opt{Size}))
167 {
168 if(exists $esmtp->{SIZE})
169 {
170 $opts .= sprintf " SIZE=%d", $v + 0
171 }
172 else
173 {
174 carp 'Net::SMTP::mail: SIZE option not supported by host';
175 }
176 }
177
178 if(defined($v = delete $opt{Return}))
179 {
180 if(exists $esmtp->{DSN})
181 {
182 $opts .= " RET=" . uc $v
183 }
184 else
185 {
186 carp 'Net::SMTP::mail: DSN option not supported by host';
187 }
188 }
189
190 if(defined($v = delete $opt{Bits}))
191 {
192 if(exists $esmtp->{'8BITMIME'})
193 {
194 $opts .= $v == 8 ? " BODY=8BITMIME" : " BODY=7BIT"
195 }
196 else
197 {
198 carp 'Net::SMTP::mail: 8BITMIME option not supported by host';
199 }
200 }
201
202 if(defined($v = delete $opt{Transaction}))
203 {
204 if(exists $esmtp->{CHECKPOINT})
205 {
206 $opts .= " TRANSID=" . _addr($v);
207 }
208 else
209 {
210 carp 'Net::SMTP::mail: CHECKPOINT option not supported by host';
211 }
212 }
213
214 if(defined($v = delete $opt{Envelope}))
215 {
216 if(exists $esmtp->{DSN})
217 {
218 $v =~ s/([^\041-\176]|=|\+)/sprintf "+%02x", ord($1)/sge;
219 $opts .= " ENVID=$v"
220 }
221 else
222 {
223 carp 'Net::SMTP::mail: DSN option not supported by host';
224 }
225 }
226
227 carp 'Net::SMTP::recipient: unknown option(s) '
228 . join(" ", keys %opt)
229 . ' - ignored'
230 if scalar keys %opt;
231 }
232 else
233 {
234 carp 'Net::SMTP::mail: ESMTP not supported by host - options discarded :-(';
235 }
236 }
237
238 $me->_MAIL("FROM:".$addr.$opts);
239}
240
241sub send { shift->_SEND("FROM:" . _addr($_[0])) }
242sub send_or_mail { shift->_SOML("FROM:" . _addr($_[0])) }
243sub send_and_mail { shift->_SAML("FROM:" . _addr($_[0])) }
244
245sub reset
246{
247 my $me = shift;
248
249 $me->dataend()
250 if(exists ${*$me}{'net_smtp_lastch'});
251
252 $me->_RSET();
253}
254
255
256sub recipient
257{
258 my $smtp = shift;
259 my $opts = "";
260 my $skip_bad = 0;
261
262 if(@_ && ref($_[-1]))
263 {
264 my %opt = %{pop(@_)};
265 my $v;
266
267 $skip_bad = delete $opt{'SkipBad'};
268
269 if(exists ${*$smtp}{'net_smtp_esmtp'})
270 {
271 my $esmtp = ${*$smtp}{'net_smtp_esmtp'};
272
273 if(defined($v = delete $opt{Notify}))
274 {
275 if(exists $esmtp->{DSN})
276 {
277 $opts .= " NOTIFY=" . join(",",map { uc $_ } @$v)
278 }
279 else
280 {
281 carp 'Net::SMTP::recipient: DSN option not supported by host';
282 }
283 }
284
285 carp 'Net::SMTP::recipient: unknown option(s) '
286 . join(" ", keys %opt)
287 . ' - ignored'
288 if scalar keys %opt;
289 }
290 elsif(%opt)
291 {
292 carp 'Net::SMTP::recipient: ESMTP not supported by host - options discarded :-(';
293 }
294 }
295
296 my @ok;
297 my $addr;
298 foreach $addr (@_)
299 {
300 if($smtp->_RCPT("TO:" . _addr($addr) . $opts)) {
301 push(@ok,$addr) if $skip_bad;
302 }
303 elsif(!$skip_bad) {
304 return 0;
305 }
306 }
307
308 return $skip_bad ? @ok : 1;
309}
310
686337f3
JH
311BEGIN {
312 *to = \&recipient;
313 *cc = \&recipient;
314 *bcc = \&recipient;
315}
406c51ee
JH
316
317sub data
318{
319 my $me = shift;
320
321 my $ok = $me->_DATA() && $me->datasend(@_);
322
323 $ok && @_ ? $me->dataend
324 : $ok;
325}
326
327sub expand
328{
329 my $me = shift;
330
331 $me->_EXPN(@_) ? ($me->message)
332 : ();
333}
334
335
336sub verify { shift->_VRFY(@_) }
337
338sub help
339{
340 my $me = shift;
341
342 $me->_HELP(@_) ? scalar $me->message
343 : undef;
344}
345
346sub quit
347{
348 my $me = shift;
349
350 $me->_QUIT;
351 $me->close;
352}
353
354sub DESTROY
355{
356# ignore
357}
358
359##
360## RFC821 commands
361##
362
363sub _EHLO { shift->command("EHLO", @_)->response() == CMD_OK }
364sub _HELO { shift->command("HELO", @_)->response() == CMD_OK }
365sub _MAIL { shift->command("MAIL", @_)->response() == CMD_OK }
366sub _RCPT { shift->command("RCPT", @_)->response() == CMD_OK }
367sub _SEND { shift->command("SEND", @_)->response() == CMD_OK }
368sub _SAML { shift->command("SAML", @_)->response() == CMD_OK }
369sub _SOML { shift->command("SOML", @_)->response() == CMD_OK }
370sub _VRFY { shift->command("VRFY", @_)->response() == CMD_OK }
371sub _EXPN { shift->command("EXPN", @_)->response() == CMD_OK }
372sub _HELP { shift->command("HELP", @_)->response() == CMD_OK }
373sub _RSET { shift->command("RSET")->response() == CMD_OK }
374sub _NOOP { shift->command("NOOP")->response() == CMD_OK }
375sub _QUIT { shift->command("QUIT")->response() == CMD_OK }
376sub _DATA { shift->command("DATA")->response() == CMD_MORE }
377sub _TURN { shift->unsupported(@_); }
378sub _ETRN { shift->command("ETRN", @_)->response() == CMD_OK }
379
3801;
381
382__END__
383
384=head1 NAME
385
386Net::SMTP - Simple Mail Transfer Protocol Client
387
388=head1 SYNOPSIS
389
390 use Net::SMTP;
686337f3 391
406c51ee
JH
392 # Constructors
393 $smtp = Net::SMTP->new('mailhost');
394 $smtp = Net::SMTP->new('mailhost', Timeout => 60);
395
396=head1 DESCRIPTION
397
398This module implements a client interface to the SMTP and ESMTP
399protocol, enabling a perl5 application to talk to SMTP servers. This
400documentation assumes that you are familiar with the concepts of the
401SMTP protocol described in RFC821.
402
403A new Net::SMTP object must be created with the I<new> method. Once
404this has been done, all SMTP commands are accessed through this object.
405
406The Net::SMTP class is a subclass of Net::Cmd and IO::Socket::INET.
407
408=head1 EXAMPLES
409
410This example prints the mail domain name of the SMTP server known as mailhost:
411
412 #!/usr/local/bin/perl -w
686337f3 413
406c51ee 414 use Net::SMTP;
686337f3 415
406c51ee
JH
416 $smtp = Net::SMTP->new('mailhost');
417 print $smtp->domain,"\n";
418 $smtp->quit;
419
420This example sends a small message to the postmaster at the SMTP server
421known as mailhost:
422
423 #!/usr/local/bin/perl -w
686337f3 424
406c51ee 425 use Net::SMTP;
686337f3 426
406c51ee 427 $smtp = Net::SMTP->new('mailhost');
686337f3 428
406c51ee
JH
429 $smtp->mail($ENV{USER});
430 $smtp->to('postmaster');
686337f3 431
406c51ee
JH
432 $smtp->data();
433 $smtp->datasend("To: postmaster\n");
434 $smtp->datasend("\n");
435 $smtp->datasend("A simple test message\n");
436 $smtp->dataend();
686337f3 437
406c51ee
JH
438 $smtp->quit;
439
440=head1 CONSTRUCTOR
441
442=over 4
443
444=item new Net::SMTP [ HOST, ] [ OPTIONS ]
445
446This is the constructor for a new Net::SMTP object. C<HOST> is the
447name of the remote host to which a SMTP connection is required.
448
449If C<HOST> is not given, then the C<SMTP_Host> specified in C<Net::Config>
450will be used.
451
452C<OPTIONS> are passed in a hash like fashion, using key and value pairs.
453Possible options are:
454
455B<Hello> - SMTP requires that you identify yourself. This option
456specifies a string to pass as your mail domain. If not
457given a guess will be taken.
458
459B<Timeout> - Maximum time, in seconds, to wait for a response from the
460SMTP server (default: 120)
461
462B<Debug> - Enable debugging information
463
464
465Example:
466
467
468 $smtp = Net::SMTP->new('mailhost',
469 Hello => 'my.mail.domain'
470 Timeout => 30,
471 Debug => 1,
472 );
473
686337f3
JH
474=back
475
406c51ee
JH
476=head1 METHODS
477
478Unless otherwise stated all methods return either a I<true> or I<false>
479value, with I<true> meaning that the operation was a success. When a method
480states that it returns a value, failure will be returned as I<undef> or an
481empty list.
482
483=over 4
484
485=item banner ()
486
487Returns the banner message which the server replied with when the
488initial connection was made.
489
490=item domain ()
491
492Returns the domain that the remote SMTP server identified itself as during
493connection.
494
495=item hello ( DOMAIN )
496
497Tell the remote server the mail domain which you are in using the EHLO
498command (or HELO if EHLO fails). Since this method is invoked
499automatically when the Net::SMTP object is constructed the user should
500normally not have to call it manually.
501
502=item etrn ( DOMAIN )
503
504Request a queue run for the DOMAIN given.
505
506=item mail ( ADDRESS [, OPTIONS] )
507
508=item send ( ADDRESS )
509
510=item send_or_mail ( ADDRESS )
511
512=item send_and_mail ( ADDRESS )
513
514Send the appropriate command to the server MAIL, SEND, SOML or SAML. C<ADDRESS>
515is the address of the sender. This initiates the sending of a message. The
516method C<recipient> should be called for each address that the message is to
517be sent to.
518
519The C<mail> method can some additional ESMTP OPTIONS which is passed
520in hash like fashion, using key and value pairs. Possible options are:
521
522 Size => <bytes>
523 Return => <???>
524 Bits => "7" | "8"
525 Transaction => <ADDRESS>
526 Envelope => <ENVID>
527
528
529=item reset ()
530
531Reset the status of the server. This may be called after a message has been
532initiated, but before any data has been sent, to cancel the sending of the
533message.
534
535=item recipient ( ADDRESS [, ADDRESS [ ...]] [, OPTIONS ] )
536
537Notify the server that the current message should be sent to all of the
538addresses given. Each address is sent as a separate command to the server.
539Should the sending of any address result in a failure then the
540process is aborted and a I<false> value is returned. It is up to the
541user to call C<reset> if they so desire.
542
543The C<recipient> method can some additional OPTIONS which is passed
544in hash like fashion, using key and value pairs. Possible options are:
545
546 Notify =>
547 SkipBad => ignore bad addresses
548
549If C<SkipBad> is true the C<recipient> will not return an error when a
550bad address is encountered and it will return an array of addresses
551that did succeed.
552
686337f3
JH
553 $smtp->recipient($recipient1,$recipient2); # Good
554 $smtp->recipient($recipient1,$recipient2, { SkipBad => 1 }); # Good
555 $smtp->recipient("$recipient,$recipient2"); # BAD
556
406c51ee
JH
557=item to ( ADDRESS [, ADDRESS [...]] )
558
686337f3
JH
559=item cc ( ADDRESS [, ADDRESS [...]] )
560
561=item bcc ( ADDRESS [, ADDRESS [...]] )
562
563Synonyms for C<recipient>.
406c51ee
JH
564
565=item data ( [ DATA ] )
566
567Initiate the sending of the data from the current message.
568
569C<DATA> may be a reference to a list or a list. If specified the contents
570of C<DATA> and a termination string C<".\r\n"> is sent to the server. And the
571result will be true if the data was accepted.
572
573If C<DATA> is not specified then the result will indicate that the server
574wishes the data to be sent. The data must then be sent using the C<datasend>
575and C<dataend> methods described in L<Net::Cmd>.
576
577=item expand ( ADDRESS )
578
579Request the server to expand the given address Returns an array
580which contains the text read from the server.
581
582=item verify ( ADDRESS )
583
584Verify that C<ADDRESS> is a legitimate mailing address.
585
586=item help ( [ $subject ] )
587
588Request help text from the server. Returns the text or undef upon failure
589
590=item quit ()
591
592Send the QUIT command to the remote SMTP server and close the socket connection.
593
594=back
595
596=head1 SEE ALSO
597
598L<Net::Cmd>
599
600=head1 AUTHOR
601
602Graham Barr <gbarr@pobox.com>
603
604=head1 COPYRIGHT
605
606Copyright (c) 1995-1997 Graham Barr. All rights reserved.
607This program is free software; you can redistribute it and/or modify
608it under the same terms as Perl itself.
609
686337f3
JH
610=for html <hr>
611
302c2e6b 612I<$Id: //depot/libnet/Net/SMTP.pm#17 $>
686337f3 613
406c51ee 614=cut