#!/p/bin/perl


#
# Directory configuration
#

umask(022);

$logdir = "/var/adm";
$logstorage = "/p/log/ftp/raw";
$upload_reports = "/p/log/ftp/upload";
$download_reports = "/p/log/ftp/download";
$stat_reports = "/p/log/ftp/statistics";
$summary_address = "ftp-reports@nic.funet.fi";
$LOGFIL="< $logdir/ftpd.log.yesterday";

$top_size = 10;

#
# Calendar :)
#

@days = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
@months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');

$yesterday = 0;
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time-$yesterday);
$verbose = sprintf("%s  %s %2d 19%d", $days[$wday], $months[$mon], $mday, $year);
$timestamp = sprintf("%02d%02d%02d", $year, $mon+1, $mday);
$daystamp = sprintf("%s", $days[$wday]);
$weekstamp = sprintf("%s", $yday/7+1);
$monthstamp = sprintf("%02d%02d", $year, $mon+1);

if ($ARGV[0] eq "save") {  # Do this at midnight..
	#
	# Move old ftpd log to log storage and create week link
	#

	mkdir ("$logstorage/$monthstamp", 0755);

	system ("/p/bin/gzip -c $logdir/ftpd.log.yesterday > $logstorage/$monthstamp/$timestamp.gz");
	unlink ("$logdir/ftpd.log.yesterday", "$logstorage/week/$daystamp");
	symlink ("../$monthstamp/$timestamp.gz", "$logstorage/week/$daystamp");

	#
	# Move current logfile to ftpd.log.yesterday
	#

	rename ("$logdir/ftpd.log", "$logdir/ftpd.log.yesterday");
	system ("touch $logdir/ftpd.log");


	exit(0);  # Save done..
}
#
# Create the daily reports for yesterday
#

if ($ARGV[0] ne "") {
	$LOGFIL="zcat $logstorage/$ARGV[0] |";
}

$yesterday = 43200;
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time-$yesterday);
$verbose = sprintf("%s  %s %2d 19%d", $days[$wday], $months[$mon], $mday, $year);
$timestamp = sprintf("%02d%02d%02d", $year, $mon+1, $mday);
$daystamp = sprintf("%s", $days[$wday]);
$weekstamp = sprintf("%s", $yday/7+1);
$monthstamp = sprintf("%02d%02d", $year, $mon+1);

open (MAIL, "| /usr/lib/sendmail $summary_address");

print MAIL "From: FTP Statistics <ftp-admin@nic.funet.fi>\n";
print MAIL "To: $summary_address\n";
print MAIL "Subject: Anonymous FTP statistics - $verbose\n\n";

open (LOG, "$LOGFIL");

$totalsize = 0.0;
$mailsize  = 0.0;

