Perl 101: The email form

Never worked with Perl but always wondered how it works? In this article Pete starts from scratch, explaining everything we need to know to code, test and implement a “mail me” script with Perl. He shows us how to setup the form, how to use the CGI module, and also how to pipe commands directly to sendmail. If you’ve never worked with Perl before, then this article is exactly what you need to get you started!

So, you’ve spent hours creating killer graphics in PaintShop, drafted and redrafted your ‘about me’ section, and scanned in photos of your family and pets. Your next step towards creating your dream website is to add interactivity – and one of the best ways to do that is with Perl CGI. In this article I’ll take you through everything you need to know to get started with Perl, finishing with the code for a ‘mail me’ form to allow your visitors to easily get in touch. But first things first…

You’ll need a webhost which offers CGI scripting – and sadly most of the free ones don’t. Of those which do, Hypermart is one of my favourites. Alternatively, if you’re willing to pay a few dollars per month, there are plenty of hosting companies out their who provide full CGI scripting along with lots of other goodies for budding web designers.

If you don’t know any Perl, then that’s fine, although having some experience with another scripting language such as PHP will help you understand certain things a bit more clearly, such as regular expressions. Anyhow, now that we’ve gotten all of that out of the way, let’s move on to learn some Perl…{mospagebreak title=Hello world in Perl&toc=1} As is tradition, we’ll start with a Hello World example in Perl:

#!/usr/bin/perl
print “Content-type:text/htmlnn”;
print “Hello World”;


Type this script into your favourite text editor (notepad, wordpad, pico etc) and save it as hello.pl. Next, upload it to the cgi directory of your webserver – typically this will be called ‘cgi’ or ‘cgi-bin’ and will be located inside your main web directory.

The next step is one that often trips up newbies, so make sure you are happy with what is happening. On Unix systems, files have permissions that govern who are allowed to access them. Typically you would set the permissions on your files so that anybody can view them but only you (the administrator) can write/delete them. In the case of CGI scripts, you need to make your scripts executable by anyone.

With a text based FTP client you would do so with the following command:

chmod 755 hello.pl

If you are using a graphical client such as CuteFTP, right clicking on a file should give you the option to change its permissions.

Fire up your web browser and navigate to http://www.yoursite.com/cgi-bin/hello.pl. If all goes well you should see ‘Hello World’ at the top of your screen. Unfortunately, this being your first CGI script, things might not go so smoothly. The most common problem is a “500 Internal Server Error” message. This usually indicates a typo in your script, so go back and check it. In particular, make sure that each line ends with a ; and that the very first line is #!/usr/bin/perl. Occasionally Perl will be installed in a different location to this – check your web hosts help pages or contact their support department if you are unsure.

If you browser simply displays the source code of your script, this indicates that the web server did not recognise the file as a program to run. The most common cause of this is incorrect file permissions – go back and make sure that your script is world executable (755 or rwxr-xr-x).

Anyway, hopefully this has wetted your appetite for PERL CGI. Through the remainder of this article, I will take you on a step by step journey through the process of creating a simple ‘mail me’ script.

Getting Data Into The Script
CGI’s real power comes from its ability to read user input, process it, then spit out a response; but first we need a way to get user information into the script. HTML forms are the most common way to do this, so we’ll spend a moment or two going over them.

A form consists of a combination of check-boxes, radio buttons, text boxes etc, as well as a field telling the browser where to send the data to once the form has been submitted. A typical form may look something like this:

<form action=”http://www.myurl.com/cgi-bin/info.pl” method=post>
Enter Your Name: <input type=text name=mytext><br><br>
<input type=”submit”>
</form>


This would display a rectangular box for users to enter their name, and a grey ‘submit’ button. Note the <form action=”http://www.myurl.com/cgi-bin/info.pl” method=post> tag. This instructs the browser to navigate to the info.pl script when you click on the submit button.

In our example we need fields for Name, Email Address and Message, so our form would be:

<form action=”http://www.yoururl/cgi-bin/mailme.pl” method=post>
Your Name : <input type=text name=name><br>
Email Address : <input type=text name=email><br><br>
Your Message :<br>
<textarea name=message cols=40 rows=10></textarea><br><br>
<input type=submit value=”send message”>
</form>


Copy this into your text editor and save it as mailme.html. Upload it to your web server as you would any other HTML file. Make sure you change the forms action attribute so that it points to your web site. Don’t worry that the mailme.pl script doesn’t exist yet – we’ll be creating that in the next section.

Browse to the mailme.html page with your web browser, and you should see something like this:

Our mailme.html form in action

