rpmsafereduce: +$IGNORE_D,die->carp
[nethome.git] / bin / idle
1 #! /usr/bin/perl
2 #
3 # $Id$
4
5 use strict;
6 use warnings;
7
8 my $idle_want=$ARGV[0] || 30;
9 die if @ARGV>1 || $idle_want!~/^\d+$/;
10 $idle_want*=60;
11
12 use User::Utmp;
13
14 # Users respected for the 'idle' state (see $IdleMax):
15 my @ValidUsers=qw(root lace jkratoch);
16
17 sub useridle()
18 {
19         my %valid_users=map(($_=>1),@ValidUsers);
20         my($idlebest,$linebest);
21         for my $utmp (User::Utmp::getut()) {
22                 local $_;
23                 next if defined($_=$utmp->{"ut_type"}) && $_!=&User::Utmp::USER_PROCESS();
24                 next if defined($_=$utmp->{"ut_user"}) && !$valid_users{$_};
25                 next if $utmp->{"ut_line"}=~m{^:\d+};   # X login
26                 my $line="/dev/".$utmp->{"ut_line"};
27                 my $atime=(stat $line)[8];
28                 my $what="user \"".($utmp->{"ut_user"} || "<local>")."\", line \"$line\"";
29                 warn "Unable to stat $what" and next if !$atime;
30                 my $idle=time()-$atime;
31                 warn "atime in future for $what" and next if $idle<0;
32                 next if defined $idlebest && $idlebest<=$idle;
33                 $idlebest=$idle;
34                 $linebest=$line;
35                 }
36         return !wantarray() ? $idlebest : ($idlebest,$linebest);
37 }
38
39 sub mplayer_running()
40 {
41         local *F;
42         open F,"/proc/net/unix" or die;
43         my %unix;
44         <F>;
45         local $_;
46         while (<F>) {
47                 /^(?:\S+\s+){6}(\d+)\s/ or die;
48                 $unix{$1}=1;
49                 }
50         close F or die;
51
52         local $_;
53         while (</proc/*/exe>) {
54                 (my $fdname=$_)=~s{/exe$}{/fd};
55                 $_=readlink or next;
56                 m{/mplayer$} or next;
57                 while (<$fdname/*>) {
58                         $_=readlink or next;
59                         my $inode=/^\Qsocket:[\E(\d+)\Q]\E$/ or next;
60                         return 1 if $unix{$1};
61                         }
62                 }
63         return;
64 }
65
66 $|=1;
67 for (;;) {
68         my $idle_is=useridle();
69         if ($idle_is>=$idle_want) {
70                 if (!mplayer_running()) {
71                         print "\n";
72                         exit 0;
73                 }
74                 print "M";
75                 sleep 10;
76         } else {
77                 print ".";
78                 sleep $idle_want-$idle_is;
79         }
80 }