Programming Languages
What is Perl?
PERL stands for for Practical Extraction and Report Language. Perl is a programming language developed by Larry Wall, especially designed for processing text. Because of its strong text processing abilities, Perl has become one of the most popular languages for writing CGI scripts. Perl is an interpretive language which makes it easy to build and test simple programs.
Tips
File I/O and Permissions
The usual way of writing to a file in Perl works in CGI scripts as well. First open the file on a file handle for writing (or die if you can't; better yet, send an error message), then print to the file and close it:
$text = "whatever"; |
Remember, though, that the server is executing the script, not you, so the server must have permission to write a file in your chosen directory. Commonly, the server runs as user "nobody" or someone else with minimal permissions, so this requires world read and write access. You should set the directory permissions as chmod 766
Of course, this means that anyone with an account on your system can edit or delete these files. Most web servers are configured this way for security reasons -- security for the server and the system, not the web pages. New CGI developers are appalled when they first hear of this problem, but there is no perfect solution on a public system.
Testing File Names
When your script writes to a new file, you probably want it to create a new and unique name for the new file, one that doesn't conflict with any existing files, which would be overwritten. One way to create a new file name that's unique is to incorporate the process id and the time into the name. Perl's special variable, $$ returns the current pid and $^T returns the time (in seconds since 1970). So you could use something like $filename = "$$" . "$^T" . ".html"; Neither alone will guarantee uniqueness since there are only a finite number of process id's, which are recycled, and your script could have been accessed twice within the same second.
This results in ugly filenames, something like "83498127310497.html". If you have prettier names that you insist on, you can test for the existence of a file with the proposed new name, using Perl's -e operator. -e $file_name is true if a file already exists with that name. In the example below, the variable $text holds some key text taken from the contents of the file that we want to use in the name. We're also assuming that the script is constructing a web page, so we add ".html" to the end of the name.
$file_name = $your_chosen_dir . $text . ".html"; |
Locking a File
A different issue arises when you want your CGI script to write or append to an existing file. There is a (small) chance that two different processes (users submitting your form) will want to write to the file almost simultaneously. If one opens the file before the other closes it, the last to close will overwrite any changes the first tried to make.
One approach to this problem is to keep files open for appending or writing as briefly as possible. Try to prepare as much of your text as possible in advance of opening the file, so that there are as few operations as possible while the file is open. For example, to append the contents of $text to the file, you might write
... a lot of code to prepare ... |
However, these don't provide the ability to lock the file for writing, but still allow other processes to access it for reading, If you don't mind locking the file against read access, you can consider these system calls. But if the file is a web page, or something the web server may otherwise want to access, you may want to permit read access, but lock out write access.
How to Install a Perl Script in Unix
The correct path to perl should appear after '#!' on the first line of the script. Typically it will be
'#!/usr/local/bin/perl' or '#!/usr/bin/perl' |
If necessary, configure the script as instructed in the documentation that comes with it.
Using FTP, move your script to your server. Be sure to use ASCII mode.
Set the permissions on the script. If using telnet type chmod 755. If using a graphical FTP program, follow its instructions. Only the owner (you) should have write access, but anyone should be able to read and execute it. Test the script by typing in the URL to the script in your browser.
Sending email f rom a Perl script is easy with Net::SMTP.
Include the Net::SMTP module in your script. Example: use Net::SMTP; |
How to Write Data Files in Perl
Saving data to files is a critical step in any programming language. Learn how to do it in Perl.
To open a file, use the open(FILE_HANDLE, filename)
function as detailed in steps 2 and 3.
Use write mode when you want to save data, overwriting any data currently in the file. Example: p
en(FD, "> test.dat") or die("Couldn't open test.dat\n"); |
Use append mode when you want to open a file for writing without destroying the current contents. Example:
open(FD, ">> test.dat") or die("Couldn't open test.dat\n"); |
Use print() or printf() with the filehandle to send output to the file rather than the screen. Example:
print FD "Hello World!\n"; |
Close the file with close( FILEHANDLE);
Example:
close(FD); |
Why do I keep getting 'Unable to Open data.txt"?
there are a few reasons for this...
1) your $boarddir doesn't point to the right directory where data.txt is kept.
2) You haven't chmod'd it correctly (777).
3) You need to up load all .cgi - txt files in ASCII... not binary.
4) make sure there is a data.txt there.
How do I change the time zones to reflect the times where I live??
You need to go to '&get-date' in both index.cgi and Robboard.cgi
Look for this line...
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = |
and change it to...
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = |
change the 3600 to whatever time zone offset your in..
How do I add the name of the post in email messages?
elsif (//) { |
And there you have it.. The message title will appear in the subject of your email :)
How do I find my full home pathway?
You have a few choices here...
1) Go to the help/support pages of your host provider. (recommended)
2) If ALL files are in the same folder as your cgi's then you can use the following line for your pathway..
$directory = '$ENV{'DOCUMENT_ROOT'}'; |
OR
$directory = 'directory'; |
3) You can go to the scripts section of this site to download a little script I wrote to find your pathway.
How can I use the members login with multiple millsieboards?
1) Make 3 directories in your cgi-bin. Call them "boards1" "boards2" and "board_members".
2) Make sure you have all the files of MillsieBoard in the "boards1" and "boards2" directories except for "pwd.txt" and the "portfolio" directory. Put those to files only in "board_members" in your cgi-bin.
3) In your cgi-bin you should have these files:
index.cgi
index2.cgi
members.cgi
members2.cgi
millsieboard.cgi
millsieboard2.cgi
millsieboard.cfg
millsieboard2.cfg
cookie.lib
4) Open up "millsieboard.cfg" and "millsieboard2.cfg". Change the paths of "$pw_file" and "$profiledir" (lines 77 & 78) to something like the following:
$pw_file = "/home/username/public_html/cgi-bin/board_members/pwd.txt"; $profiledir = "/home/username/public_html/cgi-bin/board_members/profile"; |
5) Open all of the CGI files with the number 2 in them and change:
this... |
6) [same step taken in regular multi-board mod to make a ssi page]
****NOTE: If you want more than 2 boards do the same steps, just add more files accordingly.***
How to convert date to UNIX time in perl (or vice versa)
Time return number of seconds since 0 in your computer (1 jan 1970) on UNIX localtime converts unixtime to normal dates
To convert a specific date to its corresponding unixtime, you use Time::Local, the function looks like this:
$time = timelocal($sec,$min,$hours,$mday,$mon,$year); |
Installation
After installing ActivePerl and SynEdit on Windows 98, you will obtain a SynEdit option in your Programs menu. Use this for starting SynEdit. You will use this program both for editing and running Perl. In order to do the latter, you must create a file perlbat.bat in the directory Perl with the following content:
@echo off |
and set the "Close on exit" property of this file. Then you need to define the default compiler under the Advanced menu of SynEdit as
perlbat.bat %f |
As soon as you have done that, you will be able to run your Perl programs with the "Run Default Compiler" under the same menu or by pressing F8.
Programming tips
?Use chomps after reading lines
?Don't program the same task twice
?Avoid using many temporary variables
Report format tips
- ?Don't forget answering the questions
- Include only program modifications
- Always give a test example
- Submit one text file
- Mention test results, answers and comments first and big programs later (in appendices)
Reading the whole file to a variable at one step.
Instead of reading a file line by line, you might want to read the whole file to a variable at one step. This is useful especially if you are reading html files. If you open a file and try reading from that file, perl reads only until the first [enter] character and stops. The reason of this behavior is that the default "input record separator" in perl is the [enter] character. This separator is defined in the special variable $/. By default $/ is equal to "\n". If you undefine this variable using undef, you can read the file at one step,
Example:
undef $/; |
Regular expressions to search a variable:
I am assuming from now on that you are familiar with substitution operator in perl: s///. A basic example:
s/apple/orange/;
would replace the word "apple" with the word "orange". The separator "/" we used in this example can be replaced with any other non alpha-numeric character. The catch is; you have to escape the separator character inside your regular expression. So it is a better idea to use a less common character as a separator than "/". I prefer using "#" as a separator, because it is less common in strings and visually it is a good separator. So same regular expression could be written as:
s#apple#orange#; |
A common mistake people do when using regular expressions is to try to match a variable in your regular expressions.
Example:
$data =~ s#$url#http://yahoo.com#; |
This is going to work properly most of the time. But sometime it won't behave as expected or you will be experiencing occasional run time errors. For example, if your $url is equal to http://yahoo.com/do.cgi?action=go++&tell=poetry, the substitution operator is going to fail and exit with an error message.
"/http://yahoo.com/do.cgi?action=go++&tell=poetry/: nested *?+ in regex..." |
The reason for the failure is that you can't use "++" inside your regular expression. You have to escape them. The variable might include several special variables, which have to be escaped properly. To correct way to implement this substitution is:
$temp = quotemeta($url); |
quotemeta() is a standard perl function and it escapes all non-alphanumeric characters in your variable.
Using eval for clever substitutions:
If you used regular expressions in perl, you should have used substitution operator frequently. Most of the time a simple substitution is satisfactory.
Example:
$html =~ s#\bdogs\b#cats#ig; |
In this example all the occurrences of the word "dogs" are replaced by the word "cats". What if we want to replace "dogs" with variable we calculated in our program rather than a fixed text.
Example:
$html =~ s#\bdogs\b#join(', ' , @animals)#ige; |
In this example we used "e" switch, which enables us to use a result of an expression as a replacement.
"e" means: evaluate right side as an expression.
If you want to do more complicated replacement using a chunk of code, you might want to use eval function with curly brackets.
Example: In this example if the target of a link in an html page is "_top", then we replace that link with a link to http://yahoo.com.
$html =~ s#eval{ |
|
|||