Писалось по принципу лишь бы работало. Связку с radius и Postrges можно выкинуть.
Нужные модули не забудь.
#!/usr/bin/perl
use DBI;
use Time::Local;
use Net::Telnet;
use POSIX qw(:sys_wait_h);
$kick_log="/root/kick_log.txt";
$error_log="/root/errors.log";
$config{'dbhost'}="localhost";
$config{'dbuser'}="pgsql";
$config{'dbpass'}="";
$config{'dbi'} = "DBI:Pg:dbname=radius";
$config{'host'}="localhost";
$config{'port'}="5005";
$dbh = DBI->connect($config{'dbi'},$config{'dbuser'},$config{'dbpass'});
open(STDERR, ">>$error_log");
open (LOG, ">>$kick_log");
@kick_date=&sec_to_time(time);
$who=&radwho();
foreach $user (@$who) {
$us=$user->{'login'};
$sel="SELECT a.bytes AS bytes, b.disabled AS disabled FROM limituser a, users b WHERE a.username='$us' AND a.username=b.username";
$st=$dbh->prepare($sel);
$st->execute;
$sel=$st->fetchrow_hashref;
$ostatok=$sel->{'bytes'};
$disable=$sel->{'disabled'};
$st->finish;
$sel="SELECT bytelimit FROM orders WHERE username='$us' AND bytelimit>0 AND dolg ORDER BY orderdate DESC LIMIT 1";
$st=$dbh->prepare($sel);
$st->execute;
$sel=$st->fetchrow_hashref;
$limit=($sel->{'bytelimit'});
$st->finish;
$limit=$limit*0.1;
$maxlimit=50*1024*1024;
if ( $disable!=0 || ($ostatok<=0 && (abs($ostatok)>=$limit || abs($ostatok)>=$maxlimit))){
&kick($user->{'tty'});
print LOG "User - $us - kiked successfully at - $kick_date[0] $kick_date[1]. Limit=$limit Ostatok=$ostatok\n";
}
}
close (LOG);
close (STDERR);
$dbh->disconnect;
################### kick user ################
sub kick {
local ($line, $tty);
$tty = $_[0];
$tty =~ s/S//;
if ( $conn = Net::Telnet->new( Host => $config{'host'}, Port => $config{'port'}) ) {
$conn->print("link pptp$tty");
$line=$conn->getline;
$conn->print("close");
$line=$conn->getline;
$conn->print("exit");
$line=$conn->getline;
$conn->close;
}
return 1;
}
################# who #####################
sub radwho {
local(@cmd, @line, @us);
$program='/usr/local/bin/radwho';
$arg1='-ir';
$res=`$program $arg1` or die "Couldn't run $program: $!\n";
@cmd=split(/\n/, $res);
foreach(@cmd) {
@line=split(/,/, $_);
push(@us, {'login'=>$line[0], 'name'=>$line[1],
'what'=>$line[2], 'tty'=>$line[3],
'when'=>$line[4], 'from'=>$line[5],
'location'=>$line[6]});
};
return \@us;
}
#################### time ###################
sub sec_to_time {
local ($time);
$time = $_[0];
($secn,$minn,$hour,$dayn,$monn,$yearn) = localtime($time);
$monn=$monn+1;
$yearn=$yearn-100;
if ($yearn<10) {$yearn="0$yearn";}
if ($monn<10) {$monn="0$monn";}
if ($dayn<10) {$dayn="0$dayn";}
if ($hour<10) {$hourn="0$hour";}
else {$hourn="$hour";}
if ($minn<10) {$minn="0$minn";}
if ($secn<10) {$secn="0$secn";}
$daten="$dayn\.$monn\.$yearn";
$timen="$hourn\:$minn\:$secn";
return $daten, $timen, $hour;
}