4

I'm looking for a way to determine the local input (mouse/keyboard) idle time, remotely through SSH, without having root access or access to the currently logged on user Xauthority.

I know the following solution which works if you have access to the X server: detecting keyboard, mouse activity in linux

But is it possible without having to connect to the X server? Is there another way? E.g. indirectly via CPU or memory usage of certain processes? Any ideas welcome.

Community
  • 1
  • 1
Philipp F
  • 874
  • 9
  • 29

3 Answers3

7

Using w and /dev solutions will only get you so far, since it could be that the user is around, but has not typed anything in the shell - for example, he/she could be playing some game. A better approach would be to poll /proc/interrupts. The local interrupts for the mouse and keyboard are often under "i8042" (though in some rare cases it might be different). You might want to try: "grep i8042 /proc/interrupts". This will yield IRQ 1 (keyboard) and IRQ 12 (usually, the mouse). You can get the values, store them, and then poll occasionally (no callback, alas), to get the counts. If the numbers changed, interrupts occurred - meaning keyboard (IRQ 1) or mouse (IRQ 12) were touched/pressed etc. Key presses generally generate two interrupts (key down, key up). Mouse movement is more erratic.

This has several advantages:

1) If the user so much as touches the mouse, or presses a key - you know 2) You can do so programmatically (i.e. fopen() /proc/interrupts , or (alternatively) /proc/stat, and get the "intr" line) and fread() the relevant lines 3) You don't even need to be root for this.

Technologeeks
  • 7,674
  • 25
  • 36
  • This is cool. Although it seems that it does not work with USB keyboard/mouse right? – Philipp F Nov 12 '13 at 10:12
  • I just checked, there are also usb interrupts. However they occur on a regular basis. So I can subtract this rate to see if there are additional events. This should work. – Philipp F Nov 12 '13 at 10:28
  • Won't work with USB, correct, but USB is still an interrupt source. So yes. The correlation may not be 1:1 like it is with i8042, but - all the same - you will get a non-zero value when user is active - which is what you wanted in the first place. – Technologeeks Nov 12 '13 at 13:38
1

As an unprivileged, distinct user, I'd try to do this by monitoring for new processes spawned with the target user ID. If you see a new process, chances are it means the user caused it to be spawned, unless its parent is cron (or one of a handful of similar supervisors, you'll have to try it on your system and filter out the few false alarms you get at first).

This won't give you a very precise idle time, but perhaps a maximum bound. If you want something more precise, you probably ought to have privileges to do it.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
1

The commands w and ls -l /dev/pts are the best ones I can think of. Between them, you can get a pretty good view of idleness on the linux console, ssh, and xterm sessions.

If the user is just sitting on a local thing playing with firefox or something, this won't catch it, but I'm not sure you can get that without access to X or being root. Looking for cpu usage isn't reliable because a lot of apps use a little cpu even when idle, or virtually zero when used, and watching /proc/x_server_pid/* doesn't help either, since X can still have activity even when the user is idle.

Looking for new processes like the other answer said is the best I can think of if /dev/pts doesn't help and you can't actually look at the input.

Adam D. Ruppe
  • 25,382
  • 4
  • 41
  • 60