You can also of course paste this code into an existing html page to integrate it better into your site.{mospagebreak title=Parsing User Input&toc=1} Now that we have the form setup, we need a way to get the user supplied data into our script. For the sake of simplicity we’re going to use the CGI module that makes retrieving user input a piece of cake.

#!/usr/bin/perl

First off we tell Perl to use the CGI module:

use CGI;

The CGI module an object orientated module, so we create a reference ($q) to a new instance of it:

$q = new CGI;

We can now retrieve the data stored in each element of the form by passing the elements name to our CGI object:

$name = $q->param(“name”);
$email = $q->param(“email”);
$message = $q->param(“message”);
 

If you look back to our HTML form code on the previous page, then you will see that ‘name’, ‘email’, and ‘message’ match up with the name=values in the code.

It really is that easy with CGI. Don’t worry if this talk of modules and object orientated programming is confusing you: for now just realize that we can retrieve form data using $variable = $q->(“element name”), where “element name” is the name you gave to the field in your HTML form.

Just to prove that the script is working, we’ll finish off with the following lines:

print “Content-type:text/htmlnn”;
print “<html><body>”;
print “Name $name<br>”;
print “Email Address $email<br>”;
print “Message : $message<br>”;


…which will display the data read in by the script.

Our script so far then looks like this:

#!/usr/bin/perl

use CGI;
$q = new CGI;

$name = $q->param(“name”);
$email = $q->param(“email”);
$message = $q->param(“message”);

print “Content-type:text/htmlnn”;
print “<html><body>”;
print “Name $name<br>”;
print “Email Address $email<br>”;
print “Message : $message<br>”;


Save this script as mailme.pl and upload it to your CGI-BIN directory (remembering to CHMOD 755 it). Go back to the HTML form in your web browser, fill in some value and click submit. If all goes well, you will see the values displayed back to you.

Sending the email
Next comes the code to actually send the email. Typically Perl scripters use the Unix program “sendmail”. Sendmail is present on almost all Unix/Linux systems, is highly configurable, and runs via the command line – all this makes it the ideal choice for sending email through perl.

First off you need to know the location of sendmail on your webserver, however. Again, consult your web hosts help pages or contact them if you are unsure. Most often it resides in the /usr/lib/sendmail directory:

$sendmailpath = “/usr/lib/sendmail”;

Next, we open a pipe to sendmail. Pipes are an advanced feature of Perl with lots of intricacies that I can’t even begin to explain here. Basically they allow us to send (i.e. pipe) data backwards and forwards between two programs. In this case we open a pipe to sendmail and pipe our email message to it:

open(MAIL, “| $sendmailpath -t”);

Here we’ve opened a pipe called “MAIL”. The | indicated that we are piping data *to* sendmail (rather than reading data *from* sendmail), and the -t switch tells sendmail that we are specifying the recipient of the email with a To:<email address> field.

By printing to the pipe MAIL, we can send our data to sendmail, so we do something like this:

print MAIL “To: $myemail”;
print MAIL “Reply: $email”;
print MAIL “Subject:Webmail from $name”;
print MAIL “n”;
print MAIL “$message”;


You’ll recognise the variables $email, $name, and $message – they are holding the data we read in from the form. The fourth line is simply a n (a new line break) – this is used to separate the header of the email from the body.

$myemail should be set to hold your email address (i.e. the address which the mail will be sent to). You can do this by adding the following line:

$myemail = “pete@p-smith.co.uk”;

..towards the top of your script. Perl treats @ as a special character, so you’ll need to escape it with a forward slash: @

Finally, we close the pipe and send some output to the user:

close MAIL;
print “Content-type:text/htmlnn”;
print “<html><body>Thank you for your comments, you mail has been sent”;
{mospagebreak title=Refining Your Script&toc=1} So far we have a working script, but it lacks many of the refinements which distinguish amateur scripting from professional scripting; and more importantly, it is insecure – if your web server is cracked because of one of your CGI scripts then your provider will not be very happy.

The golden rule in CGI programming is to never trust user input. Some users are stupid, others are malicious – just because you ask them for their name, it doesn’t guarantee that they won’t enter a series of commands which *could* cause your web server to display it’s password files.

