Although it is the author's belief that the statements contained within this document are true and correct, use of any of this information is at the user's sole risk. The author does not accept liability for any consequences arising from the use or misuse of this information.

Words of Caution

CGI is a wonderful tool, but it can be turned against you as a weapon. A hammer can be used to build a house, or to mash in your skull. If the script you're trying to deploy is not written with this in mind, it could be the open window through which the bad guys enter the server and vandalize to their evil hearts' content. The author of the script and I may be unwittingly working together to weave for you just enough rope for you to hang yourself.

Suppose a fatal security hole exists in that script you just downloaded, and some evil cracker discovers it without reporting it. Is he going to test his new-found knowledge by tearing up your site, your server, your good name in the community? Possibly. How does he know you're even using it? That's easy: he visits his favorite search engine and looks for the name of the script. Suddenly that high search engine ranking you wanted is getting you into trouble you never wanted. Rename all scripts you download from the internet prior to deploying them!

Something you should do is to create a blank index.html page to place in your cgi-bin directory -- this will keep snoops from perusing your files as easily as entering a URL into the browser.

First Things First

The first thing you have to do before deploying that script is to set any configuration variables that need to be defined. Perl scripts are just plain ASCII text, so you can use whatever it is that you use to edit text files to make these changes. You Windows people will probably use Notepad. Some older installations might barf on those funny newlines that micro$oft uses, in which case you will have to use something else, like the freely available HTML editor Arachnophilia that can make newlines the way they ought to be.

If it's not already too late, it's a wise practice to keep one copy of the script for reference, and edit another for use. This way, if you mess things up so badly that you don't know what it looked like before you started, you don't have to go and download the thing all over again just to find out.

The path to the interpreter

The first line of any Perl script should look something like this:

#!/usr/bin/perl

This line tells the server where to find the Perl interpreter to use. The most common places are /usr/bin/perl and /usr/local/bin/perl -- but the only way to be sure is to ask. If you are fortunate enough to be able to establish a telnet connection to your ISP, do so and then execute the following command:

which perl

And while you're at it, check the version of Perl with:

perl -v

(If your script was recently written and the interpreter version is prior to 5.004, you might have problems.)

which perl should have given you the path to the interpreter, which must be indicated by the very first line of the script. If you have to change this line, leave the shebang#! in place, and make absolutely certain that your entry is in the same case as the response you got from which perl. Unix-like operating systems trust you to be smart enough to know the difference between /Usr/ and /usr/ and will not second-guess what you tell them.

Other paths

Likewise, the paths to any other resources on the server can be found by establishing a telnet session and asking. If you need to know the location of razzlefrazzitz you would use which razzlefrazzitz.

What? You can't use telnet?

I don't know how

Just about any operating system with networking ability has a telnet client, even that funny micro$oft stuff. If you know your ISP will let you establish a telnet connection, find out the name of the host you're supposed to connect to (telnet.myisp.com in this example), open yourself a command line ("DOS window") after connecting to the internet, and enter this:

telnet telnet.myisp.com

You should be greeted with a login prompt, to which you respond with your user name. Next you will be asked for your password, which ought to be the same one you use when establishing your internet connection. After that, you will get some kind of a prompt and you're ready to rock 'n' roll. Remember, though, that you are not talking to a DOS machine on the other end and that you are running someone else's machine.

They won't let me

Sometimes all it takes is to ask, other times there are more hoops to jump through. If you want to mess around with CGI, you're probably going to need telnet access at some point. If they'll let you provide your own executables to run on their machine, they ought to let you telnet -- it's less risk to allow an authorized user to execute commands than it is to allow the world to execute them via CGI.

Things to watch out for

There are some common mistakes that Windows users make when configuring their own Perl scripts:

Backslashes in directory paths. Unix uses "forward" slashes -- the backslash is used for other things.

Leaving a bare @ symbol in double-quoted email addresses. If you're using an email address as a variable within double quotes, you need to escape it with a backslash. For example:

$my_email = "cgihelp\@artsackett.com";

Deleting semicolons from the ends of lines. This causes the interpreter to think that the next statement is a continuation of the one you deleted the semicolon from. Oops.

Eliminating the quotes around non-numeric variables. You have to trust the author to know more about his script than you do. If an argument is quoted, it should remain that way -- including the author's choice of single- or double-quotes. They do behave differently!

FTP'ing the files

Make absolutely certain that you transfer Perl scripts in ASCII format! If you're using the command line interface to ftp, execute the command:

ascii

before you upload Perl scripts. Later in the same session, if you want to upload images, compressed files, or any other binary data, you can reverse the effect of ascii by issuing the binary command. Most FTP servers will tell you when you connect which format they default to, with a statement like "Using binary format for file transfer". After changing the format, the new format remains in effect until you either terminate the session or explicitly change it.

If you're not sure which mode you used when you uploaded the broken script, save yourself some grief and upload it again as ASCII data.

This is perhaps the most confusing topic for those who don't have Unix knowledge. I'll do my best to explain the basics you'll need.

In a Unix-like operating system, each file has certain "permissions" associated with it that define who can do what with the file. If you do not have the proper permission to do a certain thing, it won't let you. It's a nice feature, and although it is not perfectly fool-proof it works very well in most cases.

