#!/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 = ; 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"); } } } }