#!/usr/bin/perl
#<LISTING>
# ------------------------------------------------------------------------
#
#  readlog  - a tool for reading part of the www-servers access log
#             and displaying it in html 
#             run it in the http-servers htbin directory
#
#  Usage:  readlog filename > log.html      (writes to std out)
#  in WWW: HREF = "htbin/readlog?filename"
#
#  Author  Brigitte Jellinek 
#  e-mail  bjelli@cosy.sbg.ac.at
#  HREF = "http://www.cosy.sbg.ac.at/people/bjelli.html"
#
#  Version 2.6   -   sorts by date, backlinks to files
#
#  use at your own risk !  - if you enhance it, please give me a copy
#
# ------------------------------------------------------------------------
# this script greps the access_log (found in $www_server_dir )
# for the filename, and then gives a summary of the information found.

$local_server = $ENV{'SERVER_NAME'};
# $www_server_dir = $ENV{'SERVER_ROOT'};
$www_server_dir = "/var/ncsa-httpd";
# $www_documents_dir = $ENV{'DOCUMENT_ROOT'};
$www_documents_dir = "/";

# a few arrays for storing the information we find:
$| = 1;
$date = `/bin/date`;

@last = ();     # last access by host
@count = ();    # no of accesses by host
%index = ();    # index: host (as found in log), value: index of above arrays


# for sorting by date

%no_of_month = ( Jan, 1, Feb, 2, Mar, 3, Apr, 4, May, 5, Jun, 6,
                     Jul, 7, Aug, 8, Sep, 9, Oct,10, Nov,11, Dec,12 );

sub bydate     # for sorting

   {   ($amonth, $ano) = split(/ /, $last[$index{$a}]);   
       ($bmonth, $bno) = split(/ /, $last[$index{$b}]);

       if ( $amonth eq $bmonth ) 
       {  $ano <=> $bno }
       else  
       { $no_of_month{$amonth} <=> $no_of_month{$bmonth} };
   }

# two little subroutins for formating output - really not important

sub pr
   {  $caller = $_[0];
      $i = $index{ $caller };
      print "$caller called ";
      if    ($count[$i]==1) { print "once, on $last[$i]\n"; }
      elsif ($count[$i]==2) { print "twice, last on $last[$i]\n"; }
      else  {print "$count[$i] times, last on $last[$i]\n"};
    };


sub prli
   {  local($heading,$pattern) = @_;
      @l = grep(/$pattern/, sort bydate keys %index);
      if ($#l >= 0) 
       { print "<H1>$heading</H1>";
         print "    <UL>\n";
         foreach (@l)
          { print "    <LI>";
            &pr( $_ ); 
            delete $index{$_};
          };
        print "    </UL>\n";
      };
    }
# Main Program.

print "Content-type: text/html \n\n";
print "<HTML>\n";
print "<HEAD>\n";
print "    <TITLE>Read Log</title>\n";
print "    <ISINDEX>\n";
print "</HEAD>\n";
print "<BODY>\n";

$filename = $ENV{'QUERY_STRING'};
$filename =~ y/+/ /;
$filename =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$filename =~ s!/[^/]+/\.\./!/!;

if ($filename eq '')    # no argument (filename to search): introduction.
    { print <<'EndOfExplanation';
      <H1>Read Log</H1>
      This is a tool for reading the httpd access log of documents.
      Enter the name of the document whos log you want to see.
      You can also use greps regular expressions.<P>
EndOfExplanation
    }
else
    {

      print "    <H1>Read Log for File[s] '$filename'</H1>\n";


      open(LOG, 
          "grep '$filename' ${www_server_dir}/logs/access_log |");

      $global_count = 0;   # whole no of accesset to $filename

      while(<LOG>)
            {
            chop;
            # ($caller,$weekday,$month,$day_of_month,
            #          $time_of_day,$year,$get,$file) = split;

	    ($p1,$p2,$p3,$p4,$p5,$p6,$p7,$p8) = split;
	    if ($p2 =~ /\[/) {
		# old format
		$caller = $p1;
		$month = $p3;
		$day_of_month = $p4;
		$file = $p8;
	    } elsif ($p4 =~ /\[([0-9]*)\/([^\/]*)\//) {
		# NCSA httpd 1.2
		$day_of_month = $1;
		$month = $2;
		$caller = $p1;
		$file = $p7;
	    } else {
		# unknown
		next;
	    };

            if ($file =~ /(.*)\?/) { $file = $1 };
            if ($file =~ /(.*)\"/) { $file = $1 };

            if ($file =~ /$filename/)
             { $global_count++;
    
                unless( $files_found =~ /$file/) 
                    { $files_found .= $file . ":" };
    
                $caller = $caller . ".cosy.sbg.ac.at"  unless $caller =~ /\./;
    
    
                if( defined $index{$caller} )  #caller already in array

                  { $i = $index{$caller};
                    $last[$i] = $month . " " . $day_of_month;
                    $count[$i]++;
                  }
                else
                  { 
                    push( @last, $month . " " . $day_of_month );
                    push( @count, 1 );
                    $i = $#count;
                    $index{ $caller } = $i;
                  };
              };
            };

      chop $files_found; 

      print "    found ($global_count) references to file[s] : \n";
      print "    <UL>  \n";
      foreach $f (split ( /:/, $files_found))
          {
          if (-e $www_documents_dir . $f )
              {
              print "    <LI><A HREF=\"http://$local_server$f\"> $f </A> \n";
              }
          else
              {
              print "    <LI> $f \n";
              }
          };
      print "    </UL> \n";

      print "<H1>local</H1>";
      foreach (grep(/cosy.sbg.ac.at/, keys %index),
              grep(/dwst..\.edvz.sbg.ac.at/, keys %index),
              grep(/.coma.sbg.ac.at/, keys %index))
            { if    ( /(.*)\.cosy/     ) {$name = $1}
              elsif ( /(dwst..\.edvz)/ ) {$name = $1}
              elsif ( /(.*\.coma)/     ) {$name = $1}
              else                       {$name = $_};
              print "$name, ";
              delete $index{$_};
            };
      print " all called.\n";

      &prli("Salzburg", '\.sbg\.ac\.at$');
      &prli("Austria", '\.at$');
      &prli("Germany", '\.de$');

      print "<H1>Earth</H1>";
      print "    <UL>\n";
      foreach (sort bydate keys %index)
            { $i = $index{ $_ };
              print "    <LI>";
              &pr($_);
            };
      print "    </UL>\n";

    }
print <<"EndOfFooter";
    <HR>
    <ADDRESS>Original script written by 
    <A HREF=${dq}http://www.cosy.sbg.ac.at/people/bjelli.html$dq>
    Brigitte Jellinek</A> (bjelli@cosy.sbg.ac.at)</ADDRESS>
    <ADDRESS>This page created: $date</ADDRESS>
</BODY> </HTML>
EndOfFooter
#
# That's all folks                                            share and enjoy !
###############################################################################
#</LISTING>
