diff options
author | runge <runge> | 2005-04-10 04:30:48 +0000 |
---|---|---|
committer | runge <runge> | 2005-04-10 04:30:48 +0000 |
commit | baee5e2b3a00993fee00dca9d4e560f904693a6c (patch) | |
tree | 7cea15f636074f4d81fd100f6f37cc25750f3211 /x11vnc/misc | |
parent | ac01f36ce0e2630db608537641b0335b249fea3c (diff) | |
download | libtdevnc-baee5e2b3a00993fee00dca9d4e560f904693a6c.tar.gz libtdevnc-baee5e2b3a00993fee00dca9d4e560f904693a6c.zip |
x11vnc: -rawfb, -pipeinput, -xtrap, -flag, ...
Diffstat (limited to 'x11vnc/misc')
-rw-r--r-- | x11vnc/misc/Makefile.am | 1 | ||||
-rw-r--r-- | x11vnc/misc/README | 32 | ||||
-rw-r--r-- | x11vnc/misc/blockdpy.c | 352 | ||||
-rw-r--r-- | x11vnc/misc/dtVncPopup | 109 | ||||
-rwxr-xr-x | x11vnc/misc/rx11vnc | 133 | ||||
-rwxr-xr-x | x11vnc/misc/rx11vnc.pl | 199 | ||||
-rwxr-xr-x | x11vnc/misc/shm_clear | 97 | ||||
-rwxr-xr-x | x11vnc/misc/slide.pl | 112 | ||||
-rwxr-xr-x | x11vnc/misc/vcinject.pl | 113 | ||||
-rwxr-xr-x | x11vnc/misc/x11vnc_loop | 89 |
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 |