Solved

Hitmatic web access and counter rewrite

Posted on 1998-01-30
3
333 Views
Last Modified: 2013-12-25
This question is intended for ozo. Ozo has the necessary files and has already worked on this in another message that has been deleted from the system.

I'm using Hitmatic from Joe's Scripts From The Crypt. The original version was dated June 7, 1997 and is the version that requires the Passmatic password script. There are many features I would like to change.

1. The $trigHour does not work. It always changes at 12:00 midnight no matter what you use as the variable.

2. I would like to add a feature that would exclude my hits to the pages that are being tracked by Hitmatic. Lets call this variable "@no_log".

3. Fix the security flaw that allows certain files to be hacked. We have discussed this in the deleted message and I don't what to repeat the details of that weakness here.

4. As of this date, all versions of Hitmatic from Joe's Scripts only track hits for 12 months. After entering the 13th month, Hitmatic now writes over the oldest month's data and is lost forever. I would like to track the hits forever. For the counts older that 12 months we can loose the details of the hit but keep a running total of those hits older than 12 months in the "hit.cnt" file. That way the size of the data files would not grow any larger than they already do with the current version.

5. The current version has a feature to delete the counts and reset the counter. For my purposes I want this completely removed as I have no reason I would want to start the counts all over again.

6. I want to change the look and function of the tables produced by "hitman.cgi". First I want to add a column on the right side, next to the column "Pages/Months", called "Prior Years". This is where I want the counts for each page that are older than 12 months to be listed. The counts need to be totaled at the bottom of the table. This total needs to be added to all the other monthly totals in the bottom of the "Page Totals" column.

7. The current version has radios to access each page and month details section. You now have to click on the radio and then hit another button to go to the detail tables for the page or month selected. If you forget to click on the correct radio and click on the button, you get an error message. I want to delete the radios and make each page or month a clickable link to the detail tables. That would get you there in just one click and there would be no need for the error message. Remove the error message from the script as it is no longer needed.

NOTE! If you are reading this message you are probably wondering what you will get for the 60 points it will cost you to see the answer. You will get two scripts, "hitmatic.cgi" and "hitman.cgi", that have been extensively rewritten and tested. These scripts are complete and not just snippets of code. All you will need to do is cut, paste and configure the scripts to your server.
0
Comment
Question by:Gary040897
  • 2
3 Comments
 
LVL 3

Expert Comment

by:bigelos
ID: 1856810
So, then, the end result is a cgi script?  That leads me to believe that this question should have been posted in the cgi questions area.
0
 
LVL 84

Accepted Solution

