Thursday, July 1, 2010

Quick Linux Idle Time Hack


Here's an excerpt from a post I made about a bug on the Timekpr project (https://bugs.launchpad.net/timekpr/+bug/306584).  This, or some variation on it could come in handy if you need to keep track of idle time on a Linux X session:


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 <scrnsaver.h>
#include <stdio.h>
main() {
  XScreenSaverInfo *info = XScreenSaverAll
ocInfo();
  Display *display = XOpenDisplay(NULL);
  if (display != NULL) {
    XScreenSave
rQueryInfo(display, DefaultRootWindow(display), info);
    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
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...)

No comments:

Post a Comment