When I'm writing CGI programs, I find that many - if not most - need to send email at some point. Rather than rewrite a mailing routine every time, I produced a simple reuseable Perl subroutine. What you're about to see is a simplified version of it, for you to build on yourself if you like.

Here's the subroutine. You'll need to save it locally, rename it with a .pl file extension, and upload it to your webserver.

System requirements

You'll need 3 things:

  1. A Unix server. It won't work on NT, but it might on MacOSX Server.

  2. Access to Sendmail or an equivalent. Exim and qmail usually work just fine, but check with your sysadmin.

  3. Perl5. Perl4 *should* work, but I can't promise anything.

How to use it.

All you have to do is require the file, tell it where your Sendmail is, and call the subroutine with appropriate variables. Here's the most trivial example:

!#/usr/bin/perl

require '/path/to/sendmail_evolt_org.pl';

$SENDMAIL = '/usr/bin/sendmail';

&simple;_sendmail('Hello!', 'scripts@easyweb.co.uk', 'martin@easyweb.co.uk', 'Hello World');

Easy!

The general format of the subroutine variables is:

subject, from, to, body, cc, bcc

The body, cc and bcc variables are completely optional, and you can either have each variable literally used as above (make sure you use single quotes, or your @ signs will cause trouble), or derived from variables:

&simple;_sendmail($subject, $from, $to, $body, $cc, $bcc);

Limitations

None of these limitations is particularly taxing to rectify.

The routine

Let's step through it.

 67: sub simple_sendmail {

102: }

103: 1;

This is the bare outline of any subroutine. Because we're requiring the file, it works as if the file is part of the main script, so you don't need a #!usr/bin/perl line. All you have to do is ensure that it's in correct syntax, and the last line evaluates to true.

69: local($subject, $from, $to, $body, $cc, $bcc) = @_;

This grabs the incoming data (stored in the Perl special variable @_), and puts it into sensible variable names. Because we're using local variables, there won't be any problems if you've used $to (etc) in your main script.

73: open(MAIL, "|$SENDMAIL -t");

75: $| = 1;

This is the main engine of the script. Unix works in such a way that everything - programs included - can be considered as a file. So what we do here is open a connection to the 'file' that is the Sendmail program, and attach it to a filehandle, MAIL; just as if we were outputting to a real file. Line 75 ensures that each line will be dispatched as it's output, which will give a more reliable result.

80: print MAIL "To: $to

";

81: print MAIL "From: $from

";

82: print MAIL "CC: $cc

" if $cc;

83: print MAIL "BCC: $bcc

" if $bcc;

84: print MAIL "Subject: $subject

";

These are the functional headers, which tell the email where to go, who it's from, and what its subject is.

85: print MAIL "x-mailer: EasyWeb Design - email scripts@easyweb.co.uk

";

86: print MAIL "x-copyright: simple_sendmail 1.0, Copyright (C) 1999 Martin Burns

";

87: print MAIL "x-license: GNU General Public License version 2

";

88: print MAIL "x-license_url: http://evolt.org/index.cfm?menu=8&cid=137&catid=17

";

If you've looked at our mail headers tutorial, you'll remember that any header which begins with x- is ours to play with. So I've used it to add an unobtrusive credit to myself for the routine. Most people won't notice it, but someone who's in a position to give you work just might. I've also put on the licensing info for the routine, so that anyone literate enough to be interested in how it's done can find out what restrictions I've put on its distribution.

I also use the x-mailer header - typically used by email clients - to distinguish incoming email from forms. As I receive a bcc from most forms I install for monitoring and diagnostic purposes, I can filter them into my deleted mail folder, where they sit for 24 hours before they're auto-deleted. My mail client (Claris Emailer) also colour codes them for me, so it's easy to keep an eye what's going on.

The other important thing to notice is that, while most of the other headers end with a line-break to separate them, the last one ends with two. This is how mail clients know where the headers end, and the message body begins - there's a blank line between the two.

Finally, we get to print the body of the message, if there is one:

93: if ($body) {

94:   print MAIL $body;

95: }

96: print MAIL "

";

And there's another blank line at the end.

The very last thing we need to do is close the file handle:

101: close(MAIL);

So there you have it - a simple, all-purpose mail subroutine.