Link to home
Start Free TrialLog in
Avatar of tucats
tucats

asked on

counter(s)

I have a project that I am working on, and I am not very well versed in perl...

what I need from perl is a counter that will work for "thousands" of web pages and sites... I heard perl was the place to look, and I am not knowledgeable in perl, so I don't know how to set up a counter program that will handle all of these websites "separately"...

If this question is easy... I apologize in the beginning...

But I would appreciate any input that you might have...

thank you...
Avatar of guadalupe
guadalupe

Do you want text display of the count or graphic?
Avatar of tucats

ASKER

I guess text display...  is there a major difference...?
Avatar of tucats

ASKER

I forgot to add that I was wanting the counter program...  (just one)...  to be able to handle "thousands" of sites that are subdomains...  i.e. https://www.experts-exchange.com/????.htm
and to track the hits all separately...
Do the following:

Write a CGI script (it's invoked from any browser remotely), which extracts the domain from where the user has connected from. This scripts store the data to the hash and saves it to the disk. Then you can interpret these results on your own. The hash key would be the domain and the value would be the number of hits.

You can extract the address of the user:

$addr = $ENV{REMOTE_HOST};

Then you store the results to the hash:

# This is your hash:

%myhash = ();

if(defined($myhash{$addr}))
{
  # We already have an address record - so we just increment the hit value.
  $myhash{$addr}++;
}
else
{
  # This was the first hit - we assign 1 to it.
  $myhash{$addr} = 1;
}

This way all your information about the user domains and hit counters is in the hash. You can print it, sort it or do whatever you want.

If you don't know Perl yet, you'll have to look for a tutorial or an introductory book.
ASKER CERTIFIED SOLUTION
Avatar of guadalupe
guadalupe

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Oh I forgot to say that you should create the counter files (text files which store current hit count) before trying to run the script.  Just to be on the safe side (and avoid the die "busy").
Sorry I know this is bad form but I forgot to copy the code of the sub &parseInput.  Here it is, just include it at the bottom of the file after the
exit(0);

#---------------------------------Parse Input---------------------------------------#
#                  Arguments:      NONE                                                                                    #
#                  Purpose            Standard Form/Query String Parsing                                          #
#                  Calls:            NONE                                                                                    #
#-----------------------------------------------------------------------------------#

sub parseInput()
{
      #Parse form variables
      if ($ENV{'REQUEST_METHOD'} eq "POST")
      {
            read(STDIN, $temp, $ENV{'CONTENT_LENGTH'});
      }

      elsif ($ENV{'REQUEST_METHOD'} eq "GET" )
      {
            $temp = $ENV{'QUERY_STRING'};
      }

      @pairs=split(/&/,$temp);
      
      foreach $item(@pairs)
      {
            ($key,$content)=split (/=/,$item,2);
            $content=~tr/+/ /;
            $content=~ s/%(..)/pack("c",hex($1))/ge;
            $fields{$key}=$content;
      }

}
Avatar of tucats

ASKER

guadalupe...

looks like a great answer...  I will have to check it out, it might take a few days...  just for reference, would you recommend a site that would offer a good tutorial or reference book, so that I can brush up on what I know...

thanks...
Avatar of tucats

ASKER

guadalupe...

looks like a great answer...  I will have to check it out, it might take a few days...  just for reference, would you recommend a site that would offer a good tutorial or reference book, so that I can brush up on what I know...

thanks...
Avatar of tucats

ASKER

guadalupe...

looks like a great answer...  I will have to check it out, it might take a few days...  just for reference, would you recommend a site that would offer a good tutorial or reference book, so that I can brush up on what I know...

thanks...
For on line stuff you could go to www.perl.com where they have references and tutorials but I would suggest you get a copy of Programming Perl published by O'Reilly (better known as The Camel Book)  Its the best.  Very well written, concise, interesting and... written by the author of perl.
Sorry bad form  again but this:

Number of visitors is :
<!--#exec cgi="couter.cgi" -->

Should be this:

Number of visitors is :
<!--#exec cgi="couter.cgi?counter_file=xxxxxx" -->

Where xxxxxxx is the name of the counter-file which corresponds to that site/page.
Avatar of tucats

ASKER

Is this right...?

#!/usr/local/bin/perl

$addr = $ENV{REMOTE_HOST};


%myhash = ();

if(defined($myhash{$addr}))
{
 
  $myhash{$addr}++;
}
else
{
 
  $myhash{$addr} = 1;
}




print "Content-type: text/html\n\n";


open(COUNTER, "< $fields{'counter.txt'}") || die "BUSY";
$value = <COUNTER>
close(COUNTER);

 
$value++;
open(COUNTER, "> $fields{'counter.txt'}") || die "BUSY";
print COUNTER $value;
close(COUNTER);
print $value;

exit(0);


sub parseInput()
{

if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $temp, $ENV{'CONTENT_LENGTH'});
}

