diff options
Diffstat (limited to 'x11vnc/misc/blockdpy.c')
-rw-r--r-- | x11vnc/misc/blockdpy.c | 352 |
1 files changed, 0 insertions, 352 deletions
diff --git a/x11vnc/misc/blockdpy.c b/x11vnc/misc/blockdpy.c deleted file mode 100644 index f3b428e..0000000 --- a/x11vnc/misc/blockdpy.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * blockdpy.c - * - * Copyright (c) 2004 Karl J. Runge <runge@karlrunge.com> - * All rights reserved. - * - * This is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - * - *----------------------------------------------------------------------- - * - * This tool is intended for use with x11vnc. It is a kludge to try to - * "block" access via the physical display while x11vnc is running. - * - * The expected application is that of a user who screen-locks his - * workstation before leaving and then later unlocks it remotely via - * x11vnc. The user is concerned people with physical access to the - * machine will be watching, etc. - * - * Of course if people have physical access to the machine there are - * much larger potential security problems, but the idea here is to put - * up a larger barrier than simply turning on the monitor and tapping - * the mouse (i.e. to wake up the monitor from DPMS and then observe - * the x11vnc activity). - * - * This program requires DPMS support in the video card and monitor, - * and the DPMS extension in the X server and the corresponding - * library with the DPMS API (libXext). - * - * It starts off by forcing the state to be DPMSModeOff (lowest power). - * Then it periodically (a few times a second) checks if the system is - * still in that state. If it discovers it to be in another state, it - * immediately runs, as a separate command, a screen-lock program, "xlock" - * by default. The environment variable XLOCK_CMD or -lock option can - * override this default. "xscreensaver-command" might be another choice. - * - * It is up to the user to make sure the screen-lock command works - * and PATH is set up correctly, etc. The command can do anything, - * it doesn't have to lock the screen. It could make the sound of a - * dog barking, for example :-) - * - * The option '-grab' causes the program to additionally call - * XGrabServer() to try to prevent physical mouse or keyboard input to get - * to any applications on the screen. NOTE: do NOT use, not working yet! - * Freezes everything. - * - * The options: -display and -auth can be used to set the DISPLAY and - * XAUTHORITY environment variables via the command line. - * - * The options -standby and -suspend change the desired DPMS level - * to be DPMSModeStandby and DPMSModeSuspend, respectively. - * - * The option '-f flagfile' indicates a flag file to watch for to cause - * the program to clean up and exit once it exists. No screen locking is - * done when the file appears: it is an 'all clear' flag. Presumably the - * x11vnc user has relocked the screen before the flagfile is created. - * See below for coupling this behavior with the -gone command. - * - * The option '-bg' causes the program to fork into the background and - * return 0 if everything looks ok. If there was an error up to that - * point the return value would be 1. - * - * Option '-v' prints more info out, useful for testing and debugging. - * - * - * These options allow this sort of x11vnc usage: - * - * x11vnc ... -accept "blockdpy -bg -f $HOME/.bdpy" -gone "touch $HOME/.bdpy" - * - * (this may also work for gone: -gone "killall blockdpy") - * - * In the above, once a client connects this program starts up in the - * background and monitors the DPMS level. When the client disconnects - * (he relocked the screen before doing so) the flag file is created and - * so this program exits normally. On the other hand, if the physical - * mouse or keyboard was used during the session, this program would - * have locked the screen as soon as it noticed the DPMS change. - * - * One could create shell scripts for -accept and -gone that do much - * more sophisticated things. This would be needed if more than one - * client connects at a time. - * - * It is important to remember once this program locks the screen - * it *exits*, so nothing will be watching the screen at that point. - * Don't immediately unlock the screen from in x11vnc!! Best to think - * about what might have happened, disconnect the VNC viewer, and then - * restart x11vnc (thereby having this monitoring program started again). - * - * - * To compile on Linux or Solaris: - - cc -o blockdpy blockdpy.c -L /usr/X11R6/lib -L /usr/openwin/lib -lX11 -lXext - - * (may also need -I /usr/.../include on older machines). - * - */ - -#include <stdio.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <signal.h> - -#include <X11/Xlib.h> -#include <X11/Xproto.h> -#include <X11/extensions/dpms.h> - -Display *dpy = NULL; -CARD16 standby, suspend, off; -int grab = 0; -int verbose = 0; -int bg = 0; - -/* for sleeping some number of millisecs */ -struct timeval _mysleep; -#define msleep(x) \ - _mysleep.tv_sec = ((x)*1000) / 1000000; \ - _mysleep.tv_usec = ((x)*1000) % 1000000; \ - select(0, NULL, NULL, NULL, &_mysleep); - -/* called on signal or if DPMS changed, or other problem */ -void reset(int sig) { - if (grab) { - if (verbose) { - fprintf(stderr, "calling XUngrabServer()\n"); - } - XUngrabServer(dpy); - } - if (verbose) { - fprintf(stderr, "resetting original DPMS values.\n"); - } - fprintf(stderr, "blockdpy: reset sig=%d called\n", sig); - DPMSEnable(dpy); - DPMSSetTimeouts(dpy, standby, suspend, off); - XFlush(dpy); - if (sig) { - XCloseDisplay(dpy); - exit(0); - } -} - -int main(int argc, char** argv) { - - int verbose = 0, bg = 0; - int i, ev, er; - char *lock_cmd = "xlock"; - char *flag_file = NULL; - char estr[100], cmd[500]; - struct stat sbuf; - CARD16 power; - CARD16 desired = DPMSModeOff; - BOOL state; - - - /* setup the lock command. it may be reset by -lock below. */ - if (getenv("XLOCK_CMD")) { - lock_cmd = (char *) getenv("XLOCK_CMD"); - } - - /* process cmd line: */ - for (i=1; i<argc; i++) { - if (!strcmp(argv[i], "-display")) { - sprintf(estr, "DISPLAY=%s", argv[++i]); - putenv(strdup(estr)); - } else if (!strcmp(argv[i], "-auth")) { - sprintf(estr, "XAUTHORITY=%s", argv[++i]); - putenv(strdup(estr)); - } else if (!strcmp(argv[i], "-lock")) { - lock_cmd = argv[++i]; - } else if (!strcmp(argv[i], "-f")) { - flag_file = argv[++i]; - unlink(flag_file); - } else if (!strcmp(argv[i], "-grab")) { - grab = 1; - } else if (!strcmp(argv[i], "-bg")) { - bg = 1; - } else if (!strcmp(argv[i], "-v")) { - verbose = 1; - } else if (!strcmp(argv[i], "-standby")) { - desired = DPMSModeStandby; - } else if (!strcmp(argv[i], "-suspend")) { - desired = DPMSModeSuspend; - } else if (!strcmp(argv[i], "-off")) { - desired = DPMSModeOff; - } - } - - /* we want it to go into background to avoid blocking, so add '&'. */ - strcpy(cmd, lock_cmd); - strcat(cmd, " &"); - lock_cmd = cmd; - - /* close any file descriptors we may have inherited (e.g. port 5900) */ - for (i=3; i<=100; i++) { - close(i); - } - - /* open DISPLAY */ - dpy = XOpenDisplay(NULL); - if (! dpy) { - fprintf(stderr, "XOpenDisplay failed.\n"); - exit(1); - } - - /* check for DPMS extension */ - if (! DPMSQueryExtension(dpy, &ev, &er)) { - fprintf(stderr, "DPMSQueryExtension failed.\n"); - exit(1); - } - if (! DPMSCapable(dpy)) { - fprintf(stderr, "DPMSCapable failed.\n"); - exit(1); - } - /* make sure DPMS is enabled */ - if (! DPMSEnable(dpy)) { - fprintf(stderr, "DPMSEnable failed.\n"); - exit(1); - } - - /* retrieve the timeouts for later resetting */ - if (! DPMSGetTimeouts(dpy, &standby, &suspend, &off)) { - fprintf(stderr, "DPMSGetTimeouts failed.\n"); - exit(1); - } - if (! standby || ! suspend || ! off) { - /* if none, set to some reasonable values */ - standby = 900; - suspend = 1200; - off = 1800; - } - if (verbose) { - fprintf(stderr, "DPMS timeouts: %d %d %d\n", standby, - suspend, off); - } - - /* now set them to very small values */ - if (desired == DPMSModeOff) { - if (! DPMSSetTimeouts(dpy, 1, 1, 1)) { - fprintf(stderr, "DPMSSetTimeouts failed.\n"); - exit(1); - } - } else if (desired == DPMSModeSuspend) { - if (! DPMSSetTimeouts(dpy, 1, 1, 0)) { - fprintf(stderr, "DPMSSetTimeouts failed.\n"); - exit(1); - } - } else if (desired == DPMSModeStandby) { - if (! DPMSSetTimeouts(dpy, 1, 0, 0)) { - fprintf(stderr, "DPMSSetTimeouts failed.\n"); - exit(1); - } - } - XFlush(dpy); - - /* set handlers for clean up in case we terminate via signal */ - signal(SIGHUP, reset); - signal(SIGINT, reset); - signal(SIGQUIT, reset); - signal(SIGABRT, reset); - signal(SIGTERM, reset); - - /* force state into DPMS Off (lowest power) mode */ - if (! DPMSForceLevel(dpy, desired)) { - fprintf(stderr, "DPMSForceLevel failed.\n"); - exit(1); - } - XFlush(dpy); - - /* read state */ - msleep(500); - if (! DPMSInfo(dpy, &power, &state)) { - fprintf(stderr, "DPMSInfo failed.\n"); - exit(1); - } - fprintf(stderr, "power: %d state: %d\n", power, state); - - /* grab display if desired. NOT WORKING */ - if (grab) { - if (verbose) { - fprintf(stderr, "calling XGrabServer()\n"); - } - XGrabServer(dpy); - } - - /* go into background if desired. */ - if (bg) { - pid_t p; - if ((p = fork()) != 0) { - if (p < 0) { - fprintf(stderr, "problem forking.\n"); - exit(1); - } else { - /* XXX no fd closing */ - exit(0); - } - } - } - - /* main loop: */ - while (1) { - /* reassert DPMSModeOff (desired) */ - if (verbose) fprintf(stderr, "reasserting desired DPMSMode\n"); - DPMSForceLevel(dpy, desired); - XFlush(dpy); - - /* wait a bit */ - msleep(200); - - /* check for flag file appearence */ - if (flag_file && stat(flag_file, &sbuf) == 0) { - if (verbose) { - fprintf(stderr, "flag found: %s\n", flag_file); - } - unlink(flag_file); - reset(0); - exit(0); - } - - /* check state and power level */ - if (! DPMSInfo(dpy, &power, &state)) { - fprintf(stderr, "DPMSInfo failed.\n"); - reset(0); - exit(1); - } - if (verbose) { - fprintf(stderr, "power: %d state: %d\n", power, state); - } - if (!state || power != desired) { - /* Someone (or maybe a cat) is evidently watching... */ - fprintf(stderr, "DPMS CHANGE: power: %d state: %d\n", - power, state); - break; - } - } - reset(0); - fprintf(stderr, "locking screen with command: \"%s\"\n", lock_cmd); - system(lock_cmd); - exit(0); -} |