Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

596 lines
13 KiB

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