#! /usr/bin/perl # # $Id$ use strict; use warnings; my $idle_want=$ARGV[0] || 30; die if @ARGV>1 || $idle_want!~/^\d+$/; $idle_want*=60; use User::Utmp; # Users respected for the 'idle' state (see $IdleMax): my @ValidUsers=qw(root lace jkratoch); sub useridle() { my %valid_users=map(($_=>1),@ValidUsers); my($idlebest,$linebest); for my $utmp (User::Utmp::getut()) { local $_; next if defined($_=$utmp->{"ut_type"}) && $_!=&User::Utmp::USER_PROCESS(); next if defined($_=$utmp->{"ut_user"}) && !$valid_users{$_}; next if $utmp->{"ut_line"}=~m{^:\d+}; # X login my $line="/dev/".$utmp->{"ut_line"}; my $atime=(stat $line)[8]; my $what="user \"".($utmp->{"ut_user"} || "")."\", line \"$line\""; warn "Unable to stat $what" and next if !$atime; my $idle=time()-$atime; warn "atime in future for $what" and next if $idle<0; next if defined $idlebest && $idlebest<=$idle; $idlebest=$idle; $linebest=$line; } return !wantarray() ? $idlebest : ($idlebest,$linebest); } sub mplayer_running() { local *F; open F,"/proc/net/unix" or die; my %unix; ; local $_; while () { /^(?:\S+\s+){6}(\d+)\s/ or die; $unix{$1}=1; } close F or die; local $_; while () { (my $fdname=$_)=~s{/exe$}{/fd}; $_=readlink or next; m{/mplayer$} or next; while (<$fdname/*>) { $_=readlink or next; my $inode=/^\Qsocket:[\E(\d+)\Q]\E$/ or next; return 1 if $unix{$1}; } } return; } $|=1; for (;;) { my $idle_is=useridle(); if ($idle_is>=$idle_want) { if (!mplayer_running()) { print "\n"; exit 0; } print "M"; sleep 10; } else { print "."; sleep $idle_want-$idle_is; } }