Problem with counter CGI script

T

T Stewart

I downloaded a free counter CGI from http://www.htmlgoodies.com/ and
it works fine on my server with one exception.

It has a feature where if someone else is detected using it without
permission, you can create a .LOCK file in the counter directory that
will always cause it to return 0 to the caller.

But I'm finding it will create the .LOCK file after the first call,
causing subsequent calls to return 0.

Here is where it goes to increment the counter:

sub incrementCount {
if (&lockFile == 1) {
$count = "0";
return;
}
&incrementTotalReads;
&unlockFile;
}


In doing so, it checks for the presence of a .LOCK file:

sub lockFile {
$lockCount = 0;
while (-f "$counterFile.lock") {
if ($lockCount > $lockWait) {
$count = 0;
return 1;
}
sleep 1;
$lockCount++;
}
open(LOCK,">$counterFile.lock") || die("Can't open
$counterFile.lock: $!\n");
return 0;
}

Shouldn't this just check for a LOCK file, not create one?

Thanks in advance,

Tim

//====================================
Full code is below FYI
Obtained free from http://www.htmlgoodies.com/
//====================================
#!c:\Perl\bin\perl.exe
$minLen = 7;

#This is absolute path of the directory where the counter files are
stored. Must be global-writeable.
$counterdir = "";

$lockWait = 5;

&ReadParse;
&initialize;
&loadbitmaps;
&incrementCount;
&generateBitmap;
&writeBitmap;
exit(0);

sub writeBitmap {
print "Content-type: image/x-xbitmap\n\n";
print "#define count_width ",$len*8,"\n#define count_height 16\n";
print "static char count_bits[] = {\n";
for($i = 0; $i < ($#bytes + 1); $i++) {
print "0x$bytes[$i]";
if ($i != $#bytes) {
print ",";
if (($i+1) % 7 == 0) {
print "\n" ;
}
}
}
print "};\n";
}

sub generateBitmap {
$count = $totalReads;
@bytes = ();
$len = length($count) > $minLen ? length($count) : $minLen;
$outtext = sprintf("%0${len}d",$count);
for ($i = 0; $i < $len*3; $i++ ) {
push(@bytes,"ff");
}
for ($y=0; $y < 10; $y++) {
for ($x=0; $x < $len; $x++) {
push(@bytes,substr($chars{substr($outtext,$x,1)},$y*3,2));
}
}
for ($i = 0; $i < $len*3; $i++ ) {
push(@bytes,"ff");
}
}


sub initialize {
if ($#in < 0) {
$scriptURL = "http://" . $ENV{'SERVER_NAME'} . ":" .
$ENV{'SERVER_PORT'} . $ENV{'SCRIPT_NAME'};
print ("Content-type: text/html\n\n");
print ("<HTML><HEAD><TITLE>Visitor counter</TITLE></HEAD>\n");
print ("<BODY><h1>counter.xbm</h1>To put a visitor counter like
this \n");
print ("<IMG SRC=\"$scriptURL?unique_id\">\n");
print ("on your web page, put an image tag in your HTML document
like:<br>\n");
print ("&lt;IMG SRC=\"$scriptURL?unique_id\"&gt;<br>\n");
print ("where \"unique_id\" is a unique identifier for your
counter.<p>\n");
print ("When creating a new counter you can set the starting value
by adding a count parameter to the URL. So if the counter \"qwerty\"
didn't exist, accessing the URL<br>\n");
print ("$scriptURL?qwerty&COUNT=1234<br>\n");
print ("will create a new counter called \"qwerty\" with its
counter set to 1234.<br>The counter can only be set when creating a
new counter.\n");
print ("<hr></BODY></HTML>\n");
exit;
}
else {
$countername = $in[0];
$countername =~ s/\W//g;
$counterFile = $counterdir . $countername;
if (!( -f $counterFile )) {
$start = $in{'COUNT'} -1;
open(CNTRFILE,">$counterFile");
print CNTRFILE "$start\n";
close(CNTRFILE);
}
}
}

sub incrementCount {
if (&lockFile == 1) {
$count = "0";
return;
}
&incrementTotalReads;
&unlockFile;
}


sub unlockFile {
unlink("$counterFile.lock");
}

sub lockFile {
$lockCount = 0;
while (-f "$counterFile.lock") {
if ($lockCount > $lockWait) {
$count = 0;
return 1;
}
sleep 1;
$lockCount++;
}
open(LOCK,">$counterFile.lock") || die("Can't open
$counterFile.lock: $!\n");
return 0;
}

sub incrementTotalReads {
if (-e $counterFile) {
open(COUNT,"$counterFile") || die("Can't open $counterFile:
$!\n");
}
$totalReads = <COUNT>;
chop $totalReads;
close(COUNT);
$totalReads++;
open(COUNT,">$counterFile") || die "$0: can\'t open $counterFile:
$!\n";
print (COUNT "$totalReads\n");
close(COUNT);
}

sub loadbitmaps {
$chars{'0'} = "c3 99 99 99 99 99 99 99 99 c3";
$chars{'1'} = "cf c7 cf cf cf cf cf cf cf c7";
$chars{'2'} = "c3 99 9f 9f cf e7 f3 f9 f9 81";
$chars{'3'} = "c3 99 9f 9f c7 9f 9f 9f 99 c3";
$chars{'4'} = "cf cf c7 c7 cb cb cd 81 cf 87";
$chars{'5'} = "81 f9 f9 f9 c1 9f 9f 9f 99 c3";
$chars{'6'} = "c7 f3 f9 f9 c1 99 99 99 99 c3";
$chars{'7'} = "81 99 9f 9f cf cf e7 e7 f3 f3";
$chars{'8'} = "c3 99 99 99 c3 99 99 99 99 c3";
$chars{'9'} = "c3 99 99 99 99 83 9f 9f cf e3";
}

# Perl Routines to Manipulate CGI input
# Copyright 1993 Steven E. Brenner
sub ReadParse {
if (@_) {
local (*in) = @_;
}

local ($i, $loc, $key, $val);

# Read in text
if ($ENV{'REQUEST_METHOD'} eq "GET") {
$in = $ENV{'QUERY_STRING'};
} elsif ($ENV{'REQUEST_METHOD'} eq "POST") {
for ($i = 0; $i < $ENV{'CONTENT_LENGTH'}; $i++) {
$in .= getc;
}
}

@in = split(/&/,$in);

foreach $i (0 .. $#in) {
# Convert plus's to spaces
$in[$i] =~ s/\+/ /g;

# Convert %XX from hex numbers to alphanumeric
$in[$i] =~ s/%(..)/pack("c",hex($1))/ge;

# Split into key and value.
$loc = index($in[$i],"=");
$key = substr($in[$i],0,$loc);
$val = substr($in[$i],$loc+1);
$in{$key} .= '\0' if (defined($in{$key})); # \0 is the multiple
separator
$in{$key} .= $val;
}

return 1;
}
 
G

Gunnar Hjalmarsson

T said:
I downloaded a free counter CGI from http://www.htmlgoodies.com/
and it works fine on my server with one exception.

It has a feature where if someone else is detected using it without
permission, you can create a .LOCK file in the counter directory
that will always cause it to return 0 to the caller.

But I'm finding it will create the .LOCK file after the first call,
causing subsequent calls to return 0.

I think you have misunderstood what the script does. If I'm
interpreting it correctly, the lock has nothing to do with using the
script without "permission" (permission to update a counter file??).

This is what I believe is happening:

- If a lock file exists, i.e. if the counter file is currently being
updated by somebody else, the script waits until the file has been
removed.

- Then it creates a new lock file, preventing others from accessing
the counter file while you are updating it.

- When the counter file has been updated, the lock file is removed.

If you are interested in a text based counter script option, resulting
in the info displayed at http://www.gunnar.cc/quotes.html, you can get
it at ftp://ftp.gunnar.cc/pub/gunnar/counter.pl

It displays only the most current hits (up to 30 days), and it would
possibly pass the critical eyes of the regulars in this group. ;-)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,821
Messages
2,569,725
Members
45,511
Latest member
Osiris-Team

Latest Threads

Top