3 # -*- perl -*- vim:set ft=perl sw=4 sts=4:
6 use vars qw(%state @ssh $last $pipe $arg);
7 @ssh=("ssh","-a","-x","-oBatchmode=yes","-oSetupTimeOut=20");
8 $pipe = "/tmp/.away-tpope";
11 daemonize() if ($arg eq "-d");
12 daemon() if ($arg eq "-D");
15 if($arg eq "activity" || $arg eq "away") {
16 if(exists($ARGV[0])) {
17 die "Daemon not running\n" unless (-p $pipe);
18 my $a = join(" ",@ARGV);
23 $arg =~ s/^away$/customaway/;
25 print $state{$arg}."\n" if($state{$arg});
32 open TMP, ">/tmp/.away-tpope.pid";
36 $SIG{'INT'} = \&quit_handler;
37 $SIG{'TERM'} = \&quit_handler;
38 $SIG{'QUIT'} = \&quit_handler;
39 $SIG{'HUP'} = \&cycle;
40 $SIG{'USR2'} = \&restart_handler;
41 die "Daemon already running\n" if (-r "/tmp/.tpope-away.pid");
44 system("mkfifo", $pipe);
59 elsif(defined($pid)) {
67 local $SIG{ALRM} = sub { die "alarm\n" };
69 open FIFO, "<$pipe" and
75 die unless $@ eq "alarm\n";
80 $read =~ s/^([a-z]*)( |$)//;
82 if($c eq "activity") {
83 custom_activity($read);
84 } elsif($c eq "away") {
87 print "Unknown command: $c\n";
90 if(time-$last >=300) {
91 local $SIG{'HUP'} = "IGNORE";
107 open(SOUT, ">&STDOUT");
109 my $ret=!(system('ping','-q','-c','1',shift)>>8);
110 open(STDOUT, ">&SOUT");
117 my $now=$now[2]*60+$now[1];
120 open(SCHEDULE, "today --category=school|");
122 my ($begin, $end, $maxend);
123 next unless /(\d\d):(\d\d)-(\d\d):(\d\d) (.*)/;
124 my ($hs,$ms,$he,$me,$ev) = ($1, $2, $3, $4, $5);
125 $begin = $hs*60+$ms-25;
126 $maxend = $he*60+$me+5;
127 $end = ($begin+25)*3/4+($maxend-5)/4;
128 if($begin <= $now && $now < $end) {
129 $state{'class'} = $ev;
132 } elsif (($state{'class'}||'') eq $ev) {
134 undef $state{'class'}
135 if ($now > $maxend || $state{'phone'} eq "present");
139 undef $state{'class'} unless ($familiar);
142 open(SCHEDULE, "today --category='!school !private'|");
145 my ($begin, $end, $maxend);
146 next unless /(\d\d):(\d\d)-(\d\d):(\d\d) (.*)/;
147 my ($hs,$ms,$he,$me,$ev) = ($1, $2, $3, $4, $5);
149 $maxend = $he*60+$me;
150 $end = ($begin)*3/4+($maxend)/4;
151 if($begin <= $now && $now < $end) {
152 $state{'schedule'} = $ev;
155 } elsif ($state{'schedule'} eq $ev) {
157 undef $state{'schedule'}
158 if ($now > $maxend || $state{'phone'} eq "present");
162 undef $state{'schedule'} unless ($familiar);
167 foreach my $host ("sarah", "homer", "lisa", "mona") {
168 push @livehosts, $host if(ping($host));
171 foreach my $host (@livehosts) {
172 $alive=$host unless(system(@ssh,$host, 'if pidof xscreensaver >/dev/null && DISPLAY=:0.0 xscreensaver-command -version >/dev/null 2>&1; then if DISPLAY=:0.0 xscreensaver-command -time 2>&1 |egrep "non-blanked|no saver status" >/dev/null; then true; else pid=`ps ax|egrep "[0-9]:[0-9][0-9] ssh marge .*(screen.*RR irc|Chat)"|sed -e "s/^ *//"|cut -d" " -f 1`; [ -f "$HOME/.irc.lock" -o -z "$pid" ] || kill $pid; false; fi; else false; fi') >> 8);
174 $state{'alive'} = $alive;
182 my $last_slh=`@ssh mona cat .blue/last_slh 2>/dev/null`;
185 } elsif (time-$last_slh < 600) {
191 if($state{'phone'} eq 'absent' && $phone eq 'present') {
197 if ($state{'customaway'}) {
198 $state{'away'}=$state{'customaway'};
199 } elsif ($state{'schedule'}) {
200 $state{'away'}=$state{'schedule'};
201 } elsif ($state{'phone'} ne 'present' && $state{'class'}) {
202 $state{'away'}="Class: ".$state{'class'};
203 } elsif ($state{'alive'}) {
204 undef($state{'away'});
205 } elsif ($state{'phone'} eq 'absent') {
206 $state{'away'}="Out";
207 } elsif ($state{'phone'} ne 'absent') {
210 $state{'away'}="Sleeping";
212 $state{'away'}="Away from keyboard";
219 $state{'customaway'} = $_[0];
221 undef $state{'customaway'};
227 sub custom_activity {
229 $state{'activity'} = $_[0];
231 undef $state{'activity'};
237 if (defined($state{'activity'})) {
238 $state{'status'}=$state{'activity'};
239 } elsif (defined($state{'away'})) {
240 $state{'status'}=$state{'away'};
241 } elsif ($state{'alive'} eq "mona" || $state{'alive'} eq "homer") {
242 $state{'status'}="On desktop";
243 } elsif ($state{'alive'} eq "lisa") {
244 $state{'status'}="On laptop";
245 } elsif ($state{'alive'} eq "sarah") {
246 $state{'status'}="In bed";
248 open CONF, '>' . $ENV{'HOME'} . "/.away-tpope" || die $!;
249 foreach my $k (keys %state) {
253 print CONF "$k=$val\n";
256 if(defined($state{'activity'})) {
257 open TMP, '>' . $ENV{'HOME'} . "/.activity";
258 print TMP $state{'activity'}."\n";
261 unlink($ENV{'HOME'} . "/.activity");
263 if(defined($state{'away'})) {
264 open TMP, '>' . $ENV{'HOME'} . "/.away";
265 print TMP $state{'away'}."\n";
268 unlink($ENV{'HOME'} . "/.away");
270 open TMP, '>' . $ENV{'HOME'} . "/.status";
271 print TMP $state{'status'}."\n";
276 open CONF, '<' . $ENV{'HOME'} . "/.away-tpope" or return;
277 while(my $line=<CONF>) {
279 $line =~ s/^([^=]*)=//;
286 sub restart_handler {
289 unlink "/tmp/.away-tpope.pid";
291 exec($0,$arg) || die $!;
292 print "Restarting $0 $arg...\n";
297 unlink "/tmp/.away-tpope.pid";
303 system("away-actions &");