by:
ozo earned 600 total points
ID: 1856811
#!/usr/local/bin/perl  
###########################################################################
#
#  HITMATIC  (hitmatic.cgi)      This version updated 1-30-98
#
#  Maintains counts for a page or all pages and logs accesses.
#  Can optionally output the count to the browser.
#
#  This script was customized at the Experts Exchange
#  http://www.experts-exchange.com
#  This script was based on the copyrighted HitMatic by Joe DePasquale
#  E-MAIL: crypt@getcruising.com  WEB: 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.
#
###########################################################################
#  Portions of the bitmap routines and the bitmap data files were         #
#  modified from a script by Eugene E. Devereaux <gened@halcyon.com>      #
#  " Permission to use, copy, modify, and distribute this software        #
#  and its documentation for any purpose and without fee is granted       #
#  provided that the above copyright notice appears in all copies.        #
#  It is provided "as is" without express or implied warranty. "          #
###########################################################################
#
# INSTALLATION
#
# 1. EDIT FILES -
#
#  Open 'hit.cfg' in a text editor. The default file is '1|1|1|'. Change
#  the first '1' to current day-of-month (1-31), the second '1' to current
#  month (1-12). Leave the third '1' as is and save the file. Hereafter,
#  these values will be read, changed and written by the script(s) so no
#  further editing should be required.
#
#  Good news! All of the 'cnt', 'dat', 'log', and 'xbm' files configure
#  themselves when the script starts counting hits. Here is a brief
#  summary of what they do:
#
#  'hit.cnt' stores the hitcounts to be displayed on HTML pages.
#
#  'hit1.dat' thru 'hit12.dat' (one file for each month) store hits by
#   page and day for a year.
#
#  'hit1.log' and 'hit2.log' store todays' and yesterday's hit data. One
#  line per hit includes date, time, $pagecode, $command, user's IP
#  address, cookies and referring page.
#
#  'hit.xbm' is an X-Bitmap image of the last Hitcount sent to a browser.
#
#
#  IMPORTANT!!
#
#  Add a reference to each HTML page following this example:
#
#  <img src="http://your.server.com/path/to/cgi-bin/hitmatic.cgi?pagecode=command">
#
#  Make up a different name in place of 'pagecode' in the example. Each
#  page must have its own unique code (such as 'page1','links','home').
#
#  'command' is one of: "SITE" displays total hits for this website
#  - OR - "PAGE" displays hits for this page only - OR - "NONE" does not
#  display a hit count, i.e. sends a null bitmap image.
#
#  TO ADD PAGES TO THE LOGGING SYSTEM:
#
#  As a security feature each page you want Hitmatic to log MUST first be
#  hit by you with with the '@auto_add' value set at
#  @auto_add = ('server.com'); where the value of 'server.com' is how
#  HitMatic records your hit in the 'hit1.log', (or by anyone with the
# '@auto_add' value set at @auto_add = ('').
# If your server records the
#  modem you are connected to as a different number with every session such
#  as '123456.server.com', you should only use the portion of your log hit
#  that remains constant. In this example use '@auto_add = ('server.com');'.
#  When you first hit your new page with the '@auto_add' value set at
#  '@auto_add = ('');' or '@auto_add = ('server.com');' hitmatic.cgi will make
#  an entry for that page in 'hit.cnt' with a count value of 0. Only then
#  will successive hits by the public be passed on to the 'hit1.dat' thru
#  'hit12.dat' and increment the counter.  This feature fixes an important
#  security flaw in other versions of HitMatic where your 'hit.cnt' and
#  'hitX.dat' files could be hacked and corrupted.

#
# 2. CONFIGURE SCRIPT -

#Exclude the logging of your hit here.
@no_log = ();  

#  With '@no_log = ();' HitMatic will not
#  exclude any hits and will allow you to see how your hit is recorded in
#  'hit1.log'. If you don't want to exclude any hits, leave this variable
#  set at '@no_log = ();'. If you want to exclude your hits use
#  '@no_log = ('server.com');' as explained in the
#  'ADD PAGES TO THE LOGGING SYSTEM' section above.
#
#Allow automatic adding of pages hit from these sites
@auto_add=('');
#
#  This default value of @auto_add = (''); will allow anyone to add a new page
#  to the Hitmatic hit tracking system. Once
#  you have added a new page and made the initial hit to that page, change
#  this value to '@auto_add = ()'; to prevent anyone from adding a page,
#  or @auto_add = ('server.com') to allow only 'server.com' to add
#  new pages

# Change these sample paths to the actual Unix paths on your server:

$hitmatDir = "/home/you/path/to/hitmat";
$flkDir    = "/home/you/path/to/flk";

#  OPTIONAL - You can edit these variables if desired:
#
#  File Maintenance is triggered each day when the FIRST HIT AFTER $trighour
#  is recieved.  This will 1) swap 'hit1.log' and 'hit2.log' and
#  2) initialize a 'hitx.dat' file on the first day of a month.
#  The default value is 0 (Midnight) which you can change to any number
#  including 3.5 (3:30 AM) or -4.0 (8:00 PM the previous day)

$trigHour = 0;

# If your server allows access to the 'flock' command, change this
# to "Y" for a more secure file-lock especially on busy websites.