elsif ($ENV{'REQUEST_METHOD'} eq "GET" )
{
$temp = $ENV{'QUERY_STRING'};
}

@pairs=split(/&/,$temp);

foreach $item(@pairs)
{
($key,$content)=split (/=/,$item,2);
$content=~tr/+/ /;
$content=~ s/%(..)/pack("c",hex($1))/ge;
$fields{$key}=$content;
}

}
Avatar of tucats

ASKER

Is this right...?

#!/usr/local/bin/perl

$addr = $ENV{REMOTE_HOST};


%myhash = ();

if(defined($myhash{$addr}))
{
 
  $myhash{$addr}++;
}
else
{
 
  $myhash{$addr} = 1;
}




print "Content-type: text/html\n\n";


open(COUNTER, "< $fields{'counter.txt'}") || die "BUSY";
$value = <COUNTER>
close(COUNTER);

 
$value++;
open(COUNTER, "> $fields{'counter.txt'}") || die "BUSY";
print COUNTER $value;
close(COUNTER);
print $value;

exit(0);


sub parseInput()
{

if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $temp, $ENV{'CONTENT_LENGTH'});
}

elsif ($ENV{'REQUEST_METHOD'} eq "GET" )
{
$temp = $ENV{'QUERY_STRING'};
}

@pairs=split(/&/,$temp);

foreach $item(@pairs)
{
($key,$content)=split (/=/,$item,2);
$content=~tr/+/ /;
$content=~ s/%(..)/pack("c",hex($1))/ge;
$fields{$key}=$content;
}

}
Avatar of tucats

ASKER

sorry...  i was using both mindo's and guadalupes answers and got everything confused...

guadalupe...  in your script...

#!/usr/local/bin/perl

print "Content-type: text/html\n\n";

open(COUNTER, "< $fields{'counter.dat}") || die "BUSY";
$value = <COUNTER>
close(COUNTER);

$value++;
open(COUNTER, "> $fields{'counter.dat}") || die "BUSY";
print COUNTER $value;
close(COUNTER);
#
print $value;

exit(0);

Do I need to add the:

sub parseInput()
{

if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $temp, $ENV{'CONTENT_LENGTH'});
}

elsif ($ENV{'REQUEST_METHOD'} eq "GET" )
{
$temp = $ENV{'QUERY_STRING'};
}

@pairs=split(/&/,$temp);

foreach $item(@pairs)
{
($key,$content)=split (/=/,$item,2);
$content=~tr/+/ /;
$content=~ s/%(..)/pack("c",hex($1))/ge;
$fields{$key}=$content;
}

}


.........???????

and how do I capture the address that the counter query is coming from and write it to "counter.dat"...?

then of course all I do is add the:


<!--#exec cgi="couter.cgi?counter_file=xxxxxx" -->

....  and would the "xxxxxxx" be something like "index.htm" ...?

I have tried all kinds of things and can't get this script to work...  

Please help...






Ok maybe I wasn't clear let me explain more.  The xxxxx would be the name of the counter file which coresponds to the site or page which includes:

<!--#exec cgi="couter.cgi?counter_file=xxxxxx" -->


This way you can always call the same program counter.cgi but pass it different "counter docs"  These counter docs contain a single line which is a numeric count.  You spoke of a program which could manage multiple sites so I believe the easiest is that whil;e you will have only one cgi script you will have multiple counter docs.  One for each site.   All the pages in one site will call the same counter doc.  For example:

