diff options
Diffstat (limited to 'bin/freeside-session-kill')
| -rwxr-xr-x | bin/freeside-session-kill | 103 | 
1 files changed, 103 insertions, 0 deletions
| diff --git a/bin/freeside-session-kill b/bin/freeside-session-kill new file mode 100755 index 000000000..d5fd703f6 --- /dev/null +++ b/bin/freeside-session-kill @@ -0,0 +1,103 @@ +#!/usr/bin/perl -w + +use strict; +use vars qw($conf); +use Fcntl qw(:flock); +use FS::UID qw(adminsuidsetup datasrc dbh); +use FS::Record qw(dbdef qsearch fields); +use FS::session; +use FS::svc_acct; + +my $user = shift or die &usage; +adminsuidsetup $user; + +my $sessionlock = "/usr/local/etc/freeside/session-kill.lock.". datasrc; + +open(LOCK,"+>>$sessionlock") or die "Can't open $sessionlock: $!"; +select(LOCK); $|=1; select(STDOUT); +unless ( flock(LOCK,LOCK_EX|LOCK_NB) ) { +  seek(LOCK,0,0); +  my($pid)=<LOCK>; +  chop($pid); +  #no reason to start loct of blocking processes +  die "Is another session kill process running under pid $pid?\n"; +} +seek(LOCK,0,0); +print LOCK $$,"\n"; + +$FS::UID::AutoCommit = 0; + +my $now = time; + +#uhhhhh + +use DBIx::DBSchema; +use DBIx::DBSchema::Table; #down this path lies madness +use DBIx::DBSchema::Column; + +my $dbdef = dbdef or die; +#warn $dbdef; +#warn $dbdef->{'tables'}; +#warn keys %{$dbdef->{'tables'}}; +my $session_table = $dbdef->table('session') or die; +my $svc_acct_table = $dbdef->table('svc_acct') or die; + +my $session_svc_acct = new DBIx::DBSchema::Table ( 'session,svc_acct', '', '', '', +  map( DBIx::DBSchema::Column->new( "session.$_", +                              $session_table->column($_)->type, +                              $session_table->column($_)->null, +                              $session_table->column($_)->length, +  ), $session_table->columns() ), +  map( DBIx::DBSchema::Column->new( "svc_acct.$_", +                              $svc_acct_table->column($_)->type, +                              $svc_acct_table->column($_)->null, +                              $svc_acct_table->column($_)->length, +  ), $svc_acct_table->columns ), +#  map("svc_acct.$_", $svc_acct_table->columns), +); + +$dbdef->addtable($session_svc_acct); #madness, i tell you + +$FS::Record::DEBUG = 1; +my @session = qsearch('session,svc_acct', {}, '', ' WHERE '. join(' AND ', +  'svc_acct.svcnum = session.svcnum', +  '( session.logout IS NULL OR session.logout = 0 )', +  "( $now - session.login ) >= svc_acct.seconds" +). " FOR UPDATE" ); + +my $dbh = dbh; + +foreach my $join ( @session ) { + +  my $session = new FS::session ( { +    map { $_ => $join->{'Hash'}{"session.$_"} } fields('session') +  } ); #see no evil + +  my $svc_acct = new FS::svc_acct ( { +    map { $_ => $join->{'Hash'}{"svc_acct.$_"} } fields('svc_acct') +  } ); + +  #false laziness w/ fs_session_server +  my $nsession = new FS::session ( { $session->hash } ); +  my $error = $nsession->replace($session); +  if ( $error ) { +    $dbh->rollback; +    die $error; +  } +  my $time = $nsession->logout - $nsession->login; +  my $new_svc_acct = new FS::svc_acct ( { $svc_acct->hash } ); +  my $seconds = $new_svc_acct->seconds; +  $seconds -= $time; +  $seconds = 0 if $seconds < 0; +  $new_svc_acct->seconds( $seconds ); +  $error = $new_svc_acct->replace( $svc_acct ); +  warn "can't debit time from ". $svc_acct->username. ": $error\n"; #don't want to rollback, though +  #ssenizal eslaf + +} + +$dbh->commit or die $dbh->errstr; + +sub usage { +  die "Usage:\n\n  freeside-session-kill user\n"; +} | 