$lockFlag = "Y";

#
# 3. UPLOAD FILES (and Set CHMOD Permissions) -
#
#  Place 'hitmatic.cgi' (755), 'hitcfg.pl' (644) and 'hitxbm.pl' (644) in
#  your main cgi-bin directory. Create a directory named 'hitmat' (755)
#  and place 'hit.cfg' (666), 'hit.cnt' (666), 'hit1.log' (666), 'hit2.log'
#  (666), 'hit.xbm' (666) plus the 12 files 'hit1.dat' thru 'hit.12.dat'
#  (666) there. Create a directory named 'flk' (777), unless you have
#  one already. This is where lock files for all the '..matic' scripts
#  are created and deleted.
#

# END OF INSTALLATION - DO NOT EDIT BELOW THIS LINE!
###########################################################################

# set constants

($month,$dayStamp) = (localtime(time-3600*$trigHour))[4,3];
$month++;
($timeStamp = localtime) =~ s/(\d+)\s([\d:]+)\s(\d+)/$1, $3 $2/;

$HITCFG  = "$hitmatDir/hit.cfg";
$HITCNT  = "$hitmatDir/hit.cnt";
$HITLOG1 = "$hitmatDir/hit1.log";
$HITLOG2 = "$hitmatDir/hit2.log";
$HITXBM  = "$hitmatDir/hit.xbm";
$HITDAT  = "$hitmatDir/hit$month.dat";

$HITCFLK = "$flkDir/hitcfg.flk";
$HITMFLK = "$flkDir/hitmat.flk";
#$HITXFLK = "$flkDir/hitxbm.flk";

$pagecode = "error"; # default
$command  = "NONE";  # default

# Read input from query string

@query = split(/&/,$ENV{'QUERY_STRING'});
($pagecode,$command) = split(/=/, $query[0]);
$codelen = length($pagecode);


foreach( @no_log ){
    if( /^(\d{1,3}\.)+\d{0,3}$/ ){ $_ = "^\Q$_\E" }else{ $_ = "\Q$_\E\$" }
}
foreach( @auto_add ){
    if( /^(\d{1,3}\.)+\d{0,3}$/ ){ $_ = "^\Q$_\E" }else{ $_ = "\Q$_\E\$" }
}

if( grep($ENV{'REMOTE_HOST'}=~/$_/,@no_log) ){
# Make the XBM image according to COMMAND
    $HITXBM = "-";
    &lock($HITCFLK);
     open(CNT,"<$HITCNT");
      @inFile = <CNT>;
     close (CNT);
    $printTtl = 0;
    $foundpage='';
    for( @inFile ){
        $printTtl += $_;        
        $foundpage = $_ if( index($_,"|$pagecode|")>=0 );
    }
    if( !$foundpage ){
          open(CNT,">>$HITCNT");
          print CNT "0|$pagecode|\n";
          close(CNT);
    }
    unlock($HITCFLK);
    print "Content-type: image/x-xbitmap\n\n";
    if( $command eq "SITE" || $command eq "PAGE" ){
        require "hitxbm.pl";
        if( $command eq "PAGE" ){
            $printTtl = 0+$foundpage;
        }
        &makeXbm;
    }else{
        print "#define number_width 1\n";
        print "#define number_height 1\n";
        print "static char number_bits[] = {\n 0xfe};\n";
    }
    exit;
}

# Count the hit
&lock ($HITCFLK);
 open (CNT,"<$HITCNT");
 @inFile = <CNT>;
 close (CNT);
 chomp(@inFile);
 $foundFlag = 0;
 @inFile = map{
    (index($_,"|$pagecode|")<0)?"$_\n":
    ($foundFlag=1+($_%999999)."|$pagecode|\n")
 }@inFile;
 if( !$foundFlag && grep($ENV{'REMOTE_HOST'}=~/$_/,@auto_add) ){
     push(@inFile,"1|$pagecode|\n");
     $foundFlag++;
 }
 open (CNT,">$HITCNT");
 print CNT @inFile;
 close (CNT);
