| #!/usr/bin/perl |
| #----------------------------------------------------------------------------- |
| # This program gives you low level control over an SMTP conversation. |
| # |
| # This program delivers a mail message to an SMTP server. Command line |
| # options tell what server to use and determine the commands this program |
| # sends to it. The program reads the mail message itself from |
| # Standard Input. |
| # |
| # This program does not generate headers inside the mail message (e.g. |
| # RFC 822 headers). You can use the program 'makemail' to do that. |
| # |
| # This program does not extract any envelope information from the mail |
| # message or rewrite the message in any way. |
| #----------------------------------------------------------------------------- |
| |
| use strict; |
| use warnings; |
| |
| use Net::SMTP; |
| use Getopt::Long; |
| use Sys::Hostname; |
| use Data::Dumper; |
| |
| my $TRUE = 1; |
| my $FALSE = 0; |
| |
| |
| sub getSender($) { |
| my ($fromOpt) = @_; |
| |
| my $retval; |
| |
| if (defined($fromOpt)) { |
| $retval = $fromOpt; |
| } else { |
| my $user = $ENV{"USER"} || $ENV{"LOGNAME"}; |
| if (!defined("$user")) { |
| die("You didn't supply a sender address with " . |
| "--from and I cannot " . |
| "default one because neither USER nor LOGNAME environment " . |
| "variables is set."); |
| } else { |
| my $hostname = hostname; |
| if (defined($hostname)) { |
| $retval = "$user\@$hostname"; |
| } else { |
| $retval = $user; |
| } |
| } |
| } |
| return $retval; |
| } |
| |
| |
| ############################################################################## |
| # MAINLINE |
| ############################################################################## |
| |
| my %options; |
| |
| $options{"to"} = []; # Establish as an array reference |
| |
| GetOptions(\%options, |
| "to=s", |
| "from=s", |
| "server=s", |
| "hello=s", |
| "timeout=i", |
| "quiet", |
| "debug" |
| ); |
| |
| if ($options{"debug"}) { |
| Net::SMTP->debug(1); |
| } |
| |
| if (@{$options{"to"}} == 0) { |
| die("Must specify the recipient email address with --to"); |
| } |
| |
| my @recipients = @{$options{"to"}}; |
| #print Data::Dumper->Dump([ \@recipients ], [ "recipients" ]); |
| |
| my $sender = getSender($options{"from"}); |
| |
| my $server = $options{"server"} || "localhost"; |
| |
| my @smtpOptions = (); # initial value |
| if (defined($options{"hello"})) { |
| push(@smtpOptions, Hello => $options{"hello"}); |
| } |
| if (defined($options{"timeout"})) { |
| push(@smtpOptions, Timeout => $options{"timeout"}); |
| } |
| if ($options{"debug"}) { |
| push(@smtpOptions, Debug => 1); |
| } |
| |
| my $smtp = Net::SMTP->new($server, @smtpOptions); |
| |
| if (!defined($smtp)) { |
| die("Failed to connect to SMTP server at '$server'"); |
| } |
| |
| if (!$options{"quiet"}) { |
| print("Server at $server identifies as '" . $smtp->domain . "' " . |
| "and says:\n"); |
| print $smtp->banner; |
| print ("\n"); |
| print ("Reading mail message from Standard Input...\n"); |
| } |
| |
| my $result = $smtp->mail($sender); |
| if (!$result) { |
| warn("Failed sending MAIL command. " . |
| "Server says '" . $smtp->message . "'"); |
| } else { |
| my $rcptError; |
| foreach my $recipient (@recipients) { |
| my $result = $smtp->recipient($recipient); |
| if (!$result) { |
| warn("Failed sending RCPT command for '$recipient'. " . |
| "Server says '" . $smtp->message . "'"); |
| $rcptError = $TRUE; |
| } |
| } |
| if ($rcptError) { |
| $smtp->quit; |
| die("send error"); |
| } else { |
| my @message = <STDIN>; |
| |
| my $result = $smtp->data(@message); |
| |
| if (!$result) { |
| warn("Server rejected message. " . |
| "Server says '" . $smtp->message . "'"); |
| $smtp->quit; |
| die("rejected"); |
| } else { |
| $smtp->quit; |
| if (!$options{"quiet"}) { |
| my $recipientDesc; |
| if (@recipients == 1) { |
| $recipientDesc = $recipients[0]; |
| } else { |
| $recipientDesc = scalar(@recipients) . " recipients"; |
| } |
| print("Message sent to $recipientDesc from $sender.\n"); |
| } |
| } |
| } |
| } |