Pipes | Streams  «Prev  Next»

Lesson 7A mail form for the Web
ObjectiveLearn 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.


  1. email.cgi
  2. edit.htmlp
  3. first.htmlp
  4. form.htmlp
  5. header.htmlp
  6. sent.htmlp
  7. 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

Click the Exercise link below to install the mail form on your server.
Install Mail Form System - Exercise