home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

HTML 4.0 Sourcebook
(Publisher: John Wiley & Sons, Inc.)
Author(s): Ian S. Graham
ISBN: 0471257249
Publication Date: 04/01/98

Bookmark It

Search this book:
 
Previous Table of Contents Next


Lines 22 through 29 attempt to lock the file (flock($cntfile,2)). Locking the file means that the running perl program is the only program that can modify the file and ensures that two users cannot simultaneously attempt to change the file. The program tries four times to lock the file, waiting one second between attempts. If it fails, it sets a default value for the string containing the counter value ($cnt) and skips the part of the program that actually reads the count file. If it succeeds in locking the file, it proceeds to the next phase, beginning at line 30, where the count file is opened, the count is read and incremented by 1, and the count is rewritten to the file, overwriting the old value. The file is then closed and the lock is released (flock($cntfile, 8)), freeing it for use by other users.

Line 39 begins the processing of the file returned to the client. The file is opened at line 40 and read in at line 42, into the array @array. When finished, the file is closed (line 43).

Line 45 prints the required content-type header. Lines 46 through 48 print the data to standard output, replacing every occurrence of the string <!-- counter --> by the counter string (line 47)—this is either the counter value from line 33 or the error string from line 25.

And that is it. The count is inserted, the document is returned, and the counter has been incremented by 1.

There are several limitations to this program. First, it is slow, since the program has to check every line for the string <-- counter -->. A second problem is associated with file permissions: The server that launches a gateway program usually runs with very limited ability to create and modify files in the directories on the server; thus this gateway program, when launched by the server, will probably not be able to create or modify the count file. If this is the case, the document author will have to create the count file by hand and change the


Figure 11.6 Listing of the perl gateway program counter.pl, which inserts an access count into a designated HTML document. The path to the designated HTML document is passed as extra path information in the URL used to access this program. Line numbers, in italics, are added for reference purposes only—they are not present in the original program.

1   #!/usr/local/bin/perl
2   if (defined($ENV{“PATH_TRANSLATED”}) ) {
3       $path = $ENV{“PATH_TRANSLATED”}# get file from extra path info
4 }
5 else {
6       &f_error(“No file specified\n”);
7 }
8   $file     = $path;    # Path to file to be processed
9   $cnt_file = $path;
10 $cnt_file =~ s/.*\///;  # Extract substring for counter filename
11  $path     =~ s/\/[\w-.;~]*$/\//;# get path to directory
12 
13  $cnt_file = $path.“.”.$cnt_file;# counter filename = path/.filename
14 
15  if( !(-e $cnt_file) ) {       # If count file doesn’t exist, create it
16     open(CNTFILE, “> $cnt_file”) ||
17             &f_error(“Unable to create count file\n”);   
18     print CNTFILE “0”;
19     close(CNTFILE);
20  }
21  $loops = 0;   # try 4 times to lock the count file
22  while ( flock($cnt_file,2) == -1 )  {
23  $loops++;
24  if( $loops > 4) {
25       $cnt = “-1 (Unable to lock counter)\n”;
26       goto PROCESS;    # If unable to lock, skip it.
27  }
28     sleep 1;
29  }
30  open(CNTFILE, “+< $cnt_file”)# open the counter file
31         || &f_error(“Unable to open counter file\n”);
32  $cnt = <CNTFILE>; # get the current count
33  $cnt++;       # increment count by one
34  seek(CNTFILE, 0, 0);  # rewind to start of file
35  print CNTFILE “$cnt”; # write out new count
36  close(CNTFILE);       # close the count file
37 flock($cntfile, 8);     # Unlock the count file
38 
39 PROCESS:
40  open(FILE, $file)     # Open file to process
41        || &f_error(“Unable to open file for processing\n”);
42  @array= <FILE>;   # Read in the file
43  close(FILE);
44        # Print out the document
45  print “Content-type: text/html\n\n”;
46  foreach (@array) {    # scan for special string, and
47     s/<!-- counter -->/ $cnt /i;# replace it by the count
48     print $_;
49  }
50  # Error Handling Subroutine
51  sub f_error {
52    print “Content-type text/plain\n\n”;
53    print “<HTML><HEAD>\n<TITLE>Error In Counter Script</TITLE>”;
54    print “\n</HEAD><BODY>\n<h2>Error</h2>\n<P>Error message: $_[0]”;
55    print “\n<P> Please report this problem to someone.׏;
56    print “\n</BODY></HTML>”;
57    die;
58  }

file characteristics so that the gateway program can modify it. Finally, we note that this program only counts accesses that pass through the gateway program. If the document is accessed via the URL

http://some.where.edu/path/file.html

then the access is not counted. In this regard, it is far better to invoke a counter using a parsed HTML document and a server-side exec.

There are several useful features you might want to add. For example, you might want to exclude your own machine or domain from the counting process, or you may prefer keeping all the count values in a single counter database file as opposed to having one file per document.

These and other variations on page counters are available in a number of counter programs, many of which are far more sophisticated than this example. The latter part of this chapter lists sites where such resources can be found.

Example 29: Inserting a Randomly Selected HTML Fragment

One useful parsed HTML trick is to use a gateway program to insert a randomly selected HTML text snippet into an HTML document. The perl program rot-new.pl is a simple implementation, which selects a file at random from a specified directory and inserts it inline within the parsed document. Assuming that the program is located in the server’s cgi-bin/ directory, the relevant server-side include instruction is:

<!--#exec cgi=“/cgi-bin/rot-new.pl” -->

When the server parses this document, it replaces this string by the output of the program rot-new.pl.

Figure 11.7 gives the listing for the program rot-new.pl.

The ideas are very simple. At line 8, the program prints a text/html content-type header—recall that this is required of CGI programs returning data to a parsed HTML document. The second block, at lines 12 to 14, retrieves a directory listing for the directory /svc/www/InsTest—this is the directory that contains the insertions. Lines 15 to 17 convert the filenames into absolute paths, excluding non-data files (i.e., directories), and store the list of files in the array @filenames. The subsequent if statement at line 22 checks to see if there are any files in this list—the program exits if there are none. The alternate block of the if , beginning at line 25, selects a filename at random (line 28), opens the file (line 29), reads in the file content and then closes the file (line 31), and prints the content to standard output (line 32). The output is the text included within the HTML document.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.