A PLAIN TEXT VERSION OF THIS DOCUMENT IS INCLUDED IN THE .ZIP ARCHIVE.

#
# HITMAN - The HITMATIC Manager
# Displays and reports various website traffic statistics.
#
# Filename: hitman.pl
# Last revised: October 8, 2006
# Copyright: 1997-2006 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. #
# #
########################################################################

sub hitman {

@labels = ('','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
@dyinMon = (0,31,28,31,30,31,30,31,31,30,31,30,31);

# Parse form input
read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@cgiPairs = split(/&/,$buffer);
foreach $cgiPair (@cgiPairs)
{
($name, $value) = split(/=/,$cgiPair);
$name =~ s/\+/ /g; $value =~ s/\+/ /g;
$name =~ s/%(..)/pack("c",hex($1))/ge;
$value =~ s/%(..)/pack("c",hex($1))/ge;
$Form{$name} .= "\0" if (defined($Form{$name}));
$Form{$name} .= "$value";
}
undef $name; undef $value;

print qq|Content-type: text/html\n\n|;
print qq|<html>\n<head>\n<title>$headTitle</title>\n<link rel="stylesheet" href="$styleUrl" type="text/css">\n</head>\n|;
print qq|$bodyTag\n$bodyTitle<p>\n|;

&passtest ($HITPWD);
print qq|<form action="$scriptUrl" method=POST>\n|;
print qq|<input type=hidden name=password value="$Form{'password'}">\n|;

print qq|<table border=0>|;
print qq|<tr><td>[<input type=radio name=type value="Pageviews"|;
if ($Form{'type'} eq 'Pageviews' || !$Form{'type'}) { print qq| checked|; }
print qq|> Pageviews] [<input type=radio name=type value="Visits"|;
if ($Form{'type'} eq 'Visits') { print qq| checked|; }
print qq|> Visits]     |;

print qq|<select name=detail>\n<option value="0">Full Year\n|;
for $x (1..12)
{ print qq|<option value="$x"|;

if ($Form{'detail'} ==$x) { print qq| selected|; }
print qq|>$labels[$x] |;
if ($mo >= $x) {$year = $yyyy +0;} else {$year = $yyyy -1;}
print qq|$year\n|;
}
print qq|</select>     <input type=submit name=hittable value="REFRESH"></td></tr>\n|;
print qq|</table>|;

########################################################################
# Case: View Hit stats by day

if ($Form{'detail'} >0)
{ $month = $Form{'detail'};

if ($Form{'type'} eq 'Visits')
{ $HITDAT = "$HVMON$month.txt";
} else
{ $Form{'type'} = 'Pageviews';
$HITDAT = "$HPMON$month.txt";
}
if ($mo >= $month) { $year = $yyyy +0; } else { $year = $yyyy -1; }
if ($year %4 == 0 && $year %100 !=0) { $dyinMon[2] = 29; }

# Read all data into hashes
$total = 0;

open (DAT,"<$HITDAT") || &endMan ("Read: $HITDAT");
flock (DAT,1);
seek (DAT,0,0);

while ($line = <DAT>)
{ @hits = split (/\|/,$line);
$page = ''; $group = '';
$pagecode = $hits[0];

if ($pagecode =~ /^([^+]+)\+$/)
{ $group = $1;
} else
{ $page = $pagecode;
}
foreach $day (1..$dyinMon[$month])
{ if ($page)
{ $Tbl{$page}{$day} += $hits[$day];
$PageTtl{$page} += $hits[$day];
$DayTtl{$day} += $hits[$day];
}
if ($group)
{ $Tbl{$group}{$day} += $hits[$day];
$GroupTtl{$group} += $hits[$day];
}
}
$total += $PageTtl{$page};
}
close (DAT);

@pages = sort {$PageTtl{$b} <=> $PageTtl{$a}} keys %PageTtl;
@groups = sort {$GroupTtl{$b} <=> $GroupTtl{$a}} keys %GroupTtl;

print qq|<table border=$border width=50%><tr align=center>\n|;
print qq|<td align=left><font color="#009900"><b>Days:</b></font></td>\n|;

foreach $day (1..$dyinMon[$month]) { print qq|<td><font color="#009900"><b>$day</b></font></td>|; }
print qq|<td><font color="#0000FF"><b>Group<br>/Page<br>Totals</b></font></td>|;

# print group hit rows
print qq|\n</tr><tr>\n<td><b>GROUPS:</b></td><td colspan=|,($dyinMon[$month]-1),qq|></td>|;
foreach $group (@groups)
{ print qq|\n</tr><tr align=right>\n<td align=left><font color="#0000FF">$group</font></td>|;
foreach $day (1..$dyinMon[$month]) { print qq|<td>$Tbl{$group}{$day}</td>|; }
print qq|<td>$GroupTtl{$group}</td>|;
}
# print page hit rows
print qq|\n</tr><tr>\n<td><b>PAGES:</b></td><td colspan=|,($dyinMon[$month]-1),qq|></td>|;
foreach $page (@pages)
{ print qq|\n</tr><tr align=right>\n<td align=left><font color="#0000FF">$page</font></td>|;
foreach $day (1..$dyinMon[$month]) { print qq|<td>$Tbl{$page}{$day}</td>|; }
print qq|<td>$PageTtl{$page}</td>|;
}
print qq|\n</tr></table><br>Completed on $timeStamp\n<p>\n|;
} else

########################################################################
# Case: View Hitstats by month
{
# Read all data into hashes
$total = 0;

foreach $month (1..12)
{ $MonthTtl{$month} =0;

if ($Form{'type'} eq 'Visits')
{ $HITDAT = "$HVMON$month.txt";
} else
{ $Form{'type'} = 'Pageviews';
$HITDAT = "$HPMON$month.txt";
}
open (DAT,"<$HITDAT") || &endMan ("Read: $HITDAT");
flock (DAT,1);
seek (DAT,0,0);
while ($line = <DAT>)
{ @hits = split (/\|/,$line);

$page = ''; $group = '';
$pagecode = $hits[0];

if ($pagecode =~ /^([^+]+)\+$/)
{ $group = $1;
} else
{ $page = $pagecode;
}
$Tbl{$month}{$page} =0;

if ($page)
{ foreach $day (1..31)
{ $Tbl{$month}{$page} += $hits[$day];
}
$PageTtl{$page} += $Tbl{$month}{$page};
$MonthTtl{$month} += $Tbl{$month}{$page};
}
if ($group)
{ foreach $day (1..31)
{ $Tbl{$month}{$group} += $hits[$day];
}
$GroupTtl{$group} += $Tbl{$month}{$group};
}
}
close (DAT);
$total += $MonthTtl{$month};
}
# Sort by descending page total
@pages = sort {$PageTtl{$b} <=> $PageTtl{$a}} keys %PageTtl;
@groups = sort {$GroupTtl{$b} <=> $GroupTtl{$a}} keys %GroupTtl;

print qq|<table border=$border><tr align=center>\n|;
print qq|<td align=left><font color="#009900"><b>Months:</b></font></td>\n|;

# Print col headers and order the months
$month = $mo;
do
{ if ($month == 12) {$month =1;} else {$month++;}
print qq|<td><font color="#009900"><b>$labels[$month]</b><br>|;
if ($month > $mo) {$year = $yyyy -1;} else {$year = $yyyy +0;}
print "$year</font></td>\n";
push @monthCol, $month;
} until ($month == $mo);
print qq|<td><font color="#0000FF"><b>Group<br>/Page<br>Totals</b></font></td>|;

# print group hit rows
print qq|\n</tr><tr>\n<td><b>GROUPS:</b></td><td colspan=13></td>|;
foreach $group (@groups)
{ print qq|\n</tr><tr align=right>\n<td align=left><font color="#0000FF">$group</font></td>|;
foreach $month (@monthCol) { print qq|<td>$Tbl{$month}{$group}</td>|; }
print qq|<td>$GroupTtl{$group}</td>|;
}

# print page hit rows
print qq|\n</tr><tr>\n<td><b>PAGES:</b></td><td colspan=13></td>|;
foreach $page (@pages)
{ print qq|\n</tr><tr align=right>\n<td align=left><font color="#0000FF">$page</font></td>|;
foreach $month (@monthCol) { print qq|<td>$Tbl{$month}{$page}</td>|; }
print qq|<td>$PageTtl{$page}</td>|;
}
print qq|\n</tr></table><br>Completed on $timeStamp\n<p>\n|;
} # end

&manFooter;
} # end hitman

########################################################################
sub newDay
{
$HPDAT = "$HPMON$logMonth.txt";
$HVDAT = "$HVMON$logMonth.txt";

@dyinMon = (0,31,28,31,30,31,30,31,31,30,31,30,31);
if ($year %4 == 0 && $year %100 !=0) { $dyinMon[2] = 29; }
$dyinMon = $dyinMon[$logMonth];

open (HPDAT,"+<$HPDAT") || &endIt;
flock (HPDAT,2);
seek (HPDAT,0,0);
@hpDat = <HPDAT>;

# add this month's views to Tbl hash
foreach $hitLine (@hpDat)
{ @hits = split (/\|/,$hitLine);
$page = $hits[0];

$PTbl{$page}[0] = $page;
for $day (1..$dyinMon)
{ $PTbl{$page}[$day] += $hits[$day];
}
$PIndex{$page} = 'Y';
}
open (HVDAT,"+<$HVDAT") || &endIt;
flock (HVDAT,2);
seek (HVDAT,0,0);
@hvDat = <HVDAT>;

# add this month's visits to VTbl hash
foreach $hitLine (@hvDat)
{ @hits = split (/\|/,$hitLine);
$page = $hits[0];

$VTbl{$page}[0] = $page;
for $day (1..$dyinMon)
{ $VTbl{$page}[$day] += $hits[$day];
}
$VIndex{$page} = 'Y';
}

# Read log file
open (LOG1,"+<$HITLOG1") || &endIt;
flock (LOG1,2);
seek (LOG1,0,0);
@logFile = <LOG1>;

# add yesterday's hits to Tbl hash

foreach $logLine (@logFile)
{ @log = split (/\|/,$logLine);

$page = "$log[1]";
($group,$foo) = split (/\+/,$page);

# create new line if no previous hits

for $x ('SITE+',$group.'+',$page)
{ if (!$PTbl{$x}[0] && $x)
{ $PTbl{$x}[0] = $x;
for $day (1..$dyinMon)
{ $PTbl{$x}[$day] +=0;
}
$PIndex{$x} = 'Y';
}
$PTbl{$x}[$logDay]++;
}
for $x ('SITE+',$group.'+',$page)
{ if (!$Ip{$log[2]}{$x})
{ $Ip{$log[2]}{$x} =1; $IpCnt{$x} ++;

if (!$VTbl{$x}[0] && $x)
{ $VTbl{$x}[0] = $x;
for $day (1..$dyinMon)
{ $VTbl{$x}[$day] +=0;
}
$VIndex{$x} = 'Y';
}
}
}
}
foreach $visit (keys %IpCnt)
{ $VTbl{$visit}[$logDay] += $IpCnt{$visit};
}
# write updated PTbl back to file
seek (HPDAT,0,0);

foreach $page (sort {uc($a) cmp uc($b)} keys %PIndex)
{ $line = '';
for $day (0..$dyinMon)
{ $line .= "$PTbl{$page}[$day]\|";
}
print HPDAT "$line\n";
}
truncate (HPDAT,tell(HPDAT)); close (HPDAT);

# write updated VTbl back to file
seek (HVDAT,0,0);

foreach $page (sort {uc($a) cmp uc($b)} keys %VIndex)
{ $line = '';
for $day (0..$dyinMon)
{ $line .= "$VTbl{$page}[$day]\|";
}
print HVDAT "$line\n";
}
truncate (HVDAT,tell (HVDAT)); close (HVDAT);

open (LOG2,">$HITLOG2") || &endIt;
flock (LOG2,2);
seek (LOG2,0,0);
print (LOG2 @logFile);
truncate (LOG2,tell (LOG2)); close (LOG2);

truncate (LOG1,0); close (LOG1);

$logDay = $dd;
&changeCfg;

} # end newDay

sub newMonth
{
# Empty last year's month file and update cfg if new month
$logMonth = $mo;

$HPDAT = "$HPMON$logMonth.txt";
open (HPDAT,">$HPDAT") || &endIt;
flock (HPDAT,2);
truncate (HPDAT,0); close (HPDAT);

$HVDAT = "$HVMON$logMonth.txt";
open (HVDAT,">$HVDAT") || &endIt;
flock (HVDAT,2);
truncate (HVDAT,0); close (HVDAT);

&changeCfg;

} # end newMonth

sub changeCfg # update hit cfg file
{
$cfgFile = join ("\|",$logDay,$logMonth,$eol);
seek (CFG,0,0);
print (CFG $cfgFile);
truncate (CFG,tell(CFG));
} # end changeCfg

sub manFooter # print hitman footer
{
print qq|</form><p>\n<a href="$exitUrl">Exit $headTitle</a>\n|;
print qq|<p><i><b>HITMATIC</b> is one of <a href="http://www.getcruising.com/crypt" target="_top">Joe's CGI Scripts From The Crypt!</a></i>\n|;
print qq|<p>\n</body></html>\n|;
} # end manFooter

sub passtest # password routines
{
$PASSFILE = $_[0];
if (-s $PASSFILE)
{ if ($Form{'password'})
{ open (PASS,"<$PASSFILE");
$passcode = <PASS>;
close (PASS);
chop ($passcode) if $passcode =~ /\n$/;
$lp = length $Form{'password'};
$salt = substr($Form{'password'},$lp-2,1).substr($Form{'password'},1,1);
if ($passcode eq crypt ($Form{'password'},$salt))
{ if ($Form{'newpassword'})
{ $lp = length $Form{'newpassword'};
if ($Form{'newpassword'} =~ /^\w{$lp}\b/)
{ $Form{'password'} = $Form{'newpassword'};
$salt = substr($Form{'password'},$lp-2,1).substr($Form{'password'},1,1);
$passcode = crypt ($Form{'password'},$salt);
open (PASS,">$PASSFILE");
print PASS "$passcode";
close (PASS);
} else
{ &passbox ("Bad choice, Creep!!");
}
}
} else
{ &passbox ("Wrong, Creep!!");
}
} else
{ &passbox ("What's the Password, Creep?");
}
} else
{ &endMan ("Password File $PASSFILE Not Found");
}
}
sub passbox
{
print <<__PASSBOX;
<form action="$scriptUrl" method="POST">
<input type=hidden name=manager value=1><table border=4>
<tr><th colspan=2><font color="#FF0000"><b><blink>$_[0]</blink></b></font></th></tr>
<tr><th> Enter Password:</td><th><input type=password name=password size=12 maxlength=12></th></tr>
<tr><th>Change Password:</td><th><input type=text name=newpassword size=12 maxlength=12></th></tr>
<th colspan=2><input type=submit value=" DO IT! "><input type=reset value=" CLEAR "></th></tr>
</table><br>
Password must be 4 to 12 alpha-numeric characters.</form>
<p></body></html>
__PASSBOX
exit;
} # end passbox

sub endMan # Error handling for manager scripts
{
print qq|<font color="#FF0000"><b>ERROR:</font><br>$_[0]</b>\n<p>|;
if ($!) { print "Server made a Boo-Boo! $!\n"; }
else { print qq|Use your browser's [BACK] button and try again.\n|; }
print qq|<p></body></html>\n|;
exit;
} # end endMan

1; # return true

HOME|PLEASE VISIT GETCRUISING'S SPONSOR: