blob: b314b2f547f39d51c69098650570d310326e9966 [file] [log] [blame]
#!/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");
}
}
}
}