home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 25 / amigaformatcd25.iso / websites / novadesign / counter.cgi < prev    next >
Text File  |  1997-10-23  |  7KB  |  216 lines

  1. #!/usr/local/bin/perl
  2. # counter.xbm - Perl script to keep count of users of a
  3. # home page.
  4. #
  5. # Credits:
  6. #   Original C code:  Frans van Hoesel (hoesel@chem.rug.nl)
  7. #   Original port to Perl: Dan Rich (drich@corp.sgi.com)
  8. #   Modifications for cgi: Michael Nelson (m.l.nelson@larc.nasa.gov)
  9. #   Modifications for NSF: Mike Morse (mmorse@nsf.gov)
  10. #   Modified from NSF version: Spencer Thomas (spencer.thomas@med.umich.edu)
  11. #   Modified for flexible use: Stefan Powell (spowell@netaccess.on.ca)
  12. #
  13. # Note: This script should be renamed to counter.xbm
  14. #
  15.  
  16. push(@INC,'/usr/local/etc/httpd/cgi-bin');
  17. require 'cgi-lib.pl';
  18.  
  19. select STDOUT;
  20. $|=1;
  21.  
  22. # Suck stuff from httpd
  23. &ReadParse;
  24.  
  25.  
  26.    &initialize;
  27.    &incrementCount;     
  28.    if ($ENV{PATH_INFO} && $ENV{PATH_INFO} =~ /.*\/text(\/.*)?/) {
  29.        &writeTextCounter;
  30.    } else {
  31.        &generateBitmap;
  32.        &writeBitmap;
  33.    } 
  34.    exit(0);
  35.  
  36.  
  37. sub writeTextCounter {
  38.     print ("Content-type: text/html\n\n");
  39.     print ("<HTML><HEAD><TITLE>Visitor counter</TITLE></HEAD>\n");
  40.     print ("<BODY>You are visitor number <B>$totalReads</B></BODY></HTML>\n");
  41. }
  42.  
  43. sub writeBitmap {
  44.    print ("Content-type: image/x-xbitmap\n\n");
  45.    if ($isHigh) {
  46.       printf ("#define count_width %d\n#define count_height 16\n", 
  47.               $len*8);
  48.    }
  49.    else {
  50.       printf ("#define count_width %d\n#define count_height 10\n", 
  51.               $len*8);
  52.    }
  53.    printf STDOUT "static char count_bits[] = {\n";
  54.    for($i = 0; $i < ($#bytes + 1); $i++) {
  55.       print("0x$bytes[$i]");
  56.       if ($i != $#bytes) {
  57.          print(",");
  58.          if (($i+1) % 7 == 0) {
  59.             print("\n");
  60.          }
  61.       }
  62.    }
  63.    print("};\n");
  64. }
  65.  
  66. # generateBitmap() - $count contains number to display
  67. #                    $minLen contains minimum number of digits to display
  68. #                    $isHigh is one for 16 bit high numbers (else 10)
  69. #                    $isInverse is one for reverse video (white on black);
  70. sub generateBitmap {
  71.    $count = $totalReads;
  72.    @bytes = ();
  73.    $len = length($count) > $minLen ? length($count) : $minLen;
  74.    $formattedCount = sprintf("%0${len}d",$count);
  75.    if ($isHigh) {
  76.       for ($i = 0; $i < $len*3; $i++ ) {
  77.          if ($isInverse) {
  78.             push(@bytes,"ff");       # add three blank rows to each digit
  79.          }
  80.          else {
  81.             push(@bytes,"00");
  82.          }
  83.       }
  84.    }
  85.    for ($y=0; $y < 10; $y++) {
  86.        for ($x=0; $x < $len; $x++) {
  87.            $digit = substr($formattedCount,$x,1);
  88.            if ($isInverse) {             # $inv = 1 for inverted text
  89.                $byte = substr(@invdigits[$digit],$y*3,2);
  90.            } 
  91.            else {
  92.                $byte = substr(@digits[$digit],$y*3,2);
  93.            }
  94.            push(@bytes,$byte);
  95.        }
  96.    }
  97.    if ($isHigh) {
  98.       for ($i = 0; $i < $len*3; $i++ ) {
  99.          if ($isInverse) {
  100.             push(@bytes,"ff");       # add three blank rows to each digit
  101.          }
  102.          else {
  103.             push(@bytes,"00");
  104.          }
  105.       }
  106.    }
  107. }
  108.  
  109.  
  110. sub initialize {
  111.    $minLen = 7;           # minimum number of digits in bigmap
  112.    $isHigh = 1;           # if 1, digits are 16 pixels high, to
  113.                           # allow room for border
  114.    $isInverse = 1;        # If 1, digits are white on black
  115.    $counterdir = "counters/";
  116.    $remote_host = $ENV{'REMOTE_HOST'};
  117.    if ($#in < 0) {
  118.      $scriptURL = "http://" . $ENV{'SERVER_NAME'} . ":" . $ENV{'SERVER_PORT'} . $ENV{'SCRIPT_NAME'};
  119.      print ("Content-type: text/html\n\n");
  120.      print ("<HTML><HEAD><TITLE>Visitor counter</TITLE></HEAD>\n");
  121.      print ("<BODY><h1>counter.xbm</h1>To put a visitor counter like this \n");
  122.      print ("<IMG SRC=\"$scriptURL?unique_id\">\n");
  123.      print ("on your web page, put an image tag in your HTML document like:<br>\n");
  124.      print ("<IMG SRC=\"$scriptURL?unique_id\"><br>\n");
  125.      print ("where \"unique_id\" is a unique identifier for your counter.<p>\n");
  126.      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");
  127.      print ("$scriptURL?qwerty&COUNT=1234<br>\n");
  128.      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");
  129.      print ("<hr></BODY></HTML>\n");
  130.      exit;
  131.    }
  132.    else {
  133.      $countername = $in[0];
  134.      $countername =~ s/\W//g;
  135.      $counterFile = $counterdir . $countername;
  136.      if (!( -f $counterFile )) {
  137.        $start = $in{'COUNT'} -1;
  138.        open(CNTRFILE,">$counterFile");
  139.        print CNTRFILE "$start\n";
  140.        close(CNTRFILE);
  141.      }
  142.    }
  143.  
  144.    $lockWait = 5;         # number of seconds to wait for lock
  145.    # bitmap for each digit
  146.    #  Each digit is 8 pixels wide, 10 high
  147.    #  @invdigits are white on black, @digits black on white
  148.    @invdigits = ("c3 99 99 99 99 99 99 99 99 c3",  # 0
  149.                  "cf c7 cf cf cf cf cf cf cf c7",  # 1
  150.                  "c3 99 9f 9f cf e7 f3 f9 f9 81",  # 2
  151.                  "c3 99 9f 9f c7 9f 9f 9f 99 c3",  # 3
  152.                  "cf cf c7 c7 cb cb cd 81 cf 87",  # 4
  153.                  "81 f9 f9 f9 c1 9f 9f 9f 99 c3",  # 5
  154.                  "c7 f3 f9 f9 c1 99 99 99 99 c3",  # 6
  155.                  "81 99 9f 9f cf cf e7 e7 f3 f3",  # 7
  156.                  "c3 99 99 99 c3 99 99 99 99 c3",  # 8
  157.                  "c3 99 99 99 99 83 9f 9f cf e3"); # 9
  158.    
  159.    
  160.       @digits = ("3c 66 66 66 66 66 66 66 66 3c",  # 0
  161.                  "30 38 30 30 30 30 30 30 30 30",  # 1
  162.                  "3c 66 60 60 30 18 0c 06 06 7e",  # 2
  163.                  "3c 66 60 60 38 60 60 60 66 3c",  # 3
  164.                  "30 30 38 38 34 34 32 7e 30 78",  # 4
  165.                  "7e 06 06 06 3e 60 60 60 66 3c",  # 5
  166.                  "38 0c 06 06 3e 66 66 66 66 3c",  # 6
  167.                  "7e 66 60 60 30 30 18 18 0c 0c",  # 7
  168.                  "3c 66 66 66 3c 66 66 66 66 3c",  # 8
  169.                  "3c 66 66 66 66 7c 60 60 30 1c"); # 9
  170. }
  171.  
  172. sub incrementCount {
  173.    if (&lockFile == 1) {
  174.       $count = "0";
  175.       return;
  176.    }
  177.    &incrementTotalReads;
  178.    &unlockFile;
  179. }
  180.  
  181.  
  182. sub unlockFile {
  183.    unlink("$counterFile.lock");
  184. }
  185.  
  186. sub lockFile {
  187.    $lockCount = 0;
  188.    while (-f "$counterFile.lock") { 
  189.       if ($lockCount > $lockWait) {
  190.          $count = 0;
  191.          return 1;             # forget it (would be nice to log though)
  192.       }
  193.       sleep 1; 
  194.       $lockCount++;
  195.    }
  196.    open(LOCK,">$counterFile.lock") || die("Can't open $counterFile.lock: $!\n");
  197.    return 0;
  198. }
  199.  
  200.  
  201.  
  202. sub incrementTotalReads {
  203.    if (-e $counterFile) {
  204.      open(COUNT,"$counterFile") || die("Can't open $counterFile: $!\n");
  205.    }
  206.    $totalReads = <COUNT>;
  207.    chop $totalReads;
  208.    close(COUNT);
  209.    
  210.    $totalReads++ if $remote_host ne "kite.netcom.com";
  211.    
  212.    open(COUNT,">$counterFile") || die "$0: can\'t open $counterFile: $!\n";
  213.    print (COUNT "$totalReads\n");
  214.    close(COUNT);
  215. }
  216.