<!--#exec cgi="couter.cgi?counter_file=experts-exchange-count.txt" -->

This SSI include could be placed on all the pages of the experts exhange site (or just the home page - depending how you want to do your counts)  Each time the program is it will access the counter doc which was passed to it as a parameter, open the doc, add one to the current count, write the new count to the doc, and output the number.
 
This way you can indicate different counter docs depending on who is calling the script.

Hope this helps!!!
Avatar of tucats

ASKER

quadalupe...

does this mean that i will have to create a new page... (xxxxxx)... for each page that i want counted...?

how can i get the program to create new pages automatically using:

$page = $ENV{'DOCUMENT_URI'};

because this counter is literally for "thousands" of web pages...

thanks...
Wait, do you want seperate counts for each page or for sites in general.  If you want for sites in general you can use one count doc for the whole site though it may be called by many pages.  Other wise we can edit the script like this:

if (-e "$path/$fields{'counter_file'}")
{

# get current count
open(COUNTER, "< $fields{'counter_file'}") || die "BUSY";
$value = <COUNTER>
close(COUNTER);
}


This modification skips the reading part of the file if it does not exist.  It will then go directly to the writing part which will create the file if it does not already exist.  The variable $path is helpful as you can define a distinct path from where the script is and not have to include it togeather with the name to the counter file.

Avatar of tucats

ASKER

guadalupe...

I restarted everything and came up with...:

#!/usr/local/bin/perl


$counter_file = "counter.dat";

$pagepath = $ENV{'DOCUMENT_URI'};

print "Content-type: text/html\n\n";

open(FILE, ">>$counter_file");
close(FILE);

open(FILE, "$counter_file");
@indata = <FILE>;
close(FILE);

$onoff = 0;
open(FILE, ">$counter_file");
foreach $temp (@indata)
{
      chop($temp);
      ($uri, $count) = split(/\|/, $temp);
      if ($uri eq $pagepath) {
            $count++;
            $onoff = 1;
            print FILE "$uri|$count\n";
            print "$count"; }
      else {      print FILE "$uri|$count\n"; }
}
if ($onoff eq 0) {
      print FILE "$pagepath|1\n";
      print "1"; }

close(FILE);


##### what i want is for the counter to create different data pages in a directory instead of storing all data on one doc... (counter.dat)...  that way it wont slow down as if it were searching a database... #####
No you have a problem here.  First, the last open which is used to write will erase you whole file because it is openj for writing and you only print one line, the line for the file/site which called the script.  This line will get written to the "new" counter file and all other data will be lost.  If you want to use on doc for multiple files you have to either input all the counter.dat info and then output it all in which case you will open the file for writing and let it destroy everything knowing that you will rewrite it all anyway OR open the file for append and use a pointer to reinsert the line corresponding to the file/site who made the call "over itself" with the new count.  The problem here is that if you tryly have lots of site/pages which call this prog and they all point to one data file you run the risk of having distinct calls overwriting each other.  If you use the previous solution you wont have to create the counter docs yourself and they could be one per site.  About slowing it down I don't know what relation there is to it searching a Dbase the two are unrelated.  The prog itself requires no database searching as the call indicates what counter.dat to open and therfore the scrtipt itself is fast.  Your solution in that sense will not be any faster.  And actually technically speaking it will be slower as you have to parse over lines until you find the one which corresponds.

It also has the problem which I explaind above which could also slow it down a little...  Stuff to think about...

Avatar of tucats

ASKER

Now are you saying that the script:

if (-e "$path/$fields{'counter_file'}")
{

# get current count
open(COUNTER, "< $fields{'counter_file'}") || die "BUSY";
$value = <COUNTER>
close(COUNTER);
}


will actually "create" separate "counter doc's" for each web page (they are separate pages under my main domain)..  instead of writing all data to one doc...  counter.dat...?


Yes, it will create the counter doc with the name you send to the script.  For example, if you put this SSI in a page:

<!--#exec cgi="couter.cgi?counter_file=experts-exchange-count.txt" -->

