use Mail::Sendmail;
%mail = ( To => 'you@there.com', From => 'me@here.com', Message => "This is a minimalistic message" );
if (sendmail %mail) { print "Mail sent OK.\n" } else { print "Error sending mail: $Mail::Sendmail::error \n" }
print STDERR "\n\$Mail::Sendmail::log says:\n", $Mail::Sendmail::log;
After struggling for some time with various command-line mailing programs which never did exactly what I wanted, I put together this Perl only solution.
Mail::Sendmail contains mainly &sendmail, which takes a hash with the message to send and sends it...
- At the top of Sendmail.pm, set your default SMTP server
- MIME::QuotedPrint is strongly recommended. It's in the MIME-Base64 package. Get it from http://www.perl.com/CPAN/modules/by-module/MIME. It is used by default on every message, and is needed to send accented characters safely.
- Bcc: and Cc: support
- Doesn't send unwanted headers
- Allows you to send any header you want
- Doesn't abort sending if there is a bad recipient address among other good ones
- Returns verbose error messages
- Adds the Date header if you don't supply your own
- Automatic Time Zone detection (hopefully)
Not tested in a situation where the server goes down during session
The SMTP server has to be set manually in Sendmail.pm or in your script, unless you can live with the default (Compuserve's smpt.site1.csi.com).
I couldn't test the automatic time zone detection much. If it doesn't work, set it manually (see below) and please let me know.
sendmail(%mail) || print "Error sending mail: $Mail::Sendmail::error\n";
- takes a hash containing the full message, with keys for all headers, Body, and optionally for another non-default SMTP server and/or Port. (The Body part can be called ``Body'', ``Message'' or ``Text'')
- returns 1 on success, 0 on error.
updates $Mail::Sendmail::error
and $Mail::Sendmail::log
.
Keys are not case-sensitive. They get normalized before use with
ucfirst( lc $key )
. The colon after headers is not necessary.
The following headers are added unless you specify them yourself:
Mime-version: 1.0 Content-type: 'text/plain; charset="iso-8859-1"'
Content-transfer-encoding: quoted-printable or (if MIME::QuotedPrint not installed) Content-transfer-encoding: 8bit Date: [string returned by time_to_date()]
If you put an 'X-mailer' header, the package version number is appended to it.
time()
) to a string suitable for the Date header as per RFC 822. See also
$Mail::Sendmail::TZ.
Example: $rx = $Mail::Sendmail::address_rx; if (/$rx/) { $address=$1; $user=$2; $domain=$3; }
time()
and gmtime(),
unless it has been preset in
Sendmail.pm.
If it doesn't work for you, let me know so I can try to fix it, and in the meantime, set it manually in RFC 822 compliant format:
$Mail::Sendmail::TZ = "+0200"; # Western Europe in summer
You can override the default in a particular script with:
$Mail::Sendmail::default_smtp_server = 'newserver.my-domain.com';
or just for a particular message by adding it to your %message
hash with a key of 'Smtp':
$message{Smtp} = 'newserver.my-domain.com';
Or override it for a particular script with:
$Mail::Sendmail::default_smtp_port = 8025;
or just for a particular message by adding it to your %message
hash with a key of 'Port':
$message{Port} = 8025;
use Mail::Sendmail;
print STDERR "Testing Mail::Sendmail version $Mail::Sendmail::VERSION\n"; print STDERR "smtp server: $Mail::Sendmail::default_smtp_server\n"; print STDERR "server port: $Mail::Sendmail::default_smtp_port\n";
$Mail::Sendmail::default_sender = 'This is me <myself@here.com>'; %mail = ( #To => 'No to field this time, only Bcc and Cc', #From => 'not needed, use default', Bcc => 'Someone <him@there.com>, Someone else her@there.com', # only addresses are extracted from Bcc, real names disregarded Cc => 'Yet someone else <xz@whatever.com>', # Cc will appear in the header. (Bcc will not) Subject => 'Test message', 'X-Mailer' => "Mail::Sendmail", );
$mail{Smtp} = 'special_server.for-this-message-only.domain.com'; $mail{'X-custom'} = 'My custom additionnal header'; $mail{message} = "Only a short message"; $mail{Date} = Mail::Sendmail::time_to_date( time() - 86400 ), # cheat on the date
if (sendmail %mail) { print "Mail sent OK.\n" } else { print "Error sending mail: $Mail::Sendmail::error \n" }
print STDERR "\n\$Mail::Sendmail::log says:\n", $Mail::Sendmail::log;
0.72: Fixed line endings in Body to ``\r\n''. MIME quoted printable encoding is now automatic if needed. Test script can now run unattended.
0.71: Fixed Time Zone bug with AS port. Added half-hour Time Zone support. Repackaged with \n line endings instead of \r\n.
You can use it freely.
I would appreciate a short (or long) e-mail note if you do (and even if you don't, especially if you care to say why). And of course, bug-reports and/or suggestions are welcome.
This version has been tested on Win95 and WinNT 4.0 with Perl 5.003_07 (AS 313) and Perl 5.004_02 (GS), and on Linux 2.0.34 (Red Hat 5.1) with 5.004_04.
Last revision: 13.07.98. Latest version should be available at http://alma.ch/perl/mail.htm, and a few days later on CPAN.