while (<LOG>) {
	chop;
	if (/^L/) {			# Open connection
		($x, $pid, $remotehost, $locality, $account, $email, @date) = split;
		if ($remotehost =~ /^\[/) { $remotehost = "ip-address"; }
		$remotehost =~ tr/[A-Z]/[a-z]/;
#		$date=join(@date, ' ');
		($login{$pid . " " . $remotehost} = $email) =~ s/'//g;
#		$hosts{$remotehost}++;
#		push (@hosts, $remotehost);
		$totalusers++;
	}
	elsif (/^O/) {			# Close connection
#		($x, $pid, $remotehost, $bytes, $time) = split;
#		$remotehost =~ tr/[A-Z]/[a-z]/;
#		$logout{$pid . " " . $remotehost} = $time;
	}
	elsif (/^RM/) {			# Retrieve file - mailserver
		($x, $pid, $remotehost, $path, $size, $transfertime, $file) = split;
		if ($remotehost =~ /^\[/) { $remotehost = "ip-address"; }
		$remotehost =~ tr/[A-Z]/[a-z]/;
		$mailfiles++;
		$mailsize+=$size;
		# $totalfiles++;
		# $totalsize+=$size;
		#if ($transfertime > 0 && $transfertime < 86400) {
		#	$totaltransfertime+=$transfertime;
		#	$retrieve_time {$remotehost} += $transfertime;
		#}
		$hosts {$remotehost}++;
		$files {$remotehost} += $size;
		if ($file =~ /^\/pub\//) {
			# $file =~ tr/[A-Z]/[a-z]/;
			(@dirs) = split(/\//, $file);
			$area_size{$dirs[2]}+=$size;
			$area_count{$dirs[2]}++;
		}
	}
	elsif (/^RN/) {			# Retrieve file - non-anonymous FTP
		($x, $pid, $remotehost, $path, $size, $transfertime, $file) = split;
		if ($remotehost =~ /^\[/) { $remotehost = "ip-address"; }
		$remotehost =~ tr/[A-Z]/[a-z]/;
		$nonanonfiles++;
		$nonanonsize+=$size;
		# $totalfiles++;
		# $totalsize+=$size;
		#if ($transfertime > 0 && $transfertime < 86400) {
		#	$totaltransfertime+=$transfertime;
		#	$retrieve_time {$remotehost} += $transfertime;
		#}
		$hosts {$remotehost}++;
		$files {$remotehost} += $size;
		if ($file =~ /^\/pub\//) {
			# $file =~ tr/[A-Z]/[a-z]/;
			(@dirs) = split(/\//, $file);
			$area_size{$dirs[2]}+=$size;
			$area_count{$dirs[2]}++;
		}
	}
	elsif (/^R/) {			# Retrieve file - ftp server
		($x, $pid, $remotehost, $path, $size, $transfertime, $file) = split;
		if ($remotehost =~ /^\[/) { $remotehost = "ip-address"; }
		$remotehost =~ tr/[A-Z]/[a-z]/;
		$totalfiles++;
		$totalsize+=$size;
		if ($transfertime > 0 && $transfertime < 86400) {
			$totaltransfertime+=$transfertime;
			$retrieve_time {$remotehost} += $transfertime;
		}
		$hosts {$remotehost}++;
		$files {$remotehost} += $size;
		if ($file =~ /^\/pub\//) {
			# $file =~ tr/[A-Z]/[a-z]/;
			(@dirs) = split(/\//, $file);
			$area_size{$dirs[2]}+=$size;
			$area_count{$dirs[2]}++;
		}
	}
	elsif (/^S/) {			# Store file
		($x, $pid, $remotehost, $size, $file) = split;
		if ($remotehost =~ /^\[/) { $remotehost = "ip-address"; }
		if ($file =~ /^\/pub\//) {
			# $file =~ tr/[A-Z]/[a-z]/;
			(@dirs) = split(/\//, $file);
		} else {
			$dirs[2] = "Others";
		}
		$upload{$dirs[2]} .= sprintf("%s\n\t%d bytes\n\t%s (%s)\n", $file, $size, $login{$pid . " " . $remotehost}, $remotehost);;
	}
	elsif (/^C/) {			# Command
	}
}

close LOG;

#
# Daily upload reports
#

mkdir ("$upload_reports/$monthstamp", 0755);

foreach $area (keys %upload) {
	open (UPLOAD, "> $upload_reports/$monthstamp/$timestamp.$area");
	chmod ($upload_reports/$monthstamp/$timestamp.$area, 0444);
	print UPLOAD "$upload{$area}";
	close UPLOAD;
}

#
# Daily domain statistics
#

mkdir ("$stat_reports/daily/$monthstamp", 0755);

foreach $host (keys %hosts) {
	next if ($host =~ /^\[/);
	(@domains) = split(/\./, $host);
	$toplevel_count{$domains[$#domains]}+=$hosts{$host};
	$toplevel_bytes{$domains[$#domains]}+=$files{$host};
	$toplevel_time{$domains[$#domains]}+=$retrieve_time{$host};
}

open (SUMMARY, "> $stat_reports/daily/$monthstamp/$timestamp.summary");

printf SUMMARY ("FUNET Archive nic.funet.fi statistics for $verbose

Daily transmission statistics:

	Files transmitted			%12d
	Bytes transmitted			%12.0f
	Average KB/s rate (per user)		%12.2f
	Average KB/s rate (daily)		%12.2f
	Number of users				%12d
	Bytes transmitted per user		%12d
	Mailserver files			%12d
	Mailserver bytes			%12.0f
	Non-anonymous FTP files			%12d
	Non-anonymous FTP bytes			%12.0f
", $totalfiles, $totalsize, ($totaltransfertime==0)?0:(($totalsize/1024)/$totaltransfertime), ($totalsize==0)?0:(($totalsize/1024)/86400.0), $totalusers, ($totalusers==0)?0:$totalsize/$totalusers), $mailfiles, $mailsize, $nonanonfiles, $nonanonsize;

printf MAIL ("FUNET Archive nic.funet.fi statistics for $verbose

Daily transmission statistics:

	Files transmitted			%12d
	Bytes transmitted			%12.0f
	Average KB/s rate (per user)		%12.2f
	Average KB/s rate (daily)		%12.2f
	Number of users				%12d
	Bytes transmitted per user		%12d
	Mailserver files			%12d
	Mailserver bytes			%12.0f
	Non-anonymous FTP files			%12d
	Non-anonymous FTP bytes			%12.0f
", $totalfiles, $totalsize, ($totaltransfertime==0)?0:(($totalsize/1024)/$totaltransfertime), ($totalsize==0)?0:(($totalsize/1024)/86400.0), $totalusers, ($totalusers==0)?0:$totalsize/$totalusers), $mailfiles, $mailsize, $nonanonfiles, $nonanonsize;

close SUMMARY;

open (SECTION, "> $stat_reports/daily/$monthstamp/$timestamp.by-area");

print SECTION "
						---- Percent  of ----
Archive section		Bytes sent  Files sent  Bytes sent Files sent
----------------------- ----------- ----------- ---------- ----------\n";

print MAIL "\nTop $top_size of archive sections:

						---- Percent  of ----
Archive section		Bytes sent  Files sent  Bytes sent Files sent
----------------------- ----------- ----------- ---------- ----------\n";

sub area_sort { $area_size{$a} < $area_size{$b} ? 1 : $area_size{$a} > $area_size{$b} ? -1 : 0; }

$count = 0;

foreach $area (sort area_sort keys %area_size) {
	printf SECTION ("%-20.20s    %9d   %9d     %5.2f %%    %5.2f %%\n", $area, $area_size{$area}, $area_count{$area}, ($area_size{$area}/$totalsize)*100, ($area_count{$area}/$totalfiles)*100);
	if ($count < $top_size) {
		printf MAIL ("%-20.20s    %9d   %9d     %5.2f %%    %5.2f %%\n", $area, $area_size{$area}, $area_count{$area}, ($area_size{$area}/$totalsize)*100, ($area_count{$area}/$totalfiles)*100);
	}
	$count++;
}

close SECTION;

open (DOMAIN, "> $stat_reports/daily/$monthstamp/$timestamp.by-domain");

printf DOMAIN ("
	Number of   Number of 	Average	   Percent of  Percent of
Domain 	files sent  bytes sent	xmit rate  files sent  bytes sent
------- ----------- ----------- ---------- ----------- ----------\n");

printf MAIL ("
Top $top_size of domains:

	Number of   Number of 	Average	   Percent of  Percent of
Domain 	files sent  bytes sent	xmit rate  files sent  bytes sent
------- ----------- ----------- ---------- ----------- ----------\n");

sub top_level_sort { $toplevel_bytes{$a} < $toplevel_bytes{$b} ? 1 : $toplevel_bytes{$a} > $toplevel_bytes{$b} ? -1 : 0; }

$count = 0;

foreach $domain (sort top_level_sort keys %toplevel_bytes) {
	printf DOMAIN ("%-6.6s  %9d   %9d   %5.2f KB/s   %5.2f %%     %5.2f %%\n", $domain, $toplevel_count{$domain}, $toplevel_bytes{$domain}, ($toplevel_time{$domain}==0)?0:($toplevel_bytes{$domain}/1024)/$toplevel_time{$domain}, ($toplevel_count{$domain}/$totalfiles)*100, ($toplevel_bytes{$domain}/$totalsize)*100);
	if ($count < $top_size) {
		printf MAIL ("%-6.6s  %9d   %9d   %5.2f KB/s   %5.2f %%     %5.2f %%\n", $domain, $toplevel_count{$domain}, $toplevel_bytes{$domain}, ($toplevel_time{$domain}==0)?0:($toplevel_bytes{$domain}/1024)/$toplevel_time{$domain}, ($toplevel_count{$domain}/$totalfiles)*100, ($toplevel_bytes{$domain}/$totalsize)*100);
	}
	$count++;
}

close DOMAIN;

close MAIL;

exit 0;
