[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

counter(s)

Posted on 2000-01-19
31
Medium Priority
?
508 Views
Last Modified: 2010-03-05
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...
0
Comment
Question by:tucats
  • 17
  • 13
31 Comments
 
LVL 3

Expert Comment

by:guadalupe
ID: 2366621
Do you want text display of the count or graphic?
0
 
LVL 1

Author Comment

by:tucats
ID: 2366774
I guess text display...  is there a major difference...?
0
 
LVL 1

Author Comment

by:tucats
ID: 2366782
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. http://www.experts-exchange.com/????.htm
and to track the hits all separately...
0
Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

 
LVL 2

Expert Comment

by:Mindo
ID: 2366939
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.
0
 
LVL 3

Accepted Solution

by:
guadalupe earned 800 total points
ID: 2366952
For text output use this script
#!/usr/local/bin/perl

#Name: counter.cgi

#Get query string values or form values
&parseInput;

# Application will access a value in a file,
# increment it, write this new value out to the
# file, and print the current value out to
# standard output. The script assumes that the file
# which maintains the necessary count (In this way
# you can use the same script for many different counts
#
# print out content type
print "Content-type: text/html\n\n";

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

# increment count and write back out to file
$value++;
open(COUNTER, "> $fields{'counter_file'}") || die "BUSY";
print COUNTER $value;
close(COUNTER);
#
print $value;

exit(0);

Then reference it in the html doc where the count is to appear like this:

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

!!!!!!Carefull!!!!!!!!!!

The SSI exec cgi command must be turned on.  On many comercial hosting services it is turned off.

Try this if it fails:

<!--#exec cmd="xxxxxxxxx/cgi-bin/couter.cgi" -->

The xxxxxx's indicate that you now must include the complete path to your script starting from root (/).
0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2366967
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").
0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2366998
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;
      }

}
0
 
LVL 1

Author Comment

by:tucats
ID: 2367438
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...
0
 
LVL 1

Author Comment

by:tucats
ID: 2367602
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...
0
 
LVL 1

Author Comment

by:tucats
ID: 2367758
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...
0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2367791
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.
0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2370675
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.
0
 
LVL 1

Author Comment

by:tucats
ID: 2378208
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;
}

}
0
 
LVL 1

Author Comment

by:tucats
ID: 2378248
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;
}

}
0
 
LVL 1

Author Comment

by:tucats
ID: 2379873
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...






0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2381254
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!!!
0
 
LVL 1

Author Comment

by:tucats
ID: 2381441
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...
0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2381477
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.

0
 
LVL 1

Author Comment

by:tucats
ID: 2381526
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... #####
0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2381854
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...

0
 
LVL 1

Author Comment

by:tucats
ID: 2382033
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...?


0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2382268
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.

0
 
LVL 1

Author Comment

by:tucats
ID: 2396598
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...?
0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2396860
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!
0
 
LVL 1

Author Comment

by:tucats
ID: 2397069
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...

0
 
LVL 1

Author Comment

by:tucats
ID: 2397125
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...

0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2397668
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...
0
 
LVL 1

Author Comment

by:tucats
ID: 2397747
thank you so much guadalupe...  i will play with this script this weekend...  

again thanks for your help...
0
 
LVL 1

Author Comment

by:tucats
ID: 2419641
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...

0
 
LVL 1

Author Comment

by:tucats
ID: 2476547
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...
0
 
LVL 3

Expert Comment

by:guadalupe
ID: 2477994
No problem.
0

Featured Post

Take Control of Web Hosting For Your Clients

As a web developer or IT admin, successfully managing multiple client accounts can be challenging. In this webinar we will look at the tools provided by Media Temple and Plesk to make managing your clients’ hosting easier.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

On Microsoft Windows, if  when you click or type the name of a .pl file, you get an error "is not recognized as an internal or external command, operable program or batch file", then this means you do not have the .pl file extension associated with …
A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (http://www.mongodb.org/downloads),  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
Six Sigma Control Plans
Suggested Courses

591 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question