First, thanks to the timekpr team - this is extremely useful. Here is my solution to the 'screen locked/user switched time keeps counting' problem - I hope this will help out someone else. I found the code for an executable named idle at http://coderrr.wordpress.com/2008/04/20/getting-idle-time-in-unix/ - I modified it somewhat to just return the number of seconds of idle time for that display. Here's the C code:
I compiled that with the command "gcc -o idle idle.c -lXss" and put the resulting binary in /usr/local/sbin/idle. You call that by first exporting the display that you want to query idle time for as $DISPLAY, then you run idle. For example, say that you have users logged in to displays :5 and :6, then you can run the following commands (as root):
export DISPLAY=:5.0;/usr/local/sbin/idle
and
export DISPLAY=:6.0;/usr/local/sbin/idle
to find the number of seconds that those users have been idle (no keyboard/mouse activity.) For timekpr, what we really need to find are the users that are active (the normal users command returns all users that are logged in, active or not.) For this, I wrote a shell script and put that in /usr/local/sbin/active_users.sh - here's the code for that:
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
for i in `w | grep tty | awk '{print $2 $3 ":" $1}' | sed 's/^tty[0-9]*\://g'`; do
display=`echo $i | awk -F ':' '{print $1}'`
display=:${display}.0
user=`echo $i | awk -F ':' '{print $2}'`
idletime=`export DISPLAY=$display;/usr/local/sbin/idle`
case "$1" in
debug)
echo "$user is on display $display with idletime $idletime"
;;
*)
if [ $idletime -lt 10 ]; then
echo -n "$user "
fi
;;
esac
done
echo
As root, when you run /usr/local/sbin/active_users.sh, you will get only a listing of users that are currently active (in a gnome session only - this doesn't help you are trying to limit time for ssh users...)
Almost done!!!
Now, we have to edit /usr/share/python-support/timekpr/timekpr.py to use /usr/local/sbin/active_users.sh instead of the built in users command. Simply change the line that reads:
u = getcmdoutput('users')
to
u = getcmdoutput('/usr/local/sbin/active_users.sh')
(it's in the getusers function.) Now, just restart the timekpr daemon (/etc/init.d/timekpr restart) and it is ready to go.
I admit, this is a huge hack, but it works for my use case and hopefully can be easily adapted to work for you. There are some problems with this approach - for example, if a time limited user is watching a movie via an app that won't lock the screen, then that user will get extra time. In my case, though, it's all interactive activity so I don't have that problem.
I hope this is useful, and hope even more so that someone improves upon it. Thanks!
First, thanks to the timekpr team - this is extremely useful. Here is my solution to the 'screen locked/user switched time keeps counting' problem - I hope this will help out someone else. I found the code for an executable named idle at http:// coderrr. wordpress. com/2008/ 04/20/getting- idle-time- in-unix/ - I modified it somewhat to just return the number of seconds of idle time for that display. Here's the C code:
#include <X11/extensions /scrnsaver. h>
#include <stdio.h>
main() { ocInfo( );
XScreenSaverInfo *info = XScreenSaverAll
Display *display = XOpenDisplay(NULL);
if (display != NULL) { rQueryInfo( display, DefaultRootWind ow(display) , info);
XScreenSave
printf("%lu", info->idle/1000);
} else {
puts ("error");
}
}
I compiled that with the command "gcc -o idle idle.c -lXss" and put the resulting binary in /usr/local/ sbin/idle. You call that by first exporting the display that you want to query idle time for as $DISPLAY, then you run idle. For example, say that you have users logged in to displays :5 and :6, then you can run the following commands (as root):
export DISPLAY= :5.0;/usr/ local/sbin/ idle :6.0;/usr/ local/sbin/ idle
and
export DISPLAY=
to find the number of seconds that those users have been idle (no keyboard/mouse activity.) For timekpr, what we really need to find are the users that are active (the normal users command returns all users that are logged in, active or not.) For this, I wrote a shell script and put that in /usr/local/ sbin/active_ users.sh - here's the code for that:
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
for i in `w | grep tty | awk '{print $2 $3 ":" $1}' | sed 's/^tty[ 0-9]*\: //g'`; do :${display} .0 `export DISPLAY= $display; /usr/local/ sbin/idle`
display=`echo $i | awk -F ':' '{print $1}'`
display=
user=`echo $i | awk -F ':' '{print $2}'`
idletime=
case "$1" in
debug)
echo "$user is on display $display with idletime $idletime"
;;
*)
if [ $idletime -lt 10 ]; then
echo -n "$user "
fi
;;
esac
done
echo
As root, when you run /usr/local/ sbin/active_ users.sh, you will get only a listing of users that are currently active (in a gnome session only - this doesn't help you are trying to limit time for ssh users...)
Almost done!!!
Now, we have to edit /usr/share/ python- support/ timekpr/ timekpr. py to use /usr/local/ sbin/active_ users.sh instead of the built in users command. Simply change the line that reads:
u = getcmdoutput( 'users' ) '/usr/local/ sbin/active_ users.sh' )
to
u = getcmdoutput(
(it's in the getusers function.) Now, just restart the timekpr daemon (/etc/init. d/timekpr restart) and it is ready to go.
I admit, this is a huge hack, but it works for my use case and hopefully can be easily adapted to work for you. There are some problems with this approach - for example, if a time limited user is watching a movie via an app that won't lock the screen, then that user will get extra time. In my case, though, it's all interactive activity so I don't have that problem.
I hope this is useful, and hope even more so that someone improves upon it. Thanks!