#!/usr/bin/perl -w

# Released under the same license as Perl itself, hack it, modify it, do whatever...
# telling me where it ends up is nice (mail me : thimal@bigfoot.com) but not really necessary
# Author: Thimal Jayasooriya, 2001.01.21

# Squidlog: a simple module for Squid proxy cache log analysis. 
# version 0.01 : just common or garden squid log file parsing happens here.

package Squidlog;
use strict;

our($VERSION) = 0.01;

sub new {
        my $proto = shift;
        my $class = ref($proto) || $proto;
        my $self  = {};
        bless ($self, $class);
        return $self;
 }
 
 sub check_filename { # set the path of the log file, or return it
 	my $self = shift;
 	my $log_file = shift;
 	if(not defined $log_file) { return $self->{PATH}; }
 	else {  $self->{PATH} = $log_file; } 	
 }
 
 sub check_type { # check log file emulation type
 	my $self = shift;
 	my $type = shift;
 	if(not defined $type) { return $self->{TYPE}; }
 	else { 
 		if($type =~ /squid/i) { $type = 'SQUID'; }
 		elsif($type =~ /httpd/i) { $type = 'HTTPD'; }
 		$self->{TYPE} = $type;
 	}
 }
 
 sub load_file { # check opening the file and see if its ok, copy file ptr to class data
 	my $self = shift;
 	my $return_value = 1;
 	open(LOGFILE, "$self->{PATH}") or $return_value = undef;
 	$self->{FPTR} = *LOGFILE; 	
 	return $return_value; 	
 }
 
 sub check_metadata { # pass in a reference to a list of log file elements.. used only for associating with a hash, a default is available if you really need it
 	my $self = shift;
 	my $ref_list = shift;
 	if(defined $ref_list) { $self->{REFERENCE_LIST} = $ref_list;	}
 	else { my $rlist = $self->{REFERENCE_LIST}; my @references = @$rlist; return \@references; }
 }
 
 sub get_array_elements { # returns split elements in a reference to array
 	my $self = shift;
 	my $input = $self->get_line;
 	my $separator = $self->{SEPARATOR};
 	if(not defined $separator) { $separator = ' '; }
 	my @elements = split($separator,$input);
 	return \@elements; # return a reference to the list
 }
 
 sub get_hash_elements { # returns split elements in a hash. Uses previously set reference list for keys. You did set references right ?
 	my $self = shift;
 	my $input = $self->get_line;
 	$input =~ s/\s+/ /; # do this to get rid of the excess whitespace
 	my $separator = $self->{SEPARATOR};
	if(not defined $separator) { $separator = ' '; }
	my $rlist = $self->{REFERENCE_LIST};
	my @reference_list;
	if(not defined $rlist) { 		
		@reference_list = ('Timestamp','Total cache response time','IP address','TCP code/HTTP code','Total bytes served','Action','URL','Separator','Director URL','Mime type');
		# get a default metadata into the picture, prevents a break if someone forgets to set metadata listing
	}
	else { @reference_list = @$rlist;	}
 	my @elements = split($separator,$input);
 	my $index = 0;
 	my %elements; # predeclare to stop -w harrassment
 	foreach my $elem(@elements) {
 		$elements{$reference_list[$index]} = $elem; 		
 		$index++;
 	}
 	return \%elements; # return a reference to the array
 }
 
 sub check_separator { # allows definition of a custom separator. Default is a space ' '. Just for completeness.. space works fine on squid
 	my $self = shift;
 	my $separator = shift;
 	if(defined $separator) { $self->{SEPARATOR} = $separator; }
 	else { return $self->{SEPARATOR}; }
 }
 
 sub get_line { # for simple line prints, or more specialized fooling around outside the module. This just passes out the line. Used internally by 
 # get_hash_elements and get_array_elements
 	my $self = shift;
 	*LOGFILE = $self->{FPTR};
 	my $line = <LOGFILE>;
 	$self->{LAST_LINE} = $line;
 	if(not defined $line) { close LOGFILE; }
 	return $line;
 }
 
 sub get_last_line { # Just for completeness, this returns the previous line read.. 
 	my $self = shift;
 	return $self->{LAST_LINE};
 }
 
 sub get_version {
 	return $VERSION; 
 }
1;