The script will check if the file exists.
(Remember that the $path variable must be correctly set so that the final evaluation of

if (-e "$path/$fields{'counter_file'}")

is something like:

if (-e "/usr/home/docs/experts-exchange-count.txt")

if the full path and document exists it will read the single line it contains which is a count and then open the doc for writing destroying its content and then rewriting the count + 1.  If the file doesn't exist it will skip the read and goto the write.  If you open a file for writing and the file doesn't exist perl creates it (provided of course it has write privledges in the specified dir)  Then an unitialized variable has a value of 0 so 0 + 1 wil be written to the file and presto you have your first hit.

Avatar of tucats

ASKER

guadalupe...  

i am sorry i haven't been back to you...  i have been out of touch...  i did rewrite the whole script and added a few variables including date and extra zeros...  you have been such a great help and always on top of things...

here is the script...  it is not done yet, but it works...

#!/usr/local/bin/perl
 

$data_dir = "/home/kidz4day/kidz4dayz-www/cgi-bin/counter/";

@valid_uri = ('/');

#@invalid_uri = ('.shtml/','.html/');

$show_link = "0";

$auto_create = "1";

$show_date = "1";

$lock_sec = "3";

$pad_size = "1";

print "Content-type: text/html\n\n";

$count_page = "$ENV{'DOCUMENT_URI'}";

&check_uri;

if ($count_page =~ /\/$/) {
   chop($count_page);
}

$count_page =~ s/[^\w]/_/g;
$lock_file = "$count_page\.lock";

&check_lock($lock_sec);

if (-e "$data_dir$count_page") {
   open(COUNT,"$data_dir$count_page");
   $line = <COUNT>;
   chop($line) if $line =~ /\n$/;
   close(COUNT);
   ($date,$count) = split(/\|\|/,$line);
}
elsif ($auto_create == 1) {
   &create;
}
else {
   &error('page_not_found');
}

$count++;
$print_count = $count;

$count_length = length($count);

for ($i = $pad_size;$i > $count_length;$i--) {
   $print_count = "0$print_count";
}

if ($show_date == 1) {
   if ($show_link =~ /http:\/\//) {
      print "<a href=\"$show_link\">$print_count</a> visitors since $date";
   }
   else {
      print "$print_count visitors since $date";
   }
}
else {
   if ($show_link =~ /http:\/\//) {
      print "<a href=\"$show_link\">$print_count</a>";
   }
   else {
      print "$print_count";
   }
}

open(COUNT,">$data_dir$count_page") || &error('could_not_increment');
print COUNT "$date\|\|$count";
close(COUNT);

&clean_up;

sub check_uri {
   $uri_check = "0";

   foreach $uri (@valid_uri) {
      if ($ENV{'DOCUMENT_URI'} =~ /$uri/) {
         $uri_check = "1";
         last;
      }
   }

   foreach $uri (@invalid_uri) {
      if ($ENV{'DOCUMENT_URI'} =~ /$uri/) {
         $uri_check = "0";
       last;
      }
   }

   if ($uri_check == 0) {
      &error('bad_uri');
   }
}

sub create {
   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
   @months = ("January","February","March","April","May","June","July",
            "August","September","October","November","December");
   $year += 1900;
   $date = "$months[$mon] $mday, $year";
   $count = "0";
   open(COUNT,">$data_dir$count_page") || &error('count_not_created');
   print COUNT "$date\|\|$count";
   close(COUNT);
}

sub error {
   $error = shift(@_);

   if ($error eq 'page_not_found') {
      print "[TextCounter Fatal Error: This Page Not Found\; Auto-Create Option Disabled]";
   }
   elsif ($error eq 'bad_uri') {
      print "[TextCounter Fatal Error: This Page Not In Valid URI]";
   }
   elsif ($error eq 'count_not_created') {
      print "[TextCounter Fatal Error: Could Not Write to File $datadir$count_page]";
   }
   elsif ($error eq 'could_not_increment') {
      print "[TextCounter Fatal Error: Could Not Increment Counter]";
   }
   exit;
}

sub check_lock {
   $time = $_[0];

   for ($i = 1;$i <= $time; $i++) {
      if (-e "$data_dir$lock_file") {
         sleep 1;
      }
      else {
         open(LOCK,">$data_dir$lock_file");
         print LOCK "0";
         close(LOCK);
         last;
      }
   }
}

sub clean_up {
   unlink("$data_dir$lock_file");
}




##### (I borrowed a few things) #####

hey quadalupe...

is there a way that i can define the variables in my SSI command...?  defining the variables $show_date and $pad_size...  that way i can customize the counter for individual people without changing the script for everyone...

i.e.  <!--#exec cgi="/cgi-bin/counter.cgi?show_date=1,pad_size=5"-->

this does not work... but is there a way i can send the values for the variables...?

thank you again...

and hey...  how do i accept your answer...?
This should work but I see in the code above that you have omitted a sub which is key to doing what you want:

sub parseInput()
{

if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $temp, $ENV{'CONTENT_LENGTH'});
}

