summaryrefslogtreecommitdiffstats
path: root/remote
diff options
context:
space:
mode:
Diffstat (limited to 'remote')
-rw-r--r--remote/modules/idleaction/data/etc/cron.d/openslx-idleaction6
-rwxr-xr-xremote/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script97
-rw-r--r--remote/modules/idleaction/idleaction.build16
-rw-r--r--remote/modules/idleaction/idleaction.conf4
-rw-r--r--remote/modules/idleaction/idleaction.conf.opensuse6
-rw-r--r--remote/modules/idleaction/idleaction.conf.ubuntu6
-rw-r--r--remote/modules/idleaction/xprintidle.c136
7 files changed, 271 insertions, 0 deletions
diff --git a/remote/modules/idleaction/data/etc/cron.d/openslx-idleaction b/remote/modules/idleaction/data/etc/cron.d/openslx-idleaction
new file mode 100644
index 00000000..66dbcd5c
--- /dev/null
+++ b/remote/modules/idleaction/data/etc/cron.d/openslx-idleaction
@@ -0,0 +1,6 @@
+# Trigger scripts that checks idle status of machine and triggers actions
+
+SHELL=/bin/ash
+
+*/5 * * * * root /opt/openslx/scripts/idleaction-cron_script
+
diff --git a/remote/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script b/remote/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script
new file mode 100755
index 00000000..c59d0f3b
--- /dev/null
+++ b/remote/modules/idleaction/data/opt/openslx/scripts/idleaction-cron_script
@@ -0,0 +1,97 @@
+#!/bin/ash
+
+. /opt/openslx/config || exit 1
+
+# If existent, no session is open. Will contain timestamp of last activity.
+# If not existent, at least one user is logged in
+IDLEHINT="/dev/shm/idlehint"
+NOW=$(date +%s)
+
+#
+# 1) Check for idle timeout
+#
+if [ -n "${SLX_LOGOUT_TIMEOUT}" ]; then
+ # Logout timeout is set, see which users we should kick
+ IS_IDLE=yes
+ # get all sessions
+ SESSIONS=$(loginctl | awk '{print $1}')
+ if [ -n "$SESSIONS" ]; then
+ TMP=$(/dev/shm/idlecheck.tmp)
+ # Iterate over sessions
+ for ses in $SESSIONS; do
+ # Get information
+ loginctl show-session "$ses" > "$TMP"
+ NAME=$(grep '^Name=' "$TMP" | cut -c 6-)
+ [ -z "$NAME" ] && continue # No name - should not happen
+ export DISPLAY=$(grep '^Display=' "$TMP" | cut -c 9-)
+ # X11
+ if [ -n "$DISPLAY" ]; then
+ # Seems to be x11
+ USRHOME=$(getent passwd "$NAME" | awk -F ':' '{print $6}')
+ export XAUTHORITY="$USRHOME/.Xauthority"
+ # Now that we have DISPLAY and XAUTHORITY set, xprintidle should work
+ IDLE=$(xprintidle)
+ if [ -n "$IDLE" ]; then
+ IDLE=$(( $IDLE / 1000 ))
+ if [ "$IDLE" -lt "$SLX_LOGOUT_TIMEOUT" ]; then
+ IS_IDLE=no
+ else
+ loginctl terminate-session "$ses"
+ fi
+ fi
+ continue # Done with this session, skip normal tty/ssh checks
+ fi
+ # end X11
+ # other sessions
+ IDLE=$(grep '^IdleSinceHint=' "$TMP" | cut -c 15-)
+ if [ "${#IDLE}" -lt 7 ]; then # wah wah waaaah
+ IS_IDLE=no
+ continue
+ fi
+ # divide by 1000000 by chopping of last 6 chars - number might be too large for $(( ))
+ IDLE=$(echo "$IDLE" | cut -c "-$(( ${#IDLE} - 6 ))")
+ [ "$IDLE" -gt "$NOW" ] && IDLE="$NOW"
+ IDLE=$(( $NOW - $IDLE ))
+ if [ "$IDLE" -lt "$SLX_LOGOUT_TIMEOUT" ]; then
+ IS_IDLE=no
+ else
+ loginctl terminate-session "$ses"
+ fi
+ # end other sessions
+ done
+ rm -f -- "$TMP"
+ if [ "$IS_IDLE" = "yes" ]; then
+ [ ! -e "$IDLEHINT" ] && echo "$NOW" > "$IDLEHINT"
+ else
+ rm -f -- "$IDLEHINT"
+ fi
+ fi
+else
+ # No logout timeout is set, take shortcut for shutdown timeout (if set)
+ if [ -n "$SLX_SHUTDOWN_TIMEOUT" ]; then
+ SESSIONS=$(loginctl | wc -l)
+ if [ "$SESSIONS" = "0" ]; then
+ [ ! -e "$IDLEHINT" ] && echo "$NOW" > "$IDLEHINT"
+ else
+ rm -f -- "$IDLEHINT"
+ fi
+ fi
+fi
+
+#
+# 2) Check for no-session-shutdown timeout
+#
+if [ -n "$SLX_SHUTDOWN_TIMEOUT" ] && [ -e "$IDLEHINT" ]; then
+ IDLE=$(cat "$IDLEHINT")
+ [ "$IDLE" -gt "$NOW" ] && IDLE="$NOW"
+ IDLE=$(( $NOW - $IDLE ))
+ if [ "$IDLE" -gt "$SLX_SHUTDOWN_TIMEOUT" ]; then
+ poweroff -nf # TODO: Do proper shutdown once it works reliably
+ fi
+fi
+
+#
+# 3) Check for hard scheduled shutdown
+#
+# TODO
+
diff --git a/remote/modules/idleaction/idleaction.build b/remote/modules/idleaction/idleaction.build
new file mode 100644
index 00000000..1b740aa1
--- /dev/null
+++ b/remote/modules/idleaction/idleaction.build
@@ -0,0 +1,16 @@
+fetch_source() {
+ :
+}
+
+build() {
+ # We ship xprintidle's source as suse doesn't have it in one of the default repos
+ # and its just too tiny to do anything fancy like fetching source from somewhere
+ mkdir -p "$MODULE_BUILD_DIR/opt/openslx/bin"
+ gcc -o "$MODULE_BUILD_DIR/opt/openslx/bin/xprintidle" "$MODULE_DIR/xprintidle.c" -lX11 -lXss -lXext \
+ || perror "Compilation of xprintidle failed!"
+}
+
+post_copy() {
+ :
+}
+
diff --git a/remote/modules/idleaction/idleaction.conf b/remote/modules/idleaction/idleaction.conf
new file mode 100644
index 00000000..1661735b
--- /dev/null
+++ b/remote/modules/idleaction/idleaction.conf
@@ -0,0 +1,4 @@
+REQUIRED_BINARIES="
+ xprintidle
+"
+
diff --git a/remote/modules/idleaction/idleaction.conf.opensuse b/remote/modules/idleaction/idleaction.conf.opensuse
new file mode 100644
index 00000000..3aff5af0
--- /dev/null
+++ b/remote/modules/idleaction/idleaction.conf.opensuse
@@ -0,0 +1,6 @@
+REQUIRED_INSTALLED_PACKAGES="
+ libX11-devel
+ libXss-devel
+ xorg-x11-proto-devel
+"
+
diff --git a/remote/modules/idleaction/idleaction.conf.ubuntu b/remote/modules/idleaction/idleaction.conf.ubuntu
new file mode 100644
index 00000000..0dad2e48
--- /dev/null
+++ b/remote/modules/idleaction/idleaction.conf.ubuntu
@@ -0,0 +1,6 @@
+REQUIRED_INSTALLED_PACKAGES="
+ libx11-dev
+ libxss-dev
+ x11proto-scrnsaver-dev
+"
+
diff --git a/remote/modules/idleaction/xprintidle.c b/remote/modules/idleaction/xprintidle.c
new file mode 100644
index 00000000..7fc62486
--- /dev/null
+++ b/remote/modules/idleaction/xprintidle.c
@@ -0,0 +1,136 @@
+/*
+
+This program prints the "idle time" of the user to stdout. The "idle
+time" is the number of milliseconds since input was received on any
+input device. If unsuccessful, the program prints a message to stderr
+and exits with a non-zero exit code.
+
+Copyright (c) 2005, 2008 Magnus Henoch <henoch@dtek.chalmers.se>
+Copyright (c) 2006, 2007 by Danny Kukawka
+ <dkukawka@suse.de>, <danny.kukawka@web.de>
+Copyright (c) 2008 Eivind Magnus Hvidevold <hvidevold@gmail.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of version 2 of the GNU General Public License
+as published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the
+Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+The function workaroundCreepyXServer was adapted from kpowersave-0.7.3 by
+Eivind Magnus Hvidevold <hvidevold@gmail.com>. kpowersave is licensed under
+the GNU GPL, version 2 _only_.
+
+*/
+
+#include <X11/Xlib.h>
+#include <X11/extensions/dpms.h>
+#include <X11/extensions/scrnsaver.h>
+#include <stdio.h>
+
+void usage(char *name);
+unsigned long workaroundCreepyXServer(Display *dpy, unsigned long _idleTime );
+
+int main(int argc, char *argv[])
+{
+ XScreenSaverInfo ssi;
+ Display *dpy;
+ int event_basep, error_basep;
+
+ if (argc != 1) {
+ usage(argv[0]);
+ return 1;
+ }
+
+ dpy = XOpenDisplay(NULL);
+ if (dpy == NULL) {
+ fprintf(stderr, "couldn't open display\n");
+ return 1;
+ }
+
+ if (!XScreenSaverQueryExtension(dpy, &event_basep, &error_basep)) {
+ fprintf(stderr, "screen saver extension not supported\n");
+ return 1;
+ }
+
+ if (!XScreenSaverQueryInfo(dpy, DefaultRootWindow(dpy), &ssi)) {
+ fprintf(stderr, "couldn't query screen saver info\n");
+ return 1;
+ }
+
+ printf("%lu\n", workaroundCreepyXServer(dpy, ssi.idle));
+
+ XCloseDisplay(dpy);
+ return 0;
+}
+
+void usage(char *name)
+{
+ fprintf(stderr,
+ "Usage:\n"
+ "%s\n"
+ "That is, no command line arguments. The user's idle time\n"
+ "in milliseconds is printed on stdout.\n",
+ name);
+}
+
+/*!
+ * This function works around an XServer idleTime bug in the
+ * XScreenSaverExtension if dpms is running. In this case the current
+ * dpms-state time is always subtracted from the current idletime.
+ * This means: XScreenSaverInfo->idle is not the time since the last
+ * user activity, as descriped in the header file of the extension.
+ * This result in SUSE bug # and sf.net bug #. The bug in the XServer itself
+ * is reported at https://bugs.freedesktop.org/buglist.cgi?quicksearch=6439.
+ *
+ * Workaround: Check if if XServer is in a dpms state, check the
+ * current timeout for this state and add this value to
+ * the current idle time and return.
+ *
+ * \param _idleTime a unsigned long value with the current idletime from
+ * XScreenSaverInfo->idle
+ * \return a unsigned long with the corrected idletime
+ */
+unsigned long workaroundCreepyXServer(Display *dpy, unsigned long _idleTime ){
+ int dummy;
+ CARD16 standby, suspend, off;
+ CARD16 state;
+ BOOL onoff;
+
+ if (DPMSQueryExtension(dpy, &dummy, &dummy)) {
+ if (DPMSCapable(dpy)) {
+ DPMSGetTimeouts(dpy, &standby, &suspend, &off);
+ DPMSInfo(dpy, &state, &onoff);
+
+ if (onoff) {
+ switch (state) {
+ case DPMSModeStandby:
+ /* this check is a littlebit paranoid, but be sure */
+ if (_idleTime < (unsigned) (standby * 1000))
+ _idleTime += (standby * 1000);
+ break;
+ case DPMSModeSuspend:
+ if (_idleTime < (unsigned) ((suspend + standby) * 1000))
+ _idleTime += ((suspend + standby) * 1000);
+ break;
+ case DPMSModeOff:
+ if (_idleTime < (unsigned) ((off + suspend + standby) * 1000))
+ _idleTime += ((off + suspend + standby) * 1000);
+ break;
+ case DPMSModeOn:
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return _idleTime;
+}