These permissions are most often expressed as a triplet of octal (base 8) digits that can have values from zero through seven. From left to right, each digit expresses the permissions for owner, group, and world (also known as "other", but I prefer to use the term world, since on the web that's exactly who that other user is: the entire world!)

owner is the person who owns the file, which is you if you placed it into the file system. It is possible to change the owner of a file to someone else who is not the owner of the directory, but you probably don't want to do that arbitrarily. Imagine leaving a file in such a state that you can't use it, even though it's in your own directory!

group is your "workgroup", in most cases your group includes anyone else who is also a customer of your ISP. These are the most dangerous users that you have to concern yourself with -- they don't have to come in through the HTTP server to get at your stuff, so they can bypass a lot of security. Don't trust 'em!

world is everyone else who has access to the file system. When there's an HTTP server around, it is quite literally the entire world.

The permissions that can be applied to a file are, in their proper sequence, read, write, and execute. Reading a file means retrieving it for viewing or saving, writing a file means having the ability to change it, and executing a file means just what it sounds like, turning it loose for processing and maybe even allowing it to gain some degree of control over what the CPU is going to do.

Working with octal notation

Back to those octal digits. Bet you never thought you'd need to know that stuff, so you forgot whatever you learned about octal (base 8) numbers way back in the eighth grade. And probably about binary (base 2) numbers, as well. Too bad.

Each of the permissions has one bit associated with it -- a bit being the smallest piece of binary data taking a value of 0 or 1. A bit is considered "set" if its value is 1, and "reset" if its value is 0. So we end up with three groups of three bits to indicate the three users (owner, group, world) and their permissions (read, write, execute). Since it takes three bits to express an octal digit, it just makes sense to use octal notation when referring to that bit field that indicates permissions.

Converting a group of three bits to octal is very easy. Just like in the decimal notation you're accustomed to, the position of a digit tells us its weight. In decimal (base 10) notation, the 1 in the integer 10 is worth ten times more than the number 1 with no zeroes to the right of it. In binary (base 2) notation, the 1 in the integer 10 is worth two times more than the number 1 with no zeroes to the right of it. So to arrive at the decimal equivalent of a binary number, we can add the weights for each of the non-zero digits, thusly:

1

0

1

= 5

4

2

1

One 4 plus zero 2's plus one 1 equals 5

So, now that we know how to work octal notation, what are we going to do with it? We're going to use it to define who can do what with your script. Here's a handy little table that you can use for future reference:

owner

group

world

r

w

x

r

w

x

r

w

x

4

2

1

4

2

1

4

2

1

You'll note that the write permissions for group and world are shown in red -- this is because you NEVER want to allow group or world to write to your scripts. If they could do that, they could replace your nice little benign script with something ugly and nasty that does rotten things like destroy the file system of the server, or send threatening email to the President of The United States with your name attached. You don't want your server administrator or the Secret Service coming to your house at 3AM, do you?

Setting the permissions bits

In most cases, you want to allow yourself to do anything you want to the script, and you want the world to be able to read and execute it. It's customary to allow your group to read and execute, also, but this is pretty redundant since they're already covered as the world user. So, here's how we put that cute little table to work:

owner

group

world

r

w

x

r

w

x

r

w

x

4

2

1

4

2

1

4

2

1

1

1

1

1

1

1

1

7

5

5

Now all we have to do is make it so. Using telnet, or your ftp client if the server will allow you to change permissions from an ftp session, all you need to do is to issue the command:

chmod 755 myscript.cgi

(Substituting the real name of your script for myscript.cgi.)

The above command must either be issued from within the directory where the script is located, or must include the path, e.g. chmod 755 public_html/cgi-bin/myscript.cgi

Note that for a directory to be accessible to the world, it must have its permissions set, also! In most cases, 705 will get things working nicely. You change the permissions for a directory just as you would for a file. If the cgi-bin directory was created for you when your account was established, it's probably already properly set.

Checking the permissions bits

If you're using one of those Windows GUI ftp clients, you might have to read the Help file that should have come with it. I don't keep up with even one of the many such programs that exist, so I can't help you. If you're ftp'ing from the command line, or have a telnet connection, cd to the proper directory and issue the command:

ls -l(Those are lowercase L's for those of you using a font that makes it difficult to distinguish them from ones.)

In response, you should get a listing that shows in the leftmost position the permissions assigned to each file in the directory. They will probably be shown something like this:

-rwxr-xr-x 1 owner group size last_modified filename

Ignoring the leftmost "bit", the next nine are the permissions bits that are set, in the order described above (owner, group, world).

Check the file name extension

Some servers will let you get away with naming the file with the .pl extension, others won't. If your script is named with .pl and you don't know for a fact that the server will accept it, change it to .cgi and see what happens. It might just come to life. (In most cases, if the file you call from your HTML document links itself to another at run time, perhaps using Perl's do statement, you shouldn't need to change the extension of any except the file(s) you call directly.)

Summary

Hopefully, this document has addressed whatever problem you were having that brought you here. If not, you might try starting with a fresh copy of the script (you did keep one for reference, didn't you?) and going through the steps one more time.

If all else fails and you can't get it going, and you're certain that your ISP allows user-provided executables, and you're really sure that you just have to have it working, you can contact me and I'll accept money to make it work for you. I am, after all, a perl programmer and a Linux system administrator.