elsif ($ENV{'REQUEST_METHOD'} eq "GET" )
{
$temp = $ENV{'QUERY_STRING'};
}

@pairs=split(/&/,$temp);

foreach $item(@pairs)
{
($key,$content)=split (/=/,$item,2);
$content=~tr/+/ /;
$content=~ s/%(..)/pack("c",hex($1))/ge;
$fields{$key}=$content;
}

}

This will parse varibales sent via a query string or a form.  Just call the sub like this:

&parseInput;

And remember to do it befroe you try and get at any of these values.  It will leave all the variables in a hash called %fields where the name is the key and the value the value

ex: $fields{'show_data=1'}

This is how I suggested you pass the name of the data file to counter.cgi so that it could dynamically lift read and update differenet counter files depending on which site/page was calling the cgi...  About accepting the answer I assume you already figured it out because I just got the points, thanks!
Avatar of tucats

ASKER

so how would i set that up...?

<!--#exec cgi="/cgi-bin/counter.cgi?$fields{'show_date=1,pad_size=5'}"-->

then add...

&parseinput;

above the variables or below the variables but above the "content type"...?

and add the actual "sub routine" with the other subs or first thing after the "content type"...?

i am sorry for my lack of knowledge but i am still trying to learn...  

thanks so much for your time, patience, and help...

Avatar of tucats

ASKER

so how would i set that up...?

<!--#exec cgi="/cgi-bin/counter.cgi?$fields{'show_date=1,pad_size=5'}"-->

then add...

&parseinput;

above the variables or below the variables but above the "content type"...?

and add the actual "sub routine" with the other subs or first thing after the "content type"...?

i am sorry for my lack of knowledge but i am still trying to learn...  

thanks so much for your time, patience, and help...

No, use this SSI:

<!--#exec cgi="/cgi-bin/counter.cgi?show_date=1&pad_size=5"-->

Then put the sub in the script counter.cgi and put the call to the script at the top of the cgi before you need any of the values you are trying to pass to it.  THEN... After the sub has been called you can refer to the values passed to the script using a hash which  the sub creates.   Followin the SSI example above the sub will create these tow has elements for you

$fields{'show_date=1'} whose value will be "1" for the example above AND
$fields{'pad_size'} whose value will be
"5"

In the example I originally gave you of how to include the name of a specific counter data file the example would be like this:

 <!--#exec cgi="couter.cgi?counter_file=site1.txt" --> or

<!--#exec cgi="couter.cgi?counter_file=site1&show_date=1,pad_size=5"-->  

depending on if you need to pass other variables.  Now the sub wil create a has element $fields{'counter_file'} with the value "site1.txt"

In this way you can mantain different counter docs for each site and the same cgi can manage them open for read and open for write which actually mangae the counting can be passes the name of the file to open as the value of the variable $fields{'counter_file'}  like this:

open(FILE, "$fields{'counter_file'}");

to read the count and then

open(FILE, ">$fields{'counter_file'}");

To destry and rewrite the file and then

print FILE $count++ to actually get the new value in.

In this way the script is 100% dynamic and the only work you have to do is put the right SSI in each page/site and that you have to do anyway...
Avatar of tucats

ASKER

thank you so much guadalupe...  i will play with this script this weekend...  

