Lesson 7 | A mail form for the Web |
Objective | Learn how to make an email Form |
Learn how to make a Perl email Form
One helpful Web program that we can employ as an example of using a pipe is a mail form. This program creates a Web page with a form for sending an email message. This is a pretty long lesson, but it is well worth the effort! This program uses all of the techniques we have learned so far, including the state-machine and the included htmlp files. It also uses a pipe to send the email to the sendmail program.
If your system does not have sendmail, you can use another program by replacing the value of the
$sendmail
variable with the command line for your mail-transfer program.
Take a look at the source code for the email CGI program or even print it out if you like, it is not very long.
- email.cgi
- edit.htmlp
- first.htmlp
- form.htmlp
- sent.htmlp
- valid.htmlp
error.htmlp in Perl
<!-- $filename -->
<table>
<tr><td width=20 height=30>
<tr><td><td>
<h3>Error:</h3>
<p>$error
<form action="$callback" method=POST>
<p>
<input type=submit value=" Continue ">
<input type=hidden name=name value="$name">
<input type=hidden name=email value="$email">
<input type=hidden name=subject value="$subject">
<input type=hidden name=message value="$message">
<input type=hidden name=referer value="$referer">
<input type=hidden name=state value=edit>
</form>
<tr><td height=30>
</table>
footer.htmlp
<!-- $filename -->
<hr noshade size=1 width=300 align=left>
<small>
Based on Magic Email by
<a href="../module5/http://www.weinman.com/wew/">Bill</a>
<a href="../module5/http://www.weinman.com/">Weinman</a>
</small> <br>
<code>[<a href="../module5/$referer">Back</a>]</code>
<code>[<a href="../module5/http://www.weinman.com/wew/">Home</a>]</code>
<code>[<a href="../module5/http://www.cgibook.com/">CGI Book</a>]</code>
<code>[<a href="../module5/http://www.perlbook.com/">Perl Book</a>]</code>
</body>
</html>
State-machine based CGI programs
For the most part, this program works just like the other state-machine-based CGI programs we've worked with in this course.
It keeps a state variable that it passes back and forth as a hidden field, and it uses a jump table to dispatch execution to the appropriate state.
In the mailvalid state, it goes to a little trouble to ensure that the message is formatted for the HTML browser with this code:
$disp_message =~ s/\r\n/\n/g; #fold the cr/lf pairs
$disp_message =~ s/\n{2}/<p>\n/g; #format it for the screen
The first line folds any CR-LF pairs (\r\n
) into a single newline. The next line takes two newlines in a row, and converts them to an HTML paragraph tag. Next, we check the email address for validity. We do not really want mail from anyone who uses a bogus email address.
return error("'$email' is not a valid email address")
unless ($email =~ /^[a-z][\w-.+]*\@[\w-]*[.][\w-.]*$/);
The valid.htmlp
file has a useful little trick in it: there are two submit buttons:
<input type=submit value="Send It">
<input type=submit name=oops value=" Oops!">
The second button has the name oops
which in turn creates a Perl variable named $oops
,
which we can test for in the program:
sub mailsent
{
if ($oops) { mailedit }
else {
mailsend() or return 0;
htmlhead("Email Sent");
htmlp("sent.htmlp");
htmlfoot();
}
}
In the mailsent
routine, if the $oops
variable is defined, then the mailedit
routine
is called instead of executing the rest of the mailsent
routine. This is a convenient way of creating separate buttons to navigate different states.
Finally, the mail is sent with this routine:
sub mailsend
{
(-x $sendmail) or return error(qq(cannot find $sendmail));
open(MAIL, "| $sendmail $switches") or
return error(qq(cannot open "$sendmail $switches": $!));
print MAIL <<SENDMAIL;
X-Mailer: $xmagic [$referer]
To: $mailto
From: $name <$email>
Subject: [$subject]
Referer: [$referer]
Remote Host: [$remote_host]
Remote Addr: [$remote_addr]
User Agent: [$user_agent]
$message
---
This message was sent by $myname
SENDMAIL
close MAIL;
}
mailsend
The
mailsend
routine is a very simple routine which first checks to make sure that the mail program exists and then opens a pipe to it and sends the mail.
The expression
(-x $sendmail)
checks to see if the mail program can be found and is executable, and the
error()
routine is used to report errors to the user so that you can be notified if the script does not work for some reason.
Install Mail Form System - Exercise