Characters such as ‘|`>< have special meanings to perl and can be used by the ingenious cracker to make your script do things it shouldn’t. In fact, it’s much safer to list what we *should* allow rather than what we should *disallow*. In this particular case, limiting user input to letters, numbers, underscores, spaces, periods, question marks, exclamation marks, hyphens, and at signs (@) should be sufficient.

Here’s where the fun starts. We’re going to be using regular expressions, which are a very important (and often complex) part of Perl. If you are coming from another programming language you may already be familiar with regular expressions (or regex’s, as the are called for short). If this is your first time then they can look very daunting, however fear not as all will be explained.

First off, a simple one:

unless ($name =~ /^[w ]/)
{
print “Oops you entered your name incorrectly – please go back and check it<br>”;
die;
}


The important part of this is $name =~ /^[w .]/ .Here we are testing to see if the name supplied by the user contains any characters which are not letters, numbers, or spaces. The two backslashes are boundaries – everything inside of them is treated by Perl as a regex, so our regex is:

^[w ]

w is a shorthand meaning ‘any word character’, however Perl’s definition of a word character is not what might you expect: to Perl it means ‘any letter, number or an underscore’. The blank space following the w is literal – i.e. Perl will look for a blank space.

The square brackets ([ and ]) indicate that everything inside them is an alternative: Perl will be happy if it finds either a word character *or* a space. Finally, we invert the meaning of [w ] by putting a carot (^) at the beginning:

unless ($name =~ /^[w ]/)
{
print “Oops you entered your name incorrectly – please go back and check it<br>”;
die;
}


Now that you have a basic understanding of regular expressions, this line could be rewritten in English as:

If $name contains any character which is NOT a letter, number, underscore or space, THEN print an error message and stop.

So that was your first lesson in pattern matching and the bizarre world of regular expressions. If you understand everything we’ve covered then give yourself a pat on the back – it can be very hard at first, but soon you’ll be able to write your own regex’s with your eyes shut. If you are still unsure of regular expressions, then please take the time to re-read this page and suss them out – the effort will pay off once you start writing your own Perl scripts.{mospagebreak title=More Regular Expressions&toc=1} As I mentioned earlier, the regular expression we created on the previous page was pretty basic (you may well be wondering what a complex regexe looks like, but try not to for now). Now that we’ve covered the basics, it’s time to improve on our regex.

unless ($name =~ /^[w ]/)
{
print “Oops you entered your name incorrectly – please go back and check it<br>”;
die;
}


This works fine for filtering the users name, but what about his email address? Email addresses contain periods and at symbols, so we’ll need to allow for those. In the previous section we talked about how characters inside the square brackets are alternates. To allow @ and . we simply add them to what we already have:

unless ($email =~ /^[w @.]/)
{
print “Oops you entered your email incorrectly – please go back and check it<br>”;
die;
}


And for the actual message we’ll again limit it to letters, number, underscores and spaces:

unless ($message =~ /^[w ]/)
{
print “Sorry, you can only use letters, numbers, underscores and spaces in your message<br>”;
die;
}


Putting It All Together
So finally we have a complete script, which now looks like this:

#!/usr/bin/perl

use CGI;
$q = new CGI;

$sendmailpath = “/usr/lib/sendmail”;
$myemail = “pete@p-smith.co.uk”;
$name = $q->param(“name”);
$email = $q->param(“email”);
$message = $q->param(“message”);

print “Content-type:text/htmlnn”;

unless ($name =~ /^[w ]/)
{
print “Oops you entered your name incorrectly – please go back and check it<br>”;
die;
}

unless ($email =~ /^[w @.]/)
{
print “Oops you entered your email incorrectly – please go back and check it<br>”;
die;
}

unless ($name =~ /^[w ]/)
{
print “Oops you entered your message incorrectly – please go back and check it<br>”;
die;
}

open(MAIL, “| $sendmailpath -t”);

print MAIL “To: $myemail”;
print MAIL “Reply: $email”;
print MAIL “Subject:Webmail $name”;
print MAIL “n”;
print MAIL “$message”;

close MAIL;

print “<html><body>Thank you for your comments, you mail has been sent”;


Upload it as you did earlier then go back to your hHTML form, fill it in, and submit it. If all goes well you will receive the ‘Thank You’ message. If not, it’s time to check through your script for typos again. Wait a few minutes then check your email. You should have received the message you sent from the form.{mospagebreak title=Conclusion&toc=1} This being your first script, you will no doubt have run into errors along the way. The most common are missing semi-colons from the ends of lines, missing content-type headers, and incorrect file permissions. If you have access to your web servers error logs these are a great way to quickly track down bugs.

Hopefully this introduction to PERL CGI has got you interested enough to find out more about Perl and its uses in web design. Be sure to check out http://www.perlcoders.com/, who specialize in CGI programming: they have hundreds of scripts (many of which are free to members) to make your site really stand out from the crowd!
[gp-comments width="770" linklove="off" ]

antalya escort bayan antalya escort bayan Antalya escort diyarbakir escort