&unlock ($HITCFLK);

# Make the XBM image according to COMMAND
$HITXBM = "-";
print "Content-type: image/x-xbitmap\n\n";
if( $command eq "SITE" || $command eq "PAGE" ){
 require "hitxbm.pl";
 if( $command eq "PAGE" ){
  @inFile = grep( index($_,"|$pagecode|")>=0, @inFile);
 }
 $printTtl = 0;
 for( @inFile ){ $printTtl += $_; }
 &makeXbm;
}else{
   print "#define number_width 1\n";
   print "#define number_height 1\n";
   print "static char number_bits[] = {\n 0xfe};\n";
}


&lock ($HITCFLK);
# Maintenance if trigger time
  open (CFG,"<$HITCFG");
  $cfgFile = <CFG>;
  close (CFG);
  ($logDay,$datMonth,$cntMonth,$eol) = split (/\|/,$cfgFile);
  # Make new log file
  if( $logDay != $dayStamp || $datMonth != $month ){
        open (CFG,">$HITCFG") ;
        print CFG join ("|",$dayStamp,$month,$cntMonth,$eol);
        close (CFG);

        open(LOG,"<$HITLOG1");
        open(LOG2,">$HITLOG2");
        while( <LOG> ){ print LOG2; }
        close LOG2;
        close LOG;

        open (LOG,">$HITLOG1");
        print LOG "$timeStamp|FILE MAINTENANCE by Guest Clobberer: $ENV{'REMOTE_HOST'}|\n";
        close (LOG);
  }

# Record hit in the log
$hitLine = join ( "|", $timeStamp, $pagecode, $command, @ENV{qw(REMOTE_HOST HTTP_COOKIE HTTP_REFERER)} );
 open (LOG,">>$HITLOG1");
 print (LOG "$hitLine\n");
 close (LOG);
&unlock ($HITCFLK);

&lock ($HITMFLK);
# Increment the month file
  if( $datMonth == $month ){
         open (DAT,"<$HITDAT");
         @mFile = <DAT>;
         close (DAT);
  }else{
        @mFile = ();
  }
 @a=();
 @outFile = map{
    (substr($_,0,$codelen+1)ne"$pagecode|")?$_:
    (@a=split(/\|/) and ++$a[$dayStamp] and join('|',@a))
 } @mFile;
 if( $foundFlag && !@a ){
  @a=($pagecode,(0) x 31,"\n");
  ++$a[$dayStamp];
  push @outFile, join ("|",@a);
  @outFile = sort @outFile;
 }
 open (DAT,">$HITDAT");
 print DAT @outFile;
 close (DAT);
&unlock ($HITMFLK);

###########################################################################
# Sub: Lock or Unlock a file

use Fcntl ':flock';
sub lock
{ $LOCKFILE = $_[0];
  $endTime = time + 10;
  while( $lockFlag ne "Y" && -e $LOCKFILE && time <= $endTime ){  # snooze
  }
  open (LOCKFILE);
  if ($lockFlag eq "Y") {flock (LOCKFILE,LOCK_EX);}
} # end lock

sub unlock
{ $LOCKFILE = $_[0];
  if ($lockFlag eq "Y") {flock (LOCKFILE,LOCK_UN);}
  close (LOCKFILE);
  if (-e $LOCKFILE) {unlink ($LOCKFILE);}
} # end unlock

0
 
LVL 84

Expert Comment

