--- /dev/null
+#! /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{$_};
+ my $line="/dev/".$utmp->{"ut_line"};
+ my $atime=(stat $line)[8];
+ my $what="user \"".($utmp->{"ut_user"} || "<local>")."\", 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;
+ <F>;
+ local $_;
+ while (<F>) {
+ /^(?:\S+\s+){6}(\d+)\s/ or die;
+ $unix{$1}=1;
+ }
+ close F or die;
+
+ local $_;
+ while (</proc/*/exe>) {
+ (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;
+ }
+}