session killer implemeting timed access
authorivan <ivan>
Mon, 23 Apr 2001 12:44:06 +0000 (12:44 +0000)
committerivan <ivan>
Mon, 23 Apr 2001 12:44:06 +0000 (12:44 +0000)
bin/freeside-session-kill [new file with mode: 0755]

diff --git a/bin/freeside-session-kill b/bin/freeside-session-kill
new file mode 100755 (executable)
index 0000000..9f11abd
--- /dev/null
@@ -0,0 +1,100 @@
+#!/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;
+