again thanks for your help...
Avatar of tucats

ASKER

i tried this...  and all i get is an...[an error occured while processing this directive]

#!/usr/local/bin/perl
 
$data_dir = "/home/kidz4day/kidz4dayz-www/cgi-bin/counter/";

@valid_uri = ('/');

#@invalid_uri = ('.shtml/','.html/');

$show_link = "0";

$auto_create = "1";

$show_date = "1";

$lock_sec = "3";

$pad_size = "1";

print "Content-type: text/html\n\n";

$count_page = "$ENV{'DOCUMENT_URI'}";

&parseInput;

&check_uri;

if ($count_page =~ /\/$/) {
   chop($count_page);
}

$count_page =~ s/[^\w]/_/g;
$lock_file = "$count_page\.lock";

&check_lock($lock_sec);

if (-e "$data_dir$count_page") {
   open(COUNT,"$data_dir$count_page");
   $line = <COUNT>;
   chop($line) if $line =~ /\n$/;
   close(COUNT);
   ($date,$count) = split(/\|\|/,$line);
}
elsif ($auto_create == 1) {
   &create;
}
else {
   &error('page_not_found');
}

$count++;
$print_count = $count;

$count_length = length($count);

for ($i = $pad_size;$i > $count_length;$i--) {
   $print_count = "0$print_count";
}

if ($show_date == 1) {
   if ($show_link =~ /http:\/\//) {
      print "<a href=\"$show_link\">$print_count</a> visitors since $date";
   }
   else {
      print "$print_count visitors since $date";
   }
}
else {
   if ($show_link =~ /http:\/\//) {
      print "<a href=\"$show_link\">$print_count</a>";
   }
   else {
      print "$print_count";
   }
}

open(COUNT,">$data_dir$count_page") || &error('could_not_increment');
print COUNT "$date\|\|$count";
close(COUNT);

&clean_up;

sub check_uri {
   $uri_check = "0";

   foreach $uri (@valid_uri) {
      if ($ENV{'DOCUMENT_URI'} =~ /$uri/) {
         $uri_check = "1";
         last;
      }
   }

   foreach $uri (@invalid_uri) {
      if ($ENV{'DOCUMENT_URI'} =~ /$uri/) {
         $uri_check = "0";
       last;
      }
   }

   if ($uri_check == 0) {
      &error('bad_uri');
   }
}

sub create {
   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
   @months = ("January","February","March","April","May","June","July",
            "August","September","October","November","December");
   $year += 1900;
   $date = "$months[$mon] $mday, $year";
   $count = "0";
   open(COUNT,">$data_dir$count_page") || &error('count_not_created');
   print COUNT "$date\|\|$count";
   close(COUNT);
}

sub error {
   $error = shift(@_);

   if ($error eq 'page_not_found') {
      print "[TextCounter Fatal Error: This Page Not Found\; Auto-Create Option Disabled]";
   }
   elsif ($error eq 'bad_uri') {
      print "[TextCounter Fatal Error: This Page Not In Valid URI]";
   }
   elsif ($error eq 'count_not_created') {
      print "[TextCounter Fatal Error: Could Not Write to File $datadir$count_page]";
   }
   elsif ($error eq 'could_not_increment') {
      print "[TextCounter Fatal Error: Could Not Increment Counter]";
   }
   exit;
}

sub check_lock {
   $time = $_[0];

   for ($i = 1;$i <= $time; $i++) {
      if (-e "$data_dir$lock_file") {
         sleep 1;
      }
      else {
         open(LOCK,">$data_dir$lock_file");
         print LOCK "0";
         close(LOCK);
         last;
      }
   }
}

sub clean_up {
   unlink("$data_dir$lock_file");
}

sub parseInput()
{

if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $temp, $ENV{'CONTENT_LENGTH'});
}

elsif ($ENV{'REQUEST_METHOD'} eq "GET" )
{
$temp = $ENV{'QUERY_STRING'};
}

@pairs=split(/&/,$temp);

foreach $item(@pairs)
{
($key,$content)=split (/=/,$item,2);
$content=~tr/+/ /;
$content=~ s/%(..)/pack("c",hex($1))/ge;
$fields{$key}=$content;
}

}


