#!/usr/bin/perl # # HITMATIC # Maintains counts for a page or all pages and logs accesses. # Can optionally output the count to the browser. # # Filename: hitmat.cgi # Last revised: July 08, 1998 # Copyright: 1996-1998 by Joe DePasquale # E-Mail: crypt@getcruising.com # Website: http://www.GetCruising.com # ######################################################################## # # # This script and accompanying files may be distributed freely # # and modified, provided this header with my name, E-Mail address and # # this notice remain intact. Ownership rights remain with me. You may # # not sell this script without my approval. # # # # This script comes with no guarantee or warranty except for my good # # intentions. By using this code you agree to indemnify me from any # # liability that might arise from it's use. # # # # There is no technical support for this script, neither am I a # # professional programmer. Refer to 'HELPME.TXT' for further guidance. # # # ######################################################################## # # 2. CONFIGURE SCRIPT - # # Change these sample paths to the actual paths on your server: # Your Unix system date command $dateCmd = '/bin/date'; # Unix path to hitmat directory $hitmatDir = '/home/derfalschehase/www.derfalschehase.com/cgi/hitmat'; # URL path to hitmat.cgi $scriptUrl = 'http://www.derfalschehase.com/cgi/hitmat/hitmat.cgi'; # URL path to hitmat directory $hitmatUrl = 'http://www.derfalschehase.com/cgi/hitmat'; # Go to this URL when exiting manager $exitUrl = 'http://www.derfalschehase.com/manager.html'; # Log will record hit but exclude domain names matching this tail $myTail = '.derfalschehase.com'; # OPTIONAL - You can edit these variables if desired: # File Maintenance is triggered each day when the FIRST HIT between # midnight and $trigHour is received. This will 1) swap 'hit1.log' and # 'hit2.log' and 2) initialize a 'hitx.dat' file on the first day of a # month. You can use any 24-hour time from 1 (1 AM) to 23 (11 PM). $trigHour = 06; $headTitle = "HITMATIC Website Counter System"; $bodyTag = qq||; $bodyTitle = qq|i>HITMATIC|; # Change the table border size? (0 = no border) $border = 0; # If you DON'T want to backup the hit*.dat files, set $bakFlag to 'N', # otherwise set the correct values in the 'if' loop .. $bakFlag = 'Y'; if ($bakFlag eq 'Y') { $bakTime = 1; # days btwn backups $bakMax = 7; # days to keep backups # Unix path to backup directory $bakDir = '/home/derfalschehase/www.derfalschehase.com/bak'; # END OF INSTALLATION - SHOULD NOT CHANGE STUFF BELOW THIS LINE ######################################################################## chop ($jDate = `$dateCmd +"%j"`); $HITBAK = "$bakDir/hit$jDate.bak"; } chop ($dayStamp = `$dateCmd +"%e"`); $dayStamp =~ s/\s*//g; chop ($hourStamp = `$dateCmd +"%H"`); chop ($timeStamp = `$dateCmd +"%a %D %H%M%Z"`); chop ($dateStamp = `$dateCmd +"%Y%m%d"`); $yearStamp = substr ($dateStamp,0,4); $monthStamp = substr ($dateStamp,4,2); $month = $monthStamp +0; $HITCFG = "$hitmatDir/hit.cfg"; $HITCNT = "$hitmatDir/hit.cnt"; $HITDAT = "$hitmatDir/hit$month.dat"; $HITFLK = "$hitmatDir/hit.flk"; $HITLOG1 = "$hitmatDir/hit1.log"; $HITLOG2 = "$hitmatDir/hit2.log"; $HITMON = "$hitmatDir/hit"; $HITXBM = "$hitmatDir/hit.xbm"; $SINCEXBM = "since.xbm"; ######################################################################## # Read GET or POST input and setup stuff if (-e "./referer.pl") { require "./referer.pl"; &referer; } if ($ENV{'QUERY_STRING'} eq 'manager' || $ENV{'REQUEST_METHOD'} eq 'POST') { require "./hitman.pl"; require "./hitxbm.pl"; $HITPWD = "$hitmatDir/hitmat.pwd"; &hitman; exit; } elsif ($ENV{'QUERY_STRING'} =~ /(\S+?)(\+(\S))?=(\S+?)(&.*|$)/) { $pagecode =$1; $group =$3; $command =$4; if ($group) { $pagecode = "$group\+$pagecode"; } } else { &endIt; } open (LOCK,">$HITFLK") || &endIt; if (!flock (LOCK,2)) { &endIt; } # Daily maintenance if trigger time if ($hourStamp < $trigHour) { require "./hitcfg.pl"; &checkCfg; } # Add hit to main counter open (CNT,"+<$HITCNT") || &endIt; flock (CNT,2); seek (CNT,0,0); @inFile = ; $recNbr = 0; $foundFlag = 'N'; while (($recNbr <= $#inFile) && ($foundFlag eq 'N')) { ($count,$code,$eol) = split(/\|/,$inFile[$recNbr]); if ($code eq $pagecode) { if ($count < 999999) {$count++;} else {$count =1;} $inFile[$recNbr] = join ("\|",$count,$pagecode,"\n"); $foundFlag = 'Y'; } $recNbr++; } if ($foundFlag eq 'N') # new page { $count =1; $addLine = join ("\|",$count,$pagecode,"\n"); push @inFile, $addLine; } @outFile = sort {($b =~ /(\d+)/)[0] <=> ($a =~ /(\d+)/)[0]} @inFile; seek (CNT,0,0); print (CNT @outFile); truncate (CNT,tell(CNT)); close (CNT); # Make the XBM image according to COMMAND if ($command eq "PAGE") { require "./hitxbm.pl"; &makeXbm ($count,6,$HITXBM); } elsif ($command eq "GROUP") { require "./hitxbm.pl"; open (CNT,"<$HITCNT") || &endIt; flock (CNT,1); seek (CNT,0,0); @inFile = ; close (CNT); $groupTtl = 0; foreach $inLine (@inFile) { if ($inLine =~ /^\d+\|$group\+/) { ($count,$code,$eol,) = split(/\|/,$inLine); $groupTtl += $count; } } &makeXbm ($groupTtl,6,$HITXBM); } elsif ($command eq "SITE") { require "./hitxbm.pl"; open (CNT,"<$HITCNT") || &endIt; flock (CNT,1); seek (CNT,0,0); @inFile = ; close (CNT); $siteTtl = 0; foreach $inLine (@inFile) { ($count,$code,$eol,) = split(/\|/,$inLine); $siteTtl += $count; } &makeXbm ($siteTtl,6,$HITXBM); } elsif ($command eq "NONE") { open (XBM,">$HITXBM"); flock (XBM,2); seek (XBM,0,0); print (XBM "#define hit_width 1\n"); print (XBM "#define hit_height 1\n"); print (XBM "static char hit_bits[] = { 0x00 };\n"); truncate (XBM,tell(XBM)); close (XBM); } # Send the XBM image to Stdout if ($command ne "IMG") { print "Content-type: image/x-xbitmap\n\n"; print `cat $HITXBM`; } # Record hit in the log $hitLine = join ("\|",$timeStamp,$pagecode,$command,$banNbr,$ENV{'REMOTE_HOST'},$ENV{'HTTP_USER_AGENT'}); if ($ENV{'HTTP_REFERER'} !~ /$myTail/i) { $hitLine .= "\|$ENV{'HTTP_REFERER'}"; } if (open (LOG,">>$HITLOG1")) { flock (LOG,2); seek (LOG,0,2); print (LOG "$hitLine\n"); close (LOG); } close (LOCK); exit; # end main program ###################################################################### sub endIt # exit on error { exit; } # end endIt