by:ozo
ID: 1856812
#!/usr/local/bin/perl
###########################################################################
#
#  HITMATIC MANAGER (hitman.cgi)     This version updated 1-30-98
#
#  Displays and reports various hit count statistics.
#
#  Requires PASSMATIC.
#
#  This script was customized at the Experts Exchange
#  http://www.experts-exchange.com
#  This script was based on the copyrighted HitMatic by Joe DePasquale
#  E-MAIL: crypt@getcruising.com  WEB: http://www.GetCruising.com
#
###########################################################################
#  
#  Original Header from Joe DePasquale
#  
#  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.
#
###########################################################################
#
# INSTALLATION
#
# HITMATIC MANAGER requires PASSMATIC (the password manager), available
# for free download at http://www.getcruising.com/crypt/
#
# Before proceeding, refer to 'hitmatic.cgi' and follow instructions
# for setting up that script and its accompanying files.

# 1. EDIT FILES -
#
# Open 'hitman.html' in a text/HTML editor and replace the default
# path "http://your.server.com/you/path/to/cgi-bin/hitman.cgi"
# with the correct script URL for your server. You will need to
# install and run 'PASSMATIC' to create a User ID and Password for
# the manager BEFORE you can use this script.
#
# HOW TO USE THE SCRIPT -
#
# Access 'hitman.html' from the web and enter UserID and Password.
# Select to start with HIT TABLES or HIT COUNTER.
#
# The default HIT TABLE is 'By YEAR' starting 12 months ago and ending
# at the end of current month. The grid shows the total hits by month
# for each page, ranked most to least popular.
#
# The 'By MONTH' table shows the total hits for each page each day
# during the selected month, plus page totals and day totals.
#
# The 'By PAGE' table shows the total hits for each page each day
# during the past year, plus month totals and day totals.
#
# The HIT COUNTER is the data that is sent to a browser when it
# encounters a HITMATIC 'SITE' or 'PAGE' command. 'DISPLAY' to see
# total hits by page.

# 2. CONFIGURE SCRIPT -
#
# Change these sample paths to the actual paths on your server:

# Your Unix system date commands
#$dateCmd   = '/usr/bin/date';

# URL path to hitman.cgi
#$scriptUrl = "http://your.server.com/you/path/to/cgi-bin/hitman.cgi";

# Unix path to hitmat directory
$hitmatDir = "/home/you/path/to/hitmat";

# Unix path to flk directory
$flkDir    = "/home/you/path/to/flk";

# Go to this URL when exiting HITMAN
$exitUrl = "http://your.server.com/you/path/to/anypage.html";;

# Optional - You can edit these variables if desired:

$headTitle = "HitMatic Manager";
$blue='color="#0000FF"';
$green='color="#009900"';
$bodyTag   = '<body bgcolor="#FFFFFF" text="#000099" link="#0000FF" alink="#FFFF00" vlink="#990000">';
$bodyTitle = '<i><b><font size=5><font color="#0000FF">HIT</font><font color="#FF0000">MATIC </font><font color="#006600">MANAGER</font></font></b></i>';

# If your server allows access to the 'flock' command, change this
# to "Y" for a more secure file-lock especially on busy websites.

$lockFlag = "N";

#
# 3. UPLOAD FILES (and Set CHMOD Permissions) -
#
# Place 'hitman.cgi' (755) into your main cgi-bin directory. You
# should also have 'passmat.pl' and 'hitmatic.cgi' in the cgi-bin.
# Place 'hitman.html' (644) into any web directory.

# END OF INSTALLATION - DO NOT EDIT BELOW THIS LINE!
###########################################################################
# Set constants

@labels = qw(Prior<br>Years Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);

$HITCFG  = "$hitmatDir/hit.cfg";
$HITCNT  = "$hitmatDir/hit.cnt";
$HITMON  = "$hitmatDir/hit";

#$HITCFLK = "$flkDir/hitcfg.flk";
$HITMFLK = "$flkDir/hitmat.flk";

($monthStamp,$yearStamp) = (localtime)[4,5];
($timeStamp = localtime) =~ s/(\d+)\s([\d:]+)\s(\d+)/$1, $3 $2/;
$monthStamp++;
$yearStamp += 1900;

require "passmat.pl";

# Parse input from form

