Mail::Sendmail FAQ

This is a little FAQ for the Mail::Sendmail Perl 5 module. It contains stuff related to the module, but which I felt shouldn't be in the POD documentation inside the module itself. The latest version of this FAQ is at alma.ch/perl/Mail-Sendmail-FAQ.htm. It pertains to versions 0.75 or higher of Mail::Sendmail.


Does Mail::Sendmail need a command-line sendmail?

No. It communicates directly with any local or remote SMTP server using only Perl sockets. This was actually it's primary "raison d'être".

Why is it called Mail::Sendmail if it has nothing to do with Unix sendmail?

Because that was available in the Mail:: namespace. Mail::Simple may have been better, but it's too late now...

Which operating systems and Perl versions are supported?

Any OS and any Perl 5 should work. Let me know if you find a Perl version or OS on which it does not.

Since the standard test script sends me a mail containing $[ (the Perl version) and $^O (the OS name), I occasionally recompile the following list of systems and Perl versions on which the module definitely worked:

Perl versions seen with versions 0.78 or 0.79:
5.003, 5.00302, 5.00307,
5.004, 5.00401, 5.00402, 5.00403, 5.00404, 5.00405, 5.00463,
5.005, 5.00501, 5.00502, 5.00503, 5.00504, 5.00551, 5.00554, 5.00556, 5.00557, 5.00562, 5.00563, 5.00566,
5.006, 5.00600000, 5.006001, 5.006002,
5.007, 5.007001, 5.007002, 5.007003,
5.008, 5.008001, 5.008002, 5.008003, 5.008004, 5.008005, 5.008006,
5.009, 5.009001, 5.009002, 5.009003

Operating systems seen with versions 0.78 or 0.79:
aix, bsdos, cygwin, darwin, dec_osf, dgux, dynixptx, freebsd, hpux, interix, irix, linux, machten, MacOS, mpeix, MSWin32, netbsd, NetWare, nto, openbsd, openunix, qnx, rhapsody, sco, sco3, sco507, solaris, sunos, svr4, svr5, unicos, uwin

Missing form Perl versions: anything before 5.003. Missing from OSes: Amiga and BeOS. Is it because nobody tried? For BeOS, I have heard the sockets parts of Perl don't work yet, which would explain it. Is that true?

How do I send mail from a CGI script?

The short answer is: just as from any normal script, or just like you do any other CGI Perl script. But if you want to know, you are probably a beginner with Perl or CGI or both. In that case, follow these steps, learning what you'll have to on the way:

  1. Run a simple script at the command line.
  2. Install Mail::Sendmail on your local machine and run a script using it at the command-line.
  3. Run a simple "Hello World" script on your web server.
  4. Install Mail::Sendmail on your web server, and go on.

A few clues for common problems for beginners on CGI scripts:

Indispensable for Perl/CGI:

How to send HTML mail?

Instead of sending your mail with a Content-type of "text/plain", you send a "multipart/alternative" MIME mail, where one part is "text/plain" (for clients which cannot display HTML) and the other is "text/html".

use MIME::QuotedPrint;
use HTML::Entities;
use Mail::Sendmail 0.75; # doesn't work with v. 0.74!

$boundary = "====" . time() . "====";

$text = "HTML mail demo\n\n"
      . "This is the message text\n"
      . "Voilà du texte qui sera encodé\n";

%mail = (
         from => 'you@domain.tld',
         to => 'whoever@someplace.tld',
         subject => 'Test HTML mail',
         'content-type' => "multipart/alternative; boundary=\"$boundary\""
        );

$plain = encode_qp $text;

$html = encode_entities($text);
$html =~ s/\n\n/\n\n<p>/g;
$html =~ s/\n/<br>\n/g;
$html = "<p><strong>" . $html . "</strong></p>";

$boundary = '--'.$boundary;

$mail{body} = <<END_OF_BODY;
$boundary
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

$plain

$boundary
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<html>$html</html>
$boundary--
END_OF_BODY

sendmail(%mail) || print "Error: $Mail::Sendmail::error\n";

If you know all the Mail clients which will get your mail are capable of displaying HTML, you could simplify it like this:

use HTML::Entities;
use Mail::Sendmail 0.75; # doesn't work with v. 0.74!

$html = <<END_HTML;
<p><strong>HTML mail demo</strong>

<p>This is the message text
<p>It will only be displayed correctly by HTML-capable Mail clients
since it has no "text/plain" alternative part.
END_HTML

$html .= "<p>" . encode_entities("Voilà du texte qui sera encodé") . "\n"
. "<pre>This is text in " . encode_entities("<pre> and <code> tags") . "</code></pre>\n"
;

%mail = (
         from => 'you@domain.tld',
         to => 'whoever@someplace.tld',
         subject => 'Test HTML mail',
         'content-type' => 'text/html; charset="iso-8859-1"',
);

$mail{body} = <<END_OF_BODY;
<html>$html</html>
END_OF_BODY

sendmail(%mail) || print "Error: $Mail::Sendmail::error\n";

How to send attachments?

In a way very similar to the HTML mail above. Be aware that you will put the whole file(s) in memory, so this method isn't suitable for very big files. For files of reasonable size though, you can adapt this example:

use MIME::QuotedPrint;
use MIME::Base64;
use Mail::Sendmail 0.75; # doesn't work with v. 0.74!

%mail = (
         from => 'you@domain.tld',
         to => 'whoever@someplace.tld',
         subject => 'Test attachment',
        );


$boundary = "====" . time() . "====";
$mail{'content-type'} = "multipart/mixed; boundary=\"$boundary\"";

$message = encode_qp( "Voilà le fichier demandé" );

$file = $^X; # This is the perl executable
open (F, $file) or die "Cannot read $file: $!";
binmode F; undef $/;
$mail{body} = encode_base64(<F>);
close F;

$boundary = '--'.$boundary;
$mail{body} = <<END_OF_BODY;
$boundary
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

$message
$boundary
Content-Type: application/octet-stream; name="$^X"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="$^X"

$mail{body}
$boundary--
END_OF_BODY

sendmail(%mail) || print "Error: $Mail::Sendmail::error\n";

How to send mail using a special character set (Russian, Greek, ...whatever...)

>Since I am Russian I would like to send my messages
>(using Sendmail) with Cyrillic codepages (KOI-8 or Win1251).
>Can you help me how to do it, please

You have to specify the right character set. By default, Mail::Sendmail puts the following header in the mail

Content-type: text/plain; charset="iso-8859-1"

You can override it in your script. I think the character set you want is ISO-8859-5. So if your mail hash is called %mail, put this in your script

$mail{'Content-type'} = 'text/plain; charset="iso-8859-5"';

or maybe you want koi8-r ?

$mail{'Content-type'} = 'text/plain; charset="koi8-r"';

Of course, the recipient mail client needs to be able to display this character set with the proper font.

I don't have make. How can I install this (or any other) module

You can just copy Sendmail.pm to a Mail subdirectory in one of the directories in your @INC. Type perl -V to see which directories you have in @INC. If none has a Mail subdirectory, create it. You can use a similar procedure for any module which doesn't use XS code or .dll's.

On Win32, you can also get nmake from Microsoft. Then you can do the usual install, just typing nmake instead of make.

Is Mail::Sendmail secure for use in CGI scripts?

Yes. Unlike scripts that rely on Unix command-line sendmail, a Perl-only socket script like Mail:Sendmail never sends anything to the shell. Whatever dreadful system command you may have in your mail hash, it won't ever actually be executed as a system command. The worst that can happen is your SMTP server rejecting the message with an error.

According to Safe CGI Programming (by Paul Phillips), and The WWW Security FAQ (by Lincoln Stein), the dangerous functions in Perl are: eval(), system(), exec(), open(), backticks and regular expressions using the /e modifier.
There is none of these in Mail::Sendmail (except eval("use MIME::QuotedPrint");, which doesn't contain user input).

Where can I ask other questions about Mail::Sendmail?

There is now a Perl Mail::Sendmail group on Google Groups.


Home | Perl Mail


perl (at) alma.ch, 30.04.1999.

Web hosting: almanet.ch