summaryrefslogtreecommitdiffstats
path: root/x11vnc/misc
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/misc')
-rw-r--r--x11vnc/misc/Makefile.am1
-rw-r--r--x11vnc/misc/README32
-rw-r--r--x11vnc/misc/blockdpy.c352
-rw-r--r--x11vnc/misc/dtVncPopup109
-rwxr-xr-xx11vnc/misc/rx11vnc133
-rwxr-xr-xx11vnc/misc/rx11vnc.pl199
-rwxr-xr-xx11vnc/misc/shm_clear97
-rwxr-xr-xx11vnc/misc/slide.pl112
-rwxr-xr-xx11vnc/misc/vcinject.pl113
-rwxr-xr-xx11vnc/misc/x11vnc_loop89
10 files changed, 1237 insertions, 0 deletions
diff --git a/x11vnc/misc/Makefile.am b/x11vnc/misc/Makefile.am
new file mode 100644
index 0000000..5cd4d0a
--- /dev/null
+++ b/x11vnc/misc/Makefile.am
@@ -0,0 +1 @@
+EXTRA_DIST=README blockdpy.c dtVncPopup rx11vnc rx11vnc.pl shm_clear slide.pl vcinject.pl x11vnc_loop
diff --git a/x11vnc/misc/README b/x11vnc/misc/README
new file mode 100644
index 0000000..be7063f
--- /dev/null
+++ b/x11vnc/misc/README
@@ -0,0 +1,32 @@
+
+In this directory you'll find a hodgepodge of wrapper scripts and
+utility programs that have found some use with x11vnc.
+
+Some are on the rough side and will need some customization for your
+use. Many of them are described on the webpage:
+
+ http://www.karlrunge.com/x11vnc
+
+(use your browser's Find action to find them!). Some of them also have
+documentation near the top of the file.
+
+x11vnc -accept scripts:
+
+ blockdpy.c try to lock screen if local person knocks monitor out of DPMS
+ dtVncPopup CDE/dtksh by Stefan Radman to accept connections, lock screen
+
+x11vnc launch wrappers:
+
+ rx11vnc simple ssh/rsh x11vnc launcher. -S option needs work...
+ rx11vnc.pl perl script tries to do rx11vnc -S tunnelling better.
+
+x11vnc -pipeinput/-rawfb utilities:
+
+ vcinject.pl perl script like LinuxVNC.c, for x11vnc viewing of linux console
+ slide.pl amusing example using x11vnc -rawfb for jpeg slideshow.
+
+Misc. scripts:
+
+ shm_clear list or remove orphaned shm slots from hard x11vnc crashes.
+ x11vnc_loop kludge to run in bg attaching x11vnc to X login. Better to
+ use Xsetup mechanism.
diff --git a/x11vnc/misc/blockdpy.c b/x11vnc/misc/blockdpy.c
new file mode 100644
index 0000000..f3b428e
--- /dev/null
+++ b/x11vnc/misc/blockdpy.c
@@ -0,0 +1,352 @@
+/*
+ * 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);
+}
diff --git a/x11vnc/misc/dtVncPopup b/x11vnc/misc/dtVncPopup
new file mode 100644
index 0000000..e90cc8b
--- /dev/null
+++ b/x11vnc/misc/dtVncPopup
@@ -0,0 +1,109 @@
+#!/usr/dt/bin/dtksh
+#
+# accept dialog script for x11vnc
+# 2004-07-13 stefan.radman@ctbto.org
+# should work in any CDE environment (Sun,HP,IBM,...)
+#
+# when called without parameters shows a CDE question dialog:
+# Do you want to accept a VNC connection
+# from IP address $RFB_CLIENT_IP to your desktop?
+# Note:
+# After 30 seconds the screen will
+# be locked and the connection will be
+# accepted automatically."
+# [Yes} {__No__] [View/Only]
+# and counts down a timer in the dialog title bar
+# when the timer is down to 0, it locks the display and returns 0
+# (if the screenlock was successful or if the login prompt was active)
+#
+# buttons=retcode:
+# Yes = 0
+# No = 1 (same as closing the dialog windows)
+# View/Only = 3
+#
+# usage: x11vnc -forever -shared -accept "yes:0,no:*,view:3 dtVncPopup" -gone "dtVncPopup lock"
+#
+# security considerations: when you return to your console and unlock the display
+# you can never know if enyone else is connected to your display
+#
+
+# timeout until accept
+timeout=30
+
+# dialog message
+test -z "${RFB_CLIENT_IP}" && unknown="an unknown " || ip="$RFB_CLIENT_IP "
+message="\
+Do you want to accept a VNC connection
+from ${unknown}IP address ${ip}to your desktop?
+Note:
+After $timeout seconds the screen will
+be locked and the connection will be
+accepted automatically."
+
+# action functions
+accept () {
+ exit 0
+}
+reject () {
+ exit 1
+}
+view () {
+ exit 3
+}
+lock () {
+ # lock only if dtsession active
+ xrdb -query | grep -c '^dtsession*' || accept
+ # accept only if lock succeeds
+ /usr/dt/bin/dtaction LockDisplay && accept || reject
+}
+
+# main
+
+# actions can be called directly
+test $# -gt 0 && $@
+
+# initialize the display
+XtInitialize TOPLEVEL vncPopup VncPopup "$0" "$@"
+
+# create a message dialog containing the contents of the specified file
+XmCreateQuestionDialog DIALOG $TOPLEVEL dialog \
+ dialogTitle:"$DTKSH_APPNAME" \
+ messageString:"$message" \
+ unmapCallback:reject \
+# symbolPixmap:/usr/dt/appconfig/icons/C/DtFlag.m.pm
+
+# change the OK button to "Yes"
+XmMessageBoxGetChild OK_BUTTON $DIALOG DIALOG_OK_BUTTON
+XtSetValues $OK_BUTTON \
+ labelString:"Yes" \
+ activateCallback:accept
+
+# change the Cancel Button to "No"
+XmMessageBoxGetChild CANCEL_BUTTON $DIALOG DIALOG_CANCEL_BUTTON
+XtSetValues $CANCEL_BUTTON \
+ labelString:"No" \
+ activateCallback:reject
+
+# change Help button to View-Only, set focus and make it the default
+XmMessageBoxGetChild HELP_BUTTON $DIALOG DIALOG_HELP_BUTTON
+XtSetValues $HELP_BUTTON \
+ labelString:"View\nOnly" \
+ activateCallback:view
+
+# make "No" the default (for unmap as well)
+XtSetValues $DIALOG \
+ defaultButton:$CANCEL_BUTTON initialFocus:$CANCEL_BUTTON \
+
+# create the ticker
+ticker () {
+ test $timeout -eq 0 && lock
+ XtSetValues $DIALOG dialogTitle:"accepting in $timeout seconds"
+ XtAddTimeOut TICKER 1000 ticker
+ timeout=`expr $timeout - 1`
+}
+
+# display dialog and activate ticker
+XtAddTimeOut TICKER 1000 ticker
+XtManageChild $DIALOG
+XtMainLoop
+
diff --git a/x11vnc/misc/rx11vnc b/x11vnc/misc/rx11vnc
new file mode 100755
index 0000000..27e6d06
--- /dev/null
+++ b/x11vnc/misc/rx11vnc
@@ -0,0 +1,133 @@
+#!/bin/sh
+#
+# usage: rx11vnc [-s] <host>:<xdisplay>
+# rx11vnc [-s] <host> (assumes xdisplay is 0)
+#
+# -s means use ssh instead of rsh.
+# -S tries to tunnel the vnc traffic thru ssh. (experimental...)
+#
+#set -xv
+
+#
+# Place your x11vnc cmd + options here (must have -bg and -display
+# with -display as the last one)
+#
+cmd="x11vnc -nap -q -bg -display"
+viewer="vncviewer"
+rsh=rsh
+
+#
+# The following two settings are only used under -S (ssh tunnel)
+#
+# Unfortunately, we have to set up the ssh port redirection *before*
+# x11vnc has started and selected its listening port.
+# tunnel_ports is a list of ports we expect/hope to be free on both
+# the local and remote machines:
+#
+tunnel_ports="5900 5901 5902 5903"
+#
+# VNC has a poor default in that if the client appears to be emanating
+# from the local machine, then raw encoding is preferred. With ssh port
+# redirection we appear to be coming from the localhost, but we are not.
+# We pass this encoding list to the viewer to give lowest preference to
+# raw encoding:
+#
+tunnel_encodings="copyrect tight zrle hextile zlib corre rre"
+
+if [ "$USER" = "runge" ]; then
+ cmd="x11vnc.expt -nap -q -bg -rfbauth .vnc/passwd -display"
+ viewer="vncviewerz"
+fi
+
+if [ "X$1" = "X-s" ]; then
+ shift
+ rsh=ssh
+elif [ "X$1" = "X-S" ]; then
+ shift
+ rsh=ssh
+ tunnel=1
+ cmd=`echo "$cmd" | sed -e 's/ / -localhost /'`
+fi
+
+remote=$1
+if echo "$remote" | grep ':' > /dev/null; then
+ :
+else
+ remote="$remote:0"
+fi
+
+host=`echo "$remote" | awk -F: '{print $1}'`
+disp=`echo "$remote" | awk -F: '{print $2}'`
+disp=":$disp"
+if [ "X$host" = "X" ]; then
+ echo "bad host."
+ exit 1
+fi
+
+# start the remote x11vnc:
+if [ $tunnel ]; then
+ # much more kludgy for tunnelling:
+ tmp=/tmp/rx11vnc.$$
+ redir=""
+ used_ports=`netstat -an | egrep '(ESTABLISHED|LISTEN) *$' \
+ | sed -e 's/^[ ]*//' -e 's/^tcp[ 0-9][ 0-9]*//' \
+ -e 's/[ ].*$//' -e 's/^.*[^0-9]//' | sort -nu`
+ for p in $tunnel_ports
+ do
+ ok=1
+ for u in $used_ports
+ do
+ if [ "X$p" = "X$u" ]; then
+ echo "port $u is in use. skipping it"
+ ok=
+ break
+ fi
+ done
+ if [ $ok ]; then
+ redir="$redir -L $p:localhost:$p"
+ fi
+ done
+ #
+ # Have ssh put the command in the bg, then we look for PORT=
+ # in the tmp file. The sleep at the end is to give us enough
+ # time to connect thru the port redir, otherwise ssh will exit
+ # before we can connect.
+ #
+ time=15
+ $rsh -f $redir $host "$cmd $disp; echo END; sleep $time" > $tmp
+
+ i=0
+ while [ $i -lt $time ]
+ do
+ sleep 1
+ if grep '^PORT=' $tmp > /dev/null; then
+ port=`grep '^PORT=' $tmp | sed -e 's/PORT=//'`
+ if [ "X$port" != "X" ]; then
+ break
+ fi
+ fi
+ i=`expr $i + 1`
+ done
+ cat $tmp
+ rm -f $tmp
+else
+ port=`$rsh $host "$cmd $disp" | grep '^PORT=' | sed -e 's/PORT=//'`
+fi
+
+echo "x11vnc port is '$port'"
+
+# now start up the viewer on this end:
+if echo "$port" | grep '^[0-9][0-9]*$' > /dev/null; then
+ if [ $port -lt 6000 -a $port -ge 5900 ]; then
+ # vncviewer special cases 0-99
+ port=`expr $port - 5900`
+ fi
+ if [ $tunnel ]; then
+ $viewer -encodings "$tunnel_encodings" "localhost:$port"
+ else
+ $viewer "$host:$port"
+ fi
+else
+ echo "bad port."
+ exit 1
+fi
diff --git a/x11vnc/misc/rx11vnc.pl b/x11vnc/misc/rx11vnc.pl
new file mode 100755
index 0000000..cf4b437
--- /dev/null
+++ b/x11vnc/misc/rx11vnc.pl
@@ -0,0 +1,199 @@
+ #!/bin/sh -- # A comment mentioning perl
+eval 'exec perl -S $0 ${1+"$@"}'
+ if 0;
+#
+# Here is the remote x11vnc command.
+# Modify to your needs, required to have %DISP item that expands to X display
+# and the -bg option to go into the background.
+#
+$x11vnc_cmd = "x11vnc -localhost -nap -q -bg -display %DISP";
+
+#
+# We will redir local ports to these remote ports hoping the remote
+# x11vnc selects one of them:
+#
+@tunnel_ports = qw(5900 5901 5902 5903 5904);
+
+#
+# We need to specify the encoding preferences since vncviewer will
+# mistakeningly prefer "raw" encoding for local connection. required to
+# have %VNC_ITEM to expand to localhost:<port>
+
+# One really needs an -encodings option otherwise the vncviewer will
+# prefer 'raw' which is very slow.
+#
+$viewer_cmd = "vncviewer -encodings 'copyrect tight zrle hextile zlib corre rre' %VNC_DISP";
+$sleep_time = 15;
+
+if ($ENV{USER} eq 'runge') {
+ # my personal kludges:
+ $viewer_cmd =~ s/vncviewer/vncviewerz/; # for tight
+ $x11vnc_cmd .= ' -rfbauth .vnc/passwd'; # I always want rfbauth
+}
+
+chop($Program = `basename $0`);
+
+$Usage = <<"END";
+
+$Program: wrapper to tunnel vncviewer <-> x11vnc VNC traffic through a ssh
+ encrypted tunnel port redirection.
+
+Usage: $Program <options> <remote-Xdisplay>
+
+Options:
+ -l <user> ssh login as remote user <user>
+
+ -rfbauth <remote-auth-file> this option is passed to the remote
+ x11vnc command for passwd file.
+
+Notes:
+
+Example: $Program snoopy:0
+
+END
+
+LOOP:
+while (@ARGV) {
+ $_ = shift;
+ CASE: {
+ /^-display$/ && ($remote_xdisplay = shift, last CASE);
+ /^-rfbauth$/ && ($x11vnc_cmd .= ' -rfbauth ' . shift, last CASE);
+ /^-l$/ && ($remote_user = ' -l ' . shift, last CASE);
+ /^--$/ && (last LOOP); # -- means end of switches
+ /^-(-.*)$/ && (unshift(@ARGV, $1), last CASE);
+ /^(-h|-help)$/ && ((print STDOUT $Usage), exit 0, last CASE);
+ if ( /^-(..+)$/ ) { # split bundled switches:
+ local($y, $x) = ($1, '');
+ (unshift(@ARGV, $y), last CASE) if $y =~ /^-/;
+ foreach $x (reverse(split(//, $y))) { unshift(@ARGV,"-$x") };
+ last CASE;
+ }
+ /^-/ && ((print STDERR "Invalid arg: $_\n$Usage"), exit 1, last CASE);
+ unshift(@ARGV,$_);
+ last LOOP;
+ }
+}
+
+select(STDERR); $| = 1;
+select(STDOUT); $| = 1;
+
+# Determine the remote X display to connect to:
+$remote_xdisplay = shift if $remote_xdisplay eq '';
+if ($remote_xdisplay !~ /:/) {
+ $remote_xdisplay .= ':0'; # assume they mean :0 over there.
+}
+if ($remote_xdisplay =~ /:/) {
+ $host = $`;
+ $disp = ':' . $';
+} else {
+ die "bad X display: $remote_xdisplay, must be <host>:<display>\n";
+}
+
+#
+# Get list of local ports in use so we can avoid them:
+# (tested on Linux and Solaris)
+#
+open(NETSTAT, "netstat -an|") || die "netstat -an: $!";
+while (<NETSTAT>) {
+ chomp ($line = $_);
+ next unless $line =~ /(ESTABLISHED|LISTEN|WAIT2?)\s*$/;
+ $line =~ s/^\s*//;
+ $line =~ s/^tcp[\s\d]*//;
+ $line =~ s/\s.*$//;
+ $line =~ s/^.*\D//;
+ if ($line !~ /^\d+$/) {
+ die "bad netstat line: $line from $_";
+ }
+ $used_port{$line} = 1;
+}
+close(NETSTAT);
+
+#
+# Now match up free local ports with the desired remote ports
+# (note that the remote ones could be in use but that won't stop
+# the ssh with port redirs from succeeding)
+#
+$lport = 5900;
+$cnt = 0;
+foreach $rport (@tunnel_ports) {
+ while ($used_port{$lport}) {
+ $lport++;
+ $cnt++;
+ die "too hard to find local ports 5900-$lport" if $cnt > 200;
+ }
+ $port_map{$rport} = $lport;
+ $lport++;
+}
+
+$redir = '';
+foreach $rport (@tunnel_ports) {
+ $redir .= " -L $port_map{$rport}:localhost:$rport";
+}
+
+#
+# Have ssh put the command in the bg, then we look for PORT= in the
+# tmp file. The sleep at the end is to give us enough time to connect
+# thru the port redir, otherwise ssh will exit before we can connect.
+#
+
+# This is the x11vnc cmd for the remote side:
+$cmd = $x11vnc_cmd;
+$cmd =~ s/%DISP/$disp/;
+
+# This is the ssh cmd for the local side (this machine):
+$ssh_cmd = "ssh -f $remote_user $redir $host '$cmd; echo END; sleep $sleep_time'";
+$ssh_cmd =~ s/ / /g;
+print STDERR "running ssh command:\n\n$ssh_cmd\n\n";
+
+#
+# Run ssh and redir into a tmp file (assumes ssh will use /dev/tty
+# for password/passphrase dialog)
+#
+$tmp = "/tmp/rx.$$";
+system("$ssh_cmd > $tmp");
+
+# Now watch for the PORT=XXXX message:
+$sleep = 0;
+$rport = '';
+print STDERR "\nWaiting for x11vnc to indicate its port ..";
+while ($sleep < $sleep_time + 10) {
+ print STDERR ".";
+ sleep(1);
+ $sleep++;
+ if (`cat $tmp` =~ /PORT=(\d+)/) {
+ $rport = $1;
+ # wait 1 more second for output:
+ sleep(1);
+ if (`cat $tmp` =~ /PORT=(\d+)/) {
+ $rport = $1;
+ }
+ last;
+ }
+}
+print STDERR "\n";
+
+if (! $rport) {
+ print STDERR `cat $tmp`;
+ unlink($tmp);
+ die "could not determine remote port.\n";
+}
+unlink($tmp);
+
+# Find the remote to local mapping:
+$lport = $port_map{$rport};
+print STDERR "remote port is: $rport (corresponds to port $lport here)\n";
+if (! $lport) {
+ die "could not determine local port redir.\n";
+}
+
+# Apply the special casing vncviewer does for 5900 <= port < 6000
+if ($lport < 6000 && $lport >= 5900) {
+ $lport = $lport - 5900;
+}
+
+# Finally, run the viewer.
+$cmd = $viewer_cmd;
+$cmd =~ s/%VNC_DISP/localhost:$lport/;
+
+print STDERR "running vncviewer command:\n\n$cmd\n\n";
+system($cmd);
diff --git a/x11vnc/misc/shm_clear b/x11vnc/misc/shm_clear
new file mode 100755
index 0000000..16d5cb6
--- /dev/null
+++ b/x11vnc/misc/shm_clear
@@ -0,0 +1,97 @@
+#!/bin/sh
+#
+# shm_clear: clean out unattached (NATTACH=0) shm segments.
+# See ipcs(1) and ipcrm(1). Tested on Linux and Solaris.
+#
+# Usage:
+# shm_clear list and prompt for removal of your unattached shm segments.
+# shm_clear -y assume "yes" to all the removal prompts.
+# shm_clear -l only list (all of) your shm segments and exit.
+#
+
+#set -xv
+if echo "$1" | grep '^-h' > /dev/null; then
+ # -h or -help
+ tail +3 $0 | head -9
+ exit
+fi
+
+if [ "X$USER" = "X" ]; then
+ USER=$LOGNAME
+fi
+l_arg="shmid.*owner|CREATOR|$USER"
+
+# set up OS dependent cmdline opts, etc.
+if [ `uname` = "Linux" ]; then
+ m_arg="-m"
+ r_arg="shm"
+ g_arg="^0x"
+ s_cmd="ipcs $m_arg -i %ID"
+ awkcut='{print $2, $6}'
+elif [ `uname` = "SunOS" ]; then
+ m_arg="-ma"
+ r_arg="-m"
+ g_arg="^m"
+ s_cmd="ipcs $m_arg | egrep ' %ID |CREATOR' | grep -v IPC.status"
+ awkcut='{print $2, $9}'
+else
+ echo unsupported OS: `uname`
+ exit 1
+fi
+
+list() {
+ if [ "X$1" = "X-L" ]; then
+ l_arg="$l_arg|."
+ echo "All shm segments for all:"
+ else
+ echo "All shm segments for $USER:"
+ fi
+ ipcs $m_arg | egrep "$l_arg"
+ echo
+}
+
+show() {
+ cmd=`echo "$s_cmd" | sed -e "s/%ID/$1/g"`
+ eval $cmd
+}
+
+remove() {
+ echo ipcrm $r_arg $1
+ ipcrm $r_arg $1
+}
+
+if [ "X$1" = "X-l" -o "X$1" = "X-L" ]; then
+ # list only. both attached and unattached listed.
+ list $1
+ exit 0
+fi
+
+if [ "X$1" = "X-y" ]; then
+ shift
+ yes=1 # assume "yes" to all delete questions.
+else
+ yes=""
+fi
+
+list
+
+ids=`ipcs $m_arg | grep "$g_arg" | grep $USER | awk "$awkcut" | grep ' 0$' | awk '{print $1}'`
+if [ "X$ids" = "X" ]; then
+ echo "No unattached shmids for $USER."
+fi
+
+for id in $ids
+do
+ if [ $yes ]; then
+ :
+ else
+ echo "-------------------------------------"
+ show $id
+ printf "\nDelete? [y]/n "
+ read x
+ if echo "$x" | grep -i n > /dev/null; then
+ continue
+ fi
+ fi
+ remove $id
+done
diff --git a/x11vnc/misc/slide.pl b/x11vnc/misc/slide.pl
new file mode 100755
index 0000000..0c90d0e
--- /dev/null
+++ b/x11vnc/misc/slide.pl
@@ -0,0 +1,112 @@
+ #!/bin/sh -- # A comment mentioning perl
+eval 'exec perl -S $0 ${1+"$@"}'
+ if 0;
+#
+# slide.pl: amusing example slideshow program for use with x11vnc -rawfb mode.
+#
+# E.g. x11vnc -rawfb map:/tmp/foo@640x480x32:ff/ff00/ff0000 -pipeinput slide.pl
+#
+# requires: jpegtopnm(1), (maybe LSB too).
+#
+
+@jpegs = qw(
+ dr_fun_new.jpg canon.jpg go_microsoft.jpg jonathan2.jpg
+ michelle1.jpg novm.jpg photo-008.jpg presrange.jpg
+);
+
+# Or:
+# @jpegs = @ARGV;
+# @jpegs = <*.jpg>;
+
+# this is x11vnc's -rawfb value:
+if ($ENV{X11VNC_RAWFB_STR} =~ m,:(.*)@(\d+)x(\d+)x(\d+),) {
+ $fb = $1; # filename
+ $W = $2; # width
+ $H = $3; # height
+} else {
+ die "No usable X11VNC_RAWFB_STR\n";
+}
+
+open(FB, ">$fb") || die "$!";
+
+# make a solid background:
+$ones = "\377" x ($W * 4);
+$grey = "\340" x ($W * 4);
+for ($y = 0; $y < $H; $y++) {
+ print FB $grey;
+}
+
+# this is rather slow with many jpegs... oh well.
+foreach $pic (@jpegs) {
+ print STDERR "loading '$pic' please wait ...\n";
+ open(JPEG, "jpegtopnm '$pic' 2>/dev/null|") || die "$!";
+ while (<JPEG>) {
+ next if /^P\d/;
+ if (/^(\d+)\s+(\d+)\s*$/) {
+ $Jpeg{$pic}{w} = $1;
+ $Jpeg{$pic}{h} = $2;
+ }
+ last if /^255$/;
+ }
+ $data = '';
+ while (<JPEG>) {
+ $data .= $_;
+ }
+ close(JPEG);
+
+ # need to put in a 4th 0 byte after RGB for 32bpp. 24bpp doesn't work.
+ # (MSB might be other way around).
+
+ $new = '';
+ for ($l = 0; $l < int(length($data)/3); $l++) {
+ $new .= substr($data, $l * 3, 3) . "\0";
+ }
+ $Jpeg{$pic}{data} = $new;
+ $data = ''; $new = '';
+
+ if ($pic eq $jpegs[0]) {
+ showpic(0);
+ }
+}
+
+$N = scalar(@jpegs);
+print STDERR "\nFinished loading $N images. Click Button or Spacebar for next.\n";
+$I = 0;
+
+while (<>) {
+ # read the next user input event, watch for button press or spacebar:
+ last if /^Keysym.* [qQ] /;
+ next unless /^(Pointer.*ButtonPress|Keysym.*space.*KeyPress)/;
+ $I = ($I + 1) % $N;
+ showpic($I);
+}
+
+sub showpic {
+ my($i) = @_;
+
+ my $pic = $jpegs[$i];
+ my $h = $Jpeg{$pic}{h};
+ my $w = $Jpeg{$pic}{w};
+
+ my $dy = int(($H - $h)/2);
+ my $dx = int(($W - $w)/2);
+
+ print STDERR "showing pic $i: $pic\t$w x $h +$dy+$dx\n";
+
+ # clear screen:
+ seek(FB, 0, 0);
+ for ($y = 0; $y < $H; $y++) {
+ print FB $ones;
+ }
+
+ # insert new picture:
+ for ($y = 0; $y < $h; $y++) {
+ seek(FB, (($y + $dy) * $W + $dx) * 4, 0);
+ $line = substr($Jpeg{$pic}{data}, $y * $w * 4, $w * 4);
+ print FB $line;
+ }
+}
+
+close(FB);
+#unlink($fb); # this (probably) won't kill x11vnc
+print STDERR "$0 done.\n";
diff --git a/x11vnc/misc/vcinject.pl b/x11vnc/misc/vcinject.pl
new file mode 100755
index 0000000..b371d4e
--- /dev/null
+++ b/x11vnc/misc/vcinject.pl
@@ -0,0 +1,113 @@
+ #!/bin/sh -- # A comment mentioning perl
+eval 'exec perl -S $0 ${1+"$@"}'
+ if 0;
+#
+# vcinject.pl: simple hack to inject keystrokes into Linux VC tty.
+# See LinuxVNC.c for a more careful treatment using C and public API.
+#
+# Usage: vcinject.pl <N> (or /dev/ttyN)
+#
+# This is an example x11vnc -pipeinput program E.g.:
+#
+# x11vnc -rawfb map:/dev/fb0@1024x768x16 -pipeinput "vcinject.pl /dev/tty3"
+#
+# (see fbset(8) for obtaining fb info).
+#
+# It reads lines like this from STDIN:
+#
+# Keysym <id> <down> <n> <Keysym> ...
+#
+# <id> is ignored, it uses the rest to deduce the keystrokes to send
+# to the console.
+#
+
+$tty = shift;
+$tty = "/dev/tty$tty" if $tty =~ /^\d+$/;
+
+warn "strange tty device: $tty\n" if $tty !~ m,^/dev/tty\d+$,;
+
+open(TTY, ">$tty") || die "open $tty: $!\n";
+$fd = fileno(TTY);
+
+$linux_ioctl_syscall = 54; # common knowledge, eh? :-)
+$TIOCSTI = 0x5412;
+
+%Map = qw(
+ Escape 27
+ Tab 9
+ Return 13
+ BackSpace 8
+ Home 1
+ End 5
+ Up 16
+ Down 14
+ Right 6
+ Left 2
+ Next 6
+ Prior 2
+);
+# the latter few above seem to be vi specials. (since they are normally
+# escape sequences, e.g. ESC [ 5 ~)
+
+sub lookup {
+ my($down, $key, $name) = @_;
+
+ my $n = -1;
+ $name =~ s/^KP_//;
+
+ # algorithm borrowed from LinuxVNC.c:
+ if (! $down) {
+ if ($name =~ /^Control/) {
+ $control--;
+ }
+ return $n;
+ }
+
+ if ($name =~ /^Control/) {
+ $control++;
+ } else {
+ if (exists($Map{$name})) {
+ $n = $Map{$name};
+ }
+ if ($control && $name =~ /^[A-z]$/) {
+ $n = ord($name);
+ # shift down to the Control zone:
+ if ($name =~ /[a-z]/) {
+ $n -= (ord("a") - 1);
+ } else {
+ $n -= (ord("A") - 1);
+ }
+ }
+ if ($n < 0 && $key < 256) {
+ $n = $key;
+ }
+ }
+ return $n;
+}
+
+$control = 0;
+$debug = 0;
+
+while (<>) {
+ chomp;
+ if (/^\w+$/) {
+ # for debugging, you type the keysym in manually.
+ $_ = "Keysym 1 0 999 $_ None";
+ }
+ next unless /^Keysym/;
+
+ my ($j, $id, $down, $k, $keysym, $rest) = split(' ', $_);
+
+ $n = lookup($down, $k, $keysym);
+ if ($n < 0 || $n > 255) {
+ print STDERR "skip: '$keysym' -> $n\n" if $down && $debug;
+ next;
+ }
+
+ $n_p = pack("c", $n);
+ $ret = syscall($linux_ioctl_syscall, $fd, $TIOCSTI, $n_p);
+
+ print STDERR "ctrl=$control $keysym/$k syscall(" .
+ "$linux_ioctl_syscall, $fd, $TIOCSTI, $n) = $ret\n" if $debug;
+
+}
diff --git a/x11vnc/misc/x11vnc_loop b/x11vnc/misc/x11vnc_loop
new file mode 100755
index 0000000..1a3e0a2
--- /dev/null
+++ b/x11vnc/misc/x11vnc_loop
@@ -0,0 +1,89 @@
+#!/bin/sh
+#
+# x11vnc_loop:
+#
+# Example startup script for connecting x11vnc to an X display
+# at system boot up and having it reconnect when the X server restarts.
+#
+# Run, in rc.local say, via, e.g.:
+#
+# /path/to/x11vnc_loop 1>> /var/tmp/x11vnc_loop.log 2>&1 &
+#
+# call with argument "once" or a number to limit the number of loops.
+#
+##########################################################################
+# The following needs to be customized:
+x11vnc_cmd=x11vnc # or use full path (or set PATH).
+pwfile=/path/to/vnc/passwd # always use a password
+display=:0 # display of interest
+restart_sleep=5 # pause between X server restarts.
+
+# modify cmdline args if desired:
+x11vnc_args="-display $display -rfbauth $pwfile -forever -nap"
+
+# you may need to customize the "grep", etc, below in get_xauthority_file()
+##########################################################################
+
+if [ "X$1" != "X" ]; then
+ max=$1
+ shift
+fi
+
+get_xauthority_file() {
+ #
+ # We need to find the MIT-COOKIE file... this not portable at all,
+ # depends on OS, distro, desktop, phase of moon, etc...
+ #
+ # If the cookie file was fixed and you knew it, you could just
+ # return it here e.g.:
+ #
+ ## echo "/var/gdm/:0.Xauth"; return
+ #
+ # or, if you knew the directory, you could look for the youngest
+ # file there and return it e.g.:
+ #
+ ## echo `ls -t /var/lib/xdm/authdir/authfiles/* | head -1`; return
+
+ # this hack tries to grep it out of ps output...
+ xauth=""
+ for i in 1 2 3
+ do
+ # very linux specific, and you likely need to tweak..
+ patt="X11R6.*/X.*-auth"
+ xauth=`ps wwwaux | grep "$patt" \
+ | egrep -v 'grep|Xprt' | head -1 \
+ | sed -e 's/^.*-auth//' | awk '{print $1}'`
+
+ if [ "X$xauth" != "X" ]; then
+ break
+ fi
+ sleep 2 # wait a bit in case X server is restarting slowly.
+ done
+ echo $xauth
+}
+
+try=1
+while [ 1 ]
+do
+ echo "`date` $0 try number: $try"; try=`expr $try + 1`
+
+ auth=`get_xauthority_file`
+ if [ ! -r "$auth" ]; then
+ echo "`date` bad auth file: \"$auth\""
+ else
+ cmd="$x11vnc_cmd $x11vnc_args"
+ sleep 1
+ echo "`date` running: $cmd -auth $auth"
+ # run x11vnc:
+ $cmd -auth $auth
+ if [ "X$max" = "Xonce" ]; then
+ exit $?
+ fi
+ fi
+ if echo "$max" | grep '[0-9]' > /dev/null; then
+ if [ $try -gt $max ]; then
+ exit
+ fi
+ fi
+ sleep $restart_sleep
+done