#!/usr/bin/perl -w
#
# Kotnet login/out/bandwidth checker
# Goldie 2006
#
# Use: perl kotnet.pl [up/start|down/stop|check]
#
# Needs 	WWW::Mechanize (libwww-mechanize-perl)
#		Crypt::SSLeay (libcrypt-ssleay-perl)
#
# Windows: use ppm to install packages

use strict;
use WWW::Mechanize;

### 
my $username = "";
my $password = "";
###

my $loginpage = "https://netlogin.kuleuven.be/cgi-bin/wayf.pl?inst=kuleuven&lang=nl&submit=Ga+verder+%2F+Continue";
my $mech = WWW::Mechanize->new(agent => "Auto kotnet login 0.2");

print "Kotnetscript - Goldie 2006\n";
sanityCheck();

if (@ARGV == 0 || $ARGV[0] eq "up" || $ARGV[0] eq "start") {	login(); 		} 
elsif ($ARGV[0] eq "down" || $ARGV[0] eq "stop") {		logout();		} 
elsif ($ARGV[0] eq "check") {					checkBandwidth();	} 
else {								printUsage();		}
exit 0;

sub login
{
	$mech->get($loginpage) or die;
	$mech->form_name ("netlogin");
	$mech->set_visible($username, $password) or die;
	$mech->submit() or die;

	interpretResultCode();
}

sub checkBandwidth
{
	login();
	
	if ($mech->content =~ m/<h2>campusnet<\/h2>/i) {
		print "There is no bandwidth control on campusnet\n";
	} else {
		$mech->content(format => 'text') =~ m/(\d{1,4}) MBytes\((\d{1,4})%\).*?(\d{1,4}) MBytes\((\d{1,4})%\)/;
		print "Download : $1 MB ($2%) \n";
		print "Upload : $3 MB ($4%) \n";
	}
}

sub logout
{
	login();

	my $logoutpage = getLogoutURL(getIp());

	$mech->get($logoutpage) or die;
	$mech->set_visible($password) or die;
	$mech->submit();

	print "Logged out\n";
}

sub logoutStaleSession
{
	print "There are too many simultaneous logins: \n";
	my $logoutAddress = getLogoutAddress(getLogins());

	print "Logging out $logoutAddress...\n";
	my $logoutpage = getLogoutURL($logoutAddress);

	$mech->get($logoutpage) or die;
	$mech->form_name ("netlogout");
	$mech->set_visible($password) or die;
	$mech->submit();
}

sub getLogoutAddress
{
	for (my $i=0; $i<@_; $i++) {
		print " (" . ($i+1) . ") - ip " . $_[$i] . " \n";
	}

	return $_[0] if (@_ == 1);

	my $choice;
	do {
		print "Select an ip to log out: ";
		$choice = <STDIN>;
		chomp $choice;
	} until (defined $choice && $choice > 0 && $choice <= @_);

	return $_[$choice-1];
}

# logins scrapen en dubbels filteren, want soms staan de ips dubbel op de 
sub getLogins
{
	my @ips = $mech->content =~ m/<INPUT type=hidden name="ip" value="([0-9\.]*)">/g;
	my @result;

	foreach my $temp (@ips) {
		my $unique = 1;
		foreach my $temp2 (@result) {
			if ($temp eq $temp2) { 
				$unique = 0; 
				last; 
			}
		}

		push(@result, $temp) if ($unique);
	}

	return @result;
}

sub getLogoutURL
{
	my $logoutip = shift;
	return "https://netlogin.kuleuven.be/cgi-bin/wayf.pl?inout=logout&ip=$logoutip&uid=kuleuven/$username&lang=ned";
}

# scrapen naar resultcode in de html
sub interpretResultCode
{
	my $text = $mech->content;
	$text =~ s/\n//g;
	$text =~ m/<b>(\d*?)<\/b> : (.*?)<.*>/i;

	if ($1 == 100) {
		print "Logged in\n";	
	} elsif ($1 == 206) {
		logoutStaleSession();
		login();
	} else {
		print "Login failed: $1: $2\n";
		exit 1;
	}
}

# ip uit html scrapen
sub getIp
{
	$mech->content =~ m/ip-addr = ([0-9\.]*)<BR>/;
	return $1;
}

sub printUsage
{
	print "Usage : \n";
	print "\t kotnet \t\t login \n";
	print "\t kotnet [up|start] \t login \n";
	print "\t kotnet [down|stop] \t logout \n";
	print "\t kotnet check \t\t display bandwidth\n";
}

sub sanityCheck 
{
	die "!! You must enter a username and password !!" if ($username eq "" || $password eq "");
}
