#!/usr/bin/perl
#
# squid-gather.pl
#
# kjl/15-12-2003
#
# Create a SOIF stream from the Squid cache objects.
#
# Usage:
#  squid-gather.pl <squid-cache-directory>
#    where "squid-cache-directory" is the top level directory of squid
#    cache objects.
#
# Or:
#  squid-gather.pl <squid-cache-directory> | template2db squid-gather.gdbm
#  consoldb PRODUCTION.gdbm squid-gather.gdbm
#

$ENV{'HARVEST_HOME'} = "/usr/local/harvest"
    if (!defined($ENV{'HARVEST_HOME'}));
$ENV{'PATH'} =
    "$ENV{'HARVEST_HOME'}/lib" . ":" .
    "$ENV{'HARVEST_HOME'}/lib/gatherer" . ":" .
    "$ENV{'PATH'}";

use Time::Local;

#
# This Gatherer Information
#

$gatherer_name = "Squid Cache Gatherer";
chop ($gatherer_host = `hostname`);
$gatherer_version = "0.0";
$time_to_live = 28 * 86400;
$refresh_rate = 7 * 86400;


usage () if ($#ARGV <= -1);
recurse_dir ($ARGV[0]);
exit;


sub usage {
    print "squid-gather.pl <squid-cache-directory>\n";
    exit 1;
}


sub recurse_dir {

    my $dir = shift;

    opendir (DIR, $dir) || return;
    my @content = grep (/\d+/, readdir (DIR));
    closedir (DIR);

    foreach $t_dir (@content) {
	if (-f "$dir/$t_dir") {
	    squid_read ("$dir/$t_dir");
	} else {
	    recurse_dir ("$dir/$t_dir");
	}
    }
}


sub squid_read {

    my $cache_file = shift;

    my ($do_print, $uri, $content_type, $type, $content_length,
	$last_modified, $date);

    $do_print = 0;

    open (IN, "<$cache_file") or die "Can't open $cache_file: $!";

    seek IN, 60, 0;
    $_ = <IN>;

    ($uri) = /^(.+?)\x00.*/;

    while (<IN>) {

	if (/^Content-Type: /) {
	    ($content_type) = /^Content-Type: (.+)\r/;
	    if (($content_type =~ /^text\/html/)) {
		$type = "HTML";
		$do_print = 1;
		next;
	    }
	}
	if (/^Content-Length: /) {
	    ($content_length) = /^Content-Length: (.+)\r/;
	    $file_size = $content_length;
	    next;
	}
	if (/^Last-Modified: /) {
	    ($last_modified) = /^Last-Modified: (.+)\r/;
	    next;
	}
	if (/^Date: /) {
	    ($date) = /^Date: (.+)\r/;
	    next;
	}
	last if (/^\r$/);
    }

    if ($do_print) {
	$last_modification_time = parse_date ($last_modified) if ($last_modified);
	$update_time = parse_date ($date) if ($date);

	open (OUT, ">squid-gather.$$") or die "Can't write :$!";
	while (<IN>) {
	    print OUT;
	}
	close (OUT);

	$summary = `HTML.sum squid-gather.$$`;
	chop ($md5 = `cat squid-gather.$$ | md5`);
	unlink "squid-gather.$$";
	print_soif ();
    }

    close (IN);
}


sub parse_date {

    my $readable_time = shift;
    $_ = $readable_time;

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

    ($day, $month, $year, $h, $m, $s) =
	/\S+\s(\d+)\s(\w+)\s(\d+)\s(\d+):(\d+):(\d+).*/;
    $time = timegm ($s, $m, $h, $day, $month_name {$month}, $year);
    return $time;
}


sub print_soif {
    print "\@FILE \{ $uri\n";
    print_soif_av ("Update-Time", $update_time);
    print_soif_av ("Last-Modification-Time", $last_modification_time);
    print_soif_av ("Time-To-Live", $time_to_live);
    print_soif_av ("Refresh-Rate", $refresh_rate);
    print_soif_av ("Gatherer-Name", $gatherer_name);
    print_soif_av ("Gatherer-Host", $gatherer_host);
    print_soif_av ("Gatherer-Version", $gatherer_version);
    print_soif_av ("Type", $type);
    print_soif_av ("File-Size", $file_size);
    print_soif_av ("URI", $uri);
    print_soif_av ("MD5", $md5);
    print $summary;
    print "\}\n";
}


sub print_soif_av {
    my ($key, $val) = @_;
    my $len = length ($val);
    return if ($len < 1);
    print "$key\{$len\}:\t$val\n";
}
