#!/usr/bin/perl # counter.cgi -- counts Web page hits # the first line of this script may have to be changed # if your system's Perl interpreter is not located in /usr/bin/perl # Written by P. Lutus Ashland, Oregon lutusp@arachnoid.com 2/21/96 # This is a cute, small, serviceable hits counter program. It uses the x-bitmap format # which is monochrome. It won't look very good if the textcolor and background are the same color # and the browser is made by Netscape. Every other place and browser, OK. # # Call the counter like this: You are Visitor Number # Ownername can have particular web page designators attached to it like this: Ownername_mypagename # This allows you to count pages independently. # The directory in which counter.cgi is stored must have world read, write and execute access. # The file counter.cgi must have world execute access. # $min_width is the minimum number of digits to print -- # the program will always print more as the number grows larger $min_width = 1; # set $collect_stats = 1 if you want to log the origins of accesses # in a file named Ownername.log $collect_stats = 1; $myaddr = '207.229.5.254'; $countname = "counter_dat"; # a default name for the counter file # This is a reasonable character set, sort of blocky but OK $counter_width = 8; $counter_height = 11; @dig_arr = ('0x00', '0x3c', '0x66', '0x66', '0x66', '0x66', '0x66', '0x66', '0x66', '0x66', '0x3c', # 0 '0x00', '0x30', '0x38', '0x30', '0x30', '0x30', '0x30', '0x30', '0x30', '0x30', '0x30', # 1 '0x00', '0x3c', '0x66', '0x60', '0x60', '0x30', '0x18', '0x0c', '0x06', '0x06', '0x7e', # 2 '0x00', '0x3c', '0x66', '0x60', '0x60', '0x38', '0x60', '0x60', '0x60', '0x66', '0x3c', # 3 '0x00', '0x30', '0x30', '0x38', '0x38', '0x34', '0x34', '0x32', '0x7e', '0x30', '0x78', # 4 '0x00', '0x7e', '0x06', '0x06', '0x06', '0x3e', '0x60', '0x60', '0x60', '0x66', '0x3c', # 5 '0x00', '0x38', '0x0c', '0x06', '0x06', '0x3e', '0x66', '0x66', '0x66', '0x66', '0x3c', # 6 '0x00', '0x7e', '0x66', '0x60', '0x60', '0x30', '0x30', '0x18', '0x18', '0x0c', '0x0c', # 7 '0x00', '0x3c', '0x66', '0x66', '0x66', '0x3c', '0x66', '0x66', '0x66', '0x66', '0x3c', # 8 '0x00', '0x3c', '0x66', '0x66', '0x66', '0x66', '0x7c', '0x60', '0x60', '0x30', '0x1c'); # 9 @digits = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); # So? Anything is possible! @envname = ( 'REMOTE_ADDR', 'REMOTE_HOST', 'HTTP_REFERER', 'HTTP_USER_AGENT', 'HTTP_ACCEPT', ); if ($ENV{COMSPEC} ne '') { # most definitely MSDOS, so use those old funky names @envname = keys(%ENV); } if ($ENV{'QUERY_STRING'} ne '') { $countname = $ENV{'QUERY_STRING'}; # get the file name from counter.cgi?ownername construct $countername = $countname . ".cnt"; } unless (-e $countername) { # unless this file already exists open (COUNT,">$countername"); # directory has to have world write permission for this to work print COUNT "0\n"; close COUNT; } $count = 0; # now get and increment the counter open (COUNT,$countername) || die "Content-type:text/plain\n\nCan't open $countername!\n"; $count = ; close COUNT; if ($ENV{'REMOTE_ADDR'} ne $myaddr) { $count++; } open (COUNT,">$countername"); # I don't lock access so this might break or not count right in busy sites print COUNT "$count\n"; # but locking has problems of its own ... close COUNT; if ($collect_stats) { # owner want to collect data on logons $logname = $countname . ".log"; unless (-e $logname) { # unless this file already exists open (LOG,">$logname"); # directory has to have world write permission for this to work print LOG "Count\tTime"; foreach $envlbl (@envname) { print LOG "\t$envlbl"; } print LOG "\n"; close LOG; } # done initializing stats file open (LOG,">>$logname"); # now enter this stat record $tim = &readtime; if ($ENV{'REMOTE_ADDR'} ne $myaddr) { print LOG "$count\t$tim"; foreach $envlbl (@envname) { print LOG "\t$ENV{$envlbl}"; } print LOG "\n"; } close LOG; } # end of collect_stats block $size = &fill_digits($count); # now show the actual count &print_digits($size); exit; sub fill_digits { $q = @_[0]; $i = 0; do { $digits[$i++] = $q % 10; $q = int($q/10); } while(($q != 0) || ($i < $min_width)); # force width to be at least $min_width $i = $i; # make it the return value } sub print_digits { $width = @_[0]; $cw = $width * $counter_width; $chh = $counter_height; # * 2; print "Content-type:text/plain\n\n"; #was "Content-type:image/x-xbitmap\n\n" print "#define counter_width $cw\n"; print "#define counter_height $counter_height\n"; print "static unsigned char counter_bits[] = {\n"; $start = 1; for($i=0;$i<$chh;$i=$i + 1) { #was $i + 2 for($j=$width-1;$j>=0;$j--) { # for($k=0;$k<2;$k++) { if ($start == 0) { print","; } print "$dig_arr[($digits[$j]*$chh)+$i+$k]"; $start = 0; # } } print "\n"; } print "};\n"; } sub readtime { local ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); sprintf ("%2.0f/%02.0f/%04.0f %2.0f:%02.0f:%02.0f",$mon+1,$mday,($year > 50)?$year+1900:year+2000,$hour,$min,$sec); # to the stack }