and the SSI is...:

<!--#exec cgi="/cgi-bin/counter.cgi?show_date=1&pad_size=5"-->



i don't know what i did wrong...

Avatar of tucats

ASKER

guadalupe...  don't worry about the answer to the above question...  i already figured it out...

#!/usr/local/bin/perl
 
sub parseInput()
{
  my( $temp, $item );
     read(STDIN, $temp, $ENV{'CONTENT_LENGTH'})

  if( $ENV{'REQUEST_METHOD'} eq "POST" );
     $temp = $ENV{'QUERY_STRING'}
 
    if( $ENV{'REQUEST_METHOD'} eq "GET" );
     @pairs=split(/&/,$temp);
  for $item(@pairs){
  my($key,$content) = split( /=/, $item, 2 );
  $content =~ tr/+/ /;
  $content =~ s/%(..)/pack("c",hex($1))/ge;

  $fields{$key}=$content;
}
}

&parseInput;


$data_dir = "/home/kidz4day/kidz4dayz-www/cgi-bin/counter/";

$show_date = $fields{ 'show_date' } or $show_date = 0;
$show_link = $fields{ 'show_link' } or $show_link = 0;
$pad_size = $fields{ 'pad_size' } or $pad_size = 1;
$auto_create = 1;
$lock_sec = 3;




print "Content-type: text/html\n\n";

$count_page = "$ENV{'DOCUMENT_URI'}";


if ($count_page =~ /\/$/) {
   chop($count_page);
}

$count_page =~ s/[^\w]/_/g;
$lock_file = "$count_page\.lock";

&check_lock($lock_sec);

if (-e "$data_dir$count_page") {
   open(COUNT,"$data_dir$count_page");
   $line = <COUNT>;
   chop($line) if $line =~ /\n$/;
   close(COUNT);
   ($date,$count) = split(/\|\|/,$line);
}
elsif ($auto_create == 1) {
   &create;
}
else {
   &error('page_not_found');
}

$count++;
$print_count = $count;

$count_length = length($count);

for ($i = $pad_size;$i > $count_length;$i--) {
   $print_count = "0$print_count";
}


if ($show_date == 1) {
   if ($show_link =~ /http:\/\//) {
      print "<a href=\"$show_link\">$print_count</a> visitors since $date";
   }
   else {
      print "$print_count visitors since $date";
   }
}
else {
   if ($show_link =~ /http:\/\//) {
      print "<a href=\"$show_link\">$print_count</a>";
   }
   else {
      print "$print_count";
   }
}

open(COUNT,">$data_dir$count_page") || &error('could_not_increment');
print COUNT "$date\|\|$count";
close(COUNT);

&clean_up;


sub create {
   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
   @months = ("January","February","March","April","May","June","July",
            "August","September","October","November","December");
   $year += 1900;
   $date = "$months[$mon] $mday, $year";
   $count = "0";
   open(COUNT,">$data_dir$count_page") || &error('count_not_created');
   print COUNT "$date\|\|$count";
   close(COUNT);
}

sub error {
   $error = shift(@_);

   if ($error eq 'page_not_found') {
      print "[TextCounter Fatal Error: This Page Not Found\; Auto-Create Option Disabled]";
   }
   elsif ($error eq 'bad_uri') {
      print "[TextCounter Fatal Error: This Page Not In Valid URI]";
   }
   elsif ($error eq 'count_not_created') {
      print "[TextCounter Fatal Error: Could Not Write to File $datadir$count_page]";
   }
   elsif ($error eq 'could_not_increment') {
      print "[TextCounter Fatal Error: Could Not Increment Counter]";
   }
   exit;
}

sub check_lock {
   $time = $_[0];

   for ($i = 1;$i <= $time; $i++) {
      if (-e "$data_dir$lock_file") {
         sleep 1;
      }
      else {
         open(LOCK,">$data_dir$lock_file");
         print LOCK "0";
         close(LOCK);
         last;
      }
   }
}

sub clean_up {
   unlink("$data_dir$lock_file");
}



##### again...  thank for your support...
No problem.