Click Here!
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.

Perl CGl Programming: No experience required.
(Publisher: Sybex, Inc.)
Author(s): Erik Strom
ISBN: 0782121578
Publication Date: 11/01/97

Bookmark It

Search this book:
 
Previous Table of Contents Next


There are two for loops in this block of code, an inner and outer loop. The outer loop:

   for ($n = 0; $n < $TotalHits; $n++)
           {

is intended to step through @IPArray, which is the list of IP addresses taken directly from the log file. Many of them are duplicates, because an entry is created in the log every time a client makes a request of the Web server. We want to distill this list down to individual IPs and count the number of requests that each of them makes.

The inner loop takes care of the distillation:

   for ($p = 0; $p < $HitCount; $p++)
       {
       if ($IPArray[$n] eq $IPHits[$p])
           {
           $NumHits[$p]++;
           last;         # Same as break in C
           }
       }

Remember that the variable $HitCount stores the number of individual IPs. This for loop steps through the second array checking for an IP address in $IPArray[$n] that matches the one in $IPHits[$p]. If a match is found, the

@NumHits array member at the same index, which is the value in $p, is incremented. This allows us to associate an IP address with a hit count; the IP address in one array and the hit count in another both have the same index numbers.

This is the point at which a new Perl statement, last, is called. Sometimes you need a way to break out of a loop before it’s finished (in fact, the identical statement in the C and C++ languages is break). In this example, we have satisfied the test in the if conditional code block, so we don’t want to continue through until the loop completes. By calling last at this point, the loop ends.

The last part of the outer loop

   # If $p == $HitCount, no matches were found. This is a new
   # IP address, so add it to the list.

         if ($p == $HitCount)
             {
             $IPHits[$HitCount] = $IPArray[$n];
             $NumHits[$HitCount]++;
             $HitCount++;
             }

checks the value in $p against that in $HitCount. If they are equal, it means the inner loop completed without finding a match, which means that this is another unique IP address and we can add it to the list. Notice that the two counters are incremented, too.

Counting Hits on the Entire Log Directory

You have gone through one IIS log file and extracted enough information from it to determine the number of hits from individual IP addresses in that file. With an extension to hitcnt.pl, you can extend your reach to the whole directory of IIS log files.

Perl, as usual, provides the method in a very straightforward fashion. Perl is able to handle directories in much the same way that it handles files: by opening, reading, and closing them. The main difference is that you have to use a new set of Perl functions to do the job:

  opendir, which returns a handle to the directory
  readdir, which returns the list of files in the directory
  closedir, which closes the directory handle

The specification for opendir is

   opendir (HANDLE, PATH);

where HANDLE is the handle that you will use in subsequent references to the directory and PATH is the full path to the directory.

To read the directory entries, use

   readdir (HANDLE);

which can fill a list variable with the contents of the directory as in

   @FileList = readdir (HANDLE);


WARNING:  UNIX and Windows directories always contain two special files designated by dots. The current directory is named “.” and the parent directory is “..”. You will find very few uses for these special files if you just want a list of file names from a particular directory. You need to explicitly bypass them if you don’t want to use them.
The Perl-C-UNIX Directory Functions

The directory functions in Perl are directly descended from—in fact, are virtually copies of—the dirent functions in the C standard library, which, of course, is descended from UNIX. Perl doesn’t give you access to all of the information you can obtain with the C library functions, but the functions are called in the same way.

In addition to opendir, readdir and closedir, there are three other Perl functions for manipulating directories:

  rewinddir, specified as rewinddir (HANDLE), which “rewinds” a directory handle back to its first entry.
  seekdir, specified as seekdir (HANDLE, POSITION), where POSITION is a place in the directory where the next readdir will take place (at the fifth or sixth file name, for example).
  telldir, specified as telldir (HANDLE), which returns the current position in the directory.

To change htcnt.pl to read and process a whole directory, you will:

1.  Get a handle for the log file directory with opendir.
2.  Read all of the files into an array with readdir.
3.  Process the files one at a time as you did in the previous section.


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.