When you're
looking around on the Web, going from site to site, you may have
seen virtual documents that greet you, pages with graphics that
are created "on the fly," or sizzling animations. These are all
examples of graphic creation and manipulation using CGI. There are
numerous tools and utilities that allow you to create documents
such as these very quickly and easily.
What is a dynamic (or virtual)
home page? It's a document that looks different when viewed at different
times or by different people. For example, you may want to display
a random fortune cookie when someone visits your home page. If you
conduct business on the Web, you might want to use a dynamic document
to advertise different products when someone accesses the document.
In order to set up a virtual home page, you have to modify
certain configuration settings to ask the server to execute a CGI
program instead of displaying a static HTML file.
Normally, the NCSA server looks for the file
index.html in the document root directory and
displays it.
The following line when added to the server resource configuration
file (srm.conf) forces the server to execute
the CGI program index.html (a Perl program
doesn't have to end with a .pl extension):
AddType application/x-httpd-cgi index.html
The AddType
server directive was originally introduced in Chapter 1, The Common
Gateway Interface. It allows you
to execute CGI programs located outside the cgi-bin
directory.
Under the CERN server, you can do something
similar by adding the following line to httpd.conf:
Exec /index.html /usr/local/etc/httpd/cgi-bin/index.pl
Now, let's create a simple virtual home page that displays
a greeting, based on the time of the access, and a message indicating
whether the webmaster is currently logged in. Of course, this is
a very simple example that illustrates the creation of a home page
with dynamic information. You can also create a virtual home page
using Server Side Includes, as shown in Chapter 5, Server Side Includes.
#!/usr/local/bin/perl
print "Content-type: text/html", "\n\n";
$webmaster = "shishir";
($seconds, $minutes, $hour) = localtime (time);
The localtime function takes the current
time (in seconds since 1970) and returns a nine-element array consisting
of the date and time for the current time zone. We will be using
only the first three elements of the array, which contain the seconds,
minutes, and hour values (in the military 24-hour format).
If your system's time zone is not configured properly, you
will get the date and time for the Greenwich time zone (GMT). In
such a case, you will need to use the TZ environment variable to
set the proper time zone before you call the localtime
function:
This sets your
time zone
to Eastern Standard Time (EST). You can see some of the other time
zones by looking at the following document:
https://wwwcrasys.anu.edu.au/reference/world.timezones.html
To return to the program:
if ( ($hour >= 23) || ($hour <= 6) ) {
$greeting = "Wow, you are up late";
} elsif ( ($hour > 6) && ($hour < 12) ) {
$greeting = "Good Morning";
} elsif ( ($hour >= 12) && ($hour <= 18) ) {
$greeting = "Good Afternoon";
} else {
$greeting = "Good Evening";
}
Since the localtime function returns
the hour in a 24-hour format, we can use this to our advantage.
It is much easier to select a greeting based on this format because
the time scale is continuous from 0-23, and we don't have to worry
about determining whether an hour value of "12" indicates 12:00
A.M. or 12:00 P.M.
if ($hour > 12) {
$hour -= 12;
} elsif ($hour == 0) {
hour = 12;
}
$time = sprintf ("%02d:%02d:%02d", $hour, $minutes, $seconds);
For display purposes, however, the hour is converted into
the regular 12-hour format. The sprintf
function formats a string according to the field specifiers. In
this case, we want the hours, minutes, and seconds to be two digits
in length, so a minute value of "9" will be displayed as "09". The
formatted string is stored in the $time variable.
open(CHECK, "/usr/bin/w -h -s $webmaster |");
if (<CHECK> =~ /$webmaster/) {
$in_out = "I am currently logged in.";
} else {
$in_out = "I just stepped out.";
}
This open
command might look strange to you if you're new to Perl. Instead
of opening a file, it opens a pipe for input. In other words, Perl
executes the UNIX program /usr/bin/w
and redirects its output to the file handle CHECK.
As you'll see throughout the book, this technique allows us to communicate
with other utilities and programs by sending and receiving data
through a pipe.
We pass the value stored in $webmaster
as the argument to /usr/bin/w, which returns
all of the system processes "owned" by $webmaster.
We don't really need to know much about the processes. The only
thing we're concerned about is whether any processes for $webmaster
exist, indicating that he/she is logged in. Depending on this, the
$in_out variable is set to a specific message.
Once we're done, we close the file handle. It's a good practice
to clean up all resources when you're done with them. Now, we're
ready to output the information that we've gathered so far.
Instead of using a print statement to send each line
to standard output, we'll use a "here" document. What is that, you
may ask? See for yourself:
This statement outputs everything below it to standard output
until it reaches the string "End_of_Homepage." This saves us from
typing print before each line that we want
to output.
Since we output a MIME content type of
text/html, we need to output some HTML
information:
<HTML>
<HEAD><TITLE>Welcome to my home page</TITLE></HEAD>
<BODY>
$greeting! It is $time. Here are some of my favorite links:
.
. (some information)
.
<ADDRESS>
Shishir Gundavaram ($in_out)
</ADDRESS>
</BODY></HTML>
End_of_Homepage
exit(0);
The whole point of this exercise is that you can "embed" another
language (like HTML) into a CGI script. But the
variables from the enclosing script can be used within
the HTML--Perl
substitutes the right value for each variable. That's what makes
this page dynamic rather than static. An important thing to note
about "here" documents is that they follow the same conventions
as the regular print statement, in that Perl
will evaluate only variables, and not function calls and other expressions.
In this program, we output a MIME content
type of text/html and followed that with the
HTML code. But we're not limited to just creating
dynamic HTML documents; we can create dynamic
graphics as well, as we'll see next.