#!/usr/local/bin/perl ################################################################################# # # # THE COOKIE COUNTER! # # # # ccounter.cgi Version 1.3 # # # # Written by Nick Donaldson - countmaster@psyclops.com # # # # Created 12/12/96 Last Modified 4/29/97 # # # # Copyright 1997 CLIQ Services Coop www.cliq.com # # # # Documentation: http://www.psyclops.com/ccounter/ # # # # This program is provided as freeware and may be freely used, as # # long as this banner is left intact. # # All that I ask in return for use of this program is that if you are # # using this program in your site, please let me know so I can check it # # out! # # # ################################################################################# # # # counter.cgi is a simple program to generate a graphical web site # # counter using server-side includes. It uses cookies to ensure that each # # visitor is counted once only per session, and contains provision for # # playing an embedded sound file on the first hit, and either displaying # # the count without incrementing, or incrementing without displaying. # # # ################################################################################# # # # Variables used: # # # # $backup Backup count # # $backupfile Backup file # # $baseurl Base URL of your homepage # # $count Hit count from file # # $counterfile Name of counter file # # $graphicsdir Path to graphics dir for # gifs # # $graphicsurl URL to graphics dir for printing # # $image Temporary digit storage # # $imgsrc Image name for html # # $nocount Flag for no increment # # $noshow Flag for no display # # $page Name of page to be counted # # $sound Name of soundfile to be played # # $soundurl URL of soundfile # # $start Flag for printing of trailing 0's # # $uselock Flag for using file locking # # $lockfile Name of file used for locking # # $waitfile Counter for locking wait time # # # # @images Array containing count in digits # # %gifs Array containing names of gif files # # # ################################################################################# # # # Usage: # # # # Each page to be counted must be assigned a unique name. For instance, # # if you are counting hits to index.shtml, assign the name "index". # # Create two new text files in the same directory as the file to be # # counted: # # # # NAME.ctr (in this example, "index.ctr") # # NAME.bak (in this example, "index.bak") # # # # And set their attributes to group r/w. This way, the cgi can write to # # the files. # # # # Next, copy the digit gif files to a graphics directory (the default is # # /graphics/ # # # # The counter is called as a server side include. You should check how # # your server handles SSIs, but the call will generally be contained in a # # *.shtml file and should look something like: # # # # # # # # Where PAGENAME = the unique name assigned to the page # # COMMAND = additional parameter passed to program # # # # In our example, the basic call would look like: # # # # # # # # COMMAND allows three seperate options: # # # # nocount : Display the count but do not increment # # noshow : Increment the count but do not display # # SOUNDFILE : path/name of soundfile to embed. # # # # examples would be: # # # # # # # # # # # # If you want to take advantage of the cookie functions, you must add # # meta tags into your html pages to set the cookies. The top of your # # html should look like this: # # # # # # # # # # Title # # # # ......etc...... # # # # Where PAGENAME = the unique name assigned to the page. # # # # In our example, the meta tag would be: # # # # # # # # Now, each time the page is loaded, a temporary cookie will be set that # # expires at the end of the session, ie when Netscape is closed. # # The program checks for the existence of this cookie, and if it exists, # # displays the count only, without incrementing. This ensures that each # # visitor is counted once only, even if they reload the page. # # # # File Locking: # # If you wish to use the locking routines, you must uncomment the line # # marked and add a directory called 'lockdir' to each html directory that # # you are using the counter with. Change the permissions on the # # 'lockdir' directories to 777 - ie, group and world writable. Now, each # # time that the program is run, it checks for the existence of the lock # # file corresponding to the page that it was called from. If the lock # # file exists, it means that another user is incrementing the count, and # # writing to the counter file may corrupt it. The programs waits until # # the lockfile disappears and increments, or times out after 3 seconds # # and displays the count with no increment. # # # ################################################################################# # recent mods: # 4/29/97 added file locking to prevent counter file overwriting # 4/3/97 fixed sound problem # 4/1/97 backup function added #------------------------------------------------------------------------------------ # Set these two variables to reflect your website structure: # the root level of your web site, often http://www.yourisp.com/~yourid $baseurl = "http://www.psyclops.com"; # change the following string to the directory where the number graphics will be stored # note there is no opening slash: the example dir would tell the program to look in # http://www.psyclops.com/graphics/ for the gifs. $graphicsdir = "graphics"; # Uncomment the following line if you wish to use the file locking routines: $filelock = 1; #------------------------------------------------------------------------------------ # initialize variables &do_init; # check the lockfile if ($filelock) { &check_lock; } # increment counter if the nocount tag is omitted (default = count) if (!$nocount) { &inc_counter; } # send img src tags to browser if the noshow tag is omitted (default = show) if (!$noshow) { &print_images; } # delete the lockfile if ($filelock) { &delete_lock; } sub do_init { # get the arguments passed from the environment: $page = $ARGV[0]; # - tells the program which page is to be counted # check for no increment to counter: if ($ARGV[1] eq "nocount") { $nocount = "1"; } # check for no display of counter: elsif ($ARGV[1] eq "noshow") { $noshow = "1"; } else { $sound = $ARGV[1]; # - sets sound file to play on first access } # initialize some variables: # construct the graphics url $graphicsurl = sprintf("%s/%s",$baseurl,$graphicsdir); # build name of file containing current count $counterfile = sprintf("%s.%s", $page,"ctr"); # build name of lock file $lockfile = sprintf("%s/%s.%s","lockdir",$page,"lock"); # build name of file containing count backup $backupfile = sprintf("%s.%s", $page,"bak"); #build the sound url $soundurl = sprintf("%s/%s",$baseurl,$sound); # create gif urls %gifs = ("1","$baseurl/graphics/1.gif","2","$baseurl/graphics/2.gif","3","$baseurl/graphics/3.gif","4","$baseurl/graphics/4.gif","5","$baseurl/graphics/5.gif","6","$baseurl/graphics/6.gif","7","$baseurl/graphics/7.gif","8","$baseurl/graphics/8.gif","9","$baseurl/graphics/9.gif","0","$baseurl/graphics/0.gif"); # read the current value of the counter: open (COUNTER, $counterfile); $count = ; close (COUNTER); # read the current value of the backup: open (BACKUP, $backupfile); $backup = ; close (BACKUP); # backup the counter file iff counter > backup # to prevent loss of count in the event of program failure / server crash etc. # if you notice that the count has dropped drastically, simply take the number # in the *.ctr file and add it to the *.bak file to get the actual current value. if ($count > $backup) { open (BACKUP, "> $backupfile"); print BACKUP $count; close (BACKUP); } } sub check_lock { $waittime = 0; # wait until lockfile has gone or 3 seconds have elapsed while ((-f $lockfile) && ($waittime <=30)) { sleep(.1); $waittime++; } # if lockfile still exists, do not increment count and return. if (-f $lockfile) { $nocount=1; return; } # create and open the lockfile: open (LOCK, "> $lockfile") || print "$!
\n" } sub delete_lock { if (-f $lockfile) { system "rm $lockfile\n"; } } sub inc_counter { # check cookie to see if this is the first hit this session, or that the browser is not excluded: # (excluding a browser from being counted is useful if you want to be able to check your own pages # without being counted. Simply add the following line to your cookies.txt or magic cookie file: # www.yourdomain.com FALSE FALSE 946598400 my_cookie exclude # note that items are spaced by tabs. # Alternatively, simply upload the file exclude_browser.html to your webspace and view it in the # browser you want to be excluded. This file will write a permanent cookie that will exclude it # from being counted. The accompanying file unexclude_browser.html will remove the cookie. # check for pertinent cookies if ((!($ENV{'HTTP_COOKIE'} =~ /$page/)) && (!($ENV{'HTTP_COOKIE'} =~ /exclude/))) { # increment counter and write to file: $count++; open (COUNTER, "> $counterfile"); print COUNTER $count; close (COUNTER); # check to see if a greeting sound is required. Note that the sound is only played for the # first hit to a page, and only if specified. if ($sound) { print ""; } } } sub print_images { # generate integer values for each digit of counter, up to 999,999, and store in an array: @images = ( (int($count/100000))-((int($count/1000000)*10)), (int($count/10000))-((int($count/100000)*10)), (int($count/1000))-((int($count/10000)*10)), (int($count/100))-((int($count/1000)*10)), (int($count/10))-((int($count/100)*10)), (int($count))-((int($count/10)*10)) ); # run through values of digits, starting from highest: foreach $image(@images) { # print an image if EITHER there is a positive value OR there has already been a digit printed # (this prints trailing zeroes if $start is defined) if ($image || $start) { # build image path, name, and alternate number value: $imgsrc = sprintf("%s %s=%s", "$gifs{$image}","alt","$image"); print ""; # set start tag if an image has been printed: $start = "YES"; } } }