#!/usr/pkg/bin/perl
#
# @(#)proc-xferlog.pl,v 1.7 2005/01/01 05:35:22 kim Exp
#
# Summarize FTP transfers
#
# 1996-07-30  Kimmo Suominen
#
$totalbytes = 0;

while (<>) {
    chomp;
    @_ = split;
    $site{$_[11]}{$_[6]}++;		# count for each site
    $time{$_[11]}{$_[6]} = 0 unless defined($time{$_[11]}{$_[6]});
    $time{$_[11]}{$_[6]} += $_[5];	# transfer times
    $size{$_[11]}{$_[6]} = 0 unless defined($size{$_[11]}{$_[6]});
    $size{$_[11]}{$_[6]} += $_[7];	# transfer bytes
    if ($_[11] ne 'd') {
	$type{$_[11]}{$_[9]}++;		# count for each transfer type
	$conv{$_[11]}{$_[10]}++;	# count for each conversion
	$totalbytes += $_[7];		# total transferred bytes
    }
    $file{$_[11]}{$_[8]}++;		# count for each file
    $anon{$_[11]}{$_[12]}++;		# count for connection type
}

$limit = 10;

printf " Total  %d kB\n\n", $totalbytes / 1024;

foreach $i (sort (keys %type)) {
    printf " Files  %s Connection Types\n", &typename($i);
    printf " -----  -------------------------------------------------------\n";
    &conncnt($type{$i}, *xfertype);
    &conncnt($conv{$i}, *convtype);
    &conncnt($anon{$i}, *logintype);
    printf "\n";
}

foreach $i (sort (keys %site)) {
    $title = "TOP $limit " . &typename($i) . " Sites";
    &topsites($title, $site{$i}, $time{$i}, $size{$i}, $i);
}

foreach $i (sort (keys %file)) {
    $title = &typename($i) . " Files";
    $l = 0;
    if ($i eq 'o') {
	$title = "TOP $limit " . $title;
	$l = $limit;
    }
    &topfiles($title, $l, $file{$i});
}

exit 0;

sub typename {
    local($type) = shift(@_);

    if ($type eq "d") {
	return "Deleted";
    }
    if ($type eq "i") {
	return "Incoming";
    }
    if ($type eq "o") {
	return "Outgoing";
    }
    return "in/out???";
}

sub xfertype {
    local($type) = shift(@_);

    if ($type eq "a") {
	return "ascii";
    }
    if ($type eq "b") {
	return "binary";
    }
    return "untyped";
}

sub convtype {
    local($type) = shift(@_);

    if ($type eq "C") {
	return "compressed";
    }
    if ($type eq "U") {
	return "uncompressed";
    }
    if ($type eq "T") {
	return "tarred";
    }
    if ($type eq "_") {
	return "unconverted";
    }
    return "converted(?)";
}

sub logintype {
    local($type) = shift(@_);

    if ($type eq "a") {
	return "anonymous access";
    }
    if ($type eq "g") {
	return "guest access";
    }
    if ($type eq "r") {
	return "real user";
    }
    return "unknown access";
}

sub conncnt {
    local(*arry) = shift(@_);
    local(*conv) = shift(@_);

    local($i);

    foreach $i (sort {$a cmp $b} (keys %arry)) {
	printf "%6d  %s transfers\n", $arry{$i}, &{*conv}($i);
    }
}

sub pathxlate {
    local($_) = shift(@_);
    s,/net/[^/]+/([^-/]+)-[0-9]+/,/\1/,;
    s,/src/NetBSD/cvsroot/doc/,/usr/doc/,;
    s,/src/NetBSD/cvsroot/htdocs/,/usr/htdocs/,;
    s,/src/NetBSD/cvsroot/pkgsrc/,/usr/pkgsrc/,;
    s,/src/NetBSD/cvsroot/src/,/usr/src/,;
    s,/src/NetBSD/cvsroot/xsrc/,/usr/xsrc/,;
    s,/usr/local/pkg/,/usr/pkg/,;
    s,/proj/ftp/root/mirrors/,/proj/ftp/root/,;
    s,/proj/ftp/root/pub/,/pub/,;
    return $_;
}

sub topfiles {
    local($title) = shift(@_);
    local($limit) = shift(@_);
    local(*file) = shift(@_);

    local($total) = 0;
    local($lines) = 0;
    local($i);

    printf " Count  %s\n", $title;
    printf " -----  -------------------------------------------------------\n";
    foreach $i (sort {$file{$b} <=> $file{$a} || $a cmp $b} (keys %file)) {
	$total += $file{$i};
	printf "%6d  %-s\n", $file{$i}, pathxlate($i);
	next if $limit < 1;
	last if (++$lines > $limit);
    }
    printf " -----  -------------------------------------------------------\n";
    printf "%6d  %-s\n\n", $total, "TOTAL";
}

sub topsites {
    local($title) = shift(@_);
    local(*site) = shift(@_);
    local(*time) = shift(@_);
    local(*size) = shift(@_);
    local($type) = shift(@_);

    local($totf) = 0;
    local($tots) = 0;
    local($totb) = 0;
    local($lines) = 0;
    local($i);

    printf " Files       kB    kB/s  %s\n", $title;
    printf " -----  -------  ------  ---------------------------------------\n";
    foreach $i (sort {$size{$b} <=> $size{$a} || $a cmp $b} (keys %size)) {
	$totc++;
	# pretend it took at least 1 second
	$time{$i}++ if $time{$i} < 1;
	$totf += $site{$i};
	$tots += $time{$i};
	$totb += $size{$i};
	printf
	    "%6d  %7d  %6.1f  %-s\n",
	    $site{$i},
	    $size{$i} / 1024,
	    (($type ne 'd') ? ($size{$i} / (1024 * $time{$i})) : 0),
	    $i;
	last if (++$lines > $limit);
    }
    printf " -----  -------  ------  ---------------------------------------\n";
    printf
	"%6d  %7d  %6.1f  %-s\n",
	$totf / $totc,
	$totb / (1024 * $totc),
	(($type ne 'd') ? ($totb / (1024 * $tots)) : 0),
	"AVERAGE";
    printf
	"%6d  %7d  %6s  %-s\n\n",
	$totf,
	$totb / 1024,
	"",
	"TOTAL";
}
