home *** CD-ROM | disk | FTP | other *** search
Wrap
#!/usr/local/bin/perl # counter.xbm - Perl script to keep count of users of a # home page. # # Credits: # Original C code: Frans van Hoesel (hoesel@chem.rug.nl) # Original port to Perl: Dan Rich (drich@corp.sgi.com) # Modifications for cgi: Michael Nelson (m.l.nelson@larc.nasa.gov) # Modifications for NSF: Mike Morse (mmorse@nsf.gov) # Modified from NSF version: Spencer Thomas (spencer.thomas@med.umich.edu) # Modified for flexible use: Stefan Powell (spowell@netaccess.on.ca) # # Note: This script should be renamed to counter.xbm # push(@INC,'/usr/local/etc/httpd/cgi-bin'); require 'cgi-lib.pl'; select STDOUT; $|=1; # Suck stuff from httpd &ReadParse; &initialize; &incrementCount; if ($ENV{PATH_INFO} && $ENV{PATH_INFO} =~ /.*\/text(\/.*)?/) { &writeTextCounter; } else { &generateBitmap; &writeBitmap; } exit(0); sub writeTextCounter { print ("Content-type: text/html\n\n"); print ("<HTML><HEAD><TITLE>Visitor counter</TITLE></HEAD>\n"); print ("<BODY>You are visitor number <B>$totalReads</B></BODY></HTML>\n"); } sub writeBitmap { print ("Content-type: image/x-xbitmap\n\n"); if ($isHigh) { printf ("#define count_width %d\n#define count_height 16\n", $len*8); } else { printf ("#define count_width %d\n#define count_height 10\n", $len*8); } printf STDOUT "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"); } # generateBitmap() - $count contains number to display # $minLen contains minimum number of digits to display # $isHigh is one for 16 bit high numbers (else 10) # $isInverse is one for reverse video (white on black); sub generateBitmap { $count = $totalReads; @bytes = (); $len = length($count) > $minLen ? length($count) : $minLen; $formattedCount = sprintf("%0${len}d",$count); if ($isHigh) { for ($i = 0; $i < $len*3; $i++ ) { if ($isInverse) { push(@bytes,"ff"); # add three blank rows to each digit } else { push(@bytes,"00"); } } } for ($y=0; $y < 10; $y++) { for ($x=0; $x < $len; $x++) { $digit = substr($formattedCount,$x,1); if ($isInverse) { # $inv = 1 for inverted text $byte = substr(@invdigits[$digit],$y*3,2); } else { $byte = substr(@digits[$digit],$y*3,2); } push(@bytes,$byte); } } if ($isHigh) { for ($i = 0; $i < $len*3; $i++ ) { if ($isInverse) { push(@bytes,"ff"); # add three blank rows to each digit } else { push(@bytes,"00"); } } } } sub initialize { $minLen = 7; # minimum number of digits in bigmap $isHigh = 1; # if 1, digits are 16 pixels high, to # allow room for border $isInverse = 1; # If 1, digits are white on black $counterdir = "counters/"; $remote_host = $ENV{'REMOTE_HOST'}; 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 ("<IMG SRC=\"$scriptURL?unique_id\"><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); } } $lockWait = 5; # number of seconds to wait for lock # bitmap for each digit # Each digit is 8 pixels wide, 10 high # @invdigits are white on black, @digits black on white @invdigits = ("c3 99 99 99 99 99 99 99 99 c3", # 0 "cf c7 cf cf cf cf cf cf cf c7", # 1 "c3 99 9f 9f cf e7 f3 f9 f9 81", # 2 "c3 99 9f 9f c7 9f 9f 9f 99 c3", # 3 "cf cf c7 c7 cb cb cd 81 cf 87", # 4 "81 f9 f9 f9 c1 9f 9f 9f 99 c3", # 5 "c7 f3 f9 f9 c1 99 99 99 99 c3", # 6 "81 99 9f 9f cf cf e7 e7 f3 f3", # 7 "c3 99 99 99 c3 99 99 99 99 c3", # 8 "c3 99 99 99 99 83 9f 9f cf e3"); # 9 @digits = ("3c 66 66 66 66 66 66 66 66 3c", # 0 "30 38 30 30 30 30 30 30 30 30", # 1 "3c 66 60 60 30 18 0c 06 06 7e", # 2 "3c 66 60 60 38 60 60 60 66 3c", # 3 "30 30 38 38 34 34 32 7e 30 78", # 4 "7e 06 06 06 3e 60 60 60 66 3c", # 5 "38 0c 06 06 3e 66 66 66 66 3c", # 6 "7e 66 60 60 30 30 18 18 0c 0c", # 7 "3c 66 66 66 3c 66 66 66 66 3c", # 8 "3c 66 66 66 66 7c 60 60 30 1c"); # 9 } 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; # forget it (would be nice to log though) } 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++ if $remote_host ne "kite.netcom.com"; open(COUNT,">$counterFile") || die "$0: can\'t open $counterFile: $!\n"; print (COUNT "$totalReads\n"); close(COUNT); }