read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
$buffer .= "&$ENV{'QUERY_STRING'}";
@cgiPairs = split(/&/,$buffer);
foreach( @cgiPairs ){
  ($name, $value) = split(/=/);
  $value =~ s/\+/ /g;
  $value =~ s/%(..)/pack("H*",$1)/ge;
  $Form{$name} .= "\0" if (defined($Form{$name}));
  $Form{$name} .= "$value";
}
if( !defined $Form{'userid'} ){
  ($_ = $ENV{'PATH_INFO'})=~tr(/0-9A-Za-z.|)( `!-_);
  ($id,$pw) = split;
  $Form{'userid'} = unpack('u',$id);
  $Form{'password'} = unpack('u',$pw);
}

($id = pack 'u',$Form{'userid'})=~tr/`!-_\n/0-9A-Za-z.|/d;
($pw = pack 'u',$Form{'password'})=~tr/`!-_\n/0-9A-Za-z.|/d;
print "Content-type: text/html\n\n";
print "<html>\n<head><title>$headTitle</title></head>\n";
print "$bodyTag\n$bodyTitle<p>\n";
print qq(<BASE HREF="http://$ENV{'HTTP_HOST'}$ENV{'SCRIPT_NAME'}/$id/$pw/">\n);

#$ref = $ENV{SCRIPT_NAME}; #this does not appear to be used anywhere

if( $Form{'bymonth'} && $Form{'month'} ){
  $Form{'table'} = "month|$Form{'month'}";
}elsif( $Form{'bypage'} && $Form{'page'} ){
  $Form{'table'} = "page|$Form{'page'}";
}

##################################################################
# print top of form

  &passmat ($Form{'userid'},$Form{'password'});
  print "<form method=POST>\n";
  $id = html($Form{'userid'});
  $pw = html($Form{'password'});
  print "<input type=hidden name=\"userid\" value=\"$id\">\n";
  print "<input type=hidden name=\"password\" value=\"$pw\">\n";
# end topForm

if( ($month) = ($Form{'table'} =~ /^month\|(\d+)/) ){

##################################################################
# Case: Hits by month

    $year = $yearStamp-($monthStamp<$month);
    print "<font size=5>Hits By MONTH</font> for <b>$labels[$month] $year</b></br>\n";

    # Read all data into a 'hash of hashes'
    $total = 0;

    $HITDAT = "$HITMON$month.dat";
    open (DAT,"<$HITDAT");

    while( <DAT> ){
      @hits = split(/\|/);
      $page = $hits[0];
      foreach $day ( 1..31 ){
        $Tbl{$page}{$day} = $hits[$day];
        $DayTtl{$day} += $hits[$day];
        $PageTtl{$page} += $hits[$day];
      }
      $total += $PageTtl{$page};
    }
    close (DAT);

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

    print qq(<table border=1><tr align=center>\n<td nowrap><b>Pages/Days</b></td>);
    foreach $day (1..31){
        print "<td><font $green><b>$day</b></font></td>";
    }
    print qq(<td><font $blue><b>Page<br>Totals</b></font><\A></td>);

    foreach $page ( @pages ){
        $p = html($page);
       print qq(\n</tr><tr align=right>\n<td align=left><A HREF="?table=page|$p"><font $blue>$p</font></a></td>);
      foreach $day ( 1..31 ){
          print "<td>$Tbl{$page}{$day}</td>";
      }
      print "<td>$PageTtl{$page}</td>";
    }
    print "\n</tr><tr align=right>\n<td nowrap align=center><font $green><b>Day Totals</b></font></td>";

    foreach $day ( 1..31 ){
        print "<td>$DayTtl{$day}</td>";
    }
    print "<th>$total</th>";

    print "\n</tr></table>";
   
# end bymonth
}elsif( ($page) = ($Form{'table'} =~/^page\|(.*)/) ){

##################################################################
# Case: Hits by page

    $p = html($page);
    print "<font size=5>Hits By PAGE</font> for <b>$p</b></br>\n";

    # Read all data into a 'hash of hashes'
    $total = 0;

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

      $HITDAT = "$HITMON$month.dat";
      open (DAT,"<$HITDAT") || next;

      while( <DAT> ){
        @hits = split (/\|/);
        next unless $hits[0] eq $page;
        foreach $day (1..31){
            $Tbl{$month}{$day} += $hits[$day];
            $DayTtl{$day} += $hits[$day];
            $MonthTtl{$month} += $hits[$day];
        }
      }
      close (DAT);
      $total += $MonthTtl{$month};
    }
    open(CNT,"<$HITCNT");
    @hitFile = <CNT>;
    close (CNT);
    foreach( @hitFile ){
        ($count,$code) = split (/\|/);
        next unless $code eq $page;
        #$oldcnt = $count-$total;
        $total = $count;
    }

    print qq(<table border=1><tr align=center>\n<td nowrap><b>Days/Months</b></td>);

    # Print col headers and order the months
    @monthCol = ($monthStamp+1..12,1..$monthStamp);
    for $month ( @monthCol ){
      $year = ($yearStamp - ($month > $monthStamp))%100;
      $year = "'$year" if( $year < 10 );
      print qq(<td><A HREF="?table=month|$month"><font $green><b>$labels[$month]</b><br>$year</font></A></td>);
    }

    print qq(<td><font $blue><b>Day<br>Totals</b></font></td>);

    foreach $day (1..31 ){
      print "\n</tr><tr align=right>\n<td><font $blue><b>$day</b></font></td>";
      foreach $month (@monthCol){
          print "<td>$Tbl{$month}{$day}</td>";
      }
      print "<td>$DayTtl{$day}</td>";
    }
    print "\n</tr><tr align=right>\n<td nowrap align=center><font $green><b>Month Totals</b></font></td>";

    foreach $month ( @monthCol ){ print "<td>$MonthTtl{$month}</td>"; }
    print "<th>$total</th>";
    print "\n</tr></table>";
 
# end bypage
}elsif( $Form{'displaycount'} ){

##################################################################
# Case: Display hitcount

  open (CNT,"<$HITCNT");
  @hitFile = <CNT>;
  close (CNT);

  print "<table border=1><tr>\n";
  print "<th>HITS</th><th>PAGECODE</th>\n";

  $hitTtl =0;
  $x = @hitFile;
  for( @hitFile ){
    print "\n</tr><tr>\n";
    ($count,$code) = split (/\|/);
    $p = html($code);
    print qq(<td align=right>$count</td><td><A HREF="?table=page|$p">$p<\A></td>);
    $hitTtl += $count;
  }
  print "\n</tr></table><p>\n";

  open (CFG,"<$HITCFG");
  $cfgFile = <CFG>;
  close (CFG);

#  ($logDay,$datMonth,$cntMonth,$eol) = split (/\|/,$cfgFile);
  $cntMonth = (split /\|/,$cfgFile)[2];

  $year = $yearStamp - ($monthStamp < $cntMonth);
  print "<b>Total: $hitTtl hits for $x pages since $labels[$cntMonth] 1, $year</b>\n";

 # end displaycount
}else{

######################################################################
# Case: View Hit stats by year

  print "<font size=5>Hits By YEAR</font> as of $timeStamp</br>\n";

  # Read all data into a 'hash of hashes'
  $total = 0;

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

    $HITDAT = "$HITMON$month.dat";
    open (DAT,"<$HITDAT") || next;

    while( <DAT> ){
      @hits = split (/\|/);
      $page = $hits[0];
      $Tbl{$month}{$page} =0;
      foreach $day (1..31){
          $Tbl{$month}{$page} += $hits[$day];
      }
      $PageTtl{$page} += $Tbl{$month}{$page};
      $MonthTtl{$month} += $Tbl{$month}{$page};
    }
    close (DAT);
    $total += $MonthTtl{$month};
  }
  open(CNT,"<$HITCNT");
  @hitFile = <CNT>;
  close (CNT);
  foreach( @hitFile ){
        ($count,$code) = split (/\|/);
        $MonthTtl{0} += $Tbl{0}{$code} = $count-$PageTtl{$code};
        $PageTtl{$code} = $count;
  }
  $total += $MonthTtl{0};

  # Sort by descending page total
  @pages = sort {$PageTtl{$b} <=> $PageTtl{$a}} keys %PageTtl;

  print "<table border=1><tr align=center>\n<td nowrap><b>Pages/Months</b></td>";
  print "<td><font $blue><b>Prior<br>Years</b></font></td>";

  # Print col headers and order the months
  @monthCol = ($monthStamp+1..12,1..$monthStamp);
  for $month ( @monthCol ){
    $year = ($yearStamp - ($month>$monthStamp))%100;
    $year = "'$year" if( $year < 10 );
    print qq(<td><A HREF="?table=month|$month"><font $green><b>$labels[$month]</b><br>$year</font></a></td>);
  }
  unshift @monthCol,0;

  print qq(<td><font $blue><b>Page<br>Totals</b></font></td>);

  foreach $page (@pages){
     $p = html($page);
     print qq(\n</tr><tr align=right>\n<td align=left><A HREF="?table=page|$p"><font $blue>$p</font></A></td>);
    foreach $month (@monthCol){
        print "<td>$Tbl{$month}{$page}</td>";
    }
    print "<td>$PageTtl{$page}</td>";
  }
  print "\n</tr><tr align=right>\n<td nowrap align=center><font $green><b>Totals</b></font></td>";

  foreach $month ( @monthCol ){
      print "<td>$MonthTtl{$month}</td>";
  }
  print "<th>$total</th>";
  print "\n</tr></table><p>\n";

 # end case byyear
}
##################################################################
# print end of form

print "<br>Completed at $timeStamp<p>" unless( $Form{'byyear'} );
&yearButton unless(  $Form{'byyear'} );
&cntButton unless( $Form{'displaycount'} );
print "</form>\n";
print "<p><a href=\"$exitUrl\">EXIT $headTitle</a>\n";
print "<p></body></html>\n";

##################################################################

sub yearButton{
  print "<p><font size=5><b>Hit Tables</b></font><br>\n";
  print '<input type=submit name="byyear" value="By YEAR">';
} # end yearButton

sub cntButton{
  print "<p><font size=5><b>Hit Counter</b></font>\n";
  print '<br><input type=submit name="displaycount" value="DISPLAY">';
} # end cntButton

sub html($){
        local($_) = @_;
        s/&/&amp;/g;
        s/"/&quot;/g;
        s/</&lt;/g;
        s/>/&gt;/g;
        return $_;
}

##################################################################
# Sub: Lock or Unlock a file

sub lock{
  $LOCKFILE = $_[0];
  $endTime = time + 10;
  while( $lockFlag ne "Y" && -e $LOCKFILE && time < $endTime ){ } # snooze
  open (LOCKFILE);
  if( $lockFlag eq "Y" ){ flock (LOCKFILE,2); }
} # end lock

sub unlock{
  $LOCKFILE = $_[0];
  if( $lockFlag eq "Y" ){ flock (LOCKFILE,8); }
  close (LOCKFILE);
  if( $lockFlag ne "Y" && -e $LOCKFILE ){ unlink ($LOCKFILE); }
} # end unlock


0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Using SQL Scripts we can save all the SQL queries as files that we use very frequently on our database later point of time. This is one of the feature present under SQL Workshop in Oracle Application Express.
Envision that you are chipping away at another e-business site with a team of pundit developers and designers. Everything seems, by all accounts, to be going easily.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial walks through the best practices in adding a local business to Google Maps including how to properly search for duplicates, marker placement, and inputing business details. Login to your Google Account, then search for "Google Mapmaker…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now