#!/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 "