diff options
Diffstat (limited to 'x11vnc/misc')
73 files changed, 0 insertions, 63653 deletions
diff --git a/x11vnc/misc/.cvsignore b/x11vnc/misc/.cvsignore deleted file mode 100644 index 22a4e72..0000000 --- a/x11vnc/misc/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -Makefile -Makefile.in - diff --git a/x11vnc/misc/LICENSE b/x11vnc/misc/LICENSE deleted file mode 100644 index ea4bdb0..0000000 --- a/x11vnc/misc/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -The following files in this directory: - - Makefile.am - README - Xdummy - blockdpy.c - ranfb.pl - rx11vnc - rx11vnc.pl - shm_clear - slide.pl - vcinject.pl - x11vnc_loop - x11vnc_pw - -are all Copyright (C) 2002-2009 Karl J. Runge <runge@karlrunge.com> -and are all released under this license: - - 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; version 2 of the License. - - 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 or see <http://www.gnu.org/licenses/>. diff --git a/x11vnc/misc/Makefile.am b/x11vnc/misc/Makefile.am deleted file mode 100644 index e6a50aa..0000000 --- a/x11vnc/misc/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -SUBDIRS = turbovnc -DIST_SUBDIRS = turbovnc -EXTRA_DIST=README blockdpy.c dtVncPopup rx11vnc rx11vnc.pl shm_clear ranfb.pl slide.pl vcinject.pl x11vnc_loop Xdummy ultravnc_repeater.pl connect_switch panner.pl desktop.cgi inet6to4 uinput.pl qt_tslib_inject.pl diff --git a/x11vnc/misc/README b/x11vnc/misc/README deleted file mode 100644 index 2ed1dff..0000000 --- a/x11vnc/misc/README +++ /dev/null @@ -1,50 +0,0 @@ - -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. - ranfb.pl example -rawfb setup:./ranfb.pl to set up a framebuffer. - - uinput.pl test perl script for Linux uinput injection. - - qt_tslib_inject.pl touchscreen -pipeinput helper for tslib on qtmoko. - -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. - Xdummy An LD_PRELOAD kludge to run the Xorg "dummy" device driver - like Xvfb. - - ultravnc_repeater.pl: Unix script to act as UltraVNC repeater proxy. - - connect_switch: Share HTTPS, VNC, SSH, etc. through a single port (e.g. 443) - - panner.pl Allows a small rectangle to pan around a desktop more or less. - - desktop.cgi CGI script for creating multi-user virtual desktops on a - server. Also can do port-redirection to internal machines. - - inet6to4 ipv6 to ipv4 relay (i.e. until libvncserver supports ipv6) diff --git a/x11vnc/misc/Xdummy b/x11vnc/misc/Xdummy deleted file mode 100755 index 638a7b3..0000000 --- a/x11vnc/misc/Xdummy +++ /dev/null @@ -1,1930 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------- -# Copyright (C) 2005-2010 Karl J. Runge <runge@karlrunge.com> -# All rights reserved. -# -# This file is part of Xdummy. -# -# Xdummy 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. -# -# Xdummy 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 Xdummy; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see <http://www.gnu.org/licenses/>. -# ---------------------------------------------------------------------- -# -# -# Xdummy: an LD_PRELOAD hack to run a stock Xorg(1) or XFree86(1) server -# with the "dummy" video driver to make it avoid Linux VT switching, etc. -# -# Run "Xdummy -help" for more info. -# -install="" -uninstall="" -runit=1 -prconf="" -notweak="" -root="" -nosudo="" -xserver="" -geom="" -nomodelines="" -depth="" -debug="" -strace="" -cmdline_config="" - -PATH=$PATH:/bin:/usr/bin -export PATH - -program=`basename "$0"` - -help () { - ${PAGER:-more} << END -$program: - - A hack to run a stock Xorg(1) or XFree86(1) X server with the "dummy" - (RAM-only framebuffer) video driver such that it AVOIDS the Linux VT - switching, opening device files in /dev, keyboard and mouse conflicts, - and other problems associated with the normal use of "dummy". - - In other words, it tries to make Xorg/XFree86 with the "dummy" - device driver act more like Xvfb(1). - - The primary motivation for the Xdummy script is to provide a virtual X - server for x11vnc but with more features than Xvfb (or Xvnc); however - it could be used for other reasons (e.g. better automated testing - than with Xvfb.) One nice thing is the dummy server supports RANDR - dynamic resizing while Xvfb does not. - - So, for example, x11vnc+Xdummy terminal services are a little better - than x11vnc+Xvfb. - - To achieve this, while running the real Xserver $program intercepts - system and library calls via the LD_PRELOAD method and modifies - the behavior to make it work correctly (e.g. avoid the VT stuff.) - LD_PRELOAD tricks are usually "clever hacks" and so might not work - in all situations or break when something changes. - - WARNING: Take care in using Xdummy, although it never has it is - possible that it could damage hardware. One can use the -prconf - option to have it print out the xorg.conf config that it would use - and then inspect it carefully before actually using it. - - This program no longer needs to be run as root as of 12/2009. - However, if there are problems for certain situations (usually older - servers) it may perform better if run as root (use the -root option.) - When running as root remember the previous paragraph and that Xdummy - comes without any warranty. - - gcc/cc and other build tools are required for this script to be able - to compile the LD_PRELOAD shared object. Be sure they are installed - on the system. See -install and -uninstall described below. - - Your Linux distribution may not install the dummy driver by default, - e.g: - - /usr/lib/xorg/modules/drivers/dummy_drv.so - - some have it in a package named xserver-xorg-video-dummy you that - need to install. - -Usage: - - $program <${program}-args> <Xserver-args> - - (actually, the arguments can be supplied in any order.) - -Examples: - - $program -install - - $program :1 - - $program -debug :1 - - $program -tmpdir ~/mytmp :1 -nolisten tcp - -startx example: - - startx -e bash -- $program :2 -depth 16 - - (if startx needs to be run as root, you can su(1) to a normal - user in the bash shell and then launch ~/.xinitrc or ~/.xsession, - gnome-session, startkde, startxfce4, etc.) - -xdm example: - - xdm -config /usr/local/dummy/xdm-config -nodaemon - - where the xdm-config file has line: - - DisplayManager.servers: /usr/local/dummy/Xservers - - and /usr/local/dummy/Xservers has lines: - - :1 local /usr/local/dummy/Xdummy :1 -debug - :2 local /usr/local/dummy/Xdummy :2 -debug - - (-debug is optional) - -gdm/kdm example: - - TBD. - -Root permission and x11vnc: - - Update: as of 12/2009 this program no longer must be run as root. - So try it as non-root before running it as root and/or the - following schemes. - - In some circumstances X server program may need to be run as root. - If so, one could run x11vnc as root with -unixpw (it switches - to the user that logs in) and that may be OK, some other ideas: - - - add this to sudo via visudo: - - ALL ALL = NOPASSWD: /usr/local/bin/Xdummy - - - use this little suid wrapper: -/* - * xdummy.c - * - cc -o ./xdummy xdummy.c - sudo cp ./xdummy /usr/local/bin/xdummy - sudo chown root:root /usr/local/bin/xdummy - sudo chmod u+s /usr/local/bin/xdummy - * - */ -#include <unistd.h> -#include <stdlib.h> -#include <sys/types.h> -#include <stdio.h> - -int main (int argc, char *argv[]) { - extern char **environ; - char str[100]; - sprintf(str, "XDUMMY_UID=%d", (int) getuid()); - putenv(str); - setuid(0); - setgid(0); - execv("/usr/local/bin/Xdummy", argv); - exit(1); - return 1; -} - - -Options: - - ${program}-args: - - -install Compile the LD_PRELOAD shared object and install it - next to the $program script file as: - - $0.so - - When that file exists it is used as the LD_PRELOAD - shared object without recompiling. Otherwise, - each time $program is run the LD_PRELOAD shared - object is compiled as a file in /tmp (or -tmpdir) - - If you set the environment variable - INTERPOSE_GETUID=1 when building, then when - $program is run as an ordinary user, the shared - object will interpose getuid() calls and pretend - to be root. Otherwise it doesn't pretend to - be root. - - You can also set the CFLAGS environment variable - to anything else you want on the compile cmdline. - - -uninstall Remove the file: - - $0.so - - The LD_PRELOAD shared object will then be compiled - each time this program is run. - - The X server is not started under -install, -uninstall, or -prconf. - - - :N The DISPLAY (e.g. :15) is often the first - argument. It is passed to the real X server and - also used by the Xdummy script as an identifier. - - -geom geom1[,geom2...] Take the geometry (e.g. 1024x768) or list - of geometries and insert them into the Screen - section of the tweaked X server config file. - Use this to have a different geometry than the - one(s) in the system config file. - - The option -geometry can be used instead of -geom; - x11vnc calls Xdummy and Xvfb this way. - - -nomodelines When you specify -geom/-geometry, $program will - create Modelines for each geometry and put them - in the Monitor section. If you do not want this - then supply -nomodelines. - - -depth n Use pixel color depth n (e.g. 8, 16, or 24). This - makes sure the X config file has a Screen.Display - subsection of this depth. Note this option is - ALSO passed to the X server. - - -DEPTH n Same as -depth, except not passed to X server. - - -tmpdir dir Specify a temporary directory, owned by you and - only writable by you. This is used in place of - /tmp/Xdummy.\$USER/.. to place the $program.so - shared object, tweaked config files, etc. - - -nonroot Run in non-root mode (working 12/2009, now default) - - -root Run as root (may still be needed in some - environments.) Same as XDUMMY_RUN_AS_ROOT=1. - - -nosudo Do not try to use sudo(1) when re-running as root, - use su(1) instead. - - -xserver path Specify the path to the Xserver to use. Default - is to try "Xorg" first and then "XFree86". If - those are not in \$PATH, it tries these locations: - /usr/bin/Xorg - /usr/X11R6/bin/Xorg - /usr/X11R6/bin/XFree86 - - -n Do not run the command to start the X server, - just show the command that $program would run. - The LD_PRELOAD shared object will be built, - if needed. Also note any XDUMMY* environment - variables that need to be set. - - -prconf Print, to stdout, the tweaked Xorg/XFree86 - config file (-config and -xf86config server - options, respectively.) The Xserver is not - started. - - -notweak Do not tweak (modify) the Xorg/XFree86 config file - (system or server command line) at all. The -geom - and similar config file modifications are ignored. - - It is up to you to make sure it is a working - config file (e.g. "dummy" driver, etc.) - Perhaps you want to use a file based on the - -prconf output. - - -debug Extra debugging output. - - -strace strace(1) the Xserver process (for troubleshooting.) - -ltrace ltrace(1) instead of strace (can be slow.) - - -h, -help Print out this help. - - - Xserver-args: - - Most of the Xorg and XFree86 options will work and are simply - passed along if you supply them. Important ones that may be - supplied if missing: - - :N X Display number for server to use. - - vtNN Linux virtual terminal (VT) to use (a VT is currently - still used, just not switched to and from.) - - -config file Driver "dummy" tweaked config file, a - -xf86config file number of settings are tweaked besides Driver. - - If -config/-xf86config is not given, the system one - (e.g. /etc/X11/xorg.conf) is used. If the system one cannot be - found, a built-in one is used. Any settings in the config file - that are not consistent with "dummy" mode will be overwritten - (unless -notweak is specified.) - - Use -config xdummy-builtin to force usage of the builtin config. - - If "file" is only a basename (e.g. "xorg.dummy.conf") with no /'s, - then no tweaking of it is done: the X server will look for that - basename via its normal search algorithm. If the found file does - not refer to the "dummy" driver, etc, then the X server will fail. - -Notes: - - The Xorg/XFree86 "dummy" driver is currently undocumented. It works - well in this mode, but it is evidently not intended for end-users. - So it could be removed or broken at any time. - - If the display Xserver-arg (e.g. :1) is not given, or ":" is given - that indicates $program should try to find a free one (based on - tcp ports.) - - If the display virtual terminal, VT, (e.g. vt9) is not given that - indicates $program should try to find a free one (or guess a high one.) - - This program is not completely secure WRT files in /tmp (but it tries - to a good degree.) Better is to use the -tmpdir option to supply a - directory only writable by you. Even better is to get rid of users - on the local machine you do not trust :-) - - Set XDUMMY_SET_XV=1 to turn on debugging output for this script. - -END -} - -warn() { - echo "$*" 1>&2 -} - -if [ "X$XDUMMY_SET_XV" != "X" ]; then - set -xv -fi - -if [ "X$XDUMMY_UID" = "X" ]; then - XDUMMY_UID=`id -u` - export XDUMMY_UID -fi -if [ "X$XDUMMY_UID" = "X0" ]; then - if [ "X$SUDO_UID" != "X" ]; then - XDUMMY_UID=$SUDO_UID - export XDUMMY_UID - fi -fi - -# check if root=1 first: -# -if [ "X$XDUMMY_RUN_AS_ROOT" = "X1" ]; then - root=1 -fi -for arg in $* -do - if [ "X$arg" = "X-nonroot" ]; then - root="" - elif [ "X$arg" = "X-root" ]; then - root=1 - fi -done - -# See if it really needs to be run as root: -# -if [ "X$XDUMMY_SU_EXEC" = "X" -a "X$root" = "X1" -a "X`id -u`" != "X0" ]; then - # this is to prevent infinite loop in case su/sudo doesn't work: - XDUMMY_SU_EXEC=1 - export XDUMMY_SU_EXEC - - dosu=1 - nosudo="" - - for arg in $* - do - if [ "X$arg" = "X-nonroot" ]; then - dosu="" - elif [ "X$arg" = "X-nosudo" ]; then - nosudo="1" - elif [ "X$arg" = "X-help" ]; then - dosu="" - elif [ "X$arg" = "X-h" ]; then - dosu="" - elif [ "X$arg" = "X-install" ]; then - dosu="" - elif [ "X$arg" = "X-uninstall" ]; then - dosu="" - elif [ "X$arg" = "X-n" ]; then - dosu="" - elif [ "X$arg" = "X-prconf" ]; then - dosu="" - fi - done - if [ $dosu ]; then - # we need to restart it with su/sudo: - if type sudo > /dev/null 2>&1; then - : - else - nosudo=1 - fi - if [ "X$nosudo" = "X" ]; then - warn "$program: supply the sudo password to restart as root:" - if [ "X$XDUMMY_UID" != "X" ]; then - exec sudo $0 -uid $XDUMMY_UID "$@" - else - exec sudo $0 "$@" - fi - else - warn "$program: supply the root password to restart as root:" - if [ "X$XDUMMY_UID" != "X" ]; then - exec su -c "$0 -uid $XDUMMY_UID $*" - else - exec su -c "$0 $*" - fi - fi - # DONE: - exit - fi -fi - -# This will hold the X display, e.g. :20 -# -disp="" -args="" -cmdline_config="" - -# Process Xdummy args: -# -while [ "X$1" != "X" ] -do - if [ "X$1" = "X-config" -o "X$1" = "X-xf86config" ]; then - cmdline_config="$2" - fi - case $1 in - ":"*) disp=$1 - ;; - "-install") install=1; runit="" - ;; - "-uninstall") uninstall=1; runit="" - ;; - "-n") runit="" - ;; - "-no") runit="" - ;; - "-norun") runit="" - ;; - "-prconf") prconf=1; runit="" - ;; - "-notweak") notweak=1 - ;; - "-noconf") notweak=1 - ;; - "-nonroot") root="" - ;; - "-root") root=1 - ;; - "-nosudo") nosudo=1 - ;; - "-xserver") xserver="$2"; shift - ;; - "-uid") XDUMMY_UID="$2"; shift - export XDUMMY_UID - ;; - "-geom") geom="$2"; shift - ;; - "-geometry") geom="$2"; shift - ;; - "-nomodelines") nomodelines=1 - ;; - "-depth") depth="$2"; args="$args -depth $2"; - shift - ;; - "-DEPTH") depth="$2"; shift - ;; - "-tmpdir") XDUMMY_TMPDIR="$2"; shift - ;; - "-debug") debug=1 - ;; - "-nodebug") debug="" - ;; - "-strace") strace=1 - ;; - "-ltrace") strace=2 - ;; - "-h") help; exit 0 - ;; - "-help") help; exit 0 - ;; - *) args="$args $1" - ;; - esac - shift -done - -# Try to get a username for use in our tmp directory, etc. -# -user="" -if [ X`id -u` = "X0" ]; then - user=root # this will also be used below for id=0 -elif [ "X$USER" != "X" ]; then - user=$USER -elif [ "X$LOGNAME" != "X" ]; then - user=$LOGNAME -fi - -# Keep trying... -# -if [ "X$user" = "X" ]; then - user=`whoami 2>/dev/null` -fi -if [ "X$user" = "X" ]; then - user=`basename "$HOME"` -fi -if [ "X$user" = "X" -o "X$user" = "X." ]; then - user="u$$" -fi - -if [ "X$debug" = "X1" -a "X$runit" != "X" ]; then - echo "" - echo "/usr/bin/env:" - env | egrep -v '^(LS_COLORS|TERMCAP)' | sort - echo "" -fi - -# Function to compile the LD_PRELOAD shared object: -# -make_so() { - # extract code embedded in this script into a tmp C file: - n1=`grep -n '^#code_begin' $0 | head -1 | awk -F: '{print $1}'` - n2=`grep -n '^#code_end' $0 | head -1 | awk -F: '{print $1}'` - n1=`expr $n1 + 1` - dn=`expr $n2 - $n1` - - tmp=$tdir/Xdummy.$RANDOM$$.c - rm -f $tmp - if [ -e $tmp -o -h $tmp ]; then - warn "$tmp still exists." - exit 1 - fi - touch $tmp || exit 1 - tail -n +$n1 $0 | head -n $dn > $tmp - - # compile it to Xdummy.so: - if [ -f "$SO" ]; then - mv $SO $SO.$$ - rm -f $SO.$$ - fi - rm -f $SO - touch $SO - if [ ! -f "$SO" ]; then - SO=$tdir/Xdummy.$user.so - warn "warning switching LD_PRELOAD shared object to: $SO" - fi - - if [ -f "$SO" ]; then - mv $SO $SO.$$ - rm -f $SO.$$ - fi - rm -f $SO - - # we assume gcc: - if [ "X$INTERPOSE_GETUID" = "X1" ]; then - CFLAGS="$CFLAGS -DINTERPOSE_GETUID" - fi - echo "$program:" cc -shared -fPIC $CFLAGS -o $SO $tmp - cc -shared -fPIC $CFLAGS -o $SO $tmp - rc=$? - rm -f $tmp - if [ $rc != 0 ]; then - warn "$program: cannot build $SO" - exit 1 - fi - if [ "X$debug" != "X" -o "X$install" != "X" ]; then - warn "$program: created $SO" - ls -l "$SO" - fi -} - -# Set tdir to tmp dir for make_so(): -if [ "X$XDUMMY_TMPDIR" != "X" ]; then - tdir=$XDUMMY_TMPDIR - mkdir -p $tdir -else - tdir="/tmp" -fi - -# Handle -install/-uninstall case: -SO=$0.so -if [ "X$install" != "X" -o "X$uninstall" != "X" ]; then - if [ -e "$SO" -o -h "$SO" ]; then - warn "$program: removing $SO" - fi - if [ -f "$SO" ]; then - mv $SO $SO.$$ - rm -f $SO.$$ - fi - rm -f $SO - if [ -e "$SO" -o -h "$SO" ]; then - warn "warning: $SO still exists." - exit 1 - fi - if [ $install ]; then - make_so - if [ ! -f "$SO" ]; then - exit 1 - fi - fi - exit 0 -fi - -# We need a tmp directory for the .so, tweaked config file, and for -# redirecting filenames we cannot create (under -nonroot) -# -tack="" -if [ "X$XDUMMY_TMPDIR" = "X" ]; then - XDUMMY_TMPDIR="/tmp/Xdummy.$user" - - # try to tack on a unique subdir (display number or pid) - # to allow multiple instances - # - if [ "X$disp" != "X" ]; then - t0=$disp - else - t0=$1 - fi - tack=`echo "$t0" | sed -e 's/^.*://'` - if echo "$tack" | grep '^[0-9][0-9]*$' > /dev/null; then - : - else - tack=$$ - fi - if [ "X$tack" != "X" ]; then - XDUMMY_TMPDIR="$XDUMMY_TMPDIR/$tack" - fi -fi - -tmp=$XDUMMY_TMPDIR -if echo "$tmp" | grep '^/tmp' > /dev/null; then - if [ "X$tmp" != "X/tmp" -a "X$tmp" != "X/tmp/" ]; then - # clean this subdir of /tmp out, otherwise leave it... - rm -rf $XDUMMY_TMPDIR - if [ -e $XDUMMY_TMPDIR ]; then - warn "$XDUMMY_TMPDIR still exists" - exit 1 - fi - fi -fi - -mkdir -p $XDUMMY_TMPDIR -chmod 700 $XDUMMY_TMPDIR -if [ "X$tack" != "X" ]; then - chmod 700 `dirname "$XDUMMY_TMPDIR"` 2>/dev/null -fi - -# See if we can write something there: -# -tfile="$XDUMMY_TMPDIR/test.file" -touch $tfile -if [ ! -f "$tfile" ]; then - XDUMMY_TMPDIR="/tmp/Xdummy.$$.$USER" - warn "warning: setting tmpdir to $XDUMMY_TMPDIR ..." - rm -rf $XDUMMY_TMPDIR || exit 1 - mkdir -p $XDUMMY_TMPDIR || exit 1 -fi -rm -f $tfile - -export XDUMMY_TMPDIR - -# Compile the LD_PRELOAD shared object if needed (needs XDUMMY_TMPDIR) -# -if [ ! -f "$SO" ]; then - SO="$XDUMMY_TMPDIR/Xdummy.so" - make_so -fi - -# Decide which X server to use: -# -if [ "X$xserver" = "X" ]; then - if type Xorg >/dev/null 2>&1; then - xserver="Xorg" - elif type XFree86 >/dev/null 2>&1; then - xserver="XFree86" - elif -x /usr/bin/Xorg; then - xserver="/usr/bin/Xorg" - elif -x /usr/X11R6/bin/Xorg; then - xserver="/usr/X11R6/bin/Xorg" - elif -x /usr/X11R6/bin/XFree86; then - xserver="/usr/X11R6/bin/XFree86" - fi - if [ "X$xserver" = "X" ]; then - # just let it fail below. - xserver="/usr/bin/Xorg" - warn "$program: cannot locate a stock Xserver... assuming $xserver" - fi -fi - -# See if the binary is suid or not readable under -nonroot mode: -# -if [ "X$BASH_VERSION" != "X" ]; then - xserver_path=`type -p $xserver 2>/dev/null` -else - xserver_path=`type $xserver 2>/dev/null | awk '{print $NF}'` -fi -if [ -e "$xserver_path" -a "X$root" = "X" -a "X$runit" != "X" ]; then - if [ ! -r $xserver_path -o -u $xserver_path -o -g $xserver_path ]; then - # XXX not quite correct with rm -rf $XDUMMY_TMPDIR ... - # we keep on a filesystem we know root can write to. - base=`basename "$xserver_path"` - new="/tmp/$base.$user.bin" - if [ -e $new ]; then - snew=`ls -l $new | awk '{print $5}' | grep '^[0-9][0-9]*$'` - sold=`ls -l $xserver_path | awk '{print $5}' | grep '^[0-9][0-9]*$'` - if [ "X$snew" != "X" -a "X$sold" != "X" -a "X$sold" != "X$snew" ]; then - warn "removing different sized copy:" - ls -l $new $xserver_path - rm -f $new - fi - fi - if [ ! -e $new -o ! -s $new ]; then - rm -f $new - touch $new || exit 1 - chmod 700 $new || exit 1 - if [ ! -r $xserver_path ]; then - warn "" - warn "NEED TO COPY UNREADABLE $xserver_path to $new as root:" - warn "" - ls -l $xserver_path 1>&2 - warn "" - warn "This only needs to be done once:" - warn " cat $xserver_path > $new" - warn "" - nos=$nosudo - if type sudo > /dev/null 2>&1; then - : - else - nos=1 - fi - if [ "X$nos" = "X1" ]; then - warn "Please supply root passwd to 'su -c'" - su -c "cat $xserver_path > $new" - else - warn "Please supply the sudo passwd if asked:" - sudo /bin/sh -c "cat $xserver_path > $new" - fi - else - warn "" - warn "COPYING SETUID $xserver_path to $new" - warn "" - ls -l $xserver_path 1>&2 - warn "" - cat $xserver_path > $new - fi - ls -l $new - if [ -s $new ]; then - : - else - rm -f $new - ls -l $new - exit 1 - fi - warn "" - warn "Please restart Xdummy now." - exit 0 - fi - if [ ! -O $new ]; then - warn "file \"$new\" not owned by us!" - ls -l $new - exit 1 - fi - xserver=$new - fi -fi - -# Work out display: -# -if [ "X$disp" != "X" ]; then - : -elif [ "X$1" != "X" ]; then - if echo "$1" | grep '^:[0-9]' > /dev/null; then - disp=$1 - shift - elif [ "X$1" = "X:" ]; then - # ":" means for us to find one. - shift - fi -fi -if [ "X$disp" = "X" -o "X$disp" = "X:" ]; then - # try to find an open display port: - # (tcp outdated...) - ports=`netstat -ant | grep LISTEN | awk '{print $4}' | sed -e 's/^.*://'` - n=0 - while [ $n -le 20 ] - do - port=`printf "60%02d" $n` - if echo "$ports" | grep "^${port}\$" > /dev/null; then - : - else - disp=":$n" - warn "$program: auto-selected DISPLAY $disp" - break - fi - n=`expr $n + 1` - done -fi - -# Work out which vt to use, try to find/guess an open one if necessary. -# -vt="" -for arg in $* -do - if echo "$arg" | grep '^vt' > /dev/null; then - vt=$arg - break - fi -done -if [ "X$vt" = "X" ]; then - if [ "X$user" = "Xroot" ]; then - # root can user fuser(1) to see if it is in use: - if type fuser >/dev/null 2>&1; then - # try /dev/tty17 thru /dev/tty32 - n=17 - while [ $n -le 32 ] - do - dev="/dev/tty$n" - if fuser $dev >/dev/null 2>&1; then - : - else - vt="vt$n" - warn "$program: auto-selected VT $vt => $dev" - break - fi - n=`expr $n + 1` - done - fi - fi - if [ "X$vt" = "X" ]; then - # take a wild guess... - vt=vt16 - warn "$program: selected fallback VT $vt" - fi -else - vt="" -fi - -# Decide flavor of Xserver: -# -stype=`basename "$xserver"` -if echo "$stype" | grep -i xfree86 > /dev/null; then - stype=xfree86 -else - stype=xorg -fi - -tweak_config() { - in="$1" - config2="$XDUMMY_TMPDIR/xdummy_modified_xconfig.conf" - if [ "X$disp" != "X" ]; then - d=`echo "$disp" | sed -e 's,/,,g' -e 's/:/_/g'` - config2="$config2$d" - fi - - # perl script to tweak the config file... add/delete options, etc. - # - env XDUMMY_GEOM=$geom \ - XDUMMY_DEPTH=$depth \ - XDUMMY_NOMODELINES=$nomodelines \ - perl > $config2 < $in -e ' - $n = 0; - $geom = $ENV{XDUMMY_GEOM}; - $depth = $ENV{XDUMMY_DEPTH}; - $nomodelines = $ENV{XDUMMY_NOMODELINES}; - $mode_str = ""; - $videoram = "24000"; - $HorizSync = "30.0 - 130.0"; - $VertRefresh = "50.0 - 250.0"; - if ($geom ne "") { - my $tmp = ""; - foreach $g (split(/,/, $geom)) { - $tmp .= "\"$g\" "; - if (!$nomodelines && $g =~ /(\d+)x(\d+)/) { - my $w = $1; - my $h = $2; - $mode_str .= " Modeline \"$g\" "; - my $dot = sprintf("%.2f", $w * $h * 70 * 1.e-6); - $mode_str .= $dot; - $mode_str .= " " . $w; - $mode_str .= " " . int(1.02 * $w); - $mode_str .= " " . int(1.10 * $w); - $mode_str .= " " . int(1.20 * $w); - $mode_str .= " " . $h; - $mode_str .= " " . int($h + 1); - $mode_str .= " " . int($h + 3); - $mode_str .= " " . int($h + 20); - $mode_str .= "\n"; - } - } - $tmp =~ s/\s*$//; - $geom = $tmp; - } - while (<>) { - if ($ENV{XDUMMY_NOTWEAK}) { - print $_; - next; - } - $n++; - if (/^\s*#/) { - # pass comments straight thru - print; - next; - } - if (/^\s*Section\s+(\S+)/i) { - # start of Section - $sect = $1; - $sect =~ s/\W//g; - $sect =~ y/A-Z/a-z/; - $sects{$sect} = 1; - print; - next; - } - if (/^\s*EndSection/i) { - # end of Section - if ($sect eq "serverflags") { - if (!$got_DontVTSwitch) { - print " ##Xdummy:##\n"; - print " Option \"DontVTSwitch\" \"true\"\n"; - } - if (!$got_AllowMouseOpenFail) { - print " ##Xdummy:##\n"; - print " Option \"AllowMouseOpenFail\" \"true\"\n"; - } - if (!$got_PciForceNone) { - print " ##Xdummy:##\n"; - print " Option \"PciForceNone\" \"true\"\n"; - } - } elsif ($sect eq "device") { - if (!$got_Driver) { - print " ##Xdummy:##\n"; - print " Driver \"dummy\"\n"; - } - if (!$got_VideoRam) { - print " ##Xdummy:##\n"; - print " VideoRam $videoram\n"; - } - } elsif ($sect eq "screen") { - if ($depth ne "" && !got_DefaultDepth) { - print " ##Xdummy:##\n"; - print " DefaultDepth $depth\n"; - } - if ($got_Monitor eq "") { - print " ##Xdummy:##\n"; - print " Monitor \"Monitor0\"\n"; - } - } elsif ($sect eq "monitor") { - if (!got_HorizSync) { - print " ##Xdummy:##\n"; - print " HorizSync $HorizSync\n"; - } - if (!got_VertRefresh) { - print " ##Xdummy:##\n"; - print " VertRefresh $VertRefresh\n"; - } - if (!$nomodelines) { - print " ##Xdummy:##\n"; - print $mode_str; - } - } - $sect = ""; - print; - next; - } - - if (/^\s*SubSection\s+(\S+)/i) { - # start of Section - $subsect = $1; - $subsect =~ s/\W//g; - $subsect =~ y/A-Z/a-z/; - $subsects{$subsect} = 1; - if ($sect eq "screen" && $subsect eq "display") { - $got_Modes = 0; - } - print; - next; - } - if (/^\s*EndSubSection/i) { - # end of SubSection - if ($sect eq "screen") { - if ($subsect eq "display") { - if ($depth ne "" && !$set_Depth) { - print " ##Xdummy:##\n"; - print " Depth\t$depth\n"; - } - if ($geom ne "" && ! $got_Modes) { - print " ##Xdummy:##\n"; - print " Modes\t$geom\n"; - } - } - } - $subsect = ""; - print; - next; - } - - $l = $_; - $l =~ s/#.*$//; - if ($sect eq "serverflags") { - if ($l =~ /^\s*Option.*DontVTSwitch/i) { - $_ =~ s/false/true/ig; - $got_DontVTSwitch = 1; - } - if ($l =~ /^\s*Option.*AllowMouseOpenFail/i) { - $_ =~ s/false/true/ig; - $got_AllowMouseOpenFail = 1; - } - if ($l =~ /^\s*Option.*PciForceNone/i) { - $_ =~ s/false/true/ig; - $got_PciForceNone= 1; - } - } - if ($sect eq "module") { - if ($l =~ /^\s*Load.*\b(dri|fbdevhw)\b/i) { - $_ = "##Xdummy## $_"; - } - } - if ($sect eq "monitor") { - if ($l =~ /^\s*HorizSync/i) { - $got_HorizSync = 1; - } - if ($l =~ /^\s*VertRefresh/i) { - $got_VertRefresh = 1; - } - } - if ($sect eq "device") { - if ($l =~ /^(\s*Driver)\b/i) { - $_ = "$1 \"dummy\"\n"; - $got_Driver = 1; - } - if ($l =~ /^\s*VideoRam/i) { - $got_VideoRam= 1; - } - } - if ($sect eq "inputdevice") { - if ($l =~ /^\s*Option.*\bDevice\b/i) { - print " ##Xdummy:##\n"; - $_ = " Option \"Device\" \"/dev/dilbert$n\"\n"; - } - } - if ($sect eq "screen") { - if ($l =~ /^\s*DefaultDepth\s+(\d+)/i) { - if ($depth ne "") { - print " ##Xdummy:##\n"; - $_ = " DefaultDepth\t$depth\n"; - } - $got_DefaultDepth = 1; - } - if ($l =~ /^\s*Monitor\s+(\S+)/i) { - $got_Monitor = $1; - $got_Monitor =~ s/"//g; - } - if ($subsect eq "display") { - if ($geom ne "") { - if ($l =~ /^(\s*Modes)\b/i) { - print " ##Xdummy:##\n"; - $_ = "$1 $geom\n"; - $got_Modes = 1; - } - } - if ($l =~ /^\s*Depth\s+(\d+)/i) { - my $d = $1; - if (!$set_Depth && $depth ne "") { - $set_Depth = 1; - if ($depth != $d) { - print " ##Xdummy:##\n"; - $_ = " Depth\t$depth\n"; - } - } - } - } - } - print; - } - if ($ENV{XDUMMY_NOTWEAK}) { - exit; - } - # create any crucial sections that are missing: - if (! exists($sects{serverflags})) { - print "\n##Xdummy:##\n"; - print "Section \"ServerFlags\"\n"; - print " Option \"DontVTSwitch\" \"true\"\n"; - print " Option \"AllowMouseOpenFail\" \"true\"\n"; - print " Option \"PciForceNone\" \"true\"\n"; - print "EndSection\n"; - } - if (! exists($sects{device})) { - print "\n##Xdummy:##\n"; - print "Section \"Device\"\n"; - print " Identifier \"Videocard0\"\n"; - print " Driver \"dummy\"\n"; - print " VideoRam $videoram\n"; - print "EndSection\n"; - } - if (! exists($sects{monitor})) { - print "\n##Xdummy:##\n"; - print "Section \"Monitor\"\n"; - print " Identifier \"Monitor0\"\n"; - print " HorizSync $HorizSync\n"; - print " VertRefresh $VertRefresh\n"; - print "EndSection\n"; - } - if (! exists($sects{screen})) { - print "\n##Xdummy:##\n"; - print "Section \"Screen\"\n"; - print " Identifier \"Screen0\"\n"; - print " Device \"Videocard0\"\n"; - if ($got_Monitor ne "") { - print " Monitor \"$got_Monitor\"\n"; - } else { - print " Monitor \"Monitor0\"\n"; - } - if ($depth ne "") { - print " DefaultDepth $depth\n"; - } else { - print " DefaultDepth 24\n"; - } - print " SubSection \"Display\"\n"; - print " Viewport 0 0\n"; - print " Depth 24\n"; - if ($got_Modes) { - ; - } elsif ($geom ne "") { - print " Modes $geom\n"; - } else { - print " Modes \"1280x1024\" \"1024x768\" \"800x600\"\n"; - } - print " EndSubSection\n"; - print "EndSection\n"; - } -'; -} - -# Work out config file and tweak it. -# -if [ "X$cmdline_config" = "X" ]; then - : -elif [ "X$cmdline_config" = "Xxdummy-builtin" ]; then - : -elif echo "$cmdline_config" | grep '/' > /dev/null; then - : -else - # ignore basename only case (let server handle it) - cmdline_config="" - notweak=1 -fi - -config=$cmdline_config - -if [ "X$notweak" = "X1" -a "X$root" = "X" -a -f "$cmdline_config" ]; then - # if not root we need to copy (but not tweak) the specified config. - XDUMMY_NOTWEAK=1 - export XDUMMY_NOTWEAK - notweak="" -fi - -if [ ! $notweak ]; then - # tweaked config will be put in $config2: - config2="" - if [ "X$config" = "X" ]; then - # use the default one: - if [ "X$stype" = "Xxorg" ]; then - config=/etc/X11/xorg.conf - else - if [ -f "/etc/X11/XF86Config-4" ]; then - config="/etc/X11/XF86Config-4" - else - config="/etc/X11/XF86Config" - fi - fi - if [ ! -f "$config" ]; then - for c in /etc/X11/xorg.conf /etc/X11/XF86Config-4 /etc/X11/XF86Config - do - if [ -f $c ]; then - config=$c - break - fi - done - fi - fi - - if [ "X$config" = "Xxdummy-builtin" ]; then - config="" - fi - - if [ ! -f "$config" ]; then - config="$XDUMMY_TMPDIR/xorg.conf" - warn "$program: using minimal built-in xorg.conf settings." - cat > $config <<END - -Section "ServerLayout" - Identifier "Layout0" - Screen 0 "Screen0" - InputDevice "Keyboard0" "CoreKeyboard" - InputDevice "Mouse0" "CorePointer" -EndSection - -Section "Files" -EndSection - -Section "Module" - Load "dbe" - Load "extmod" - Load "freetype" - Load "glx" -EndSection - -Section "InputDevice" - Identifier "Mouse0" - Driver "mouse" - Option "Protocol" "auto" - Option "Device" "/dev/psaux" - Option "Emulate3Buttons" "no" - Option "ZAxisMapping" "4 5" -EndSection - -Section "InputDevice" - Identifier "Keyboard0" - Driver "kbd" -EndSection - -Section "Monitor" - Identifier "Monitor0" - VendorName "Unknown" - ModelName "Unknown" - HorizSync 30.0 - 130.0 - VertRefresh 50.0 - 250.0 - Option "DPMS" -EndSection - -Section "Device" - Identifier "Device0" - Driver "foovideo" - VendorName "foovideo Corporation" -EndSection - -Section "Screen" - Identifier "Screen0" - Device "Device0" - Monitor "Monitor0" - DefaultDepth 24 - SubSection "Display" - Depth 24 - Modes "1280x1024" - EndSubSection -EndSection - -END - fi - - if [ -f "$config" ]; then - tweak_config $config - fi - - # now we need to get our tweaked config file onto the command line: - if [ "X$cmdline_config" = "X" ]; then - # append to cmdline (FUBAR will be substituted below.) - if [ "X$stype" = "Xxorg" ]; then - args="$args -config FUBAR" - else - args="$args -xf86config FUBAR" - fi - fi - if [ "X$config2" != "X" ]; then - # or modify $args: - c2=$config2 - if [ "X$root" = "X" ]; then - # ordinary user cannot use absolute path. - c2=`basename $config2` - fi - args=`echo "$args" | sed \ - -e "s,-config *[^ ][^ ]*,-config $c2,g" \ - -e "s,-xf86config *[^ ][^ ]*,-xf86config $c2,g"` - fi -fi - -if [ $prconf ]; then - warn "" - warn "Printing out the Xorg/XFree86 server config file:" - warn "" - if [ "X$config2" = "X" ]; then - warn "NO CONFIG GENERATED." - exit 1 - else - cat "$config2" - fi - exit 0 -fi - -if [ $debug ]; then - XDUMMY_DEBUG=1 - export XDUMMY_DEBUG -fi -if [ $root ]; then - XDUMMY_ROOT=1 - export XDUMMY_ROOT -fi - -# Finally, run it: -# -if [ "X$debug" != "X" -o "X$runit" = "X" ]; then - if [ ! $runit ]; then - echo "" - echo "/usr/bin/env:" - env | egrep -v '^(LS_COLORS|TERMCAP)' | sort - echo "" - echo "XDUMMY*:" - env | grep '^XDUMMY' | sort - echo "" - fi - warn "" - warn "The command to run is:" - warn "" - so=$SO - pwd=`pwd` - if echo "$so" | grep '^\./' > /dev/null; then - so=`echo "$so" | sed -e "s,^\.,$pwd,"` - fi - if echo "$so" | grep '/' > /dev/null; then - : - else - so="$pwd/$so" - fi - warn "env LD_PRELOAD=$so $xserver $disp $args $vt" - warn "" - if [ ! $runit ]; then - exit 0 - fi -fi - -if [ $strace ]; then - if [ "X$strace" = "X2" ]; then - ltrace -f env LD_PRELOAD=$SO $xserver $disp $args $vt - else - strace -f env LD_PRELOAD=$SO $xserver $disp $args $vt - fi -else - exec env LD_PRELOAD=$SO $xserver $disp $args $vt -fi - -exit $? - -######################################################################### - -code() { -#code_begin -#include <stdio.h> -#define O_ACCMODE 0003 -#define O_RDONLY 00 -#define O_WRONLY 01 -#define O_RDWR 02 -#define O_CREAT 0100 /* not fcntl */ -#define O_EXCL 0200 /* not fcntl */ -#define O_NOCTTY 0400 /* not fcntl */ -#define O_TRUNC 01000 /* not fcntl */ -#define O_APPEND 02000 -#define O_NONBLOCK 04000 -#define O_NDELAY O_NONBLOCK -#define O_SYNC 010000 -#define O_FSYNC O_SYNC -#define O_ASYNC 020000 - -#include <unistd.h> -#include <stdlib.h> -#include <string.h> - -#include <linux/vt.h> -#include <linux/kd.h> - -#define __USE_GNU -#include <dlfcn.h> - -static char tmpdir[4096]; -static char str1[4096]; -static char str2[4096]; - -static char devs[256][1024]; -static int debug = -1; -static int root = -1; -static int changed_uid = 0; -static int saw_fonts = 0; -static int saw_lib_modules = 0; - -static time_t start = 0; - -void check_debug(void) { - if (debug < 0) { - if (getenv("XDUMMY_DEBUG") != NULL) { - debug = 1; - } else { - debug = 0; - } - /* prevent other processes using the preload: */ - putenv("LD_PRELOAD="); - } -} -void check_root(void) { - if (root < 0) { - /* script tells us if we are root */ - if (getenv("XDUMMY_ROOT") != NULL) { - root = 1; - } else { - root = 0; - } - } -} - -void check_uid(void) { - if (start == 0) { - start = time(NULL); - if (debug) fprintf(stderr, "START: %u\n", (unsigned int) start); - return; - } else if (changed_uid == 0) { - if (saw_fonts || time(NULL) > start + 20) { - if (getenv("XDUMMY_UID")) { - int uid = atoi(getenv("XDUMMY_UID")); - if (debug) fprintf(stderr, "SETREUID: %d saw_fonts=%d\n", uid, saw_fonts); - if (uid >= 0) { - /* this will simply fail in -nonroot mode: */ - setreuid(uid, -1); - } - } - changed_uid = 1; - } - } -} - -#define CHECKIT if (debug < 0) check_debug(); \ - if (root < 0) check_root(); \ - check_uid(); - -static void set_tmpdir(void) { - char *s; - static int didset = 0; - if (didset) { - return; - } - s = getenv("XDUMMY_TMPDIR"); - if (! s) { - s = "/tmp"; - } - tmpdir[0] = '\0'; - strcat(tmpdir, s); - strcat(tmpdir, "/"); - didset = 1; -} - -static char *tmpdir_path(const char *path) { - char *str; - set_tmpdir(); - strcpy(str2, path); - str = str2; - while (*str) { - if (*str == '/') { - *str = '_'; - } - str++; - } - strcpy(str1, tmpdir); - strcat(str1, str2); - return str1; -} - -int open(const char *pathname, int flags, unsigned short mode) { - int fd; - char *store_dev = NULL; - static int (*real_open)(const char *, int , unsigned short) = NULL; - - CHECKIT - if (! real_open) { - real_open = (int (*)(const char *, int , unsigned short)) - dlsym(RTLD_NEXT, "open"); - } - - if (strstr(pathname, "lib/modules/")) { - /* not currently used. */ - saw_lib_modules = 1; - } - - if (!root) { - if (strstr(pathname, "/dev/") == pathname) { - store_dev = strdup(pathname); - } - if (strstr(pathname, "/dev/tty") == pathname && strcmp(pathname, "/dev/tty")) { - pathname = tmpdir_path(pathname); - if (debug) fprintf(stderr, "OPEN: %s -> %s (as FIFO)\n", store_dev, pathname); - /* we make it a FIFO so ioctl on it does not fail */ - unlink(pathname); - mkfifo(pathname, 0666); - } else if (0) { - /* we used to handle more /dev files ... */ - fd = real_open(pathname, O_WRONLY|O_CREAT, 0777); - close(fd); - } - } - - fd = real_open(pathname, flags, mode); - - if (debug) fprintf(stderr, "OPEN: %s %d %d fd=%d\n", pathname, flags, mode, fd); - - if (! root) { - if (store_dev) { - if (fd < 256) { - strcpy(devs[fd], store_dev); - } - free(store_dev); - } - } - - return(fd); -} - -int open64(const char *pathname, int flags, unsigned short mode) { - int fd; - - CHECKIT - if (debug) fprintf(stderr, "OPEN64: %s %d %d\n", pathname, flags, mode); - - fd = open(pathname, flags, mode); - return(fd); -} - -int rename(const char *oldpath, const char *newpath) { - static int (*real_rename)(const char *, const char *) = NULL; - - CHECKIT - if (! real_rename) { - real_rename = (int (*)(const char *, const char *)) - dlsym(RTLD_NEXT, "rename"); - } - - if (debug) fprintf(stderr, "RENAME: %s %s\n", oldpath, newpath); - - if (root) { - return(real_rename(oldpath, newpath)); - } - - if (strstr(oldpath, "/var/log") == oldpath) { - if (debug) fprintf(stderr, "RENAME: returning 0\n"); - return 0; - } - return(real_rename(oldpath, newpath)); -} - -FILE *fopen(const char *pathname, const char *mode) { - static FILE* (*real_fopen)(const char *, const char *) = NULL; - char *str; - - if (! saw_fonts) { - if (strstr(pathname, "/fonts/")) { - if (strstr(pathname, "fonts.dir")) { - saw_fonts = 1; - } else if (strstr(pathname, "fonts.alias")) { - saw_fonts = 1; - } - } - } - - CHECKIT - if (! real_fopen) { - real_fopen = (FILE* (*)(const char *, const char *)) - dlsym(RTLD_NEXT, "fopen"); - } - - if (debug) fprintf(stderr, "FOPEN: %s %s\n", pathname, mode); - - if (strstr(pathname, "xdummy_modified_xconfig.conf")) { - /* make our config appear to be in /etc/X11, etc. */ - char *q = strrchr(pathname, '/'); - if (q != NULL && getenv("XDUMMY_TMPDIR") != NULL) { - strcpy(str1, getenv("XDUMMY_TMPDIR")); - strcat(str1, q); - if (debug) fprintf(stderr, "FOPEN: %s -> %s\n", pathname, str1); - pathname = str1; - } - } - - if (root) { - return(real_fopen(pathname, mode)); - } - - str = (char *) pathname; - if (strstr(pathname, "/var/log") == pathname) { - str = tmpdir_path(pathname); - if (debug) fprintf(stderr, "FOPEN: %s -> %s\n", pathname, str); - } - return(real_fopen(str, mode)); -} - - -#define RETURN0 if (debug) \ - {fprintf(stderr, "IOCTL: covered %d 0x%x\n", fd, req);} return 0; -#define RETURN1 if (debug) \ - {fprintf(stderr, "IOCTL: covered %d 0x%x\n", fd, req);} return -1; - -int ioctl(int fd, int req, void *ptr) { - static int closed_xf86Info_consoleFd = 0; - static int (*real_ioctl)(int, int , void *) = NULL; - - CHECKIT - if (! real_ioctl) { - real_ioctl = (int (*)(int, int , void *)) - dlsym(RTLD_NEXT, "open"); - } - if (debug) fprintf(stderr, "IOCTL: %d 0x%x %p\n", fd, req, ptr); - - /* based on xorg-x11-6.8.1-dualhead.patch */ - if (req == VT_GETMODE) { - /* close(xf86Info.consoleFd) */ - if (0 && ! closed_xf86Info_consoleFd) { - /* I think better not to close it... */ - close(fd); - closed_xf86Info_consoleFd = 1; - } - RETURN0 - } else if (req == VT_SETMODE) { - RETURN0 - } else if (req == VT_GETSTATE) { - RETURN0 - } else if (req == KDSETMODE) { - RETURN0 - } else if (req == KDSETLED) { - RETURN0 - } else if (req == KDGKBMODE) { - RETURN0 - } else if (req == KDSKBMODE) { - RETURN0 - } else if (req == VT_ACTIVATE) { - RETURN0 - } else if (req == VT_WAITACTIVE) { - RETURN0 - } else if (req == VT_RELDISP) { - if (ptr == (void *) 1) { - RETURN1 - } else if (ptr == (void *) VT_ACKACQ) { - RETURN0 - } - } - - return(real_ioctl(fd, req, ptr)); -} - -typedef void (*sighandler_t)(int); -#define SIGUSR1 10 -#define SIG_DFL ((sighandler_t)0) - -sighandler_t signal(int signum, sighandler_t handler) { - static sighandler_t (*real_signal)(int, sighandler_t) = NULL; - - CHECKIT - if (! real_signal) { - real_signal = (sighandler_t (*)(int, sighandler_t)) - dlsym(RTLD_NEXT, "signal"); - } - - if (debug) fprintf(stderr, "SIGNAL: %d %p\n", signum, handler); - - if (signum == SIGUSR1) { - if (debug) fprintf(stderr, "SIGNAL: skip SIGUSR1\n"); - return SIG_DFL; - } - - return(real_signal(signum, handler)); -} - -int close(int fd) { - static int (*real_close)(int) = NULL; - - CHECKIT - if (! real_close) { - real_close = (int (*)(int)) dlsym(RTLD_NEXT, "close"); - } - - if (debug) fprintf(stderr, "CLOSE: %d\n", fd); - if (!root) { - if (fd < 256) { - devs[fd][0] = '\0'; - } - } - return(real_close(fd)); -} - -struct stat { - int foo; -}; - -int stat(const char *path, struct stat *buf) { - static int (*real_stat)(const char *, struct stat *) = NULL; - - CHECKIT - if (! real_stat) { - real_stat = (int (*)(const char *, struct stat *)) - dlsym(RTLD_NEXT, "stat"); - } - - if (debug) fprintf(stderr, "STAT: %s\n", path); - - return(real_stat(path, buf)); -} - -int stat64(const char *path, struct stat *buf) { - static int (*real_stat64)(const char *, struct stat *) = NULL; - - CHECKIT - if (! real_stat64) { - real_stat64 = (int (*)(const char *, struct stat *)) - dlsym(RTLD_NEXT, "stat64"); - } - - if (debug) fprintf(stderr, "STAT64: %s\n", path); - - return(real_stat64(path, buf)); -} - -int chown(const char *path, uid_t owner, gid_t group) { - static int (*real_chown)(const char *, uid_t, gid_t) = NULL; - - CHECKIT - if (! real_chown) { - real_chown = (int (*)(const char *, uid_t, gid_t)) - dlsym(RTLD_NEXT, "chown"); - } - - if (root) { - return(real_chown(path, owner, group)); - } - - if (debug) fprintf(stderr, "CHOWN: %s %d %d\n", path, owner, group); - - if (strstr(path, "/dev") == path) { - if (debug) fprintf(stderr, "CHOWN: return 0\n"); - return 0; - } - - return(real_chown(path, owner, group)); -} - -extern int *__errno_location (void); -#ifndef ENODEV -#define ENODEV 19 -#endif - -int ioperm(unsigned long from, unsigned long num, int turn_on) { - static int (*real_ioperm)(unsigned long, unsigned long, int) = NULL; - - CHECKIT - if (! real_ioperm) { - real_ioperm = (int (*)(unsigned long, unsigned long, int)) - dlsym(RTLD_NEXT, "ioperm"); - } - if (debug) fprintf(stderr, "IOPERM: %d %d %d\n", (int) from, (int) num, turn_on); - if (root) { - return(real_ioperm(from, num, turn_on)); - } - if (from == 0 && num == 1024 && turn_on == 1) { - /* we want xf86EnableIO to fail */ - if (debug) fprintf(stderr, "IOPERM: setting ENODEV.\n"); - *__errno_location() = ENODEV; - return -1; - } - return 0; -} - -int iopl(int level) { - static int (*real_iopl)(int) = NULL; - - CHECKIT - if (! real_iopl) { - real_iopl = (int (*)(int)) dlsym(RTLD_NEXT, "iopl"); - } - if (debug) fprintf(stderr, "IOPL: %d\n", level); - if (root) { - return(real_iopl(level)); - } - return 0; -} - -#ifdef INTERPOSE_GETUID - -/* - * we got things to work w/o pretending to be root. - * so we no longer interpose getuid(), etc. - */ - -uid_t getuid(void) { - static uid_t (*real_getuid)(void) = NULL; - CHECKIT - if (! real_getuid) { - real_getuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "getuid"); - } - if (root) { - return(real_getuid()); - } - if (debug) fprintf(stderr, "GETUID: 0\n"); - return 0; -} -uid_t geteuid(void) { - static uid_t (*real_geteuid)(void) = NULL; - CHECKIT - if (! real_geteuid) { - real_geteuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid"); - } - if (root) { - return(real_geteuid()); - } - if (debug) fprintf(stderr, "GETEUID: 0\n"); - return 0; -} -uid_t geteuid_kludge1(void) { - static uid_t (*real_geteuid)(void) = NULL; - CHECKIT - if (! real_geteuid) { - real_geteuid = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid"); - } - if (debug) fprintf(stderr, "GETEUID: 0 saw_libmodules=%d\n", saw_lib_modules); - if (root && !saw_lib_modules) { - return(real_geteuid()); - } else { - saw_lib_modules = 0; - return 0; - } -} - -uid_t getuid32(void) { - static uid_t (*real_getuid32)(void) = NULL; - CHECKIT - if (! real_getuid32) { - real_getuid32 = (uid_t (*)(void)) dlsym(RTLD_NEXT, "getuid32"); - } - if (root) { - return(real_getuid32()); - } - if (debug) fprintf(stderr, "GETUID32: 0\n"); - return 0; -} -uid_t geteuid32(void) { - static uid_t (*real_geteuid32)(void) = NULL; - CHECKIT - if (! real_geteuid32) { - real_geteuid32 = (uid_t (*)(void)) dlsym(RTLD_NEXT, "geteuid32"); - } - if (root) { - return(real_geteuid32()); - } - if (debug) fprintf(stderr, "GETEUID32: 0\n"); - return 0; -} - -gid_t getgid(void) { - static gid_t (*real_getgid)(void) = NULL; - CHECKIT - if (! real_getgid) { - real_getgid = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getgid"); - } - if (root) { - return(real_getgid()); - } - if (debug) fprintf(stderr, "GETGID: 0\n"); - return 0; -} -gid_t getegid(void) { - static gid_t (*real_getegid)(void) = NULL; - CHECKIT - if (! real_getegid) { - real_getegid = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getegid"); - } - if (root) { - return(real_getegid()); - } - if (debug) fprintf(stderr, "GETEGID: 0\n"); - return 0; -} -gid_t getgid32(void) { - static gid_t (*real_getgid32)(void) = NULL; - CHECKIT - if (! real_getgid32) { - real_getgid32 = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getgid32"); - } - if (root) { - return(real_getgid32()); - } - if (debug) fprintf(stderr, "GETGID32: 0\n"); - return 0; -} -gid_t getegid32(void) { - static gid_t (*real_getegid32)(void) = NULL; - CHECKIT - if (! real_getegid32) { - real_getegid32 = (gid_t (*)(void)) dlsym(RTLD_NEXT, "getegid32"); - } - if (root) { - return(real_getegid32()); - } - if (debug) fprintf(stderr, "GETEGID32: 0\n"); - return 0; -} -#endif - -#if 0 -/* maybe we need to interpose on strcmp someday... here is the template */ -int strcmp(const char *s1, const char *s2) { - static int (*real_strcmp)(const char *, const char *) = NULL; - CHECKIT - if (! real_strcmp) { - real_strcmp = (int (*)(const char *, const char *)) dlsym(RTLD_NEXT, "strcmp"); - } - if (debug) fprintf(stderr, "STRCMP: '%s' '%s'\n", s1, s2); - return(real_strcmp(s1, s2)); -} -#endif - -#code_end -} 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); -} diff --git a/x11vnc/misc/connect_switch b/x11vnc/misc/connect_switch deleted file mode 100755 index 08376c6..0000000 --- a/x11vnc/misc/connect_switch +++ /dev/null @@ -1,696 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) 2006-2010 by Karl J. Runge <runge@karlrunge.com> -# -# connect_switch 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. -# -# connect_switch 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 connect_switch; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see <http://www.gnu.org/licenses/>. -# -# -# connect_switch: -# -# A kludge script that sits between web clients and a mod_ssl (https) -# enabled apache webserver. -# -# If an incoming web client connection makes a proxy CONNECT request -# it is handled directly by this script (apache is not involved). -# Otherwise, all other connections are forwarded to the apache webserver. -# -# This can be useful for VNC redirection using an existing https (port -# 443) webserver, thereby not requiring a 2nd (non-https) port open on -# the firewall for the CONNECT requests. -# -# It does not seem possible (to me) to achieve this entirely within apache -# because the CONNECT request appears to be forwarded encrypted to -# the remote host and so the SSL dies immediately. -# -# It can also be used to redirect ANY protocol, e.g. SSH, not just VNC. -# See CONNECT_SWITCH_APPLY_VNC_OFFSET=0 to disable VNC 5900 shift. -# -# Note: There is no need to use this script for a non-ssl apache webserver -# port because mod_proxy works fine for doing the switching all inside -# apache (see ProxyRequests and AllowCONNECT parameters). -# -# -# Apache configuration: -# -# The mod_ssl configuration is often in a file named ssl.conf. In the -# simplest case you change something like this: -# -# From: -# -# Listen 443 -# -# <VirtualHost _default_:443> -# ... -# </VirtualHost> -# -# To: -# -# Listen 127.0.0.1:443 -# -# <VirtualHost _default_:443> -# ... -# </VirtualHost> -# -# (i.e. just change the Listen directive). -# -# If you have mod_ssl listening on a different internal port, you do -# not need to specify the localhost Listen address. -# -# It is probably a good idea to set $listen_host below to the known -# IP address you want the service to listen on (to avoid localhost where -# apache is listening). -# - -#################################################################### -# NOTE: For more info on configuration settings, read below for -# all of the CONNECT_SWITCH_* env. var. parameters. -#################################################################### - - -#################################################################### -# Allow env vars to also be specified on cmdline: -# -foreach my $arg (@ARGV) { - if ($arg =~ /^(CONNECT_SWITCH.*?)=(.*)$/) { - $ENV{$1} = $2; - } -} - -# Set up logging: -# -if (exists $ENV{CONNECT_SWITCH_LOGFILE}) { - close STDOUT; - if (!open(STDOUT, ">>$ENV{CONNECT_SWITCH_LOGFILE}")) { - die "connect_switch: $ENV{CONNECT_SWITCH_LOGFILE} $!\n"; - } - close STDERR; - open(STDERR, ">&STDOUT"); -} -select(STDERR); $| = 1; -select(STDOUT); $| = 1; - -# interrupt handler: -# -my $looppid = ''; -my $pidfile = ''; -my $listen_sock = ''; # declared here for get_out() -# -sub get_out { - print STDERR "$_[0]:\t$$ looppid=$looppid\n"; - close $listen_sock if $listen_sock; - if ($looppid) { - kill 'TERM', $looppid; - fsleep(0.2); - } - unlink $pidfile if $pidfile; - exit 0; -} -$SIG{INT} = \&get_out; -$SIG{TERM} = \&get_out; - -# pidfile: -# -sub open_pidfile { - if (exists $ENV{CONNECT_SWITCH_PIDFILE}) { - my $pf = $ENV{CONNECT_SWITCH_PIDFILE}; - if (open(PID, ">$pf")) { - print PID "$$\n"; - close PID; - $pidfile = $pf; - } else { - print STDERR "could not open pidfile: $pf - $! - continuing...\n"; - } - delete $ENV{CONNECT_SWITCH_PIDFILE}; - } -} - -#################################################################### -# Set CONNECT_SWITCH_LOOP=1 to have this script create an outer loop -# restarting itself if it ever exits. Set CONNECT_SWITCH_LOOP=BG to -# do this in the background as a daemon. - -if (exists $ENV{CONNECT_SWITCH_LOOP}) { - my $csl = $ENV{CONNECT_SWITCH_LOOP}; - if ($csl ne 'BG' && $csl ne '1') { - die "connect_switch: invalid CONNECT_SWITCH_LOOP.\n"; - } - if ($csl eq 'BG') { - # go into bg as "daemon": - setpgrp(0, 0); - my $pid = fork(); - if (! defined $pid) { - die "connect_switch: $!\n"; - } elsif ($pid) { - wait; - exit 0; - } - if (fork) { - exit 0; - } - setpgrp(0, 0); - close STDIN; - if (! $ENV{CONNECT_SWITCH_LOGFILE}) { - close STDOUT; - close STDERR; - } - } - delete $ENV{CONNECT_SWITCH_LOOP}; - - if (exists $ENV{CONNECT_SWITCH_PIDFILE}) { - open_pidfile(); - } - - print STDERR "connect_switch: starting service at ", scalar(localtime), " master-pid=$$\n"; - while (1) { - $looppid = fork; - if (! defined $looppid) { - sleep 10; - } elsif ($looppid) { - wait; - } else { - exec $0; - exit 1; - } - print STDERR "connect_switch: re-starting service at ", scalar(localtime), " master-pid=$$\n"; - sleep 1; - } - exit 0; -} -if (exists $ENV{CONNECT_SWITCH_PIDFILE}) { - open_pidfile(); -} - - -############################################################################ -# The defaults for hosts and ports (you can override them below if needed): -# -# Look below for these environment variables that let you set the various -# parameters without needing to edit this script: -# -# CONNECT_SWITCH_LISTEN -# CONNECT_SWITCH_HTTPD -# CONNECT_SWITCH_ALLOWED -# CONNECT_SWITCH_ALLOW_FILE -# CONNECT_SWITCH_VERBOSE -# CONNECT_SWITCH_APPLY_VNC_OFFSET -# CONNECT_SWITCH_VNC_OFFSET -# CONNECT_SWITCH_LISTEN_IPV6 -# CONNECT_SWITCH_BUFSIZE -# CONNECT_SWITCH_LOGFILE -# CONNECT_SWITCH_PIDFILE -# CONNECT_SWITCH_MAX_CONNECTIONS -# -# You can also set these on the cmdline: -# connect_switch CONNECT_SWITCH_LISTEN=X CONNECT_SWITCH_ALLOW_FILE=Y ... -# - -# By default we will use hostname and assume it resolves: -# -my $hostname = `hostname`; -chomp $hostname; - -my $listen_host = $hostname; -my $listen_port = 443; - -# Let user override listening situation, e.g. multihomed: -# -if (exists $ENV{CONNECT_SWITCH_LISTEN}) { - # - # E.g. CONNECT_SWITCH_LISTEN=192.168.0.32:443 - # - $listen_host = ''; - $listen_port = ''; - if ($ENV{CONNECT_SWITCH_LISTEN} =~ /^(.*):(\d+)$/) { - ($listen_host, $listen_port) = ($1, $2); - } -} - -my $httpd_host = 'localhost'; -my $httpd_port = 443; - -if (exists $ENV{CONNECT_SWITCH_HTTPD}) { - # - # E.g. CONNECT_SWITCH_HTTPD=127.0.0.1:443 - # - $httpd_host = ''; - $httpd_port = ''; - if ($ENV{CONNECT_SWITCH_HTTPD} =~ /^(.*):(\d+)$/) { - ($httpd_host, $httpd_port) = ($1, $2); - } -} - -my $bufsize = 8192; -if (exists $ENV{CONNECT_SWITCH_BUFSIZE}) { - # - # E.g. CONNECT_SWITCH_BUFSIZE=32768 - # - $bufsize = $ENV{CONNECT_SWITCH_BUFSIZE}; -} - - -############################################################################ -# You can/should override the host/port settings here: -# -#$listen_host = '23.45.67.89'; # set to your interface IP number. -#$listen_port = 555; # and/or nonstandard port. -#$httpd_host = 'somehost'; # maybe you redir https to another machine. -#$httpd_port = 666; # and/or nonstandard port. - -# You must set the allowed host:port CONNECT redirection list. -# Only these host:port pairs will be redirected to. -# Port ranges are allowed too: host:5900-5930. -# If there is one entry named ALL all connections are allow. -# You must supply something, default is deny. -# -my @allowed = qw( - machine1:5915 - machine2:5900 -); - -if (exists $ENV{CONNECT_SWITCH_ALLOWED}) { - # - # E.g. CONNECT_SWITCH_ALLOWED=machine1:5915,machine2:5900 - # - @allowed = split(/,/, $ENV{CONNECT_SWITCH_ALLOWED}); -} - -# Or you could also use an external "allow file". -# They get added to the @allowed list. -# The file is re-read for each new connection. -# -# Format of $allow_file: -# -# host1 vncdisp -# host2 vncdisp -# -# where, e.g. vncdisp = 15 => port 5915, say -# -# joesbox 15 -# fredsbox 15 -# rupert 1 - -# For examply, mine is: -# -my $allow_file = '/dist/apache/2.0/conf/vnc.hosts'; -$allow_file = ''; - -if (exists $ENV{CONNECT_SWITCH_ALLOW_FILE}) { - # E.g. CONNECT_SWITCH_ALLOW_FILE=/usr/local/etc/allow.txt - $allow_file = $ENV{CONNECT_SWITCH_ALLOW_FILE}; -} - -# Set to 1 to re-map to vnc port, e.g. 'hostname 15' to 'hostname 5915' -# i.e. assume a port 0 <= port < 200 is actually a VNC display -# and add 5900 to it. Set to 0 to not do the mapping. -# Note that negative ports, e.g. 'joesbox -22' go directly to -port. -# -my $apply_vnc_offset = 1; -my $vnc_offset = 5900; - -if (exists $ENV{CONNECT_SWITCH_APPLY_VNC_OFFSET}) { - # - # E.g. CONNECT_SWITCH_APPLY_VNC_OFFSET=0 - # - $apply_vnc_offset = $ENV{CONNECT_SWITCH_APPLY_VNC_OFFSET}; -} -if (exists $ENV{CONNECT_SWITCH_VNC_OFFSET}) { - # - # E.g. CONNECT_SWITCH_VNC_OFFSET=6000 - # - $vnc_offset = $ENV{CONNECT_SWITCH_VNC_OFFSET}; -} - -# Set to 1 or higher for more info output: -# -my $verbose = 0; - -if (exists $ENV{CONNECT_SWITCH_VERBOSE}) { - # - # E.g. CONNECT_SWITCH_VERBOSE=1 - # - $verbose = $ENV{CONNECT_SWITCH_VERBOSE}; -} - -# zero means loop forever, positive value means exit after handling that -# many connections. -# -my $cmax = 0; -if (exists $ENV{CONNECT_SWITCH_MAX_CONNECTIONS}) { - $cmax = $ENV{CONNECT_SWITCH_MAX_CONNECTIONS}; -} - - -#=========================================================================== -# No need for any changes below here. -#=========================================================================== - -use IO::Socket::INET; -use strict; -use warnings; - -# Test for INET6 support: -# -my $have_inet6 = 0; -eval "use IO::Socket::INET6;"; -$have_inet6 = 1 if $@ eq ""; - -my $killpid = 1; - -setpgrp(0, 0); - -if (exists $ENV{CONNECT_SWITCH_LISTEN_IPV6}) { - # note we leave out LocalAddr. - my $cmd = ' - $listen_sock = IO::Socket::INET6->new( - Listen => 10, - LocalPort => $listen_port, - ReuseAddr => 1, - Domain => AF_INET6, - Proto => "tcp" - ); - '; - eval $cmd; - die "$@\n" if $@; -} else { - $listen_sock = IO::Socket::INET->new( - Listen => 10, - LocalAddr => $listen_host, - LocalPort => $listen_port, - ReuseAddr => 1, - Proto => "tcp" - ); -} - -if (! $listen_sock) { - die "connect_switch: $!\n"; -} - -my $current_fh1 = ''; -my $current_fh2 = ''; - -my $conn = 0; - -while (1) { - $conn++; - if ($cmax > 0 && $conn > $cmax) { - print STDERR "last connection ($cmax)\n" if $verbose; - last; - } - print STDERR "listening for connection: $conn\n" if $verbose; - my ($client, $ip) = $listen_sock->accept(); - if (! $client) { - fsleep(0.5); - next; - } - print STDERR "conn: $conn -- ", $client->peerhost(), " at ", scalar(localtime), "\n" if $verbose; - - my $pid = fork(); - if (! defined $pid) { - die "connect_switch: $!\n"; - } elsif ($pid) { - wait; - next; - } else { - close $listen_sock; - if (fork) { - exit 0; - } - setpgrp(0, 0); - handle_conn($client); - } -} - -exit 0; - -sub handle_conn { - my $client = shift; - - my $start = time(); - - my @allow = @allowed; - - # read allow file. Note we read it for every connection - # to allow the admin to modify it w/o restarting us. - # better way would be to read in parent and check mtime. - # - if ($allow_file && -f $allow_file) { - if (open(ALLOW, "<$allow_file")) { - while (<ALLOW>) { - next if /^\s*#/; - next if /^\s*$/; - chomp; - my ($host, $dpy) = split(' ', $_); - next if ! defined $host; - next if ! defined $dpy; - if ($dpy < 0) { - $dpy = -$dpy; - } elsif ($apply_vnc_offset) { - $dpy += $vnc_offset if $dpy < 200; - } - push @allow, "$host:$dpy"; - } - close(ALLOW); - } else { - warn "$allow_file: $!\n"; - } - } - - # Read the first 7 bytes of connection, see if it is 'CONNECT' - # - my $str = ''; - my $N = 0; - my $isconn = 1; - for (my $i = 0; $i < 7; $i++) { - my $b; - sysread($client, $b, 1); - $str .= $b; - $N++; - print STDERR "read: '$str'\n" if $verbose > 1; - my $cstr = substr('CONNECT', 0, $i+1); - if ($str ne $cstr) { - $isconn = 0; - last; - } - } - - my $sock = ''; - - if ($isconn) { - # it is CONNECT, read rest of HTTP header: - # - while ($str !~ /\r\n\r\n/) { - my $b; - sysread($client, $b, 1); - $str .= $b; - } - print STDERR "read: $str\n" if $verbose > 1; - - # get http version and host:port - # - my $ok = 0; - my $hostport = ''; - my $http_vers = '1.0'; - if ($str =~ /^CONNECT\s+(\S+)\s+HTTP\/(\S+)/) { - $hostport = $1; - $http_vers = $2; - my $h = ''; - my $p = ''; - - if ($hostport =~ /^(.*):(\d+)$/) { - ($h, $p) = ($1, $2); - } - if ($p =~ /^\d+$/) { - # check allowed host list: - foreach my $hp (@allow) { - if ($hp eq 'ALL') { - $ok = 1; - } - if ($hp eq $hostport) { - $ok = 1; - } - if ($hp =~ /^(.*):(\d+)-(\d+)$/) { - my $ahost = $1; - my $pmin = $2; - my $pmax = $3; - if ($h eq $ahost) { - if ($p >= $pmin && $p <= $pmax) { - $ok = 1; - } - } - } - last if $ok; - } - } - } - - my $msg_1 = "HTTP/$http_vers 200 Connection Established\r\n" - . "Proxy-agent: connect_switch v0.2\r\n\r\n"; - my $msg_2 = "HTTP/$http_vers 502 Bad Gateway\r\n" - . "Connection: close\r\n\r\n"; - - if (! $ok) { - # disallowed. drop with message. - # - syswrite($client, $msg_2, length($msg_2)); - close $client; - exit 0; - } - - my $host = ''; - my $port = ''; - - if ($hostport =~ /^(.*):(\d+)$/) { - ($host, $port) = ($1, $2); - } - - print STDERR "connecting to: $host:$port\n" if $verbose; - - $sock = IO::Socket::INET->new( - PeerAddr => $host, - PeerPort => $port, - Proto => "tcp" - ); - print STDERR "connect to host='$host' port='$port' failed: $!\n" if !$sock; - if (! $sock && $have_inet6) { - eval {$sock = IO::Socket::INET6->new( - PeerAddr => $host, - PeerPort => $port, - Proto => "tcp" - );}; - print STDERR "connect to host='$host' port='$port' failed: $! (ipv6)\n" if !$sock; - } - my $msg; - - # send the connect proxy reply: - # - if ($sock) { - $msg = $msg_1; - } else { - $msg = $msg_2; - } - syswrite($client, $msg, length($msg)); - $str = ''; - } else { - # otherwise, redirect to apache for normal https: - # - print STDERR "connecting to: $httpd_host:$httpd_port\n" if $verbose; - $sock = IO::Socket::INET->new( - PeerAddr => $httpd_host, - PeerPort => $httpd_port, - Proto => "tcp" - ); - if (! $sock && $have_inet6) { - eval {$sock = IO::Socket::INET6->new( - PeerAddr => $httpd_host, - PeerPort => $httpd_port, - Proto => "tcp" - );}; - } - } - - if (! $sock) { - close $client; - die "connect_switch: $!\n"; - } - - # get ready for xfer phase: - # - $current_fh1 = $client; - $current_fh2 = $sock; - - $SIG{TERM} = sub {print STDERR "got sigterm\[$$]\n" if $verbose; close $current_fh1; close $current_fh2; exit 0}; - - my $parent = $$; - if (my $child = fork()) { - xfer($sock, $client, 'S->C'); - if ($killpid) { - fsleep(0.5); - kill 'TERM', $child; - } - } else { - # write those first bytes if not CONNECT: - # - if ($str ne '' && $N > 0) { - syswrite($sock, $str, $N); - } - xfer($client, $sock, 'C->S'); - if ($killpid) { - fsleep(0.75); - kill 'TERM', $parent; - } - } - if ($verbose > 1) { - my $dt = time() - $start; - print STDERR "duration\[$$]: $dt seconds. ", scalar(localtime), "\n"; - } - exit 0; -} - -sub xfer { - my($in, $out, $lab) = @_; - my ($RIN, $WIN, $EIN, $ROUT); - $RIN = $WIN = $EIN = ""; - $ROUT = ""; - vec($RIN, fileno($in), 1) = 1; - vec($WIN, fileno($in), 1) = 1; - $EIN = $RIN | $WIN; - my $buf; - - while (1) { - my $nf = 0; - while (! $nf) { - $nf = select($ROUT=$RIN, undef, undef, undef); - } - my $len = sysread($in, $buf, $bufsize); - if (! defined($len)) { - next if $! =~ /^Interrupted/; - print STDERR "connect_switch\[$lab/$conn/$$]: $!\n"; - last; - } elsif ($len == 0) { - print STDERR "connect_switch\[$lab/$conn/$$]: " - . "Input is EOF.\n"; - last; - } - - if (0) { - # very verbose debugging of data: - syswrite(STDERR , "\n$lab: ", 6); - syswrite(STDERR , $buf, $len); - } - - my $offset = 0; - my $quit = 0; - while ($len) { - my $written = syswrite($out, $buf, $len, $offset); - if (! defined $written) { - print STDERR "connect_switch\[$lab/$conn/$$]: " - . "Output is EOF. $!\n"; - $quit = 1; - last; - } - $len -= $written; - $offset += $written; - } - last if $quit; - } - close($in); - close($out); -} - -sub fsleep { - my ($time) = @_; - select(undef, undef, undef, $time) if $time; -} diff --git a/x11vnc/misc/desktop.cgi b/x11vnc/misc/desktop.cgi deleted file mode 100755 index d99a39c..0000000 --- a/x11vnc/misc/desktop.cgi +++ /dev/null @@ -1,1550 +0,0 @@ -#!/usr/bin/perl -# -########################################################################## -# desktop.cgi: -# -# This is an example CGI script to provide multi-user web access to -# x11vnc desktops. The user desktop sessions run in 'Xvfb' displays -# that are created automatically. -# -# This script should/must be served by an HTTPS (i.e. SSL) webserver, -# otherwise the unix and vnc passwords would be sent over the network -# unencrypted (see below to disable if you really want to.) -# -# The Java VNC Viewer applet connections are encrypted by SSL as well. -# -# You can use this script to provide unix users desktops available on -# demand via any Java enabled web browser. One could also use this for -# a special-purpose 'single application' service running in a minimal -# window manager. -# -# One example of a special-purpose application would be a scientific -# data visualization tool running on a server where the data is housed. -# To do this set $x11vnc_extra_opts = '-env FD_PROG=/path/to/app/launcher' -# where the program launches your special purpose application. A very -# simple example: '-env FD_PROG=/usr/bin/xclock' -# -# -# Depending on where you place this script, the user accesses the service -# with the URL: -# -# https://your.webserver.net/cgi-bin/desktop.cgi -# -# Then they login with their unix username and password to get their -# own desktop session. -# -# If the user has an existing desktop it is connected to directly, -# otherwise a new session is created inside an Xvfb display and then -# connected to by VNC. -# -# It is possible to do port redirection to other machines running SSL -# enabled VNC servers (see below.) This script does not start the VNC -# servers on the other machines, although with some extra rigging you -# should be able to do that as well. -# -# You can customize the login procedure to whatever you want by modifying -# this script, or by using ideas in this script write your own PHP, -# (for example), script. -# -########################################################################## -# Overriding default settings: -# -# If you want to override any settings in this script and do not -# want to edit this script create the assignments in a file named -# 'desktop.cgi.conf' in the same directory as desktop.cgi. It will be -# sourced after the defaults are set. The format of desktop.cgi.conf -# is simply perl statements that make the assignments. -# -# For example, if you put something like this in desktop.cgi.conf: -# -# $x11vnc = '/usr/local/bin/x11vnc'; -# -# that will set the path to the x11vnc binary to that location. Look at -# the settings below for the other variables that you can modify, for -# example one could set $allowed_users_file. -# -########################################################################## -# x11vnc: -# -# You need to install x11vnc or otherwise have it available. It is -# REQUIRED that you use x11vnc 0.9.10 or later. It won't work with -# earlier versions. See below the $x11vnc parameter that you can set -# to the full path to x11vnc. -# -########################################################################## -# Xvfb: -# -# Note that the x11vnc -create virtual desktop service used below requires -# that you install the 'Xvfb' program. On debian this is currently done -# via 'apt-get install xvfb'. -# -# If you are having trouble getting 'x11vnc -create' to work with this -# script (it can be tricky), try it manually and/or see the x11vnc FAQ -# links below. -# -########################################################################## -# Apache httpd: -# -# You should put this script in, say, a cgi-bin directory. Enable cgi -# scripts in your apache (or other httpd) config. For example, we have -# these lines (not commented): -# -# In httpd.conf: -# -# ScriptAlias /cgi-bin/ "/dist/apache/2.0/cgi-bin/" -# -# <Directory "/dist/apache/2.0/cgi-bin"> -# AllowOverride None -# Options None -# Order allow,deny -# Allow from all -# </Directory> -# -# and in ssl.conf: -# -# <Directory "/dist/apache/2.0/cgi-bin"> -# SSLOptions +StdEnvVars -# </Directory> -# -# Do not be confused by the non-standard /dist/apache/2.0 apache -# installation location that we happen to use. Yours will be different. -# -# You can test that you have CGI scripts working properly with the -# 'test-cgi' and 'printenv' scripts apache provides. -# -# Copy this file (desktop.cgi) to /dist/apache/2.0/cgi-bin and then run -# 'chmod 755 ...' on it to make it executable. -# -########################################################################## -# Applet Jar files served by apache: -# -# You will *also* need to copy the x11vnc classes/ssl/UltraViewerSSL.jar -# file to the httpd DocumentRoot to be accessible by: /UltraViewerSSL.jar -# in a URL (or change $applet_jar below or the html in $applet_html if -# you want to use a different location.) -# -# This location is relative to the apache DocumentRoot 'htdocs' directory. -# For our (non-standard location installation) that meant we copied the -# file to: -# -# /dist/apache/2.0/htdocs/UltraViewerSSL.jar -# -# (your DocumentRoot directory will be different.) -# -# The VncViewer.jar (tightvnc) will also work, but you need to change -# the $applet_jar below. You can get these jar files from the x11vnc -# tarball from: -# -# http://www.karlrunge.com/x11vnc/#downloading -# -# This script requires x11vnc 0.9.10 or later. -# -# Note that the usage mode for this script is a different from regular -# 'x11vnc -http ...' usage where x11vnc acts as a mini web server and -# serves its own applet jars. We don't use that mode for this script. -# Apache (httpd) serves the jars. -# -# -########################################################################## -# Notes and Information: -# -# Each x11vnc server created for a user login will listen on its own port -# (see below for port selection schemes.) Your firewall must let in *ALL* -# of these ports (e.g. a port range, see below for the syntax.) -# -# It is also possible, although not as reliable, to do all of this through -# a single port, see the fixed port scheme $find_free_port = 'fixed:5910' -# below. This single port mode must be different from apache's port -# (usually 443 for https) and must also be allowed in by your firewall. -# -# Note: The fixed port scheme is DISABLED by default. -# -# It is also possible to have this script act as a vnc redirector to SSL -# enabled VNC servers running on *other* machines inside your firewall -# (presumably the users' desktops) See the $enable_port_redirection -# setting below. The user provides 'username@host:port' instead of just -# 'username' when she logs in. This script doesn't start VNC servers -# on those other machines, the servers must be running there already. -# (If you want this script to start them you will need to add it -# yourself.) It is possible to provide a host:port allow list to limit -# which internal machines and ports can be redirected to. This is the -# $port_redirection_allowed_hosts parameter. -# -# Note: The vnc redirector scheme is DISABLED by default. -# -# Note there are *two* SSL certificates involved that the user may be -# asked to inspect: apache's SSL cert and x11vnc's SSL cert. This may -# confuse naive users. You may want to use the same cert for both. -# -# This script provides one example on how to provide the service. You can -# customize it to meet your needs, e.g. switch to php, newer cgi modules, -# different authentication, SQL database for user authentication, etc, -# etc. If you plan to use it in production, please examine all security -# aspects of it carefully; read the comments in the script for more info. -# -# More information and background and troubleshooting: -# -# http://www.karlrunge.com/x11vnc/faq.html#faq-xvfb -# http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-viewers -# http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-java-viewer-proxy -# http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-portal -# http://www.karlrunge.com/x11vnc/faq.html#faq-unix-passwords -# http://www.karlrunge.com/x11vnc/faq.html#faq-userlogin -# -# -# Please also read the comments below for changing specific settings. -# You can modify them in this script or by override file 'desktop.cgi.conf' - - -#------------------------------------------------------------------------- -# Copyright (c) 2010 by Karl J. Runge <runge@karlrunge.com> -# -# desktop.cgi 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. -# -# desktop.cgi 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 desktop.cgi; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see <http://www.gnu.org/licenses/>. -#------------------------------------------------------------------------- - -use strict; -use IO::Socket::INET; - -# Test for INET6 support: -# -my $have_inet6 = 0; -eval "use IO::Socket::INET6;"; -$have_inet6 = 1 if $@ eq ""; - -########################################################################## -# Path to the x11vnc program: -# -my $x11vnc = '/usr/bin/x11vnc'; - - -########################################################################## -# You can set some extra x11vnc cmdline options here: -# -my $x11vnc_extra_opts = ''; - - -########################################################################## -# Override the default x11vnc viewer connection timeout of 75 seconds: -# -my $x11vnc_timeout = ''; - - -########################################################################## -# TCP Ports: -# -# Set find_free_port to 1 (or the other modes described below) to -# autoselect a free port to use. The default is to use a port based on -# the userid number (7000 + uid). -# -my $find_free_port = 0; - -# Or specify a port range: -# -#$find_free_port = '7000-8000'; -# -# Or indicate to use a kludge to try to do everything through a SINGLE -# port. To try to avoid contention on the port, simultaneous instances -# of this script attempt to 'take turns' using it the single port. -# -#$find_free_port = 'fixed:5910'; - -# This is the starting port for 7000 + uid and also $find_free_port = 1 -# autoselection: -# -my $starting_port = 7000; - -# Listen on AF_INET6 if IO::Socket::INET6 is available. -# -my $listen_on_ipv6 = 0; - - -########################################################################## -# Port redirection mode: -# -# This is to enable port redirection mode: username@host:port. If -# username is valid, there will be a port redirection to internal machine -# host:port. Presumably there is already an SSL enabled and password -# protected VNC server running there. We don't start that VNC server. -# (You might be able to figure out a way to do this yourself.) -# -# See the next setting for an allowed hosts file. The default for port -# redirection is off. -# -my $enable_port_redirection = 0; - -# A file with allowed port redirections. The empty string '' (the -# default) means all host:port redirections would be allowed. -# -# Format of the file: A list of 'user@host:port' or 'host:port' -# entries, one per line. Port ranges, e.g. host:n-m are also accepted. -# -# Leading and trailing whitespace is trimmed off each line. Blank lines -# and comment lines starting with '#' are skipped. A line consisting of -# 'ALL' matches everything. If no match can be found or the file cannot -# be opened the connection is dropped. -# -my $port_redirection_allowed_hosts = ''; - - -########################################################################## -# Allowed users: -# -# To limit which users can use this service, set the following to a file -# that contains the allowed user names one per line. Lines starting with -# the '#' character are skipped. -# -my $allowed_users_file = ''; - - -########################################################################## -# Denied users: -# -# As with $allowed_users_file, but to deny certain users. Applied after -# any $allowed_users_file check and overrides the result. -# -my $denied_users_file = ''; - - -########################################################################## -# trustUrlVncCert applet parameter: -# -# Set to 0 to have the java applet html set the parameter -# trustUrlVncCert=no, i.e. the applet will not automatically accept -# an SSL cert already accepted by an HTTPS URL. See $applet_html and -# print_applet_html() below for more info. -# -my $trustUrlVncCert = 1; - - -########################################################################## -# One-time VNC password fifo: -# -# For extra security against local untrusted users a fifo is used -# to copy the one-time VNC password to the user's VNC password file -# ~user/x11vnc.pw. If that fifo transfer technique causes problems, -# you can set this value to 1 to disable the security feature: -# -my $disable_vnc_passwd_fifo_safety = 0; - - -########################################################################## -# Comment this out if you don't want PATH modified: -# -$ENV{PATH} = "/usr/bin:/bin:$ENV{PATH}"; - - -########################################################################## -# For the next two settings, note that most users will be confused that -# geometry and session are ignored when they are returning to their -# existing desktop session (x11vnc FINDDISPLAY action.) - - -########################################################################## -# Used below if user did not specify preferred geometry and color depth: -# -my $default_geometry = '1024x768x24'; - - -# Set this to the list of x11vnc -create sessions types to show a session -# dropdown for the user to select from. -# -my $session_types = ''; -# -# example: -#$session_types = 'gnome kde xfce lxde wmaker enlightenment mwm twm failsafe'; - - -########################################################################## -# Set this to 1 to enable user setting a unique tag for each one -# of his desktops and so can have multiple ones simultaneously and -# select which one he wants. For now we just hack this onto geometry -# 1024x768x24:my_2nd_desktop but ultimately there should be a form entry -# for it. Search for enable_unique_tags for more info: -# -my $enable_unique_tags = 0; -my $unique_tag = ''; - - -########################################################################## -# String of HTML for the login form: -# -# Feel free to customize to your taste, _USERNAME_ and _GEOMETRY_ are -# expanded to that of the request. -# -my $login_str = <<"END"; -<title>x11vnc web access</title> -<h3>x11vnc web access</h3> -<form action="$ENV{REQUEST_URI}" method="post"> - <table border="0"> - <tr><td colspan=2><h2>Login</h2></td></tr> - <tr><td>Username:</td><td> - <input type="text" name="username" maxlength="40" value="_USERNAME_"> - </td></tr> - <tr><td>Password:</td><td> - <input type="password" name="password" maxlength="50"> - </td></tr> - <tr><td>Geometry:</td><td> - <input type="text" name="geometry" maxlength="40" value="_GEOMETRY_"> - </td></tr> - <!-- session --> - <tr><td colspan="2" align="right"> - <input type="submit" name="submit" value="Login"> - </td></tr> - </table> -</form> -END - - -########################################################################## -# String of HTML returned to web browser to launch applet: -# -# Feel free to customize to your taste, _UID_, _VNC_PORT_, _WIDTH_, -# _HEIGHT_, _PASS_, _TRUST_UVC_, _APPLET_JAR_, and _APPLET_CLASS_ are -# expanded to the appropriate values before sending out to the browser. -# -my $applet_html = <<"END"; -<html> -<TITLE> -x11vnc desktop (_UID_/_VNC_PORT_) -</TITLE> -<APPLET CODE=_APPLET_CLASS_ ARCHIVE=_APPLET_JAR_ WIDTH=_WIDTH_ HEIGHT=_HEIGHT_> -<param name=PORT value=_VNC_PORT_> -<param name=VNCSERVERPORT value=_VNC_PORT_> -<param name=PASSWORD value=_PASS_> -<param name=trustUrlVncCert value=_TRUST_UVC_> -<param name="Open New Window" value=yes> -<param name="Offer Relogin" value=no> -<param name="ignoreMSLogonCheck" value=yes> -<param name="delayAuthPanel" value=yes> -<!-- extra --> -</APPLET> -<br> -<a href="$ENV{REQUEST_URI}">Login page</a><br> -<a href=http://www.karlrunge.com/x11vnc>x11vnc website</a> -</html> -END - - -########################################################################## -# These java applet strings are expanded into the above $applet_html. -# Note that $applet_jar is relative to your apache DocumentRoot (htdocs) -# not the filesystem root. -# -my $applet_jar = '/UltraViewerSSL.jar'; -my $applet_class = 'VncViewer.class'; - -# These make the applet panel smaller because we use 'Open New Window' -# anyway (set to 'W' or 'H' to use actual session geometry values): -# -my $applet_width = '400'; -my $applet_height = '300'; - -# To customize ALL of the HTML printed out you may need to redefine -# the bye() subtroutine in your desktop.cgi.conf file. - - -########################################################################## -# Override any of the above settings by setting them in a file named -# 'desktop.cgi.conf'. It is sourced here. -# -# You can override any variable set above by supplying perl code -# in $0.conf that sets it to the desired value. -# -# Some examples you could put in $0.conf: -# -# $x11vnc = '/usr/local/bin/x11vnc'; -# $x11vnc_extra_opts = '-env FD_PROG=/usr/bin/xclock'; -# $x11vnc_extra_opts = '-ssl /usr/local/etc/dtcgi.pem'; -# $find_free_port = 'fixed:5999'; -# $enable_port_redirection = 1; -# $allowed_users_file = '/usr/local/etc/dtcgi.allowed'; -# -if (-f "$0.conf") { - eval `cat "$0.conf"`; -} - - -########################################################################## -# END OF MAIN USER SETTINGS. -# Only power users should change anything below. -########################################################################## - -# Print http header reply: -# -print STDOUT "Content-Type: text/html\r\n\r\n"; - - -# Require HTTPS so that unix and vnc passwords are not sent in clear text -# (perhaps it is too late...) Disable HTTPS here at your own risk. -# -if ($ENV{HTTPS} !~ /^on$/i) { - bye("HTTPS must be used (to encrypt passwords)"); -} - - -# Read URL request: -# -my $request; -if ($ENV{'REQUEST_METHOD'} eq "POST") { - read(STDIN, $request, $ENV{'CONTENT_LENGTH'}); -} elsif ($ENV{'REQUEST_METHOD'} eq "GET" ) { - $request = $ENV{'QUERY_STRING'}; -} else { - $request = $ARGV[0]; -} - -my %request = url_decode(split(/[&=]/, $request)); - - -# Experiment for FD_TAG x11vnc feature for multiple desktops for a -# single user: -# -# we hide it in geometry:tag for now: -# -if ($enable_unique_tags && $request{geometry} =~ /^(.*):(\w+)$/) { - $request{geometry} = $1; - $unique_tag = $2; -} - -# Check/set geometry and session: -# -if (!exists $request{geometry} || $request{geometry} !~ /^[x\d]+$/) { - # default geometry and depth: - $request{geometry} = $default_geometry; -} -if (!exists $request{session} || $request{session} =~ /^\s*$/) { - $request{session} = ''; -} - - -# Expand _USERNAME_ and _GEOMETRY_ in the login string HTML: -# -$login_str =~ s/_USERNAME_/$request{username}/g; -$login_str =~ s/_GEOMETRY_/$request{geometry}/g; - - -# Check x11vnc version for installers of this script who do not know -# how to read and follow instructions: -# -my $version = (split(' ', `$x11vnc -version`))[1]; -$version =~ s/\D*$//; - -my ($major, $minor, $micro) = split(/\./, $version); -if ($major !~ /^\d+$/ || $minor !~ /^\d+$/) { - bye("The x11vnc program is not installed correctly."); -} -$micro = 0 unless $micro; -my $level = $major * 100 * 100 + $minor * 100 + $micro; -my $needed = 0 * 100 * 100 + 9 * 100 + 10; -if ($level < $needed) { - bye("x11vnc version 0.9.10 or later is required. (Found version $version)"); -} - - -# Set up user selected desktop session list, if enabled: -# -my %sessions; - -if ($session_types ne '') { - my $str = "<tr><td>Session:</td><td>\n<select name=session>"; - $str .= "<option value=none>select</option>"; - - foreach my $sess (split(' ', $session_types)) { - next if $sess =~ /^\s*$/; - next if $sess !~ /^\w+$/; # alphanumeric - $sessions{$sess} = 1; - $str .= "<option value=$sess>$sess</option>"; - } - $str .= "</select>\n</td></tr>"; - - # This forces $request{session} to be a valid one: - # - if (! exists $sessions{$request{session}}) { - $request{session} = 'none'; - } - - # Insert into login_str: - # - my $r = $request{session}; - $str =~ s/option value=\Q$r\E/option selected value=$r/; - $login_str =~ s/<!-- session -->/$str/; -} - - -# If no username or password, show login form: -# -if (!$request{username} && !$request{password}) { - bye($login_str); -} elsif (!$request{username}) { - bye("No Username.<p>$login_str"); -} elsif (!$request{password}) { - bye("No Password.<p>$login_str"); -} - - -# Some shorthand names: -# -my $username = $request{username}; -my $password = $request{password}; -my $geometry = $request{geometry}; -my $session = $request{session}; - - -# If port redirection is enabled, split username@host:port -# -my $redirect_host = ''; -my $current_fh1 = ''; -my $current_fh2 = ''; - -if ($enable_port_redirection) { - ($username, $redirect_host) = split(/@/, $username, 2); - if ($redirect_host ne '') { - # will exit if the redirection is not allowed: - check_redirect_host(); - } -} - -# If there is an $allowed_users_file, check username against it: -# -if ($allowed_users_file ne '') { - if (! open(USERS, "<$allowed_users_file")) { - bye("Internal Error #0"); - } - my $ok = 0; - while (<USERS>) { - chomp; - $_ =~ s/^\s*//; - $_ =~ s/\s*$//; - next if /^#/; - if ($username eq $_) { - $ok = 1; - } - } - close USERS; - if (! $ok) { - bye("Denied Username.<p>$login_str"); - } -} - -# If there is a $denied_users_file, check username against it: -# -if ($denied_users_file ne '') { - if (! open(USERS, "<$denied_users_file")) { - bye("Internal Error #0"); - } - my $ok = 1; - while (<USERS>) { - chomp; - $_ =~ s/^\s*//; - $_ =~ s/\s*$//; - next if /^#/; - if ($username eq $_) { - $ok = 0; - } - } - close USERS; - if (! $ok) { - bye("Denied Username.<p>$login_str"); - } -} - -# Require username to be alphanumeric + '-' + '_': -# (one may want to add '.' as well) -# -if ($username !~ /^\w[-\w]*$/) { - bye("Invalid Username.<p>$login_str"); -} - - -# Get the userid number, we may use it as his VNC display port; this -# also checks if the username exists: -# -my $uid = `/usr/bin/id -u '$username'`; -chomp $uid; -if ($? != 0 || $uid !~ /^\d+$/) { - bye("Invalid Username.<p>$login_str"); -} - - -# Use x11vnc trick to check if the unix password is valid: -# (requires x11vnc 0.9.10 or later.) -# -if (!open(X11VNC, "| $x11vnc -unixpw \%stdin > /dev/null")) { - bye("Internal Error #1"); -} -print X11VNC "$username:$password\n"; - -if (!close X11VNC) { - # x11vnc returns non-zero for invalid username+password: - bye("Invalid Password.<p>$login_str"); -} - - -# Initialize random number generator for use below: -# -initialize_random(); - - -# Set vnc port: -# -my $vnc_port = 0; -my $fixed_port = 0; - -if (! $find_free_port) { - # Fixed port based on userid (we assume it is free): - # - $vnc_port = $starting_port + $uid; - -} elsif ($find_free_port =~ /^fixed:(\d+)$/) { - # - # Enable the -loopbg method that tries to share a single port: - # - $vnc_port = $1; - $fixed_port = 1; -} else { - # Autoselect a port, either default range (7000-8000) or a user - # supplied range. (note that $find_free_port will now contain - # a socket listening on the found port so that it is held.) - # - $vnc_port = auto_select_port(); -} - -# Check for crazy port value: -# -if ($vnc_port > 64000 || $vnc_port < 1) { - bye("Internal Error #2 $vnc_port"); -} - - -# If port redirection is enabled and the user selected it via -# username@host:port, we do that right now and then exit. -# -if ($enable_port_redirection && $redirect_host ne '') { - port_redir(); - exit 0; -} - - -# Make a random, onetime vnc password: -# -my $pass = ''; -my $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; -my @abc = split(//, $chars); - -for (my $i = 0; $i < 8; $i++) { - $pass .= $abc[ rand(scalar(@abc)) ]; -} - -# Use x11vnc trick to switch to user and store vnc pass in the passwdfile. -# Result is $pass is placed in user's $HOME/x11vnc.pw -# -# (This is actually difficult to do without untrusted LOCAL users being -# able to see the pass as well, see copy_password_to_user() for details -# on how we try to avoid this.) -# -copy_password_to_user($pass); - - -# Make a tmp file for x11vnc launcher script: -# -my $tmpfile = `/bin/mktemp /tmp/desktop.cgi.XXXXXX`; -chomp $tmpfile; - -# Check if the tmpfile is valid: -# -if (! -e $tmpfile || ! -o $tmpfile || -l $tmpfile) { - unlink $tmpfile; - bye("Internal Error #3"); -} -if (!chmod 0644, $tmpfile) { - unlink $tmpfile; - bye("Internal Error #4"); -} -if (!open(TMP, ">$tmpfile")) { - unlink $tmpfile; - bye("Internal Error #5"); -} - - -# The x11vnc command. You adjust it to suit your needs. -# -# some ideas: -env FD_PROG=/usr/bin/gnome-session -# -env FD_SESS=kde -# -env FD_TAG=my_2nd_desktop -# -ultrafilexfer -# -# Note that -timeout will cause it to exit if client does not connect -# and -sslonly disables VeNCrypt SSL connections. - -# Some settings: -# (change these if you encounter timing problems, etc.) -# -my $timeout = 75; -my $extra = ''; -if ($fixed_port) { - # settings for fixed port case: - $timeout = 45; - $extra .= " -loopbg100,1"; -} -$timeout = $x11vnc_timeout if $x11vnc_timeout ne ''; - -if ($session_types ne '') { - # settings for session selection case: - if (exists $sessions{$session}) { - $extra .= " -env FD_SESS='$session'"; - } -} -if ($enable_unique_tags && $unique_tag ne '' && $unique_tag =~ /^\w+$/) { - $extra .= " -env FD_TAG='$unique_tag'"; -} - -# This md5sum check of the vnc passwd is for extra safety (see -# copy_password_to_user for details.) -# -my $md5sum = ''; -system("type md5sum > /dev/null"); -if ($? == 0) { - my $md5 = `/bin/mktemp /tmp/desktop.cgi.XXXXXX`; - chomp $md5; - # compute md5sum of password: - if (-o $md5 && open(MD5, "| md5sum > $md5")) { - print MD5 "$pass\n"; - close MD5; - if (open(MD5, "<$md5")) { - # read it: - my $line = <MD5>; - close MD5; - my ($s, $t) = split(' ', $line); - if (length($s) >= 32 && $s =~ /^\w+$/) { - # shell code for user to check he has correct passwd: - $md5sum = "if md5sum \$HOME/x11vnc.pw | grep '$s' > /dev/null; then true; else exit 1; fi"; - } - } - } - unlink $md5; -} - -# Write x11vnc command to the tmp file: -# -print TMP <<"END"; -#!/bin/sh -export PATH=/usr/bin:/bin:\$PATH -$md5sum -$x11vnc -sigpipe ignore:HUP -nopw -rfbport $vnc_port \\ - -passwdfile \$HOME/x11vnc.pw -oa \$HOME/x11vnc.log \\ - -create -ssl SAVE -sslonly -env FD_GEOM=$geometry \\ - -timeout $timeout $extra $x11vnc_extra_opts \\ - >/dev/null 2>/dev/null </dev/null & -sleep 2 -exit 0 -END - -close TMP; - -# Now launch x11vnc to switch to user and run the wrapper script: -# (this requires x11vnc 0.9.10 or later.) -# -$ENV{UNIXPW_CMD} = "/bin/sh $tmpfile"; - -# For the fixed port scheme we try to cooperate via lock file: -# (disabled by default.) -# -my $rmlock = ''; -# -if ($fixed_port) { - # try to grab the fixed port for the next 90 secs removing stale - # locks older than 60 secs: - # - $rmlock = lock_fixed_port(90, 60); -} - -# Start the x11vnc cmd: -# -if (!open(X11VNC, "| $x11vnc -unixpw \%stdin > /dev/null")) { - unlink $tmpfile; - unlink $rmlock if $rmlock; - bye("Internal Error #6"); -} - -select(X11VNC); $| = 1; select(STDOUT); - -# Close any port we held. There is still a gap of time between now -# and when when x11vnc in $tmpfile reopens the port after the password -# authentication. So another instance of this script could accidentally -# think it is free... -# -sleep 1; -close $find_free_port if $find_free_port; - -print X11VNC "$username:$password\n"; -close X11VNC; # note we ignore return value. -unlink $tmpfile; - -if ($rmlock) { - # let our x11vnc proceed a bit before removing lock. - sleep 2; - unlink $rmlock; -} - -# Return html for the java applet to connect to x11vnc. -# -print_applet_html(); - -exit 0; - -################################################################# -# Subroutines: - -# print the message to client and exit with success. -# -sub bye { - my $msg = shift; - print STDOUT "<html>$msg</html>\n"; - exit 0; -} - -# decode %xx to character: -# -sub url_decode { - foreach (@_) { - tr/+/ /; - s/%(..)/pack("c",hex($1))/ge; - } - @_; -} - -# seed random -# -sub initialize_random { - my $rbytes = ''; - if (open(RAN, "</dev/urandom")) { - read(RAN, $rbytes, 8); - } elsif (open(RAN, "</dev/random")) { - read(RAN, $rbytes, 8); - } else { - $rbytes = sprintf("%08d", $$); - } - close RAN; - - # set seed: - # - my $seed = join('', unpack("C8", $rbytes)); - $seed = substr($seed, -9); - srand($seed); - - for (my $i = 0; $i < ($$ % 4096); $i++) { - # Mix it up even a little bit more. There should be - # over 1 billion possible vnc passwords now. - rand(); - } -} - -# Autoselect a port for vnc. Note that a socket for the found port -# is kept open (and stored in $find_free_port) until we call x11vnc at -# the end. -# -sub auto_select_port { - my $pmin = $starting_port; # default range 7000-8000. - my $pmax = $starting_port + 1000; - - if ($find_free_port =~ /^(\d+)-(\d+)$/) { - # user supplied a range: - $pmin = $1; - $pmax = $2; - if ($pmin > $pmax) { - ($pmin, $pmax) = ($pmax, $pmin); - } - } elsif ($find_free_port > 1024) { - # user supplied a starting port: - $pmin = $find_free_port; - $pmax = $pmin + 1000; - } - - # Try to add a bit of randomness to the starting port so - # simultaneous instances of this script won't be fooled by the gap - # of time before x11vnc reopens the port (see near the bottom.) - # - my $dp = int(rand(1.0) * 0.25 * ($pmax - $pmin)); - if ($pmin + $dp < $pmax - 20) { - $pmin = $pmin + $dp; - } - - my $port = 0; - - # Now try to find a free one: - # - for (my $p = $pmin; $p <= $pmax; $p++) { - my $sock = ''; - if ($have_inet6 && $listen_on_ipv6) { - eval {$sock = IO::Socket::INET6->new( - Listen => 1, - LocalPort => $p, - ReuseAddr => 1, - Domain => AF_INET6, - LocalAddr => "::", - Proto => "tcp" - );}; - } else { - $sock = IO::Socket::INET->new( - Listen => 1, - LocalPort => $p, - ReuseAddr => 1, - Proto => "tcp" - ); - } - if ($sock) { - # we will keep this open until we call x11vnc: - $find_free_port = $sock; - $port = $p; - last; - } - } - return $port; -} - -# Since apache typically runs as user 'apache', 'nobody', etc, and not -# as root it is tricky for us to copy the pass string to a file owned by -# the user without some other untrusted local user being able to learn -# the password (e.g. via reading a file or watching ps.) Note that with -# the x11vnc -unixpw trick we unfortunately can't use a pipe because -# the user command is run in its own tty. -# -# The best way would be a sudo action or a special setuid program for -# copying. So consider doing that and thereby simplify this function. -# -# Short of a special program doing this, we use a fifo so ONLY ONE -# process can read the password. If the untrusted local user reads it, -# then the logging-in user's x11vnc won't get it. The login and x11vnc -# will fail, but the untrusted user won't gain access to the logging-in -# user's desktop. -# -# So here we start long, tedious work carefully managing the fifo. -# -sub copy_password_to_user { - - my $pass = shift; - - my $use_fifo = ''; - - # Find a command to make a fifo: - # - system("type mkfifo > /dev/null"); - if ($? == 0) { - $use_fifo = 'mkfifo %s'; - } else { - system("type mknod > /dev/null"); - if ($? == 0) { - $use_fifo = 'mknod %s p'; - } - } - - # Create the filename for our fifo: - # - my $fifo = `/bin/mktemp /tmp/desktop.cgi.XXXXXX`; - chomp $fifo; - - if (! -e $fifo || ! -o $fifo || -l $fifo) { - unlink $fifo; - bye("Internal Error #7"); - } - - # disable fifo safety if requested: - # - if ($disable_vnc_passwd_fifo_safety) { - $use_fifo = ''; - } - - # Make the fifo: - # - if ($use_fifo) { - $use_fifo = sprintf($use_fifo, $fifo); - - # there is a small race here: - system("umask 077; rm -f $fifo; $use_fifo; chmod 600 $fifo"); - - if (!chmod 0600, $fifo) { - # we chmod once more.. - unlink $fifo; - bye("Internal Error #8"); - } - - if (! -o $fifo || ! -p $fifo || -l $fifo) { - # but we get out if not owned by us anymore: - unlink $fifo; - bye("Internal Error #9"); - } - } - - # Build cmd for user to read our fifo: - # - my $upw = '$HOME/x11vnc.pw'; - $ENV{UNIXPW_CMD} = "touch $upw; chmod 600 $upw; cat $fifo > $upw"; - - # Start it: - # - if (!open(X11VNC, "| $x11vnc -unixpw \%stdin > /dev/null")) { - unlink $fifo; - bye("Internal Error #10"); - } - select(X11VNC); $| = 1; select(STDOUT); - - if (! $use_fifo) { - # regular file, we need to write it now. - if (!open(FIFO, ">$fifo")) { - close X11VNC; - unlink $fifo; - bye("Internal Error #11"); - } - print FIFO "$pass\n"; - close FIFO; - } - - # open fifo up for reading. - # (this means the bad guy can read it too.) - # - if (!chmod 0644, $fifo) { - unlink $fifo; - bye("Internal Error #12"); - } - - # send the user's passwd now: - # - print X11VNC "$username:$password\n"; - - if ($use_fifo) { - # wait a bit for the cat $fifo to start, reader will block. - sleep 1; - if (!open(FIFO, ">$fifo")) { - close X11VNC; - unlink $fifo; - bye("Internal Error #13"); - } - # here it goes: - print FIFO "$pass\n"; - close FIFO; - } - close X11VNC; # note we ignore return value. - fsleep(0.5); - unlink $fifo; - - # Done! -} - -# For fixed, single port mode. Try to open and lock the port before -# proceeding. -# -sub lock_fixed_port { - my ($t_max, $t_age) = @_; - - # lock file name: - # - my $lock = '/tmp/desktop.cgi.lock'; - my $remove = ''; - - my $t = 0; - my $sock = ''; - - while ($t < $t_max) { - if (-e $lock) { - # clean out stale locks if possible: - if (! -l $lock) { - unlink $lock; - } else { - my ($pid, $time) = split(/:/, readlink($lock)); - if (! -d "/proc/$pid") { - unlink $lock; - } - if (time() > $time + $t_age) { - unlink $lock; - } - } - } - - my $reason = ''; - - if (-l $lock) { - # someone has locked it. - $reason = 'locked'; - } else { - # unlocked, try to listen on port: - if ($have_inet6 && $listen_on_ipv6) { - eval {$sock = IO::Socket::INET6->new( - Listen => 1, - LocalPort => $vnc_port, - ReuseAddr => 1, - Domain => AF_INET6, - LocalAddr => "::", - Proto => "tcp" - );}; - } else { - $sock = IO::Socket::INET->new( - Listen => 1, - LocalPort => $vnc_port, - ReuseAddr => 1, - Proto => "tcp" - ); - } - if ($sock) { - # we got it, now try to lock: - my $str = "$$:" . time(); - if (symlink($str, $lock)) { - $remove = $lock; - $find_free_port = $sock; - last; - } - # wow, we didn't lock it... - $reason = "symlink failed: $!"; - close $sock; - } else { - $reason = "listen failed: $!"; - } - } - # sleep a bit and then try again: - # - print STDERR "$$ failed to get fixed port $vnc_port for $username at $t ($reason)\n"; - $sock = ''; - $t += 5; - sleep 5; - } - if (! $sock) { - bye("Failed to lock fixed TCP port. Try again a bit later.<p>$login_str"); - } - print STDERR "$$ got fixed port $vnc_port for $username at $t\n"; - - # Return the file to remove, if any: - # - return $remove; -} - - -# Return html for the java applet to connect to x11vnc. -# -# N.B. Please examine the applet params, e.g. trustUrlVncCert=yes to -# see if you agree with them. See x11vnc classes/ssl/README for all -# parameters. -# -# Note how we do not take extreme care to authenticate the server to -# the client applet (but note that trustUrlVncCert=yes is better than -# trustAllVncCerts=yes) One can tighten all of this up at the expense -# of extra certificate dialogs (assuming the user bothers to check...) -# -# This assumes /UltraViewerSSL.jar is at document root; you need to put -# it there. -# -sub print_applet_html { - my ($W, $H, $D) = split(/x/, $geometry); - - # make it smaller since we 'Open New Window' below anyway. - if ($applet_width ne 'W') { - $W = $applet_width; - } - if ($applet_height ne 'H') { - $H = $applet_height; - } - - my $tUVC = ($trustUrlVncCert ? 'yes' : 'no'); - - # see $applet_html set in defaults section for more info: - # - my $str = $applet_html; - - $str =~ s/_UID_/$uid/g; - $str =~ s/_VNC_PORT_/$vnc_port/g; - $str =~ s/_WIDTH_/$W/g; - $str =~ s/_HEIGHT_/$H/g; - $str =~ s/_PASS_/$pass/g; - $str =~ s/_APPLET_JAR_/$applet_jar/g; - $str =~ s/_APPLET_CLASS_/$applet_class/g; - $str =~ s/_TRUST_UVC_/$tUVC/g; - - if ($enable_port_redirection && $redirect_host ne '') { - $str =~ s/name=PASSWORD value=.*>/name=NOT_USED value=yes>/i; - #$str =~ s/<!-- extra -->/<!-- extra -->\n<param name="ignoreProxy" value=yes>/; - } - - print $str; -} - -########################################################################## -# The following subroutines are for port redirection only, which is -# disabled by default ($enable_port_redirection == 0) -# -sub port_redir { - # To aid in avoiding zombies: - # - setpgrp(0, 0); - - # For the fixed port scheme we try to cooperate via lock file: - # - my $rmlock = ''; - # - if ($fixed_port) { - # try to grab the fixed port for the next 90 secs removing - # stale locks older than 60 secs: - # - $rmlock = lock_fixed_port(90, 60); - - } elsif ($find_free_port eq '0') { - if ($have_inet6 && $listen_on_ipv6) { - eval {$find_free_port = IO::Socket::INET6->new( - Listen => 1, - LocalPort => $vnc_port, - ReuseAddr => 1, - Domain => AF_INET6, - LocalAddr => "::", - Proto => "tcp" - );}; - } else { - $find_free_port = IO::Socket::INET->new( - Listen => 1, - LocalPort => $vnc_port, - ReuseAddr => 1, - Proto => "tcp" - ); - } - } - # In all cases, at this point $find_free_port is the listening - # socket. - - # fork a helper process to do the port redir: - # - # Actually we need to spawn 4(!) of them in case the proxy check - # /check.https.proxy.connection (it is by default) and the other - # test connections. Spawn one for each expected connection, for - # whatever applet parameter usage mode you set up. - # - for (my $n = 1; $n <= 4; $n++) { - my $pid = fork(); - if (! defined $pid) { - bye("Internal Error #14"); - } elsif ($pid) { - wait; - } else { - if (fork) { - exit 0; - } - setpgrp(0, 0); - handle_conn(); - exit 0; - } - } - - # We now close the listening socket: - # - close $find_free_port; - - if ($rmlock) { - # let our process proceed a bit before removing lock. - sleep 1; - unlink $rmlock; - } - - # Now send html to the browser so it can connect: - # - print_applet_html(); - - exit 0; -} - -# This checks the validity of a username@host:port for the port -# redirection mode. Finishes and exits if it is invalid. -# -sub check_redirect_host { - # First check that the host:port string is valid: - # - if ($redirect_host !~ /^\w[-\w\.]*:\d+$/) { - bye("Invalid Redirect Host:Port.<p>$login_str"); - } - # Second, check if the allowed host file permits it: - # - if ($port_redirection_allowed_hosts ne '') { - if (! open(ALLOWED, "<$port_redirection_allowed_hosts")) { - bye("Internal Error #15"); - } - my $ok = 0; - while (my $line = <ALLOWED>) { - chomp $line; - # skip blank lines and '#' comments: - next if $line =~ /^\s*$/; - next if $line =~ /^\s*#/; - - # trim spaces from ends: - $line =~ s/^\s*//; - $line =~ s/\s*$//; - - # collect host:ports in case port range given: - my @items; - if ($line =~ /^(.*):(\d+)-(\d+)$/) { - # port range: - my $host = $1; - my $pmin = $2; - my $pmax = $3; - for (my $p = $pmin; $p <= $pmax; $p++) { - push @items, "$host:$p"; - } - } else { - push @items, $line; - } - - # now check each item for a match: - foreach my $item (@items) { - if ($item eq 'ALL') { - $ok = 1; - last; - } elsif ($item =~ /@/) { - if ("$username\@$redirect_host" eq $item) { - $ok = 1; - last; - } - } elsif ($redirect_host eq $item) { - $ok = 1; - last; - } - } - # got a match: - last if $ok; - } - close ALLOWED; - - if (! $ok) { - bye("Disallowed Redirect Host:Port.<p>$login_str"); - } - } -} - -# Much of this code is borrowed from 'connect_switch': -# -# (it only applies to the vnc redirector $enable_port_redirection mode -# which is off by default.) -# -sub handle_conn { - close STDIN; - close STDOUT; - close STDERR; - - $SIG{ALRM} = sub {close $find_free_port; exit 0}; - - # We only wait 30 secs for the redir case, esp. since - # we need to spawn so many helpers... - # - alarm(30); - - my ($client, $ip) = $find_free_port->accept(); - - alarm(0); - - close $find_free_port; - - if (!$client) { - exit 1; - } - - my $host = ''; - my $port = ''; - if ($redirect_host =~ /^(.*):(\d+)$/) { - ($host, $port) = ($1, $2); - } - - my $sock = IO::Socket::INET->new( - PeerAddr => $host, - PeerPort => $port, - Proto => "tcp" - ); - if (! $sock && $have_inet6) { - eval {$sock = IO::Socket::INET6->new( - PeerAddr => $host, - PeerPort => $port, - Proto => "tcp" - );}; - } - - if (! $sock) { - close $client; - exit 1; - } - - $current_fh1 = $client; - $current_fh2 = $sock; - - $SIG{TERM} = sub {close $current_fh1; close $current_fh2; exit 0}; - - my $killpid = 1; - - my $parent = $$; - if (my $child = fork()) { - xfer($sock, $client, 'S->C'); - if ($killpid) { - fsleep(0.5); - kill 'TERM', $child; - } - } else { - xfer($client, $sock, 'C->S'); - if ($killpid) { - fsleep(0.75); - kill 'TERM', $parent; - } - } - exit 0; -} - -# This does socket data transfer in one direction. -# -sub xfer { - my($in, $out, $lab) = @_; - my ($RIN, $WIN, $EIN, $ROUT); - $RIN = $WIN = $EIN = ""; - $ROUT = ""; - vec($RIN, fileno($in), 1) = 1; - vec($WIN, fileno($in), 1) = 1; - $EIN = $RIN | $WIN; - my $buf; - - while (1) { - my $nf = 0; - while (! $nf) { - $nf = select($ROUT=$RIN, undef, undef, undef); - } - my $len = sysread($in, $buf, 8192); - if (! defined($len)) { - next if $! =~ /^Interrupted/; - last; - } elsif ($len == 0) { - last; - } - - my $offset = 0; - my $quit = 0; - while ($len) { - my $written = syswrite($out, $buf, $len, $offset); - if (! defined $written) { - $quit = 1; - last; - } - $len -= $written; - $offset += $written; - } - last if $quit; - } - close($in); - close($out); -} - -# Sleep a small amount of time (float) -# -sub fsleep { - my ($time) = @_; - select(undef, undef, undef, $time) if $time; -} diff --git a/x11vnc/misc/dtVncPopup b/x11vnc/misc/dtVncPopup deleted file mode 100644 index e90cc8b..0000000 --- a/x11vnc/misc/dtVncPopup +++ /dev/null @@ -1,109 +0,0 @@ -#!/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/enhanced_tightvnc_viewer/COPYING b/x11vnc/misc/enhanced_tightvnc_viewer/COPYING deleted file mode 100644 index a3f6b12..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program 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 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/README b/x11vnc/misc/enhanced_tightvnc_viewer/README deleted file mode 100644 index 52eb93a..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/README +++ /dev/null @@ -1,756 +0,0 @@ - Enhanced TightVNC Viewer (SSVNC: SSL/SSH VNC viewer) - -Copyright (c) 2006-2009 Karl J. Runge <runge@karlrunge.com> -All rights reserved. - -These bundles provide 1) An enhanced TightVNC Viewer on Unix, 2) Binaries -for many Operating Systems (including Windows and Mac OS X) for your -convenience, 3) Wrapper scripts and a GUI for gluing them all together. - -One can straight-forwardly download all of the components and get them -to work together by oneself: this bundle is mostly for your convenience -to combine and wrap together the freely available software. - -Bundled software co-shipped is copyright and licensed by others. -See these sites and related ones for more information: - - http://www.tightvnc.com - http://www.realvnc.com - http://stunnel.mirt.net - http://www.stunnel.org - http://www.openssl.org - http://www.chiark.greenend.org.uk/~sgtatham/putty/ - http://sourceforge.net/projects/cotvnc/ - -Note: Some of the binaries included contain cryptographic software that -you may not be allowed to download, use, or redistribute. Please check -your situation first before downloading any of these bundles. See the -survey http://rechten.uvt.nl/koops/cryptolaw/index.htm for useful -information. - -All work done by Karl J. Runge in this project is -Copyright (c) 2006-2008 Karl J. Runge and is licensed under the GPL as -described in the file COPYING in this directory. - -All the files and information in this project are provided "AS IS" -without any warranty of any kind. Use them at your own risk. - - -============================================================================= - -This bundle contains a convenient collection of enhanced TightVNC -viewers and stunnel binaries for different flavors of Unix and wrapper -scripts and a GUI front-end to glue them together. Automatic SSL and -SSH encryption tunnelling is provided. - -A Windows SSL wrapper for the bundled TightVNC binary and other utilities -are provided. (Launch ssvnc.exe in the Windows subdirectory). - -The short name of the project is "ssvnc" for SSL/SSH VNC Viewer. - -It is a self-contained bundle, you could carry it around on, say, -a USB memory stick for secure VNC viewing from almost any machine, -Unix, Mac, or Windows. - -Features: --------- - -The enhanced TightVNC viewer features are: - - - SSL support for connections using the bundled stunnel program. - - - Automatic SSH connections from the GUI (ssh must already be - installed on Unix; bundled plink is used on Windows) - - - Ability to Save and Load VNC profiles for different hosts. - - - You can also use your own VNC Viewer, e.g. UltraVNC or RealVNC, - with the front-end GUI or scripts if you like. - - - Create or Import SSL Certificates and Private Keys. - - - Reverse (viewer listening) VNC connections via SSL and SSH. - - - VeNCrypt SSL/TLS VNC encryption support (used by VeNCrypt, - QEMU, ggi, libvirt/virt-manager/xen, vinagre/gvncviewer/gtk-vnc) - - - ANONTLS SSL/TLS VNC encryption support (used by Vino) - - - VeNCrypt and ANONTLS are also enabled for any 3rd party VNC - Viewer (e.g. RealVNC, TightVNC, UltraVNC ...) on Unix, MacOSX, - and Windows via the provided SSVNC VeNCrypt Viewer Bridge tool - (use 'Change VNC Viewer' to select the one you want.) - - - Support for Web Proxies, SOCKS Proxies, and the UltraVNC - repeater proxy (e.g. repeater://host:port+ID:1234). Multiple - proxies may be chained together (3 max). - - - Support for SSH Gateway connections and non-standard SSH ports. - - - Automatic Service tunnelling via SSH for CUPS and SMB Printing, - ESD/ARTSD Audio, and SMB (Windows/Samba) filesystem mounting. - - - Sets up any additional SSH port redirections that you want. - - - Zeroconf (aka Bonjour) is used on Unix and Mac OS X to find - VNC servers on your local network if the avahi-browse or dns-sd - program is available and in your PATH. - - - Port Knocking for "closed port" SSH/SSL connections. In addition - to a simple fixed port sequence and one-time-pad implementation, - a hook is also provided to run any port knocking client before a - connecting. - - - Support for native MacOS X usage with bundled Chicken of the - VNC viewer (the Unix X11 viewer is also provided for MacOS X, - and is better IMHO). - - - Dynamic VNC Server Port determination and redirection (using - ssh's builtin SOCKS proxy, -D) for servers like x11vnc that - print out PORT= at startup. - - - Unix Username and Password entry for use with "x11vnc -unixpw" - type login dialogs. - - - Simplified mode launched by command "sshvnc" that is SSH Only. - - - Simplified mode launched by command "tsvnc" that provides a VNC - "Terminal Services" mode (uses x11vnc on the remote side). - - - (the following features only apply to the bundled Unix tightvnc viewer - including MacOS X) - - - rfbNewFBSize VNC support (screen resizing) - - - Client-side Scaling of the Viewer. - - - ZRLE VNC encoding support (RealVNC's encoding) - - - Support for the ZYWRLE encoding, a wavelet based extension to - ZRLE to improve compression of motion video and photo regions. - - - TurboVNC support (VirtualGL's modified TightVNC encoding; - requires TurboJPEG library) - - - Pipelined Updates of the framebuffer as in TurboVNC (asks for - the next update before the current one has finished downloading; - this gives some speedup on high latency connections.) - - - Cursor alphablending with x11vnc at 32bpp (-alpha option) - - - Option "-unixpw ..." for use with "x11vnc -unixpw" login dialogs. - - - Support for UltraVNC extensions: Single Window, Disable - Server-side Input, 1/n Server side scaling, Text Chat (shell - terminal UI). Both UltraVNC and x11vnc servers support these - extensions - - - UltraVNC File Transfer via an auxiliary Java helper program - (java must be in $PATH). Note that the x11vnc server supports - UltraVNC file transfer. - - - Connection support for the UltraVNC repeater proxy (-repeater - option). - - - Support for UltraVNC Single Click operation. (both unencrypted: - SC I, and SSL encrypted: SC III) - - - Support for UltraVNC DSM Encryption Plugin mode. (ARC4 and - AESV2, MSRC4, and SecureVNC) - - - Support for UltraVNC MS-Logon authentication (NOTE: the - UltraVNC MS-Logon key exchange implementation is very weak; an - eavesdropper on the network can recover your Windows password - easily in a few seconds; you need to use an additional encrypted - tunnel with MS-Logon.) - - - Support for symmetric encryption (including blowfish and 3des - ciphers) to Non-UltraVNC Servers. Any server using the same - encryption method will work, e.g.: x11vnc -enc blowfish:./my.key - - - Instead of hostname:display one can also supply "exec=command - args..." to connect the viewer to the stdio of an external command - (e.g. stunnel or socat) rather than using a TCP/IP socket. Unix - domain sockets, e.g. /path/to/unix/socket, and a previously - opened file descriptor fd=0, work too. - - - Local Port Protections for STUNNEL and SSH: avoid having for - long periods of time a listening port on the the local (VNC - viewer) side that redirects to the remote side. - - - Reverse (viewer listening) VNC connections can show a - Popup dialog asking whether to accept the connection or not - (-acceptpopup.) The extra info provided by UltraVNC Single Click - reverse connections is also supported (-acceptpopupsc) - - - Extremely low color modes: 64 and 8 colors in 8bpp - (-use64/-bgr222, -use8/-bgr111) - - - Medium color mode: 16bpp mode even for 32bpp Viewer display - (-16bpp/-bgr565) - - - x11vnc's client-side caching -ncache method cropping option - (-ycrop n). This will "hide" the large pixel buffer cache - below the actual display. Set to actual height or use -1 for - autodetection (tall screens are autodetected by default). - - - Escape Keys: enable a set of modifier keys so when they - are all pressed down you can invoke Popup menu actions via - keystrokes. I.e., a set of 'Hot Keys'. One can also pan (move) - the desktop inside the viewport via Arrow keys or a mouse drag. - - - Scrollbar width setting: -sbwidth n, the default is very thin, - 2 pixels, for less distracting -ycrop usage. - - - Selection text sending and receiving can be fine-tuned with the - -sendclipboard, -sendalways, and -recvtext options. - - - TightVNC compression and quality levels are automatically set - based on observed network latency (n.b. not bandwidth.) - - - Improvements to the Popup menu, all of these can now be changed - dynamically via the menu: ViewOnly, Toggle Bell, CursorShape - updates, X11 Cursor, Cursor Alphablending, Toggle Tight/ZRLE, - Toggle JPEG, FullColor/16bpp/8bpp (256/64/8 colors), Greyscale - for low color modes, Scaling the Viewer resolution, Escape Keys, - Pipeline Updates, and others, including UltraVNC extensions. - - - Maintains its own BackingStore if the X server does not - - - The default for localhost:0 connections is not raw encoding - (local machine). Default assumes you are using SSH tunnel. Use - -rawlocal to revert. - - - XGrabServer support for fullscreen mode, for old window managers - (-grab/-graball option). - - - Fix for Popup menu positioning for old window managers - (-popupfix option). - - - Run vncviewer -help for all options. - - - -The list of software bundled in the archive files: - - TightVNC Viewer (windows, unix, macosx) - Chicken of the VNC Viewer (macosx) - Stunnel (windows, unix, macosx) - Putty/Plink/Pageant (windows) - OpenSSL (windows) - esound (windows) - -These are all self-contained in the bundle directory: they will not be -installed on your system. Just un-zip or un-tar the file you downloaded -and run it straight from its directory. - - -Quick Start: ------------ - -Unix and Mac OS X: - - Inside a Terminal do something like the following. - - Unpack the archive: - - % gzip -dc ssvnc-1.0.28.tar.gz | tar xvf - - - Run the GUI: - - % ./ssvnc/Unix/ssvnc (for Unix) - - % ./ssvnc/MacOSX/ssvnc (for Mac OS X) - - The smaller file "ssvnc_no_windows-1.0.28.tar.gz" - could have been used as well. - - On MacOSX you could also click on the SSVNC app icon in the Finder. - - On MacOSX if you don't like the Chicken of the VNC (e.g. no local - cursors, no screen size rescaling, and no password prompting), and you - have the XDarwin X server installed, you can set DISPLAY before starting - ssvnc (or type DISPLAY=... in Host:Disp and hit Return). Then our - enhanced TightVNC viewer will be used instead of COTVNC. - Update: there is now a 'Use X11 vncviewer on MacOSX' under Options ... - - - If you want a SSH-only tool (without the distractions of SSL) run - the command: - - sshvnc - - instead of "ssvnc". Or click "SSH-Only Mode" under Options. - Control-h will toggle between the two modes. - - - If you want a simple VNC Terminal Services only mode (requires x11vnc - on the remote server) run the command: - - tsvnc - - instead of "ssvnc". Or click "Terminal Services" under Options. - Control-t will toggle between the two modes. - - "tsvnc profile-name" and "tsvnc user@hostname" work too. - - -Unix/MacOSX Install: - - There is no standard install for the bundles, but you can make - symlinks like so: - - cd /a/directory/in/PATH - ln -s /path/to/ssvnc/bin/{s,t}* . - - Or put /path/to/ssvnc/bin, /path/to/ssvnc/Unix, or /path/to/ssvnc/MacOSX - in your PATH. - - For the conventional source tarball it will compile and install, e.g.: - - gzip -dc ssvnc-1.0.28.src.tar.gz | tar xvf - - cd ssvnc-1.0.28 - make config - make all - make PREFIX=/my/install/dir install - - then have /my/install/dir/bin in your PATH. - - -Windows: - - Unzip, using WinZip or a similar utility, the zip file: - - ssvnc-1.0.28.zip - - Run the GUI, e.g.: - - Start -> Run -> Browse - - and then navigate to - - .../ssvnc/Windows/ssvnc.exe - - select Open, and then OK to launch it. - - The smaller file "ssvnc_windows_only-1.0.28.zip" - could have been used as well. - - You can make a Windows shortcut to this program if you want to. - - See the Windows/README.txt for more info. - - - If you want a SSH-only tool (without the distractions of SSL) run - the command: - - sshvnc.bat - - Or click "SSH-Only Mode" under Options. - - - If you want a simple VNC Terminal Services only mode (requires x11vnc - on the remote server) run the command: - - tsvnc.bat - - Or click "Terminal Services" under Options. Control-t will toggle - between the two modes. "tsvnc profile-name" and "tsvnc user@hostname" - work too. - - - -Important Note for Windows Vista: One user reports that on Windows Vista -if you move or extract the "ssvnc" folder down to the "Program Files" -folder you will be prompted to do this as the Administrator. But then -when you start up ssvnc, as a regular user, it cannot create files in -that folder and so it fails to run properly. We recommend to not copy -or extract the "ssvnc" folder into "Program Files". Rather, extract -it to somewhere you have write permission (e.g. C:\ or your User dir) -and create a Shortcut to ssvnc.exe on the desktop. - -If you must put a launcher file down in "Program Files", perhaps an -"ssvnc.bat" that looks like this: - -C: -cd \ssvnc\Windows -ssvnc.exe - - -SSH-ONLY Mode: --------------- - -If you don't care for SSL and the distractions it provides in the GUI, -run "sshvnc" (unix/macosx) or "sshvnc.bat" (windows) to run an SSH only -version of the GUI. - -Terminal Services Mode ----------------------- - -There is an even simpler mode that uses x11vnc on the remote side for the -session finding and management. Run "tsvnc" (unix/macosx) or "tsvnc.bat" -(windows) to run the Terminal Services version of the GUI. - - -Bundle Info: ------------- - -The bundle files unpack a directory/folder named: ssvnc - -It contains these programs to launch the GUI: - - Windows/ssvnc.exe for Windows - MacOSX/ssvnc for Mac OS X - Unix/ssvnc for Unix - -(the Mac OS X and Unix launchers are simply links to the bin directory). - - -Your bundle file should have included binaries for many OS's: Linux, -Solaris, FreeBSD, etc. Unpack your archive and see the subdirectories of - - ./bin - -for the ones that were shipped in this project, e.g. ./bin/Linux.i686 -Run "uname -sm" to see your OS+arch combination (n.b. all Linux x86 are -mapped to Linux.i686). (See the ./bin/ssvnc_cmd -h output for how to -override platform autodection via the UNAME env. var). - - -Memory Stick Usage: -------------------- - -If you create a directory named "Home" in that toplevel ssvnc directory -then that will be used as the base for storing VNC profiles and -certificates. Also, for convenience, if you first run the command with -"." as an argument (e.g. "ssvnc .") it will automatically create that -"Home" directory for you. This is handy if you want to place SSVNC -on a USB flash drive that you carry around for mobile use and you want -the profiles you create to stay with the drive (otherwise you'd have to -browse to the drive directory each time you load or save). - -One user on Windows created a BAT file to launch SSVNC and needed to -do this to get the Home directory correct: - -cd \ssvnc\Windows -start \ssvnc\Windows\ssvnc.exe - -(an optional profile name can be supplied to the ssvnc.exe line) - -WARNING: if you use ssvnc from an "Internet Cafe", i.e. an untrusted -computer, an intruder may be capturing keystrokes etc. - - -External Dependencies: ----------------------- - -On Windows everything is included. Let us know if you find otherwise. - -On Unix depending on what you do you need these programs installed: - - - basic unix utilities (sh, ls, cat, awk, sed, etc..) - - tcl/tk (wish interpreter) - - xterm - - perl - - ssh - - openssl - - Lesser used ones: netcat, esd/artsd, smbclient, smbmount, cups - -On Mac OS X depending on what you do you need these programs installed: - - - basic unix utilities (sh, ls, cat, awk, sed, etc..) - - tcl/tk (wish interpreter) - - Terminal - - perl - - ssh - - openssl - - Lesser used ones: netcat, smbclient, cups - -Most Mac OS X and Unix OS come with the main components installed. - -See the README.src for a more detailed description of dependencies. - - -TurboVNC Support: ----------------- - -TurboVNC is supported in an experimental way. To it build via the -build.unix script described in the next section, do something like: - - env TURBOVNC='-L/DIR -Xlinker --rpath=/DIR -lturbojpeg' ./build.unix - -where you replace /DIR with the directory where the libturbojpeg.so -(http://sourceforge.net/project/showfiles.php?group_id=117509&package_id=166100) -is installed. - -You may not need to set rpath if libturbojpeg.so is installed in a -standard location or you use LD_LIBRARY_PATH to point to it. - -See the turbovnc/README in the vnc_unixsrc/vncviewer directory for -more info. You can find it in the ssvnc source tarball and also -in: - - src/zips/vnc_unixsrc_vncviewer.patched.tar - -More TurboVNC features will be enabled in the future. - - -If you need to Build: --------------------- - -If your OS/arch is not included or the provided binary has the wrong -library dependencies, etc. the script "build.unix" may be able to -successfully build on for you and deposit the binaries down in ./bin/... -using the included source code. It is a hack but usually works. - -You MUST run the build.unix script from this directory (that this toplevel -README is in, i.e "ssvnc") and like this: - - ./build.unix - -To use custom locations for libraries see the LDFLAGS_OS and CPPFLAGS_OS -description at the top of the build.unix script. - -You can set these env. vars to customize the build: - - SSVNC_BUILD_NO_STATIC=1 do not try to statically link libs - SSVNC_BUILD_FORCE_OVERWRITE=1 do not prompt about existing binaries - SSVNC_BUILD_SKIP_VIEWER=1 do not build vncviewer - SSVNC_BUILD_SKIP_STUNNEL=1 do not build stunnel - SSVNC_BUILD_ULTRAFTP=1 only build the file xfer helper jar - -here is an example to build only the vncviewer and with normal library -linking (and in a more or less automated way): - - env SSVNC_BUILD_NO_STATIC=1 SSVNC_BUILD_FORCE_OVERWRITE=1 SSVNC_BUILD_SKIP_STUNNEL=1 ./build.unix - -Feel free to ask us if you need help running ./build.unix - - -Convential Build: - -A more conventional source tarball is provided in ssvnc-x.y.z.src.tar.gz. -It uses a more or less familiar 'make config; make all; make PREFIX=path install' -method. It does not include stunnel, so that must be installed on the -system separately. - - -The programs: ------------- - -Unpack your archive, and you will see "bin", "Windows", "src" directories -and other files. The command line wrapper scripts: - - ./bin/ssvnc_cmd - ./bin/tightvncviewer - -are the main programs that are run and will try to autodetect your OS+arch -combination and if binaries are present for it automatically use them. -(if not found try the running the build.unix script). - -If you prefer a GUI to prompt for parameters and then start ssvnc_cmd -you can run this instead: - - ./bin/ssvnc - -this is the same GUI that is run on Windows (the ssvnc.exe). -There are also: - - ./bin/sshvnc (SSH-Only) - ./bin/tsvnc (Terminal Services Mode) - -For convenience, you can make symlinks from a directory in your PATH to -any of the 3 programs above you wish to run. That is all you usually -need to do for it to pick up all of the binaries, utils, etc. E.g. -assuming $HOME/bin is in your $PATH: - - cd $HOME/bin - ln -s /path/to/ssvnc/bin/{s,t}* . - -(note the "." at the end). The above commands is basically the way to -"install" this on Unix or MacOS X. - -Also links to the GUI launcher script are provided in: - - MacOSX/ssvnc - Unix/ssvnc - -and sshvnc and tsvnc. You could also put the Unix or MacOSX directory -in your PATH. - - -On Windows unpack your archive and run: - - Windows/ssvnc.exe - - -Examples: --------- - -The following assume you are in the toplevel directory of the -archive you unpacked. - -Use enhanced TightVNC unix viewer to connect to x11vnc via SSL: - - ./bin/ssvnc_cmd far-away.east:0 - - ./bin/tightvncviewer -ssl far-away.east:0 (same) - - ./bin/ssvnc (start GUI launcher) - -Use enhanced TightVNC unix viewer without SSL: - - ./bin/tightvncviewer far-away.east:0 - -Use SSL to connect to a x11vnc server, and also verify the server's -identity using the SSL Certificate in the file ./x11vnc.pem: - - ./bin/ssvnc_cmd -alpha -verify ./x11vnc.pem far-away.east:0 - -(also turns on the viewer-side cursor alphablending hack). - - -Brief description of the subdirectories: ---------------------------------------- - - ./bin/util some utility scripts, e.g. ss_vncviewer - and ssvnc.tcl - - ./src source code and patches. - ./src/zips zip files of source code and binaries. - - ./src/vnc_unixsrc unpacked tightvnc source code tree. - ./src/stunnel-4.14 unpacked stunnel source code tree. - ./src/patches patches to TightVNC viewer for the new - features on Unix (used by build.unix). - ./src/tmp temporary build dir for build.unix - (the last four are used by build.unix) - - - ./man man pages for TightVNC viewer and stunnel. - - ./Windows Stock TightVNC viewer and Stunnel, Openssl - etc Windows binaries. ssvnc.exe is the - program to run. - - ./MacOSX contains an unpacked Chicken of the VNC - viewer and a symlink to ssvnc. - - ./Unix contains a symlink to ssvnc. - -Depending on which bundle you use not all of the above may be present. -The smallest bundles with binaries are: - - ssvnc_windows_only-1.x.y.zip Windows - ssvnc_no_windows-1.x.y.tar.gz Unix and MacOSX - -however, the tiny scripts only one (only 60KB) will run properly on Unix -as long as you install external vncviewer and stunnel packages: - - ssvnc_unix_minimal-1.x.y.tar.gz - - -Untrusted Local Users: ---------------------- - - *IMPORTANT WARNING*: If you run SSVNC on a workstation or computer - that other users can log into and you DO NOT TRUST these users - (it is a shame but sometimes one has to work in an environment like - this), then please note the following warning. - - By 'do not trust' we mean they might try to gain access to remote - machines you connect to via SSVNC. Note that an untrusted local - user can often obtain root access in a short amount of time; if a - user has achieved that, then all bets are off for ANYTHING that you - do on the workstation. It is best to get rid of Untrusted Local - Users as soon as possible. - - Both the SSL and SSH tunnels set up by SSVNC listen on certain ports - on the 'localhost' address and redirect TCP connections to the remote - machine; usually the VNC server running there (but it could also be - another service, e.g. CUPS printing). These are the stunnel(8) SSL - redirection and the ssh(1) '-L' port redirection. Because 'localhost' - is used only users or programs on the same workstation that is - running SSVNC can connect to these ports, however this includes any - local users (not just the user running SSVNC.) - - If the untrusted local user tries to connect to these ports, he may - succeed in varying degrees to gain access to the remote machine. - We now list some safeguards one can put in place to try to make this - more difficult to achieve. - - It probably pays to have the VNC server require a password, even - though there has already been SSL or SSH authentication (via - certificates or passwords). In general if the VNC Server requires - SSL authentication of the viewer that helps, unless the untrusted - local user has gained access to your SSVNC certificate keys. - - If the VNC server is configured to only allow one viewer connection - at a time, then the window of opportunity that the untrusted local - user can use is greatly reduced: he might only have a second or two - between the tunnel being set up and the SSVNC vncviewer connecting - to it (i.e. if the VNC server only allows a single connection, the - untrusted local user cannot connect once your session is established). - Similarly, when you disconnect the tunnel is torn down quickly and - there is little or no window of opportunity to connect (e.g. x11vnc - in its default mode exits after the first client disconnects). - - Also for SSL tunnelling with stunnel(8) on Unix using one of the SSVNC - prebuilt 'bundles', a patched stunnel is provided that denies all - connections after the first one, and exits when the first one closes. - This is not true if the system installed stunnel(8) is used and is - not true when using SSVNC on Windows. - - The following are two experimental features that are added to SSVNC - to improve the situation for the SSL/stunnel case. Set them via - Options -> Advanced -> "STUNNEL Local Port Protections". - - 1) For SSL tunnelling with stunnel(8) on Unix there is a setting - 'Use stunnel EXEC mode' (experimental) that will try to exec(2) - stunnel instead of using a listening socket. This will require - using the specially modified vncviewer unix viewer provided - by SSVNC. If this mode proves stable it will become the default. - - 2) For SSL tunnelling with stunnel(8) on Unix there is a setting - 'Use stunnel IDENT check' (experimental) to limit socket - connections to be from you (this assumes the untrusted local - user has not become root on your workstation and has modified - your local IDENT check service; if he has you have much bigger - problems to worry about...) - - There is also one simple LD_PRELOAD trick for SSH to limit the number - of accepted port redirection connections. This makes the window of - time the untrusted local user can connect to the tunnel much smaller. - Enable it via Options -> Advanced -> "SSH Local Port Protections". - You will need to have the lim_accept.so file in your SSVNC package. - - The main message is to 'Watch your Back' when you connect via the - SSVNC tunnels and there are users you don't trust on your workstation. - The same applies to ANY use of SSH '-L' port redirections or outgoing - stunnel SSL redirection services. - - -Help and Info: -------------- - -For more help on other options and usage patterns run these: - - ./bin/ssvnc_cmd -h - ./bin/util/ss_vncviewer -h - -See also: - - http://www.karlrunge.com/x11vnc - http://www.karlrunge.com/x11vnc/faq.html - x11vnc -h | more - - http://stunnel.mirt.net - http://www.stunnel.org - http://www.openssl.org - http://www.tightvnc.com - http://www.realvnc.com - http://www.chiark.greenend.org.uk/~sgtatham/putty/ - http://sourceforge.net/projects/cotvnc/ diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt deleted file mode 100644 index 4d816d2..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt +++ /dev/null @@ -1,72 +0,0 @@ -
-This is a Windows utility to automatically start up STUNNEL to redirect
-SSL VNC connections to a remote host. Then TightVNC Viewer (included)
-is launched to use this SSL tunnel.
-
-An example server would be "x11vnc -ssl", or any VNC server with a
-2nd STUNNEL program running on the server side.
-
-Just click on the program "ssvnc.exe", and then enter the remote
-VNC Server and click "Connect". Click on "Help" for more information
-information. You can also set some simple options under "Options ..."
-
-If you want that application to run in "SSH-ONLY" mode, click on
-the "sshvnc.bat" wrapper instead. Or enter SSH_ONLY.
-
-Note that on Windows when the TightVNC viewer disconnects you may need to
-terminate the STUNNEL program manually. To do this: Click on the STUNNEL
-icon (dark green) on the System Tray and then click "Exit". Before that,
-however, you will be prompted if you want ssvnc.exe to try to terminate
-STUNNEL for you. (Note that even if STUNNEL termination is successful,
-the Tray Icon may not go away until the mouse hovers over it!)
-
-With this STUNNEL and TightVNC Viewer wrapper you can also enable using
-SSL Certificates with STUNNEL, and so the connection is not only encrypted
-but it is also not susceptible to man-in-the-middle attacks.
-
-See the STUNNEL and x11vnc documentation for how to create and add SSL
-Certificates (PEM files) for authentication. Click on the "Certs ..."
-button to specify the certificate(s). See the Help there for more info
-and also:
-
- http://www.karlrunge.com/x11vnc
- http://www.tightvnc.com
- http://www.stunnel.org
- http://www.openssl.org
- http://www.chiark.greenend.org.uk/~sgtatham/putty/
-
-You can use x11vnc to create certificates if you like:
-
- http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca
-
-
-Misc:
-
- The openssl.exe stunnel.exe vncviewer.exe libeay32.dll
- libssl32.dll programs came from the websites mentioned above.
-
- IMPORTANT: some of these binaries may have cryptographic
- software that you may not be allowed to download or use.
- See the above websites for more information and also the
- util/info subdirectories.
-
- Also, the kill.exe and tlist.exe programs in the w98 directory
- came from diagnostic tools ftp site of Microsoft's.
-
-
-
-Important Note for Windows Vista: One user reports that on Windows Vista
-if you move or extract the "ssvnc" folder down to the "Program Files"
-folder you will be prompted to do this as the Administrator. But then
-when you start up ssvnc, as a regular user, it cannot create files in
-that folder and so it fails to run properly. We recommend to not copy
-or extract the "ssvnc" folder into "Program Files". Rather, extract
-it to somewhere you have write permission (e.g. C:\ or your User dir)
-and create a Shortcut to ssvnc.exe on the desktop.
-
-If you must put a launcher file down in "Program Files", perhaps an
-"ssvnc.bat" that looks like this:
-C:
-cd \ssvnc\Windows
-ssvnc.exe
-
diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat deleted file mode 100644 index 9cd2d9e..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat +++ /dev/null @@ -1 +0,0 @@ -start ssvnc.exe -ssh %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat deleted file mode 100644 index 1331d02..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat +++ /dev/null @@ -1 +0,0 @@ -start ssvnc.exe -ts %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl deleted file mode 100755 index ec2e0b0..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl +++ /dev/null @@ -1,1271 +0,0 @@ -#!/usr/bin/wish - -proc check_callback {} { - global debug - if {$debug} { - puts stderr "." - } - check_closed - after 1000 check_callback -} - -proc getout {} { - global client_fh server_fh - - set delay 50 - catch {flush $client_fh} - after $delay - catch {close $client_fh} - set client_fh "" - after $delay - catch {flush $server_fh} - after $delay - catch {close $server_fh} - set server_fh "" - after $delay - - global bmesg_cnt - if [info exists bmesg_cnt] { - catch {tkwait window .bmesg$bmesg_cnt} - } - destroy . - exit -} - -proc check_closed {} { - global got_connection debug - global client_fh server_fh - - if {! $got_connection} { - return - } - if {$client_fh != ""} { - set ef "" - catch {set ef [eof $client_fh]} - if {$ef == 1} { - if {$debug} { - puts stderr "client_fh EOF" - } - getout - } - } - if {$server_fh != ""} { - set ef "" - catch {set ef [eof $server_fh]} - if {$ef == 1} { - if {$debug} { - puts stderr "server_fh EOF" - } - getout - } - } -} - -proc xfer_in_to_out {} { - global client_fh server_fh debug do_bridge - if {$client_fh != "" && ![eof $client_fh]} { - set ef "" - catch {set ef [eof $client_fh]} - if {$ef == 0} { - set str "" - catch {set str [read $client_fh 4096]} - if {$debug} { - #puts stderr "xfer_in_to_out: $str" - puts stderr "xfer_in_to_out: [string length $str]" - } - if {$server_fh != "" && $str != ""} { - catch {puts -nonewline $server_fh $str} - catch {flush $server_fh} - } - } - } - check_closed -} - -proc xfer_out_to_in {} { - global client_fh server_fh debug do_bridge - if {$server_fh != ""} { - set ef "" - catch {set ef [eof $server_fh]} - if {$ef == 0} { - set str "" - catch {set str [read $server_fh 4096]} - if {$debug} { - #puts stderr "xfer_out_to_in: $str" - puts stderr "xfer_out_to_in: [string length $str]" - } - if {$client_fh != "" && $str != ""} { - catch {puts -nonewline $client_fh $str} - catch {flush $client_fh} - } - } - } - check_closed -} - -proc bmesg {msg} { - global env - if {! [info exists env(BMESG)]} { - return - } - if {$env(BMESG) == 0} { - return - } - - global bmesg_cnt - if {! [info exists bmesg_cnt]} { - set bmesg_cnt 0 - } - incr bmesg_cnt - set w .bmesg$bmesg_cnt - catch {destroy $w} - toplevel $w - label $w.l -width 70 -text "$msg" - pack $w.l - update - if {$env(BMESG) > 1} { - for {set i 0} {$i < $env(BMESG)} {incr i} { - after 1000 - update - } - } -} - -proc do_connect_http {sock hostport which} { - global debug cur_proxy - set con "" - append con "CONNECT $hostport HTTP/1.1\r\n" - append con "Host: $hostport\r\n" - append con "Connection: close\r\n\r\n" - - puts stderr "pxy=$which CONNECT $hostport HTTP/1.1 via $cur_proxy" - bmesg "H: $which CONNECT $hostport HTTP/1.1 $cur_proxy"; - - puts -nonewline $sock $con - flush $sock - - set r "" - set cnt 0 - while {1} { - incr cnt - set c [read $sock 1] - if {$c == ""} { - check_closed - after 20 - } - append r $c - if {[regexp "\r\n\r\n" $r] || [regexp "a--no--\n\n" $r]} { - break - } - if {$cnt > 30000} { - break - } - } - if {! [regexp {HTTP/.* 200} $r]} { - puts stderr "did not find HTTP 200 #1" - destroy . - exit 1 - } -} - -proc do_connect_socks4 {sock hostport which} { - global debug cur_proxy - - set host "" - set port "" - if [regexp {^(.*):([0-9][0-9]*)$} $hostport mvar host port] { - ; - } else { - puts stderr "could not parse host:port $hostport" - destroy . - exit 1 - } - - set i1 "" - set i2 "" - set i3 "" - set i4 "" - - set socks4a 0 - - if {$host == "localhost" || $host == "127.0.0.1"} { - set i1 127 - set i2 0 - set i3 0 - set i4 1 - - } elseif [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $host] { - set n [split $host "."] - set i1 [lindex $n 0] - set i2 [lindex $n 1] - set i3 [lindex $n 2] - set i4 [lindex $n 3] - } else { - set i1 0 - set i2 0 - set i3 0 - set i4 3 - - set socks4a 1 - } - - if {$socks4a} { - puts stderr "pxy=$which socks4a connection to $host:$port via $cur_proxy" - } else { - puts stderr "pxy=$which socks4 connection to $host:$port via $cur_proxy" - } - - set p1 [binary format ccScccc 4 1 $port $i1 $i2 $i3 $i4] - set p2 "nobody" - set p3 [binary format c 0] - - puts -nonewline $sock $p1 - puts -nonewline $sock $p2 - puts -nonewline $sock $p3 - if {$socks4a} { - puts -nonewline $sock $host - puts -nonewline $sock $p3 - } - flush $sock - - set r ""; set s ""; set i 0; set cnt 0 - set ok 1 - while {$cnt < 30000 && $i < 8} { - incr cnt - set c [read $sock 1] - if {$c == ""} { - check_closed - after 20 - continue - } - - binary scan $c c s - if {$i == 0 && $s != 0} { - puts stderr "socks4: $i - $s" - set ok 0 - } - if {$i == 1 && $s != 90} { - puts stderr "socks4: $i - $s" - set ok 0 - } - set r "$r,$s" - incr i - } - if {! $ok} { - puts stderr "socks4 failure: $r" - destroy . - exit 1 - } -} - -proc do_connect_socks5 {sock hostport which} { - global debug cur_proxy - - set host "" - set port "" - if [regexp {^(.*):([0-9][0-9]*)$} $hostport mvar host port] { - ; - } else { - puts stderr "could not parse host:port $hostport" - destroy . - exit 1 - } - - set p1 [binary format ccc 5 1 0] - puts -nonewline $sock $p1 - flush $sock - - set r ""; set s ""; set i 0; set cnt 0 - set ok 1 - while {$cnt < 30000 && $i < 2} { - incr cnt - set c [read $sock 1] - if {$c == ""} { - check_closed - after 20 - continue - } - - binary scan $c c s - if {$i == 0 && $s != 5} { - puts stderr "$i - $s" - set ok 0 - } - if {$i == 1 && $s != 0} { - puts stderr "$i - $s" - set ok 0 - } - set r "$r,$s" - incr i - } - if {! $ok} { - puts stderr "socks5 failure: $r" - destroy . - exit 1 - } - - set len [string length $host] - set p1 [binary format ccccc 5 1 0 3 $len] - set p2 $host - - set n1 [expr int($port/256)] - set n2 [expr "$port - $n1 * 256"] - set p3 [binary format cc $n1 $n2] - - puts stderr "pxy=$which socks5 connection to $host:$port via $cur_proxy" - - puts -nonewline $sock $p1 - puts -nonewline $sock $p2 - puts -nonewline $sock $p3 - flush $sock - - set i1 ""; set i2 ""; set i3 ""; set i4 "" - set r ""; set s ""; set i 0; set cnt 0 - set ok 1 - while {$cnt < 30000 && $i < 4} { - incr cnt - set c [read $sock 1] - if {$c == ""} { - check_closed - after 20 - continue - } - - binary scan $c c s - if {$i == 0} { - set i1 $s - } elseif {$i == 1} { - set i2 $s - } elseif {$i == 2} { - set i3 $s - } elseif {$i == 3} { - set i4 $s - } - incr i - } - set r "i1=$i1,i2=$i2,i3=$i3,i4=$i4" - - if {$i4 == 1} { - set n 6 - } elseif {$i4 == 3} { - set c "" - for {set i 0} {$i < 1000} {incr i} { - set c [read $sock 1] - if {$c == ""} { - check_closed - after 20 - continue - } - break; - } - if {$c == ""} { - puts stderr "socks5 failure c: $r" - destroy . - exit 1 - } - binary scan $c c s - set n [expr $s + 2] - } elseif {$i4 == 4} { - set n 18 - } else { - puts stderr "socks5 failure x: $r" - destroy . - exit 1 - } - #puts "n=$n --- $r" - - set i 0; set cnt 0 - while {$cnt < 30000 && $i < $n} { - incr cnt - set c [read $sock 1] - if {$c == ""} { - check_closed - after 20 - continue - } - incr i - } - if {$i1 != 5 || $i2 != 0 || $i3 != 0} { - puts stderr "socks failure $r" - destroy . - exit 1 - } -} - -proc do_connect_repeater {sock hostport which repeater} { - global debug cur_proxy - - # 250 is UltraVNC buffer size. - set con [binary format a250 $repeater] - - puts stderr "pxy=$which REPEATER $repeater via $cur_proxy" - bmesg "R: $which CONNECT $hostport | $repeater $cur_proxy"; - - puts -nonewline $sock $con - flush $sock - - set r "" - set cnt 0 - while {1} { - incr cnt - set c [read $sock 1] - if {$c == ""} { - check_closed - after 20 - } - append r $c - if {[string length $r] >= 12} { - puts stderr "do_connect_repeater: $r" - break - } - if {$cnt > 30000} { - break - } - } -} - -proc vread {n sock} { - set str "" - set max 3000 - set dt 10 - set i 0 - set cnt 0 - while {$cnt < $max && $i < $n} { - incr cnt - set c [read $sock 1] - if {$c == ""} { - check_closed - after $dt - continue - } - incr i - append str $c - } - if {$i != $n} { - puts stderr "vread failure $n $i" - destroy .; exit 1 - } - return $str -} - -proc append_handshake {str} { - global env - if [info exists env(SSVNC_PREDIGESTED_HANDSHAKE)] { - set file $env(SSVNC_PREDIGESTED_HANDSHAKE) - set fh "" - catch {set fh [open $file a]} - if {$fh != ""} { - puts $fh $str - catch {close $fh} - } - } -} - -proc vencrypt_bridge_connection {fh host port} { - puts stderr "vencrypt_bridge_connection: got connection $fh $host $port" - bmesg "vencrypt_bridge_connection: got connection $fh $host $port" - global viewer_sock - set viewer_sock $fh -} - -proc center_win {w} { - update - set W [winfo screenwidth $w] - set W [expr $W + 1] - wm geometry $w +$W+0 - update - set x [expr [winfo screenwidth $w]/2 - [winfo width $w]/2] - set y [expr [winfo screenheight $w]/2 - [winfo height $w]/2] - - wm geometry $w +$x+$y - wm deiconify $w - update -} - - -proc get_user_pass {} { - global env - set up "" - if [info exists env(SSVNC_UNIXPW)] { - set rm 0 - set up $env(SSVNC_UNIXPW) - if [regexp {^rm:} $up] { - set rm 1 - regsub {^rm:} $up "" up - } - if [file exists $up] { - set fh "" - set f $up - catch {set fh [open $up r]} - if {$fh != ""} { - gets $fh u - gets $fh p - catch {close $fh} - set up "$u@$p" - } - if {$rm} { - catch {file delete $f} - } - } - } elseif [info exists env(SSVNC_VENCRYPT_USERPASS)] { - set up $env(SSVNC_VENCRYPT_USERPASS) - } - if {$up != ""} { - return $up - } - - toplevel .t - wm title .t {VeNCrypt Viewer Bridge User/Pass} - - global user pass - set user "" - set pass "" - label .t.l -text {SSVNC VeNCrypt Viewer Bridge} - - frame .t.f0 - frame .t.f0.fL - label .t.f0.fL.la -text {Username: } - label .t.f0.fL.lb -text {Password: } - - pack .t.f0.fL.la .t.f0.fL.lb -side top - - frame .t.f0.fR - entry .t.f0.fR.ea -width 24 -textvariable user - entry .t.f0.fR.eb -width 24 -textvariable pass -show * - - pack .t.f0.fR.ea .t.f0.fR.eb -side top -fill x - - pack .t.f0.fL -side left - pack .t.f0.fR -side right -expand 1 -fill x - - button .t.no -text Cancel -command {set user ""; set pass ""; destroy .t} - button .t.ok -text Done -command {destroy .t} - - center_win .t - pack .t.l .t.f0 .t.no .t.ok -side top -fill x - update - wm deiconify .t - - bind .t.f0.fR.ea <Return> {focus .t.f0.fR.eb} - bind .t.f0.fR.eb <Return> {destroy .t} - focus .t.f0.fR.ea - - wm resizable .t 1 0 - wm minsize .t [winfo reqwidth .t] [winfo reqheight .t] - - tkwait window .t - if {$user == "" || $pass == ""} { - return "" - } else { - return "$user@$pass" - } -} - -proc do_vencrypt_viewer_bridge {listen connect} { - global env - - #set env(BMESG) 1 - - vencrypt_constants - - set backwards 0 - - if {! [info exists env(SSVNC_PREDIGESTED_HANDSHAKE)]} { - puts stderr "no SSVNC_PREDIGESTED_HANDSHAKE filename in environment." - destroy .; exit 1 - } - set handshake $env(SSVNC_PREDIGESTED_HANDSHAKE) - bmesg $handshake - - if {$listen < 0} { - set backwards 1 - set listen [expr -$listen] - } - - # listen on $listen - global viewer_sock - set viewer_sock "" - set lsock "" - set rc [catch {set lsock [socket -myaddr 127.0.0.1 -server vencrypt_bridge_connection $listen]}] - if {$rc != 0} { - puts stderr "error listening on 127.0.0.1:$listen" - destroy .; exit 1 - } - bmesg "listen on $listen OK" - - # accept - vwait viewer_sock - catch {close $lsock} - fconfigure $viewer_sock -translation binary -blocking 0 - - global got_connection - set got_connection 1 - - # connect to $connect - set server_sock "" - set rc [catch {set server_sock [socket 127.0.0.1 $connect]}] - if {$rc != 0} { - puts stderr "error connecting to 127.0.0.1:$connect" - destroy .; exit 1 - } - bmesg "made connection to $connect" - fconfigure $server_sock -translation binary -blocking 0 - - if {$backwards} { - puts stderr "reversing roles of viewer and server" - set t $viewer_sock - set viewer_sock $server_sock - set server_sock $t - } - - # wait for SSVNC_PREDIGESTED_HANDSHAKE "done", put in hash. - set dt 200 - set slept 0 - set maxwait 20000 - set hs(mode) init - while {$slept < $maxwait} { - after $dt - set slept [expr $slept + $dt] - set done 0 - set fh "" - catch {set fh [open $handshake r]} - set str "" - if {$fh != ""} { - array unset hs - while {[gets $fh line] > -1} { - set line [string trim $line] - set str "$str$line\n"; - if {$line == "done"} { - set done 1 - } elseif [regexp {=} $line] { - set s [split $line "="] - set key [lindex $s 0] - set val [lindex $s 1] - set hs($key) $val - } - } - catch {close $fh} - } - if {$done} { - puts stderr $str - bmesg "$str" - break - } - } - - catch [file delete $handshake] - - if {! [info exists hs(sectype)]} { - puts stderr "no hs(sectype) found" - destroy .; exit 1 - } - - # read viewer RFB - if {! [info exists hs(server)]} { - set hs(server) "RFB 003.008" - } - puts -nonewline $viewer_sock "$hs(server)\n" - flush $viewer_sock - puts stderr "sent $hs(server) to viewer sock." - - set viewer_rfb [vread 12 $viewer_sock] - puts stderr "read viewer_rfb $viewer_rfb" - - set viewer_major 3 - set viewer_minor 8 - if [regexp {^RFB 003\.0*([0-9][0-9]*)} $viewer_rfb m v] { - set viewer_minor $v - } - - if {$hs(sectype) == $rfbSecTypeAnonTls} { - puts stderr "handling rfbSecTypeAnonTls" - if {$viewer_major > 3 || $viewer_minor >= 7} { - puts stderr "viewer >= 3.7, nothing to set up." - } else { - puts stderr "viewer <= 3.3, faking things up." - set t [vread 1 $server_sock] - binary scan $t c nsectypes - puts stderr "nsectypes=$nsectypes" - for {set i 0} {$i < $nsectypes} {incr i} { - set t [vread 1 $server_sock] - binary scan $t c st - puts stderr " $i: $st" - set types($st) $i - } - set use 1 - if [info exists types(1)] { - set use 1 - } elseif [info exists types(2)] { - set use 2 - } else { - puts stderr "no valid sectypes" - destroy .; exit 1 - } - # this should be MSB: - vsend_uchar $viewer_sock 0 - vsend_uchar $viewer_sock 0 - vsend_uchar $viewer_sock 0 - vsend_uchar $viewer_sock $use - - vsend_uchar $server_sock $use - if {$use == 1} { - set t [vread 4 $server_sock] - } - } - } elseif {$hs(sectype) == $rfbSecTypeVencrypt} { - puts stderr "handling rfbSecTypeVencrypt" - if {! [info exists hs(subtype)]} { - puts stderr "no subtype" - destroy .; exit 1 - } - set fake_type "None" - set plain 0 - - set sub_type $hs(subtype) - - - if {$sub_type == $rfbVencryptTlsNone} { - set fake_type "None" - } elseif {$sub_type == $rfbVencryptTlsVnc} { - set fake_type "VncAuth" - } elseif {$sub_type == $rfbVencryptTlsPlain} { - set fake_type "None" - set plain 1 - } elseif {$sub_type == $rfbVencryptX509None} { - set fake_type "None" - } elseif {$sub_type == $rfbVencryptX509Vnc} { - set fake_type "VncAuth" - } elseif {$sub_type == $rfbVencryptX509Plain} { - set fake_type "None" - set plain 1 - } - - if {$plain} { - set up [get_user_pass] - if [regexp {@} $up] { - set user $up - set pass $up - regsub {@.*$} $user "" user - regsub {^[^@]*@} $pass "" pass - vsend_uchar $server_sock 0 - vsend_uchar $server_sock 0 - vsend_uchar $server_sock 0 - vsend_uchar $server_sock [string length $user] - vsend_uchar $server_sock 0 - vsend_uchar $server_sock 0 - vsend_uchar $server_sock 0 - vsend_uchar $server_sock [string length $pass] - puts stderr "sending VencryptPlain user and pass." - puts -nonewline $server_sock $user - puts -nonewline $server_sock $pass - flush $server_sock - } - } - set ft 0 - if {$fake_type == "None"} { - set ft 1 - } elseif {$fake_type == "VncAuth"} { - set ft 2 - } else { - puts stderr "no valid fake_type" - destroy .; exit 1 - } - - if {$viewer_major > 3 || $viewer_minor >= 7} { - vsend_uchar $viewer_sock 1 - vsend_uchar $viewer_sock $ft - set t [vread 1 $viewer_sock] - binary scan $t c cr - if {$cr != $ft} { - puts stderr "client selected wront type $cr $ft" - destroy .; exit 1 - } - } else { - puts stderr "viewer <= 3.3, faking things up." - # this should be MSB: - vsend_uchar $viewer_sock 0 - vsend_uchar $viewer_sock 0 - vsend_uchar $viewer_sock 0 - vsend_uchar $viewer_sock $ft - - if {$ft == 1} { - set t [vread 4 $server_sock] - } - } - } - - global client_fh server_fh - set client_fh $viewer_sock - set server_fh $server_sock - - fileevent $client_fh readable xfer_in_to_out - fileevent $server_fh readable xfer_out_to_in -} - -proc vsend_uchar {sock n} { - set s [binary format c $n] - puts -nonewline $sock $s - flush $sock -} - -proc vencrypt_constants {} { - uplevel { - set rfbSecTypeAnonTls 18 - set rfbSecTypeVencrypt 19 - - set rfbVencryptPlain 256 - set rfbVencryptTlsNone 257 - set rfbVencryptTlsVnc 258 - set rfbVencryptTlsPlain 259 - set rfbVencryptX509None 260 - set rfbVencryptX509Vnc 261 - set rfbVencryptX509Plain 262 - } -} - -proc do_vencrypt {sock which} { - - vencrypt_constants - - set t [vread 1 $sock] - binary scan $t c vs_major - set t [vread 1 $sock] - binary scan $t c vs_minor - - if {$vs_minor == "" || $vs_major == "" || $vs_major != 0 || $vs_minor < 2} { - puts stderr "vencrypt failure bad vs version major=$major minor=$minor" - destroy .; exit 1 - } - puts stderr "server vencrypt version $vs_major.$vs_minor" - bmesg "server vencrypt version $vs_major.$vs_minor" - - append_handshake "subversion=0.2" - vsend_uchar $sock 0 - vsend_uchar $sock 2 - - set t [vread 1 $sock] - binary scan $t c result - if {$result != 0} { - puts stderr "vencrypt failed result: $result" - bmesg "vencrypt failed result: $result" - destroy .; exit 1 - } - - set t [vread 1 $sock] - binary scan $t c nsubtypes - puts stderr "nsubtypes: $nsubtypes" - bmesg "nsubtypes: $nsubtypes" - - for {set i 0} {$i < $nsubtypes} {incr i} { - set t [vread 4 $sock] - binary scan $t I stype - puts stderr "subtypes: $i: $stype" - append_handshake "sst$i=$stype" - set subtypes($stype) $i - } - - set subtype 0 - if [info exists subtypes($rfbVencryptX509None)] { - set subtype $rfbVencryptX509None - puts stderr "selected rfbVencryptX509None" - } elseif [info exists subtypes($rfbVencryptX509Vnc)] { - set subtype $rfbVencryptX509Vnc - puts stderr "selected rfbVencryptX509Vnc" - } elseif [info exists subtypes($rfbVencryptX509Plain)] { - set subtype $rfbVencryptX509Plain - puts stderr "selected rfbVencryptX509Plain" - } elseif [info exists subtypes($rfbVencryptTlsNone)] { - set subtype $rfbVencryptTlsNone - puts stderr "selected rfbVencryptTlsNone" - } elseif [info exists subtypes($rfbVencryptTlsVnc)] { - set subtype $rfbVencryptTlsVnc - puts stderr "selected rfbVencryptTlsVnc" - } elseif [info exists subtypes($rfbVencryptTlsPlain)] { - set subtype $rfbVencryptTlsPlain - puts stderr "selected rfbVencryptTlsPlain" - } - append_handshake "subtype=$subtype" - set st [binary format I $subtype] - puts -nonewline $sock $st - flush $sock - - if {$subtype == 0} { - puts stderr "vencrypt could not find an acceptable subtype: $subtype" - destroy .; exit 1 - } - - set t [vread 1 $sock] - binary scan $t c result - puts stderr "result=$result" - - append_handshake "done" - - if {$result == 0} { - puts stderr "vencrypt failure result: $result" - destroy .; exit 1 - } - -} - -proc do_connect_vencrypt {sock hostport which} { - global debug cur_proxy - - vencrypt_constants - - puts stderr "pxy=$which vencrypt $hostport via $cur_proxy" - bmesg "V: $which vencrypt $hostport via $cur_proxy" - - append_handshake "mode=connect" - - set srfb [vread 12 $sock] - puts stderr "srfb: $srfb" - bmesg "srfb: $srfb" - set srfb [string trim $srfb] - append_handshake "server=$srfb" - - set minor "" - if [regexp {^RFB 00[456]\.} $srfb] { - set minor 8 - } elseif [regexp {^RFB 003\.0*([0-9][0-9]*)} $srfb mvar minor] { - ; - } - if {$minor == "" || $minor < 7} { - puts stderr "vencrypt failure bad minor=$minor" - destroy .; exit 1 - } - - set vrfb "RFB 003.008\n" - if {$minor == 7} { - set vrfb "RFB 003.007\n" - } - puts -nonewline $sock $vrfb - flush $sock - - set vrfb [string trim $vrfb] - append_handshake "viewer=$vrfb" - append_handshake "latency=0.10" - - set str [vread 1 $sock] - binary scan $str c nsec - puts stderr "nsec: $nsec" - bmesg "nsec: $nsec" - for {set i 0} {$i < $nsec} {incr i} { - set str [vread 1 $sock] - binary scan $str c sec - puts stderr "sec: $sec" - bmesg "sec: $sec" - set sectypes($i) $sec - } - for {set i 0} {$i < $nsec} {incr i} { - if {$sectypes($i) == $rfbSecTypeVencrypt} { - append_handshake "sectype=$rfbSecTypeVencrypt" - vsend_uchar $sock $rfbSecTypeVencrypt - after 500 - bmesg "do_vencrypt $sock $which" - do_vencrypt $sock $which - return - } - } - for {set i 0} {$i < $nsec} {incr i} { - if {$sectypes($i) == $rfbSecTypeAnonTls} { - append_handshake "sectype=$rfbSecTypeAnonTls" - vsend_uchar $sock $rfbSecTypeAnonTls - bmesg "rfbSecTypeAnonTls" - after 500 - append_handshake "done" - return - } - } -} - -proc do_connect {sock type hostport which} { - if {$type == "http"} { - do_connect_http $sock $hostport $which - } elseif {$type == "socks"} { - do_connect_socks4 $sock $hostport $which - } elseif {$type == "socks5"} { - do_connect_socks5 $sock $hostport $which - } elseif [regexp -nocase {^repeater:} $type] { - regsub -nocase {^repeater:} $type "" repeater - do_connect_repeater $sock $hostport $which $repeater - } elseif {$type == "vencrypt"} { - do_connect_vencrypt $sock $hostport $which - } -} - -proc handle_connection {fh host port} { - global proxy1_host proxy1_port proxy1_type - global proxy2_host proxy2_port proxy2_type - global proxy3_host proxy3_port proxy3_type - global proxy1 proxy2 proxy3 dest - global debug cur_proxy - global got_connection - - if {$got_connection} { - catch {close $fh} - return - } - set got_connection 1 - - if {$debug} { - puts stderr "connection from: $host $port" - puts stderr "socket $proxy1_host $proxy1_port" - } - - set rc [catch {set sock [socket $proxy1_host $proxy1_port]}] - if {$rc != 0} { - puts stderr "error connecting" - catch {close $sock} - destroy . - exit - } - - if {$debug} { - puts stderr "got sock: $sock" - } - - global client_fh server_fh - set client_fh $fh - set server_fh $sock - - fconfigure $fh -translation binary -blocking 0 - fconfigure $sock -translation binary -blocking 0 - - set cur_proxy $proxy1 - if {$proxy2 != ""} { - do_connect $sock $proxy1_type "$proxy2_host:$proxy2_port" 1 - - set cur_proxy $proxy2 - if {$proxy3 != ""} { - do_connect $sock $proxy2_type "$proxy3_host:$proxy3_port" 2 - - set cur_proxy $proxy3 - do_connect $sock $proxy3_type $dest 3 - - } else { - do_connect $sock $proxy2_type $dest 2 - } - } else { - do_connect $sock $proxy1_type $dest 1 - } - - fileevent $fh readable xfer_in_to_out - fileevent $sock readable xfer_out_to_in -} - -proc proxy_type {proxy} { - if [regexp -nocase {^socks://} $proxy] { - return "socks" - } elseif [regexp -nocase {^socks4://} $proxy] { - return "socks" - } elseif [regexp -nocase {^socks4a://} $proxy] { - return "socks" - } elseif [regexp -nocase {^socks5://} $proxy] { - return "socks5" - } elseif [regexp -nocase {^http://} $proxy] { - return "http" - } elseif [regexp -nocase {^https://} $proxy] { - return "http" - } elseif [regexp -nocase {^repeater://.*\+(.*)$} $proxy mat idstr] { - return "repeater:$idstr" - } elseif [regexp -nocase {^vencrypt://} $proxy] { - return "vencrypt" - } else { - return "http" - } -} - -proc proxy_hostport {proxy} { - regsub -nocase {^[a-z][a-z0-9]*://} $proxy "" hp - regsub {\+.*$} $hp "" hp - if {! [regexp {:[0-9]} $hp] && [regexp {^repeater:} $proxy]} { - set hp "$hp:5900" - } - return $hp -} - -proc setb {} { - wm withdraw . - catch {destroy .b} - button .b -text "CONNECT_BR" -command {destroy .} - pack .b - after 1000 check_callback -} - -proc connect_br_sleep {} { - global env - if [info exists env(CONNECT_BR_SLEEP)] { - if [regexp {^[0-9][0-9]*$} $env(CONNECT_BR_SLEEP)] { - setb - for {set i 0} {$i < $env(CONNECT_BR_SLEEP)} {incr i} { - bmesg "$i sleep" - after 1000 - } - } - } -} - -global env - -set got_connection 0 -set proxy1 "" -set proxy2 "" -set proxy3 "" -set client_fh "" -set server_fh "" -set do_bridge 0 -set debug 0 - -if [info exists env(CONNECT_BR_DEBUG)] { - set debug 1 -} - -if [info exists env(SSVNC_VENCRYPT_VIEWER_BRIDGE)] { - set s [split $env(SSVNC_VENCRYPT_VIEWER_BRIDGE) ","] - set listen [lindex $s 0] - set connect [lindex $s 1] - - setb - - do_vencrypt_viewer_bridge $listen $connect - set do_bridge 1 -} - -if {$do_bridge} { - ; -} else { - if {$debug && 0} { - if {! [info exists env(SSVNC_DEST)]} { - set env(SSVNC_DEST) "haystack:2037" - } - if {! [info exists env(SSVNC_PROXY)]} { - set env(SSVNC_PROXY) "haystack:2037" - } - if {! [info exists env(SSVNC_LISTEN)]} { - set env(SSVNC_LISTEN) "6789" - } - } else { - if {! [info exists env(SSVNC_DEST)]} { - destroy .; exit; - } - if {! [info exists env(SSVNC_PROXY)]} { - destroy .; exit; - } - if {! [info exists env(SSVNC_LISTEN)] && ! [info exists env(SSVNC_REVERSE)]} { - destroy .; exit; - } - } - - #set env(BMESG) 1 - - set dest $env(SSVNC_DEST) - - if [regexp {,} $env(SSVNC_PROXY)] { - set s [split $env(SSVNC_PROXY) ","] - set proxy1 [lindex $s 0] - set proxy2 [lindex $s 1] - set proxy3 [lindex $s 2] - } else { - set proxy1 $env(SSVNC_PROXY) - } - - set proxy1_type [proxy_type $proxy1] - set proxy1_hp [proxy_hostport $proxy1] - - set proxy1_host "" - set proxy1_port "" - if [regexp {^(.*):([0-9][0-9]*)$} $proxy1_hp mvar proxy1_host proxy1_port] { - ; - } else { - puts stderr "could not parse hp1 host:port $proxy1_hp" - destroy . - exit 1 - } - - set proxy2_type "" - set proxy2_host "" - set proxy2_port "" - - if {$proxy2 != ""} { - set proxy2_type [proxy_type $proxy2] - set proxy2_hp [proxy_hostport $proxy2] - - set proxy2_host "" - set proxy2_port "" - if [regexp {^(.*):([0-9][0-9]*)$} $proxy2_hp mvar proxy2_host proxy2_port] { - ; - } else { - puts stderr "could not parse hp2 host:port $proxy2_hp" - destroy . - exit 1 - } - } - - set proxy3_type "" - set proxy3_host "" - set proxy3_port "" - - if {$proxy3 != ""} { - set proxy3_type [proxy_type $proxy3] - set proxy3_hp [proxy_hostport $proxy3] - - set proxy3_host "" - set proxy3_port "" - if [regexp {^(.*):([0-9][0-9]*)$} $proxy3_hp mvar proxy3_host proxy3_port] { - ; - } else { - puts stderr "could not parse hp3 host:port $proxy3_hp" - destroy . - exit 1 - } - } - - bmesg "1: '$proxy1_host' '$proxy1_port' '$proxy1_type'"; - bmesg "2: '$proxy2_host' '$proxy2_port' '$proxy2_type'"; - bmesg "3: '$proxy3_host' '$proxy3_port' '$proxy3_type'"; - - if [info exists env(SSVNC_REVERSE)] { - set rhost "" - set rport "" - if [regexp {^(.*):([0-9][0-9]*)$} $env(SSVNC_REVERSE) mvar rhost rport] { - ; - } else { - puts stderr "could not parse SSVNC_REVERSE host:port $env(SSVNC_REVERSE)" - destroy . - exit 1 - } - setb - set rc [catch {set lsock [socket $rhost $rport]}] - if {$rc != 0} { - puts stderr "error reversing" - bmesg "1 error reversing" - after 2000 - set rc [catch {set lsock [socket $rhost $rport]}] - } - if {$rc != 0} { - puts stderr "error reversing" - bmesg "2 error reversing" - after 2000 - set rc [catch {set lsock [socket $rhost $rport]}] - } - if {$rc != 0} { - puts stderr "error reversing" - bmesg "3 error reversing" - destroy .; exit 1 - } - puts stderr "SSVNC_REVERSE to $rhost $rport OK"; - bmesg "SSVNC_REVERSE to $rhost $rport OK"; - connect_br_sleep - handle_connection $lsock $rhost $rport - } else { - set lport $env(SSVNC_LISTEN) - connect_br_sleep - set rc [catch {set lsock [socket -myaddr 127.0.0.1 -server handle_connection $lport]}] - if {$rc != 0} { - puts stderr "error listening" - destroy .; exit 1 - } - puts stderr "SSVNC_LISTEN on $lport OK"; - setb - } -} diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/download.url deleted file mode 100644 index 59f1f6b..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/download.url +++ /dev/null @@ -1 +0,0 @@ -http://www.tux.org/~ricdude/EsounD.html diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/download.url deleted file mode 100644 index 237d4b1..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/download.url +++ /dev/null @@ -1 +0,0 @@ -http://www.stunnel.org/download/stunnel/win32/ diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/location.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/location.url deleted file mode 100644 index c700866..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/location.url +++ /dev/null @@ -1 +0,0 @@ -http://www.stunnel.org/download/binaries.html diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/download.url deleted file mode 100644 index a23901e..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/download.url +++ /dev/null @@ -1 +0,0 @@ -http://www.chiark.greenend.org.uk/%7esgtatham/putty/download.html diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licence.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licence.url deleted file mode 100644 index 2efcc31..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licence.url +++ /dev/null @@ -1 +0,0 @@ -http://www.chiark.greenend.org.uk/%7esgtatham/putty/licence.html diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/download.url deleted file mode 100644 index 237d4b1..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/download.url +++ /dev/null @@ -1 +0,0 @@ -http://www.stunnel.org/download/stunnel/win32/ diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/location.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/location.url deleted file mode 100644 index 4f87491..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/location.url +++ /dev/null @@ -1,2 +0,0 @@ -http://www.stunnel.org/download/binaries.html -http://stunnel.mirt.net/ diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/download.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/download.url deleted file mode 100644 index 36c60e4..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/download.url +++ /dev/null @@ -1 +0,0 @@ -http://www.tightvnc.com/download.html diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/location.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/location.url deleted file mode 100644 index a686ae0..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/location.url +++ /dev/null @@ -1 +0,0 @@ -http://www.tightvnc.com diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.conf b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.conf deleted file mode 100644 index 7517e23..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.conf +++ /dev/null @@ -1,43 +0,0 @@ -# -# Example SSL stunnel CLIENT configuration file. (you run stunnel on -# this machine and point your vnc viewer to it, it goes to remote VNC -# server via SSL) -# -# To use this file you will need to edit it. Then you will need -# to manually start up stunnel using it. -# (e.g. /path/to/stunnel stunnel-server.conf) -# -# This is just an example and is not used by the tools in this package. -# It is here to show how to create outgoing SSL connections to remote -# VNC servers when not using the tools in this package. -# -client = yes -options = ALL -RNDbytes = 2048 -RNDfile = bananarand.bin -RNDoverwrite = yes -# -# Remote server certs could go here: -# CApath = /path/to/.../crt-dir -# CAfile = /path/to/.../foo.crt -# verify = 2 -# My cert could go here: -# cert = /path/to/.../my.pem -# -[vnc] -# -# Set to local listening port number (e.g. 5900 for vnc display 0): -# -accept = localhost:5900 -# -# Set to remote host:port to connect to (e.g. far-away.east:5900): -# (this is where the VNC server is. :0 -> port 5900, etc) -# -connect = HOST:PORT -delay = no -# -# You could add additional ones going to other VNC servers: -# [vnc2] -# accept = localhost:5901 -# connect = HOST2:PORT2 -# etc ... diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.conf b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.conf deleted file mode 100644 index 8e5dd50..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.conf +++ /dev/null @@ -1,34 +0,0 @@ -# -# Example SSL stunnel SERVER configuration file. (e.g. for your VNC -# server on this same machine.) -# -# To use this file you may need to edit it. Then you will need -# to manually start up stunnel using it. -# (e.g. /path/to/stunnel stunnel-server.conf) -# -# This is just an example and is not used by the tools in this package. -# It is here in case you wanted to see how to add SSL support to any -# VNC server you have. -# -RNDbytes = 2048 -RNDfile = bananarand.bin -RNDoverwrite = yes -# -# Remote client certs could go here: -# CApath = /path/to/.../crt-dir -# CAfile = /path/to/.../foo.crt -# verify = 2 -# My server cert could go here: -# cert = /path/to/.../my.pem -# -[vnc] -# -# Set to local listening port number (e.g. 5901 for vnc display 1): -# so the remote viewers would connect to: yourmachine:1 -# -accept = 5901 -# -# Set to localhost:port to connect to VNC server on this same machine: -# (E.g. you run WinVNC on :0, preferably listening on localhost). -# -connect = localhost:5900 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url b/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url deleted file mode 100644 index eb94b91..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url +++ /dev/null @@ -1 +0,0 @@ -ftp://ftp.microsoft.com/Services/TechNet/samples/PS/Win98/Reskit/DIAGNOSE/ diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cpover b/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cpover deleted file mode 100755 index 45ec5ae..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cpover +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -cp -p vncviewer.sh vncviewer -pwd -ls -l vncviewer.sh vncviewer - -(cd ../Darwin.i386; .cpover) diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vncviewer.sh b/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vncviewer.sh deleted file mode 100755 index 92dcefb..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vncviewer.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -# copy "vncviewer.sh" back over to "vncviewer" in case you delete or overwrite it -# via build.unix. etc - -dir=`dirname "$0"` - -if [ "X$SSVNC_DYLD_LIBRARY_PATH" != "X" ]; then - if [ "X$DYLD_LIBRARY_PATH" = "X" ] ; then - DYLD_LIBRARY_PATH=$SSVNC_DYLD_LIBRARY_PATH - else - DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$SSVNC_DYLD_LIBRARY_PATH - fi - export DYLD_LIBRARY_PATH -fi - -if [ "X$DISPLAY" != "X" -a "X$DARWIN_COTVNC" != "X1" ]; then - "$dir/vncviewer.x11" "$@" -else - args="" - for a in "$@" - do - if echo "$a" | grep '^-' > /dev/null; then - args="$args $a" - elif echo "$a" | grep ':' > /dev/null; then - h=`echo "$a" | awk -F: '{print $1}'` - p=`echo "$a" | awk -F: '{print $2}'` - if [ "X$p" != "X" ]; then - if [ $p -lt 5900 ]; then - p=`expr $p + 5900` - fi - fi - args="$args $h:$p" - else - args="$args $a" - fi - done - "$dir/../../MacOSX/Chicken of the VNC.app/Contents/MacOS/Chicken of the VNC" $args -fi diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover b/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover deleted file mode 100755 index c0080b1..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -cp -p ../Darwin.Power.Macintosh/vncviewer.sh . -cp -p vncviewer.sh vncviewer -pwd -ls -l vncviewer.sh vncviewer diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc deleted file mode 100755 index a427b42..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -# -# wrapper for SSH_ONLY mode -# -PATH=`dirname "$0"`:$PATH; export PATH -SSVNC_SSH_ONLY=1; export SSVNC_SSH_ONLY -exec ssvnc -ssh "$@" diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc deleted file mode 100755 index 9cd636b..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc +++ /dev/null @@ -1,289 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com> -# -# ssvnc: -# -# A wrapper for ssvnc_cmd using a tcl/tk gui. -# -# See ssvnc_cmd for details. -# -if [ "X$1" = "X-help" -o "X$1" = "X-h" ]; then - cat << END -ssvnc - a GUI wrapper for SSL and SSH VNC connections. - -SYNOPSIS - ssvnc - ssvnc [host][:display] - ssvnc [saved-profile-name] - ssvnc [options] [host-or-profile] - ssvnc -cmd [ssvnc_cmd-args] - ssvnc --help - -DESCRIPTION - ssvnc is a tcl/tk gui wrapper that runs on Unix, MacOSX, and Windows. - It sets up an SSL or SSH tunnel to the remote VNC Server and then - launches the VNC viewer (either the one provided or another one that - you have specified) to use that encrypted tunnel to connect to the VNC - Server. The use of Proxies and Gateways to make the connections is - implemented. - -OPTIONS - -help, -h Print this help. - - --help Starts up the GUI as though the 'Help' button was pressed to - show the main Help panel. - - -cmd [ssvnc_cmd-args] - Launch the ssvnc_cmd utility command directly (no GUI) with the - given arguments (for use when ssvnc_cmd is not in one's PATH.) - If neither ssvnc_cmd nor ssvncviewer is in PATH, one can launch - the viewer directly via: ssvnc -cmd -viewer [viewer-args] - - -profiles - List the saved SSVNC profiles you have created. A profile is a - destination host with specific parameter settings. - - -list Same as -profiles - - -ssh Start in "SSH Only Mode". No SSL aspects are shown. Same as - running the command sshvnc - - -ts Start in "Terminal Services Mode". This is like "SSH Only - Mode", but simpler and assumes x11vnc is available on the remote - side to start and manage X and VNC sessions. Same as running - the command tsvnc - - -tso Same as -ts "Terminal Services Mode", however never let the user - leave this mode (no button to switch modes is provided.) Same - as SSVNC_TS_ALWAYS=1. - - -ssl Force the full GUI Mode: both SSL and SSH. This is the default. - Same as -ss. - - -nv Toggle the "Verify All Certs" button to be off at startup. - - -nvb Never show the "Verify All Certs" button. Same as SSVNC_NO_VER- - IFY_ALL_BUTTON=1. - - -bigger - Make the Profile Selection Dialog window bigger. Same as - SSVNC_BIGGER_DIALOG=1. - - -noenc Start off in a mode where a 'No Encryption' check button is - present. You can toggle the mode with Ctrl-E. Same as - SSVNC_DISABLE_ENCRYPTION_BUTTON=1. Or noenc=1 in ~/.ssvncrc. - Selecting no encryption is the same as the vnc:// and Vnc:// - prefixes described below. The -noenc mode is now the default, - use -enc or noenc=0 for the opposite behavior. - - -killstunnel - On Windows, automatically terminate the STUNNEL process when the - viewer exits instead of prompting you (same as killstunnel=1 in - ssvnc_rc or toggle in Options menu) - - -nokillstunnel - On Windows, disable -killstunnel mode. Same as killstunnel=0 in - ssvnc_rc or toggle in Options menu. Note that -killstunnel mode - is now the default. - - -mycert /path/to/mycert.pem - Set the default "MyCert" to be /path/to/mycert.pem. Same as - -cert. If the file does not exist, ~/.vnc/certs is prefixed and - tried. You can also set mycert=/path/to/mycert.pem in ~/.ssvncrc - - -cacert /path/to/cacert.crt - Set the default "ServerCert" to be /path/to/cacert.crt. Same as - -ca. If the file does not exist, ~/.vnc/certs is prefixed and - tried. You can also set cacert=/path/to/cacert.crt in ~/.ssvncrc - - -crl /path/to/mycrl.pem - Set the default Certificate Revocation List to be - /path/to/mycrl.pem. If the file does not exist, ~/.vnc/certs is - prefixed and tried. You can also set crl=/path/to/mycrl.pem in - ~/.ssvncrc. -END - exit 0 -fi -if [ "X$1" = "X-ssh" ]; then - if [ "X$2" = "X-help" -o "X$2" = "X-h" ]; then - cat << END -sshvnc - a GUI wrapper for SSH VNC connections. - -SYNOPSIS - sshvnc - sshvnc [host][:display] - sshvnc [saved-profile-name] - sshvnc [options] [host-or-profile] - sshvnc --help - -See 'ssvnc $2' and 'ssvnc --help' for more information. -END - exit 0 - fi -fi - -if [ "X$1" = "X-ts" -o "X$1" = "X-tso" ]; then - if [ "X$2" = "X-help" -o "X$2" = "X-h" ]; then - cat << END -tsvnc - a GUI wrapper for SSH VNC connections using x11vnc Terminal Services. - -SYNOPSIS - tsvnc - tsvnc [host][:display] - tsvnc [saved-profile-name] - tsvnc [options] [host-or-profile] - tsvnc --help - -See 'ssvnc $2' and 'tsvnc --help' for more information. -END - exit 0 - fi -fi - - -if [ "X$XTERM_PRINT" != "X" ]; then - XTERM_PRINT="" - cat > /dev/null -fi -if [ "X$1" = "X-bg" ]; then - shift - $0 "$@" & - exit 0 -fi - - -PATH=$PATH:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/openwin/bin:/usr/sfw/bin:/usr/local/bin -export PATH - -if [ "X$FULLNAME" = "XKarl J. Runge" ]; then - if [ "X$NOPOPUFIX" = "X" ]; then - VNCVIEWER_POPUP_FIX=1 - export VNCVIEWER_POPUP_FIX - fi - PATH=`echo "$PATH" | sed -e 's,runge/bin/override,-------------,'` -fi - -if [ "X$WISH" = "X" ]; then - WISH=wish - for try in wish8.4 wish wish8.3 wish8.5 wish8.6 - do - if type $try > /dev/null 2>&1; then - WISH=$try - break - fi - done - export WISH -fi - - -SSVNC_GUI_CMD="$0 $*" -export SSVNC_GUI_CMD -SSVNC_LAUNCH=$SSVNC_GUI_CMD -export SSVNC_LAUNCH - -# work out os.arch platform string and check for binaries: -# -name=$UNAME -if [ "X$name" = "X" ]; then - name=`uname -sm | sed -e 's/ /./g' -e 's,/.*,,' -e 's/Linux\.i.86/Linux.i686/'` -fi - -dL="-L" -if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then - dL="-h" -fi - -f="$0" -for t in 1 2 3 4 5 -do - if [ $dL "$f" ]; then - f0="$f" - f=`ls -l "$f" | sed -e 's/^.* -> //'` - if echo "$f" | grep '^/' > /dev/null; then - : - else - f="`dirname "$f0"`/$f" - fi - else - break - fi -done -dir=`dirname "$f"` -PATH="$dir:$PATH" - -nearby=0 -if [ -x "$dir/vncviewer" -a -x "$dir/stunnel" ]; then - nearby=1 -fi -if [ "X$name" = "X." ]; then - : - #type vncviewer - #type stunnel -elif [ ! -d "$dir/$name" -a $nearby = 0 ]; then - echo - echo "Cannot find platform dir for your OS `uname -sm`:" - echo - echo " $dir/$name" - echo - PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin - - quit=0 - if type vncviewer >/dev/null 2>/dev/null; then - : - else - echo "vncviewer not found in PATH." - quit=1 - fi - if type stunnel >/dev/null 2>/dev/null; then - : - else - echo "stunnel not found in PATH." - quit=1 - fi - echo - if [ "X$quit" = "X1" ]; then - echo "You can set the \$UNAME env. var. to override the OS setting." - echo "Or, if available, run the ./build.unix script to build it." - echo "Or install external \"vncviewer\" and \"stunnel\" packages." - exit 1 - fi - echo "Using externel \"vncviewer\" and \"stunnel\" found in PATH." -else - STUNNEL=stunnel - #STUNNEL_EXTRA_OPTS=${STUNNEL_EXTRA_OPTS:-"maxconn = 1"} - #export STUNNEL STUNNEL_EXTRA_OPTS - SSVNC_VIEWER_INTERNAL=1 - export SSVNC_VIEWER_INTERNAL -fi - - -# Put our os.arch and other utils dirs at head of PATH to be sure to -# pick them up: -# -PATH="$dir:$dir/$name:$dir/util:$PATH" -if echo "$dir" | grep '^/' > /dev/null; then - : -else - dir=`pwd`/$dir - PATH="$dir:$dir/$name:$dir/util:$PATH" -fi - -SSVNC_BASEDIR="$dir" -export SSVNC_BASEDIR -SSVNC_BASEDIRNAME="$dir/$name" -export SSVNC_BASEDIRNAME - -if [ -f "$dir/util/ultraftp.jar" ]; then - SSVNC_ULTRA_FTP_JAR="$dir/util/ultraftp.jar" - export SSVNC_ULTRA_FTP_JAR -fi - -if [ "X$1" = "X-cmd" -o "X$1" = "X--cmd" ]; then - shift - exec ssvnc_cmd "$@" -elif [ "X$WISH" = "Xwish" ]; then - exec ssvnc.tcl "$@" -else - exec $WISH $dir/util/ssvnc.tcl "$@" -fi diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd b/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd deleted file mode 100755 index f84eb58..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd +++ /dev/null @@ -1,286 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com> -# -# ssvnc_cmd: -# -# A wrapper that calls ss_vncviewer to use the enhanced TightVNC viewer. -# -# The enhanced TightVNC viewer features are: -# -# - SSL support for connections using the co-bundled stunnel program. -# - rfbNewFBSize VNC support (screen resizing) -# - cursor alphablending with x11vnc at 32bpp -# - xgrabserver support for fullscreen mode (for old window mgrs) -# -# -# Your platform (e.g. Linux.i686) is autodetected and enhanced -# vncviewer and stunnel binaries for it are used (see the ./bin directory). -# -# See the build.unix script if your platform is not in this package. -# You can also set the env. var. UNAME=os.arch to any "os.arch" you want -# to override the autodetetion. -# -# Usage: -# -# ssvnc_cmd [ss_vncviewer-args] hostname:N [vncviewer-args] -# -# if, instead, this script is named "tightvncviewer" or "-viewer" is the -# first argument it calls the vncviewer directly (there is no encryption) -# and must be invoked as: -# -# tightvncviewer [vncviewer-args] hostname:N -# or -# ssvnc_cmd -viewer [vncviewer-args] hostname:N -# -# In both cases, "hostname:N" is the host and VNC display to connect to, -# e.g. snoopy:0. (-listen N and -appshare N modes works too.) -# -# See the script util/ss_vncviewer for details about its arguments: -# -# -verify pemfile -# -mycert pemfile -# -proxy phost:pport -# -alpha -# -grab -# -# N.B. if this script is named "tightvncviewer" the vncviewer is called -# directly, and there won't be any SSL or SSH encryption tunnels. -# -# If the *very first* argument is "-cotvnc" then it is assumed you are on -# Darwin and want to run the Chicken of the VNC viewer via our wrapper. -# -# -# See the TightVNC viewer documentation for on its cmdline arguments. -# -# For convenience, here is the TightVNC 1.3dev5 viewer -help output: -# -# TightVNC viewer version 1.3dev5 -# -# Usage: vncviewer [<OPTIONS>] [<HOST>][:<DISPLAY#>] -# vncviewer [<OPTIONS>] [<HOST>][::<PORT#>] -# vncviewer [<OPTIONS>] -listen [<DISPLAY#>] -# vncviewer -help -# -# <OPTIONS> are standard Xt options, or: -# -via <GATEWAY> -# -shared (set by default) -# -noshared -# -viewonly -# -fullscreen -# -noraiseonbeep -# -passwd <PASSWD-FILENAME> (standard VNC authentication) -# -user <USERNAME> (Unix login authentication) -# -encodings <ENCODING-LIST> (e.g. "tight copyrect") -# -bgr233 -# -owncmap -# -truecolour -# -depth <DEPTH> -# -compresslevel <COMPRESS-VALUE> (0..9: 0-fast, 9-best) -# -quality <JPEG-QUALITY-VALUE> (0..9: 0-low, 9-high) -# -nojpeg -# -nocursorshape -# -x11cursor -# -autopass -# -# Option names may be abbreviated, e.g. -bgr instead of -bgr233. -# See the manual page for more information. -# -# Note: the enhanced tightvnc viewer (SSVNC) has many more options, run -# this script as "ssvnc_cmd Vnc://a:0 -help" or "tightvncviewer -help" -# to seem them. - -if [ "X$1" = "X-h" -o "X$1" = "X-helpxxx" -o "X$1" = "X--help" ]; then - tail -n +2 "$0" | sed -e '/^$/ q' -e 's/^#//' - exit -fi - -# Include /usr/bin... to be sure to get regular utilities: -# -PATH=$PATH:/usr/bin:/bin -export PATH - -if [ "X$FULLNAME" = "XKarl J. Runge" ]; then - if [ "X$NOPOPUFIX" = "X" ]; then - VNCVIEWER_POPUP_FIX=1 - export VNCVIEWER_POPUP_FIX - fi - PATH=`echo "$PATH" | sed -e 's,runge/bin/override,-------------,'` -fi - -# Set this for ss_vncviewer to pick up: -# -if [ "X$1" = "X-cotvnc" ]; then - shift - DARWIN_COTVNC=1 - export DARWIN_COTVNC -elif [ "X$DARWIN_COTVNC" = "X" -a "X$DISPLAY" = "X" ]; then - uname=`uname` - if [ "X$uname" = "XDarwin" ]; then - DARWIN_COTVNC=1 - export DARWIN_COTVNC - fi -fi - -use_ours=0 -if [ "X$VNCVIEWERCMD" = "X" ]; then - VNCVIEWERCMD="vncviewer" - export VNCVIEWERCMD - if [ "X$DARWIN_COTVNC" != "X1" ]; then - use_ours=1 - fi -fi - -# work out os.arch platform string and check for binaries: -# -name=$UNAME -if [ "X$name" = "X" ]; then - name=`uname -sm | sed -e 's/ /./g' -e 's,/.*,,' -e 's/Linux\.i.86/Linux.i686/'` -fi - -dL="-L" -if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then - dL="-h" -fi - -f="$0" -for t in 1 2 3 4 5 6 -do - if [ $dL "$f" ]; then - f0="$f" - f=`ls -l "$f" | sed -e 's/^.* -> //'` - if echo "$f" | grep '^/' > /dev/null; then - : - else - f="`dirname "$f0"`/$f" - fi - else - break - fi -done -dir=`dirname "$f"` -PATH="$dir:$PATH" -SSVNC_BASEDIR="$dir" -export SSVNC_BASEDIR -SSVNC_BASEDIRNAME="$dir/$name" -export SSVNC_BASEDIRNAME -SSVNC_UNAME="$name" -export SSVNC_UNAME - -nearby=0 -if [ -x "$dir/vncviewer" -a -x "$dir/stunnel" ]; then - nearby=1 -fi -if [ "X$name" = "X." ]; then - : - #type vncviewer - #type stunnel -elif [ ! -d "$dir/$name" -a $nearby = 0 ]; then - echo - echo "Cannot find platform dir for your OS `uname -sm`:" - echo - echo " $dir/$name" - echo - PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin - - quit=0 - if type vncviewer >/dev/null 2>/dev/null; then - : - else - echo "vncviewer not found in PATH." - quit=1 - fi - if type stunnel >/dev/null 2>/dev/null; then - : - else - echo "stunnel not found in PATH." - quit=1 - fi - echo - if [ "X$quit" = "X1" ]; then - echo "You can set the \$UNAME env. var. to override the OS setting." - echo "Or, if available, run the ./build.unix script to build it." - echo "Or install external \"vncviewer\" and \"stunnel\" packages." - exit 1 - fi - echo "Using externel \"vncviewer\" and \"stunnel\" found in PATH." - -else - STUNNEL=stunnel - #STUNNEL_EXTRA_OPTS=${STUNNEL_EXTRA_OPTS:-"maxconn = 1"} - #export STUNNEL STUNNEL_EXTRA_OPTS - SSVNC_VIEWER_INTERNAL=1 - export SSVNC_VIEWER_INTERNAL -fi - -if [ "X$DARWIN_COTVNC" != "X1" -a "X$VNCVIEWERCMD" = "Xvncviewer" ]; then - hstr=`$VNCVIEWERCMD -h 2>&1 | head -5` - if echo "$hstr" | grep 'SSVNC.*TightVNC.*version 1\.3' > /dev/null; then - # we need to avoid raw encoding - use_ours=1 - fi -fi - -# Put our os.arch and other utils dirs at head of PATH to be sure to -# pick them up: -# -PATH="$dir:$dir/$name:$dir/util:$PATH" -if echo "$dir" | grep '^/' > /dev/null; then - : -else - dir=`pwd`/$dir - PATH="$dir:$dir/$name:$dir/util:$PATH" -fi - -if [ -f "$dir/util/ultraftp.jar" ]; then - SSVNC_ULTRA_FTP_JAR="$dir/util/ultraftp.jar" - export SSVNC_ULTRA_FTP_JAR -fi - -base=`basename "$0"` -if [ "X$1" = "X-ssl" ]; then - shift - base="ssvnc_cmd" -fi - -do_viewer_directly="" -if [ "X$1" = "X-viewer" ]; then - do_viewer_directly=1 - shift -fi -if [ "X$base" = "Xtightvncviewer" ]; then - do_viewer_directly=1 -fi - -# If ours (and not cotvnc), force the use of tight encoding for localhost -# redir connection: -# -# -if [ $use_ours = 1 ]; then - # avoid system vncviewer app-defaults - #XFILESEARCHPATH="/tmp/path/nowhere"; export XFILESEARCHPATH - - SSVNC_USE_OURS=1; export SSVNC_USE_OURS - - if [ "X$SSVNC_TURBOVNC" != "X" ]; then - if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then - : - else - if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then - VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc" - fi - fi - fi - - if [ "X$do_viewer_directly" = "X1" ]; then - $VNCVIEWERCMD -encodings 'copyrect tight zrle zlib hextile' "$@" - else - ss_vncviewer "$@" -encodings 'copyrect tight zrle zlib hextile' - fi -else - if [ "X$do_viewer_directly" = "X1" ]; then - $VNCVIEWERCMD "$@" - else - ss_vncviewer "$@" - fi -fi diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc b/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc deleted file mode 100755 index acf55c6..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -# -# wrapper for TS_ONLY mode -# -PATH=`dirname "$0"`:$PATH; export PATH -SSVNC_TS_ONLY=1; export SSVNC_TS_ONLY -exec ssvnc -ts "$@" diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer deleted file mode 100755 index b0245af..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer +++ /dev/null @@ -1,3635 +0,0 @@ -#!/bin/sh -# -# ss_vncviewer: wrapper for vncviewer to use an stunnel SSL tunnel -# or an SSH tunnel. -# -# Copyright (c) 2006-2009 by Karl J. Runge <runge@karlrunge.com> -# -# ss_vncviewer 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. -# -# ss_vncviewer 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 ss_vncviewer; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see <http://www.gnu.org/licenses/>. -# -# -# You must have stunnel(8) installed on the system and in your PATH -# (however, see the -ssh option below, in which case you will need ssh(1) -# installed) Note: stunnel is usually installed in an "sbin" subdirectory. -# -# You should have "x11vnc -ssl ..." or "x11vnc -stunnel ..." -# already running as the VNC server on the remote machine. -# (or use stunnel on the server side for any other VNC server) -# -# -# Usage: ss_vncviewer [cert-args] host:display <vncviewer-args> -# -# e.g.: ss_vncviewer snoopy:0 -# ss_vncviewer snoopy:0 -encodings "copyrect tight zrle hextile" -# -# [cert-args] can be: -# -# -verify /path/to/cacert.pem -# -mycert /path/to/mycert.pem -# -crl /path/to/my_crl.pem (or directory) -# -proxy host:port -# -# -verify specifies a CA cert PEM file (or a self-signed one) for -# authenticating the VNC server. -# -# -mycert specifies this client's cert+key PEM file for the VNC server to -# authenticate this client. -# -# -proxy try host:port as a Web proxy to use the CONNECT method -# to reach the VNC server (e.g. your firewall requires a proxy). -# -# For the "double proxy" case use -proxy host1:port1,host2:port2 -# (the first CONNECT is done through host1:port1 to host2:port2 -# and then a 2nd CONNECT to the destination VNC server.) -# -# Use socks://host:port, socks4://host:port, or socks5://host,port -# to force usage of a SOCKS proxy. Also repeater://host:port and -# sslrepeater://host:port. -# -# -showcert Only fetch the certificate using the 'openssl s_client' -# command (openssl(1) must in installed). On ssvnc 1.0.27 and -# later the bundled command 'ultravnc_dsm_helper' is used. -# -# See http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca for details on -# SSL certificates with VNC. -# -# A few other args (not related to SSL and certs): -# -# -2nd Run the vncviewer a 2nd time if the first connections fails. -# -# -ssh Use ssh instead of stunnel SSL. ssh(1) must be installed and you -# must be able to log into the remote machine via ssh. -# -# In this case "host:display" may be of the form "user@host:display" -# where "user@host" is used for the ssh login (see ssh(1) manpage). -# -# If -proxy is supplied it can be of the forms: "gwhost" "gwhost:port" -# "user@gwhost" or "user@gwhost:port". "gwhost" is an incoming ssh -# gateway machine (the VNC server is not running there), an ssh -L -# redir is used to "host" in "host:display" from "gwhost". Any "user@" -# part must be in the -proxy string (not in "host:display"). -# -# Under -proxy use "gwhost:port" if connecting to any ssh port -# other than the default (22). (even for the non-gateway case, -# -proxy must be used to specify a non-standard ssh port) -# -# A "double ssh" can be specified via a -proxy string with the two -# hosts separated by a comma: -# -# [user1@]host1[:port1],[user2@]host2[:port2] -# -# in which case a ssh to host1 and thru it via a -L redir a 2nd -# ssh is established to host2. -# -# Examples: -# -# ss_vncviewer -ssh bob@bobs-home.net:0 -# ss_vncviewer -ssh -sshcmd 'x11vnc -localhost' bob@bobs-home.net:0 -# -# ss_vncviewer -ssh -proxy fred@mygate.com:2022 mymachine:0 -# ss_vncviewer -ssh -proxy bob@bobs-home.net:2222 localhost:0 -# -# ss_vncviewer -ssh -proxy fred@gw-host,fred@peecee localhost:0 -# -# -sshcmd cmd Run "cmd" via ssh instead of the default "sleep 15" -# e.g. -sshcmd 'x11vnc -display :0 -localhost -rfbport 5900' -# -# -sshargs "args" pass "args" to the ssh process, e.g. -L/-R port redirs. -# -# -sshssl Tunnel the SSL connection thru a SSH connection. The tunnel as -# under -ssh is set up and the SSL connection goes thru it. Use -# this if you want to have and end-to-end SSL connection but must -# go thru a SSH gateway host (e.g. not the vnc server). Or use -# this if you need to tunnel additional services via -R and -L -# (see -sshargs above). -# -# ss_vncviewer -sshssl -proxy fred@mygate.com mymachine:0 -# -# -listen (or -reverse) set up a reverse connection. -# -# -alpha turn on cursor alphablending hack if you are using the -# enhanced tightvnc vncviewer. -# -# -grab turn on XGrabServer hack if you are using the enhanced tightvnc -# vncviewer (e.g. for fullscreen mode in some windowmanagers like -# fvwm that do not otherwise work in fullscreen mode) -# -# -# set VNCVIEWERCMD to whatever vncviewer command you want to use. -# -VNCIPCMD=${VNCVIEWERCMD:-vncip} -VNCVIEWERCMD=${VNCVIEWERCMD:-vncviewer} -if [ "X$SSVNC_TURBOVNC" != "X" ]; then - if echo "$VNCVIEWERCMD" | grep '\.turbovnc' > /dev/null; then - : - else - if type "$VNCVIEWERCMD.turbovnc" > /dev/null 2>/dev/null; then - VNCVIEWERCMD="$VNCVIEWERCMD.turbovnc" - fi - fi -fi -# -# Same for STUNNEL, e.g. set it to /path/to/stunnel or stunnel4, etc. -# - -# turn on verbose debugging output -if [ "X$SS_DEBUG" != "X" -a "X$SS_DEBUG" != "X0" ]; then - set -xv -fi - -PATH=$PATH:/usr/sbin:/usr/local/sbin:/dist/sbin; export PATH - -localhost="localhost" -if uname | grep Darwin >/dev/null; then - localhost="127.0.0.1" -fi - -# work out which stunnel to use (debian installs as stunnel4) -stunnel_set_here="" -if [ "X$STUNNEL" = "X" ]; then - check_stunnel=1 - if [ "X$SSVNC_BASEDIRNAME" != "X" ]; then - if [ -x "$SSVNC_BASEDIRNAME/stunnel" ]; then - type stunnel > /dev/null 2>&1 - if [ $? = 0 ]; then - # found ours - STUNNEL=stunnel - check_stunnel=0 - fi - fi - fi - if [ "X$check_stunnel" = "X1" ]; then - type stunnel4 > /dev/null 2>&1 - if [ $? = 0 ]; then - STUNNEL=stunnel4 - else - STUNNEL=stunnel - fi - fi - stunnel_set_here=1 -fi - -help() { - tail -n +2 "$0" | sed -e '/^$/ q' -} - -secondtry="" -gotalpha="" -use_ssh="" -use_sshssl="" -direct_connect="" -ssh_sleep=15 - -# sleep longer in -listen mode: -if echo "$*" | grep '.*-listen' > /dev/null; then - ssh_sleep=1800 -fi - - -ssh_cmd="" -# env override of ssh_cmd: -if [ "X$SS_VNCVIEWER_SSH_CMD" != "X" ]; then - ssh_cmd="$SS_VNCVIEWER_SSH_CMD" -fi - -ssh_args="" -showcert="" -reverse="" - -ciphers="" -anondh="ALL:RC4+RSA:+SSLv2:@STRENGTH" -anondh_set="" -stunnel_debug="6" -if [ "X$SS_DEBUG" != "X" -o "X$SSVNC_VENCRYPT_DEBUG" != "X" -o "X$SSVNC_STUNNEL_DEBUG" != "X" ]; then - stunnel_debug="7" -fi - -if [ "X$1" = "X-viewerflavor" ]; then - # special case, try to guess which viewer: - # - if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then - echo "unknown" - exit 0 - fi - if echo "$VNCVIEWERCMD" | grep -i chicken.of > /dev/null; then - echo "cotvnc" - exit 0 - fi - if echo "$VNCVIEWERCMD" | grep -i ultra > /dev/null; then - echo "ultravnc" - exit 0 - fi - # OK, run it for help output... - str=`$VNCVIEWERCMD -h 2>&1 | head -n 5` - if echo "$str" | grep -i 'TightVNC.viewer' > /dev/null; then - echo "tightvnc" - elif echo "$str" | grep -i 'VNC viewer version 3' > /dev/null; then - echo "realvnc3" - elif echo "$str" | grep -i 'VNC viewer .*Edition 4' > /dev/null; then - echo "realvnc4" - elif echo "$str" | grep -i 'RealVNC.Ltd' > /dev/null; then - echo "realvnc4" - else - echo "unknown" - fi - exit 0 -fi -if [ "X$1" = "X-viewerhelp" ]; then - $VNCVIEWERCMD -h 2>&1 - exit 0 -fi - -# grab our cmdline options: -while [ "X$1" != "X" ] -do - case $1 in - "-verify") shift; verify="$1" - ;; - "-mycert") shift; mycert="$1" - ;; - "-crl") shift; crl="$1" - ;; - "-proxy") shift; proxy="$1" - ;; - "-ssh") use_ssh=1 - ;; - "-sshssl") use_ssh=1 - use_sshssl=1 - ;; - "-sshcmd") shift; ssh_cmd="$1" - ;; - "-sshargs") shift; ssh_args="$1" - ;; - "-anondh") ciphers="ciphers=$anondh" - ULTRAVNC_DSM_HELPER_SHOWCERT_ADH=1 - export ULTRAVNC_DSM_HELPER_SHOWCERT_ADH - anondh_set=1 - ;; - "-ciphers") shift; ciphers="ciphers=$1" - ;; - "-alpha") gotalpha=1 - ;; - "-showcert") showcert=1 - ;; - "-listen") reverse=1 - ;; - "-reverse") reverse=1 - ;; - "-2nd") secondtry=1 - ;; - "-grab") VNCVIEWER_GRAB_SERVER=1; export VNCVIEWER_GRAB_SERVER - ;; - "-x11cursor") VNCVIEWER_X11CURSOR=1; export VNCVIEWER_X11CURSOR - ;; - "-rawlocal") VNCVIEWER_RAWLOCAL=1; export VNCVIEWER_RAWLOCAL - ;; - "-scale") shift; SSVNC_SCALE="$1"; export SSVNC_SCALE - ;; - "-onelisten") SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE - ;; - "-sendclipboard") VNCVIEWER_SEND_CLIPBOARD=1; export VNCVIEWER_SEND_CLIPBOARD - ;; - "-sendalways") VNCVIEWER_SEND_ALWAYS=1; export VNCVIEWER_SEND_ALWAYS - ;; - "-recvtext") shift; VNCVIEWER_RECV_TEXT="$1"; export VNCVIEWER_RECV_TEXT - ;; - "-escape") shift; VNCVIEWER_ESCAPE="$1"; export VNCVIEWER_ESCAPE - ;; - "-ssvnc_encodings") shift; VNCVIEWER_ENCODINGS="$1"; export VNCVIEWER_ENCODINGS - ;; - "-ssvnc_extra_opts") shift; VNCVIEWERCMD_EXTRA_OPTS="$1"; export VNCVIEWERCMD_EXTRA_OPTS - ;; - "-rfbversion") shift; VNCVIEWER_RFBVERSION="$1"; export VNCVIEWER_RFBVERSION - ;; - "-nobell") VNCVIEWER_NOBELL=1; export VNCVIEWER_NOBELL - ;; - "-popupfix") VNCVIEWER_POPUP_FIX=1; export VNCVIEWER_POPUP_FIX - ;; - "-realvnc4") VNCVIEWER_IS_REALVNC4=1; export VNCVIEWER_IS_REALVNC4 - ;; - "-h"*) help; exit 0 - ;; - "--h"*) help; exit 0 - ;; - *) break - ;; - esac - shift -done - -# maxconn is something we added to stunnel, this disables it: -if [ "X$SS_VNCVIEWER_NO_MAXCONN" != "X" ]; then - STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` -elif echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then - STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` -elif [ "X$reverse" != "X" ]; then - STUNNEL_EXTRA_OPTS=`echo "$STUNNEL_EXTRA_OPTS" | sed -e 's/maxconn/#maxconn/'` -else - # new way (our patches). other than the above, we set these: - if [ "X$SKIP_STUNNEL_ONCE" = "X" ]; then - STUNNEL_ONCE=1; export STUNNEL_ONCE - fi - if [ "X$SKIP_STUNNEL_MAX_CLIENTS" = "X" ]; then - STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS - fi -fi -# always set this one: -if [ "X$SKIP_STUNNEL_NO_SYSLOG" = "X" ]; then - STUNNEL_NO_SYSLOG=1; export STUNNEL_NO_SYSLOG -fi - -# this is the -t ssh option (gives better keyboard response thru SSH tunnel) -targ="-t" -if [ "X$SS_VNCVIEWER_NO_T" != "X" ]; then - targ="" -fi - -# set the alpha blending env. hack: -if [ "X$gotalpha" = "X1" ]; then - VNCVIEWER_ALPHABLEND=1 - export VNCVIEWER_ALPHABLEND -else - NO_ALPHABLEND=1 - export NO_ALPHABLEND -fi - -if [ "X$reverse" != "X" ]; then - ssh_sleep=1800 - if [ "X$proxy" != "X" ]; then - # check proxy usage under reverse connection: - if [ "X$use_ssh" = "X" -a "X$use_sshssl" = "X" ]; then - echo "" - if echo "$proxy" | egrep -i "(repeater|vencrypt)://" > /dev/null; then - : - else - echo "*Warning*: SSL -listen and a Web proxy does not make sense." - sleep 2 - fi - elif echo "$proxy" | grep "," > /dev/null; then - : - else - echo "" - echo "*Warning*: -listen and a single proxy/gateway does not make sense." - sleep 2 - fi - - # we now try to PPROXY_LOOP_THYSELF, set this var to disable that. - #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE - fi -fi -if [ "X$ssh_cmd" = "X" ]; then - # if no remote ssh cmd, sleep a bit: - ssh_cmd="sleep $ssh_sleep" -fi - -# this should be a host:display: -# -orig="$1" -shift - -dL="-L" -if uname -sr | egrep 'SunOS 5\.[5-8]' > /dev/null; then - dL="-h" -fi - -have_uvnc_dsm_helper_showcert="" -if [ "X$showcert" = "X1" -a "X$SSVNC_USE_S_CLIENT" = "X" -a "X$reverse" = "X" ]; then - if type ultravnc_dsm_helper >/dev/null 2>&1; then - if ultravnc_dsm_helper -help 2>&1 | grep -w showcert >/dev/null; then - have_uvnc_dsm_helper_showcert=1 - fi - fi -fi -have_uvnc_dsm_helper_ipv6="" -if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then - if type ultravnc_dsm_helper >/dev/null 2>&1; then - if ultravnc_dsm_helper -help 2>&1 | grep -iw ipv6 >/dev/null; then - have_uvnc_dsm_helper_ipv6=1 - fi - fi -fi - -rchk() { - # a kludge to set $RANDOM if we are not bash: - if [ "X$BASH_VERSION" = "X" ]; then - RANDOM=`date +%S``sh -c 'echo $$'``ps -elf 2>&1 | sum 2>&1 | awk '{print $1}'` - fi -} -rchk - -# a portable, but not absolutely safe, tmp file creator -mytmp() { - tf=$1 - if type mktemp > /dev/null 2>&1; then - # if we have mktemp(1), use it: - tf2="$tf.XXXXXX" - tf2=`mktemp "$tf2"` - if [ "X$tf2" != "X" -a -f "$tf2" ]; then - if [ "X$DEBUG_MKTEMP" != "X" ]; then - echo "mytmp-mktemp: $tf2" 1>&2 - fi - echo "$tf2" - return - fi - fi - # fallback to multiple cmds: - rm -rf "$tf" || exit 1 - if [ -d "$tf" ]; then - echo "tmp file $tf still exists as a directory." - exit 1 - elif [ $dL "$tf" ]; then - echo "tmp file $tf still exists as a symlink." - exit 1 - elif [ -f "$tf" ]; then - echo "tmp file $tf still exists." - exit 1 - fi - touch "$tf" || exit 1 - chmod 600 "$tf" || exit 1 - rchk - if [ "X$DEBUG_MKTEMP" != "X" ]; then - echo "mytmp-touch: $tf" 1>&2 - fi - echo "$tf" -} - -# set up special case of ultravnc single click III mode: -if echo "$proxy" | egrep "^sslrepeater://" > /dev/null; then - pstr=`echo "$proxy" | sed -e 's,sslrepeater://,,'` - pstr1=`echo "$pstr" | sed -e 's/+.*$//'` - pstr2=`echo "$pstr" | sed -e 's/^[^+]*+//'` - SSVNC_REPEATER="SCIII=$pstr2"; export SSVNC_REPEATER - orig=$pstr1 - echo - echo "reset: SSVNC_REPEATER=$SSVNC_REPEATER orig=$orig proxy=''" - proxy="" -fi -if echo "$proxy" | egrep "vencrypt://" > /dev/null; then - vtmp="/tmp/ss_handshake${RANDOM}.$$.txt" - vtmp=`mytmp "$vtmp"` - SSVNC_PREDIGESTED_HANDSHAKE="$vtmp" - export SSVNC_PREDIGESTED_HANDSHAKE - if [ "X$SSVNC_USE_OURS" = "X" ]; then - NEED_VENCRYPT_VIEWER_BRIDGE=1 - fi -fi -if [ "X$SSVNC_USE_OURS" = "X" ]; then - VNCVIEWERCMD_EXTRA_OPTS="" -fi - - -# check -ssh and -mycert/-verify conflict: -if [ "X$use_ssh" = "X1" -a "X$use_sshssl" = "X" ]; then - if [ "X$mycert" != "X" -o "X$verify" != "X" ]; then - echo "-mycert and -verify cannot be used in -ssh mode" - exit 1 - fi -fi - -# direct mode Vnc:// means show no warnings. -# direct mode vnc:// will show warnings. -if echo "$orig" | grep '^V[Nn][Cc]://' > /dev/null; then - SSVNC_NO_ENC_WARN=1 - export SSVNC_NO_ENC_WARN - orig=`echo "$orig" | sed -e 's/^...:/vnc:/'` -fi - -# interprest the pseudo URL proto:// strings: -if echo "$orig" | grep '^vnc://' > /dev/null; then - orig=`echo "$orig" | sed -e 's,vnc://,,'` - verify="" - mycert="" - crl="" - use_ssh="" - use_sshssl="" - direct_connect=1 -elif echo "$orig" | grep '^vncs://' > /dev/null; then - orig=`echo "$orig" | sed -e 's,vncs://,,'` -elif echo "$orig" | grep '^vncssl://' > /dev/null; then - orig=`echo "$orig" | sed -e 's,vncssl://,,'` -elif echo "$orig" | grep '^vnc+ssl://' > /dev/null; then - orig=`echo "$orig" | sed -e 's,vnc.ssl://,,'` -elif echo "$orig" | grep '^vncssh://' > /dev/null; then - orig=`echo "$orig" | sed -e 's,vncssh://,,'` - use_ssh=1 -elif echo "$orig" | grep '^vnc+ssh://' > /dev/null; then - orig=`echo "$orig" | sed -e 's,vnc.ssh://,,'` - use_ssh=1 -fi - -if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then - verify="" - mycert="" - crl="" - use_ssh="" - use_sshssl="" - direct_connect=1 - if echo "$SSVNC_ULTRA_DSM" | grep 'noultra:' > /dev/null; then - SSVNC_NO_ULTRA_DSM=1; export SSVNC_NO_ULTRA_DSM - fi -fi - -# rsh mode is an internal/secret thing only I use. -rsh="" -if echo "$orig" | grep '^rsh://' > /dev/null; then - use_ssh=1 - rsh=1 - orig=`echo "$orig" | sed -e 's,rsh://,,'` -elif echo "$orig" | grep '^rsh:' > /dev/null; then - use_ssh=1 - rsh=1 - orig=`echo "$orig" | sed -e 's,rsh:,,'` -fi - -# play around with host:display port: -if echo "$orig" | grep ':' > /dev/null; then - : -else - # add or assume :0 if no ':' - if [ "X$reverse" = "X" ]; then - orig="$orig:0" - elif [ "X$orig" = "X" ]; then - orig=":0" - fi -fi - -# extract host and disp number: - -# try to see if it is ipv6 address: -ipv6=0 -if echo "$orig" | grep '\[' > /dev/null; then - # ipv6 [fe80::219:dbff:fee5:3f92%eth1]:5900 - host=`echo "$orig" | sed -e 's/\].*$//' -e 's/\[//'` - disp=`echo "$orig" | sed -e 's/^.*\]://'` - ipv6=1 -elif echo "$orig" | grep ':..*:' > /dev/null; then - # ipv6 fe80::219:dbff:fee5:3f92%eth1:5900 - host=`echo "$orig" | sed -e 's/:[^:]*$//'` - disp=`echo "$orig" | sed -e 's/^.*://'` - ipv6=1 -else - # regular host:port - host=`echo "$orig" | awk -F: '{print $1}'` - disp=`echo "$orig" | awk -F: '{print $2}'` -fi - -if [ "X$reverse" != "X" -a "X$STUNNEL_LISTEN" = "X" -a "X$host" != "X" ]; then - STUNNEL_LISTEN=$host - echo "set STUNNEL_LISTEN=$STUNNEL_LISTEN" -fi - -if [ "X$host" = "X" ]; then - host=$localhost -fi - -if [ "X$SSVNC_IPV6" = "X0" ]; then - # disable checking for it. - ipv6=0 -#elif [ "X$reverse" != "X" -a "X$ipv6" = "X1" ]; then -# ipv6=0 -elif [ "X$ipv6" = "X1" ]; then - : -elif echo "$host" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then - : -else - # regular hostname, can't be sure... - gout="" - if type getent > /dev/null 2>/dev/null; then - gout=`getent hosts "$host" 2>/dev/null` - fi - if echo "$gout" | grep ':.*:' > /dev/null; then - if echo "$gout" | grep '^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$' > /dev/null; then - : - else - echo "ipv6: "`echo "$gout" | grep ':.*:' | head -n 1` - ipv6=1 - fi - fi - if [ "X$ipv6" = "X0" ]; then - hout="" - if type host > /dev/null 2>/dev/null; then - host "$host" >/dev/null 2>&1 - host "$host" >/dev/null 2>&1 - hout=`host "$host" 2>/dev/null` - fi - if echo "$hout" | grep -i 'has ipv6 address' > /dev/null; then - if echo "$hout" | grep -i 'has address' > /dev/null; then - : - else - echo "ipv6: "`echo "$hout" | grep -i 'has ipv6 address' | head -n 1` - ipv6=1 - fi - fi - fi - if [ "X$ipv6" = "X0" ]; then - dout="" - if type dig > /dev/null 2>/dev/null; then - dout=`dig -t any "$host" 2>/dev/null` - fi - if echo "$dout" | grep -i "^$host" | grep '[ ]AAAA[ ]' > /dev/null; then - if echo "$dout" | grep -i "^$host" | grep '[ ]A[ ]' > /dev/null; then - : - else - echo "ipv6: "`echo "$dout" | grep -i '[ ]AAAA[ ]' | head -n 1` - ipv6=1 - fi - fi - fi - if [ "X$ipv6" = "X0" ]; then - sout=`env LOOKUP="$host" \ - perl -e ' eval {use Socket}; exit 0 if $@; - eval {use Socket6}; exit 0 if $@; - @res = getaddrinfo($ENV{LOOKUP}, "daytime", AF_UNSPEC, SOCK_STREAM); - $ipv4 = 0; - $ipv6 = 0; - $ip6 = ""; - while (scalar(@res) >= 5) { - ($family, $socktype, $proto, $saddr, $canon, @res) = @res; - $ipv4 = 1 if $family == AF_INET; - $ipv6 = 1 if $family == AF_INET6; - if ($family == AF_INET6 && $ip6 eq "") { - my ($host, $port) = getnameinfo($saddr, NI_NUMERICHOST | NI_NUMERICSERV); - $ip6 = $host; - } - } - if (! $ipv4 && $ipv6) { - print "AF_INET6_ONLY: $ENV{LOOKUP}: $ip6\n"; - } - exit 0; - ' 2>/dev/null` - if echo "$sout" | grep AF_INET6_ONLY > /dev/null; then - echo "$sout" - ipv6=1 - fi - fi -fi -if [ "X$ipv6" = "X1" ]; then - echo "ipv6: addr=$host disp=$disp" -fi -if [ "X$disp" = "X" ]; then - port="" # probably -listen mode. -elif [ $disp -lt 0 ]; then - # negative means use |n| without question: - port=`expr 0 - $disp` -elif [ $disp -lt 200 ]; then - # less than 200 means 5900+n - if [ "X$reverse" = "X" ]; then - port=`expr $disp + 5900` - else - port=`expr $disp + 5500` - fi -else - # otherwise use the number directly, e.g. 443, 2345 - port=$disp -fi - -if [ "X$ipv6" = "X1" -a "X$direct_connect" = "X1" ]; then - if [ "X$proxy" = "X" -a "X$reverse" = "X" ]; then - if [ "X$SSVNC_ULTRA_DSM" != "X" -a "X$have_uvnc_dsm_helper_ipv6" = "X1" ]; then - : - elif [ "X$SSVNC_NO_IPV6_PROXY" != "X" ]; then - : - elif [ "X$SSVNC_NO_IPV6_PROXY_DIRECT" != "X" ]; then - : - else - proxy="ipv6://$host:$port" - echo "direct connect: set proxy=$proxy" - fi - fi -fi - -# (possibly) tell the vncviewer to only listen on lo: -if [ "X$reverse" != "X" ]; then - if [ "X$direct_connect" = "X" -o "X$proxy" != "X" -o "X$STUNNEL_LISTEN" != "X" ]; then - VNCVIEWER_LISTEN_LOCALHOST=1 - export VNCVIEWER_LISTEN_LOCALHOST - fi -fi - -# try to find an open listening port via netstat(1): -inuse="" -if uname | grep Linux > /dev/null; then - inuse=`netstat -ant | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*://'` -elif uname | grep SunOS > /dev/null; then - inuse=`netstat -an -f inet -P tcp | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $1}' | sed 's/^.*\.//'` -elif uname | egrep -i 'bsd|darwin' > /dev/null; then - inuse=`netstat -ant -f inet | egrep 'LISTEN|WAIT|ESTABLISH|CLOSE' | awk '{print $4}' | sed 's/^.*\.//'` -# add others... -fi - -# this is a crude attempt for unique ports tags, etc. -date_sec=`date +%S` - -# these are special cases of no vnc, e.g. sleep or xmessage. -# these are for using ssvnc as a general port redirector. -if echo "$VNCVIEWERCMD" | grep '^sleep[ ][ ]*[0-9][0-9]*' > /dev/null; then - if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then - p=`echo "$VNCVIEWERCMD" | awk '{print $3}'` - if [ "X$p" != "X" ]; then - SS_VNCVIEWER_LISTEN_PORT=$p - fi - fi - p2=`echo "$VNCVIEWERCMD" | awk '{print $2}'` - VNCVIEWERCMD="eval sleep $p2; echo Local " -elif echo "$VNCVIEWERCMD" | grep '^xmessage[ ][ ]*[0-9][0-9]*' > /dev/null; then - if [ "X$SS_VNCVIEWER_LISTEN_PORT" = "X" ]; then - p=`echo "$VNCVIEWERCMD" | awk '{print $2}'` - SS_VNCVIEWER_LISTEN_PORT=$p - fi -fi - -# utility to find a free port to listen on. -findfree() { - try0=$1 - try=$try0 - use0="" - - if [ "X$SS_VNCVIEWER_LISTEN_PORT" != "X" ]; then - echo "$SS_VNCVIEWER_LISTEN_PORT" - return - fi - if [ $try -ge 6000 ]; then - fmax=`expr $try + 1000` - else - fmax=6000 - fi - - while [ $try -lt $fmax ] - do - if [ "X$inuse" = "X" ]; then - break - fi - if echo "$inuse" | grep -w $try > /dev/null; then - : - else - use0=$try - break - fi - try=`expr $try + 1` - done - if [ "X$use0" = "X" ]; then - use0=`expr $date_sec + $try0` - fi - - echo $use0 -} - -# utility for exiting; kills some helper processes, -# removes files, etc. -final() { - echo "" - if [ "X$tmp_cfg" != "X" ]; then - rm -f $tmp_cfg - fi - if [ "X$SS_VNCVIEWER_RM" != "X" ]; then - rm -f $SS_VNCVIEWER_RM 2>/dev/null - fi - if [ "X$tcert" != "X" ]; then - rm -f $tcert - fi - if [ "X$pssh" != "X" ]; then - echo "Terminating background ssh process" - echo kill -TERM "$pssh" - kill -TERM "$pssh" 2>/dev/null - sleep 1 - kill -KILL "$pssh" 2>/dev/null - pssh="" - fi - if [ "X$stunnel_pid" != "X" ]; then - echo "Terminating background stunnel process" - echo kill -TERM "$stunnel_pid" - kill -TERM "$stunnel_pid" 2>/dev/null - sleep 1 - kill -KILL "$stunnel_pid" 2>/dev/null - stunnel_pid="" - fi - if [ "X$dsm_pid" != "X" ]; then - echo "Terminating background ultravnc_dsm_helper process" - echo kill -TERM "$dsm_pid" - kill -TERM "$dsm_pid" 2>/dev/null - sleep 1 - kill -KILL "$dsm_pid" 2>/dev/null - stunnel_pid="" - fi - if [ "X$tail_pid" != "X" ]; then - kill -TERM $tail_pid - fi - if [ "X$tail_pid2" != "X" ]; then - kill -TERM $tail_pid2 - fi -} - -if [ "X$reverse" = "X" ]; then - # normal connections try 5930-5999: - if [ "X$showcert" = "X" ]; then - use=`findfree 5930` - else - # move away from normal place for (possibly many) -showcert - pstart=`date +%S` - pstart=`expr 6130 + $pstart + $pstart` - use=`findfree $pstart` - fi - if [ $use -ge 5900 ]; then - N=`expr $use - 5900` - else - N=$use - fi -else - # reverse connections: - p2=`expr $port + 30` - use=`findfree $p2` - if [ $use -ge 5500 ]; then - N=`expr $use - 5500` - else - N=$use - fi -fi - -# this is for my special use of ss_vncip -> vncip viewer. -if echo "$0" | grep vncip > /dev/null; then - VNCVIEWERCMD="$VNCIPCMD" -fi - -if echo "$VNCVIEWERCMD" | egrep -i '^(xmessage|sleep )' > /dev/null; then - : -elif [ "X$VNCVIEWERCMD_EXTRA_OPTS" != "X" ]; then - VNCVIEWERCMD="$VNCVIEWERCMD $VNCVIEWERCMD_EXTRA_OPTS" -fi - -# trick for the undocumented rsh://host:port method. -rsh_setup() { - if echo "$ssh_host" | grep '@' > /dev/null; then - ul=`echo "$ssh_host" | awk -F@ '{print $1}'` - ul="-l $ul" - ssh_host=`echo "$ssh_host" | awk -F@ '{print $2}'` - else - ul="" - fi - ssh_cmd=`echo "$ssh_cmd" | sed -e 's/ -localhost/ /g'` -} - -# trick for the undocumented rsh://host:port method. -rsh_viewer() { - trap "final" 0 2 15 - if [ "X$PORT" = "X" ]; then - exit 1 - elif [ $PORT -ge 5900 ]; then - vdpy=`expr $PORT - 5900` - else - vdpy=":$PORT" - fi - stty sane - echo "$VNCVIEWERCMD" "$@" $ssh_host:$vdpy - echo "" - $VNCVIEWERCMD "$@" $ssh_host:$vdpy - if [ $? != 0 ]; then - sleep 2 - $VNCVIEWERCMD "$@" $ssh_host:$vdpy - fi -} - -check_perl() { - if type "$1" > /dev/null 2>&1; then - : - elif [ ! -x "$1" ]; then - echo "" - echo "*******************************************************" - echo "** Problem finding the Perl command '$1': **" - echo "" - type "perl" - echo "" - echo "** Perhaps you need to install the Perl package. **" - echo "*******************************************************" - echo "" - sleep 5 - fi -} - -# this is the PPROXY tool. used only here for now... -pcode() { - tf=$1 - PPROXY_PROXY=$proxy; export PPROXY_PROXY - PPROXY_DEST="$host:$port"; export PPROXY_DEST - check_perl /usr/bin/perl - - cod='#!/usr/bin/perl - -# A hack to glue stunnel to a Web or SOCKS proxy, UltraVNC repeater for -# client connections. -# Also acts as a VeNCrypt bridge (by redirecting to stunnel.) - -use IO::Socket::INET; - -my $have_inet6 = ""; -eval "use IO::Socket::INET6;"; -$have_inet6 = 1 if $@ eq ""; - -#my $have_sock6 = ""; -#eval "use Socket; use Socket6;"; -#$have_sock6 = 1 if $@ eq ""; - -if (exists $ENV{PPROXY_LOOP_THYSELF}) { - # used for reverse vnc, run a repeating outer loop. - print STDERR "PPROXY_LOOP: $ENV{PPROXY_LOOP_THYSELF}\n"; - my $rm = $ENV{PPROXY_REMOVE}; - my $lp = $ENV{PPROXY_LOOP_THYSELF}; - delete $ENV{PPROXY_REMOVE}; - delete $ENV{PPROXY_LOOP_THYSELF}; - $ENV{PPROXY_LOOP_THYSELF_MASTER} = $$; - my $pid = $$; - my $dbg = 0; - my $c = 0; - use POSIX ":sys_wait_h"; - while (1) { - $pid = fork(); - last if ! defined $pid; - if ($pid eq "0") { - last; - } - $c++; - print STDERR "\nPPROXY_LOOP: pid=$$ child=$pid count=$c\n"; - while (1) { - waitpid(-1, WNOHANG); - fsleep(0.25); - if (! kill 0, $pid) { - print STDERR "PPROXY_LOOP: child=$pid gone.\n"; - last; - } - print STDERR "PPROXY_LOOP: child=$pid alive.\n" if $dbg; - if (! -f $lp) { - print STDERR "PPROXY_LOOP: flag file $lp gone, killing $pid\n"; - kill TERM, $pid; - fsleep(0.1); - wait; - last; - } - print STDERR "PPROXY_LOOP: file exists $lp\n" if $dbg; - } - last if ! -f $lp; - fsleep(0.25); - } - if ($pid ne "0") { - unlink($0) if $rm; - exit 0; - } -} - -if (exists $ENV{PPROXY_SLEEP} && $ENV{PPROXY_SLEEP} > 0) { - print STDERR "PPROXY_PID: $$\n"; - sleep $ENV{PPROXY_SLEEP}; -} - -foreach my $var (qw( - PPROXY_DEST - PPROXY_KILLPID - PPROXY_LISTEN - PPROXY_PROXY - PPROXY_REMOVE - PPROXY_REPEATER - PPROXY_REVERSE - PPROXY_SLEEP - PPROXY_SOCKS - PPROXY_VENCRYPT - PPROXY_VENCRYPT_VIEWER_BRIDGE - )) { - if (0 || $ENV{SS_DEBUG} || $ENV{SSVNC_VENCRYPT_DEBUG}) { - print STDERR "$var: $ENV{$var}\n"; - } -} - -if ($ENV{PPROXY_SOCKS} ne "" && $ENV{PPROXY_PROXY} !~ m,^socks5?://,i) { - if ($ENV{PPROXY_SOCKS} eq "5") { - $ENV{PPROXY_PROXY} = "socks5://$ENV{PPROXY_PROXY}"; - } else { - $ENV{PPROXY_PROXY} = "socks://$ENV{PPROXY_PROXY}"; - } -} - -my $rfbSecTypeAnonTls = 18; -my $rfbSecTypeVencrypt = 19; - -my $rfbVencryptPlain = 256; -my $rfbVencryptTlsNone = 257; -my $rfbVencryptTlsVnc = 258; -my $rfbVencryptTlsPlain = 259; -my $rfbVencryptX509None = 260; -my $rfbVencryptX509Vnc = 261; -my $rfbVencryptX509Plain = 262; - -my $handshake_file = ""; -if (exists $ENV{SSVNC_PREDIGESTED_HANDSHAKE}) { - $handshake_file = $ENV{SSVNC_PREDIGESTED_HANDSHAKE}; -} - -my $have_gettimeofday = 0; -eval "use Time::HiRes;"; -if ($@ eq "") { - $have_gettimeofday = 1; -} -sub gettime { - my $t = "0.0"; - if ($have_gettimeofday) { - $t = Time::HiRes::gettimeofday(); - } - return $t; -} - -my $listen_handle = ""; -my $sock = ""; -my $parent = $$; - -my $initial_data = ""; - -if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) { - my ($from, $to) = split(/,/, $ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}); - do_vencrypt_viewer_bridge($from, $to); - exit 0; -} - -my ($first, $second, $third) = split(/,/, $ENV{PPROXY_PROXY}, 3); -my ($mode_1st, $mode_2nd, $mode_3rd) = ("", "", ""); - -($first, $mode_1st) = url_parse($first); - -my ($proxy_host, $proxy_port) = ($first, ""); -if ($proxy_host =~ /^(.*):(\d+)$/) { - $proxy_host = $1; - $proxy_port = $2; -} -my $connect = $ENV{PPROXY_DEST}; - -if ($second ne "") { - ($second, $mode_2nd) = url_parse($second); -} - -if ($third ne "") { - ($third, $mode_3rd) = url_parse($third); -} - - -print STDERR "\n"; -print STDERR "PPROXY v0.4: a tool for Web, SOCKS, and UltraVNC proxies and for\n"; -print STDERR "PPROXY v0.4: IPv6 and VNC VeNCrypt bridging.\n"; -print STDERR "proxy_host: $proxy_host\n"; -print STDERR "proxy_port: $proxy_port\n"; -print STDERR "proxy_connect: $connect\n"; -print STDERR "pproxy_params: $ENV{PPROXY_PROXY}\n"; -print STDERR "pproxy_listen: $ENV{PPROXY_LISTEN}\n"; -print STDERR "pproxy_reverse: $ENV{PPROXY_REVERSE}\n"; -print STDERR "io_socket_inet6: $have_inet6\n"; -print STDERR "\n"; -if (! $have_inet6) { - print STDERR "PPROXY: To enable IPv6 connections, install the IO::Socket::INET6 perl module.\n\n"; -} - -if (1) { - print STDERR "pproxy 1st: $first\t- $mode_1st\n"; - print STDERR "pproxy 2nd: $second\t- $mode_2nd\n"; - print STDERR "pproxy 3rd: $third\t- $mode_3rd\n"; - print STDERR "\n"; -} - -sub pdie { - my $msg = shift; - kill_proxy_pids(); - die "$msg"; -} - -if ($ENV{PPROXY_REVERSE} ne "") { - my ($rhost, $rport) = ($ENV{PPROXY_REVERSE}, ""); - if ($rhost =~ /^(.*):(\d+)$/) { - $rhost = $1; - $rport = $2; - } - $rport = 5900 unless $rport; - my $emsg = ""; - $listen_handle = IO::Socket::INET->new( - PeerAddr => $rhost, - PeerPort => $rport, - Proto => "tcp" - ); - $emsg = $!; - if (! $listen_handle && $have_inet6) { - eval {$listen_handle = IO::Socket::INET6->new( - PeerAddr => $rhost, - PeerPort => $rport, - Proto => "tcp" - );}; - $emsg .= " / $!"; - } - if (! $listen_handle) { - pdie "pproxy: $emsg -- PPROXY_REVERSE\n"; - } - print STDERR "PPROXY_REVERSE: connected to $rhost $rport\n"; - -} elsif ($ENV{PPROXY_LISTEN} ne "") { - my $listen_sock = ""; - my $maxtry = 12; - my $sleep = 5; - my $p2 = ""; - my $emsg = ""; - for (my $i=0; $i < $maxtry; $i++) { - my ($if, $p) = ("", $ENV{PPROXY_LISTEN}); - if ($p =~ /^(.*):(\d+)$/) { - $if = $1; - $p = $2; - } - $p2 = "*:$p"; - if ($if eq "") { - $if = "localhost"; - } - print STDERR "pproxy interface: $if\n"; - - $emsg = ""; - if (($if eq "INADDR_ANY6" || $if eq "::") && $have_inet6) { - eval {$listen_sock = IO::Socket::INET6->new( - Listen => 2, - ReuseAddr => 1, - Domain => AF_INET6, - LocalAddr => "::", - LocalPort => $p, - Proto => "tcp" - );}; - $p2 = ":::$p"; - } elsif ($if =~ /^INADDR_ANY/) { - $listen_sock = IO::Socket::INET->new( - Listen => 2, - ReuseAddr => 1, - LocalPort => $p, - Proto => "tcp" - ); - } elsif (($if eq "INADDR_LOOPBACK6" || $if eq "::1") && $have_inet6) { - $p2 = "::1:$p"; - eval {$listen_sock = IO::Socket::INET6->new( - Listen => 2, - ReuseAddr => 1, - Domain => AF_INET6, - LocalAddr => "::1", - LocalPort => $p, - Proto => "tcp" - );}; - $p2 = "::1:$p"; - } else { - $p2 = "$if:$p"; - $listen_sock = IO::Socket::INET->new( - Listen => 2, - ReuseAddr => 1, - LocalAddr => $if, - LocalPort => $p, - Proto => "tcp" - ); - $emsg = $!; - - if (! $listen_sock && $have_inet6) { - print STDERR "PPROXY_LISTEN: retry with INET6\n"; - eval {$listen_sock = IO::Socket::INET6->new( - Listen => 2, - ReuseAddr => 1, - Domain => AF_INET6, - LocalAddr => $if, - LocalPort => $p, - Proto => "tcp" - );}; - $emsg .= " / $!"; - } - } - if (! $listen_sock) { - if ($i < $maxtry - 1) { - warn "pproxy: $emsg $!\n"; - warn "Could not listen on port $p2, retrying in $sleep seconds... (Ctrl-C to quit)\n"; - sleep $sleep; - } - } else { - last; - } - } - if (! $listen_sock) { - pdie "pproxy: $emsg -- PPROXY_LISTEN\n"; - } - print STDERR "pproxy: listening on $p2\n"; - my $ip; - ($listen_handle, $ip) = $listen_sock->accept(); - my $err = $!; - close $listen_sock; - if (! $listen_handle) { - pdie "pproxy: $err\n"; - } - - if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) { - my $sml = $ENV{SSVNC_MULTIPLE_LISTEN}; - if ($sml ne "" && $sml ne "0") { - setpgrp(0, 0); - if (fork()) { - close $viewer_sock; - wait; - exit 0; - } - if (fork()) { - close $viewer_sock; - exit 0; - } - setpgrp(0, 0); - $parent = $$; - } - } -} - -$sock = IO::Socket::INET->new( - PeerAddr => $proxy_host, - PeerPort => $proxy_port, - Proto => "tcp" -); - -my $err = ""; - -if (! $sock && $have_inet6) { - $err = $!; - - eval {$sock = IO::Socket::INET6->new( - PeerAddr => $proxy_host, - PeerPort => $proxy_port, - Proto => "tcp" - );}; - $err .= " / $!"; -} - -if (! $sock) { - unlink($0) if $ENV{PPROXY_REMOVE}; - pdie "pproxy: $err\n"; -} - -unlink($0) if $ENV{PPROXY_REMOVE}; - -if ($ENV{PPROXY_PROXY} =~ /^vencrypt:/ && $ENV{PPROXY_VENCRYPT_REVERSE}) { - print STDERR "\nPPROXY: vencrypt+reverse: swapping listen socket with connect socket.\n"; - my $tmp_swap = $sock; - $sock = $listen_handle; - $listen_handle = $tmp_swap; -} - -$cur_proxy = $first; -setmode($mode_1st); - -if ($second ne "") { - connection($second, 1); - - setmode($mode_2nd); - $cur_proxy = $second; - - if ($third ne "") { - connection($third, 2); - setmode($mode_3rd); - $cur_proxy = $third; - connection($connect, 3); - } else { - connection($connect, 2); - } -} else { - connection($connect, 1); -} - -sub kill_proxy_pids() { - if ($ENV{PPROXY_VENCRYPT_VIEWER_BRIDGE}) { - return; - } - if ($ENV{PPROXY_KILLPID}) { - foreach my $p (split(/,/, $ENV{PPROXY_KILLPID})) { - if ($p =~ /^(\+|-)/) { - $p = $parent + $p; - } - print STDERR "kill TERM, $p (PPROXY_KILLPID)\n"; - kill "TERM", $p; - } - } -} - -sub xfer { - my($in, $out) = @_; - $RIN = $WIN = $EIN = ""; - $ROUT = ""; - vec($RIN, fileno($in), 1) = 1; - vec($WIN, fileno($in), 1) = 1; - $EIN = $RIN | $WIN; - - while (1) { - my $nf = 0; - while (! $nf) { - $nf = select($ROUT=$RIN, undef, undef, undef); - } - my $len = sysread($in, $buf, 8192); - if (! defined($len)) { - next if $! =~ /^Interrupted/; - print STDERR "pproxy[$$]: $!\n"; - last; - } elsif ($len == 0) { - print STDERR "pproxy[$$]: Input is EOF.\n"; - last; - } - my $offset = 0; - my $quit = 0; - while ($len) { - my $written = syswrite($out, $buf, $len, $offset); - if (! defined $written) { - print STDERR "pproxy[$$]: Output is EOF. $!\n"; - $quit = 1; - last; - } - $len -= $written; - $offset += $written; - } - last if $quit; - } - close($out); - close($in); - print STDERR "pproxy[$$]: finished xfer.\n"; -} - -sub handler { - print STDERR "pproxy[$$]: got SIGTERM.\n"; - close $listen_handle if $listen_handle; - close $sock if $sock; - exit; -} - -sub xfer_both { - $child = fork; - - if (! defined $child) { - kill_proxy_pids(); - exit 1; - } - - $SIG{TERM} = "handler"; - - if ($child) { - if ($listen_handle) { - print STDERR "pproxy parent[$$] listen_handle -> socket\n"; - xfer($listen_handle, $sock); - } else { - print STDERR "pproxy parent[$$] STDIN -> socket\n"; - xfer(STDIN, $sock); - } - select(undef, undef, undef, 0.25); - if (kill 0, $child) { - select(undef, undef, undef, 0.9); - if (kill 0, $child) { - print STDERR "pproxy[$$]: kill TERM child $child\n"; - kill "TERM", $child; - } else { - print STDERR "pproxy[$$]: child $child gone.\n"; - } - } - } else { - select(undef, undef, undef, 0.05); - if ($listen_handle) { - print STDERR "pproxy child [$$] socket -> listen_handle\n"; - if ($initial_data ne "") { - my $len = length $initial_data; - print STDERR "pproxy child [$$] sending initial_data, length $len\n\n"; - syswrite($listen_handle, $initial_data, $len); - } else { - print STDERR "\n"; - } - xfer($sock, $listen_handle); - } else { - print STDERR "pproxy child [$$] socket -> STDOUT\n"; - if ($initial_data ne "") { - my $len = length $initial_data; - print STDERR "pproxy child [$$] sending initial_data, length $len\n\n"; - syswrite(STDOUT, $initial_data, $len); - } else { - print STDERR "\n"; - } - xfer($sock, STDOUT); - } - select(undef, undef, undef, 0.25); - if (kill 0, $parent) { - select(undef, undef, undef, 0.8); - if (kill 0, $parent) { - print STDERR "pproxy[$$]: kill TERM parent $parent\n"; - kill "TERM", $parent; - } else { - print STDERR "pproxy[$$]: parent $parent gone.\n"; - } - } - } - - kill_proxy_pids(); -} - -xfer_both(); - -exit; - -sub fsleep { - select(undef, undef, undef, shift); -} - -sub url_parse { - my $hostport = shift; - my $mode = "http"; - if ($hostport =~ m,^socks4?://(\S*)$,i) { - $mode = "socks4"; - $hostport = $1; - } elsif ($hostport =~ m,^socks5://(\S*)$,i) { - $mode = "socks5"; - $hostport = $1; - } elsif ($hostport =~ m,^https?://(\S*)$,i) { - $mode = "http"; - $hostport = $1; - } elsif ($hostport =~ m,^ipv6://(\S*)$,i) { - $mode = "ipv6"; - $hostport = $1; - } elsif ($hostport =~ m,^repeater://(\S*)\+(\S*)$,i) { - # ultravnc repeater proxy. - $hostport = $1; - $mode = "repeater:$2"; - if ($hostport !~ /:\d+$/) { - $hostport .= ":5900"; - } - } elsif ($hostport =~ m,^vencrypt://(\S*)$,i) { - # vencrypt handshake. - $hostport = $1; - my $m = "connect"; - if ($hostpost =~ /^(\S+)\+(\S+)$/) { - $hostport = $1; - $mode = $2; - } - $mode = "vencrypt:$m"; - if ($hostport !~ /:\d+$/) { - $hostport .= ":5900"; - } - } - return ($hostport, $mode); -} - -sub setmode { - my $mode = shift; - $ENV{PPROXY_REPEATER} = ""; - $ENV{PPROXY_VENCRYPT} = ""; - if ($mode =~ /^socks/) { - if ($mode =~ /^socks5/) { - $ENV{PPROXY_SOCKS} = 5; - } else { - $ENV{PPROXY_SOCKS} = 1; - } - } elsif ($mode =~ /^ipv6/i) { - $ENV{PPROXY_SOCKS} = 0; - } elsif ($mode =~ /^repeater:(.*)/) { - $ENV{PPROXY_REPEATER} = $1; - $ENV{PPROXY_SOCKS} = ""; - } elsif ($mode =~ /^vencrypt:(.*)/) { - $ENV{PPROXY_VENCRYPT} = $1; - $ENV{PPROXY_SOCKS} = ""; - } else { - $ENV{PPROXY_SOCKS} = ""; - } -} - -sub connection { - my ($CONNECT, $w) = @_; - - my $con = ""; - my $msg = ""; - - if ($ENV{PPROXY_SOCKS} eq "5") { - # SOCKS5 - my ($h, $p) = ($CONNECT, ""); - if ($h =~ /^(.*):(\d+)$/) { - $h = $1; - $p = $2; - } - $con .= pack("C", 0x05); - $con .= pack("C", 0x01); - $con .= pack("C", 0x00); - - $msg = "SOCKS5 via $cur_proxy to $h:$p\n\n"; - print STDERR "proxy_request$w: $msg"; - - syswrite($sock, $con, length($con)); - - my ($n1, $n2, $n3, $n4, $n5, $n6); - my ($r1, $r2, $r3, $r4, $r5, $r6); - my ($s1, $s2, $s3, $s4, $s5, $s6); - - $n1 = sysread($sock, $r1, 1); - $n2 = sysread($sock, $r2, 1); - - $s1 = unpack("C", $r1); - $s2 = unpack("C", $r2); - if ($s1 != 0x05 || $s2 != 0x00) { - print STDERR "SOCKS5 fail s1=$s1 s2=$s2 n1=$n1 n2=$n2\n"; - close $sock; - exit(1); - } - - $con = ""; - $con .= pack("C", 0x05); - $con .= pack("C", 0x01); - $con .= pack("C", 0x00); - $con .= pack("C", 0x03); - $con .= pack("C", length($h)); - $con .= $h; - $con .= pack("C", $p >> 8); - $con .= pack("C", $p & 0xff); - - syswrite($sock, $con, length($con)); - - $n1 = sysread($sock, $r1, 1); - $n2 = sysread($sock, $r2, 1); - $n3 = sysread($sock, $r3, 1); - $n4 = sysread($sock, $r4, 1); - $s1 = unpack("C", $r1); - $s2 = unpack("C", $r2); - $s3 = unpack("C", $r3); - $s4 = unpack("C", $r4); - - if ($s4 == 0x1) { - sysread($sock, $r5, 4 + 2); - } elsif ($s4 == 0x3) { - sysread($sock, $r5, 1); - $s5 = unpack("C", $r5); - sysread($sock, $r6, $s5 + 2); - } elsif ($s4 == 0x4) { - sysread($sock, $r5, 16 + 2); - } - - if ($s1 != 0x5 || $s2 != 0x0 || $s3 != 0x0) { - print STDERR "SOCKS5 failed: s1=$s1 s2=$s2 s3=$s3 s4=$s4 n1=$n1 n2=$n2 n3=$n3 n4=$n4\n"; - close $sock; - exit(1); - } - - } elsif ($ENV{PPROXY_SOCKS} eq "1") { - # SOCKS4 SOCKS4a - my ($h, $p) = ($CONNECT, ""); - if ($h =~ /^(.*):(\d+)$/) { - $h = $1; - $p = $2; - } - $con .= pack("C", 0x04); - $con .= pack("C", 0x01); - $con .= pack("n", $p); - - my $SOCKS_4a = 0; - if ($h eq "localhost" || $h eq "127.0.0.1") { - $con .= pack("C", 127); - $con .= pack("C", 0); - $con .= pack("C", 0); - $con .= pack("C", 1); - } elsif ($h =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { - $con .= pack("C", $1); - $con .= pack("C", $2); - $con .= pack("C", $3); - $con .= pack("C", $4); - } else { - $con .= pack("C", 0); - $con .= pack("C", 0); - $con .= pack("C", 0); - $con .= pack("C", 3); - $SOCKS_4a = 1; - } - - $con .= "nobody"; - $con .= pack("C", 0); - - $msg = "SOCKS4 via $cur_proxy to $h:$p\n\n"; - if ($SOCKS_4a) { - $con .= $h; - $con .= pack("C", 0); - $msg =~ s/SOCKS4/SOCKS4a/; - } - print STDERR "proxy_request$w: $msg"; - syswrite($sock, $con, length($con)); - - my $ok = 1; - for (my $i = 0; $i < 8; $i++) { - my $c; - sysread($sock, $c, 1); - my $s = unpack("C", $c); - if ($i == 0) { - $ok = 0 if $s != 0x0; - } elsif ($i == 1) { - $ok = 0 if $s != 0x5a; - } - } - if (! $ok) { - print STDERR "SOCKS4 failed.\n"; - close $sock; - exit(1); - } - } elsif ($ENV{PPROXY_SOCKS} eq "0") { - # hack for ipv6 "proxy", nothing to do, assume INET6 call worked. - ; - } elsif ($ENV{PPROXY_REPEATER} ne "") { - my $rep = $ENV{PPROXY_REPEATER}; - print STDERR "repeater: $rep\n"; - $rep .= pack("x") x 250; - syswrite($sock, $rep, 250); - - my $rfb = ""; - - my $ok = 1; - for (my $i = 0; $i < 12; $i++) { - my $c; - last if $ENV{PPROXY_GENERIC_REPEATER}; - sysread($sock, $c, 1); - print STDERR $c; - $rfb .= $c; - } - if ($rfb ne "" && $rfb !~ /^RFB 000\.000/) { - $initial_data = $rfb; - $rfb =~ s/\n//g; - print STDERR "detected non-UltraVNC repeater; forwarding \"$rfb\"\nlength: ", length($initial_data), "\n"; - } - } elsif ($ENV{PPROXY_VENCRYPT} ne "") { - my $vencrypt = $ENV{PPROXY_VENCRYPT}; - vencrypt_dialog($vencrypt); - - } else { - # Web Proxy: - $con = "CONNECT $CONNECT HTTP/1.1\r\n"; - $con .= "Host: $CONNECT\r\n"; - $con .= "Connection: close\r\n\r\n"; - $msg = $con; - - print STDERR "proxy_request$w: via $cur_proxy:\n$msg"; - syswrite($sock, $con, length($con)); - - my $rep = ""; - my $n = 0; - while ($rep !~ /\r\n\r\n/ && $n < 30000) { - my $c; - sysread($sock, $c, 1); - print STDERR $c; - $rep .= $c; - $n++; - } - if ($rep !~ m,HTTP/.* 200,) { - print STDERR "HTTP CONNECT failed.\n"; - close $sock; - exit(1); - } - } -} - -sub vdie { - append_handshake("done\n"); - close $sock; - kill_proxy_pids(); - exit(1); -} - -sub anontls_handshake { - my ($vmode, $db) = @_; - - print STDERR "\nPPROXY: Doing ANONTLS Handshake\n"; - - my $psec = pack("C", $rfbSecTypeAnonTls); - syswrite($sock, $psec, 1); - - append_handshake("done\n"); -} - -sub vencrypt_handshake { - - my ($vmode, $db) = @_; - - print STDERR "\nPPROXY: Doing VeNCrypt Handshake\n"; - - my $psec = pack("C", $rfbSecTypeVencrypt); - - if (exists $ENV{SSVNC_TEST_SEC_TYPE}) { - my $fake = $ENV{SSVNC_TEST_SEC_TYPE}; - print STDERR "PPROXY: sending sec-type: $fake\n"; - $psec = pack("C", $fake); - } - - syswrite($sock, $psec, 1); - - my $vmajor; - my $vminor; - sysread($sock, $vmajor, 1); - sysread($sock, $vminor, 1); - - vdie if $vmajor eq "" || $vminor eq ""; - - $vmajor = unpack("C", $vmajor); - $vminor = unpack("C", $vminor); - print STDERR "server vencrypt version $vmajor.$vminor\n" if $db; - - if (exists $ENV{SSVNC_TEST_SEC_TYPE}) { - print STDERR "PPROXY: continuing on in test mode.\n"; - } else { - vdie if $vmajor ne 0; - vdie if $vminor < 2; - } - - $vmajor = pack("C", 0); - $vminor = pack("C", 2); - append_handshake("subversion=0.2\n"); - - syswrite($sock, $vmajor, 1); - syswrite($sock, $vminor, 1); - - my $result; - sysread($sock, $result, 1); - print STDERR "result empty\n" if $db && $result eq ""; - - vdie if $result eq ""; - $result = unpack("C", $result); - print STDERR "result=$result\n" if $db; - - vdie if $result ne 0; - - my $nsubtypes; - sysread($sock, $nsubtypes, 1); - - vdie if $nsubtypes eq ""; - $nsubtypes = unpack("C", $nsubtypes); - print STDERR "nsubtypes=$nsubtypes\n" if $db; - - my %subtypes; - - for (my $i = 0; $i < $nsubtypes; $i++) { - my $subtype = ""; - sysread($sock, $subtype, 4); - vdie if length($subtype) != 4; - - # XXX fix 64bit. - $subtype = unpack("N", $subtype); - print STDERR "subtype: $subtype\n" if $db; - $subtypes{$subtype} = 1; - append_handshake("sst$i=$subtype\n"); - } - - my $subtype = 0; - if (exists $subtypes{$rfbVencryptX509None}) { - $subtype = $rfbVencryptX509None; - print STDERR "selected rfbVencryptX509None\n" if $db; - } elsif (exists $subtypes{$rfbVencryptX509Vnc}) { - $subtype = $rfbVencryptX509Vnc; - print STDERR "selected rfbVencryptX509Vnc\n" if $db; - } elsif (exists $subtypes{$rfbVencryptX509Plain}) { - $subtype = $rfbVencryptX509Plain; - print STDERR "selected rfbVencryptX509Plain\n" if $db; - } elsif (exists $subtypes{$rfbVencryptTlsNone}) { - $subtype = $rfbVencryptTlsNone; - print STDERR "selected rfbVencryptTlsNone\n" if $db; - } elsif (exists $subtypes{$rfbVencryptTlsVnc}) { - $subtype = $rfbVencryptTlsVnc; - print STDERR "selected rfbVencryptTlsVnc\n" if $db; - } elsif (exists $subtypes{$rfbVencryptTlsPlain}) { - $subtype = $rfbVencryptTlsPlain; - print STDERR "selected rfbVencryptTlsPlain\n" if $db; - } - - if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) { - my $fake = $ENV{SSVNC_TEST_SEC_SUBTYPE}; - print STDERR "PPROXY: sending sec-subtype: $fake\n"; - $subtype = $fake; - } - - append_handshake("subtype=$subtype\n"); - - my $pst = pack("N", $subtype); - syswrite($sock, $pst, 4); - - if (exists $ENV{SSVNC_TEST_SEC_SUBTYPE}) { - print STDERR "PPROXY: continuing on in test mode.\n"; - } else { - vdie if $subtype == 0; - } - - my $ok; - sysread($sock, $ok, 1); - $ok = unpack("C", $ok); - print STDERR "ok=$ok\n" if $db; - - append_handshake("done\n"); - - vdie if $ok == 0; -} - -sub vencrypt_dialog { - my $vmode = shift; - my $db = 0; - - $db = 1 if exists $ENV{SS_DEBUG}; - $db = 1 if exists $ENV{SSVNC_VENCRYPT_DEBUG}; - - append_handshake("mode=$vmode\n"); - - my $server_rfb = ""; - #syswrite($sock, $rep, 250); - for (my $i = 0; $i < 12; $i++) { - my $c; - sysread($sock, $c, 1); - $server_rfb .= $c; - print STDERR $c; - } - print STDERR "server_rfb: $server_rfb\n" if $db; - append_handshake("server=$server_rfb"); - - my $minor = ""; - if ($server_rfb =~ /^RFB 003\.(\d+)/) { - $minor = $1; - } else { - vdie; - } - my $viewer_rfb = "RFB 003.008\n"; - if ($minor < 7) { - vdie; - } elsif ($minor == 7) { - $viewer_rfb = "RFB 003.007\n"; - } - my $nsec; - my $t1 = gettime(); - my $t0 = gettime(); - - syswrite($sock, $viewer_rfb, 12); - sysread($sock, $nsec, 1); - - $t1 = gettime(); - $t1 = sprintf("%.6f", $t1 - $t0); - - append_handshake("viewer=$viewer_rfb"); - append_handshake("latency=$t1\n"); - - vdie if $nsec eq ""; - - $nsec = unpack("C", $nsec); - - print STDERR "nsec: $nsec\n" if $db; - vdie if $nsec eq 0 || $nsec > 100; - - my %sectypes = (); - - for (my $i = 0; $i < $nsec; $i++) { - my $sec; - sysread($sock, $sec, 1); - vdie if $sec eq ""; - $sec = unpack("C", $sec); - print STDERR "sec: $sec\n" if $db; - $sectypes{$sec} = 1; - } - - if (exists $sectypes{$rfbSecTypeVencrypt}) { - print STDERR "found rfbSecTypeVencrypt\n" if $db; - append_handshake("sectype=$rfbSecTypeVencrypt\n"); - vencrypt_handshake($vmode, $db); - } elsif (exists $sectypes{$rfbSecTypeAnonTls}) { - print STDERR "found rfbSecTypeAnonTls\n" if $db; - append_handshake("sectype=$rfbSecTypeAnonTls\n"); - anontls_handshake($vmode, $db); - } else { - print STDERR "No supported sec-type found\n" if $db; - vdie; - } -} - -sub append_handshake { - my $str = shift; - if ($handshake_file) { - if (open(HSF, ">>$handshake_file")) { - print HSF $str; - close HSF; - } - } -} - -sub do_vencrypt_viewer_bridge { - my ($listen, $connect) = @_; - print STDERR "\npproxy: starting vencrypt_viewer_bridge[$$]: $listen \-> $connect\n"; - my $db = 0; - my $backwards = 0; - if ($listen < 0) { - $backwards = 1; - $listen = -$listen; - } - if ($handshake_file eq "") { - die "pproxy: vencrypt_viewer_bridge[$$]: no SSVNC_PREDIGESTED_HANDSHAKE\n"; - } - my $listen_sock; - my $maxtry = 12; - my $sleep = 5; - for (my $i=0; $i < $maxtry; $i++) { - $listen_sock = IO::Socket::INET->new( - Listen => 2, - ReuseAddr => 1, - LocalAddr => "127.0.0.1", - LocalPort => $listen, - Proto => "tcp" - ); - if (! $listen_sock) { - if ($i < $maxtry - 1) { - warn "pproxy: vencrypt_viewer_bridge[$$]: $!\n"; - warn "Could not listen on port $listen, retrying in $sleep seconds... (Ctrl-C to quit)\n"; - sleep $sleep; - } - } else { - last; - } - } - if (! $listen_sock) { - die "pproxy: vencrypt_viewer_bridge[$$]: $!\n"; - } - print STDERR "pproxy: vencrypt_viewer_bridge[$$]: listening on port $listen\n\n"; - my ($viewer_sock, $ip) = $listen_sock->accept(); - my $err = $!; - close $listen_sock; - if (! $viewer_sock) { - die "pproxy: vencrypt_viewer_bridge[$$]: $err\n"; - } - if ($ENV{PPROXY_LOOP_THYSELF_MASTER}) { - my $sml = $ENV{SSVNC_MULTIPLE_LISTEN}; - if ($sml ne "" && $sml ne "0") { - setpgrp(0, 0); - if (fork()) { - close $viewer_sock; - wait; - exit 0; - } - if (fork()) { - close $viewer_sock; - exit 0; - } - setpgrp(0, 0); - $parent = $$; - } - } - print STDERR "vencrypt_viewer_bridge[$$]: viewer_sock $viewer_sock\n" if $db; - - print STDERR "pproxy: vencrypt_viewer_bridge[$$]: connecting to 127.0.0.1:$connect\n"; - my $server_sock = IO::Socket::INET->new( - PeerAddr => "127.0.0.1", - PeerPort => $connect, - Proto => "tcp" - ); - print STDERR "vencrypt_viewer_bridge[$$]: server_sock $server_sock\n" if $db; - if (! $server_sock) { - my $err = $!; - die "pproxy: vencrypt_viewer_bridge[$$]: $err\n"; - } - - if ($backwards) { - print STDERR "vencrypt_viewer_bridge[$$]: reversing roles of viewer and server.\n"; - my $t = $viewer_sock; - $viewer_sock = $server_sock; - $server_sock = $t; - } - - my %hs = (); - my $dt = 0.2; - my $slept = 0.0; - while ($slept < 20.0) { - select(undef, undef, undef, $dt); - $slept += $dt; - if (-f $handshake_file && open(HSF, "<$handshake_file")) { - my $done = 0; - %hs = (); - my $str = ""; - while (<HSF>) { - print STDERR "vencrypt_viewer_bridge[$$]: $_" if $ENV{VENCRYPT_VIEWER_BRIDGE_DEBUG}; - $str .= "vencrypt_viewer_bridge[$$]: $_"; - chomp; - if ($_ eq "done") { - $done = 1; - } else { - my ($k, $v) = split(/=/, $_, 2); - if ($k ne "" && $v ne "") { - $hs{$k} = $v; - } - } - } - close HSF; - if ($done) { - print STDERR "\n" . $str; - last; - } - } - } - if (! exists $hs{server}) { - $hs{server} = "RFB 003.008"; - } - if (! exists $hs{sectype}) { - unlink($handshake_file); - die "pproxy: vencrypt_viewer_bridge[$$]: no sectype.\n"; - } - syswrite($viewer_sock, "$hs{server}\n", length($hs{server}) + 1); - my $viewer_rfb = ""; - for (my $i = 0; $i < 12; $i++) { - my $c; - sysread($viewer_sock, $c, 1); - $viewer_rfb .= $c; - print STDERR $c; - } - my $viewer_major = 3; - my $viewer_minor = 8; - if ($viewer_rfb =~ /RFB (\d+)\.(\d+)/) { - $viewer_major = $1; - $viewer_minor = $2; - } - my $u0 = pack("C", 0); - my $u1 = pack("C", 1); - my $u2 = pack("C", 2); - if ($hs{sectype} == $rfbSecTypeAnonTls) { - unlink($handshake_file); - print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeAnonTls\n"; - if ($viewer_major > 3 || $viewer_minor >= 7) { - ; # setup ok, proceed to xfer. - } else { - print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n"; - my $n; - sysread($server_sock, $n, 1); - $n = unpack("C", $n); - if ($n == 0) { - die "pproxy: vencrypt_viewer_bridge[$$]: nsectypes == $n.\n"; - } - my %types; - for (my $i = 0; $i < $n; $i++) { - my $t; - sysread($server_sock, $t, 1); - $t = unpack("C", $t); - $types{$t} = 1; - } - my $use = 1; # None - if (exists $types{1}) { - $use = 1; # None - } elsif (exists $types{2}) { - $use = 2; # VncAuth - } else { - die "pproxy: vencrypt_viewer_bridge[$$]: no valid sectypes" . join(",", keys %types) . "\n"; - } - - # send 4 bytes sectype to viewer: - # (note this should be MSB, network byte order...) - my $up = pack("C", $use); - syswrite($viewer_sock, $u0, 1); - syswrite($viewer_sock, $u0, 1); - syswrite($viewer_sock, $u0, 1); - syswrite($viewer_sock, $up, 1); - # and tell server the one we selected: - syswrite($server_sock, $up, 1); - if ($use == 1) { - # even None has security result, so read it here and discard it. - my $sr = ""; - sysread($server_sock, $sr, 4); - } - } - } elsif ($hs{sectype} == $rfbSecTypeVencrypt) { - print STDERR "\npproxy: vencrypt_viewer_bridge[$$]: rfbSecTypeVencrypt\n"; - if (! exists $hs{subtype}) { - unlink($handshake_file); - die "pproxy: vencrypt_viewer_bridge[$$]: no subtype.\n"; - } - my $fake_type = "None"; - my $plain = 0; - my $sub_type = $hs{subtype}; - if ($sub_type == $rfbVencryptTlsNone) { - $fake_type = "None"; - } elsif ($sub_type == $rfbVencryptTlsVnc) { - $fake_type = "VncAuth"; - } elsif ($sub_type == $rfbVencryptTlsPlain) { - $fake_type = "None"; - $plain = 1; - } elsif ($sub_type == $rfbVencryptX509None) { - $fake_type = "None"; - } elsif ($sub_type == $rfbVencryptX509Vnc) { - $fake_type = "VncAuth"; - } elsif ($sub_type == $rfbVencryptX509Plain) { - $fake_type = "None"; - $plain = 1; - } - if ($plain) { - if (!open(W, ">$handshake_file")) { - unlink($handshake_file); - die "pproxy: vencrypt_viewer_bridge[$$]: $handshake_file $!\n"; - } - print W <<"END"; - - proc print_out {} { - global user pass env - - if [info exists env(SSVNC_UP_DEBUG)] { - toplevel .b - button .b.b -text "user=\$user pass=\$pass" -command {destroy .b} - pack .b.b - update - tkwait window .b - } - - if [info exists env(SSVNC_UP_FILE)] { - set fh "" - catch {set fh [open \$env(SSVNC_UP_FILE) w]} - if {\$fh != ""} { - puts \$fh user=\$user\\npass=\$pass - flush \$fh - close \$fh - return - } - } - puts stdout user=\$user\\npass=\$pass - flush stdout - } - - proc center_win {w} { - update - set W [winfo screenwidth \$w] - set W [expr \$W + 1] - wm geometry \$w +\$W+0 - update - set x [expr [winfo screenwidth \$w]/2 - [winfo width \$w]/2] - set y [expr [winfo screenheight \$w]/2 - [winfo height \$w]/2] - - wm geometry \$w +\$x+\$y - wm deiconify \$w - update - } - - wm withdraw . - - global env - set up {} - if [info exists env(SSVNC_UNIXPW)] { - set rm 0 - set up \$env(SSVNC_UNIXPW) - if [regexp {^rm:} \$up] { - set rm 1 - regsub {^rm:} \$up {} up - } - if [file exists \$up] { - set fh "" - set f \$up - catch {set fh [open \$up r]} - if {\$fh != ""} { - gets \$fh u - gets \$fh p - close \$fh - set up "\$u@\$p" - } - if {\$rm} { - catch {file delete \$f} - } - } - } elseif [info exists env(SSVNC_VENCRYPT_USERPASS)] { - set up \$env(SSVNC_VENCRYPT_USERPASS) - } - #puts stderr up=\$up - if {\$up != ""} { - if [regexp {@} \$up] { - global user pass - set user \$up - set pass \$up - regsub {@.*\$} \$user "" user - regsub {^[^@]*@} \$pass "" pass - print_out - exit - } - } - - wm title . {VeNCrypt Viewer Bridge User/Pass} - - set user {} - set pass {} - - label .l -text {SSVNC VeNCrypt Viewer Bridge} - - frame .f0 - frame .f0.fL - label .f0.fL.la -text {Username: } - label .f0.fL.lb -text {Password: } - - pack .f0.fL.la .f0.fL.lb -side top - - frame .f0.fR - entry .f0.fR.ea -width 24 -textvariable user - entry .f0.fR.eb -width 24 -textvariable pass -show * - - pack .f0.fR.ea .f0.fR.eb -side top -fill x - - pack .f0.fL -side left - pack .f0.fR -side right -expand 1 -fill x - - button .no -text Cancel -command {destroy .} - button .ok -text Done -command {print_out; destroy .} - - center_win . - pack .l .f0 .no .ok -side top -fill x - update - wm deiconify . - - bind .f0.fR.ea <Return> {focus .f0.fR.eb} - bind .f0.fR.eb <Return> {print_out; destroy .} - focus .f0.fR.ea - - wm resizable . 1 0 - wm minsize . [winfo reqwidth .] [winfo reqheight .] -END - close W; - - #system("cat $handshake_file"); - my $w = "wish"; - if ($ENV{WISH}) { - $w = $ENV{WISH}; - } - print STDERR "pproxy: vencrypt_viewer_bridge[$$]: prompt VencryptPlain user and passwd.\n"; - my $res = ""; - if (`uname` =~ /Darwin/) { - my $mtmp = `mktemp /tmp/hsup.XXXXXX`; - chomp $mtmp; - system("env SSVNC_UP_FILE=$mtmp $w $handshake_file"); - $res = `cat $mtmp`; - unlink $mtmp; - } else { - $res = `$w $handshake_file`; - } - my $user = ""; - my $pass = ""; - if ($res =~ /user=(\S*)/) { - $user = $1; - } - if ($res =~ /pass=(\S*)/) { - $pass = $1; - } - print STDERR "pproxy: vencrypt_viewer_bridge[$$]: sending VencryptPlain user and passwd.\n"; - my $ulen = pack("C", length($user)); - my $plen = pack("C", length($pass)); - # (note this should be MSB, network byte order...) - syswrite($server_sock, $u0, 1); - syswrite($server_sock, $u0, 1); - syswrite($server_sock, $u0, 1); - syswrite($server_sock, $ulen, 1); - syswrite($server_sock, $u0, 1); - syswrite($server_sock, $u0, 1); - syswrite($server_sock, $u0, 1); - syswrite($server_sock, $plen, 1); - syswrite($server_sock, $user, length($user)); - syswrite($server_sock, $pass, length($pass)); - } - unlink($handshake_file); - - my $ft = 0; - if ($fake_type eq "None") { - $ft = 1; - } elsif ($fake_type eq "VncAuth") { - $ft = 2; - } else { - die "pproxy: vencrypt_viewer_bridge[$$]: unknown fake type: $fake_type\n"; - } - my $fp = pack("C", $ft); - if ($viewer_major > 3 || $viewer_minor >= 7) { - syswrite($viewer_sock, $u1, 1); - syswrite($viewer_sock, $fp, 1); - my $cr; - sysread($viewer_sock, $cr, 1); - $cr = unpack("C", $cr); - if ($cr != $ft) { - die "pproxy: vencrypt_viewer_bridge[$$]: client selected wrong type: $cr / $ft\n"; - } - } else { - print STDERR "pproxy: vencrypt_viewer_bridge[$$]: faking RFB version 3.3 to viewer.\n"; - # send 4 bytes sect type to viewer: - # (note this should be MSB, network byte order...) - syswrite($viewer_sock, $u0, 1); - syswrite($viewer_sock, $u0, 1); - syswrite($viewer_sock, $u0, 1); - syswrite($viewer_sock, $fp, 1); - if ($ft == 1) { - # even None has security result, so read it here and discard it. - my $sr = ""; - sysread($server_sock, $sr, 4); - } - } - } - - $listen_handle = $viewer_sock; - $sock = $server_sock; - - xfer_both(); -} -' - # ' - # xpg_echo will expand \n \r, etc. - # try to unset and then test for it. - if type shopt > /dev/null 2>&1; then - shopt -u xpg_echo >/dev/null 2>&1 - fi - v='print STDOUT "abc\n";' - echo "$v" > $tf - chmod 700 $tf - - lc=`wc -l $tf | awk '{print $1}'` - if [ "X$lc" = "X1" ]; then - echo "$cod" > $tf - else - printf "%s" "$cod" > $tf - echo "" >> $tf - fi - # prime perl - perl -e 'use IO::Socket::INET; select(undef, undef, undef, 0.01)' >/dev/null 2>&1 -} - -# make_tcert is no longer invoked via the ssvnc gui (Listen mode). -# make_tcert is for testing only now via -mycert BUILTIN -make_tcert() { - tcert="/tmp/ss_vnc_viewer_tcert${RANDOM}.$$" - tcert=`mytmp "$tcert"` - cat > $tcert <<END ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAvkfXxb0wcxgrjV2ziFikjII+ze8iKcTBt47L0GM/c21efelN -+zZpJUUXLu4zz8Ryq8Q+sQgfNy7uTOpN9bUUaOk1TnD7gaDQnQWiNHmqbW2kL+DS -OKngJVPo9dETAS8hf7+D1e1DBZxjTc1a4RQqWJixwpYj99ixWzu8VC2m/xXsjvOs -jp4+DLBB490nbkwvstmhmiWm1CmI5O5xOkgioVNQqHvQMdVKOSz9PpbjvZiRX1Uo -qoMrk+2NOqwP90TB35yPASXb9zXKpO7DLhkube+yYGf+yk46aD707L07Eb7cosFP -S84vNZ9gX7rQ0UOwm5rYA/oZTBskgaqhtIzkLwIDAQABAoIBAD4ot/sXt5kRn0Ca -CIkU9AQWlC+v28grR2EQW9JiaZrqcoDNUzUqbCTJsi4ZkIFh2lf0TsqELbZYNW6Y -6AjJM7al4E0UqYSKJTv2WCuuRxdiRs2BMwthqyBmjeanev7bB6V0ybt7u3Y8xU/o -MrTuYnr4vrEjXPKdLirwk7AoDbKsRXHSIiHEIBOq1+dUQ32t36ukdnnza4wKDLZc -PKHiCdCk/wOGhuDlxD6RspqUAlRnJ8/aEhrgWxadFXw1hRhRsf/v1shtB0T3DmTe -Jchjwyiw9mryb9JZAcKxW+fUc4EVvj6VdQGqYInQJY5Yxm5JAlVQUJicuuJEvn6A -rj5osQECgYEA552CaHpUiFlB4HGkjaH00kL+f0+gRF4PANCPk6X3UPDVYzKnzmuu -yDvIdEETGFWBwoztUrOOKqVvPEQ+kBa2+DWWYaERZLtg2cI5byfDJxQ3ldzilS3J -1S3WgCojqcsG/hlxoQJ1dZFanUy/QhUZ0B+wlC+Zp1Q8AyuGQvhHp68CgYEA0lBI -eqq2GGCdJuNHMPFbi8Q0BnX55LW5C1hWjhuYiEkb3hOaIJuJrqvayBlhcQa2cGqp -uP34e9UCfoeLgmoCQ0b4KpL2NGov/mL4i8bMgog4hcoYuIi3qxN18vVR14VKEh4U -RLk0igAYPU+IK2QByaQlBo9OSaKkcfm7U1/pK4ECgYAxr6VpGk0GDvfF2Tsusv6d -GIgV8ZP09qSLTTJvvxvF/lQYeqZq7sjI5aJD5i3de4JhpO/IXQJzfZfWOuGc8XKA -3qYK/Y2IqXXGYRcHFGWV/Y1LFd55mCADHlk0l1WdOBOg8P5iRu/Br9PbiLpCx9oI -vrOXpnp03eod1/luZmqguwKBgQCWFRSj9Q7ddpSvG6HCG3ro0qsNsUMTI1tZ7UBX -SPogx4tLf1GN03D9ZUZLZVFUByZKMtPLX/Hi7K9K/A9ikaPrvsl6GEX6QYzeTGJx -3Pw0amFrmDzr8ySewNR6/PXahxPEuhJcuI31rPufRRI3ZLah3rFNbRbBFX+klkJH -zTnoAQKBgDbUK/aQFGduSy7WUT7LlM3UlGxJ2sA90TQh4JRQwzur0ACN5GdYZkqM -YBts4sBJVwwJoxD9OpbvKu3uKCt41BSj0/KyoBzjT44S2io2tj1syujtlVUsyyBy -/ca0A7WBB8lD1D7QMIhYUm2O9kYtSCLlUTHt5leqGaRG38DqlX36 ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDzDCCArQCCQDSzxzxqhyqLzANBgkqhkiG9w0BAQQFADCBpzELMAkGA1UEBhMC -VVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNVBAcTBkJvc3RvbjETMBEG -A1UEChMKTXkgQ29tcGFueTEcMBoGA1UECxMTUHJvZHVjdCBEZXZlbG9wbWVudDEZ -MBcGA1UEAxMQd3d3Lm5vd2hlcmUubm9uZTEhMB8GCSqGSIb3DQEJARYSYWRtaW5A -bm93aGVyZS5ub25lMB4XDTA3MDMyMzE4MDc0NVoXDTI2MDUyMjE4MDc0NVowgacx -CzAJBgNVBAYTAlVTMRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQ8wDQYDVQQHEwZC -b3N0b24xEzARBgNVBAoTCk15IENvbXBhbnkxHDAaBgNVBAsTE1Byb2R1Y3QgRGV2 -ZWxvcG1lbnQxGTAXBgNVBAMTEHd3dy5ub3doZXJlLm5vbmUxITAfBgkqhkiG9w0B -CQEWEmFkbWluQG5vd2hlcmUubm9uZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAL5H18W9MHMYK41ds4hYpIyCPs3vIinEwbeOy9BjP3NtXn3pTfs2aSVF -Fy7uM8/EcqvEPrEIHzcu7kzqTfW1FGjpNU5w+4Gg0J0FojR5qm1tpC/g0jip4CVT -6PXREwEvIX+/g9XtQwWcY03NWuEUKliYscKWI/fYsVs7vFQtpv8V7I7zrI6ePgyw -QePdJ25ML7LZoZolptQpiOTucTpIIqFTUKh70DHVSjks/T6W472YkV9VKKqDK5Pt -jTqsD/dEwd+cjwEl2/c1yqTuwy4ZLm3vsmBn/spOOmg+9Oy9OxG+3KLBT0vOLzWf -YF+60NFDsJua2AP6GUwbJIGqobSM5C8CAwEAATANBgkqhkiG9w0BAQQFAAOCAQEA -vGomHEp6TVU83X2EBUgnbOhzKJ9u3fOI/Uf5L7p//Vxqow7OR1cguzh/YEzmXOIL -ilMVnzX9nj/bvcLAuqEP7MR1A8f4+E807p/L/Sf49BiCcwQq5I966sGKYXjkve+T -2GTBNwMSq+5kLSf6QY8VZI+qnrAudEQMeJByQhTZZ0dH8Njeq8EGl9KUio+VWaiW -CQK6xJuAvAHqa06OjLmwu1fYD4GLGSrOIiRVkSXV8qLIUmzxdJaIRznkFWsrCEKR -wAH966SAOvd2s6yOHMvyDRIL7WHxfESB6rDHsdIW/yny1fBePjv473KrxyXtbz7I -dMw1yW09l+eEo4A7GzwOdw== ------END CERTIFICATE----- -END - chmod 600 $tcert - echo "$tcert" -} - -Kecho() { - NO_KECHO=1 - if [ "X$USER" = "Xrunge" -a "X$NO_KECHO" = "X" ]; then - echo "dbg: $*" - fi -} - -NHAFL_warning() { - echo "" - echo "** Warning: For the proxy: $proxy" - echo "** Warning: the ssh(1) option: $ssh_NHAFL" - echo "** Warning: will be used to avoid frequent 'ssh key has changed for localhost'" - echo "** Warning: dialogs and connection failures (for example, ssh will exit asking" - echo "** Warning: you to manually remove a key from ~/.ssh/known_hosts.)" - echo "** Warning: " - echo "** Warning: This decreases security: a Man-In-The-Middle attack is possible." - echo "** Warning: For chained ssh connections the first ssh leg is secure but the" - echo "** Warning: 2nd ssh leg is vulnerable. For an ssh connection going through" - echo "** Warning: a HTTP or SOCKS proxy the ssh connection is vulnerable." - echo "** Warning: " - echo "** Warning: You can set the SSVNC_SSH_LOCALHOST_AUTH=1 env. var. to disable" - echo "** Warning: using the NoHostAuthenticationForLocalhost=yes ssh option." - echo "** Warning: " - echo "** Warning: A better solution is to configure (in the SSVNC GUI) the setting:" - echo "** Warning: 'Options -> Advanced -> Private SSH KnownHosts file' (or set" - echo "** Warning: SSVNC_KNOWN_HOSTS_FILE directly) to a per-connection known hosts" - echo "** Warning: file. That file holds the 'localhost' cert for this specific" - echo "** Warning: connection. This yields a both secure and convenient solution." - echo "" -} - -space_expand() { - str=`echo "$1" | sed -e 's/%SPACE/ /g' -e 's/%TAB/\t/g'` - echo "$str" -} - -# handle ssh case: -# -if [ "X$use_ssh" = "X1" ]; then - # - # USING SSH - # - ssh_port="22" - ssh_host="$host" - vnc_host="$localhost" - ssh_UKHF="" - localhost_extra="" - # let user override ssh via $SSH - ssh=${SSH:-"ssh -x"} - - sshword=`echo "$ssh" | awk '{print $1}'` - if [ "X$sshword" != "X" ]; then - if [ -x "$sshword" ]; then - : - elif type "$sshword" > /dev/null 2>&1; then - : - else - echo "" - echo "*********************************************************" - echo "** Problem finding the SSH command '$sshword': **" - echo "" - type "$sshword" - echo "" - echo "** Perhaps you need to install the SSH client package. **" - echo "*********************************************************" - echo "" - sleep 5 - fi - fi - - ssh_NHAFL="-o NoHostAuthenticationForLocalhost=yes" - if [ "X$SSVNC_SSH_LOCALHOST_AUTH" = "X1" ]; then - ssh_NHAFL="" - fi - if [ "X$SSVNC_KNOWN_HOSTS_FILE" != "X" ]; then - ssh_NHAFL="" - - ssh_UKHF="-o UserKnownHostsFile=$SSVNC_KNOWN_HOSTS_FILE" - ssh_args="$ssh_args $ssh_UKHF" - if [ ! -f "$SSVNC_KNOWN_HOSTS_FILE" ]; then - touch "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1 - fi - chmod 600 "$SSVNC_KNOWN_HOSTS_FILE" >/dev/null 2>&1 - fi - did_ssh_NHAFL="" - - if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then - SSVNC_LIM_ACCEPT_PRELOAD="$SSVNC_BASEDIR/$SSVNC_UNAME/$SSVNC_LIM_ACCEPT_PRELOAD" - fi - if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ]; then - echo "" - echo "SSVNC_LIM_ACCEPT_PRELOAD=$SSVNC_LIM_ACCEPT_PRELOAD" - fi - - if [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" -a -f "$SSVNC_LIM_ACCEPT_PRELOAD" ]; then - plvar=LD_PRELOAD - if uname | grep Darwin >/dev/null; then - plvar="DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES" - fi - ssh="env $plvar=$SSVNC_LIM_ACCEPT_PRELOAD $ssh" - else - SSVNC_LIM_ACCEPT_PRELOAD="" - fi - - ssh_vencrypt_proxy="" - # We handle vencrypt for SSH+SSL mode. - if echo "$proxy" | grep 'vencrypt://' > /dev/null; then - proxynew="" - for part in `echo "$proxy" | tr ',' ' '` - do - if echo "$part" | egrep -i '^vencrypt://' > /dev/null; then - ssh_vencrypt_proxy=$part - else - if [ "X$proxynew" = "X" ]; then - proxynew="$part" - else - proxynew="$proxynew,$part" - fi - fi - done - proxy=$proxynew - fi - Kecho ssh_vencrypt_proxy=$ssh_vencrypt_proxy - - # note that user must supply http:// for web proxy in SSH and SSH+SSL. - # No xxxx:// implies ssh server+port. - # - if echo "$proxy" | egrep '(http|https|socks|socks4|socks5)://' > /dev/null; then - # Handle Web or SOCKS proxy(ies) for the initial connect. - Kecho host=$host - Kecho port=$port - pproxy="" - sproxy1="" - sproxy_rest="" - for part in `echo "$proxy" | tr ',' ' '` - do - Kecho proxy_part=$part - if [ "X$part" = "X" ]; then - continue - elif echo "$part" | egrep -i '^(http|https|socks|socks4|socks5)://' > /dev/null; then - pproxy="$pproxy,$part" - else - if [ "X$sproxy1" = "X" ]; then - sproxy1="$part" - else - sproxy_rest="$sproxy_rest,$part" - fi - fi - done - pproxy=`echo "$pproxy" | sed -e 's/^,,*//' -e 's/,,*/,/g'` - sproxy_rest=`echo "$sproxy_rest" | sed -e 's/^,,*//' -e 's/,,*/,/g'` - - Kecho pproxy=$pproxy - Kecho sproxy1=$sproxy1 - Kecho sproxy_rest=$sproxy_rest - - sproxy1_host="" - sproxy1_port="" - sproxy1_user="" - - if [ "X$sproxy1" != "X" ]; then - sproxy1_host=`echo "$sproxy1" | awk -F: '{print $1}'` - sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'` - sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'` - if [ "X$sproxy1_host" = "X" ]; then - sproxy1_host=$sproxy1_user - sproxy1_user="" - else - sproxy1_user="${sproxy1_user}@" - fi - sproxy1_port=`echo "$sproxy1" | awk -F: '{print $2}'` - if [ "X$sproxy1_port" = "X" ]; then - sproxy1_port="22" - fi - else - sproxy1_host=`echo "$host" | awk -F: '{print $1}'` - sproxy1_user=`echo "$sproxy1_host" | awk -F@ '{print $1}'` - sproxy1_host=`echo "$sproxy1_host" | awk -F@ '{print $2}'` - if [ "X$sproxy1_host" = "X" ]; then - sproxy1_host=$sproxy1_user - sproxy1_user="" - else - sproxy1_user="${sproxy1_user}@" - fi - sproxy1_port=`echo "$host" | awk -F: '{print $2}'` - if [ "X$sproxy1_port" = "X" ]; then - sproxy1_port="22" - fi - fi - - Kecho sproxy1_host=$sproxy1_host - Kecho sproxy1_port=$sproxy1_port - Kecho sproxy1_user=$sproxy1_user - - ptmp="/tmp/ss_vncviewer_ssh${RANDOM}.$$.pl" - ptmp=`mytmp "$ptmp"` - PPROXY_REMOVE=1; export PPROXY_REMOVE - proxy=$pproxy - port_save=$port - host_save=$host - if [ "X$sproxy1_host" != "X" ]; then - host=$sproxy1_host - fi - if [ "X$sproxy1_port" != "X" ]; then - port=$sproxy1_port - fi - host=`echo "$host" | sed -e 's/^.*@//'` - port=`echo "$port" | sed -e 's/^.*://'` - pcode "$ptmp" - port=$port_save - host=$host_save - - nd=`findfree 6600` - PPROXY_LISTEN=$nd; export PPROXY_LISTEN - # XXX no reverse forever PPROXY_LOOP_THYSELF ... - $ptmp & - sleep 1 - if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then - NHAFL_warning - ssh_args="$ssh_args $ssh_NHAFL" - did_ssh_NHAFL=1 - fi - sleep 1 - if [ "X$sproxy1" = "X" ]; then - u="" - if echo "$host" | grep '@' > /dev/null; then - u=`echo "$host" | sed -e 's/@.*$/@/'` - fi - - proxy="${u}$localhost:$nd" - else - proxy="${sproxy1_user}$localhost:$nd" - fi - localhost_extra=".2" - if [ "X$sproxy_rest" != "X" ]; then - proxy="$proxy,$sproxy_rest" - fi - Kecho proxy=$proxy - fi - - if echo "$proxy" | grep "," > /dev/null; then - - proxy1=`echo "$proxy" | awk -F, '{print $1}'` - proxy2=`echo "$proxy" | awk -F, '{print $2}'` - - # user1@gw1.com:port1,user2@ws2:port2 - ssh_host1=`echo "$proxy1" | awk -F: '{print $1}'` - ssh_port1=`echo "$proxy1" | awk -F: '{print $2}'` - if [ "X$ssh_port1" != "X" ]; then - ssh_port1="-p $ssh_port1" - fi - ssh_host2=`echo "$proxy2" | awk -F: '{print $1}'` - ssh_user2=`echo "$ssh_host2" | awk -F@ '{print $1}'` - ssh_host2=`echo "$ssh_host2" | awk -F@ '{print $2}'` - if [ "X$ssh_host2" = "X" ]; then - ssh_host2=$ssh_user2 - ssh_user2="" - else - ssh_user2="${ssh_user2}@" - fi - ssh_port2=`echo "$proxy2" | awk -F: '{print $2}'` - if [ "X$ssh_port2" = "X" ]; then - ssh_port2="22" - fi - proxport=`findfree 3500` - if [ "X$ssh_NHAFL" != "X" -a "X$did_ssh_NHAFL" != "X1" ]; then - NHAFL_warning - did_ssh_NHAFL=1 - sleep 1 - fi - echo - echo "Running 1st ssh proxy:" - ukhf="" - if [ "X$ssh_UKHF" != "X" ]; then - ukhf="$ssh_UKHF$localhost_extra" - fi - if echo "$ssh_host1" | grep '%' > /dev/null; then - uath=`space_expand "$ssh_host1"` - else - uath="$ssh_host1" - fi - echo "$ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 \"$uath\" \"sleep 30\"" - echo "" - $ssh -f -x $ssh_port1 $targ -e none $ssh_NHAFL $ukhf -L $proxport:$ssh_host2:$ssh_port2 "$uath" "sleep 30" - ssh_args="$ssh_args $ssh_NHAFL" - sleep 1 - stty sane - proxy="${ssh_user2}$localhost:$proxport" - fi - - if [ "X$proxy" != "X" ]; then - ssh_port=`echo "$proxy" | awk -F: '{print $2}'` - if [ "X$ssh_port" = "X" ]; then - ssh_port="22" - fi - ssh_host=`echo "$proxy" | awk -F: '{print $1}'` - vnc_host="$host" - fi - - echo "" - echo "Running ssh:" - sz=`echo "$ssh_cmd" | wc -c` - if [ "$sz" -gt 300 ]; then - info="..." - else - info="$ssh_cmd" - fi - - C="" - if [ "X$SS_VNCVIEWER_USE_C" != "X" ]; then - C="-C" - fi - - getport="" - teeport="" - if echo "$ssh_cmd" | egrep "(PORT=|P=) " > /dev/null; then - getport=1 - if echo "$ssh_cmd" | egrep "P= " > /dev/null; then - teeport=1 - fi - - PORT="" - ssh_cmd=`echo "$ssh_cmd" | sed -e 's/PORT=[ ]*//' -e 's/P=//'` - SSVNC_NO_ENC_WARN=1 - if [ "X$use_sshssl" = "X" ]; then - direct_connect=1 - fi - fi - if [ "X$getport" != "X" ]; then - ssh_redir="-D ${use}" - elif [ "X$reverse" = "X" ]; then - ssh_redir="-L ${use}:${vnc_host}:${port}" - else - ssh_redir="-R ${port}:${vnc_host}:${use}" - fi - pmark=`sh -c 'echo $$'` - - # the -t option actually speeds up typing response via VNC!! - if [ "X$ssh_port" = "X22" ]; then - ssh_port="" - else - ssh_port="-p $ssh_port" - fi - - if echo "$ssh_host" | grep '%' > /dev/null; then - uath=`space_expand "$ssh_host"` - else - uath="$ssh_host" - fi - if [ "X$SS_VNCVIEWER_SSH_ONLY" != "X" ]; then - echo "$ssh -x $ssh_port $targ $C $ssh_args \"$uath\" \"$info\"" - echo "" - $ssh -x $ssh_port $targ $C $ssh_args "$uath" "$ssh_cmd" - exit $? - - elif [ "X$SS_VNCVIEWER_NO_F" != "X" ]; then - echo "$ssh -x $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\"" - echo "" - $ssh -x $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd" - rc=$? - - elif [ "X$getport" != "X" ]; then - tport=/tmp/ss_vncviewer_tport${RANDOM}.$$ - tport=`mytmp "$tport"` - tport2=/tmp/ss_vncviewer_tport2${RANDOM}.$$ - tport2=`mytmp "$tport2"` - - if [ "X$rsh" != "X1" ]; then - if echo "$ssh_cmd" | grep "sudo " > /dev/null; then - echo "" - echo "Initial ssh with 'sudo id' to prime sudo so hopefully the next one" - echo "will require no password..." - echo "" - targ="-t" - $ssh -x $ssh_port $targ $ssh_args "$uath" "sudo id; tty" - echo "" - fi - echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\"" - echo "" - $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd" > $tport 2> $tport2 - if [ "X$teeport" = "X1" ]; then - tail -f $tport 1>&2 & - tail_pid=$! - tail -f $tport2 1>&2 & - tail_pid2=$! - fi - rc=$? - else - rsh_setup - echo "rsh $ul \"$ssh_host\" \"$ssh_cmd\"" - echo "" - rsh $ul "$ssh_host" "$ssh_cmd" > $tport & - sleep 1 - rc=0 - fi - - if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then - echo "sleep $SSVNC_EXTRA_SLEEP" - sleep $SSVNC_EXTRA_SLEEP - fi - - stty sane - i=0 - if type perl > /dev/null 2>&1; then - imax=50 - sleepit="perl -e 'select(undef, undef, undef, 0.20)'" - else - imax=10 - sleepit="sleep 1" - fi - while [ $i -lt $imax ]; do - #echo $sleepit - eval $sleepit - PORT=`grep "^PORT=" $tport | tr '\r' ' ' | head -n 1 | sed -e 's/PORT=//' -e 's/\r//g' -e 's/ *$//'` - if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then - break - fi - vnss=`sed -e 's/\r//g' $tport $tport2 | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1 | awk '{print $NF}'` - if [ "X$vnss" != "X" ]; then - PORT=`echo "$vnss" | awk -F: '{print $2}'` - if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then - if [ $PORT -lt 100 ]; then - PORT=`expr $PORT + 5900` - fi - fi - if echo "$PORT" | grep '^[0-9][0-9]*$' > /dev/null; then - vnss=`sed -e 's/\r//g' $tport | egrep -i '^(New.* desktop is|A VNC server is already running).*:[0-9[0-9]*$' | head -n 1` - echo "vncserver string: $vnss" 1>&2 - break - fi - fi - i=`expr $i + 1` - done - - echo "found: PORT='$PORT'" 1>&2 - lh6="" - if [ "X$SSVNC_PORT_IPV6" != "X" ]; then - lh6=1 - elif egrep 'Info: listening on IPv6 only|Info: listening only on IPv6' $tport > /dev/null; then - lh6=1 - fi - if [ "X$lh6" = "X1" ]; then - echo "set SOCKS5 localhost to ::1" 1>&2 - fi - rm -f $tport $tport2 - if [ "X$rsh" = "X1" ]; then - rsh_viewer "$@" - exit $? - fi - PPROXY_SOCKS=5 - if [ "X$SSVNC_SOCKS5" != "X" ]; then - PPROXY_SOCKS=5 - elif [ "X$SSVNC_SOCKS4" != "X" ]; then - PPROXY_SOCKS=1 - fi - export PPROXY_SOCKS - if [ "X$lh6" = "X" ]; then - host="$localhost" - else - host="::1" - fi - port="$PORT" - proxy="$localhost:$use" - - else - if [ "X$rsh" != "X1" ]; then - echo "$ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args \"$uath\" \"$info\"" - echo "" - $ssh -x -f $ssh_port $targ $C $ssh_redir $ssh_args "$uath" "$ssh_cmd" - rc=$? - else - rsh_setup - echo "rsh $ul \"$ssh_host\" \"$ssh_cmd\"" - echo "" - rsh $ul "$ssh_host" "$ssh_cmd" & - sleep 1 - PORT=$port - rsh_viewer "$@" - exit $? - fi - fi - - if [ "$rc" != "0" ]; then - echo "" - echo "ssh to \"$uath\" failed." - exit 1 - fi - stty sane - - c=0 - pssh="" - while [ $c -lt 40 ] - do - p=`expr $pmark + $c` - pout=`ps -p "$p" 2>/dev/null | grep -v '^[ ]*PID' | sed -e 's/-L.*$//' -e 's/-x .*$//'` - if echo "$pout" | grep "ssh" > /dev/null; then - if echo "$pout" | egrep -i 'ssh.*(-add|-agent|-ask|-keygen|-argv0|vnc)' >/dev/null; then - : - elif echo "$pout" | egrep -i 'scp|sshd' >/dev/null; then - : - else - pssh=$p - break - fi - fi - c=`expr $c + 1` - done - if [ "X$getport" != "X" ]; then - : - elif [ "X$SSVNC_LIM_ACCEPT_PRELOAD" != "X" ] ; then - sleep 2 - elif [ "X$ssh_cmd" = "Xsleep $ssh_sleep" ] ; then - #echo T sleep 1 - sleep 1 - elif echo "$ssh_cmd" | grep '^sleep ' >/dev/null; then - #echo T sleep 2 - sleep 2 - else - # let any command get started a bit. - #echo T sleep 5 - sleep 5 - fi - echo "" - #reset - stty sane - if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then - echo "sleep $SSVNC_EXTRA_SLEEP" - sleep $SSVNC_EXTRA_SLEEP - fi - echo "ssh_pid='$pssh'"; echo - if [ "X$use_sshssl" = "X" -a "X$getport" = "X" ]; then - echo "Running viewer:" - - trap "final" 0 2 15 - if [ "X$reverse" = "X" ]; then - echo "$VNCVIEWERCMD" "$@" $localhost:$N - echo "" - $VNCVIEWERCMD "$@" $localhost:$N - if [ $? != 0 ]; then - echo "vncviewer command failed: $?" - if [ "X$secondtry" = "X1" ]; then - sleep 2 - $VNCVIEWERCMD "$@" $localhost:$N - fi - fi - else - echo "" - echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." - echo "" - N2=$N - if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then - N2=`echo "$N2" | sed -e 's/://g'` - if [ $N2 -le 200 ]; then - N2=`expr $N2 + 5500` - fi - fi - echo "$VNCVIEWERCMD" "$@" -listen $N2 - echo "" - $VNCVIEWERCMD "$@" -listen $N2 - fi - - exit $? - else - use2=`findfree 5960` - host0=$host - port0=$port - host=$localhost - port=$use - use=$use2 - N=`expr $use - 5900` - if [ "X$getport" != "X" ]; then - host="$host0" - port="$port0" - else - proxy="" - fi - if [ "X$ssh_vencrypt_proxy" != "X" ]; then - ssh_vencrypt_proxy="vencrypt://$host:$port" - if [ "X$proxy" = "X" ]; then - proxy=$ssh_vencrypt_proxy - else - proxy="$proxy,$ssh_vencrypt_proxy" - fi - Kecho "proxy_now=$proxy" - unset PPROXY_LISTEN - fi - fi -fi - -if [ "X$stunnel_set_here" = "X1" -a "X$showcert" = "X" ]; then - if type $STUNNEL > /dev/null 2>&1; then - : - else - echo "" - echo "***************************************************************" - echo "** Problem finding the Stunnel command '$STUNNEL': **" - echo "" - type $STUNNEL - echo "" - echo "** Perhaps you need to install the stunnel/stunnel4 package. **" - echo "***************************************************************" - echo "" - sleep 5 - fi -fi - -# create the stunnel config file: -if [ "X$verify" != "X" ]; then - if [ -d $verify ]; then - verify="CApath = $verify" - else - verify="CAfile = $verify" - fi - verify="$verify -verify = 2" -fi -if [ "X$SSVNC_STUNNEL_VERIFY3" != "X" ]; then - verify=`echo "$verify" | sed -e 's/verify = 2/verify = 3/'` -fi -if [ "X$mycert" != "X" ]; then - cert="cert = $mycert" -fi -if [ "X$crl" != "X" ]; then - if [ -d $crl ]; then - crl="CRLpath = $crl" - else - crl="CRLfile = $crl" - fi -fi - -if [ "X$showcert" = "X1" ]; then - if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then - : - elif [ "X$SSVNC_NO_IPV6_PROXY" != "X" ]; then - : - elif [ "X$ipv6" = "X1" -a "X$proxy" = "X" ]; then - proxy="ipv6://$host:$port" - fi -fi - -if [ "X$direct_connect" != "X" -a "X$STUNNEL_LISTEN" != "X" ]; then - proxy=reverse_direct -fi - -ptmp="" -if [ "X$proxy" != "X" ]; then - ptmp="/tmp/ss_vncviewer${RANDOM}.$$.pl" - ptmp=`mytmp "$ptmp"` - PPROXY_REMOVE=1; export PPROXY_REMOVE - pcode "$ptmp" - if [ "X$showcert" != "X1" -a "X$direct_connect" = "X" ]; then - if uname | egrep 'Darwin|SunOS' >/dev/null; then - vout=`echo "$proxy" | grep -i vencrypt` - if [ "X$vout" != "X" -a "X$reverse" = "X1" ]; then - # need to exec for reverse vencrypt - connect="exec = $ptmp" - else - # on mac and solaris we need to listen on socket instead of stdio: - nd=`findfree 6700` - PPROXY_LISTEN=$nd - export PPROXY_LISTEN - if [ "X$reverse" = "X" ]; then - $ptmp & - fi - sleep 2 - host="$localhost" - port="$nd" - connect="connect = $localhost:$nd" - fi - else - # otherwise on unix we can exec it: - connect="exec = $ptmp" - fi - else - connect="exec = $ptmp" - fi -else - connect="connect = $host:$port" -fi - -# handle showcert case: -# -if [ "X$showcert" = "X1" ]; then - if [ "X$proxy" != "X" ]; then - PPROXY_LISTEN=$use - export PPROXY_LISTEN - if [ "X$SS_DEBUG" != "X" ]; then - $ptmp & - else - $ptmp 2>/dev/null & - fi - sleep 1 - more_sleep=1 - if uname | grep Linux > /dev/null; then - if netstat -ant | grep LISTEN | grep "127.0.0.1:$use" > /dev/null; then - more_sleep="" - fi - elif uname | grep SunOS > /dev/null; then - if netstat -an -f inet -P tcp | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then - more_sleep="" - fi - elif uname | egrep -i 'bsd|darwin' > /dev/null; then - if netstat -ant -f inet | grep LISTEN | grep "127.0.0.1.$use" > /dev/null; then - more_sleep="" - fi - fi - if [ "X$more_sleep" = "X1" ]; then - sleep 1 - fi - host="$localhost" - port="$use" - fi - cipher_args="" - if [ "X$ciphers" != "X" ]; then - cipher_args=`echo "$ciphers" | sed -e 's/ciphers=/-cipher /'` - fi - if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then - : - elif type openssl > /dev/null 2>&1; then - : - else - echo "" - echo "********************************************************" - echo "** Problem finding the OpenSSL command 'openssl': **" - echo "" - type openssl 2>&1 - echo "" - echo "** Perhaps you need to install the 'openssl' package. **" - echo "********************************************************" - echo "" - fi - #echo "openssl s_client $cipher_args -connect $host:$port" - if [ "X$reverse" = "X" ]; then - if type host > /dev/null 2>/dev/null; then - host $host >/dev/null 2>&1 - host $host >/dev/null 2>&1 - fi - timeout=15 - if [ "X$SSVNC_FETCH_TIMEOUT" != "X" ]; then - timeout=$SSVNC_FETCH_TIMEOUT - fi - if [ "X$have_uvnc_dsm_helper_showcert" = "X1" ]; then - if type pkill >/dev/null 2>&1; then - (sleep $timeout; if kill -0 $$; then pkill -TERM -f "ultravnc_dsm_helper.*$host.*$port"; fi) >/dev/null 2>&1 & - fi - ultravnc_dsm_helper showcert $host:$port 2>&1 - else - if type pkill >/dev/null 2>&1; then - (sleep $timeout; if kill -0 $$; then pkill -TERM -f "openssl.*s_client.*$host.*$port"; fi) >/dev/null 2>&1 & - fi - openssl s_client $cipher_args -prexit -connect $host:$port 2>&1 < /dev/null - fi - rc=$? - else - tcert="" - if [ "X$mycert" = "X" ]; then - tcert=`make_tcert` - cert_args="-cert $tcert -CAfile $tcert" - else - cert_args="-cert $mycert -CAfile $mycert" - fi - tmp_out=/tmp/showcert_out${RANDOM}.$$ - tmp_out=`mytmp "$tmp_out"` - tmp_err=/tmp/showcert_err${RANDOM}.$$ - tmp_err=`mytmp "$tmp_err"` - - #echo "openssl s_server $cipher_args $cert_args -accept $port -verify 2 > $tmp_out 2> $tmp_err" 1>&2 - - # assume we have perl: - check_perl perl - - perl -e " - \$p = open(O, \"|openssl s_server $cipher_args $cert_args -accept $port -verify 2 1>$tmp_out 2> $tmp_err\"); - exit 1 unless \$p; - while (1) { - sleep 1; - if (!open(F, \"<$tmp_out\")) { - kill \$p; - exit 1; - } - while (<F>) { - if (/RFB 00/) { - fsleep(0.25); - print O \"RFB 000.000\\n\"; - fsleep(1.00); - kill \$p; - fsleep(0.25); - exit 0; - } - } - close F; - } - sub fsleep { - select(undef, undef, undef, shift); - } - "; - - echo "" - cat $tmp_out - echo "" - echo "----2----" - cat $tmp_err - if grep BEGIN.CERTIFICATE $tmp_out >/dev/null; then - rc=0 - else - rc=1 - fi - - rm -f $tmp_out $tmp_err - fi - if [ "X$SSVNC_PREDIGESTED_HANDSHAKE" != "X" ]; then - rm -f $SSVNC_PREDIGESTED_HANDSHAKE - fi - if [ "X$SSVNC_SHOWCERT_EXIT_0" = "X1" ]; then - exit 0 - else - exit $rc - fi -fi - -# handle direct connect case: -# -if [ "X$direct_connect" != "X" ]; then - if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then - SSVNC_NO_ENC_WARN=1 - echo "" - echo "Using UltraVNC DSM Plugin key for encryption:" - echo "" - ustr=`echo "$SSVNC_ULTRA_DSM" | sed -e 's/pw=[^ ]*/pw=******/g'` - echo " $ustr PORT HOST:PORT" - echo "" - elif [ "X$getport" = "X" ]; then - echo "" - echo "Running viewer for direct connection:" - if echo X"$@" | grep chatonly > /dev/null; then - : - else - echo "" - echo "** WARNING: THERE WILL BE NO SSL OR SSH ENCRYPTION **" - echo "" - fi - fi - x="" - if [ "X$SSVNC_NO_ENC_WARN" != "X" ]; then - if [ "X$getport" = "X" ]; then - sleep 1 - fi - elif type printf > /dev/null 2>&1; then - printf "Are you sure you want to continue? [y]/n " - read x - else - echo -n "Are you sure you want to continue? [y]/n " - read x - fi - if [ "X$x" = "Xn" ]; then - exit 1 - fi - echo "" - if [ "X$ptmp" != "X" ]; then - if [ "X$reverse" = "X" ]; then - PPROXY_LISTEN=$use - export PPROXY_LISTEN - else - if [ "X$proxy" = "Xreverse_direct" ]; then - PPROXY_LISTEN="$STUNNEL_LISTEN:`expr 5500 + $disp`" - PPROXY_DEST="$localhost:$use" - PPROXY_PROXY="ipv6://$localhost:$use" # not always ipv6.. - export PPROXY_LISTEN PPROXY_DEST PPROXY_PROXY - pps=1 - else - PPROXY_REVERSE="$localhost:$use" - export PPROXY_LISTEN - pps=3 - fi - if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then - PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself.${RANDOM}.$$"` - export PPROXY_LOOP_THYSELF - pps=2 - fi - if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then - pps=`expr $pps + $SSVNC_EXTRA_SLEEP` - fi - PPROXY_SLEEP=$pps; export PPROXY_SLEEP; - PPROXY_KILLPID=+1; export PPROXY_KILLPID; - fi - - $ptmp & - - if [ "X$reverse" = "X" ]; then - #sleep 2 - #echo T sleep 1 - sleep 1 - fi - host="$localhost" - disp="$N" - port=`expr $disp + 5900` - fi - if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then - echo "T sleep $SSVNC_EXTRA_SLEEP" - sleep $SSVNC_EXTRA_SLEEP - fi - if [ "X$reverse" = "X" ]; then - hostdisp="$host:$disp" - if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then - if [ "X$SSVNC_USE_OURS" = "X1" ]; then - hostdisp="exec=$SSVNC_ULTRA_DSM 0 $host:$port" - else - pf=`findfree 5970` - cmd="$SSVNC_ULTRA_DSM -$pf $host:$port" - pf=`expr $pf - 5900` - hostdisp="$localhost:$pf" - ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'` - echo "Running:" - echo - echo "$ustr &" - echo - $cmd & - dsm_pid=$! - sleep 2 - fi - fi - hostdisp2=`echo "$hostdisp" | sed -e 's/pw=[^ ]*/pw=******/g'` - echo "$VNCVIEWERCMD" "$@" "$hostdisp2" - trap "final" 0 2 15 - echo "" - $VNCVIEWERCMD "$@" "$hostdisp" - if [ $? != 0 ]; then - echo "vncviewer command failed: $?" - if [ "X$secondtry" = "X1" ]; then - sleep 2 - $VNCVIEWERCMD "$@" "$hostdisp" - fi - fi - else - echo "" - echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." - echo "" - trap "final" 0 2 15 - if [ "X$SSVNC_ULTRA_DSM" != "X" ]; then - if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then - echo "NOTE: The ultravnc_dsm_helper only runs once. So after the first LISTEN" - echo " ends you must restart the Listening mode. You may also need to" - echo " Press Ctrl-C to stop the viewer and restart for another connection." - echo "" - fi - #SSVNC_LISTEN_ONCE=1; export SSVNC_LISTEN_ONCE - VNCVIEWER_LISTEN_LOCALHOST=1 - export VNCVIEWER_LISTEN_LOCALHOST - dport=`expr 5500 + $disp` - cmd="$SSVNC_ULTRA_DSM $dport $localhost:$use" - ustr=`echo "$cmd" | sed -e 's/pw=[^ ]*/pw=******/g'` - echo "Running:" - echo - echo "$ustr &" - echo - if [ "X$SSVNC_LISTEN_ONCE" = "X1" ]; then - $cmd & - dsm_pid=$! - else - while [ 1 ]; do $cmd; sleep 1; done & - dsm_pid=$! - fi - sleep 2 - disp=$use - if [ $disp -ge 5500 ]; then - disp=`expr $disp - 5500` - fi - fi - disp2=$disp - if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then - disp2=`echo "$disp2" | sed -e 's/://g'` - if [ $disp2 -le 200 ]; then - disp2=`expr $disp2 + 5500` - fi - fi - echo "$VNCVIEWERCMD" "$@" -listen $disp2 - echo "" - $VNCVIEWERCMD "$@" -listen $disp2 - if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then - rm -f $PPROXY_LOOP_THYSELF - fi - fi - exit $? -fi - -tmp_cfg=/tmp/ss_vncviewer${RANDOM}.$$ -tmp_cfg=`mytmp "$tmp_cfg"` - -stunnel_exec="" -if [ "X$SSVNC_USE_OURS" != "X1" ]; then - : -elif echo $STUNNEL_EXTRA_SVC_OPTS | grep '#stunnel-exec' > /dev/null; then - stunnel_exec="#" -fi - -if [ "X$reverse" = "X" ]; then - - if echo "$proxy" | grep "^repeater://" > /dev/null; then - if [ "X$cert" = "XBUILTIN" ]; then - ttcert=`make_tcert` - cert="cert = $ttcert" - fi - # Note for listen mode, an empty cert will cause stunnel to fail. - # The ssvnc gui will have already taken care of this. - fi - - cat > "$tmp_cfg" <<END -foreground = yes -pid = -client = yes -debug = $stunnel_debug -$ciphers -$STUNNEL_EXTRA_OPTS -$STUNNEL_EXTRA_OPTS_USER -$cert -$crl -$verify - -${stunnel_exec}[vnc_stunnel] -${stunnel_exec}accept = $localhost:$use -$connect -$STUNNEL_EXTRA_SVC_OPTS -$STUNNEL_EXTRA_SVC_OPTS_USER - -END - -else - # REVERSE case: - - stunnel_exec="" # doesn't work for listening. - - p2=`expr 5500 + $N` - connect="connect = $localhost:$p2" - if [ "X$cert" = "XBUILTIN" ]; then - ttcert=`make_tcert` - cert="cert = $ttcert" - fi - # Note for listen mode, an empty cert will cause stunnel to fail. - # The ssvnc gui will have already taken care of this. - - - hloc="" - if [ "X$use_ssh" = "X1" ]; then - hloc="$localhost:" - elif [ "X$STUNNEL_LISTEN" != "X" ]; then - hloc="$STUNNEL_LISTEN:" - fi - if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then - hloc="$localhost:" - pv=`findfree 5570` - proxy="vencrypt:$pv:$port" - port=$pv - if [ "X$anondh_set" = "X1" ]; then - # not needed for ANONDH in this mode - #ciphers="ciphers = ADH:@STRENGTH" - : - fi - fi - cat > "$tmp_cfg" <<END -foreground = yes -pid = -client = no -debug = $stunnel_debug -$ciphers -$STUNNEL_EXTRA_OPTS -$STUNNEL_EXTRA_OPTS_USER -$cert -$crl -$verify - -[vnc_stunnel] -accept = $hloc$port -$connect -$STUNNEL_EXTRA_SVC_OPTS -$STUNNEL_EXTRA_SVC_OPTS_USER - -END - -fi - -echo "" -echo "Using this stunnel configuration:" -echo "" -cat "$tmp_cfg" | uniq -echo "" -if egrep -i '^[ ]*(CApath|CAfile) =' "$tmp_cfg" > /dev/null ; then - : -else - echo "** WARNING: THE STUNNEL CONFIG HAS NO SERVER CERTIFICATE SPECIFIED **" - echo "** WARNING: (the CApath or CAfile stunnel option) THE VNC SERVER WILL **" - echo "** WARNING: NOT BE AUTHENTICATED. A MAN-IN-THE-MIDDLE ATTACK IS POSSIBLE **" - echo "" -fi -sleep 1 - -if [ "X$stunnel_exec" = "X" ]; then - echo "" - echo "Running stunnel:" - echo "$STUNNEL $tmp_cfg" - st=`echo "$STUNNEL" | awk '{print $1}'` - $st -help > /dev/null 2>&1 - $STUNNEL "$tmp_cfg" < /dev/tty > /dev/tty & - stunnel_pid=$! - echo "" - - # pause here to let the user supply a possible passphrase for the - # mycert key: - if [ "X$mycert" != "X" ]; then - nsl=10 - dsl=0 - if [ ! -f $mycert ]; then - dsl=0 - elif grep -i 'Proc-Type.*ENCRYPTED' "$mycert" > /dev/null 2>/dev/null; then - dsl=1 - fi - if [ "X$dsl" = "X1" ]; then - echo "" - echo "(** pausing $nsl secs for possible certificate passphrase dialog **)" - echo "" - sleep $nsl - echo "(** done pausing for passphrase **)" - echo "" - fi - fi - #echo T sleep 1 - sleep 1 - rm -f "$tmp_cfg" -fi - - -echo "" -if [ "X$SSVNC_EXTRA_SLEEP" != "X" ]; then - echo "sleep $SSVNC_EXTRA_SLEEP" - sleep $SSVNC_EXTRA_SLEEP -fi - -if [ "X$reverse" = "X" ]; then - if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then - port1=`expr 5900 + $N` # stunnel port - port2=`findfree 5970` # bridge port (viewer connects to it.) - N=`expr $port2 - 5900` - env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="$port2,$port1" $ptmp & - sleep 1 - fi - echo "Running viewer:" - vnc_hp=$localhost:$N - if [ "X$stunnel_exec" != "X" ]; then - vnc_hp="exec=$STUNNEL $tmp_cfg" - fi - echo "$VNCVIEWERCMD" "$@" "$vnc_hp" - trap "final" 0 2 15 - echo "" - $VNCVIEWERCMD "$@" "$vnc_hp" - if [ $? != 0 ]; then - echo "vncviewer command failed: $?" - if [ "X$secondtry" = "X1" ]; then - sleep 2 - $VNCVIEWERCMD "$@" "$vnc_hp" - fi - fi -else - echo "Running viewer:" - echo "" - echo "NOTE: Press Ctrl-C to terminate viewer LISTEN mode." - echo "" - trap "final" 0 2 15 - N2=$N - N2_trim=`echo "$N2" | sed -e 's/://g'` - if [ $N2_trim -le 200 ]; then - N2_trim=`expr $N2_trim + 5500` - fi - if [ "X$proxy" != "X" ]; then - if echo "$proxy" | grep -i '^vencrypt:' > /dev/null; then - pstunnel=`echo "$proxy" | awk -F: '{print $2}'` - plisten=`echo "$proxy" | awk -F: '{print $3}'` - IF=INADDR_ANY - if [ "X$STUNNEL_LISTEN" != "X" ]; then - IF=$STUNNEL_LISTEN - fi - PPROXY_VENCRYPT_REVERSE=1; export PPROXY_VENCRYPT_REVERSE - PPROXY_LISTEN="$IF:$plisten"; export PPROXY_LISTEN - PPROXY_PROXY="vencrypt://$localhost:$pstunnel"; export PPROXY_PROXY - PPROXY_DEST="$localhost:$pstunnel"; export PPROXY_DEST - STUNNEL_ONCE=1; export STUNNEL_ONCE - STUNNEL_MAX_CLIENTS=1; export STUNNEL_MAX_CLIENTS - if [ "X$NEED_VENCRYPT_VIEWER_BRIDGE" = "X1" -a "X$ptmp" != "X" ] ; then - port1=`expr 5500 + $N2` - port2=`findfree 5580` - N2=`expr $port2 - 5500` - N2_trim=`echo "$N2" | sed -e 's/://g'` - if [ $N2_trim -le 200 ]; then - N2_trim=`expr $N2_trim + 5500` - fi - if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then - PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself1.${RANDOM}.$$"` - export PPROXY_LOOP_THYSELF - PPROXY_LOOP_THYSELF0=$PPROXY_LOOP_THYSELF - fi - env PPROXY_REMOVE=0 PPROXY_SLEEP=0 PPROXY_VENCRYPT_VIEWER_BRIDGE="-$port1,$port2" $ptmp & - sleep 1 - fi - else - PPROXY_REVERSE="$localhost:$port"; export PPROXY_REVERSE - PPROXY_SLEEP=1; export PPROXY_SLEEP; - fi - PPROXY_KILLPID=+1; export PPROXY_KILLPID; - if [ "X$SSVNC_LISTEN_ONCE" != "X1" ]; then - PPROXY_LOOP_THYSELF=`mytmp "/tmp/pproxy_loop_thyself2.${RANDOM}.$$"` - export PPROXY_LOOP_THYSELF - fi - $ptmp & - # Important to have no extra pids generated between here and VNCVIEWERCMD - fi - if [ "X$VNCVIEWER_IS_REALVNC4" = "X1" ]; then - N2=$N2_trim - fi - echo "$VNCVIEWERCMD" "$@" -listen $N2 - echo "" - $VNCVIEWERCMD "$@" -listen $N2 - - if [ "X$PPROXY_LOOP_THYSELF" != "X" ]; then - rm -f $PPROXY_LOOP_THYSELF - fi - if [ "X$PPROXY_LOOP_THYSELF0" != "X" ]; then - rm -f $PPROXY_LOOP_THYSELF0 - fi -fi - -sleep 1 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl deleted file mode 100755 index fefb143..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl +++ /dev/null @@ -1,19041 +0,0 @@ -#!/bin/sh -# the next line restarts using wish \ -exec wish "$0" "$@" - -# -# Copyright (c) 2006-2010 by Karl J. Runge <runge@karlrunge.com> -# -# ssvnc.tcl: gui wrapper to the programs in this -# package. Also sets up service port forwarding. -# -set version 1.0.28 - -set buck_zero $argv0 - -proc center_win {w} { - global is_windows - update - set W [winfo screenwidth $w] - set W [expr $W + 1] - wm geometry $w +$W+0 - update - set x [expr [winfo screenwidth $w]/2 - [winfo width $w]/2] - set y [expr [winfo screenheight $w]/2 - [winfo height $w]/2] - - if {$is_windows} { - set y [expr "$y - 30"] - if {$y <= 0} { - set y 1 - } - } - wm geometry $w +$x+$y - wm deiconify $w - update -} - -proc small_height {} { - set H [winfo screenheight .] - if {$H < 700} { - return 1 - } else { - return 0 - } -} - -proc mac_raise {} { - global uname - if {$uname == "Darwin"} { - catch {exec /bin/sh -c {osascript -e 'tell application "Wish Shell" to activate' >/dev/null 2>&1 &}} - after 150 - update - update idletasks - } -} - -proc toplev {w} { - catch {destroy $w} - toplevel $w - catch {wm withdraw $w} -} - -proc apply_bg {w} { - global is_windows system_button_face - if {$is_windows && $system_button_face != ""} { - catch {$w configure -bg "$system_button_face"} - } -} - -proc line_count {{str ""} {pad 0}} { - set n $pad - foreach l [split $str "\n"] { - incr n - } - return $n -} - -proc scroll_text {fr {w 80} {h 35}} { - global help_font is_windows scroll_text_focus - - if {$h == 35 && [small_height]} { - set h 28 - } - catch {destroy $fr} - - frame $fr -bd 0 - - eval text $fr.t -width $w -height $h $help_font \ - -setgrid 1 -bd 2 -yscrollcommand {"$fr.y set"} -relief ridge - - apply_bg $fr.t - - scrollbar $fr.y -orient v -relief sunken -command "$fr.t yview" - pack $fr.y -side right -fill y - pack $fr.t -side top -fill both -expand 1 - - if {$scroll_text_focus} { - focus $fr.t - } -} - -proc scroll_text_dismiss {fr {w 80} {h 35}} { - global help_font - - if {$h == 35 && [small_height]} { - set h 28 - } - scroll_text $fr $w $h - - set up $fr - regsub {\.[^.]*$} $up "" up - - button $up.d -text "Dismiss" -command "destroy $up" - bind $up <Escape> "destroy $up" - pack $up.d -side bottom -fill x - pack $fr -side top -fill both -expand 1 -} - -proc jiggle_text {w} { - global uname - if {$uname == "Darwin"} { - $w yview scroll 1 pages - update idletasks - $w yview scroll -1 pages - update idletasks - } -} - -proc ts_help {} { - toplev .h - - scroll_text_dismiss .h.f - - center_win .h - wm title .h "Terminal Services VNC Viewer Help" - - set msg { - Terminal Services: - - The Terminal Services VNC Viewer uses SSH to establish an encrypted - and authenticated connection to the remote server. - - Through the SSH channel, it automatically starts x11vnc in terminal - services mode on the remote server to find or create your desktop - session. x11vnc is used for both the session management and the - VNC transport. - - You MUST be able to log in via SSH to the remote terminal server. - Ask your administrator to set this up for you if it isn't already. - x11vnc must also be installed on the remote server machine. - See "Requirements" below. - - This mode is started by the commands 'tsvnc' or 'ssvnc -ts' or - toggled by pressing Ctrl-t. "SSVNC Mode" under Options -> Advanced - will also return to the full SSVNC. - - Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc" - to have the tool always start up in that mode. To constrain the UI, - run with -tso or SSVNC_TS_ALWAYS set to prevent leaving the Terminal - Services mode. - - - Hosts and Displays: - - Enter the remote VNC Terminal Services hostname in the - 'VNC Terminal Server' entry. - - Examples: - - 24.67.132.27 - far-away.east - fred@someplace.no - - Then click on "Connect". - - Once the SSH is running (you may need to type a password or accept - a new ssh key in the terminal window that pops up), the VNC Viewer - will be automatically started directed to the local port of the SSH - tunnel which, in turn, encrypts and redirects the connection to the - remote VNC server. - - x11vnc is run remotely to find or create your terminal services desktop - session. It must be installed and accessible on the remote system. - - Enter "user@hostname.com" in 'VNC Terminal Server' if the remote - username is different from the yours on this machine. On Windows - you *MUST* supply the remote username due to a deficiency in Plink. - This entry is passed to SSH; it could also be an SSH alias you have - created (in ~/.ssh/config). - - If the remote SSH server is run on a non-standard port, e.g. 2222, use - something like one of these: - - far-away.east:2222 - fred@someplace.no:2222 - - (unlike SSVNC mode, the number is the SSH port, not the VNC display) - - If you find yourself in the unfortunate circumstance that your ssh - username has a space in it, use %SPACE (or %TAB) like this: - - fred%SPACEflintstone@xyzzy.net - - - Zeroconf/Bonjour: - - On Unix or Mac OS X, if the 'avahi-browse' or 'dns-sd' command is - available on the system and in your PATH, a 'Find' button is placed by - 'VNC Host:Display'. Clicking on Find will try to find VNC Servers - on your Local Network that advertize via the Zeroconf protocol. - A menu of found hosts is presented for you to select from. - - - Profiles: - - Use "Save" to save a profile (i.e. a host:display and its specific - settings) with a name. The "TS-" prefix will be suggested to help - you distinguish between Terminal Services and regular profiles. - - To load in a saved Options profile, click on the "Load" button, - and choose which one you want. - - To list your profiles from the command line use: - - tsvnc -profiles (or -list) - - To launch profile1 directly from the command-line, or to a server - use things like: - - tsvnc profile1 - tsvnc /path/to/profile1.vnc - tsvnc hostname - tsvnc user@hostname - - Note that the 'Verify All Certs' setting is NOT saved in profiles. - - - Proxies/Gateways: - - Proxy/Gateway is usually a gateway machine to log into via SSH that is - not the machine running the VNC terminal services. However, Web and - SOCKS proxies can also be used (see below). - - For example if a company had a central login server: "ssh.company.com" - (accessible from the internet) and the internal server name was - "ts-server", one could put in - - VNC Terminal Server: ts-server - Proxy/Gateway: ssh.company.com - - It is OK if the hostname "ts-server" only resolves inside the firewall. - - The 2nd host, ts-server in this example, MUST also be running an SSH - server and you must be able to log into it. You may need to supply - a 2nd password to it to login. - - Use username@host (e.g. joe@ts-server or jsmith@ssh.company.com) - if the user name differs between machines. - - NOTE: On Windows you MUST always supply the username@ because putty's - plink requires it. - - - NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other - than 22) you need to use the Proxy/Gateways as well. E.g. something - like this for port 2222: - - VNC Terminal Server: ts-server - Proxy/Gateway: jsmith@ssh.company.com:2222 - - On Unix/MacOSX the username@ is not needed if it is the same as on this - machine. - - - A Web or SOCKS proxy can also be used. Use this if you are inside a - firewall that prohibits direct connections to remote SSH servers. - In Terminal Services SSH mode, the "http://" prefix is required for - web proxies. - - VNC Terminal Server: fred@someplace.no - Proxy/Gateway: http://myproxy.west:8080 - - or for SOCKS: - - VNC Terminal Server: fred@someplace.no - Proxy/Gateway: socks://mysocks.west:1080 - - use socks5://... to force the SOCKS5 version. For a non-standard - port the above would be, e.g., fred@someplace.no:2222 - - As with a username that contains a space, use %SPACE (or %TAB) to - indicate it in the SSH proxies, e.g. john%SPACEsmith@ssh.company.com - - One can also chain proxies and other things. See the section - "SSH Proxies/Gateways" in the Main SSVNC Help for full details. - - - Options: - - Click on Options to get to dialog boxes to: - - - Desktop Type (kde, gnome, failsafe, twm...) - - Desktop Size (Geometry WxH and pixel depth) - - X Server Type (Xvfb, Xdummy, Xvnc) - - Enable Printing (CUPS and/or SMB/Windows) - - Enable Sound (TBD, ESD partially working) - - File Transfer (Ultra or TightVNC filexfer) - - View Only (View only client) - - Change VNC Viewer (Realvnc, ultra, etc...) - - X11 viewer MacOSX (use bundled X11 vncviewer) - - Delete Profile... (Delete a saved profile) - - - Advanced Options: - - - VNC Shared (optional traditional VNC sharing) - - Multiple Sessions (more than 1 session per server) - - X Login Greeter (Connect to Login/Greeter Display) - - Other VNC Server (redirect to 3rd party VNC Server) - - Use unixpw (optional x11vnc login mode) - - Client 8bit Color (VNC Viewer requests low color mode) - - Client-Side Caching (experimental x11vnc speedup) - - X11VNC Options (set any extra x11vnc options) - - Extra Sleep (delay a bit before starting viewer) - - Putty Args (Windows: string for plink/putty cmd) - - Putty Agent (Windows: launch pageant) - - Putty Key-Gen (Windows: launch puttygen) - - SSH Local Protections (a bit of safety on local side) - - SSH KnownHosts file (to avoid SSH 'localhost' collisions) - - SSVNC Mode (Return to full SSVNC mode) - - - Unix ssvncviewer (set options for supplied Unix viewer) - - - Requirements: - - When running this application on Unix/MacOSX the ssh(1) program must - be installed locally. On Windows a plink/putty binary is included. - - On the remote VNC Terminal Services host, x11vnc must be installed - (0.9.3 or higher), and at least one virtual X server: Xvfb, Xdummy, - or Xvnc must be available. Xvfb is the most often used one. All of - these programs must be available in $PATH on the remote server when - logged in via SSH. - - The VNC terminal services administrator can make "x11vnc" be a wrapper - script that sets everything up correctly and then runs the real x11vnc. - - - Real X servers: - - As a *BONUS*, if on the remote host, say a workstation, you have a - regular X session running on the physical hardware that you are - ALREADY logged into you can access to that display as well (x11vnc - will find it). - - So this tool can be used as a simple way to launch x11vnc to find - your real X display on your workstation and connect to it. - - The Printing and Sound redirection won't work for this mode however. - You will need to use the full SSVNC application to attempt that. - - If you (mistakenly) have not logged into an X session on the real - X server on the workstation, a VIRTUAL (Xvfb, etc.) server will be - created for you (that may or may not be what you want). - - The X Login Advanced setting can be used to connect to a X Display - Manger Greeter login panel (no one is logged in yet). This requires - sudo(1) privileges on the remote machine. - - More Info: - - See these links for more information: - - http://www.karlrunge.com/x11vnc/#tunnelling -} - - global version - set msg " SSVNC version: $version\n$msg" - - .h.f.t insert end $msg - jiggle_text .h.f.t -} - -proc help {} { - global ts_only - if {$ts_only} { - ts_help - return - } - toplev .h - - set h 37 - if [small_height] { - set h 26 - } - scroll_text_dismiss .h.f 82 $h - - center_win .h - wm title .h "SSL/SSH VNC Viewer Help" - - global help_main help_prox help_misc help_tips - - set help_main { - Hosts and Displays: - - Enter the VNC host and display in the 'VNC Host:Display' entry box. - - It is of the form "host:number", where "host" is the hostname of the - machine running the VNC Server and "number" is the VNC display number; - it is often "0". Some Examples: - - snoopy:0 - - far-away.east:0 - - sunray-srv1.west:17 - - 24.67.132.27:0 - - Then click on "Connect". When you do the STUNNEL program will be started - locally to provide you with an outgoing SSL tunnel. - - Once the STUNNEL is running, the TightVNC Viewer (Or perhaps Chicken of - the VNC on Mac OS X, or one you set under Options) will be automatically - started and directed to the local port of the SSL tunnel which, in turn, - encrypts and redirects the connection to the remote VNC server. - - The remote VNC server **MUST** support an initial SSL/TLS handshake before - using the VNC protocol (i.e. VNC is tunnelled through the SSL channel - after it is established). "x11vnc -ssl ..." does this, and any VNC server - can be made to do this by using, e.g., STUNNEL or socat on the remote side. - SSVNC also supports VeNCrypt and ANONTLS SSL/TLS VNC servers (see below.) - - * Automatic SSH Tunnels are described below. - - * The 'No Encryption' / 'None' option provides a direct connection without - encryption (disable the button with the -enc option, or Options menu.) - More info in Tip 5. - - Port numbers: - - If you are using a port less than the default VNC port 5900 (usually - the VNC display = port - 5900), use the full port number itself, e.g.: - - 24.67.132.27:443 - - Note, however, if the number n after the colon is < 200, then a - port number 5900 + n is assumed; i.e. n is the VNC display number. - If you must use a TCP port less than 200, specify a negative value, - e.g.: 24.67.132.27:-80 - - For Reverse VNC connections (listening viewer, See Tip 2 and - Options -> Help), the port mapping is similar, except "listening - display :0" corresponds to port 5500, :1 to 5501, etc. - Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel - listen on that interface only. Listening on IPv6 can also be done, use - e.g. :::0 or ::1:0 This listening on IPv6 (:::0) works for UN-encrypted - reverse connections as well (mode 'None'). - - - Zeroconf/Bonjour: - - On Unix or Mac OS X, if the 'avahi-browse' or 'dns-sd' command is - available on the system and in your PATH, a 'Find' button is placed by - 'VNC Host:Display'. Clicking on Find will try to find VNC Servers on - your Local Network that advertize via the Zeroconf protocol. A menu of - found hosts is presented for you to select from. - - - VNC Password: - - On Unix or MacOSX IF there is a VNC password for the server you can - enter it in the "VNC Password:" entry box. - - This is *REQUIRED* on MacOSX when Chicken of the VNC is used, because - that viewer does not put up a user password prompt when it learns - that a password is needed. - - On Unix (including MacOSX using the X11 viewer) if you choose not to - enter the password you will simply be prompted for it in the terminal - window running TightVNC viewer if one is required. - - On Windows TightVNC viewer will prompt you if a password is required. - - NOTE: when you Save a VNC profile, the password is NOT saved (you need - to enter it each time). Nor is the 'Verify All Certs' setting. - - - Profiles: - - Use "Save" to save a profile (i.e. a host:display and its specific - settings) with a name. - - To load in a saved Options profile, click on the "Load" button. - - To list your profiles from the command line use: - - ssvnc -profiles (or -list) - - You can launch ssvnc and have it immediately connect to the server - by invoking it something like this: - - ssvnc profile1 (launches profile named "profile1") - ssvnc /path/to/profile.vnc (loads the profile file, no launching) - ssvnc hostname:0 (connect to hostname VNC disp 0 via SSL) - ssvnc vnc+ssl://hostname:0 (same) - ssvnc vnc+ssh://hostname:0 (connect to hostname VNC disp 0 via SSH) - - see the Tips 5 and 7 for more about the URL-like syntax. - - If you don't want "ssvnc profile1" to immediately launch the connection - to the VNC server set the SSVNC_PROFILE_LOADONLY env. var. to 1. - (or specify the full path to the profile.vnc as shown above.) - - - SSL Certificate Verification: - - *** IMPORTANT ***: If you do not take the steps to VERIFY the VNC Server's - SSL Certificate, you are in principle vulnerable to a Man-In-The-Middle - attack. Without SSL Certificate verification, only passive network - sniffing attacks will be guaranteed to be prevented. There are hacker - tools like dsniff/webmitm and cain that implement SSL Man-In-The-Middle - attacks. They rely on the client user not bothering to check the cert. - - Some people may be confused by the above because they are familiar with - their Web Browser using SSL (i.e. https://... websites) and those sites - are authenticated securely without the user's need to verify anything - manually. The reason why this happens automatically is because 1) their - web browser comes with a bundle of Certificate Authority certificates - and 2) the https sites have paid money to the Certificate Authorities to - have their website certificate signed by them. When using SSL in VNC we - normally do not do something this sophisticated, and so we have to verify - the certificates manually. However, it is possible to use Certificate - Authorities with SSVNC; that method is described below. - - You can use the "Fetch Cert" button to retrieve the Cert and then - after you check it is OK (say, via comparing the MD5 or other info) - you can "Save" it and use it to verify future connections to servers. - (However, see the note at the end of this section about CA certificates.) - - When "Verify All Certs" is checked, this check is always enforced, - and so the first time you connect to a new server you may need to - follow a few dialogs to inspect and save the server certificate. - See the "Certs... -> Help" for information on how to manage certificates. - - "Verify All Certs" is on by default. - - Note, however, "Fetch Cert" and "Verify All Certs" are currently disabled - in the very rare "SSH + SSL" usage mode to avoid SSHing in twice. - You can manually set a ServerCert or CertsDir in this case if you like. - - - Advanced Method: Certificate Authority (CA): - - If you, or your site administrator, goes though the steps of setting up - a Certificate Authority (CA) to sign the VNC server and/or VNC client - Certs, that can be used instead and avoids the need to manually verify - every cert while still authenticating every connection. More info: - http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-ca - - See the cmdline option -cacert file below in 'SSL Certificates' - for setting a default ServerCert/CA Cert. - - You may also Import the CA Cert and save it to the 'Accepted Certs' - directory so the "Verify All Certs" automatic checking will find it. - - Note that if a Server is using a CA signed certificate instead of - its own Self-Signed one, then the default "Verify All Certs/Fetch Cert" - saving mechanism will NOT succeed. You must obtain the CA certificate - and explicitly set it as the ServerCert or Import it to Accepted Certs. - - - SSL/TLS Variants; VeNCrypt and ANONTLS: - - SSVNC can also connect to VNC SSL/TLS variants; namely the VeNCrypt and - "TLS" VNC Security types. Vino uses the latter (we call it "ANONTLS"); - and a growing number use VeNCrypt (QEMU, ggi, virt-manager, VeNCrypt, Xen.) - - Via the VeNCrypt bridge that SSVNC provides, the VeNCrypt/ANONTLS - support ALSO works with ANY 3rd party VNC Viewers you specify via - 'Change VNC Viewer' (e.g. RealVNC, TightVNC, UltraVNC, etc.) that do - not directly support VeNCrypt or ANONTLS. This works on all platforms: - Unix, MacOSX, and Windows. - - - Notes on VeNCrypt/ANONTLS Auto-detection: - - IMPORTANT: VeNCrypt Server Auto-detection *ONLY* occurs in SSL mode - and when an initial fetch-cert action takes place. - - While the initial certificate fetch is taking place SSVNC applies - heuristics to try to automatically detect the VeNCrypt or ANONTLS - protocol use by the VNC server. This way it learns that the server - is using it and then knows to switch to VeNCrypt encrypted SSL/TLS at - the right point. Then SSVNC makes a second (the real) connection to - VNC server and connects the VNC viewer to it. - - In the default "Verify All Certs" mode, a fetch cert action always - takes place, and so VeNCrypt/ANONTLS will be autodected. - - However, if you have specified an explicit ServerCert or disabled - "Verify All Certs" then even though the initial fetch cert action is no - longer needed, it is performed anyway because it allows VeNCrypt/ANONTLS - auto-detection. - - To disabled this initial fetch (e.g. you know the VNC server is normal - SSL and not VeNCrypt/ANONTLS and want to connect more quickly) then - select "Do not Probe for VeNCrypt" in the Advanced Options menu. - - On the other hand, if you know the VNC server ONLY supports VeNCrypt or - ANONTLS, to improve the accuracy and speed with which the connection - takes place, you can specify the one or both of the 'Server uses - VeNCrypt SSL encryption' and 'Server uses Anonymous Diffie-Hellman' - in the 'Advanced' options panel. That way guessing via an initial - probe is not needed or performed. See each options's Advanced Options - Help for more info. - - Note that if you are using VeNCrypt or ANONTLS for REVERSE connections - (Listen) then you *MUST* set the 'Server uses VeNCrypt SSL encryption' - (and the ANON-DH if it applies) option in Advanced. Note also that - REVERSE VeNCrypt and ANONTLS connections currently do not work on - Windows. - - Also, if you are using the "Use SSH+SSL" double tunnel, you MUST set - 'Server uses VeNCrypt SSL encryption' (and the ANON-DH if it applies) - because the initial fetch cert is disabled in SSH+SSL mode. - - - Deciphering SSL Negotiation Success or Failure: - - Since SSVNC is a "glue program", in this case gluing VNCViewer and stunnel - together (with possibly a proxy helper) reporting is clumsy at best. - (In SSH encryption mode, it glues to ssh instead of stunnel.) In most - cases the programs being "glued" are run in a terminal window where you - can see the program's output. On Windows you will need to double click - on the stunnel tray icon to view its log. - - Although the output is quite cryptic, you are encouraged to learn to - recognize some of the errors reported in it. - - Here is stunnel output for a case of successfully verifying the VNC - Server's Certificate: - - 2008.11.20 08:09:39 LOG5[1472]: VERIFY OK: depth=0, /C=AU/L=... - 2008.11.20 08:09:39 LOG6[1472]: SSL connected: new session negotiated - 2008.11.20 08:09:39 LOG6[1472]: Negotiated ciphers: AES256-SHA SSLv3 ... - - Here is a case where the Server's Cert did not match the ServerCert - we set: - - 2008.11.20 08:12:31 LOG4[1662]: VERIFY ERROR: depth=0, error=self ... - 2008.11.20 08:12:31 LOG3[1662]: SSL_connect: 14090086: error:14090086:SSL - routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed - - Here is a case where the Server's Cert has expired: - - 2009.12.27 12:20:25 LOG4[25500]: VERIFY ERROR: depth=0, error=certificate - has expired: /C=AU/L=... - 2009.12.27 12:20:25 LOG3[25500]: SSL_connect: 14090086: error:14090086:SSL - routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed - - - If you disable "Verify All Certs" and do not supply a ServerCert, - then there will be no 'VERIFY ...' in the output because the SSVNC - stunnel accepts the server's cert without question (this is insecure.) - - Also in the output will be messages about whether the SSL VNC server - rejected your connection because it requires you to authenticate - yourself with a certificate (MyCert). Here is the case when you - supplied no MyCert: - - 2008.11.20 08:16:29 LOG3[1746]: SSL_connect: 14094410: error:14094410: - SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure - - or you used a certificate the server did not recognize: - - 2008.11.20 08:18:46 LOG3[1782]: SSL_connect: 14094412: error:14094412: - SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate - - or your certificate has been revoked: - - 2008.11.20 08:20:08 LOG3[1913]: SSL_connect: 14094414: error:14094414: - SSL routines:SSL3_READ_BYTES:sslv3 alert certificate revoked - - - SSH: - - Click on "Use SSH" if you want to use an *SSH* tunnel instead of SSL - (then the VNC Server does not need to speak SSL or use STUNNEL or socat). - - You will need to be able to login to your account on the remote host - via SSH (e.g. via password, ssh keys, or ssh-agent). - - Specify the SSH hostname and VNC display in the VNC Host:Display entry. - Use something like: - - username@far-away.east:0 - - if your remote username is different from the one on the local viewer - machine. - - On Windows you *MUST* supply the "username@" part because Putty/Plink - needs it to work correctly. - - "SSH + SSL" is similar but its use is more rare because it requires 2 - encrypted tunnels to reach the VNC server. See the Help under Options - for more info. - - To connect to a non-standard SSH port, see SSH Proxies/Gateways section. - - See Tip 8) for how to make this application be SSH-only with the -ssh - command line option or "sshvnc". - - If you find yourself in the unfortunate circumstance that your ssh - username has a space in it, use %SPACE (or %TAB) like this: - - fred%SPACEflintstone@xyzzy.net:0 - - Remote SSH Command: - - In SSH or SSH + SSL mode you can also specify a remote command to run - on the remote ssh host in the "Remote SSH Command" entry. The default - is just to sleep a bit (e.g. sleep 15) to make sure the tunnel ports - are established. Alternatively you could have the remote command start - the VNC server, e.g. - - x11vnc -display :0 -rfbport 5900 -localhost -nopw - - When starting the VNC server this way, note that sometimes you will need - to correlate the VNC Display number with the "-rfbport" (or similar) - option of the server. E.g. for VNC display :2 - - VNC Host:Display username@somehost.com:2 - Remote SSH Command: x11vnc -find -rfbport 5902 -nopw - - See the Tip 18) for using x11vnc PORT=NNNN feature (or vncserver(1) - output) to not need to specify the VNC display number or the x11vnc - -rfbport option. - - Windows SSH SERVER: if you are ssh'ing INTO Windows (e.g. CYGWIN SSHD - server) there may be no "sleep" command so put in something like - "ping localhost" or "ping -n 10 -w 1000 localhost" to set a short - delay to let the tunnel ports get established. - - - SSL Certificates: - - If you want to use a SSL Certificate (PEM) file to authenticate YOURSELF to - the VNC server ("MyCert") and/or to verify the identity of the VNC Server - ("ServerCert" or "CertsDir") select the certificate file by clicking the - "Certs ..." button before connecting. - - Certificate verification is needed to prevent Man-In-The-Middle attacks; - if it is not done then only passive network sniffing attacks are prevented. - There are hacker tools like dsniff/webmitm and cain that implement SSL - Man-In-The-Middle attacks. They rely on the client user not bothering to - check the cert. - - - See the x11vnc documentation: - - http://www.karlrunge.com/x11vnc/ssl.html - - for how to create and use PEM SSL certificate files. An easy way is: - - x11vnc -ssl SAVE ... - - where it will print out its automatically generated certificate to the - screen and that can be copied safely to the viewer side. - - You can also use the "Create Certificate" feature of this program under - "Certs ...". Just click on it and follow the instructions in the dialog. - Then copy the cert file to the VNC Server and specify the other one in - the "Certs ..." dialog. - - Alternatively you can use the "Import Certificate" action to paste in a - certificate or read one in from a file. Or you can use the "Fetch Cert" - button on the main panel. If "Verify All Certs" is checked, you will - be forced to check Certs of any new servers the first time you connect. - - Note that "Verify All Certs" is on by default so that users who do not - understand the SSL Man-In-The-Middle problem will not be left completely - vulnerable to it (everyone still must make the effort to verify new - certificates by an external method to be completely safe). - - To have "Verify All Certs" toggled off at startup, use "ssvnc -nv" or - set SSVNC_NO_VERIFY_ALL=1 before starting. If you do not even want to - see the button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1. - - Use the "-mycert file" option (same as "-cert file") to set a default - MyCert. This is the same as "mycert=file" (also "cert=file") in the - ~/.ssvncrc file. See Certs -> Help for more info. - - Use the "-cacert file" option (same as "-ca file") to set a default - ServerCert (or CA). This is the same as "cacert=file" (also "ca=file") - in the ~/.ssvncrc file. See Certs -> Help for more info. - - Use the "-crl file" option to set a default CRL File. This is the same - as "crl=file" in the ~/.ssvncrc file. See Certs -> Help for more info. - - Prefix any of these files with "FORCE:" to make them immutable. - - - - More Options: - - To set other Options, e.g. for View-Only usage or to limit the number - of colors used, click on the "Options ..." button and read the Help there. - - More Info: - - Press the 'Proxies', 'Misc', and 'Tips' buttons below. - - See also these links for more information: - - http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext - http://stunnel.mirt.net - http://www.tightvnc.com -} - - set help_misc { - Windows STUNNEL problems: - - Note that on Windows when the Viewer connection is finished by default - SSVNC will try to kill the STUNNEL process for you. - - If Options -> Kill Stunnel Automatically is not set you will be - prompted if you want SSVNC to try to kill the STUNNEL process for you. - Usually you will say Yes, however if there are problems connecting - you may want to look at the STUNNEL Log first. - - Before it is killed, double clicking the STUNNEL tray icon (dark green) - will show you its Log file (useful for debugging connection problems). - - Even though SSVNC will kill the STUNNEL process for you, you will - still need to move the mouse over the icon to make the little picture - go away!!! This is unfortunate but there does not seem to be a way - to avoid it. - - In some cases you may need to terminate STUNNEL manually from the System - Tray (right click on dark green icon) and selecting "Exit". - - Use -nokillstunnel or killstunnel=0 in ~/.ssvncrc to have SSVNC - start up with stunnel killing disabled. - - Untrusted Local Users: - - *IMPORTANT WARNING*: If you run SSVNC on a workstation or computer - that other users can log into and you DO NOT TRUST these users - (it is a shame but sometimes one has to work in an environment like - this), then please note the following warning. - - By 'do not trust' we mean they might try to gain access to remote - machines you connect to via SSVNC. Note that an untrusted local - user can often obtain root access in a short amount of time; if a - user has achieved that, then all bets are off for ANYTHING that you - do on the workstation. It is best to get rid of Untrusted Local - Users as soon as possible. - - Both the SSL and SSH tunnels set up by SSVNC listen on certain ports - on the 'localhost' address and redirect TCP connections to the remote - machine; usually the VNC server running there (but it could also be - another service, e.g. CUPS printing). These are the stunnel(8) SSL - redirection and the ssh(1) '-L' port redirection. Because 'localhost' - is used only users or programs on the same workstation that is - running SSVNC can connect to these ports, however this includes any - local users (not just the user running SSVNC.) - - If the untrusted local user tries to connect to these ports, he may - succeed by varying degrees to gain access to the remote machine. - We now list some safeguards one can put in place to try to make this - more difficult to achieve. - - It probably pays to have the VNC server require a password, even - though there has already been SSL or SSH authentication (via - certificates or passwords). In general if the VNC Server requires - SSL authentication of the viewer that helps, unless the untrusted - local user has gained access to your SSVNC certificate keys. - - If the VNC server is configured to only allow one viewer connection - at a time, then the window of opportunity that the untrusted local - user can use is greatly reduced: he might only have a second or two - between the tunnel being set up and the SSVNC vncviewer connecting - to it (i.e. if the VNC server only allows a single connection, the - untrusted local user cannot connect once your session is established). - Similarly, when you disconnect the tunnel is torn down quickly and - there is little or no window of opportunity to connect (e.g. x11vnc - in its default mode exits after the first client disconnects). - - Also for SSL tunnelling with stunnel(8) on Unix using one of the SSVNC - prebuilt 'bundles', a patched stunnel is provided that denies all - connections after the first one, and exits when the first one closes. - This is not true if the system installed stunnel(8) is used and is - not true when using SSVNC on Windows. - - The following are experimental features that are added to SSVNC to - improve the situation for the SSL/stunnel and SSH cases. Set them - via Options -> Advanced -> "STUNNEL Local Port Protections" or - "SSH Local Port Protections". - - STUNNEL: - - 1) For SSL tunnelling with stunnel(8) on Unix there is a setting - 'Use stunnel EXEC mode' that will try to exec(2) stunnel - instead of using a listening socket. This will require using - the specially modified vncviewer unix viewer provided by SSVNC. - The mode works well and is currently set as the default. - Disable it if it causes problems or conflicts. - - 2) For SSL tunnelling with stunnel(8) on Unix there is a setting - 'Use stunnel IDENT check' (experimental) to limit socket - connections to be from you (this assumes the untrusted local - user has not become root on your workstation and has modified - your local IDENT check service; if he has you have much bigger - problems to worry about...) - - Neither of the above methods are available on Windows. - - SSH: - - 1) There is also a simple LD_PRELOAD trick for SSH to limit the - number of accepted port redirection connections. This makes the - window of time the untrusted local user can connect to the tunnel - much smaller. Enable it via Options -> Advanced -> "SSH Local - Port Protections". You will need to have the lim_accept.so file - in your SSVNC package. The mode works well and is currently set - as the default. Disable it if it causes problems or conflicts. - - The above method is not available on Windows. - - The main message is to 'Watch your Back' when you connect via the - SSVNC tunnels and there are users you don't trust on your workstation. - The same applies to ANY use of SSH '-L' port redirections or outgoing - stunnel SSL redirection services. -} - - set help_prox { - Here are a number of long sections on all sorts of proxies, Web, SOCKS, - SSH tunnels/gateways, UltraVNC, Single Click, etc., etc. - - - Proxies/Gateways: - - If an intermediate proxy is needed to make the SSL connection - (e.g. a web gateway out of a firewall) enter it in the "Proxy/Gateway" - entry box: - - VNC Host-Display: host:number - Proxy/Gateway: proxy-host:port - e.g.: - VNC Host-Display: far-away.east:0 - Proxy/Gateway: myproxy.west:8080 - - - If the "double proxy" case is required (e.g. coming out of a web - proxied firewall environment and then INTO a 2nd proxy to ultimately - reach the VNC server), separate them via a comma, e.g.: - - VNC Host-Display: far-away:0 - Proxy/Gateway: myproxy.west:8080,myhome.net:443 - - So it goes: viewer -> myproxy.west -> myhome.net -> far-away (VNC) - - The proxies are assumed to be Web proxies. To use SOCKS proxies: - - VNC Host-Display: far-away.east:0 - Proxy/Gateway: socks://mysocks.west:1080 - - Use socks5:// to force the SOCKS5 proxy protocol (e.g. for ssh -D). - - You can prefix web proxies with http:// in SSL mode but it doesn't matter - since that is the default for a proxy. (NOTE that in SSH or SSH+SSL - mode you MUST supply the http:// prefix for web proxies because in those - modes an SSH tunnel is the default proxy type: see the next section.) - - Note that Web proxies are often configured to ONLY allow outgoing - connections to ports 443 (HTTPS) and 563 (SNEWS), so you might - have run the VNC server (or router port redirector) on those ports. - SOCKS proxies usually have no restrictions on port number. - - You can chain up to 3 proxies (any combination of web (http://) and - socks://) by separating them with commas (i.e. first,second,third). - - Proxies also work for un-encrypted connections ("None" or vnc://, Tip 5) - - See the ss_vncviewer description and x11vnc FAQ for info on proxies: - - http://www.karlrunge.com/x11vnc/faq.html#ss_vncviewer - http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-java-viewer-proxy - - - SSH Proxies/Gateways: - - Proxy/Gateway also applies to SSH mode, it is a usually a gateway SSH - machine to log into via ssh that is not the workstation running the - VNC server. However, Web and SOCKS proxies can also be used (see below). - - For example if a company had a central login server: "ssh.company.com" - (accessible from the internet) and the internal workstation with VNC was - named "joes-pc", then to create an SSH tunnel one could put this in: - - VNC Host:Display: joes-pc:0 - Proxy/Gateway: ssh.company.com - - It is OK if the hostname "joes-pc" only resolves inside the firewall. - - The 2nd leg, from ssh.company.com -> joes-pc is done by a ssh -L - redir and is not encrypted (but the viewer -> ssh.company.com 1st leg is - an encrypted tunnel). - - To SSH encrypt BOTH legs, try the "double SSH gateway" method using - the "comma" notation: - - VNC Host:Display: localhost:0 - Proxy/Gateway: ssh.company.com,joes-pc - - this requires an SSH server also running on joes-pc. So an initial SSH - login is done to ssh.company.com, then a 2nd SSH is performed (through - port a redirection of the first) to login straight to joes-pc where - the VNC server is running. - - Use username@host (e.g. joe@joes-pc jsmith@ssh.company.com) if the - user names differ between the various machines. - - NOTE: On Windows you MUST always supply the username@ because putty's - plink requires it. - - - NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other - than 22) you need to use the Proxy/Gateways as well. E.g. something - like this for port 2222: - - VNC Host:Display: localhost:0 - Proxy/Gateway: joe@far-away.east:2222 - - On Unix/MacOSX the username@ is not needed if it is the same as on - the client. This will also work going to a different internal machine, - e.g. "joes-pc:0" instead of "localhost:0", as in the first example. - - - A Web or SOCKS proxy can also be used with SSH. Use this if you are - inside a firewall that prohibits direct connections to remote SSH servers. - - VNC Host:Display: joe@far-away.east:0 - Proxy/Gateway: http://myproxy.west:8080 - - or for SOCKS: - - VNC Host:Display: joe@far-away.east:0 - Proxy/Gateway: socks://mysocks.west:1080 - - Use socks5://... to force the SOCKS5 version. Note that the http:// - prefix is REQUIRED for web proxies in SSH or SSH+SSL modes (but it is - the default proxy type in SSL mode.) - - You can chain up to 3 proxies (any combination of http://, socks:// - and ssh) by separating them with commas (i.e. first,second,third). - - Note: the Web and/or SOCKS proxies must come before any SSH gateways. - - For a non-standard SSH port and a Web or SOCKS proxy try: - - VNC Host:Display: localhost:0 - Proxy/Gateway: http://myproxy.west:8080,joe@far-away.east:2222 - - Even the "double SSH gateway" method (2 SSH encrypted legs) described - above works with an initial Web or SOCKS proxy, e.g.: - - VNC Host:Display: localhost:0 - Proxy/Gateway: socks://mysocks.west:1080,ssh.company.com,joes-pc - - - - Some Notes on SSH localhost tunnelling with SSH options - NoHostAuthenticationForLocalhost=yes and UserKnownHostsFile=file: - - Warning: Note that for proxy use with ssh(1), tunnels going through - 'localhost' are used. This means ssh(1) thinks the remote hostname is - 'localhost', which may cause collisions and confusion when storing - and checking SSH keys. - - By default on Unix when a 'localhost' ssh host is involved the - ssh option -o NoHostAuthenticationForLocalhost=yes is applied (see - ssh_config(1) for details.) This avoids the warnings and ssh refusing - to connect, but it reduces security. A man in the middle attack may - be possible. SSVNC prints out a warning in the terminal every time - the NoHostAuthenticationForLocalhost option is used. - - On Unix to disable the use of NoHostAuthenticationForLocalhost set the env. - variable SSVNC_SSH_LOCALHOST_AUTH=1. This may induce extra ssh(1) dialogs. - - On Unix a MUCH SAFER and more convenient way to proceed is to set the - known hosts option in Options -> Advanced -> 'Private SSH KnownHosts file' - Then, only for the host in the current profile, a private known_hosts - file will be used and so there will be no 'localhost' collisions. - This method is secure (assuming you verify the SSH key fingerprint) - and avoids the man in the middle attack. - - On Windows, Putty/Plink is used and does not have the UserKnownHosts - or NoHostAuthenticationForLocalhost features. Keys are stored in - the registry as localhost:port pairs and so it is possible to use the - 'Port Slot' option to keep the keys separate to avoid the dialogs and - also maintain good security. - - Note that for the "double SSH gateway" method the risk from using - NoHostAuthenticationForLocalhost is significantly less because the first - ssh connection does not use the option (it connects directly to the remote - host) and the second one is only exposed for the leg inside the first - gateway (but is still vulnerable there when NoHostAuthenticationForLocalhost - is used.) - - As with a username that contains a space, use %SPACE (or %TAB) to - indicate it in the SSH proxies, e.g. john%SPACEsmith@ssh.company.com - - UltraVNC Proxies/Gateways: - - UltraVNC has a "repeater" tool (http://www.uvnc.com/addons/repeater.html - and http://koti.mbnet.fi/jtko/) that acts as a VNC proxy. SSVNC can - work with both mode I and mode II schemes of this repeater. - - For Unix and MacOS X there is another re-implementation of the - UltraVNC repeater: - - http://www.karlrunge.com/x11vnc/ultravnc_repeater.pl - - So one does not need to run the repeater on a Windows machine. - - Note that even though the UltraVNC repeater tool is NOT SSL enabled, - it can nevertheless act as a proxy for SSVNC SSL connections. - This is because, just as with a Web proxy, the proxy negotiations - occur before the SSL traffic starts. (There is a separate UltraVNC - tool, repeater_SSL.exe, that is SSL enabled and is discussed below.) - - Note: it seems only SSL SSVNC connections make sense with the - UltraVNC repeater. SSH connections (previous section) do not seem to - and so are not enabled to (let us know if you find a way to use it.) - - Unencrypted (aka Direct) SSVNC VNC connections (Vnc:// prefix in - 'VNC Host:Display'; see Tip 5) also work with the UltraVNC repeater. - - MODE I REPEATER: - - For the mode I UltraVNC repeater the Viewer initiates the connection - and passes a string that is the VNC server's IP address (or hostname) - and port or display to the repeater (the repeater then makes the - connection to the server host and then exchanges data back and forth.) - To do this in SSVNC: - - VNC Host:Display: :0 - Proxy/Gateway: repeater://myuvncrep.west:5900+joes-pc:1 - - Where "myuvncrep.west" is running the UltraVNC repeater and - "joes-pc:1" is the VNC server the repeater will connect us to. - - Note here that the VNC Host:Display can be anything because it is - not used; we choose :0. You cannot leave VNC Host:Display empty. - - The Proxy/Gateway format is repeater://proxy:port+vncserver:display. - The string after the "+" sign is passed to the repeater server for - it to interpret (and so does not have to be the UltraVNC repeater; - you could create your own if you wanted to.) For this example, - instead of joes-pc:1 it could be joes-pc:5901 or 192.168.1.4:1, - 192.168.1.4:5901, etc. - - If you do not supply a proxy port, then the default 5900 is assumed, - e.g. use repeater://myuvncrep.west+joes-pc:1 for port 5900 on - myuvncrep.west then connecting to port 5901 on joes-pc. - - X11VNC: For mode I operation the VNC server x11vnc simply runs as - a normal SSL/VNC server: - - x11vnc -ssl SAVE - - because the repeater will connect to it as a VNC client would. - For mode II operation additional options are needed (see below.) - - - MODE II REPEATER: - - For the mode II repeater both the VNC viewer and VNC server initiate - TCP connections to the repeater proxy. In this case they pass a string - that identifies their mutual connection via "ID:NNNN", for example: - - VNC Host:Display: :0 - Proxy/Gateway: repeater://myuvncrep.west:5900+ID:2345 - - again, the default proxy port is 5900 if not supplied. And we need - to supply a placeholder display ":0". - - The fact that BOTH the VNC viewer and VNC server initiate outgoing - TCP connections to the repeater makes some things tricky, especially - for the SSL aspect. In SSL one side takes the 'client' role and - the other side must take the 'server' role. These roles must be - coordinated correctly or otherwise the SSL handshake will fail. - - We now describe two scenarios: 1) SSVNC in Listening mode with STUNNEL - in 'SSL server' role; and 2) SSVNC in Forward mode with STUNNEL in - 'SSL client' role. For both cases we show how the corresponding - VNC server x11vnc would be run. - - SSVNC Listening mode / STUNNEL 'SSL server' role: - - By default, when using SSL over a reverse connection the x11vnc VNC - server will take the 'SSL client' role. This way it can connect to a - standard STUNNEL (SSL server) redirecting connections to a VNC viewer - in Listen mode. This is how SSVNC with SSL is normally intended to - be used for reverse connections (i.e. without the UltraVNC Repeater.) - - To do it this way with the mode II UltraVNC Repeater; you set - Options -> Reverse VNC Connection, i.e. a "Listening Connection". - You should disable 'Verify All Certs' unless you have already - saved the VNC Server's certificate to Accepted Certs. Or you can - set ServerCert to the saved certificate. Then click 'Listen'. - In this case an outgoing connection is made to the UltraVNC - repeater, but everything else is as for a Reverse connection. - - Note that in Listening SSL mode you must supply a MyCert or use the - "listen.pem" one you are prompted by SSVNC to create. - - X11VNC command: - - x11vnc -ssl -connect_or_exit repeater://myuvncrep.west+ID:2345 - - - SSVNC Forward mode / STUNNEL 'SSL client' role: - - x11vnc 0.9.10 and later can act in the 'SSL server' role for Reverse - connections (i.e. as it does for forward connections.) Set these - x11vnc options: '-env X11VNC_DISABLE_SSL_CLIENT_MODE=1 -sslonly' - - The -sslonly option is to prevent x11vnc from thinking the delay in - connection implies VeNCrypt instead of VNC over SSL. With x11vnc - in X11VNC_DISABLE_SSL_CLIENT_MODE mode, you can then have SSVNC make - a regular forward connection to the UltraVNC repeater. - - Note that SSVNC may attempt to do a 'Fetch Cert' action in forward - connection mode to either retrieve the certificate or probe for - VeNCrypt and/or ANONDH. After that 'Fetch Cert' is done the - connection to the UltraVNC repeater will be dropped. This is a - problem for the subsequent real VNC connection. You can disable - 'Verify All Certs' AND also set 'Do not Probe for VeNCrypt' - to avoid the 'Fetch Cert' action. Or, perhaps better, add to - x11vnc command line '-connect_or_exit repeater://... -loop300,2' - (in addition to the options in the previous paragraphs.) That way - x11vnc will reconnect once to the Repeater after the 'Fetch Cert' - action. Then things should act pretty much as a normal forward - SSL connection. - - X11VNC 0.9.10 command (split into two lines): - - x11vnc -ssl -connect_or_exit repeater://myuvncrep.west+ID:2345 \ - -env X11VNC_DISABLE_SSL_CLIENT_MODE=1 -loop300,2 -sslonly - - We recommend using "SSVNC Forward mode / STUNNEL 'SSL client' role" - if you are connecting to x11vnc 0.9.10 or later. Since this does - not use Listen mode it should be less error prone and less confusing - and more compatible with other features. Be sure to use all of - the x11vnc options in the above command line. To enable VeNCrypt, - replace '-sslonly' with '-vencrypt force'. If you do not indicate - them explicitly to SSVNC, SSVNC may have to probe multiple times for - VeNCrypt and/or ANONDH. So you may need '-loop300,4' on the x11vnc - cmdline so it will reconnect to the UltraVNC repeater 3 times. - - - Note that for UNENCRYPTED (i.e. direct) SSVNC connections (see vnc:// - in Tip 5) using the UltraVNC Repeater mode II there is no need to - use a reverse "Listening connection" and so you might as well use - a forward connection. - - For Listening connections, on Windows after the VNC connection you - MUST manually terminate the listening VNC Viewer (and connect again - if desired.) Do this by going to the System Tray and terminating - the Listening VNC Viewer. Subsequent connection attempts using the - repeater will fail unless you do this and restart the Listen. - - On Unix and MacOS X after the VNC connection the UltraVNC repeater - proxy script will automatically restart and reconnect to the repeater - for another connection. So you do not need to manually restart it. - To stop the listening, kill the listening VNC Viewer with Ctrl-C. - - In the previous sections it was mentioned one can chain up to 3 - proxies together by separating them with commas: proxy1,proxy2,proxy3. - Except where explicitly noted below this should work for "repeater://..." - as the final proxy. E.g. you could use a web proxy to get out of a - firewall, and then connect to a remote repeater. - - The UltraVNC SSL enabled repeater_SSL.exe is discussed below. - - - UltraVNC Single Click: - - UltraVNC has Single Click (SC) Windows VNC servers that allow naive - users to get them running very easily (a EXE download and a few - mouse clicks). See http://sc.uvnc.com/ for details on how to create - these binaries. Also there is a how-to here: - http://www.simply-postcode-lookup.com/SingleClickUltraVNC/SingleClickVNC.htm - - The SC EXE is a VNC *server* that starts up a Reverse VNC connection - to a Listening Viewer (e.g. the viewer address/port/ID is hardwired - into the SC EXE). So SC is not really a proxy, but it can be used - with UltraVNC repeater proxies and so we describe it here. - - One important point for SC III binary creation: do NOT include - "-id N" in the helpdesk.txt config file. This is because the with - SSVNC the Ultra VNC repeater IS NOT USED (see below for how to - use it). Use something like for helpdesk.txt: - - [TITLE] - My UltraVNC SC III - - [HOST] - Internet Support XYZ - -sslproxy -connect xx.xx.xx.xx:5500 -noregistry - - (replace xx.xx.xx.xx with IP address or hostname of the SSVNC machine.) - - The Unix SSVNC vncviewer supports the both the unencrypted "SC I" - mode and the SSL encrypted "SC III" mode. For both cases SSVNC - must be run in Listening mode (Options -> Reverse VNC Connection) - - For SC I, enable Reverse VNC Connection and put Vnc://0 (see Tip 5 - below) in the VNC Host:Display to disable encryption (use a different - number if you are not using the default listening port 5500). - Then click on the "Listen" button and finally have the user run your - Single Click I EXE. - - BTW, we used this for a SC I helpdesk.txt: - - [TITLE] - My UltraVNC SC I - - [HOST] - Internet Support XYZ - -connect xx.xx.xx.xx:5500 -noregistry - - For SC III (SSL), enable Reverse VNC Connection and then UNSET "Verify - All Certs" (this is required). Let the VNC Host:Display be ":0" - (use a different number if you are not using the default listening - port 5500). Then click on the "Listen" button and finally have the - user run your Single Click III EXE. - - Note that in Listening SSL mode you MUST supply a MyCert or use the - "listen.pem" one you are prompted by SSVNC to create. - - - UltraVNC repeater_SSL.exe proxy: - - For repeater_SSL.exe SSL usage, with Single Click III or otherwise - (available at http://www.uvnc.com/pchelpware/SCIII/index.html) - it helps to realize that the ENTIRE connection is SSL encrypted, - even the proxy host:port/ID:NNNN negotiation, and so a different - approach needs to be taken from that described above in 'UltraVNC - Proxies/Gateways'. In this case do something like this: - - VNC Host:Display: :0 - Proxy/Gateway: sslrepeater://myuvncrep.west:443+ID:2345 - - The sslrepeater:// part indicates the entire ID:XYZ negotiation must - occur inside the SSL tunnel. Listening mode is not required in this - case: a forward VNC connection works fine (and is recommended). - As before, the ":0" is simply a placeholder and is not used. - Note that the UltraVNC repeater_SSL.exe listens on port 443 (HTTPS), - (it is not clear that it can be modified to use another port.) - - Non-ID connections sslrepeater://myuvncrep.west:443+host:disp also - work, but the 2nd leg repeater <-> host:disp must be unencrypted. - The first leg SSVNC <-> repeater is, however, SSL encrypted. - - sslrepeater:// only works on Unix or MacOSX using the provided - SSVNC vncviewer. The modified viewer is needed; stock VNC viewers - will not work. Also, proxy chaining (bouncing off of more than one - proxy) currently does not work for repeater_SSL.exe. - - - VeNCrypt is treated as a proxy: - - SSVNC supports the VeNCrypt VNC security type. You will find out more - about this security type in the other parts of the Help documentation. - In short, it does a bit of plain-text VNC protocol negotiation before - switching to SSL/TLS encryption and authentication. - - SSVNC implements its VeNCrypt support as final proxy in a chain - of proxies. You don't need to know this or specify anything, but - it is good to know since it uses up one of the 3 proxies you are - allowed to chain together. If you watch the command output you will - see the vencrypt:// proxy item. - - You can specify that a VNC server uses VeNCrypt (Options -> Advanced) - or you can let SSVNC try to autodetect VeNCrypt. - - - IPv6 can be treated as a proxy for UN-ENCRYPTED connections: - - Read Tip 20 about SSVNC's IPv6 (128 bit IP addresses) support. - In short, because stunnel and ssh support IPv6 hostnames and - addresses, SSVNC does too without you needing to do anything. - - However, in some rare usage modes you will need to specify the IPv6 - server destination in the Proxy/Gateway entry box. The only case - this appears to be needed is when making an un-encrypted connection - to an IPv6 VNC server. In this case neither stunnel nor ssh are - used and you need to specify something like this: - - VNC Host:Display: localhost:0 - Proxy/Gateway: ipv6://2001:4860:b009::68:5900 - - and then select 'None' as the encryption type. Note that the above - 'localhost:0' setting can be anything; it is basically ignored. - - Note that on Unix, MacOSX, and Windows un-encrypted ipv6 connections - are AUTODETECTED and so you likely NEVER need to supply ipv6:// - Only try it if you encounter problems. Also note that the ipv6:// - proxy type does not work on Windows, so only the autodetection is - available there. - - Note that if there is some other proxy, e.g. SOCKS or HTTP and that - proxy server is an IPv6 host (or will connect you to one) then any - sort of connection through that proxy will work OK: un-encrypted as - well as SSL or SSH connections, etc. - - Unencrypted connection is the only special case where you may need - to specify an ipv6:// proxy. If you find another use let us know. - - See Tip 20 for more info. -} - - set help_tips { - Tips and Tricks: - - Table of Contents: - - 1) Connect to Non-Standard SSH port. - 2) Reverse VNC connections (Listening) - 3) Global options in ~/.ssvncrc - 4) Fonts - 5) vnc://host for un-encrypted connection - 6) Home directory for memory stick usage, etc. - 7) vncs:// vncssl:// vnc+ssl:// vnc+ssh:// URL-like prefixes - 8) sshvnc / -ssh SSH only GUI - 9) tsvnc / -ts Terminal services only GUI (SSH+x11vnc) - 10) 2nd GUI window on Unix/MacOSX - 11) Ctrl-L or Button3 to Load profile - 12) SHELL command or Ctrl-S for SSH terminal w/o VNC - 13) KNOCK command for port-knock sequence - 14) Unix/MacOSX general SSL redirector (not just VNC) - 15) Environment variables - 16) Bigger "Open File" dialog window - 17) Unix/MacOSX extra debugging output - 18) Dynamic VNC Server Port determination with SSH - 19) No -t ssh cmdline option for older sshd - 20) IPv6 support. - - 1) To connect in SSH-Mode to a server running SSH on a non-standard - port (22 is the standard port) you need to use the Proxy/Gateway - setting. The following is from the Proxies Help panel: - - NON-STANDARD SSH PORT: To use a non-standard ssh port (i.e. a port other - than 22) you need to use the Proxy/Gateways as well. E.g. something - like this for port 2222: - - VNC Host:Display: localhost:0 - Proxy/Gateway: joe@far-away.east:2222 - - The username@ is not needed if it is the same as on the client. This - will also work going to a different internal machine, e.g. "joes-pc:0" - instead of "localhost:0", as in the first example. - - 2) Reverse VNC connections (Listening) are possible as well. - In this case the VNC Server initiates the connection to your - waiting (i.e. listening) SSVNC viewer. - - Go to Options and select "Reverse VNC connection". In the 'VNC - Host:Display' entry box put in the number (e.g. "0" or ":0", or - ":1", etc) that corresponds to the Listening display (0 -> port - 5500, 1 -> port 5501, etc.) you want to use. Then clicking on - 'Listen' puts your SSVNC viewer in a "listening" state on that - port number, waiting for a connection from the VNC Server. - - On Windows or using a 3rd party VNC Viewer multiple, simultaneous - reverse connections are always enabled. On Unix/MacOSX with the - provided ssvncviewer they are disabled by default. To enable them: - Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Connections - - Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel - only listen on that interface. IPv6 works too, e.g. :::0 or ::1:0 - This also works for UN-encrypted reverse connections as well ('None'). - - See the Options Help for more info. - - 3) You can put global options in your ~/.ssvncrc file (ssvnc_rc on - Windows). Currently they are: - - Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have - the application start up in the given mode. - - desktop_type=wmaker (e.g.) to switch the default Desktop Type. - - desktop_size=1280x1024 (e.g.) to switch the default Desktop Size. - - desktop_depth=24 (e.g.) to switch the default Desktop Color Depth - - xserver_type=Xdummy (e.g.) to switch the default X Server Type. - - (The above 4 settings apply only to the Terminal Services Mode.) - - noenc=1 (same as the -noenc option for a 'No Encryption' option) - noenc=0 (do not show the 'No Encryption' option) - - killstunnel=1 (same as -killstunnel), on Windows automatically kills - the STUNNEL process when the viewer exits. Disable via killstunnel=0 - and -nokillstunnel. - - ipv6=0 act as though IPv6 was not detected. - ipv6=1 act as though IPv6 was detected. - - cotvnc=1 have the default vncviewer on Mac OS X be the Chicken of - the VNC. By default the included ssvnc X11 vncviewer is used - (requires Mac OS X X11 server to be running.) - - mycert=file (same as -mycert file option). Set your default MyCert - to "file". If file does not exist ~/.vnc/certs/file is used. - - cacert=file (same as -cacert file option). Set your default ServerCert - to "file". If file does not exist ~/.vnc/certs/file is used. If - file is "CA" then ~/.vnc/certs/CA/cacert.pem is used. - - crl=file (same as -crl file option). Set your default CRL File - to "file". If file does not exist ~/.vnc/certs/file is used. - - Prefix any of these cert/key files with "FORCE:" to make them - immutable, e.g. "cacert=FORCE:CA". - - You can set any environment variable in ~/.ssvncrc by using a line - like env=VAR=value, for example: env=SSVNC_FINISH_SLEEP=2 - - To change the fonts (see Tip 4 below for examples): - - font_default=tk-font-name (sets the font for menus and buttons) - font_fixed=tk-font-name (sets the font for help text) - - 4) Fonts: To change the tk fonts, set these environment variables - before starting up ssvnc: SSVNC_FONT_DEFAULT and SSVNC_FONT_FIXED. - For example: - - % env SSVNC_FONT_DEFAULT='helvetica -20 bold' ssvnc - % env SSVNC_FONT_FIXED='courier -14' ssvnc - - or set both of them at once. You can also set 'font_default' and - 'font_fixed' in your ~/.ssvncrc. E.g.: - - font_default=helvetica -16 bold - font_fixed=courier -12 - - 5) If you want to make a Direct VNC connection, WITH *NO* SSL OR - SSH ENCRYPTION or authentication, use the "vnc://" prefix in the - VNC Host:Display entry box, e.g. "vnc://far-away.east:0" This - also works for reverse connections, e.g. vnc://0 - - Use Vnc:// (i.e. capital 'V') to avoid being prompted if you are - sure you want no encryption. For example, "Vnc://far-away.east:0" - Shift+Ctrl-E in the entry box is a short-cut to add or remove - the prefix "Vnc://" from the host:disp string. - - You can also run ssvnc with the '-noenc' cmdline option (now - the default) to have a check option 'None' that lets you turn off - Encryption (and profiles will store this setting). Pressing Ctrl-E - on the main panel is a short-cut to toggle between the -noenc 'No - Encryption' mode and normal mode. The option "Show 'No Encryption' - Option" under Options also toggles it. - - The '-enc' option disables the button (and so makes it less obvious - to naive users how to disable encryption.) - - Note as of SSVNC 1.0.25 the '-noenc' mode is now the default. I.e. - the 'No Encryption' option ('None') is shown by default. When - you select 'None' you do not need to supply the "vnc://" prefix. - To disable the button supply the '-enc' cmdline option. - - Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=1 in your environment is - the same as -noenc. You can also put noenc=1 in your ~/.ssvncrc file. - - Setting SSVNC_DISABLE_ENCRYPTION_BUTTON=0 in your environment is - the same as -enc. You can also put noenc=0 in your ~/.ssvncrc file. - - Please be cautious/thoughtful when you make a VNC connection with - encryption disabled. You may send sensitive information (e.g. a - password) over the network that can be sniffed. - - It is also possible (although difficult) for someone to hijack an - existing unencrypted VNC session. - - Often SSVNC is used to connect to x11vnc where the Unix username and - password is sent over the channel. It would be a very bad idea to - let that data be sent over an unencrypted connection! In general, - it is not wise to have a plaintext VNC connection. - - Note that even the VNC Password challenge-response method (the password - is not sent in plaintext) leaves your VNC password susceptible to a - dictionary attack unless encryption is used to hide it. - - So (well, before we made the button visible by default!) we forced - you to learn about and supply the "vnc://" or "Vnc://" prefix to - the host:port or use -noenc or the "Show 'No Encryption' Option" - to disable encryption. This is a small hurdle, but maybe someone - will think twice. It is a shame that VNC has been around for - over 10 years and still does not have built-in strong encryption. - - Note the Vnc:// or vnc:// prefix will be stored in any profile that - you save so you do not have to enter it every time. - - Set the env var SSVNC_NO_ENC_WARN=1 to skip the warning prompts the - same as the capitalized Vnc:// does. - - 6) Mobile USB memory stick / flash drive usage: You can unpack - ssvnc to a flash drive for impromptu usage (e.g. from a friends - computer). - - If you create a directory "Home" in the toplevel ssvnc directory, - then that will be the default location for your VNC profiles - and certs. So they follow the drive this way. If you run like - this: "ssvnc ." or "ssvnc.exe ." the "Home" directory will be - created for you. - - WARNING: if you use ssvnc from an "Internet Cafe", i.e. an - untrusted computer, an unscrupulous person may be capturing - keystrokes, etc.! - - You can also set the SSVNC_HOME env. var. to point to any - directory you want. It can be set after starting ssvnc by putting - HOME=/path/to/dir in the Host:Display box and clicking "Connect". - - For a Windows BAT file to get the "Home" directory correct - something like this might be needed: - - cd \ssvnc\Windows - start \ssvnc\Windows\ssvnc.exe - - 7) In the VNC Host:Display entry you can also use these "URL-like" - prefixes: - - vncs://host:0, vncssl://host:0, vnc+ssl://host:0 for SSL - - and - - vncssh://host:0, vnc+ssh://host:0 for SSH - - There is no need to toggle the SSL/SSH setting. These also work - from the command line, e.g.: ssvnc vnc+ssh://mymachine:10 - - 8) If you want this application to be SSH only, then supply the - command line option "-ssh" or set the env. var SSVNC_SSH_ONLY=1. - - Then no GUI elements specific to SSL will appear (the - documentation wills still refer to the SSL mode, however). - To convert a running app to ssh-only select "Mode: SSH-Only" - in Options. - - The wrapper scripts "sshvnc" and "sshvnc.bat" will start it up - automatically this way. - - Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=sshvnc" - to have the tool always start up in that mode. - - 9) For an even simpler "Terminal Services" mode use "tsvnc" or - "tsvnc.bat" (or "-ts" option). This mode automatically launches - x11vnc on the remote side to find or create your Desktop session - (usually the Xvfb X server). So x11vnc must be available on the - remote server machines under "Terminal Services" mode. - - From a full ssvnc you can press Ctrl-h to go into ssh-only mode - and Ctrl-t to toggle between "tsvnc" and "ssvnc" modes. The - Options Mode menu also let you switch. - - Or in your ~/.ssvncrc (or ~/ssvnc_rc on Windows) put "mode=tsvnc" - to have the tool always start up in that mode. - - 10) On Unix to get a 2nd GUI (e.g. for a 2nd connection) press Ctrl-N - on the GUI. If only the xterm window is visible you can press - Ctrl-N or try Ctrl-LeftButton -> New SSVNC_GUI. On Windows you - will have to manually Start a new one: Start -> Run ..., etc. - - 11) Pressing the "Load" button or pressing Ctrl-L or Clicking the Right - mouse button on the main GUI will invoke the Load dialog. - - Pressing Ctrl-O on the main GUI will bring up the Options Panel. - Pressing Ctrl-A on the main GUI will bring up the Advanced Options. - - 12) If you use "SHELL" for the "Remote SSH Command" (or in the display - line: "user@hostname cmd=SHELL") then you get an SSH shell only: - no VNC viewer will be launched. On Windows "PUTTY" will try - to use putty.exe (better terminal emulation than plink.exe). - - A ShortCut for this is Ctrl-S with user@hostname in the entry box. - - 13) If you use "KNOCK" for the "Remote SSH Command" (or in the display - line "user@hostname cmd=KNOCK") then only the port-knocking is done. - - A ShortCut for this is Ctrl-P with hostname the entry box. - - If it is KNOCKF, i.e. an extra "F", then the port-knocking - "FINISH" sequence is sent, if any. A ShortCut for this - Shift-Ctrl-P as long as hostname is present. - - 14) On Unix to have SSVNC act as a general STUNNEL redirector (i.e. no - VNC), put the desired host:port in VNC Host:Display (use a - negative port value if it is to be less than 200), then go to - Options -> Advanced -> Change VNC Viewer. Change the "viewer" - command to be "xmessage OK" or "xmessage <port>" (or sleep) where - port is the desired local listening port. Then click Connect. - If you didn't set the local port look for it in the terminal output. - - On Windows set 'viewer' to "NOTEPAD" or similar; you can't - control the port though. It is usually 5930, 5931, ... Watch - the messages or look at the stunnel log. - - 15) Tricks with environment variables: - - You can change the X DISPLAY variable by typing DISPLAY=... into - VNC Host:Display and hitting Return or clicking Connect. Same - for HOME=. On Mac, you can set DYLD_LIBRARY_PATH=... too. - It should propagate down the viewer. - - Setting SLEEP=n increases the amount of time waited before - starting the viewer. The env. var. SSVNC_EXTRA_SLEEP also does - this (and also Sleep: Option setting) Setting FINISH=n sets the - amount of time slept before the Terminal window exits on Unix - and MacOS X. (same as SSVNC_FINISH_SLEEP env. var.) - - Full list of parameters HOME/SSVNC_HOME, DISPLAY/SSVNC_DISPLAY - DYLD_LIBRARY_PATH/SSVNC_DYLD_LIBRARY_PATH, SLEEP/SSVNC_EXTRA_SLEEP - FINISH/SSVNC_FINISH_SLEEP, DEBUG_NETSTAT, REPEATER_FORCE, - SSH_ONLY, TS_ONLY, NO_DELETE, BAT_SLEEP, IPV6/SSVNC_IPV6=0 or 1. - See below for more info. (the ones joined by "/" are equivalent - names, and the latter can be set as an env. var. as well.) - - After you set the parameter, clear out the 'VNC Host:Display' - entry and replace it with the actual host and display number. - - To replace the xterm terminal where most of the external commands - are run set SSVNC_XTERM_REPLACEMENT to a command that will run - a command in a terminal. I.e.: "$SSVNC_XTERM_REPLACEMENT cmd" - will run cmd. If present, %GEOMETRY is expanded to a desired - +X+Y geometry. If present, %TITLE is expanded to a desired title. - Examples: SSVNC_XTERM_REPLACEMENT='gnome-terminal -e' - SSVNC_XTERM_REPLACEMENT='gnome-terminal -t "%TITLE" -e' - SSVNC_XTERM_REPLACEMENT='konsole -e' - - More info: EXTRA_SLEEP: seconds of extra sleep in scripts; - FINISH_SLEEP: final extra sleep at end; DEBUG_NETSTAT put up a - window showing what netstat reports; NO_DELETE: do not delete tmp - bat files on Windows (for debugging); BAT_SLEEP: sleep this many - seconds at the end of each Windows bat file (for debugging.) - - You can also set any environment variable by entering in something - like ENV=VAR=VAL e.g. ENV=SSH_AUTH_SOCK=/tmp/ssh-BF2297/agent.2297 - Use an empty VAL to unset the variable. - - There are also a HUGE number of env. vars. that apply to the Unix - and MacOS X wrapper script 'ss_vncviewer' and/or the ssvncviewer - binary. See Options -> Advanced -> Unix ssvncviewer -> Help for - all of them. - - 16) On Unix you can make the "Open File" and "Save File" dialogs - bigger by setting the env. var. SSVNC_BIGGER_DIALOG=1 or - supplying the -bigger option. If you set it to a Width x Height, - e.g. SSVNC_BIGGER_DIALOG=500x200, that size will be used. - - 17) On Unix / MacOSX to enable debug output you can set these env. - vars to 1: SSVNC_STUNNEL_DEBUG, SSVNC_VENCRYPT_DEBUG, and - SS_DEBUG (very verbose) - - 18) Dynamic VNC Server Port determination and redirection: If you - are running SSVNC on Unix and are using SSH to start the remote - VNC server and the VNC server prints out the line "PORT=NNNN" - to indicate which dynamic port it is using (x11vnc does this), - then if you prefix the SSH command with "PORT=" SSVNC will watch - for the PORT=NNNN line and uses ssh's built in SOCKS proxy - (ssh -D ...) to connect to the dynamic VNC server port through - the SSH tunnel. For example: - - VNC Host:Display user@somehost.com - Remote SSH Command: PORT= x11vnc -find -nopw - - or "PORT= x11vnc -display :0 -localhost", etc. Or use "P= ..." - - There is also code to detect the display of the regular Unix - vncserver(1). It extracts the display (and hence port) from - the lines "New 'X' desktop is hostname:4" and also - "VNC server is already running as :4". So you can use - something like: - - PORT= vncserver; sleep 15 - or: PORT= vncserver :4; sleep 15 - - the latter is preferred because when you reconnect with it will - find the already running one. The former one will keep creating - new X sessions if called repeatedly. - - On Windows if PORT= is supplied SOCKS proxying is not used, but - rather a high, random value of the VNC port is chosen (e.g. 8453) - and assumed to be free, and is passed to x11vnc's -rfbport option. - This only works with x11vnc (not vncserver). - - 19) On Unix if you are going to an older SSH server (e.g. Solaris 10), - you will probably need to set the env. var. SS_VNCVIEWER_NO_T=1 - to disable the ssh "-t" option being used (that can prevent the - command from being run). - - 20) SSVNC is basically a wrapper for the stunnel and ssh programs, - and because those two programs have good IPv6 support SSVNC will - for most usage modes support it as well. IPv6 is 128 bit internet - addresses (as opposed to IPv4 with its 32 bit xxx.yyy.zzz.nnn IPs. - - So for basic SSL and SSH connections if you type in an IPv6 IP - address, e.g. '2001:4860:b009::68', or a hostname with only an - IPv6 lookup, e.g. ipv6.l.google.com, the connection will work - because stunnel and ssh handle these properly. - - Note that you often need to supply a display number or port after - the address so put it, e.g. ':0' at the end: 2001:4860:b009::68:0 - You can also use the standard notation [2001:4860:b009::68]:0 - that is more clear. You MUST specify the display if you use - the IPv6 address notation (but :0 is still the default for a - non-numeric hostname string.) - - IPv4 addresses encoded in IPv6 notation also work, e.g. - ::ffff:192.168.1.100 should work for the most part. - - SSVNC on Unix and MacOSX also has its own Proxy helper tool - (pproxy) This script has been modified to handle IPv6 hostnames - and addresses as long as the IO::Socket::INET6 Perl module - is available. On Windows the relay6.exe tool is used. - - So for the most part IPv6 should work without you having to do - anything special. However, for rare usage, the proxy helper tool - can also treat and IPv6 address as a special sort of 'proxy'. - So in the entry Proxy/Gateway you can include ipv6://host:port - and the IPv6 host will simply be connected to and the data - transferred. In this usage mode, set the VNC Host:Display - to anything, e.g. 'localhost:0'; it is ignored if the ipv6:// - endpoint is specified as a proxy. Need for ipv6:// usage proxy - should be rare. - - Note that for link local (not global) IPv6 addresses you may - need to include the network interface at the end of the address, - e.g. fe80::a00:20ff:fefd:53d4%eth0 - - Note that one can use a 3rd party VNC Viewer with SSVNC (see - Options -> Advanced -> Change VNC Viewer.) IPv6 will work for - them as well even if they do not support IPv6. - - IPv6 support on Unix, MacOSX, and Windows is essentially complete - for all types of connections (including proxied, unencrypted and - reverse connections.) Let us know if you find a scenario that - does not work (see the known exception for putty/plink below.) - - You can set ipv6=0 in your ssvncrc, then no special relaying for - IPv6 will be done (do this if there are problems or slowness in - trying to relay ipv6 and you know you will not connect to any - such hosts.) Set ipv6=1 to force the special processing even if - IPv6 was not autodetected. To change this dynamically, you also - enter IPV6=... in the VNC Host:Display entry box and press Enter. - Also on Unix or MacOSX you can set the env. var. SSVNC_IPV6=0 - to disable the wrapper script from checking if hosts have ipv6 - addresses (this is the same as setting ipv6=0 in ssvncrc or by - the setting ipv6 in the Entry box.) - - On Windows plink.exe (SSH client) currently doesn't work for - IPv6 address strings (e.g. 2001:4860:b009::68) but it does work - for hostname strings that resolve to IPv6 addresses. - - Note that one can make a home-brew SOCKS5 ipv4-to-ipv6 gateway - proxy using ssh like this: - - ssh -D '*:1080' localhost "printf 'Press Enter to Exit: '; read x" - - then specify a proxy like socks5://hostname:1080 where hostname - is the machine running the above ssh command. Add '-v' to the - ssh cmdline for verbose output. See also the x11vnc inet6to4 tool - (a direct ipv4/6 relay, not socks.) -} - - global version - set help_main " SSVNC version: $version\n$help_main" - set help_misc " SSVNC version: $version\n$help_misc" - set help_prox " SSVNC version: $version\n$help_prox" - set help_tips " SSVNC version: $version\n$help_tips" - - frame .h.w - button .h.w.b1 -text "Main" -command {help_text main} - button .h.w.b2 -text "Proxies" -command {help_text prox} - button .h.w.b3 -text "Misc" -command {help_text misc} - button .h.w.b4 -text "Tips" -command {help_text tips} - - pack .h.w.b1 .h.w.b2 .h.w.b3 .h.w.b4 -side left -fill x -expand 1 - - pack .h.w -side bottom -after .h.d -fill x - - .h.f.t insert end $help_main - jiggle_text .h.f.t -} - -proc help_text {which} { - global help_main help_misc help_prox help_tips - set txt "" - if {$which == "main"} { - set txt $help_main - } - if {$which == "misc"} { - set txt $help_misc - } - if {$which == "prox"} { - set txt $help_prox - } - if {$which == "tips"} { - set txt $help_tips - } - catch {.h.f.t delete 0.0 end; .h.f.t insert end $txt; jiggle_text .h.f.t} -} - -proc ssvnc_escape_help {} { - toplev .ekh - - scroll_text_dismiss .ekh.f - - center_win .ekh - wm title .ekh "SSVNC Escape Keys Help" - - set msg { - SSVNC Escape Keys: - - The Unix SSVNC VNC Viewer, ssvncviewer(1), has an 'Escape Keys' - mechanism that enables using keystrokes that are bound as 'Hot Keys' - to specific actions. - - So, when you have all of the modifier keys ('escape keys') pressed down, - then subsequent keystrokes are interpreted as local special actions - instead of being sent to the remote VNC server. - - This enables quick parameter changing and also panning of the viewport. - E.g. the keystroke 'r' is mapped to refresh the screen. - - Enter 'default' in the entry box to enable this feature and to use the - default modifier list (Alt_L,Super_L on unix and Control_L,Meta_L on - macosx) or set it to a list of modifier keys, e.g. Alt_L,Control_L. - Note that _L means left side of keyboard and _R means right side. - - Alt_L is the 'Alt' key on the left side of the keyboard, and Super_L - is usually the 'WindowsFlaggie(TM)' on the left side of the keyboard, - so when both of those are pressed, the escape keys mapping take effect. - - - Here is info from the ssvncviewer(1) manual page: - - -escape str This sets the 'Escape Keys' modifier sequence and enables - escape keys mode. When the modifier keys escape sequence - is held down, the next keystroke is interpreted locally - to perform a special action instead of being sent to the - remote VNC server. - - Use '-escape default' for the default modifier sequence. - (Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L) - - Here are the 'Escape Keys: Help+Set' instructions from the Popup Menu: - - Escape Keys: Enter a comma separated list of modifier keys to be the - 'escape sequence'. When these keys are held down, the next keystroke is - interpreted locally to invoke a special action instead of being sent to - the remote VNC server. In other words, a set of 'Hot Keys'. - - To enable or disable this, click on 'Escape Keys: Toggle' in the Popup. - - Here is the list of hot-key mappings to special actions: - - r: refresh desktop b: toggle bell c: toggle full-color - f: file transfer x: x11cursor z: toggle Tight/ZRLE - l: full screen g: graball e: escape keys dialog - s: scale dialog +: scale up (=) -: scale down (_) - t: text chat a: alphablend cursor - V: toggle viewonly Q: quit viewer 1 2 3 4 5 6: UltraVNC scale 1/n - - Arrow keys: pan the viewport about 10% for each keypress. - PageUp / PageDown: pan the viewport by a screenful vertically. - Home / End: pan the viewport by a screenful horizontally. - KeyPad Arrow keys: pan the viewport by 1 pixel for each keypress. - Dragging the Mouse with Button1 pressed also pans the viewport. - Clicking Mouse Button3 brings up the Popup Menu. - - The above mappings are *always* active in ViewOnly mode, unless you set the - Escape Keys value to 'never'. - - If the Escape Keys value below is set to 'default' then a default list of - of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it - is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag - on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side - of the keyboard. - - On Unix the default is Alt and Windows keys on Left side of keyboard. - On MacOSX the default is Control and Command keys on Left side of keyboard. - - Example: Press and hold the Alt and Windows keys on the LEFT side of the - keyboard and then press 'c' to toggle the full-color state. Or press 't' - to toggle the ultravnc Text Chat window, etc. - - To use something besides the default, supply a comma separated list (or a - single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L - Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch. -} - - .ekh.f.t insert end $msg - jiggle_text .ekh.f.t -} - -# Or Alternatively one can supply both hosts separated by -# spaces (with the proxy second) in the VNC Host:Display box: -# -# VNC Host-Display: far-away.east:0 theproxy.net:8080 -# -# This looks a little strange, but it actually how SSVNC stores the -# host info internally. - -# You can also specify the remote SSH command by putting a string like -# -# cmd=x11vnc -nopw -display :0 -rfbport 5900 -localhost -# -# (use any command you wish to run) at the END of the VNC Host:Display -# entry. In general, you can cram it all in the VNC Host:Display if -# you like: host:disp proxy:port cmd=... (this is the way it is -# stored internally). - -proc help_certs {} { - toplev .ch - - set h 33 - if [small_height] { - set h 28 - } - scroll_text_dismiss .ch.f 87 $h - - center_win .ch - wm resizable .ch 1 0 - - wm title .ch "SSL Certificates Help" - - set msg { - Description: - - *** IMPORTANT ***: Only with SSL Certificate verification (either manually - or via a Certificate Authority certificate) can Man-In-The-Middle attacks be - prevented. Otherwise, only passive network sniffing attacks are prevented. - There are hacker tools like dsniff/webmitm and cain that implement SSL - Man-In-The-Middle attacks. They rely on the client user not bothering to - check the cert. - - Some people may be confused by the above because they are familiar with - their Web Browser using SSL (i.e. https://... websites) and those sites - are authenticated securely without the user's need to verify anything - manually. The reason why this happens automatically is because 1) their - web browser comes with a bundle of Certificate Authority certificates - and 2) the https sites have paid money to the Certificate Authorities to - have their website certificate signed by them. When using SSL in VNC we - normally do not do something this sophisticated, and so we have to verify - the certificates manually. However, it is possible to use Certificate - Authorities with SSVNC; that method is described below. - - The SSL Certificate files described below may have been created externally - (e.g. by x11vnc or openssl): you can import them via "Import Certificate". - OR you can click on "Create Certificate ..." to use THIS program to generate - a Certificate + Private Key pair for you (in this case you will need to - distribute one of the generated files to the VNC Server). - - Then you associate the Saved cert with the VNC server, see the panel entry - box description below. Then click Connect. You will usually want to Save - this association in a VNC Server profile for the next time you connect. - - Expiration: - - SSL Certificates will Expire after a certain period (usually 1-2 years; - if you create a cert with this tool you can set it to any length you want). - So if for a particular Cert you find you can no longer connect, check the - STUNNEL log output to see if the cert has expired. Then create and distribute - a new one. - - Fetch Cert: - - You can also retrieve and view the VNC Server's Cert via the "Fetch Cert" - button on the main panel. After you check that it is the correct Cert (e.g. by - comparing MD5 hash or other info), you can save it. The file it was saved - as will be set as the "ServerCert" to verify against for the next connection. - To make this verification check permanent, you will need to save the profile - via 'Save'. - - NOTE: See the CA section below for how "Fetch Cert/Verify All Certs" WILL NOT - WORK when a Certificate Authority (CA) is used (i.e. you need to save the CA's - cert instead.) It will work if the certificate is Self-Signed. - - Verify All Certs: - - If "Verify All Certs" is checked on the main panel, you are always forced - to check unrecognized server certs, and so the first time you connect to - a new server you may need to follow a few dialogs to inspect and save the - server certificate. - - Under "Verify All Certs", new certificates are saved in the 'Accepted Certs' - directory. When the checkbox is set all host profiles with "CertsDir" set to - "ACCEPTED_CERTS" (and an empty "ServerCert" setting) will be checked against - the pool of accepted certificates in the 'Accepted Certs' directory. - - Note that we have "Verify All Certs" on by default so that users who do not - understand the SSL Man-In-The-Middle problem will not be left completely - vulnerable to it. Everyone still must make the effort to verify new - certificates by an external method to be completely safe. - - To have "Verify All Certs" toggled off at startup, use "ssvnc -nv" or set - SSVNC_NO_VERIFY_ALL=1 before starting. If you do not even want to see the - button, use "ssvnc -nvb" or SSVNC_NO_VERIFY_ALL_BUTTON=1. - - Note: "Fetch Cert" and "Verify All Certs" are currently not implemented in - "SSH + SSL" mode. In this case to have server authentication "ServerCert" - must be set explicitly to a file (or "CertsDir" to a directory). - - Also note that "Fetch Cert" only works in a limited fashion in "Listen" - mode (it is the VNC Server that initiates the connection), and so you - may need to be set via "ServerCert" as well. - - NOTE: See the CA section below for how "Fetch Cert/Verify All Certs" - WILL NOT WORK when a Certificate Authority (CA) is used (i.e. you need - to save the CA's cert instead.) The "Fetch Cert" saving method will - work if the certificate is Self-Signed. - - CA: - - One can make SSL VNC server authentication more "automatic" as it is in - Web Browsers going to HTTPS sites, by using a Certificate Authority (CA) - cert (e.g. a professional one like Verisign or Thawte, or one your company - or organization creates) for the "ServerCert". This is described in detail - here: http://www.karlrunge.com/x11vnc/ssl.html - - CA's are not often used, but if the number of VNC Servers scales up it can - be very convenient because the viewers (i.e. SSVNC) only need the CA cert, - not all of the Server certs. - - IMPORTANT NOTE: if a VNC Server is using a CA signed certificate instead - of its own Self-Signed one, then "Fetch Cert", etc. saving mechanism - WILL NOT WORK. You must obtain the CA certificate and explicitly set - it as the ServerCert or import it to 'Accepted Certs'. - - - Now what goes into the panel's entry boxes is described. - - - Your Certificate + Key (MyCert): - - You can specify YOUR own SSL certificate (PEM) file in "MyCert" in which - case it is used to authenticate YOU (the viewer) to the remote VNC Server. - If this fails the remote VNC Server will drop the connection. - - So the Server could use this method to authenticate Viewers instead of the - more common practice of using a VNC password or x11vnc's -unixpw mode. - - - Server Certificates (ServerCert/CertsDir): - - Server certs can be specified in one of two ways: - - - A single certificate (PEM) file for a single server - or a single Certificate Authority (CA) - - - A directory of certificate (PEM) files stored in - the special OpenSSL hash fashion. - - The former is set via "ServerCert" in this gui. - The latter is set via "CertsDir" in this gui. - - The former corresponds to the "CAfile" STUNNEL parameter. - The latter corresponds to the "CApath" STUNNEL parameter. - - See stunnel(8) or stunnel.mirt.net for more information. - - If the remote VNC Server fails to authenticate itself with respect to the - specified certificate(s), then the VNC Viewer (your side) will drop the - connection. - - Select which file or directory by clicking on the appropriate "Browse..." - button. Once selected, if you click Info or the Right Mouse button on - "Browse..." then information about the certificate will be displayed. - - If, as is the default, "CertsDir" is set to the token "ACCEPTED_CERTS" - (and "ServerCert" is unset) then the certificates accumulated in the special - 'Accepted Certs' directory will be used. "ACCEPTED_CERTS" is the default for - every server ("Verify All Certs"). Note that if you ever need to clean this - directory, each cert is saved in two files, for example: - - hostname-0=bf-d0-d6-9c-68-5a-fe-24-c6-60-ba-b4-14-e6-66-14.crt - and - 9eb7c8be.0 - - This is because of the way OpenSSL must use hash-based filenames in Cert dirs. - The file will have a "full filename:" line indicating the fingerprint and - hostname associated with it. Be sure to remove both files. The Delete Certs - dialog should automatically find the matching one for you and prompt you to - remove it as well. - - Certificate Revocation List (CRL File): - - For large scale deployments, usually involving a CA Cert, it is worthwhile - to be able to revoke individual certs (so that a new CA cert does not need to - be created and new keys distributed). Set CRL File to the path to the - file containing the revoked certificates (or a directory containing - OpenSSL style hash-based filenames.) See the x11vnc -sslCRL documentation - for how to create CRL's. In short, the commands 'openssl ca -revoke ...' - and 'openssl ca -gencrl ...' are the ones to look for; See the ca(1) manpage. - - Create Certificate: - - A simple dialog to create a Self-Signed Certificate. See the x11vnc - -sslGenCA, -sslGenCert options for creating a CA Cert and signing with it. - - Import Certificate: - - You can paste in a Certificate or read one in from a file to add to your - list of Server Certificates. If (also) saved in the 'Accepted Certs' - directory, it will be automatically used to verify any Server when in - 'Verify All Certs' Mode. - - Deleting Certificates: - - To delete a Certificate+private_key pair click on "Delete Certificate" - and select one in the menu. You will be prompted to remove it, - and also any corresponding .pem or .crt file. For "ACCEPTED_CERTS" - it will find the matching "HASH" file and prompt you to remove that too. - - - Default Certs and Keys: - - Use the "-mycert file" option (same as "-cert file") to set a default - MyCert. The user will then have to manually clear the field to not - use a certificate. This is the same as "mycert=file" (also "cert=file") - in the ~/.ssvncrc file. If "file" does not exist, then ~/.vnc/certs is - prepended to it. - - Use the "-cacert file" option (same as "-ca file") to set a default - ServerCert. The user will then have to manually clear the field to not - set a server cert. This is the same as "cacert=file" (also "ca=file") - in the ~/.ssvncrc file. If "file" does not exist, then ~/.vnc/certs is - prepended to it. Use "-cacert CA" to set it to ~/.vnc/certs/CA/cacert.pem - - Use the "-crl file" option to set a default CRL File. The user will - then have to manually clear the field to not use a CRL. This is the - same as "crl=file" in the ~/.ssvncrc file. If "file" does not exist, - then ~/.vnc/certs is prepended to it. - - A sys-admin might set up an SSVNC deployment for user's workstations or - laptops using one or more of -cacert (authenticate VNC server to the - user) or -mycert (authenticate user to VNC server) or -crl (supply a - list of revoked certificates). Prefix either one with "FORCE:" to make - the setting unchangable. - - - Notes: - - If "Use SSH" has been selected then SSL certs are disabled. - - See the x11vnc and STUNNEL documentation for how to create and use PEM - certificate files: - - http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-ext - http://www.karlrunge.com/x11vnc/ssl.html - http://stunnel.mirt.net - - A common way to create and use a VNC Server certificate is: - - x11vnc -ssl SAVE ... - - and then copy the Server certificate to the local (viewer-side) machine. - x11vnc prints out to the screen the Server certificate it generates - (stored in ~/.vnc/certs/server.crt). You can set "ServerCert" to it - directly or use the "Import Certificate" action to save it to a file. - Or use the "Fetch Cert" method to retrieve it (be sure to verify the - MD5 fingerprint, etc). - - x11vnc also has command line utilities to create server, client, and CA - (Certificate Authority) certificates and sign with it. See the above URLs. -} - - .ch.f.t insert end $msg - jiggle_text .ch.f.t -} - -proc help_ts_opts {} { - toplev .oh - - scroll_text_dismiss .oh.f - - center_win .oh - - wm title .oh "Terminal Services VNC Options Help" - -set msg { - Options: Click on a checkbox to enable a feature and bring up its Dialog. - Deselecting a checkbox will disable the feature (but settings from the - Dialog are remembered). Click on it again to re-enable. - - - Desktop Type: - - The default type of remote Desktop type is the "kde" (The K Desktop - Environment) You can choose a different type: gnome, failsafe, - twm, etc. - - This setting will ONLY be used if the desktop needs to be created. - If an existing session of yours is found it will be used instead - (log out of that session if you want to create a new Desktop type - or see the Multiple Sessions option under Advanced). - - Desktop Size: - - The default size of remote Desktop type is the "1280x1024" with a - Color depth of 16 bits per pixel (BPP). Choose one of the standard - WxH values or enter a custom one (TBD). - - This setting will ONLY be used if the desktop needs to be created. - If an existing session of yours is found it will be used instead - (log out of that session if you want to create a new Desktop size - or see the Multiple Sessions option under Advanced). - - Some X servers, Xdummy or a real X server, will allow dynamic screen - size changing after the session has started via a GUI configuration - tool (or xrandr(1) from the command line). - - X Server Type: - - The default type of remote X session is the "Xvfb" (X virtual frame - buffer) X server. It is available on most systems. To choose a - different type, select "Xdummy", "Xvnc", "Xvnc.redirect". - - Xdummy is part of the x11vnc project and is a virtual X server with - some nice features, but it Linux only and requires root permission - to run. One user put 'ALL ALL = NOPASSWD: /usr/local/bin/Xdummy*' - in his sudo(1) configuration (via visudo). - - For Xvnc that server is started up, and x11vnc polls it in its - normal way. Use Xvnc.redirect if you want x11vnc to find and/or - create the Xvnc session, but after that merely transfer packets back - and forth between VNC viewer and Xvnc (I.e. x11vnc does no polling - or VNC protocol). - - - Enable Printing: - - This sets up a SSH port redirection for you from your remote session - to your local print server. The CUPS mechanism is used. The local - print server can also be SMB/Windows. - - Enable Sound: - - Not completely implemented yet. A partially working ESD method - is provided. It may change over to http://nas.sourceforge.net in - the future. As with printing, it uses a SSH port redirection to a - server running locally. - - File Transfer: - - x11vnc supports both the UltraVNC and TightVNC file transfer - extensions. On Windows both viewers support their file transfer - protocol. On Unix only the SSVNC VNC Viewer has filexfer support; - it supports the UltraVNC flavor via a Java helper program. - - Choose the one you want based on VNC viewer you will use. - The defaults for the SSVNC viewer package are TightVNC on Windows - and UltraVNC on Unix. - - View Only: - - Start the VNC Viewer in View-Only mode (it may be switched to full - access later in the session). - - Change VNC Viewer: - - If you do not like the VNC Viewer bundled in the package, you can - indicate another one here. - - X11 viewer MacOSX: - - On MacOSX try to use the bundled X11 vncviewer instead of the - Chicken of the VNC viewer; the Xquartz X server must be installed - (it is by default on 10.5.x) and the DISPLAY variable must be set - (see Tip 15 of SSVNC Help to do this manually.) - - - Advanced Options: - - VNC Shared: - - Normal use of this program, 'tsvnc', *ALREADY* allows simultaneous - shared access of the remote desktop: You simply log in as many - times from as many different locations with 'tsvnc' as you like. - - Select this option for the traditional VNC server shared mode of - operation using a single x11vnc server. SSH access is still required. - - Multiple Sessions: - - To enable one user to have more than one Terminal Services Desktop - X session on a single machine, this option lets you create Tags for - multiple ones (e.g. KDE_BIG, TWM_800x600) - - X Login Greeter: - - If you have root (sudo(1)) permission on the remote machine, - you can have x11vnc try to connect to X displays that have nobody - logged in yet. This is most likely the login greeter running on - the Physical console. sudo(1) is used to run x11vnc with FD_XDM=1. - - An initial ssh running 'sudo id' is performed to try to 'prime' - sudo so the 2nd one that starts x11vnc does not need a password. - - Note that if someone is already logged into the console of the XDM - display you will see their X session. - - Other VNC Server: - - The x11vnc program running on the remote machine can be instructed to - immediately redirect to some other (3rd party, e.g. Xvnc or vnc.so) - VNC server. - - Use unixpw: - - This enables the x11vnc unixpw mode. A Login: and Password: dialog - will be presented in the VNC Viewer for the user to provide any Unix - username and password whose session he wants to connect to. - - This mode is useful if a shared terminal services user (e.g. 'tsuser') - is used for the SSH login part (say via the SSH authorized_keys - mechanism and all users share the same private SSH key for 'tsuser'). - - In normal usage the per-user SSH login should be the simplest and - sufficient, in which case the unixpw option should NOT be selected. - - Client 8bit Color: - - Have the VNC Viewer request low color mode (8 bits per pixel) for - slow links. This may be disabled or further tuned (e.g. 64 color - mode) in the viewer during the session. - - Client-Side Caching: - - x11vnc has an experiment Client-Side caching scheme "-ncache n" - that can give nice speedups. But there are some drawbacks - because the cache-region is visible and uses much RAM. - http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching - - X11VNC Options: - - If you are familiar with x11vnc, you can specify any of its features - that you would like enabled. - - SSVNC Mode: - - Clicking on this button will return you to the full SSVNC Mode. - - Unix ssvncviewer: - - Clicking on this button will popup a menu for setting options - of the Unix (and Mac OS X) provided SSVNC vncviewer. - - - ~/.ssvncrc file: - - You can put global options in your ~/.ssvncrc file (ssvnc_rc on - Windows). Currently they are: - - Put "mode=tsvnc" or "mode=sshvnc" in the ~/.ssvncrc file to have - the application start up in the given mode. - - desktop_type=wmaker (e.g.) to switch the default Desktop Type. - - desktop_size=1280x1024 (e.g.) to switch the default Desktop Size. - - desktop_depth=24 (e.g.) to switch the default Desktop Color Depth. - - xserver_type=Xdummy (e.g.) to switch the default X Server Type. - - (The above 4 settings apply only to the Terminal Services Mode.) - - noenc=1 (same as the -noenc option for a 'No Encryption' option) - noenc=0 (do not show the 'No Encryption' option) - - font_default=tk-font-name (sets the font for menus and buttons) - font_fixed=tk-font-name (sets the font for help text) -} - .oh.f.t insert end $msg - jiggle_text .oh.f.t -} - -proc help_opts {} { - toplev .oh - - scroll_text_dismiss .oh.f - - center_win .oh - - wm title .oh "SSL/SSH Viewer Options Help" - -set msg { - Use SSL: The default, use SSL via STUNNEL (this requires SSL aware VNC - server, e.g. x11vnc -ssl SAVE ...) See the description in the - main Help panel. - - Use SSH: Instead of using STUNNEL SSL, use ssh(1) for the encrypted - tunnel. You must be able to log in via ssh to the remote host. - - On Unix the cmdline ssh(1) program (it must already be installed) - will be run in an xterm for passphrase authentication, prompts - about RSA keys, etc. On Windows the cmdline plink.exe program - will be launched in a Windows Console window. (Apologies for - the klunkiness..) - - You can set the "VNC Host:Display" to "user@host:disp" to - indicate ssh should log in as "user" on "host". NOTE: On - Windows you *MUST* always supply the "user@" part (due to a - plink deficiency). E.g.: - - VNC Host:Display: fred@far-away.east:0 - - - Gateway: If an intermediate gateway machine must be used - (e.g. to enter a firewall; the VNC Server is not running on it), - put it in the Proxy/Gateway entry, e.g.: - - VNC Host:Display: workstation:0 - Proxy/Gateway: user@gateway-host:port - - ssh is used to login to user@gateway-host and then a -L port - redirection is set up to go to workstation:0 from gateway-host. - ":port" is optional, use it if the gateway-host SSH port is - not the default value 22. - - Chaining 2 ssh's: One can also do a "double ssh", i.e. a - first SSH to the gateway login machine then a 2nd ssh to the - destination machine (presumably it is running the vnc server). - - Unlike the above example, the "last leg" (gateway-host -> - workstation) is also encrypted by SSH this way. Do this by - splitting the gateway in two with a comma, the part before it - is the first SSH: - - VNC Host:Display: localhost:0 - Proxy/Gateway: user@gateway-host:port,user@workstation:port - - Web and SOCKS proxies can also be used with SSH: - - VNC Host:Display: user@workstation:0 - Proxy/Gateway: socks://socks.server:1080 - - See the "SSH Proxies/Gateways" in the Main Help document for full - details. - - - Remote Command: In the "Remote SSH Command" entry you can to - indicate that a remote command to be run. The default is - "sleep 15" to make sure port redirections get established. But you - can run anything else, for example, to run x11vnc on your X :0 - workstation display: - - x11vnc -display :0 -nopw - - - Windows SSH SERVER: if you are ssh'ing INTO Windows (e.g. CYGWIN - SSHD server) there may be no "sleep" command so put in something - like "ping localhost" or "ping -n 10 -w 1000 localhost" to - set a short delay to let the port redir get established. - - - Trick: If you use "SHELL" asl the "Remote SSH Command" then - you get an SSH shell only: no VNC viewer will be launched. - On Windows "PUTTY" will try to use putty.exe (better terminal - emulation than plink.exe) A shortcut for this is Ctrl-S as - long as user@hostname is present in the "VNC Host:Display" box. - - - Use SSH + SSL: - - Tunnel the SSL connection through a SSH tunnel. Use this - if you want end-to-end SSL and must use a SSH gateway (e.g. to - enter a firewall) or if additional SSH port redirs are required - (CUPS, Sound, SMB tunnelling: See Advanced Options). - - This is a RARELY used mode, but included in case the need arises. - - - No Encryption: - - In '-noenc' mode, which is now the default, (Ctrl-E also toggles - this mode), use this to make a Direct connection to the VNC Server - with no encryption whatsoever. (Be careful about passwords, etc.) - - The -noenc mode is now the default since SSVNC 1.0.25, use - the '-enc' cmdline option to disable the button. - - - Automatically Find X Session: - - When using SSH mode to connect, you can select this option. It - simply sets the Remote SSH Command to: - - PORT= x11vnc -find -localhost - - This requires that x11vnc is installed on the remote computer - and is available in $PATH for the ssh login. The command - "x11vnc -find -localhost" command is run on the remote - machine. - - The -find option causes x11vnc to try to find an existing X - session owned by the user (i.e. who you ssh in as). If it - does it attaches to it; otherwise the x11vnc VNC server exits - immediately followed by your VNC Viewer. - - The PORT= option just means to let x11vnc pick its own - VNC port and then connect to whatever it picked. Use P= - for more debugging output. - - The idea for this mode is you simply type 'username@workstation' - in the VNC Host:Display box, Select 'Options -> Automatically - Find X Session', and then click Connect. The tsvnc mode is - similar (it runs x11vnc on the remote side with the intent - of automatically finding, or creating, your desktop). - - - Unix Username & Password: - - This is only available on Unix and MacOSX and when using - the SSVNC enhanced TightVNC viewer (it has been modified to - do Unix logins). It supports a login dialog with servers - doing something like x11vnc's "-unixpw" mode. After any - regular VNC authentication takes place (VNC Password), then - it sends the Unix Username, a Return, the Unix Password and - a final Return. This saves you from typing them into the - "login:" and "Password:" prompts in the viewer window. - - Note that the x11vnc -unixpw login mode is external to the - VNC protocol, so you need to be sure the VNC server is in - this mode and will be waiting for the dialog. Otherwise the - username and password will be typed directly into the desktop - application that happens to have the focus! - - When you select this option "Unix Username:" and "Unix - Password:" entry boxes appear on the main panel where you can - type them in. x11vnc has settings that can be specified after - a ":" in the Unix username; they may be used here as well. - (For example: username:3/4,nc for a smaller screen and -nocache) - - If the Unix Username is not set when you click Connect, then - any SSH username@host is used. Otherwise the environment - variable $USER or $LOGNAME and finally whoami(1) is used. - - Also Note that the Unix Password is never saved in a VNC - profile (so you have to type it each time). Also, the remote - x11vnc server is instructed to not echo the Username string - by sending an initial Escape. Set the SSVNC_UNIXPW_NOESC=1 - environment variable to override this. - - Reverse VNC Connection: - - Reverse (listening) VNC connections are possible as well. - Enable with this button "Reverse VNC Connection (-LISTEN)" - - In this case the VNC Server initiates the connection to your - waiting (i.e. listening) SSVNC viewer. - - For SSL connections in the 'VNC Host:Display' entry box put in - the number (e.g. "0" or ":0" or ":1", etc.) that corresponds to - the Listening display (0 -> port 5500, 1 -> port 5501, etc.) you - want to use. For example x11vnc can then be used via: - "x11vnc ... -ssl SAVE -connect hostname:port" using the "port" - with the one you chose. - - Clicking on the 'Listen' button puts your SSVNC viewer - in a "listening" state on that port number, waiting for a - connection from the VNC Server. - - Then a VNC server should establish a reverse connection to - that port on this machine (e.g. -connect this-machine:5500 - or -connect this-machine:5503, etc.) - - Server SSL certificates will be verified, however you WILL - NOT be prompted about unrecognized ones; rather, you MUST - set up the correct Server certificate (e.g. by importing). - prior to any connections. - - If the connection is failing in Reverse VNC (listening) mode, - check the STUNNEL log output to see if STUNNEL is unable to - authenticate the VNC Server. If you want to allow in a - reverse connection with NO Server authentication, unset the - 'Verify All Certs' option. - - When listening in SSL, you will ALSO need to specify YOUR - OWN SSL cert, "MyCert", or otherwise let the GUI prompt you - to create a "listen.pem" and use that. - - The "listen.pem" will be reused in later SSL Listening - connections unless you specify a different one with MyCert. - - On Windows or using a 3rd party VNC Viewer multiple, - simultaneous reverse connections are always enabled. - On Unix/MacOSX with the provided ssvncviewer they are disabled - by default. To enable them: - Options -> Advanced -> Unix ssvncviewer -> Multiple LISTEN Conns. - - For reverse connections in SSH or SSH + SSL modes it is a - little trickier. The SSH tunnel (with -R tunnel) must be - established and remain up waiting for reverse connections. - The default time is "sleep 1800", i.e. 30 mins. You can put - a longer or shorter sleep in "Remote SSH Command" (perhaps - after your command runs: cmd; sleep 3600). - - For SSH reverse connections put "hostname:n" in - 'VNC Host:Display' or "user@hostname:n". The "n" will be the - listening display on the *REMOTE* side. So to have the remote - x11vnc connect use: "x11vnc ... -connect localhost:n" or - "x11vnc -R connect:localhost:n" (-ssl will be needed for SSH+SSL - mode). If the -R port cannot be opened because it is in use - by another program you will have to kill everything and start - over using a different port. - - In reverse connections mode be careful to protect the listening - VNC Viewer from direct connections (neither SSL nor SSH) - connecting directly to its listening port thereby bypassing - the tunnel. This can be done by a host-level firewall that - only lets in, say, port 5500 (the default one ":0" for stunnel - to listen on). Or for SSH reverse connections allow NO 5500+n - ports in. For reverse connections, the Unix enhanced tightvnc - viewers supplied in the SSVNC package will only listen on - localhost so these precautions are not needed. - - Specify a specific interface, e.g. 192.168.1.1:0 to have stunnel - only listen on that interface. IPv6 works too, e.g. :::0 or ::1:0 - Also works for UN-encrypted reverse connections as well ('None'). - - Note that for SSL connections use of "Proxy/Gateway" does not - make sense: the remote side cannot initiate its reverse connection - via the Proxy. - - Note that for SSH or SSH+SSL connections use of "Proxy/Gateway" - does not make sense (the ssh cannot do a -R on a remote host:port), - unless it is a double proxy where the 2nd host is the machine with - the VNC server. - - - View Only: Have VNC Viewer ignore mouse and keyboard input. - - Fullscreen: Start the VNC Viewer in fullscreen mode. - - Raise On Beep: Deiconify viewer when bell rings. - - Use 8bit color: Request a very low-color pixel format. - - Do not use JPEG: Do not use the jpeg aspect of the tight encoding. - - Use X11 vncviewer on MacOSX: - On MacOSX try to use the bundled X11 vncviewer - instead of the Chicken of the VNC viewer; - The Xquartz X server must be installed (it is by - default on 10.5.x) and the DISPLAY variable must - be set (see Tip 15 of Help to do this manually.) - Put cotvnc=1 in ~/.ssvncrc to switch the default. - - Kill Stunnel Automatically: - On Windows, automatically try to kill the STUNNEL - process when the VNC Viewer exits. This is a - global setting (not per-profile); it can be also - set via either the -killstunnel cmdline option, - or killstunnel=1 in ssvnc_rc. To disable it supply - -nokillstunnel or put killstunnel=0 in ssvnc_rc. - As of 1/2009 this option is on by default. - - The main drawback to having STUNNEL automatically - killed is that you will not be able to view its - logfile. If you are having trouble connecting via - SSL, disable this option and double click on the - dark green STUNNEL icon in the tray to view the log. - - - Compress Level/Quality: Set TightVNC encoding parameters. - - - Putty PW: On Windows only: use the supplied password for plink SSH - logins. Unlike the other options the value is not saved - when 'Save' is performed. This feature is useful when - options under "Advanced" are set that require TWO SSH's: - you just have to type the password once in this entry box. - The bundled pageant.exe and puttygen.exe programs can also - be used to avoid repeatedly entering passwords (note this - requires setting up and distributing SSH keys). Start up - pageant.exe or puttygen.exe and read the instructions there. - - Note, that there is a small exposure to someone seeing the - putty password on the plink command line. - - Note that the Putty PW is not cleared if you load in a - new VNC profile. - - - Port Slot: On Windows ports cannot be selected or checked as easily as - on Unix. So listening ports for ssh redirs, proxy tunnelling, - and etc. things are picked via finding a free "slot". - The slots run from 30 to 99 and are locked based on the - existence of a file with the slot number in it. When the - connection is about to be made, a free slot is found and used - to work out some ports (e.g. 5930 for the local VNC port, - etc.) This way simultaneous SSVNC connections can take place. - - One drawback of this is that Putty/Plink stores SSH keys based - on hostname:port, and with a proxy tunnel the hostname is - "localhost". So the Putty key store may have key collisions - for the localhost tunnels, and plink will prompt you to - resolve the conflict WRT a different SSH key being discovered. - - To work around this to some degree you can select a unique - Port Slot (in the range 50-99) for a specific host. Then the - ssh redir port to this host will never change and so the - Putty localhost:fixed-port key should remain valid. - - - Mode: To change the GUI Mode, select between the full SSVNC - (i.e. SSL and SSH), SSHVNC (i.e. SSH-Only), and Terminal - Services mode (TSVNC; uses x11vnc) - - Note: You can put "mode=tsvnc" or "mode=sshvnc" in your - ~/.ssvncrc file (ssvnc_rc on Windows) to have the application - start up in the given mode. - - - Show 'No Encryption' Option: - - Note: since SSVNC 1.0.25 the 'No Encryption' Option is - enabled by default. - - Select this to display a button that disables both SSL and - SSH encryption. This is the same as Ctrl+E. This puts - a check item "None" on the main panel and also a "No - Encryption" check item in the "Options" panel. If you - select this item, there will be NO encryption for the VNC - connection (use cautiously) See Tip 5) under Help for more - information about disabling encryption. - - - Buttons: - - Use Defaults: Set all options to their defaults (i.e. unset). - - Delete Profile: Delete a saved profile. - - Advanced: Bring up the Advanced Options dialog. - - Save and Load: - - You can Save the current settings by clicking on Save - (.vnc file) and you can also read in a saved one with Load - Profile. Use the Browse... button to select the filename - via the GUI. - - Pressing Ctrl-L or Clicking the Right mouse button on the - main GUI will invoke the Load dialog. - - Note: On Windows since the TightVNC Viewer will save its own - settings in the Registry, some unexpected behavior is possible - because the viewer is nearly always directed to the VNC host - "localhost:30". E.g. if you specify "View Only" in this gui - once but not next time the Windows VNC Viewer may remember - the setting. Unfortunately there is not a /noreg option for - the Viewer. -} - .oh.f.t insert end $msg - jiggle_text .oh.f.t -} - -proc help_fetch_cert {{selfsigned 1}} { - toplev .fh - - set h 35 - if [small_height] { - set h 28 - } - scroll_text_dismiss .fh.f 85 $h - - center_win .fh - wm resizable .fh 1 0 - - wm title .fh "Fetch Certificates Help" - - set msg { - The displayed SSL Certificate has been retrieved from the VNC Server via the - "Fetch Cert" action. - - It has merely been downloaded via the SSL Protocol: - - *** IT HAS NOT BEEN VERIFIED OR AUTHENTICATED IN ANY WAY *** - - So, in principle, it could be a fake certificate being inserted by a bad - person attempting to perform a Man-In-The-Middle attack on your SSL connection. - - If, however, by some external means you can verify the authenticity of this SSL - Certificate you can use it for your VNC SSL connection to the VNC server you - wish to connect to. It will provide an authenticated and encrypted connection. - - You can verify the SSL Certificate by comparing the MD5 or SHA1 hash value - via a method/channel you know is safe (i.e. not also under control of a - Man-In-The-Middle attacker). You could also check the text between the - -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- tags, etc. - - Once you are sure it is correct, you can press the Save button to save the - certificate to a file on the local machine for use when you connect via VNC - tunneled through SSL. If you save it, then that file will be set as the - Certificate to verify the VNC server against. You can see this in the dialog - started via the "Certs..." button on the main panel. - - NOTE: If you want to make Permanent the association of the saved SSL certificate - file with the VNC server host, you MUST save the setting as a profile for - loading later. To Save a Profile, click on Options -> Save Profile ..., - and choose a name for the profile and then click on Save. - - If "Verify All Certs" is checked, then you are forced to check all new certs. - In this case the certs are saved in the 'Accepted Certs' directory against - which all servers will be checked unless "ServerCert" or "CertsDir" has been - set to something else. - - To reload the profile at a later time, click on the "Load" button on the - main panel and then select the name and click "Open". If you want to be - sure the certificate is still associated with the loaded in host, click on - "Certs..." button and make sure the "ServerCert" points to the desired SSL - filename. - - See the Certs... Help for more information. A sophisticated method can be set - up using a Certificate Authority key to verify never before seen certificates - (i.e. like your web browser does). -} - - set msg2 { - -------------------------------------------------------------------------- - NOTE: The certificate that was just downloaded IS NOT a Self-Signed - certificate. It was signed by a Certificate Authority (CA) instead. - So saving it does not make sense because it cannot be used to authenticate - anything. - - You need to Obtain and Save the CA's certificate instead. - - The remainder of this Help description applies ONLY to Self-Signed - certificates (i.e. NOT the most recently downloaded one.) - -------------------------------------------------------------------------- - - -} - - if {!$selfsigned} { - regsub { If, however,} $msg "$msg2 If, however," msg - } - - .fh.f.t insert end $msg - jiggle_text .fh.f.t -} - -proc win_nokill_msg {} { - global help_font is_windows system_button_face - toplev .w - - eval text .w.t -width 60 -height 11 $help_font - button .w.d -text "Dismiss" -command {destroy .w} - pack .w.t .w.d -side top -fill x - - apply_bg .w.t - - center_win .w - wm resizable .w 1 0 - - wm title .w "SSL/SSH Viewer: Warning" - - set msg { - The VNC Viewer has exited. - - You will need to terminate STUNNEL manually. - - To do this go to the System Tray and right-click on the STUNNEL - icon (dark green). Then click "Exit". - - You can also double click on the STUNNEL icon to view the log - for error messages and other information. -} - .w.t insert end $msg -} - -proc win_kill_msg {pids} { - global terminate_pids - global help_font - - toplev .w - - eval text .w.t -width 72 -height 21 $help_font - button .w.d -text "Dismiss" -command {destroy .w; set terminate_pids no} - button .w.k -text "Terminate STUNNEL" -command {destroy .w; set terminate_pids yes} - pack .w.t .w.k .w.d -side top -fill x - - apply_bg .w.t - - center_win .w - wm resizable .w 1 0 - - wm title .w "SSL/SSH Viewer: Warning" - - set msg { - The VNC Viewer has exited. - - We can terminate the following still running STUNNEL process(es): - -} - append msg " $pids\n" - - append msg { - Click on the "Terminate STUNNEL" button below to do so. - - Before terminating STUNNEL you can double click on the STUNNEL - Tray icon to view its log for error messages and other information. - - Note: You may STILL need to terminate STUNNEL manually if we are - unable to kill it. To do this go to the System Tray and right-click - on the STUNNEL icon (dark green). Then click "Exit". You will - probably also need to hover the mouse over the STUNNEL Tray Icon to - make the Tray notice STUNNEL is gone... - - To have STUNNEL automatically killed when the Viewer exits use the - -killstunnel cmdline option, or set it under Options or in ssvnc_rc. -} - .w.t insert end $msg -} - -proc win9x_plink_msg {file} { - global help_font win9x_plink_msg_done - toplev .pl - - eval text .pl.t -width 90 -height 26 $help_font - button .pl.d -text "OK" -command {destroy .pl; set win9x_plink_msg_done 1} - wm protocol .pl WM_DELETE_WINDOW {catch {destroy .pl}; set win9x_plink_msg_done 1} - pack .pl.t .pl.d -side top -fill x - - apply_bg .pl.t - - center_win .pl - wm resizable .pl 1 0 - - wm title .pl "SSL/SSH Viewer: Win9x Warning" - - set msg { - Due to limitations on Window 9x you will have to manually start up - a COMMAND.COM terminal and paste in the following command: - -} - set pwd [pwd] - regsub -all {/} $pwd "\\" pwd - append msg " $pwd\\$file\n" - - append msg { - The reason for this is a poor Console application implementation that - affects many text based applications. - - To start up a COMMAND.COM terminal, click on the Start -> Run, and then - type COMMAND in the entry box and hit Return or click OK. - - To select the above command, highlight it with the mouse and then press - Ctrl-C. Then go over to the COMMAND.COM window and click on the - Clipboard paste button. Once pasted in, press Return to run the script. - - This will start up a PLINK.EXE ssh login to the remote computer, - and after you log in successfully and indicate (QUICKLY!!) that the - connection is OK by clicking OK in this dialog. If the SSH connection - cannot be autodetected you will ALSO need to click "Success" in the - "plink ssh status?" dialog, the VNC Viewer will be started going - through the SSH tunnel. -} - .pl.t insert end $msg - wm deiconify .pl -} - -proc mesg {str} { - set maxx 60 - if [regexp {^INFO: without Certificate} $str] { - set maxx 72 - } - if {[string length $str] > $maxx} { - set lend [expr $maxx - 1] - set str [string range $str 0 $lend] - append str " ..." - } - .l configure -text $str - update - global env - if [info exists env(SSVNC_MESG_DELAY)] { - after $env(SSVNC_MESG_DELAY) - } -} - -proc get_ssh_hp {str} { - regsub {cmd=.*$} $str "" str - set str [string trim $str] - regsub {[ ].*$} $str "" str - return $str -} - -proc get_ssh_cmd {str} { - set str [string trim $str] - global ts_only - if {$ts_only} { - return [ts_x11vnc_cmd] - } - if [regexp {cmd=(.*$)} $str m cmd] { - set cmd [string trim $cmd] - regsub -nocase {^%x11vncr$} $cmd "x11vnc -nopw -display none -rawfb rand" cmd - regsub -nocase {^%x11vnc$} $cmd "x11vnc -nopw -display none -rawfb null" cmd - return $cmd - } else { - return "" - } -} - -proc get_ssh_proxy {str} { - set str [string trim $str] - regsub {cmd=.*$} $str "" str - set str [string trim $str] - if { ![regexp {[ ]} $str]} { - return "" - } - regsub {^.*[ ][ ]*} $str "" str - return $str -} - -proc ts_x11vnc_cmd {} { - global is_windows - global ts_xserver_type choose_xserver ts_desktop_type choose_desktop ts_unixpw ts_vncshared - global ts_desktop_size ts_desktop_depth choose_desktop_geom - global choose_filexfer ts_filexfer - global ts_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport choose_x11vnc_opts - global ts_othervnc choose_othervnc ts_xlogin - global choose_sleep extra_sleep - - set cmd "" - if {$choose_x11vnc_opts && $ts_x11vnc_path != ""} { - set cmd $ts_x11vnc_path - } else { - set cmd "x11vnc" - } - if {! $is_windows} { - set cmd "PORT= $cmd" - } else { - set cmd "PORT= $cmd" - } - - set type $ts_xserver_type; - if {! $choose_xserver} { - set type "" - } - if {$choose_othervnc && $ts_othervnc == "find"} { - set type "Xvnc.redirect" - } - - if [info exists choose_sleep] { - if {! $choose_sleep} { - set extra_sleep "" - } - } - - if {$choose_othervnc && $ts_othervnc != "find"} { - set cmd "$cmd -redirect $ts_othervnc" - } elseif {$type == ""} { - global ts_xserver_type_def - if {$ts_xserver_type_def != ""} { - set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-$ts_xserver_type_def"; - } else { - set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb"; - } - } elseif {$type == "Xvfb"} { - set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvfb"; - } elseif {$type == "Xdummy"} { - set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xdummy"; - } elseif {$type == "Xvnc"} { - set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvnc"; - } elseif {$type == "Xvnc.redirect"} { - set cmd "$cmd -display WAIT:cmd=FINDCREATEDISPLAY-Xvnc.redirect"; - } - - # TBD: Cups + sound - - set cmd "$cmd -localhost"; - set cmd "$cmd -nopw"; - global ts_ncache choose_ncache - if {$choose_ncache && [regexp {^[0-9][0-9]*$} $ts_ncache]} { - set cmd "$cmd -ncache $ts_ncache"; - } else { - #set cmd "$cmd -nonc"; - } - set cmd "$cmd -timeout 120"; - global ts_multisession choose_multisession - regsub -all {[^A-z0-9_-]} $ts_multisession "" ts_multisession - if {$choose_multisession && $ts_multisession != ""} { - set cmd "$cmd -env FD_TAG='$ts_multisession'"; - } - if {$choose_filexfer && $ts_filexfer != ""} { - if {$ts_filexfer == "tight"} { - set cmd "$cmd -tightfilexfer"; - } else { - set cmd "$cmd -ultrafilexfer"; - } - } - if {$ts_unixpw} { - set cmd "$cmd -unixpw"; - } - if {$ts_vncshared} { - set cmd "$cmd -shared"; - } - set u "unknown" - global env - if {[info exists env(USER)]} { - regsub -all {[^A-z]} $env(USER) "_" u - } - set cmd "$cmd -o \$HOME/.tsvnc.log.$u"; # XXX perms - - set sess "kde" - global ts_desktop_type_def - if {$ts_desktop_type_def != ""} { - set sess $ts_desktop_type_def - } - if {$choose_desktop && $ts_desktop_type != ""} { - set sess $ts_desktop_type - } - set cmd "$cmd -env FD_SESS=$sess"; - - if {$choose_desktop_geom} { - set geom "1280x1024" - set dep 16 - global ts_desktop_size_def ts_desktop_depth_def - if {$ts_desktop_size_def != ""} { - set geom $ts_desktop_size_def - } - if {$ts_desktop_depth_def != ""} { - set dep $ts_desktop_depth_def - } - if {$ts_desktop_size != ""} { - if [regexp {^[0-9][0-9]*x[0-9][0-9]*$} $ts_desktop_size] { - set geom $ts_desktop_size - } - if {$ts_desktop_depth != ""} { - set geom "${geom}x$ts_desktop_depth" - } else { - set geom "${geom}x$dep" - } - } else { - set geom "${geom}x$dep" - } - set cmd "$cmd -env FD_GEOM=$geom"; - } - if {$is_windows} { - ; - } elseif {$choose_x11vnc_opts && $ts_x11vnc_autoport != "" && [regexp {^[0-9][0-9]*$} $ts_x11vnc_autoport]} { - set cmd "$cmd -autoport $ts_x11vnc_autoport"; - } else { - set cmd "$cmd -env AUTO_PORT=5950"; - } - if {$choose_x11vnc_opts && $ts_x11vnc_opts != ""} { - set cmd "$cmd $ts_x11vnc_opts"; - } - if {$ts_xlogin} { - regsub {PORT= } $cmd "PORT= sudo " cmd - regsub {P= } $cmd "P= sudo " cmd - regsub { -o [^ ][^ ]*} $cmd "" cmd - - set cmd "$cmd -env FD_XDM=1"; - } - - return $cmd -} - -proc set_defaults {} { - global defs env - - global mycert svcert crtdir crlfil - global use_alpha use_turbovnc disable_pipeline use_grab use_ssl use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233 - global use_send_clipboard use_send_always - global disable_all_encryption - global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx - global compresslevel_text quality_text - global use_cups use_sound use_smbmnt - global cups_local_server cups_remote_port cups_manage_rcfile ts_cups_manage_rcfile cups_x11vnc - global cups_local_smb_server cups_remote_smb_port - global change_vncviewer change_vncviewer_path vncviewer_realvnc4 - global choose_xserver ts_xserver_type choose_desktop ts_desktop_type ts_unixpw ts_vncshared - global choose_filexfer ts_filexfer - global ts_x11vnc_opts choose_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport ts_xlogin - global ts_othervnc choose_othervnc choose_sleep - global choose_ncache ts_ncache choose_multisession ts_multisession - global ts_mode ts_desktop_size ts_desktop_depth choose_desktop_geom - global additional_port_redirs additional_port_redirs_list - global stunnel_local_protection stunnel_local_protection_type ssh_local_protection multiple_listen listen_once listen_accept_popup listen_accept_popup_sc - global ssh_known_hosts ssh_known_hosts_filename - global ultra_dsm ultra_dsm_type ultra_dsm_file ultra_dsm_noultra ultra_dsm_salt - global sound_daemon_remote_cmd sound_daemon_remote_port sound_daemon_kill sound_daemon_restart - global sound_daemon_local_cmd sound_daemon_local_port sound_daemon_local_kill sound_daemon_x11vnc sound_daemon_local_start - global smb_su_mode smb_mount_list - global use_port_knocking port_knocking_list port_slot putty_args - global ycrop_string ssvnc_scale ssvnc_escape sbwid_string rfbversion ssvnc_encodings ssvnc_extra_opts use_x11cursor use_nobell use_rawlocal use_notty use_popupfix extra_sleep use_listen use_unixpw use_x11vnc_find unixpw_username - global disable_ssl_workarounds disable_ssl_workarounds_type - global no_probe_vencrypt server_vencrypt server_anondh - global include_list - global svcert_default mycert_default crlfil_default - - - set defs(use_viewonly) 0 - set defs(use_listen) 0 - set defs(disable_ssl_workarounds) 0 - set defs(disable_ssl_workarounds_type) "none" - set defs(use_unixpw) 0 - set defs(unixpw_username) "" - set defs(use_x11vnc_find) 0 - set defs(use_fullscreen) 0 - set defs(use_raise_on_beep) 0 - set defs(use_bgr233) 0 - set defs(use_alpha) 0 - set defs(use_send_clipboard) 0 - set defs(use_send_always) 0 - set defs(use_turbovnc) 0 - set defs(disable_pipeline) 0 - set defs(no_probe_vencrypt) 0 - set defs(server_vencrypt) 0 - set defs(server_anondh) 0 - set defs(use_grab) 0 - set defs(use_nojpeg) 0 - set defs(use_x11_macosx) 1 - if [info exists env(SSVNC_COTVNC)] { - if {$env(SSVNC_COTVNC) != 0} { - set defs(use_x11_macosx) 0 - } - } elseif {![info exists env(DISPLAY)]} { - set defs(use_x11_macosx) 0 - } - set defs(use_compresslevel) "default" - set defs(use_quality) "default" - set defs(compresslevel_text) "Compress Level: default" - set defs(quality_text) "Quality: default" - - set defs(mycert) $mycert_default - set defs(svcert) $svcert_default - set defs(crtdir) "ACCEPTED_CERTS" - set defs(crlfil) $crlfil_default - - set defs(use_cups) 0 - set defs(use_sound) 0 - set defs(use_smbmnt) 0 - - set defs(choose_xserver) 0 - set defs(ts_xserver_type) "" - set defs(choose_desktop) 0 - set defs(ts_desktop_type) "" - set defs(ts_desktop_size) "" - set defs(ts_desktop_depth) "" - set defs(choose_desktop_geom) 0 - set defs(ts_unixpw) 0 - set defs(ts_vncshared) 0 - set defs(ts_ncache) 8 - set defs(choose_ncache) 0 - set defs(ts_multisession) "" - set defs(choose_multisession) 0 - set defs(ts_filexfer) "" - set defs(choose_filexfer) 0 - set defs(choose_x11vnc_opts) 0 - set defs(ts_x11vnc_opts) "" - set defs(ts_x11vnc_path) "" - set defs(ts_x11vnc_autoport) "" - set defs(ts_othervnc) "" - set defs(choose_othervnc) 0 - set defs(ts_xlogin) 0 - set defs(ts_mode) 0 - - set defs(change_vncviewer) 0 - set defs(change_vncviewer_path) "" - set defs(cups_manage_rcfile) 1 - set defs(ts_cups_manage_rcfile) 0 - set defs(cups_x11vnc) 0 - set defs(vncviewer_realvnc4) 0 - - set defs(additional_port_redirs) 0 - set defs(additional_port_redirs_list) "" - - set defs(stunnel_local_protection) 1 - set defs(stunnel_local_protection_type) "exec" - set defs(ssh_local_protection) 1 - set defs(ssh_known_hosts) 0 - set defs(ssh_known_hosts_filename) "" - set defs(multiple_listen) 0 - set defs(listen_once) 0 - set defs(listen_accept_popup) 0 - set defs(listen_accept_popup_sc) 0 - - set defs(ultra_dsm) 0 - set defs(ultra_dsm_file) "" - set defs(ultra_dsm_type) "guess" - set defs(ultra_dsm_noultra) 0 - set defs(ultra_dsm_salt) "" - - set defs(port_slot) "" - set defs(putty_args) "" - - set defs(cups_local_server) "" - set defs(cups_remote_port) "" - set defs(cups_local_smb_server) "" - set defs(cups_remote_smb_port) "" - - set defs(smb_su_mode) "sudo" - set defs(smb_mount_list) "" - - set defs(sound_daemon_remote_cmd) "" - set defs(sound_daemon_remote_port) "" - set defs(sound_daemon_kill) 0 - set defs(sound_daemon_restart) 0 - - set defs(sound_daemon_local_cmd) "" - set defs(sound_daemon_local_port) "" - set defs(sound_daemon_local_start) 0 - set defs(sound_daemon_local_kill) 0 - set defs(sound_daemon_x11vnc) 0 - - set defs(ycrop_string) "" - set defs(ssvnc_scale) "" - set defs(ssvnc_escape) "" - set defs(sbwid_string) "" - set defs(rfbversion) "" - set defs(ssvnc_encodings) "" - set defs(ssvnc_extra_opts) "" - set defs(use_x11cursor) 0 - set defs(use_nobell) 0 - set defs(use_rawlocal) 0 - set defs(use_notty) 0 - set defs(use_popupfix) 0 - set defs(extra_sleep) "" - set defs(use_port_knocking) 0 - set defs(port_knocking_list) "" - - set defs(include_list) "" - - set dir [get_profiles_dir] - set deffile "" - if [file exists "$dir/defaults"] { - set deffile "$dir/defaults" - } elseif [file exists "$dir/defaults.vnc"] { - set deffile "$dir/defaults.vnc" - } - if {$deffile != ""} { - set fh "" - catch {set fh [open $deffile "r"]} - if {$fh != ""} { - while {[gets $fh line] > -1} { - set line [string trim $line] - if [regexp {^#} $line] { - continue - } - if [regexp {^([^=]*)=(.*)$} $line m var val] { - if {$var == "disp"} { - continue - } - if [info exists defs($var)] { - set pct 0 - if {$var == "smb_mount_list"} { - set pct 1 - } - if {$var == "port_knocking_list"} { - set pct 1 - } - if {$pct} { - regsub -all {%%%} $val "\n" val - } - set defs($var) $val - } - } - } - close $fh - } - } - - global ssh_only ts_only - if {$ssh_only || $ts_only} { - set defs(use_ssl) 0 - set defs(use_ssh) 1 - set defs(use_sshssl) 0 - } else { - set defs(use_ssl) 1 - set defs(use_ssh) 0 - set defs(use_sshssl) 0 - } - set defs(disable_all_encryption) 0 - - foreach var [array names defs] { - set $var $defs($var) - } - - global vncauth_passwd unixpw_passwd - set vncauth_passwd "" - set unixpw_passwd "" - - if {$ssh_only || $ts_only} { - ssl_ssh_adjust ssh - } else { - ssl_ssh_adjust ssl - } - listen_adjust - unixpw_adjust - - global last_load - set last_load "" -} - -proc windows_listening_message {n} { - global did_listening_message - - global extra_cmd - set extra_cmd "" - set cmd [get_cmd $n] - - if {$did_listening_message < 2} { - incr did_listening_message - global listening_name - - set ln $listening_name - if {$ln == ""} { - set ln "this-computer:$n" - } - - set msg " - About to start the Listening VNC Viewer (Reverse Connection). - - The VNC Viewer command to be run is: - - $cmd - - After the Viewer starts listening, the VNC server should - then Reverse connect to: - - $ln - - When the VNC Connection has ended **YOU MUST MANUALLY STOP** - the Listening VNC Viewer. - - To stop the Listening Viewer: right click on the VNC Icon in - the tray and select 'Close listening daemon' (or similar). - - ONLY AFTER THAT will you return to the SSVNC GUI. - - Click OK now to start the Listening VNC Viewer.$extra_cmd -" - global use_ssh use_sshssl - if {$use_ssh || $use_sshssl} { - set msg "${msg} NOTE: You will probably also need to kill the SSH in the\n terminal via Ctrl-C" - } - - global help_font is_windows system_button_face - toplev .wll - global wll_done - - set wll_done 0 - - eval text .wll.t -width 64 -height 22 $help_font - button .wll.d -text "OK" -command {destroy .wll; set wll_done 1} - pack .wll.t .wll.d -side top -fill x - - apply_bg .wll.t - - center_win .wll - wm resizable .wll 1 0 - - wm title .wll "SSL/SSH Viewer: Listening VNC Info" - - .wll.t insert end $msg - - vwait wll_done - } -} - -proc get_cmd {n} { - global use_alpha use_grab use_x11cursor use_nobell use_ssh - global use_sshssl use_viewonly use_fullscreen use_bgr233 - global use_nojpeg use_raise_on_beep use_compresslevel use_quality - global use_send_clipboard use_send_always change_vncviewer - global change_vncviewer_path vncviewer_realvnc4 use_listen - global disable_ssl_workarounds disable_ssl_workarounds_type env - - set cmd "vncviewer" - if {$change_vncviewer && $change_vncviewer_path != ""} { - set cmd [string trim $change_vncviewer_path] - regsub -all {\\} $cmd {/} cmd - if {[regexp {[ \t]} $cmd]} { - if {[regexp -nocase {\.exe$} $cmd]} { - if {! [regexp {["']} $cmd]} { #" - # hmmm, not following instructions, are they? - set cmd "\"$cmd\"" - } - } - } - } - if {$use_viewonly} { - if {$vncviewer_realvnc4} { - append cmd " viewonly=1" - } else { - append cmd " /viewonly" - } - } - if {$use_fullscreen} { - if {$vncviewer_realvnc4} { - append cmd " fullscreen=1" - } else { - append cmd " /fullscreen" - } - } - if {$use_bgr233} { - if {$vncviewer_realvnc4} { - append cmd " lowcolourlevel=1" - } else { - append cmd " /8bit" - } - } - if {$use_nojpeg} { - if {! $vncviewer_realvnc4} { - append cmd " /nojpeg" - } - } - if {$use_raise_on_beep} { - if {! $vncviewer_realvnc4} { - append cmd " /belldeiconify" - } - } - if {$use_compresslevel != "" && $use_compresslevel != "default"} { - if {$vncviewer_realvnc4} { - append cmd " zliblevel=$use_compresslevel" - } else { - append cmd " /compresslevel $use_compresslevel" - } - } - if {$use_quality != "" && $use_quality != "default"} { - if {! $vncviewer_realvnc4} { - append cmd " /quality $use_quality" - } - } - - global extra_cmd - set extra_cmd "" - if {$use_listen} { - if {$vncviewer_realvnc4} { - append cmd " listen=1" - } else { - append cmd " /listen" - } - set nn $n - if {$nn < 100} { - set nn [expr "$nn + 5500"] - } - global direct_connect_reverse_host_orig is_win9x - if {![info exists direct_connect_reverse_host_orig]} { - set direct_connect_reverse_host_orig "" - } - if {$direct_connect_reverse_host_orig != "" && !$is_win9x} { - set nn2 [expr $nn + 15] - set h0 $direct_connect_reverse_host_orig - global win_localhost - set extra_cmd "\n\nrelay6.exe $nn $win_localhost $nn2 /b:$h0" - set nn $nn2 - } - - append cmd " $nn" - - } else { - if [regexp {^[0-9][0-9]*$} $n] { - global win_localhost - append cmd " $win_localhost:$n" - } else { - append cmd " $n" - } - } - return $cmd -} - -proc do_viewer_windows {n} { - global use_listen env - - set cmd [get_cmd $n] - - set ipv6_pid2 "" - if {$use_listen} { - set nn $n - if {$nn < 100} { - set nn [expr "$nn + 5500"] - } - global direct_connect_reverse_host_orig is_win9x - if {![info exists direct_connect_reverse_host_orig]} { - set direct_connect_reverse_host_orig "" - } - if {$direct_connect_reverse_host_orig != "" && !$is_win9x} { - set nn2 [expr $nn + 15] - set h0 $direct_connect_reverse_host_orig - global win_localhost - set ipv6_pid2 [exec relay6.exe $nn $win_localhost $nn2 /b:$h0 &] - set nn $nn2 - } - } - - if [info exists env(SSVNC_EXTRA_SLEEP)] { - set t $env(SSVNC_EXTRA_SLEEP) - mesg "sleeping an extra $t seconds..." - set t [expr "$t * 1000"] - after $t - } - global extra_sleep - if {$extra_sleep != ""} { - set t $extra_sleep - mesg "sleeping an extra $t seconds..." - set t [expr "$t * 1000"] - after $t - } - - mesg $cmd - set emess "" - set rc [catch {eval exec $cmd} emess] - - if {$ipv6_pid2 != ""} { - winkill $ipv6_pid2 - } - - if {$rc != 0} { - raise . - tk_messageBox -type ok -icon error -message $emess -title "Error: $cmd" - } -} - -proc get_netstat {} { - set ns "" - catch {set ns [exec netstat -an]} - return $ns -} - -proc get_ipconfig {} { - global is_win9x - set ip "" - if {! $is_win9x} { - catch {set ip [exec ipconfig]} - return $ip - } - - set file "ip" - append file [pid] - append file ".txt" - - # VF - catch {[exec winipcfg /Batch $file]} - - if [file exists $file] { - set fh [open $file "r"] - while {[gets $fh line] > -1} { - append ip "$line\n" - } - close $fh - catch {file delete $file} - } - return $ip -} - -proc read_file {file} { - set str "" - if [file exists $file] { - set fh "" - catch {set fh [open $file "r"]} - if {$fh != ""} { - while {[gets $fh line] > -1} { - append str "$line\n" - } - close $fh - } - } - return $str -} - -proc guess_nat_ip {} { - global save_nat last_save_nat - set s "" - - if {! [info exists save_nat]} { - set save_nat "" - set last_save_nat 0 - } - if {$save_nat != ""} { - set now [clock seconds] - if {$now < $last_save_nat + 45} { - return $save_nat - } - } - set s "" - catch {set s [socket "www.whatismyip.com" 80]} - set ip "unknown" - if {$s != ""} { - fconfigure $s -buffering none - #puts $s "GET / HTTP/1.1" - puts $s "GET /automation/n09230945.asp HTTP/1.1" - puts $s "Host: www.whatismyip.com" - puts $s "Connection: close" - puts $s "" - flush $s - set on 0 - while { [gets $s line] > -1 } { - if {! $on && [regexp {<HEAD>} $line]} {set on 1} - if {! $on && [regexp {<HTML>} $line]} {set on 1} - if {! $on && [regexp {<TITLE>} $line]} {set on 1} - if {! $on && [regexp {^[0-9][0-9]*\.[0-9]} $line]} {set on 1} - if {! $on} { - continue; - } - if [regexp {([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*)} $line ip] { - break - } - } - close $s - } - if {$ip != "unknown"} { - set save_nat $ip - set last_save_nat [clock seconds] - } - return $ip -} - -proc check_for_ipv6 {} { - global is_windows have_ipv6 - if {$have_ipv6 != ""} { - return - } - if {! $is_windows} { - set out "" - catch {set out [exec netstat -an]} - if [regexp {tcp6} $out] { - set have_ipv6 1 - } elseif [regexp {udp6} $out] { - set have_ipv6 1 - } elseif [regexp {:::} $out] { - set have_ipv6 1 - } elseif [regexp {::1} $out] { - set have_ipv6 1 - } elseif [regexp {TCP: IPv6.*LISTEN} $out] { - set have_ipv6 1 - } else { - set have_ipv6 0 - } - } else { - set out [get_ipconfig] - set out [string trim $out] - if {$out == ""} { - catch {set out [exec ping6 -n 1 -w 2000 ::1]} - if [regexp {Reply from.*bytes} $out] { - if [regexp {Received = 1} $out] { - set have_ipv6 1 - return - } - } - set have_ipv6 0 - return - } - foreach line [split $out "\n\r"] { - if {[regexp -nocase {IP Address.*:[ \t]*[a-f0-9]*:[a-f0-9]*:} $line]} { - set have_ipv6 1 - return - } - } - set have_ipv6 0 - } -} -proc guess_ip {} { - global is_windows - if {! $is_windows} { - set out "" - set out [get_hostname] - if {$out != ""} { - set hout "" - catch {set hout [exec host $out]} - if {$hout != ""} { - if [regexp {has address ([.0-9][.0-9]*)} $hout mvar ip] { - set ip [string trim $ip] - return $ip - } - } - } - return "" - } else { - set out [get_ipconfig] - set out [string trim $out] - if {$out == ""} { - return "" - } - foreach line [split $out "\n\r"] { - if {[regexp -nocase {IP Address.*:[ \t]*([.0-9][.0-9]*)} $line mvar ip]} { - set ip [string trim $ip] - if [regexp {^[.0]*$} $ip] { - continue - } - if [regexp {127\.0\.0\.1} $ip] { - continue - } - if {$ip != ""} { - return $ip - } - } - } - foreach line [split $out "\n\r"] { - if {[regexp -nocase {IP Address.*:[ \t]*([:a-f0-9][%:a-f0-9]*)} $line mvar ip]} { - set ip [string trim $ip] - if [regexp {^[.0]*$} $ip] { - continue - } - if [regexp {127\.0\.0\.1} $ip] { - continue - } - if {$ip != ""} { - return $ip - } - } - } - } -} - -proc bat_sleep {fh} { - global env - if [info exists env(SSVNC_BAT_SLEEP)] { - puts $fh "@echo ." - puts $fh "@echo -----" - puts $fh "@echo Debug: BAT SLEEP for $env(SSVNC_BAT_SLEEP) seconds ..." - puts $fh "@ping -n $env(SSVNC_BAT_SLEEP) -w 1000 0.0.0.1 > NUL" - puts $fh "@echo BAT SLEEP done." - } -} - -proc windows_start_sound_daemon {file} { - global env - global use_sound sound_daemon_local_cmd sound_daemon_local_start - - # VF - regsub {\.bat} $file "snd.bat" file2 - set fh2 [open $file2 "w"] - - puts $fh2 $sound_daemon_local_cmd - bat_sleep $fh2 - puts $fh2 "del $file2" - close $fh2 - - mesg "Starting SOUND daemon..." - if [info exists env(COMSPEC)] { - if [info exists env(SSVNC_BAT_SLEEP)] { - exec $env(COMSPEC) /c start $env(COMSPEC) /c $file2 & - } else { - exec $env(COMSPEC) /c $file2 & - } - } else { - if [info exists env(SSVNC_BAT_SLEEP)] { - exec cmd.exe /c start cmd.exe /c $file2 & - } else { - exec cmd.exe /c $file2 & - } - } - after 1500 -} - -proc winkill {pid} { - global is_win9x - - if {$pid == ""} { - return - } - if {! $is_win9x} { - catch {exec tskill.exe $pid} - after 100 - catch {exec taskkill.exe /PID $pid} - after 100 - } - catch {exec w98/kill.exe /f $pid} -} - -proc windows_stop_sound_daemon {} { - global use_sound sound_daemon_local_cmd sound_daemon_local_start - - set cmd [string trim $sound_daemon_local_cmd] - - regsub {[ \t].*$} $cmd "" cmd - regsub {^.*\\} $cmd "" cmd - regsub {^.*/} $cmd "" cmd - - if {$cmd == ""} { - return - } - - set output [get_task_list] - - foreach line [split $output "\n\r"] { - if [regexp "$cmd" $line] { - if [regexp {(-?[0-9][0-9]*)} $line m p] { - set pids($p) $line - } - } - } - - set count 0 - foreach pid [array names pids] { - mesg "Stopping SOUND pid: $pid" - winkill $pid - if {$count == 0} { - after 1200 - } else { - after 500 - } - incr count - } -} - -proc contag {} { - global concount - if {! [info exists concount]} { - set concount 0 - } - incr concount - set str [pid] - set str "-$str-$concount" -} - -proc make_plink {} { - toplev .plink - #wm geometry .plink +700+500 - wm geometry .plink -40-40 - wm title .plink "plink SSH status?" - set wd 37 - label .plink.l1 -anchor w -text "Login via plink/ssh to the remote server" -width $wd - label .plink.l2 -anchor w -text "(supply username and password as needed)." -width $wd - label .plink.l3 -anchor w -text "" -width $wd - label .plink.l4 -anchor w -text "After ssh is set up, AND if the connection" -width $wd - label .plink.l5 -anchor w -text "success is not autodetected, please click" -width $wd - label .plink.l6 -anchor w -text "one of these buttons:" -width $wd - global plink_status - button .plink.fail -text "Failed" -command {destroy .plink; set plink_status no} - button .plink.ok -text "Success" -command {destroy .plink; set plink_status yes} - pack .plink.l1 .plink.l2 .plink.l3 .plink.l4 .plink.l5 .plink.l6 .plink.fail .plink.ok -side top -fill x - - update -} - -proc ssh_split {str} { - regsub { .*$} $str "" str - if {! [regexp {:[0-9][0-9]*$} $str]} { - append str ":22" - } - regsub {:[0-9][0-9]*$} $str "" ssh_host - regsub {^.*:} $str "" ssh_port - if {$ssh_port == ""} { - set ssh_port 22 - } - if [regexp {@} $ssh_host] { - regsub {@.*$} $ssh_host "" ssh_user - regsub {^.*@} $ssh_host "" ssh_host - } else { - set ssh_user "" - } - return [list $ssh_user $ssh_host $ssh_port] -} - -proc check_debug_netstat {port str wn} { - global debug_netstat - if {! [info exists debug_netstat]} { - return - } - if {$debug_netstat == "0" || $debug_netstat == ""} { - return - } - mesg "DBG: $wn" - - toplev .dbns - - set h 35 - if [small_height] { - set h 28 - } - scroll_text_dismiss .dbns.f 82 $h - center_win .dbns - .dbns.f.t insert end "LOOKING FOR PORT: $port\n\n$str" - jiggle_text .dbns.f.t - update - after 1000 -} - -proc launch_windows_ssh {hp file n} { - global is_win9x env - global use_sshssl use_ssh putty_pw putty_args - global port_knocking_list - global use_listen listening_name - global disable_ssl_workarounds disable_ssl_workarounds_type - global ts_only - global debug_netstat - - set hpnew [get_ssh_hp $hp] - set proxy [get_ssh_proxy $hp] - set sshcmd [get_ssh_cmd $hp] - - global win_localhost - - set vnc_host $win_localhost - set vnc_disp $hpnew - regsub {^.*:} $vnc_disp "" vnc_disp - - regsub {\.bat} $file ".flg" flag - - if {$ts_only} { - regsub {:0$} $hpnew "" hpnew - if {$proxy == ""} { - if {[regexp {^(.*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} { - set proxy "$sshhst:$sshpt" - set hpnew $win_localhost - } - } else { - if {![regexp {,} $proxy]} { - if {$hpnew != $win_localhost} { - set proxy "$proxy,$hpnew" - set hpnew $win_localhost - } - } - } - } elseif {![regexp {^-?[0-9][0-9]*$} $vnc_disp]} { - if {[regexp {cmd=SHELL} $hp]} { - ; - } elseif {[regexp {cmd=PUTTY} $hp]} { - ; - } else { - # XXX add :0 instead? - if {1} { - set vnc_disp "vnc_disp:0" - mesg "Added :0 to $vnc_disp" - } else { - mesg "Bad vncdisp, missing :0 ?, $vnc_disp" - bell - return 0 - } - } - } - - if {$use_listen} { - set vnc_port 5500 - } else { - set vnc_port 5900 - } - - if {$ts_only || [regexp {PORT= .*x11vnc} $sshcmd] || [regexp {P= .*x11vnc} $sshcmd]} { - regsub {PORT= [ ]*} $sshcmd "" sshcmd - regsub {P= [ ]*} $sshcmd "" sshcmd - set vnc_port [expr "8100 + int(4000 * rand())"] - set sshcmd "$sshcmd -rfbport $vnc_port" - } elseif {[regexp {^-[0-9][0-9]*$} $vnc_disp]} { - set vnc_port [expr "- $vnc_disp"] - } elseif {![regexp {^[0-9][0-9]*$} $vnc_disp]} { - ; - } elseif {$vnc_disp < 200} { - if {$use_listen} { - set vnc_port [expr $vnc_disp + 5500] - } else { - set vnc_port [expr $vnc_disp + 5900] - } - } else { - set vnc_port $vnc_disp - } - - global ssh_ipv6_pid - set ssh_ipv6_pid "" - - set ssh_port 22 - set ssh_host [host_part $hpnew] - - set double_ssh "" - set p_port "" - if {$proxy != ""} { - if [regexp -nocase {(http|https|socks|socks4|socks5|repeater)://} $proxy] { - set pproxy "" - set sproxy1 "" - set sproxy_rest "" - set sproxy1_host "" - set sproxy1_user "" - set sproxy1_port "" - foreach part [split $proxy ","] { - if {[regexp {^[ ]*$} $part]} { - continue - } - if [regexp -nocase {^(http|https|socks|socks4|socks5|repeater)://} $part] { - if {$pproxy == ""} { - set pproxy $part - } else { - set pproxy "$pproxy,$part" - } - } else { - if {$sproxy1 == ""} { - set sproxy1 $part - } else { - if {$sproxy_rest == ""} { - set sproxy_rest $part - } else { - set sproxy_rest "$sproxy_rest,$part" - } - } - } - } - -#mesg "pproxy: $pproxy"; after 2000 -#mesg "sproxy1: $sproxy1"; after 2000 -#mesg "sproxy_rest: $sproxy_rest"; after 2000 -#mesg "ssh_host: $ssh_host"; after 2000 -#mesg "ssh_port: $ssh_port"; after 2000 - - if {$sproxy1 != ""} { - regsub {:[0-9][0-9]*$} $sproxy1 "" sproxy1_host - regsub {^.*@} $sproxy1_host "" sproxy1_host - regsub {@.*$} $sproxy1 "" sproxy1_user - regsub {^.*:} $sproxy1 "" sproxy1_port - } else { - regsub {:[0-9][0-9]*$} $ssh_host "" sproxy1_host - regsub {^.*@} $sproxy1_host "" sproxy1_host - regsub {@.*$} $ssh_host "" sproxy1_user - regsub {^.*:} $ssh_host "" sproxy1_port - } - if {![regexp {^[0-9][0-9]*$} $sproxy1_port]} { - set sproxy1_port 22 - } - if {$sproxy1_user != ""} { - set sproxy1_user "$sproxy1_user@" - } - -#mesg "sproxy1_host: $sproxy1_host"; after 2000 -#mesg "sproxy1_user: $sproxy1_user"; after 2000 -#mesg "sproxy1_port: $sproxy1_port"; after 2000 - - set port2 "" - if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] { - set port2 [expr 21000 + $dport] - } else { - set port2 [rand_port] - } - - global have_ipv6 - if {$have_ipv6} { - set res [ipv6_proxy $pproxy "" ""] - set pproxy [lindex $res 0] - set ssh_ipv6_pid [lindex $res 3] - } - - set env(SSVNC_PROXY) $pproxy - set env(SSVNC_LISTEN) $port2 - set env(SSVNC_DEST) "$sproxy1_host:$sproxy1_port" - - mesg "Starting Proxy TCP helper on port $port2 ..." - after 300 - # ssh br case: - set proxy_pid [exec "connect_br.exe" &] - - catch { unset env(SSVNC_PROXY) } - catch { unset env(SSVNC_LISTEN) } - catch { unset env(SSVNC_DEST) } - - if {$sproxy1 == ""} { - set proxy "$win_localhost:$port2" - if [regexp {^(.*)@} $ssh_host mv u] { - set proxy "$u@$proxy" - } - } else { - set proxy "${sproxy1_user}$win_localhost:$port2" - } - if {$sproxy_rest != ""} { - set proxy "$proxy,$sproxy_rest" - } - mesg "Set proxy to: $proxy" - after 300 - } - if [regexp {,} $proxy] { - if {$is_win9x} { - mesg "Double proxy does not work on Win9x" - bell - winkill $ssh_ipv6_pid - set ssh_ipv6_pid "" - return 0 - } - # user1@gateway:port1,user2@workstation:port2 - set proxy1 "" - set proxy2 "" - set s [split $proxy ","] - set proxy1 [lindex $s 0] - set proxy2 [lindex $s 1] - - set p_port "" - if [regexp -- {-([0-9][0-9]*)} [file tail $file] mv dport] { - set p_port [expr 4000 + $dport] - } else { - set p_port [expr 3000 + 1000 * rand()] - set p_port [expr round($p_port)] - } - - set s [ssh_split $proxy1] - set ssh_user1 [lindex $s 0] - set ssh_host1 [lindex $s 1] - set ssh_port1 [lindex $s 2] - - set s [ssh_split $proxy2] - set ssh_user2 [lindex $s 0] - set ssh_host2 [lindex $s 1] - set ssh_port2 [lindex $s 2] - - if {! [regexp {^[0-9][0-9]*$} $ssh_port1]} { - set ssh_port1 22 - } - if {! [regexp {^[0-9][0-9]*$} $ssh_port2]} { - set ssh_port2 22 - } - - set u1 "" - if {$ssh_user1 != ""} { - set u1 "${ssh_user1}@" - } - set u2 "" - if {$ssh_user2 != ""} { - set u2 "${ssh_user2}@" - } - - set double_ssh "-L $p_port:$ssh_host2:$ssh_port2 -P $ssh_port1 $u1$ssh_host1" - set proxy_use "${u2}$win_localhost:$p_port" - - } else { - # user1@gateway:port1 - set proxy_use $proxy - } - - set ssh_host [host_part $proxy_use] - - set ssh_port [port_part $proxy_use] - if {! [regexp {^[0-9][0-9]*$} $ssh_port]} { - set ssh_port 22 - } - - set vnc_host [host_part $hpnew] - if {$vnc_host == ""} { - set vnc_host $win_localhost - } - } - - if {![regexp {^[^ ][^ ]*@} $ssh_host]} { - mesg "You must supply a username: user@host..." - bell - winkill $ssh_ipv6_pid - set ssh_ipv6_pid "" - return 0 - } - - set verb "-v" - - set pwd "" - if {$is_win9x} { - set pwd [pwd] - regsub -all {/} $pwd "\\" pwd - } - if {! [regexp {^[0-9][0-9]*$} $n]} { - set n 0 - } - - if {$use_listen} { - set use [expr $n + 5500] - } else { - set use [expr $n + 5900] - } - - set_smb_mounts - - global use_smbmnt use_sound sound_daemon_kill - set do_pre 0 - if {$use_smbmnt} { - set do_pre 1 - } elseif {$use_sound && $sound_daemon_kill} { - set do_pre 1 - } - - global skip_pre - if {$skip_pre} { - set do_pre 0 - set skip_pre 0 - } - - set pw "" - if {$putty_pw != ""} { - if {! [regexp {"} $putty_pw]} { #" - set pw " -pw \"$putty_pw\"" - } - } - - set tag [contag] - - set file_double "" - - set file_pre "" - set file_pre_cmd "" - if {$do_pre} { - set setup_cmds [ugly_setup_scripts pre $tag] - - if {$setup_cmds != ""} { - # VF - regsub {\.bat} $file "pre.cmd" file_pre_cmd - set fh [open $file_pre_cmd "w"] - puts $fh "$setup_cmds sleep 10; " - bat_sleep $fh - close $fh - - # VF - regsub {\.bat} $file "pre.bat" file_pre - set fh [open $file_pre "w"] - set plink_str "plink.exe -ssh -C -P $ssh_port -m $file_pre_cmd $verb -t" - if {$putty_args != ""} { - append plink_str " $putty_args" - } - - global smb_redir_0 - if {$smb_redir_0 != ""} { - append plink_str " $smb_redir_0" - } - - if [regexp {%} $ssh_host] { - set uath "" - regsub -all {%SPACE} $ssh_host " " uath - regsub -all {%TAB} $uath " " uath - append plink_str "$pw \"$uath\"" - } else { - append plink_str "$pw $ssh_host" - } - - if {$pw != ""} { - puts $fh "echo off" - } - puts $fh $plink_str - - bat_sleep $fh - if {![info exists env(SSVNC_NO_DELETE)]} { - if {$file_pre_cmd != ""} { - puts $fh "del $file_pre_cmd" - } - puts $fh "del $file_pre" - } - close $fh - } - } - - if {$is_win9x} { - set sleep 35 - } else { - set sleep 20 - } - if {$use_listen} { - set sleep 1800 - } - - set setup_cmds [ugly_setup_scripts post $tag] - - set do_shell 0 - if {$sshcmd == "SHELL"} { - set setup_cmds "" - set sshcmd {$SHELL} - set do_shell 1 - } elseif {$sshcmd == "PUTTY"} { - set setup_cmds "" - set do_shell 1 - } - - if {$sshcmd != "SHELL" && [regexp -nocase {x11vnc} $sshcmd]} { - global use_cups cups_x11vnc cups_remote_port - global cups_remote_smb_port - global use_sound sound_daemon_x11vnc sound_daemon_remote_port - global ts_only - if {$ts_only} { - set cups_x11vnc 1 - set sound_daemon_x11vnc 1 - } - if {$use_cups && $cups_x11vnc && $cups_remote_port != ""} { - set crp $cups_remote_port - if {$ts_only} { - set cups_remote_port [rand_port] - set crp "DAEMON-$cups_remote_port" - } - set sshcmd "$sshcmd -env FD_CUPS=$crp" - } - if {$use_cups && $cups_x11vnc && $cups_remote_smb_port != ""} { - set csp $cups_remote_smb_port - if {$ts_only} { - set cups_remote_smb_port [rand_port] - set csp "DAEMON-$cups_remote_smb_port" - } - set sshcmd "$sshcmd -env FD_SMB=$csp" - } - if {$use_sound && $sound_daemon_x11vnc && $sound_daemon_remote_port != ""} { - set srp $sound_daemon_remote_port - if {$ts_only} { - set sound_daemon_remote_port [rand_port] - set srp "DAEMON-$sound_daemon_remote_port" - } - set sshcmd "$sshcmd -env FD_ESD=$srp" - } - } - - set file_cmd "" - if {$setup_cmds != ""} { - # VF - regsub {\.bat} $file ".cmd" file_cmd - set fh_cmd [open $file_cmd "w"] - - set str $setup_cmds - if {$sshcmd != ""} { - append str " $sshcmd; " - } else { - append str " sleep $sleep; " - } - puts $fh_cmd $str - bat_sleep $fh_cmd - close $fh_cmd - - set sshcmd $setup_cmds - } - - if {$sshcmd == ""} { - set pcmd "echo; echo SSH connected OK.; echo If this state is not autodetected,; echo Go Click the Success button." - set sshcmd "$pcmd; sleep $sleep" - } - - global use_sound sound_daemon_local_cmd sound_daemon_local_start - if {! $do_shell && ! $is_win9x && $use_sound && $sound_daemon_local_start && $sound_daemon_local_cmd != ""} { - windows_start_sound_daemon $file - } - - # VF - set fh [open $file "w"] - if {$is_win9x} { - puts $fh "cd $pwd" - if {$file_pre != ""} { - puts $fh "echo Press Ctrl-C --HERE-- when done with the Pre-Command shell work." - puts $fh "start /w command.com /c $file_pre" - } - } - - global use_cups use_smbmnt - set extra_redirs "" - if {$use_cups} { - append extra_redirs [get_cups_redir] - } - if {$use_sound} { - append extra_redirs [get_sound_redir] - } - global additional_port_redirs - if {$additional_port_redirs} { - append extra_redirs [get_additional_redir] - } - - if {$vnc_host == ""} { - set vnc_host $win_localhost - } - regsub {^.*@} $vnc_host "" vnc_host - - set redir "-L $use:$vnc_host:$vnc_port" - if {$use_listen} { - set redir "-R $vnc_port:$vnc_host:$use" - set listening_name "localhost:$vnc_port (on remote SSH side)" - } - - set plink_str "plink.exe -ssh -P $ssh_port $verb $redir $extra_redirs -t" - if {$putty_args != ""} { - append plink_str " $putty_args" - } - if {$extra_redirs != ""} { - regsub {exe} $plink_str "exe -C" plink_str - } else { - # hmm we used to have it off... why? - # ssh typing response? - regsub {exe} $plink_str "exe -C" plink_str - } - set uath $ssh_host - if [regexp {%} $uath] { - regsub -all {%SPACE} $uath " " uath - regsub -all {%TAB} $uath " " uath - set uath "\"$uath\"" - } - if {$do_shell} { - if {$sshcmd == "PUTTY"} { - if [regexp {^".*@} $uath] { #" - regsub {@} $uath {" "} uath - set uath "-l $uath" - } - if {$is_win9x} { - set plink_str "putty.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath" - } else { - set plink_str "start \"putty $ssh_host\" putty.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath" - if [regexp {FINISH} $port_knocking_list] { - regsub {start} $plink_str "start /wait" plink_str - } - } - } else { - set plink_str "plink.exe -ssh -C -P $ssh_port $extra_redirs $putty_args -t $pw $uath" - append plink_str { "$SHELL"} - } - } elseif {$file_cmd != ""} { - append plink_str " -m $file_cmd$pw $uath" - } else { - append plink_str "$pw $uath \"$sshcmd\"" - } - - if {$pw != ""} { - puts $fh "echo off" - } - if {$ts_only && [regexp {sudo } $sshcmd]} { - puts $fh "echo \" \"" - puts $fh "echo \"Doing Initial SSH with sudo id to prime sudo...\"" - puts $fh "echo \" \"" - puts $fh "plink.exe -ssh $putty_args -t $uath \"sudo id; tty\"" - puts $fh "echo \" \"" - } - puts $fh $plink_str - bat_sleep $fh - puts $fh "del $flag" - if {![info exists env(SSVNC_NO_DELETE)]} { - if {$file_cmd != ""} { - puts $fh "del $file_cmd" - } - puts $fh "del $file" - } - close $fh - - catch {destroy .o} - catch {destroy .oa} - catch {destroy .os} - - if { ![do_port_knock $ssh_host start]} { - if {![info exists env(SSVNC_NO_DELETE)]} { - catch {file delete $file} - if {$file_cmd != ""} { - catch {file delete $file_cmd} - } - if {$file_pre != ""} { - catch {file delete $file_pre} - } - } - winkill $ssh_ipv6_pid - set ssh_ipv6_pid "" - return 0 - } - - if {$double_ssh != ""} { - set plink_str_double_ssh "plink.exe -ssh $putty_args -t $pw $double_ssh \"echo sleep 60 ...; sleep 60; echo done.\"" - - # VF - regsub {\.bat} $file "dob.bat" file_double - set fhdouble [open $file_double "w"] - puts $fhdouble $plink_str_double_ssh - bat_sleep $fhdouble - puts $fhdouble "del $flag" - if {![info exists env(SSVNC_NO_DELETE)]} { - puts $fhdouble "del $file_double" - } - close $fhdouble - - set com "cmd.exe" - if [info exists env(COMSPEC)] { - set com $env(COMSPEC) - } - - set ff [open $flag "w"] - puts $ff "flag" - close $ff - - global env - if [info exists env(SSVNC_BAT_SLEEP)] { - exec $com /c start $com /c $file_double & - } else { - exec $com /c $file_double & - } - - set waited 0 - set gotit 0 - while {$waited < 30000} { - after 500 - update - if {$use_listen} { - set gotit 1 - break; - } - set ns [get_netstat] - set re ":$p_port" - check_debug_netstat $p_port $ns $waited - append re {[ ][ ]*[0:.][0:.]*[ ][ ]*LISTEN} - if [regexp $re $ns] { - set gotit 1 - break - } - set waited [expr "$waited + 500"] - if {![file exists $flag]} { - break - } - } - catch {file delete $flag} - if {! $gotit} { - after 5000 - } - } - - vencrypt_tutorial_mesg - - set wdraw 1 - #set wdraw 0 - if [info exists debug_netstat] { - if {$debug_netstat != "" && $debug_netstat != "0"} { - set wdraw 0 - } - } - - set ff [open $flag "w"] - puts $ff "flag" - close $ff - - if {$is_win9x} { - if {$wdraw} { - wm withdraw . - } - update - win9x_plink_msg $file - global win9x_plink_msg_done - set win9x_plink_msg_done 0 - vwait win9x_plink_msg_done - } else { - set com "cmd.exe" - if [info exists env(COMSPEC)] { - set com $env(COMSPEC) - } - - if {$file_pre != ""} { - set sl 0 - if {$use_smbmnt} { - global smb_su_mode - if {$smb_su_mode == "su"} { - set sl [expr $sl + 15] - } elseif {$smb_su_mode == "sudo"} { - set sl [expr $sl + 15] - } else { - set sl [expr $sl + 3] - } - } - if {$pw == ""} { - set sl [expr $sl + 5] - } - - set sl [expr $sl + 5] - set st [clock seconds] - set dt 0 - global entered_gui_top button_gui_top - set entered_gui_top 0 - set button_gui_top 0 - - catch {wm geometry . "-40-40"} - catch {wm withdraw .; update; wm deiconify .; raise .; update} - mesg "Click on *This* Label when done with 1st SSH 0/$sl" - after 600 - - global env - if [info exists env(SSVNC_BAT_SLEEP)] { - exec $com /c start $com /c $file_pre & - } else { - exec $com /c $file_pre & - } - - catch {lower .; update; raise .; update} - - while {$dt < $sl} { - after 100 - set dt [clock seconds] - set dt [expr $dt - $st] - mesg "Click on *This* Label when done with 1st SSH $dt/$sl" - update - update idletasks - if {$dt <= 1} { - set button_gui_top 0 - } - if {$button_gui_top != 0 && $dt >= 3} { - mesg "Running 2nd SSH now ..." - after 1000 - break - } - } - mesg "Running 2nd SSH ..." - } - - if {! $do_shell} { - make_plink - } - if {$wdraw} { - wm withdraw . - } - - update - if {$do_shell && [regexp {FINISH} $port_knocking_list]} { - catch {exec $com /c $file} - } else { - global env - if [info exists env(SSVNC_BAT_SLEEP)] { - exec $com /c start $com /c $file & - } else { - exec $com /c $file & - } - } - after 1000 - } - - if {$do_shell} { - wm deiconify . - update - if {[regexp {FINISH} $port_knocking_list]} { - do_port_knock $ssh_host finish - } - return 1 - } - set made_plink 0 - if {$is_win9x} { - make_plink - set made_plink 1 - } - global plink_status - set plink_status "" - set waited 0 - set cnt 0 - while {$waited < 30000} { - after 500 - update - if {$use_listen} { - set plink_status yes - break; - } - set ns [get_netstat] - set re ":$use" - check_debug_netstat $use $ns $waited - append re {[ ][ ]*[0:.][0:.]*[ ][ ]*LISTEN} - if [regexp $re $ns] { - set plink_status yes - } - if {$plink_status != ""} { - catch {destroy .plink} - break - } - - if {$waited == 0} { - #wm deiconify .plink - } - set waited [expr "$waited + 500"] - - incr cnt - if {$cnt >= 12} { - set cnt 0 - } - if {![file exists $flag]} { - set plink_status flag_gone - break - } - } - catch {file delete $flag} - if {$plink_status == ""} { - if {! $made_plink} { - make_plink - set made_plink 1 - } - vwait plink_status - } - - if {$use_sshssl} { - global launch_windows_ssh_files - if {$file != ""} { - append launch_windows_ssh_files "$file " - } - if {$file_pre != ""} { - append launch_windows_ssh_files "$file_pre " - } - if {$file_pre_cmd != ""} { - append launch_windows_ssh_files "$file_pre_cmd " - } - regsub { *$} $launch_windows_ssh_files "" launch_windows_ssh_files - return 1 - } - - if {$plink_status != "yes"} { - set m "unknown" - if {$plink_status == "flag_gone"} { - set m "plink script failed" - } elseif {$plink_status == ""} { - set m "timeout" - } - mesg "Error ($m) to $hp" - wm deiconify . - } else { - after 1000 - do_viewer_windows $n - wm deiconify . - mesg "Disconnected from $hp" - } - update - if [regexp {FINISH} $port_knocking_list] { - do_port_knock $ssh_host finish - } - - if {![info exists env(SSVNC_NO_DELETE)]} { - if {$file != ""} { - catch {file delete $file} - } - if {$file_pre != ""} { - catch {file delete $file_pre} - } - if {$file_pre_cmd != ""} { - catch {file delete $file_pre_cmd} - } - if {$file_double != ""} { - catch {file delete $file_double} - } - } - - winkill $ssh_ipv6_pid - set ssh_ipv6_pid "" - - global sound_daemon_local_kill - if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} { - windows_stop_sound_daemon - } - return 1 -} - -proc check_ssh_needed {} { - globalize - - if {$use_ssh || $use_sshssl} { - return - } - set must_cups 0 - set must_snd 0 - set must_smb 0 - set must_addl 0 - if {$use_cups} { - if {$cups_local_server != ""} {set must_cups 1} - if {$cups_remote_port != ""} {set must_cups 1} - if {$cups_local_smb_server != ""} {set must_cups 1} - if {$cups_remote_smb_port != ""} {set must_cups 1} - if {$cups_manage_rcfile != ""} {set must_cups 1} - } - if {$use_sound} { - if {$sound_daemon_remote_cmd != ""} {set must_snd 1} - if {$sound_daemon_remote_port != ""} {set must_snd 1} - if {$sound_daemon_kill} {set must_snd 1} - if {$sound_daemon_restart} {set must_snd 1} - if {$sound_daemon_local_cmd != ""} {set must_snd 1} - if {$sound_daemon_local_port != ""} {set must_snd 1} - if {$sound_daemon_local_kill} {set must_snd 1} - if {$sound_daemon_local_start} {set must_snd 1} - } - if {$use_smbmnt} { - if {[regexp {//} $smb_mount_list]} {set must_smb 1} - } - if {$additional_port_redirs} { - set must_addl 1 - } - if {$must_cups || $must_snd || $must_smb || $must_addl} { - mesg "Cannot do Port redirs in non-SSH mode (SSL)" - set msg "" - if {$must_smb} { - append msg " - SMB Mount Port Redirection\n" - } - if {$must_snd} { - append msg " - ESD Sound Port Redirection\n" - } - if {$must_cups} { - append msg " - CUPS Port Redirection\n" - } - if {$must_addl} { - append msg " - Additional Port Redirections\n" - } - set msg "\"Use SSL\" mode selected (no SSH)\nThe following options will be disabled:\n\n$msg" - bell - update - raise . - tk_messageBox -type ok -icon info -message $msg - } -} - -proc set_smb_mounts {} { - global smb_redir_0 smb_mounts use_smbmnt - - set smb_redir_0 "" - set smb_mounts "" - if {$use_smbmnt} { - set l2 [get_smb_redir] - set smb_redir_0 [lindex $l2 0] - set smb_redir_0 [string trim $smb_redir_0] - set smb_mounts [lindex $l2 1] - } -} - -proc mytmp {tmp} { - global is_windows mktemp env - - if {$is_windows} { - return $tmp - } - - if {! [info exists mktemp]} { - set mktemp "" - foreach dir {/bin /usr/bin /usr/local/bin} { - if [file exists "$dir/mktemp"] { - set mktemp "$dir/mktemp" - break - } - } - } - if {$mktemp != ""} { - set tmp2 "" - catch {set tmp2 [exec $mktemp "$tmp.XXXXXX"]} - if [file exists $tmp2] { - if [info exists env(DEBUG_MKTEMP)] { - puts stderr "mytmp: $tmp2" - } - return $tmp2 - } - } - catch {exec rm -f $tmp} - catch {file delete $tmp} - if [file exists $tmp] { - puts stderr "tmp file still exists: $tmp" - exit 1 - } - catch {exec touch $tmp} - catch {exec chmod 600 $tmp} - if [info exists env(DEBUG_MKTEMP)] { - puts stderr "mytmp: $tmp" - } - return $tmp -} - -proc darwin_terminal_cmd {{title ""} {cmd ""} {bg 0}} { - global darwin_terminal - - set tries "" - lappend tries "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal" - - if {! [info exists darwin_terminal]} { - foreach try $tries { - if [file exists $try] { - if [file executable $try] { - set darwin_terminal $try - break - } - } - } - if {! [info exists darwin_terminal]} { - set fh "" - catch {set fh [open "| find /Applications -type f -name Terminal" "r"]} - if {$fh != ""} { - while {[gets $fh line] > -1} { - if {! [file exists $line]} { - continue - } - if {[file isdirectory $line]} { - continue - } - if {! [regexp {/Terminal$} $line]} { - continue - } - if {! [file executable $line]} { - continue - } - set darwin_terminal $line - break - } - close $fh - } - } - } - if {! [info exists darwin_terminal]} { - raise . - tk_messageBox -type ok -icon error -message "Cannot find Darwin Terminal program." -title "Cannot find Terminal program" - mac_raise - return - } - - global darwin_terminal_cnt - set tmp /tmp/darwin_terminal_cmd.[tpid] - if {! [info exists darwin_terminal_cnt]} { - set darwin_terminal_cnt 0 - } - incr darwin_terminal_cnt - append tmp ".$darwin_terminal_cnt" - set tmp [mytmp $tmp] - - set fh "" - catch {set fh [open $tmp w 0755]} - catch {[exec chmod 755 $tmp]} - if {$fh == ""} { - raise . - tk_messageBox -type ok -icon error -message "Cannot open temporary file: $tmp" -title "Cannot open file" - mac_raise - return - } - global env - puts $fh "#!/bin/sh" - puts $fh "PATH=$env(PATH)" - puts $fh "export PATH" - puts $fh "tmp=$tmp" - puts $fh "sleep 1" - puts $fh {if [ "X$DDDBG" != "X" ]; then ps www; fi} - puts $fh {termpid=`ps www | grep -w Terminal | grep $tmp | grep -v grep | awk '{print $1}' | sort -n | tail -1`} - puts $fh {echo try-1: termpid=$termpid mypid=$$} - puts $fh {if [ "X$termpid" = "X" ]; then} - puts $fh { termpid=`ps www | grep -w Terminal | grep -v grep | awk '{print $1}' | sort -n | tail -1`} - puts $fh { echo try-2: termpid=$termpid mypid=$$} - puts $fh {fi} - puts $fh {if [ "X$termpid" = "X" ]; then} - puts $fh { termpid=`ps wwwwaux | grep -w Terminal | grep $tmp | grep -v grep | awk '{print $2}' | sort -n | tail -1`} - puts $fh { echo try-3: termpid=$termpid mypid=$$} - puts $fh {fi} - puts $fh {if [ "X$termpid" = "X" ]; then} - puts $fh { termpid=$$} - puts $fh { echo termpid-find-fail: termpid=$termpid mypid=$$} - puts $fh {fi} - puts $fh {trap "rm -f $tmp; kill -TERM $termpid; kill -TERM $mypid; kill -KILL $mypid; exit 0" 0 2 15} - puts $fh {osascript -e 'tell application "Terminal" to activate' >/dev/null 2>&1 &} - puts $fh "$cmd" - puts $fh "sleep 1" - puts $fh {rm -f $tmp} - puts $fh {kill -TERM $termpid} - puts $fh {kill -TERM $mypid} - puts $fh {kill -KILL $mypid} - puts $fh "exit 0" - close $fh - if {$bg} { - catch {exec $darwin_terminal $tmp &} - } else { - catch {exec $darwin_terminal $tmp} - } -} - -proc unix_terminal_cmd {{geometry "+100+100"} {title "xterm-command"} {cmd "echo test"} {bg 0} {xrm1 ""} {xrm2 ""} {xrm3 ""}} { - global uname env - if {$uname == "Darwin"} { - global env - set doX 0; - if {! $doX} { - darwin_terminal_cmd $title $cmd $bg - return - } - } - - global checked_for_xterm - if {![info exists checked_for_xterm]} { - set p "" - set r [catch {set p [exec /bin/sh -c {type xterm}]}] - set checked_for_xterm 1 - if {$r != 0} { - set p [exec /bin/sh -c {type xterm 2>&1; exit 0}] - set txt "Problem finding the 'xterm' command:\n\n$p\n\n" - append txt "Perhaps you need to install a package containing 'xterm' (Sigh...)\n\n" - fetch_dialog $txt "xterm" "xterm" 0 [line_count $txt] - update - after 1000 - catch {tkwait window .fetch} - update - } - } - - if [info exists env(SSVNC_XTERM_REPLACEMENT)] { - set tcmd $env(SSVNC_XTERM_REPLACEMENT) - if {$tcmd != ""} { - regsub -all {%GEOMETRY} $tcmd $geometry tcmd - regsub -all {%TITLE} $tcmd $title tcmd - - set tmp1 /tmp/xterm_replacement1.[tpid] - set tmp1 [mytmp $tmp1] - set fh1 "" - catch {set fh1 [open $tmp1 "w"]} - - set tmp2 /tmp/xterm_replacement2.[tpid] - set tmp2 [mytmp $tmp2] - set fh2 "" - catch {set fh2 [open $tmp2 "w"]} - if {$fh1 != "" && $fh2 != ""} { - puts $fh1 "#!/bin/sh"; - puts $fh1 "$cmd" - puts $fh1 "rm -f $tmp1" - close $fh1 - catch {exec chmod 755 $tmp1} - puts $fh2 "#!/bin/sh" - puts $fh2 "$tcmd $tmp1" - puts $fh2 "rm -f $tmp2" - close $fh2 - catch {exec chmod 755 $tmp2} - if {$bg} { - exec $tmp2 2>@stdout & - } else { - exec $tmp2 2>@stdout - } - return - } - catch {close $fh1} - catch {close $fh2} - } - } - - if {$bg} { - if {$xrm1 == ""} { - exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout & - } else { - exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout & - } - } else { - if {$xrm1 == ""} { - exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -e sh -c "$cmd" 2>@stdout - } else { - exec xterm -sb -sl 2000 -geometry "$geometry" -title "$title" -xrm "$xrm1" -xrm "$xrm2" -xrm "$xrm3" -e sh -c "$cmd" 2>@stdout - } - } -} - -proc xterm_center_geometry {} { - set sh [winfo screenheight .] - set sw [winfo screenwidth .] - set gw 500 - set gh 300 - set x [expr $sw/2 - $gw/2] - set y [expr $sh/2 - $gh/2] - if {$x < 0} { - set x 10 - } - if {$y < 0} { - set y 10 - } - - return "+$x+$y" -} - -proc smbmnt_wait {tee} { - if {$tee != ""} { - set start [clock seconds] - set cut 30 - while {1} { - set now [clock seconds] - if {$now > $start + $cut} { - break; - } - if [file exists $tee] { - set sz 0 - catch {set sz [file size $tee]} - if {$sz > 50} { - set cut 50 - } - } - set g "" - catch {set g [exec grep main-vnc-helper-finished $tee]} - if [regexp {main-vnc-helper-finished} $g] { - break - } - after 1000 - } - catch {file delete $tee} - } else { - global smb_su_mode - if {$smb_su_mode == "su"} { - after 15000 - } elseif {$smb_su_mode == "sudo"} { - after 10000 - } - } -} - -proc do_unix_pre {tag proxy hp pk_hp} { - global env smb_redir_0 use_smbmnt - global did_port_knock - - set setup_cmds [ugly_setup_scripts pre $tag] - set c "ss_vncviewer -ssh" - - if {$proxy == ""} { - set pxy $hp - regsub {:[0-9][0-9]*$} $pxy "" pxy - set c "$c -proxy '$pxy'" - } else { - set c "$c -proxy '$proxy'" - } - - if {$setup_cmds != ""} { - set env(SS_VNCVIEWER_SSH_CMD) "$setup_cmds sleep 10" - set env(SS_VNCVIEWER_SSH_ONLY) 1 - if {$smb_redir_0 != ""} { - set c "$c -sshargs '$smb_redir_0'" - } - - if {! [do_port_knock $pk_hp start]} { - return - } - set did_port_knock 1 - - if {$use_smbmnt} { - set title "SSL/SSH VNC Viewer $hp -- SMB MOUNTS" - } else { - set title "SSL/SSH VNC Viewer $hp -- Pre Commands" - } - - set tee "" - if {$use_smbmnt} { - set tee $env(SSVNC_HOME) - append tee "/.tee-etv$tag" - set fh "" - catch {set fh [open $tee "w"]} - if {$fh == ""} { - set tee "" - } else { - close $fh - set c "$c | tee $tee" - } - } - - unix_terminal_cmd "80x25+100+100" "$title" "set -xv; $c" 1 - - set env(SS_VNCVIEWER_SSH_CMD) "" - set env(SS_VNCVIEWER_SSH_ONLY) "" - - if {$use_smbmnt} { - smbmnt_wait $tee - } else { - after 2000 - } - } -} -proc init_vncdisplay {} { - global vncdisplay vncproxy remote_ssh_cmd - set vncdisplay [string trim $vncdisplay] - - if {$vncdisplay == ""} { - set vncproxy "" - set remote_ssh_cmd "" - return - } - - set hpnew [get_ssh_hp $vncdisplay] - set proxy [get_ssh_proxy $vncdisplay] - set sshcmd [get_ssh_cmd $vncdisplay] - - set vncdisplay $hpnew - set vncproxy $proxy - set remote_ssh_cmd $sshcmd - - global ssh_only ts_only - if {$sshcmd != "" || $ssh_only || $ts_only} { - global use_ssl use_ssh use_sshssl - set use_ssl 0 - if {! $use_ssh && ! $use_sshssl} { - set use_ssh 1 - } - } - # ssl_ssh_adjust will be called. -} - -proc get_vncdisplay {} { - global vncdisplay vncproxy remote_ssh_cmd - set vncdisplay [string trim $vncdisplay] - - set t $vncdisplay - regsub {[ \t]*cmd=.*$} $t "" t - set t [string trim $t] - - set str "" - if [regexp {[ \t]} $t] { - set str $t - } else { - if {$vncproxy != "" && $t == ""} { - set str "--nohost-- $vncproxy" - } else { - set str "$t $vncproxy" - } - } - if [regexp {cmd=.*$} $vncdisplay match] { - if {$str == ""} { - set str "--nohost--" - } - set str "$str $match" - } else { - if {$remote_ssh_cmd != ""} { - if {$str == ""} { - set str "--nohost--" - } - set str "$str cmd=$remote_ssh_cmd" - } - } - set str [string trim $str] - return $str -} - -proc port_knock_only {hp {mode KNOCK}} { - if {$hp == ""} { - set hp [get_vncdisplay] - if {$hp == ""} { - mesg "No host port found" - bell - return - } - } - set hpnew [get_ssh_hp $hp] - set proxy [get_ssh_proxy $hp] - set sshcmd [get_ssh_cmd $hp] - set hp $hpnew - - set pk_hp "" - if {$proxy != ""} { - set pk_hp $proxy - } - if {$pk_hp == ""} { - set pk_hp $hp - } - if {$mode == "KNOCK"} { - do_port_knock $pk_hp start - } elseif {$mode == "FINISH"} { - do_port_knock $pk_hp finish - } -} - -proc direct_connect_msg {} { - set msg "" - global env - globalize - if {$use_sshssl} { - append msg " - SSH + SSL tunnelling\n" - } elseif {$use_ssh} { - append msg " - SSH tunnelling\n" - } else { - append msg " - SSL tunnelling\n" - } - if [info exists env(SSVNC_NO_ENC_WARN)] { - set msg "" - } - if {$use_smbmnt} { - append msg " - SMB Mount Port Redirection\n" - } - if {$use_sound} { - append msg " - ESD Sound Port Redirection\n" - } - if {$use_cups} { - append msg " - CUPS Port Redirection\n" - } - if {$additional_port_redirs} { - append msg " - Additional Port Redirections\n" - } - if {$mycert != "" || $svcert != "" || $crtdir != ""} { - append msg " - SSL certificate authentication\n" - } - if {$msg != ""} { - set msg "Direct connect via vnc://hostname\nThe following options will be disabled:\n\n$msg" - raise . - tk_messageBox -type ok -icon info -message $msg - } -} - -proc fetch_cert {save} { - global env vncdisplay is_windows - set hp [get_vncdisplay] - - global vencrypt_detected - set vencrypt_detected "" - - global use_listen - if {$use_listen} { - if {$is_windows} { - mesg "Fetch Cert not enabled for Reverse Connections" - bell - catch {raise .} - mac_raise - return - } - toplev .fcr - global help_font - wm title .fcr "Fetch Cert for Reverse Connections" - global fcr_result - set fcr_result 0 - eval text .fcr.t -width 55 -height 17 $help_font - .fcr.t insert end { - In Reverse VNC Connections (-LISTEN) mode, the - Fetch Cert operation requires that the Remote - VNC Server makes an initial connection NOW so - we can collect its SSL Certificate. Note that - this method does not work for VeNCrypt servers. - (If there are problems Fetching, one can always - copy and import the Cert file manually.) - - Do you want to Continue with this operation? - If so, press "Continue" and Then instruct the - remote VNC Server to make a Reverse Connection - to us. - - Otherwise, press "Cancel" to cancel the Fetch - Cert operation. -} - - button .fcr.cancel -text Cancel -command {set fcr_result 0; destroy .fcr} - button .fcr.continue -text Continue -command {set fcr_result 1; destroy .fcr} - button .fcr.continu2 -text Continue -command {set fcr_result 1; destroy .fcr} - global uname - if {$uname == "Darwin"} { - pack .fcr.t .fcr.continu2 .fcr.continue .fcr.cancel -side top -fill x - - } else { - pack .fcr.t .fcr.continue .fcr.cancel -side top -fill x - } - center_win .fcr - - tkwait window .fcr - update - after 50 - - if {$fcr_result != 1} { - return - } - update idletasks - after 50 - } - - regsub {[ ]*cmd=.*$} $hp "" tt - if {[regexp {^[ ]*$} $tt]} { - mesg "No host:disp supplied." - bell - catch {raise .} - mac_raise - return - } - if {[regexp -- {--nohost--} $tt]} { - mesg "No host:disp supplied." - bell - catch {raise .} - mac_raise - return - } - if {! [regexp ":" $hp]} { - if {! [regexp {cmd=} $hp]} { - append hp ":0" - } - } - set hpnew [get_ssh_hp $hp] - set proxy [get_ssh_proxy $hp] - - - set pstr 1 - mesg "Fetching $hpnew Cert..." - global cert_text - set cert_text "" - .f4.getcert configure -state disabled - update - if {! $is_windows} { - catch {set cert_text [fetch_cert_unix $hp]} - } else { - set cert_text [fetch_cert_windows $hp] - } - - if [info exists env(CERTDBG)] {puts "\nFetch-0-\n$cert_text"} - - set vencrypt 0 - set anondh 0 - if {![regexp {BEGIN CERTIFICATE} $cert_text]} { - if [regexp {CONNECTED} $cert_text] { - set m 0 - if {![regexp -nocase {GET_SERVER_HELLO} $cert_text]} { - set m 1 - } - if [regexp -nocase -line {GET_SERVER_HELLO.*unknown protocol} $cert_text] { - set m 1 - } - if {![regexp -nocase {show_cert: SSL_connect failed} $cert_text]} { - set m 1 - } - if {!$m && $is_windows} { - if [regexp -nocase {write:errno} $cert_text] { - if [regexp -nocase {no peer certificate} $cert_text] { - set m 1 - } - } - } - if {$m} { - # suspect VeNCrypt or ANONTLS plaintext RFB - set cert_text "" - set vencrypt 1 - incr pstr - mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh" - if {! $is_windows} { - catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]} - } else { - after 600 - catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]} - } - if [info exists env(CERTDBG)] {puts "\nFetch-1-\n$cert_text"} - } - } - } - if {![regexp {BEGIN CERTIFICATE} $cert_text]} { - if [regexp {CONNECTED} $cert_text] { - set m 0 - if [regexp -nocase -line {error.*handshake failure} $cert_text] { - set m 1 - } - if [regexp -nocase -line {error.*unknown protocol} $cert_text] { - set m 1 - } - if {![regexp -nocase {show_cert: SSL_connect failed} $cert_text]} { - set m 1 - } - if {!$m && $is_windows} { - if [regexp -nocase {no peer certificate} $cert_text] { - set m 1 - } - } - if {$m} { - # suspect Anonymous Diffie Hellman - set cert_text "" - set anondh 1 - incr pstr - mesg "#${pstr} Fetching $hpnew Cert... $vencrypt/$anondh" - if {! $is_windows} { - catch {set cert_text [fetch_cert_unix $hp $vencrypt $anondh]} - } else { - after 600 - catch {set cert_text [fetch_cert_windows $hp $vencrypt $anondh]} - } - if [info exists env(CERTDBG)] {puts "\nFetch-2-\n$cert_text"} - } - } - } - if {![regexp {BEGIN CERTIFICATE} $cert_text]} { - if [regexp {CONNECTED} $cert_text] { - if {[regexp -nocase -line {cipher.*ADH} $cert_text]} { - # it is Anonymous Diffie Hellman - mesg "WARNING: Anonymous Diffie Hellman Server detected (NO CERT)" - after 300 - .f4.getcert configure -state normal - return $cert_text - } else { - global vencrypt_detected - set vencrypt_detected "" - } - } - } - - global vencrypt_detected server_vencrypt - if {$vencrypt_detected != "" && !$server_vencrypt} { - mesg "VeNCrypt or ANONTLS server detected." - after 600 - } - - .f4.getcert configure -state normal - mesg "Fetched $hpnew Cert" - - set n 47 - set ok 1 - if {$cert_text == ""} { - set cert_text "An Error occurred in fetching SSL Certificate from $hp" - set ok 0 - set n 4 - } elseif {! [regexp {BEGIN CERTIFICATE} $cert_text]} { - set cert_text "An Error occurred in fetching $hp\n\n$cert_text" - set n [line_count $cert_text 1] - set ok 0 - } else { - if [regexp -- {-----BEGIN SSL SESSION PARAMETERS-----} $cert_text] { - set new "" - set off 0 - foreach line [split $cert_text "\n"] { - if [regexp -- {RFB 00} $line] { - continue - } - if [regexp -- {Using default temp} $line] { - continue - } - if [regexp -- {-----BEGIN SSL SESSION PARAMETERS-----} $line] { - set off 1 - } - if [regexp -- {-----END SSL SESSION PARAMETERS-----} $line] { - set off 0 - continue - } - if {$off} { - continue; - } - append new "$line\n" - } - if [regexp -- {-----BEGIN CERTIFICATE-----} $new] { - set cert_text $new - } - } - set text "" - set on 0 - set subject "" - set curr_subject "" - set chain_n -1 - set chain(__empty__) "" - foreach line [split $cert_text "\n"] { - if [regexp -- {-----BEGIN CERTIFICATE-----} $line] { - incr on - } - if {$chain_n < -1} { - ; - } elseif [regexp {^ *([0-9]) *s:(.*/[A-Z][A-Z]*=.*$)} $line m cn sb] { - set cn [string trim $cn] - set sb [string trim $sb] - #puts cn=$cn - #puts sb=$sb - if {$subject == ""} { - set subject $sb - } - if {$cn > $chain_n} { - set chain_n $cn - set curr_subject $sb - } else { - set chain_n -2 - } - } elseif [regexp {^ *i:(.*/[A-Z][A-Z]*=.*$)} $line m is] { - set is [string trim $is] - #puts is=$is - if {$curr_subject != ""} { - set chain($curr_subject) $is - } - } - if {$on != 1} { - continue; - } - append text "$line\n" - if [regexp -- {-----END CERTIFICATE-----} $line] { - set on 2 - } - } - set chain_str "subject: not-known\n" - set curr_subject $subject - set self_signed 0 - set top_issuer "" - for {set i 0} {$i < 10} {incr i} { - if {$curr_subject != ""} { - if {$i == 0} { - set chain_str "- subject: $curr_subject\n\n" - } else { - set chain_str "${chain_str}- issuer$i: $curr_subject\n\n" - set top_issuer $curr_subject; - } - if {![info exists chain($curr_subject)]} { - break - } elseif {$chain($curr_subject) == ""} { - break - } elseif {$curr_subject == $chain($curr_subject)} { - set j [expr $i + 1] - set chain_str "${chain_str}- issuer$j: $curr_subject\n\n" - set top_issuer $curr_subject; - if {$i == 0} { - set self_signed 1 - } - break; - } - set curr_subject $chain($curr_subject) - } - } - set chain_str "${chain_str}INFO: SELF_SIGNED=$self_signed\n\n" - if {$self_signed} { - set chain_str "${chain_str}INFO: Certificate is Self-Signed.\n" - set chain_str "${chain_str}INFO: It will successfully authenticate when used as a ServerCert or Accepted-Cert.\n" - set chain_str "${chain_str}INFO: Be sure to check carefully that you trust this certificate before saving it.\n" - } else { - set chain_str "${chain_str}INFO: Certificate is signed by a Certificate Authority (CA).\n" - set chain_str "${chain_str}INFO: It *WILL NOT* successfully authenticate when used as a ServerCert or Accepted-Cert.\n" - set chain_str "${chain_str}INFO: You need to Obtain and Save the CA's Certificate (issuer) instead" - if {$top_issuer != ""} { - set chain_str "${chain_str}:\nINFO: CA: $top_issuer\n" - } else { - set chain_str "${chain_str}.\n" - } - } - #puts "\n$chain_str\n" - - global is_windows - set tmp "/tmp/cert.hsh.[tpid]" - set tmp [mytmp $tmp] - if {$is_windows} { - # VF - set tmp cert.hsh - } - set fh "" - catch {set fh [open $tmp "w"]} - if {$fh != ""} { - puts $fh $text - close $fh - set info "" - catch {set info [get_x509_info $tmp]} - catch {file delete $tmp} - if [regexp -nocase {MD5 Finger[^\n]*} $info mvar] { - set cert_text "$mvar\n\n$cert_text" - } - if [regexp -nocase {SHA. Finger[^\n]*} $info mvar] { - set cert_text "$mvar\n\n$cert_text" - } - set cert_text "$cert_text\n\n----------------------------------\nOutput of openssl x509 -text -fingerprint:\n\n$info" - } - set cert_text "==== SSL Certificate from $hp ====\n\n$chain_str\n$cert_text" - } - - if {! $save} { - return $cert_text - } - - fetch_dialog $cert_text $hp $hpnew $ok $n -} - -proc skip_non_self_signed {w hp} { - set msg "Certificate from $hp is not Self-Signed, it was signed by a Certificate Authority (CA). Saving it does not make sense because it cannot be used to authenticate anything. You need to Obtain and Save the CA Certificate instead. Save it anyway?" - set reply [tk_messageBox -type okcancel -default cancel -parent $w -icon warning -message $msg -title "CA Signed Certificate"] - if {$reply == "cancel"} { - return 1 - } else { - return 0 - } -} - -proc fetch_dialog {cert_text hp hpnew ok n} { - toplev .fetch - - if [small_height] { - set n 28 - } - - scroll_text_dismiss .fetch.f 90 $n - - if {$ok} { - set ss 0 - if [regexp {INFO: SELF_SIGNED=1} $cert_text] { - button .fetch.save -text Save -command "destroy .fetch; save_cert {$hpnew}" - set ss 1 - } else { - button .fetch.save -text Save -command "if \[skip_non_self_signed .fetch {$hpnew}\] {return} else {destroy .fetch; save_cert {$hpnew}}" - set ss 0 - } - button .fetch.help -text Help -command "help_fetch_cert $ss" - pack .fetch.help .fetch.save -side bottom -fill x - .fetch.d configure -text "Cancel" - } - - center_win .fetch - wm title .fetch "$hp Certificate" - - .fetch.f.t insert end $cert_text - jiggle_text .fetch.f.t -} - - -proc host_part {hp} { - regsub {^ *} $hp "" hp - regsub { .*$} $hp "" hp - if [regexp {^[0-9][0-9]*$} $hp] { - return "" - } - set h $hp - regsub {:[0-9][0-9]*$} $hp "" h - return $h -} - -proc port_part {hp} { - regsub { .*$} $hp "" hp - set p "" - if [regexp {:([0-9][0-9]*)$} $hp m val] { - set p $val - } - return $p -} - -proc get_vencrypt_proxy {hpnew} { - if [regexp -nocase {^vnc://} $hpnew] { - return "" - } - set hpnew [get_ssh_hp $hpnew] - regsub -nocase {^[a-z0-9+]*://} $hpnew "" hpnew - set h [host_part $hpnew] - set p [port_part $hpnew] - - if {$p == ""} { - # might not matter, i.e. SSH+SSL only... - set p 5900 - } - set hp2 $h - if {$p < 0} { - set hp2 "$hp2:[expr - $p]" - } elseif {$p < 200} { - set hp2 "$hp2:[expr $p + 5900]" - } else { - set hp2 "$hp2:$p" - } - return "vencrypt://$hp2" -} - -proc fetch_cert_unix {hp {vencrypt 0} {anondh 0}} { - global use_listen - - set hpnew [get_ssh_hp $hp] - set proxy [get_ssh_proxy $hp] - - if {$vencrypt} { - global vencrypt_detected - set vencrypt_detected [get_vencrypt_proxy $hpnew] - if {$proxy != ""} { - set proxy "$proxy,$vencrypt_detected" - } else { - set proxy $vencrypt_detected - } - } - - set cmd [list ss_vncviewer] - if {$anondh} { - lappend cmd "-anondh" - } - if {$proxy != ""} { - lappend cmd "-proxy" - lappend cmd $proxy - } - if {$use_listen} { - lappend cmd "-listen" - } - lappend cmd "-showcert" - lappend cmd $hpnew - - if {$proxy != ""} { - lappend cmd "2>/dev/null" - } - global env - if [info exists env(CERTDBG)] {puts "\nFetch-cmd: $cmd"} - set env(SSVNC_SHOWCERT_EXIT_0) 1 - - return [eval exec $cmd] -} - -proc win_nslookup {host} { - global win_nslookup_cache - if [info exists win_nslookup_cache($host)] { - return $win_nslookup_cache($host) - } - if [regexp -nocase {[^a-z0-9:._-]} $host] { - set win_nslookup_cache($host) "invalid" - return $win_nslookup_cache($host) - } - if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $host] { - set win_nslookup_cache($host) $host - return $win_nslookup_cache($host) - } - if [regexp -nocase {^[a-f0-9]*:[a-f0-9:]*:[a-f0-9:]*$} $host] { - set win_nslookup_cache($host) $host - return $win_nslookup_cache($host) - } - set nsout "" - catch {set nsout [exec nslookup $host]} - if {$nsout == "" || [regexp -nocase {server failed} $nsout]} { - after 250 - set nsout "" - catch {set nsout [exec nslookup $host]} - } - if {$nsout == "" || [regexp -nocase {server failed} $nsout]} { - set win_nslookup_cache($host) "unknown" - return $win_nslookup_cache($host) - } - regsub -all {Server:[^\n]*\nAddress:[^\n]*} $nsout "" nsout - regsub {^.*Name:} $nsout "" nsout - if [regexp {Address:[ \t]*([^\n]+)} $nsout mv addr] { - set addr [string trim $addr] - if {$addr != ""} { - set win_nslookup_cache($host) $addr - return $win_nslookup_cache($host) - } - } - set win_nslookup_cache($host) "unknown" - return $win_nslookup_cache($host) -} - -proc win_ipv4 {host} { - global win_localhost - set ip [win_nslookup $host]; - if [regexp {^[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*$} $ip] { - return 1 - } - return 0 -} - -proc ipv6_proxy {proxy host port} { - global is_windows win_localhost have_ipv6 - - if {!$have_ipv6} { - return [list $proxy $host $port ""] - } elseif {!$is_windows} { - return [list $proxy $host $port ""] - } else { - set h0 "" - set p0 "" - set port3 "" - set ipv6_pid "" - set proxy0 $proxy - if {$proxy == ""} { - if [win_ipv4 $host] { - return [list $proxy $host $port ""] - } - set port3 [rand_port] - set h0 $host - set p0 $port - set host $win_localhost - set port $port3 - } else { - set parts [split $proxy ","] - set n [llength $parts] - for {set i 0} {$i < $n} {incr i} { - set part [lindex $parts $i] - set prefix "" - set repeater 0 - regexp -nocase {^[a-z0-9+]*://} $part prefix - regsub -nocase {^[a-z0-9+]*://} $part "" part - if [regexp {^repeater://} $prefix] { - regsub {\+.*$} $part "" part - if {![regexp {:([0-9][0-9]*)$} $part]} { - set part "$part:5900" - } - } - set modit 0 - set h1 "" - set p1 "" - if [regexp {^(.*):([0-9][0-9]*)$} $part mvar h1 p1] { - if {$h1 == "localhost" || $h1 == $win_localhost} { - continue - } elseif [win_ipv4 $h1] { - break - } - set modit 1 - } else { - break - } - if {$modit} { - set port3 [rand_port] - set h0 $h1 - set p0 $p1 - lset parts $i "$prefix$win_localhost:$port3" - break - } - } - if {$h0 != "" && $p0 != "" && $port3 != ""} { - set proxy [join $parts ","] - #mesg "Reset proxy: $proxy"; after 3000 - } - } - if {$h0 != "" && $p0 != "" && $port3 != ""} { - mesg "Starting IPV6 helper on port $port3 ..." - set ipv6_pid [exec relay6.exe $port3 "$h0" "$p0" /b:$win_localhost &] - after 400 - #mesg "r6 $port3 $h0 $p0"; after 3000 - } - return [list $proxy $host $port $ipv6_pid] - } -} - -proc fetch_cert_windows {hp {vencrypt 0} {anondh 0}} { - global have_ipv6 - - regsub {^vnc.*://} $hp "" hp - - set hpnew [get_ssh_hp $hp] - set proxy [get_ssh_proxy $hp] - - if {$vencrypt} { - global vencrypt_detected - set vencrypt_detected [get_vencrypt_proxy $hpnew] - if {$proxy != ""} { - set proxy "$proxy,$vencrypt_detected" - } else { - set proxy $vencrypt_detected - } - } - - set host [host_part $hpnew] - - global win_localhost - - if {$host == ""} { - set host $win_localhost - } - - if [regexp {^.*@} $host match] { - mesg "Trimming \"$match\" from hostname" - regsub {^.*@} $host "" host - } - - set disp [port_part $hpnew] - - if {[regexp {^-[0-9][0-9]*$} $disp]} { - ; - } elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} { - set disp 0 - } - if {$disp < 0} { - set port [expr "- $disp"] - } elseif {$disp < 200} { - set port [expr "$disp + 5900"] - } else { - set port $disp - } - - set ipv6_pid "" - if {$have_ipv6} { - set res [ipv6_proxy $proxy $host $port] - set proxy [lindex $res 0] - set host [lindex $res 1] - set port [lindex $res 2] - set ipv6_pid [lindex $res 3] - } - - if {$proxy != ""} { - global env - - set port2 [rand_port] - - set sp "" - if [info exists env(SSVNC_PROXY)] { - set sp $env(SSVNC_PROXY) - } - set sl "" - if [info exists env(SSVNC_LISTEN)] { - set sl $env(SSVNC_LISTEN) - } - set sd "" - if [info exists env(SSVNC_DEST)] { - set sd $env(SSVNC_DEST) - } - - set env(SSVNC_PROXY) $proxy - set env(SSVNC_LISTEN) $port2 - set env(SSVNC_DEST) "$host:$port" - - set host $win_localhost - set port $port2 - - mesg "Starting Proxy TCP helper on port $port2 ..." - after 300 - # fetch cert br case: - set proxy_pid [exec "connect_br.exe" &] - - if {$sp == ""} { - catch { unset env(SSVNC_PROXY) } - } else { - set env(SSVNC_PROXY) $sp - } - if {$sl == ""} { - catch { unset env(SSVNC_LISTEN) } - } else { - set env(SSVNC_LISTEN) $sl - } - if {$sd == ""} { - catch { unset env(SSVNC_DEST) } - } else { - set env(SSVNC_DEST) $sd - } - } - - set ossl [get_openssl] - update - # VF - set tin tmpin.txt - set tou tmpout.txt - set fh "" - catch {set fh [open $tin "w"]} - if {$fh != ""} { - puts $fh "Q" - puts $fh "GET /WOMBAT HTTP/1.1\r\nHost: wombat.com\r\n\r\n\r\n" - close $fh - } - - if {1} { - set ph "" - if {$anondh} { - set ph [open "| $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH < $tin 2>NUL" "r"] - } else { - set ph [open "| $ossl s_client -prexit -connect $host:$port < $tin 2>NUL" "r"] - } - - set text "" - if {$ph != ""} { - set pids [pid $ph] - set got 0 - while {[gets $ph line] > -1} { - append text "$line\n" - if [regexp {END CERT} $line] { - set got 1 - } - if {$anondh && [regexp -nocase {cipher.*ADH} $line]} { - set got 1 - } - if {$got && [regexp {^ *Verify return code} $line]} { - break - } - if [regexp {^RFB } $line] { - break - } - if [regexp {^DONE} $line] { - break - } - } - foreach pid $pids { - winkill $pid - } - if {$ipv6_pid != ""} { - winkill $ipv6_pid - } - - catch {close $ph} - catch {file delete $tin $tou} - return $text - } - } else { - set pids "" - - if {1} { - if {$anondh} { - set ph2 [open "| $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH > $tou 2>NUL" "w"] - } else { - set ph2 [open "| $ossl s_client -prexit -connect $host:$port > $tou 2>NUL" "w"] - } - set pids [pid $ph2] - after 500 - for {set i 0} {$i < 128} {incr i} { - puts $ph2 "Q" - } - catch {close $ph2} - } else { - if {$anondh} { - set pids [exec $ossl s_client -prexit -connect $host:$port -cipher ALL:RC4+RSA:+SSLv2:@STRENGTH < $tin >& $tou &] - } else { - set pids [exec $ossl s_client -prexit -connect $host:$port < $tin >& $tou &] - } - } - - for {set i 0} {$i < 10} {incr i} { - after 500 - set got 0 - set ph "" - catch {set ph [open $tou "r"]} - if {$ph != ""} { - while {[gets $ph line] > -1} { - if [regexp {END CERT} $line] { - set got 1 - break - } - } - close $ph - } - if {$got} { - break - } - } - foreach pid $pids { - winkill $pid - } - after 500 - set ph "" - catch {set ph [open $tou "r"]} - } - set text "" - if {$ph != ""} { - while {[gets $ph line] > -1} { - append text "$line\n" - } - close $ph - } - catch {file delete $tin $tou} - if {$ipv6_pid != ""} { - winkill $ipv6_pid - } - return $text -} - -proc check_accepted_certs {{probe_only 0}} { - global cert_text always_verify_ssl - global skip_verify_accepted_certs use_listen - global ultra_dsm env - global server_vencrypt server_anondh no_probe_vencrypt - - if {! $always_verify_ssl} { - set skip_verify_accepted_certs 1 - if {$server_vencrypt} { - return 1 - } - if {$no_probe_vencrypt} { - return 1 - } - } - if {$server_anondh} { - mesg "WARNING: Anonymous Diffie Hellman (SKIPPING CERT CHECK)" - after 1000 - set skip_verify_accepted_certs 1 - return 1 - } - if {$ultra_dsm} { - return 1; - } - if {$use_listen} { - return 1; - } - - global anon_dh_detected - set anon_dh_detected 0 - - set cert_text [fetch_cert 0] - - set mvar "" - if {[regexp -nocase -line {cipher.*ADH} $cert_text mvar]} { - - if [info exists env(CERTDBG)] {puts "\nFetch-MSG-\n$cert_text"} - if [info exists env(CERTDBG)] {puts "\nBEGIN_MVAR: $mvar\nEND_MVAR\n"} - - set msg "Anonymous Diffie-Hellman server detected. There will be encryption, but no SSL/TLS authentication. Continue?" - set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title "Anonymous Diffie-Hellman Detected"] - set anon_dh_detected 1 - if {$reply == "cancel"} { - return 0 - } else { - global skip_verify_accepted_certs - set skip_verify_accepted_certs 1 - return 1 - } - } - - if {$probe_only} { - return 1 - } - if {! $always_verify_ssl} { - return 1 - } - - set from "" - set fingerprint "" - set fingerline "" - set self_signed 1 - set subject_issuer "" - set subject "" - set issuer "" - - set i 0 - foreach line [split $cert_text "\n"] { - incr i - if {$i > 50} { - break - } - if [regexp {^- subject: *(.*)$} $line m val] { - set val [string trim $val] - set subject_issuer "${subject_issuer}subject:$val\n" - set subject $val - } - if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] { - set val [string trim $val] - set subject_issuer "${subject_issuer}$is:$val\n" - set issuer $val - } - if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] { - set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n" - } - if [regexp {^depth=} $line] { - break - } - if [regexp {^verify } $line] { - break - } - if [regexp {^CONNECTED} $line] { - break - } - if [regexp {^Certificate chain} $line] { - break - } - if [regexp {^==== SSL Certificate from (.*) ====} $line mv str] { - set from [string trim $str] - } - if [regexp -nocase {Fingerprint=(.*)} $line mv str] { - set fingerline $line - set fingerprint [string trim $str] - } - if [regexp -nocase {^INFO: SELF_SIGNED=([01])} $line mv str] { - set self_signed $str - } - } - - set fingerprint [string tolower $fingerprint] - regsub -all {:} $fingerprint "-" fingerprint - regsub -all {[\\/=]} $fingerprint "_" fingerprint - - set from [string tolower $from] - regsub -all {[\[\]]} $from "" from - regsub -all {^[+a-z]*://} $from "" from - regsub -all {:} $from "-" from - regsub -all {[\\/=]} $from "_" from - regsub -all {[ ]} $from "_" from - - if {$from == "" || $fingerprint == ""} { - bell - catch {raise .; update} - mesg "WARNING: Error fetching Server Cert" - after 500 - set hp [get_vncdisplay] - set n [line_count $cert_text 1] - fetch_dialog $cert_text $hp $hp 0 $n - update - after 2000 - return 0 - } - - set hp [get_vncdisplay] - - set adir [get_idir_certs ""] - catch {file mkdir $adir} - set adir "$adir/accepted" - catch {file mkdir $adir} - - set crt "$adir/$from=$fingerprint.crt" - - if [file exists $crt] { - if {$self_signed} { - mesg "OK: Certificate found in ACCEPTED_CERTS" - after 750 - return 1 - } - } - - set cnt 0 - foreach f [glob -nocomplain -directory $adir "*$fingerprint*.crt"] { - mesg "CERT: $f" - after 150 - if {$self_signed} { - incr cnt - } - } - - set oth 0 - set others [list] - foreach f [glob -nocomplain -directory $adir "*$from*.crt"] { - if {$f == $crt} { - continue - } - set fb [file tail $f] - mesg "OTHER CERT: $fb" - if {$cnt > 0} { - after 400 - } else { - bell - after 800 - } - lappend others $f - incr oth - } - - foreach f [glob -nocomplain -directory $adir "*.crt"] { - if {$f == $crt} { - continue - } - set saw 0 - foreach o $others { - if {$f == $o} { - set saw 1 - break - } - } - if {$saw} { - continue - } - set fh [open $f "r"] - if {$fh == ""} { - continue - } - set same 0 - set sub "" - set iss "" - set isn -1; - while {[gets $fh line] > -1} { - if [regexp {^Host-Display: (.*)$} $line mv hd] { - if {$hd == $hp || $hd == $from} { - set same 1 - } - } - if [regexp {^subject:(.*)$} $line mv val] { - set sub $val - } - if [regexp {^issue([0-9][0-9]*):(.*)$} $line mv in val] { - if {$in > $isn} { - set isn $in - set iss $val - } - } - } - close $fh; - - if {!$self_signed} { - if {$sub == ""} { - set ossl [get_openssl] - set si_txt [exec $ossl x509 -subject -issuer -noout -in $f] - foreach line [split $si_txt "\n"] { - if [regexp -nocase {^subject= *(.*)$} $line mv str] { - set str [string trim $str] - if {$str != ""} { - set sub $str - } - } elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] { - set str [string trim $str] - if {$iss != ""} { - set iss $str - } - } - } - } - if {$issuer != "" && $sub != ""} { - global env - if [info exists env(CERTDBG)] { - puts "f: $f" - puts "s: $sub" - puts "i: $issuer" - puts "===================" - } - if {$issuer == $sub} { - set fb [file tail $f] - mesg "Certificate Authority (CA) CERT: $fb" - incr cnt - after 500 - } - } - continue - } - - if {! $same} { - continue - } - - set fb [file tail $f] - mesg "OTHER CERT: $fb" - if {$cnt > 0} { - after 400 - } else { - bell - after 800 - } - lappend others $f - incr oth - } - - if {$cnt > 0} { - if {$self_signed} { - mesg "OK: Server Certificate found in ACCEPTED_CERTS" - after 400 - } else { - mesg "OK: CA Certificate found in ACCEPTED_CERTS" - after 800 - } - return 1 - } - - set hp2 [get_vncdisplay] - set msg " - The Self-Signed SSL Certificate from host: - - $hp2 - - Fingerprint: $fingerprint - - Subject: $subject - - is not present in the 'Accepted Certs' directory: - - $adir -%WARN - You will need to verify on your own that this is a certificate from a - VNC server that you trust (e.g. by checking the fingerprint with that - sent to you by the server administrator). - - - THE QUESTION: Do you want this certificate to be saved in the Accepted Certs - directory and then used to SSL authenticate VNC servers? - - - By clicking 'Inspect and maybe Save Cert' you will be given the opportunity - to inspect the certificate before deciding to save it or not. -" - - set msg_bottom " - Choose 'Ignore Cert for One Connection' to connect a single time to the - server with *NO* certificate authentication. You will see this dialog again - the next time you connect to the same server. - - Choose 'Continue as though I saved it' to launch stunnel and the VNC viewer. - Do this if you know the correct Certificate is in the 'Accepted Certs' - directory. If it is not, stunnel will fail and report 'VERIFY ERROR:...' - - Choose 'Cancel' to not connect to the VNC Server at all. -" - - set msg_ca " - The CA-signed SSL Certificate from host: - - $hp2 - - Fingerprint: $fingerprint - - Subject: $subject - - Issuer: $issuer - - is signed by a Certificate Authority (CA) (the 'Issuer' above.) - - However, the certificate of the CA 'Issuer' is not present in the - 'Accepted Certs' directory: - - $adir - - You will need to obtain the certificate of the CA 'Issuer' via some means - (perhaps ask the VNC server administrator for it.) Then, after you have - verified that the CA certificate is one that you trust, import the - certificate via Certs -> Import Certificate. Be sure to select to also - save it to the Accepted Certs directory so it will automatically be used. -" - set msg "$msg$msg_bottom" - set msg_ca "$msg_ca$msg_bottom" - - if {!$self_signed} { - set msg $msg_ca - } - - if {$oth == 0} { - regsub {%WARN} $msg "" msg - } else { - set warn "" - set wfp "" - if {$oth == 1} { - set warn " -**WARNING** The Following Cert was previously saved FOR THE SAME HOST-DISPLAY: - -" - set wfp "BUT WITH A DIFFERENT FINGERPRINT." - - } else { - set warn " -**WARNING** The Following Certs were previously saved FOR THE SAME HOST-DISPLAY: - -" - set wfp "BUT WITH DIFFERENT FINGERPRINTS." - } - - foreach o $others { - set fb [file tail $o] - set warn "$warn $fb\n" - } - set warn "$warn\n $wfp\n" - set warn "$warn\n This could be a Man-In-The-Middle attack, or simply that the Server changed" - set warn "$warn\n its Certificate. *PLEASE CHECK* before proceeding!\n" - regsub {%WARN} $msg $warn msg - bell - } - - set n 0 - foreach l [split $msg "\n"] { - incr n - } - if {!$self_signed} { - set n [expr $n + 2] - } else { - set n [expr $n + 1] - } - if [small_height] { - if {$n > 26} { - set n 26 - } - } - toplev .acert - scroll_text .acert.f 83 $n - - button .acert.inspect -text "Inspect and maybe Save Cert ..." -command "destroy .acert; set accept_cert_dialog 1" - button .acert.accept -text "Ignore Cert for One Connection " -command "destroy .acert; set accept_cert_dialog 2" - button .acert.continue -text "Continue as though I saved it " -command "destroy .acert; set accept_cert_dialog 3" - button .acert.cancel -text "Cancel" -command "destroy .acert; set accept_cert_dialog 0" - - wm title .acert "Unrecognized SSL Cert!" - - .acert.f.t insert end $msg - - pack .acert.cancel .acert.continue .acert.accept .acert.inspect -side bottom -fill x - pack .acert.f -side top -fill both -expand 1 - - if {! $self_signed} { - catch {.acert.inspect configure -state disabled} - } - - center_win .acert - - global accept_cert_dialog - set accept_cert_dialog "" - - jiggle_text .acert.f.t - - tkwait window .acert - - if {$accept_cert_dialog == 2} { - set skip_verify_accepted_certs 1 - return 1 - } - if {$accept_cert_dialog == 3} { - return 1 - } - if {$accept_cert_dialog != 1} { - return 0 - } - - global accepted_cert_dialog_in_progress - set accepted_cert_dialog_in_progress 1 - - global fetch_cert_filename - set fetch_cert_filename $crt - - global do_save_saved_it - set do_save_saved_it 0 - global do_save_saved_hash_it - set do_save_saved_hash_it 0 - - fetch_dialog $cert_text $hp $hp 1 47 - update; after 150 - - catch {tkwait window .fetch} - update; after 250 - catch {tkwait window .scrt} - update; after 250 - if [winfo exists .scrt] { - catch {tkwait window .scrt} - } - - set fetch_cert_filename "" - set accepted_cert_dialog_in_progress 0 - - if {!$do_save_saved_hash_it} { - save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer - } - - if {$do_save_saved_it} { - return 1 - } else { - return 0 - } -} - -proc save_hash {crt adir hp fingerline from fingerprint {subject_issuer ""}} { - if ![file exists $crt] { - return - } - set ossl [get_openssl] - set hash [exec $ossl x509 -hash -noout -in $crt] - set hash [string trim $hash] - if [regexp {^([0-9a-f][0-9a-f]*)} $hash mv h] { - set hashfile "$adir/$h.0" - set hn "$h.0" - if [file exists $hashfile] { - set hashfile "$adir/$h.1" - set hn "$h.1" - if [file exists $hashfile] { - set hashfile "$adir/$h.2" - set hn "$h.2" - } - } - set fh [open $crt "a"] - if {$fh != ""} { - puts $fh "" - puts $fh "SSVNC-info:" - puts $fh "Host-Display: $hp" - puts $fh "$fingerline" - puts $fh "hash-filename: $hn" - puts $fh "full-filename: $from=$fingerprint.crt" - puts -nonewline $fh $subject_issuer - close $fh - } - catch {file copy -force $crt $hashfile} - if [file exists $hashfile] { - return 1 - } - } -} - -proc tpid {} { - global is_windows - set p "" - - if {!$is_windows} { - catch {set p [exec sh -c {echo $$}]} - } - if {$p == ""} { - set p [pid]; - } - append p [clock clicks] - return $p -} - -proc repeater_proxy_check {proxy} { - if [regexp {^repeater://.*\+ID:[0-9]} $proxy] { - global env rpc_m1 rpc_m2 - if {![info exists rpc_m1]} { - set rpc_m1 0 - set rpc_m2 0 - } - set force 0 - if [info exists env(REPEATER_FORCE)] { - if {$env(REPEATER_FORCE) != "" && $env(REPEATER_FORCE) != "0"} { - # no longer makes a difference. - set force 1 - } - } - global use_listen ultra_dsm - if {! $use_listen} { - if {$ultra_dsm} { - return 1; - } else { - if {0} { - mesg "WARNING: repeater:// ID:nnn proxy might need Listen Mode" - incr rpc_m1 - if {$rpc_m1 <= 2} { - after 1000 - } else { - after 200 - } - } - if {0} { - # no longer required by x11vnc (X11VNC_DISABLE_SSL_CLIENT_MODE) - bell - mesg "ERROR: repeater:// ID:nnn proxy must use Listen Mode" - after 1000 - return 0 - } - } - } - global always_verify_ssl - if [info exists always_verify_ssl] { - if {$always_verify_ssl} { - mesg "WARNING: repeater:// ID:nnn Verify All Certs may fail" - incr rpc_m2 - if {$rpc_m2 == 1} { - after 1500 - } elseif {$rpc_m2 == 2} { - after 500 - } else { - after 200 - } - } - } - } - return 1 -} - -proc fini_unixpw {} { - global named_pipe_fh unixpw_tmp - - if {$named_pipe_fh != ""} { - catch {close $named_pipe_fh} - } - if {$unixpw_tmp != ""} { - catch {file delete $unixpw_tmp} - } -} - -proc init_unixpw {hp} { - global use_unixpw unixpw_username unixpw_passwd - global named_pipe_fh unixpw_tmp env - - set named_pipe_fh "" - set unixpw_tmp "" - - if {$use_unixpw} { - set name $unixpw_username - set env(SSVNC_UNIXPW) "" - if {$name == ""} { - regsub {^.*://} $hp "" hp - set hptmp [get_ssh_hp $hp] - if [regexp {^(.*)@} $hptmp mv m1] { - set name $m1 - } - } - if {$name == ""} { - if [info exists env(USER)] { - set name $env(USER) - } - } - if {$name == ""} { - if [info exists env(LOGNAME)] { - set name $env(LOGNAME) - } - } - if {$name == ""} { - set name [exec whoami] - } - if {$name == ""} { - set name "unknown" - } - - set tmp "/tmp/unixpipe.[tpid]" - set tmp [mytmp $tmp] - # need to make it a pipe - catch {file delete $tmp} - if {[file exists $tmp]} { - mesg "file still exists: $tmp" - bell - return - } - - catch {exec mknod $tmp p} - set fh "" - if {! [file exists $tmp]} { - catch {set fh [open $tmp "w"]} - } else { - catch {set fh [open $tmp "r+"]} - set named_pipe_fh $fh - } - catch {exec chmod 600 $tmp} - if {! [file exists $tmp]} { - mesg "cannot create: $tmp" - if {$named_pipe_fh != ""} {catch close $named_pipe_fh} - bell - return - } - #puts [exec ls -l $tmp] - set unixpw_tmp $tmp - puts $fh $name - puts $fh $unixpw_passwd - if {$named_pipe_fh != ""} { - flush $fh - } else { - close $fh - } - exec sh -c "sleep 60; /bin/rm -f $tmp" & - if {$unixpw_passwd == ""} { - set env(SSVNC_UNIXPW) "." - } else { - set env(SSVNC_UNIXPW) "rm:$tmp" - } - } else { - if [info exists env(SSVNC_UNIXPW)] { - set env(SSVNC_UNIXPW) "" - } - } -} - -proc check_for_listen_ssl_cert {} { - global mycert use_listen use_ssh ultra_dsm - if {! $use_listen} { - return 1 - } - if {$use_ssh} { - return 1 - } - if {$ultra_dsm} { - return 1 - } - if {$mycert != ""} { - return 1 - } - - set name [get_idir_certs ""] - set name "$name/listen.pem" - if {[file exists $name]} { - set mycert $name - mesg "Using Listen Cert: $name" - after 700 - return 1 - } - - set title "SSL Listen requires MyCert"; - set msg "In SSL Listen mode a cert+key is required, but you have not specified 'MyCert'.\n\nCreate a cert+key 'listen' now?" - set reply [tk_messageBox -type okcancel -default ok -icon warning -message $msg -title $msg] - if {$reply == "cancel"} { - return 0 - } - create_cert $name - tkwait window .ccrt - if {[file exists $name]} { - set mycert $name - mesg "Using Listen Cert: $name" - after 700 - return 1 - } - return 0 -} - -proc listen_verify_all_dialog {hp} { - global use_listen always_verify_ssl - global did_listen_verify_all_dialog - global svcert - global sshssl_sw ultra_dsm - - if {!$use_listen} { - return 1 - } - if {!$always_verify_ssl} { - return 1 - } - if {$svcert != ""} { - return 1 - } - if {$ultra_dsm} { - return 1 - } - if [regexp -nocase {^vnc://} $hp] { - return 1 - } - if [info exists sshssl_sw] { - if {$sshssl_sw == "none"} { - return 1 - } - if {$sshssl_sw == "ssh"} { - return 1 - } - } - if [info exists did_listen_verify_all_dialog] { - return 1 - } - - toplev .lvd - global help_font - wm title .lvd "Verify All Certs for Reverse Connections" - eval text .lvd.t -width 55 -height 22 $help_font - .lvd.t insert end { - Information: - - You have the 'Verify All Certs' option enabled - in Reverse VNC Connections (-LISTEN) mode. - - For this to work, you must have ALREADY saved - the remote VNC Server's Certificate to the - 'Accepted Certs' directory. Otherwise the - incoming Reverse connection will be rejected. - - You can save the Server's Certificate by using - the 'Import Certificate' dialog or on Unix - and MacOSX by pressing 'Fetch Cert' and then - have the Server make an initial connection. - - If you do not want to save the certificate of - the VNC Server making the Reverse connection, - you must disable 'Verify All Certs' (note that - this means the server authenticity will not be - checked.) -} - - button .lvd.ok -text OK -command {destroy .lvd} - button .lvd.ok2 -text OK -command {destroy .lvd} - button .lvd.disable -text "Disable 'Verify All Certs'" -command {set always_verify_ssl 0; destroy .lvd} - global uname - if {$uname == "Darwin"} { - pack .lvd.t .lvd.ok2 .lvd.disable .lvd.ok -side top -fill x - } else { - pack .lvd.t .lvd.disable .lvd.ok -side top -fill x - } - center_win .lvd - update - - tkwait window .lvd - update - after 50 - update - - set did_listen_verify_all_dialog 1 - return 1 -} - -proc reset_stunnel_extra_opts {} { - global stunnel_extra_opts0 stunnel_extra_svc_opts0 env - global ssvnc_multiple_listen0 - if {$stunnel_extra_opts0 != "none"} { - set env(STUNNEL_EXTRA_OPTS) $stunnel_extra_opts0 - } - if {$stunnel_extra_svc_opts0 != "none"} { - set env(STUNNEL_EXTRA_SVC_OPTS) $stunnel_extra_svc_opts0 - } - set env(SSVNC_LIM_ACCEPT_PRELOAD) "" - if {$ssvnc_multiple_listen0 != "none"} { - set env(SSVNC_MULTIPLE_LISTEN) $ssvnc_multiple_listen0 - } - set env(SSVNC_ULTRA_DSM) "" - set env(SSVNC_TURBOVNC) "" - catch { unset env(VNCVIEWER_NO_PIPELINE_UPDATES) } - catch { unset env(VNCVIEWER_NOTTY) } - catch { unset env(SSVNC_ACCEPT_POPUP) } - catch { unset env(SSVNC_ACCEPT_POPUP_SC) } - catch { unset env(SSVNC_KNOWN_HOSTS_FILE) } -} - -proc maybe_add_vencrypt {proxy hp} { - global vencrypt_detected server_vencrypt - set vpd "" - if {$vencrypt_detected != ""} { - set vpd $vencrypt_detected - set vencrypt_detected "" - } elseif {$server_vencrypt} { - set vpd [get_vencrypt_proxy $hp] - } - if {$vpd != ""} { - mesg "vencrypt proxy: $vpd" - if {$proxy != ""} { - set proxy "$proxy,$vpd" - } else { - set proxy "$vpd" - } - } - return $proxy -} - -proc no_certs_tutorial_mesg {} { - global svcert crtdir - global server_anondh - global always_verify_ssl - - set doit 0 - if {!$always_verify_ssl} { - if {$svcert == ""} { - if {$crtdir == "" || $crtdir == "ACCEPTED_CERTS"} { - set doit 1 - } - } - } elseif {$server_anondh} { - set doit 1 - } - if {$doit} { - mesg "INFO: without Certificate checking man-in-the-middle attack is possible." - } else { - set str "" - catch {set str [.l cget -text]} - if {$str != "" && [regexp {^INFO: without Certificate} $str]} { - mesg "" - } - } -} - -proc vencrypt_tutorial_mesg {} { - global use_ssh use_sshssl use_listen - global server_vencrypt no_probe_vencrypt - global ultra_dsm - - set m "" - if {$use_ssh} { - ; - } elseif {$server_vencrypt} { - ; - } elseif {$ultra_dsm} { - ; - } elseif {$use_listen} { - set m "No VeNCrypt Auto-Detection: Listen mode." - } elseif {$use_sshssl} { - set m "No VeNCrypt Auto-Detection: SSH+SSL mode." - } elseif {$no_probe_vencrypt} { - set m "No VeNCrypt Auto-Detection: Disabled." - } - if {$m != ""} { - mesg $m - after 1000 - } - return $m - - #global svcert always_verify_ssl - #$svcert != "" || !$always_verify_ssl - # set m "No VeNCrypt Auto-Detection: 'Verify All Certs' disabled" -} - -proc launch_unix {hp} { - global smb_redir_0 smb_mounts env - global vncauth_passwd use_unixpw unixpw_username unixpw_passwd - global ssh_only ts_only use_x11cursor use_nobell use_rawlocal use_notty use_popupfix ssvnc_scale ssvnc_escape - global ssvnc_encodings ssvnc_extra_opts - - globalize - - set cmd "" - - if {[regexp {^vncssh://} $hp] || [regexp {^vnc\+ssh://} $hp]} { - set use_ssl 0 - set use_ssh 1 - sync_use_ssl_ssh - } elseif {[regexp {^vncs://} $hp] || [regexp {^vncssl://} $hp] || [regexp {^vnc\+ssl://} $hp]} { - set use_ssl 1 - set use_ssh 0 - sync_use_ssl_ssh - } - if {[regexp {^rsh:/?/?} $hp]} { - set use_ssl 0 - set use_ssh 1 - sync_use_ssl_ssh - } - - check_ssh_needed - - set_smb_mounts - - global did_port_knock - set did_port_knock 0 - set pk_hp "" - - set skip_ssh 0 - set do_direct 0 - - if [regexp {vnc://} $hp] { - set skip_ssh 1 - set do_direct 1 - if {! [info exists env(SSVNC_NO_ENC_WARN)]} { - direct_connect_msg - } - } - - listen_verify_all_dialog $hp - - if {! $do_direct} { - if {! [check_for_listen_ssl_cert]} { - return - } - } - - global stunnel_extra_opts0 stunnel_extra_svc_opts0 - set stunnel_extra_opts0 "" - set stunnel_extra_svc_opts0 "" - global ssvnc_multiple_listen0 - set ssvnc_multiple_listen0 "" - - if {[regexp -nocase {sslrepeater://} $hp]} { - if {$disable_ssl_workarounds} { - set disable_ssl_workarounds 0 - mesg "Disabling SSL workarounds for 'UVNC Single Click III Bug'" - after 400 - } - } - - if [info exists env(STUNNEL_EXTRA_OPTS)] { - set stunnel_extra_opts0 $env(STUNNEL_EXTRA_OPTS) - if {$disable_ssl_workarounds} { - if {$disable_ssl_workarounds_type == "none"} { - ; - } elseif {$disable_ssl_workarounds_type == "noempty"} { - set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = DONT_INSERT_EMPTY_FRAGMENTS" - } - } else { - set env(STUNNEL_EXTRA_OPTS) "$env(STUNNEL_EXTRA_OPTS)\noptions = ALL" - } - } else { - if {$disable_ssl_workarounds} { - if {$disable_ssl_workarounds_type == "none"} { - ; - } elseif {$disable_ssl_workarounds_type == "noempty"} { - set env(STUNNEL_EXTRA_OPTS) "options = DONT_INSERT_EMPTY_FRAGMENTS" - } - } else { - set env(STUNNEL_EXTRA_OPTS) "options = ALL" - } - } - if {$stunnel_local_protection && ! $use_listen} { - if {$stunnel_local_protection_type == "ident"} { - set user "" - if {[info exists env(USER)]} { - set user $env(USER) - } elseif {[info exists env(LOGNAME)]} { - set user $env(USER) - } - if {$user != ""} { - if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] { - set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS) - set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\nident = $user" - } else { - set env(STUNNEL_EXTRA_SVC_OPTS) "ident = $user" - } - } - } elseif {$stunnel_local_protection_type == "exec"} { - if [info exists env(STUNNEL_EXTRA_SVC_OPTS)] { - set stunnel_extra_svc_opts0 $env(STUNNEL_EXTRA_SVC_OPTS) - set env(STUNNEL_EXTRA_SVC_OPTS) "$env(STUNNEL_EXTRA_SVC_OPTS)\n#stunnel-exec" - } else { - set env(STUNNEL_EXTRA_SVC_OPTS) "#stunnel-exec" - } - } - } - if {$ultra_dsm} { - if {$ultra_dsm_type == "securevnc"} { - ; - } elseif {![file exists $ultra_dsm_file] && ![regexp {pw=} $ultra_dsm_file]} { - mesg "DSM key file does exist: $ultra_dsm_file" - bell - after 1000 - return - } - global vncauth_passwd - if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} { - if {![info exists vncauth_passwd] || $vncauth_passwd == ""} { - mesg "For DSM pw=VNCPASSWD you must supply the VNC Password" - bell - after 1000 - return - } - if [regexp {'} $vncauth_passwd] { - mesg "For DSM pw=VNCPASSWD password must not contain single quotes." - bell - after 1000 - return - } - } - set dsm "ultravnc_dsm_helper " - if {$ultra_dsm_noultra} { - append dsm "noultra:" - } - if {$use_listen} { - append dsm "rev:" - } - if {$ultra_dsm_type == "guess"} { - append dsm "." - } else { - append dsm $ultra_dsm_type - } - if {$ultra_dsm_noultra} { - if {$ultra_dsm_salt != ""} { - append dsm "@$ultra_dsm_salt" - } - } - if {$ultra_dsm_file == "pw=VNCPASSWORD" || $ultra_dsm_file == "pw=VNCPASSWD"} { - append dsm " pw='$vncauth_passwd'" - } else { - if {$ultra_dsm_file == "" && $ultra_dsm_type == "securevnc"} { - append dsm " none" - } else { - append dsm " $ultra_dsm_file" - } - } - set env(SSVNC_ULTRA_DSM) $dsm - } - if {$multiple_listen && $use_listen} { - if [info exists env(SSVNC_MULTIPLE_LISTEN)] { - set ssvnc_multiple_listen0 $env(SSVNC_MULTIPLE_LISTEN) - } - set env(SSVNC_MULTIPLE_LISTEN) "1" - } - - if {$use_ssh} { - ; - } elseif {$use_sshssl} { - ; - } elseif {$use_ssl} { - set prox [get_ssh_proxy $hp] - if {$prox != "" && [regexp {@} $prox]} { - mesg "Error: proxy contains '@' Did you mean to use SSH mode?" - bell - return - } - if [regexp {@} $hp] { - mesg "Error: host contains '@' Did you mean to use SSH mode?" - bell - return - } - } - - if {$use_ssh || $use_sshssl} { - if {$ssh_local_protection} { - if {![info exists env(LIM_ACCEPT)]} { - set env(LIM_ACCEPT) 1 - } - if {![info exists env(LIM_ACCEPT_TIME)]} { - set env(LIM_ACCEPT_TIME) 35 - } - set env(SSVNC_LIM_ACCEPT_PRELOAD) "lim_accept.so" - mesg "SSH LIM_ACCEPT($env(LIM_ACCEPT),$env(LIM_ACCEPT_TIME)): lim_accept.so" - after 700 - } - if {$skip_ssh || $ultra_dsm} { - set cmd "ss_vncviewer" - } elseif {$use_ssh} { - set cmd "ss_vncviewer -ssh" - } else { - set cmd "ss_vncviewer -sshssl" - if {$mycert != ""} { - set cmd "$cmd -mycert '$mycert'" - } - if {$crlfil != ""} { - set cmd "$cmd -crl '$crlfil'" - } - if {$svcert != ""} { - set cmd "$cmd -verify '$svcert'" - } elseif {$crtdir != "" && $crtdir != "ACCEPTED_CERTS"} { - set cmd "$cmd -verify '$crtdir'" - } - } - if {$use_listen} { - set cmd "$cmd -listen" - } - if {$ssh_local_protection} { - regsub {ss_vncviewer} $cmd "ssvnc_cmd" cmd - } - set hpnew [get_ssh_hp $hp] - set proxy [get_ssh_proxy $hp] - set sshcmd [get_ssh_cmd $hp] - - if {$use_sshssl} { - if {!$do_direct} { - set proxy [maybe_add_vencrypt $proxy $hp] - } - } - - if {$ts_only} { - regsub {:0$} $hpnew "" hpnew - if {$proxy == ""} { - # XXX host_part - if {[regexp {^([^:]*):([0-9][0-9]*)$} $hpnew mv sshhst sshpt]} { - set proxy "$sshhst:$sshpt" - set hpnew "localhost" - } - } else { - if {![regexp {,} $proxy]} { - if {$hpnew != "localhost"} { - set proxy "$proxy,$hpnew" - set hpnew "localhost" - } - } - } - } - -#puts hp=$hp -#puts hpn=$hpnew -#puts pxy=$proxy -#puts cmd=$sshcmd - - set hp $hpnew - - if {$proxy != ""} { - set cmd "$cmd -proxy '$proxy'" - set pk_hp $proxy - } - if {$pk_hp == ""} { - set pk_hp $hp - } - - set do_pre 0 - if {$use_smbmnt} { - set do_pre 1 - } elseif {$use_sound && $sound_daemon_kill} { - set do_pre 1 - } - global skip_pre - if {$skip_pre || $skip_ssh} { - set do_pre 0 - set skip_pre 0 - } - - set tag [contag] - - if {$do_pre} { - do_unix_pre $tag $proxy $hp $pk_hp - } - - - set setup_cmds [ugly_setup_scripts post $tag] - - if {$skip_ssh} { - set setup_cmds "" - } - if {$sshcmd != "SHELL" && [regexp -nocase {x11vnc} $sshcmd]} { - global use_cups cups_x11vnc cups_remote_port - global cups_remote_smb_port - global use_sound sound_daemon_x11vnc sound_daemon_remote_port - global ts_only - if {$ts_only} { - set cups_x11vnc 1 - set sound_daemon_x11vnc 1 - } - if {$use_cups && $cups_x11vnc && $cups_remote_port != ""} { - set crp $cups_remote_port - if {$ts_only} { - set cups_remote_port [rand_port] - set crp "DAEMON-$cups_remote_port" - } - set sshcmd "$sshcmd -env FD_CUPS=$crp" - } - if {$use_cups && $cups_x11vnc && $cups_remote_smb_port != ""} { - set csp $cups_remote_smb_port - if {$ts_only} { - set cups_remote_smb_port [rand_port] - set csp "DAEMON-$cups_remote_smb_port" - } - set sshcmd "$sshcmd -env FD_SMB=$csp" - } - if {$use_sound && $sound_daemon_x11vnc && $sound_daemon_remote_port != ""} { - set srp $sound_daemon_remote_port - if {$ts_only} { - set sound_daemon_remote_port [rand_port] - set srp "DAEMON-$sound_daemon_remote_port" - } - set sshcmd "$sshcmd -env FD_ESD=$srp" - } - } - - if {$sshcmd == "SHELL"} { - set env(SS_VNCVIEWER_SSH_CMD) {$SHELL} - set env(SS_VNCVIEWER_SSH_ONLY) 1 - } elseif {$setup_cmds != ""} { - if {$sshcmd == ""} { - set sshcmd "sleep 15" - } - set env(SS_VNCVIEWER_SSH_CMD) "$setup_cmds$sshcmd" - } else { - if {$sshcmd != ""} { - set cmd "$cmd -sshcmd '$sshcmd'" - } - } - - set sshargs "" - if {$use_cups} { - append sshargs [get_cups_redir] - } - if {$use_sound} { - append sshargs [get_sound_redir] - } - if {$additional_port_redirs} { - append sshargs [get_additional_redir] - } - - set sshargs [string trim $sshargs] - if {$skip_ssh} { - set sshargs "" - } - if {$sshargs != ""} { - set cmd "$cmd -sshargs '$sshargs'" - set env(SS_VNCVIEWER_USE_C) 1 - } else { - # hmm we used to have it off... why? - # ssh typing response? - set env(SS_VNCVIEWER_USE_C) 1 - } - if {$sshcmd == "SHELL"} { - set env(SS_VNCVIEWER_SSH_ONLY) 1 - if {$proxy == ""} { - set hpt $hpnew - # XXX host_part - regsub {:[0-9][0-9]*$} $hpt "" hpt - set cmd "$cmd -proxy '$hpt'" - } - set geometry [xterm_center_geometry] - if {$pk_hp == ""} { - set pk_hp $hp - } - if {! $did_port_knock} { - if {! [do_port_knock $pk_hp start]} { - reset_stunnel_extra_opts - return - } - set did_port_knock 1 - } - - if {[regexp {FINISH} $port_knocking_list]} { - wm withdraw . - update - unix_terminal_cmd $geometry "SHELL to $hp" "$cmd" - wm deiconify . - update - do_port_knock $pk_hp finish - } else { - unix_terminal_cmd $geometry "SHELL to $hp" "$cmd" 1 - } - set env(SS_VNCVIEWER_SSH_CMD) "" - set env(SS_VNCVIEWER_SSH_ONLY) "" - set env(SS_VNCVIEWER_USE_C) "" - reset_stunnel_extra_opts - return - } - } else { - set cmd "ssvnc_cmd" - set hpnew [get_ssh_hp $hp] - set proxy [get_ssh_proxy $hp] - - if {!$do_direct && ![repeater_proxy_check $proxy]} { - reset_stunnel_extra_opts - return - } - - if {! $do_direct && ! $ultra_dsm && ![regexp -nocase {ssh://} $hpnew]} { - set did_check 0 - if {$mycert != ""} { - set cmd "$cmd -mycert '$mycert'" - } - if {$crlfil != ""} { - set cmd "$cmd -crl '$crlfil'" - } - if {$svcert != ""} { - set cmd "$cmd -verify '$svcert'" - } elseif {$crtdir != ""} { - if {$crtdir == "ACCEPTED_CERTS"} { - global skip_verify_accepted_certs - set skip_verify_accepted_certs 0 - - set did_check 1 - if {! [check_accepted_certs 0]} { - reset_stunnel_extra_opts - return - } - if {! $skip_verify_accepted_certs} { - set adir [get_idir_certs ""] - set adir "$adir/accepted" - catch {file mkdir $adir} - set cmd "$cmd -verify '$adir'" - } - - } else { - set cmd "$cmd -verify '$crtdir'" - } - } - if {! $did_check} { - check_accepted_certs 1 - } - } - - if {!$do_direct} { - set proxy [maybe_add_vencrypt $proxy $hp] - } - - if {$proxy != ""} { - set cmd "$cmd -proxy '$proxy'" - } - set hp $hpnew - if [regexp {^.*@} $hp match] { - catch {raise .; update} - mesg "Trimming \"$match\" from hostname" - after 700 - regsub {^.*@} $hp "" hp - } - if [regexp {@} $proxy] { - bell - catch {raise .; update} - mesg "WARNING: SSL proxy contains \"@\" sign" - after 1500 - } - } - - global anon_dh_detected - if {$anon_dh_detected || $server_anondh} { - if {!$do_direct} { - set cmd "$cmd -anondh" - } - set anon_dh_detected 0 - } - if {$use_alpha} { - set cmd "$cmd -alpha" - } - if {$use_send_clipboard} { - set cmd "$cmd -sendclipboard" - } - if {$use_send_always} { - set cmd "$cmd -sendalways" - } - if {$use_turbovnc} { - set env(SSVNC_TURBOVNC) 1 - } - if {$disable_pipeline} { - set env(VNCVIEWER_NO_PIPELINE_UPDATES) 1 - } - if {$ssh_known_hosts_filename != ""} { - set env(SSVNC_KNOWN_HOSTS_FILE) $ssh_known_hosts_filename - } - if {$use_grab} { - set cmd "$cmd -grab" - } - if {$use_x11cursor} { - set cmd "$cmd -x11cursor" - } - if {$use_nobell} { - set cmd "$cmd -nobell" - } - if {$use_rawlocal} { - set cmd "$cmd -rawlocal" - } - if {$use_notty} { - set env(VNCVIEWER_NOTTY) 1 - } - if {$use_popupfix} { - set cmd "$cmd -popupfix" - } - if {$ssvnc_scale != ""} { - set cmd "$cmd -scale '$ssvnc_scale'" - } - if {$ssvnc_escape != ""} { - set cmd "$cmd -escape '$ssvnc_escape'" - } - if {$ssvnc_encodings != ""} { - set cmd "$cmd -ssvnc_encodings '$ssvnc_encodings'" - } - if {$ssvnc_extra_opts != ""} { - set cmd "$cmd -ssvnc_extra_opts '$ssvnc_extra_opts'" - } - if {$rfbversion != ""} { - set cmd "$cmd -rfbversion '$rfbversion'" - } - if {$vncviewer_realvnc4} { - set cmd "$cmd -realvnc4" - } - if {$use_listen} { - set cmd "$cmd -listen" - if {$listen_once} { - set cmd "$cmd -onelisten" - } - if {$listen_accept_popup} { - if {$listen_accept_popup_sc} { - set env(SSVNC_ACCEPT_POPUP_SC) 1 - } else { - set env(SSVNC_ACCEPT_POPUP) 1 - } - } - } - - global darwin_cotvnc - if {$darwin_cotvnc} { - set env(DARWIN_COTVNC) 1 - } else { - if [info exists env(DISPLAY)] { - if {$env(DISPLAY) != ""} { - set env(DARWIN_COTVNC) 0 - } else { - set env(DARWIN_COTVNC) 1 - } - } else { - set env(DARWIN_COTVNC) 1 - } - } - - set do_vncspacewrapper 0 - if {$change_vncviewer && $change_vncviewer_path != ""} { - set path [string trim $change_vncviewer_path] - if [regexp {^["'].} $path] { # " - set tmp "/tmp/vncspacewrapper.[tpid]" - set tmp [mytmp $tmp] - set do_vncspacewrapper 1 - if {0} { - catch {file delete $tmp} - if {[file exists $tmp]} { - catch {destroy .c} - mesg "file still exists: $tmp" - bell - reset_stunnel_extra_opts - return - } - } - catch {set fh [open $tmp "w"]} - catch {exec chmod 700 $tmp} - if {! [file exists $tmp]} { - catch {destroy .c} - mesg "cannot create: $tmp" - bell - reset_stunnel_extra_opts - return - } - puts $fh "#!/bin/sh" - puts $fh "echo $tmp; set -xv" - puts $fh "$path \"\$@\"" - puts $fh "sleep 1; rm -f $tmp" - close $fh - set path $tmp - } - set env(VNCVIEWERCMD) $path - } else { - if [info exists env(VNCVIEWERCMD_OVERRIDE)] { - set env(VNCVIEWERCMD) $env(VNCVIEWERCMD_OVERRIDE) - } else { - set env(VNCVIEWERCMD) "" - } - } - - set realvnc4 $vncviewer_realvnc4 - set realvnc3 0 - set flavor "" - if {! $darwin_cotvnc} { - set done 0 - if {$do_vncspacewrapper} { - if [regexp -nocase {ultra} $change_vncviewer_path] { - set done 1 - set flavor "ultravnc" - } elseif [regexp -nocase {chicken.of} $change_vncviewer_path] { - set done 1 - set flavor "cotvnc" - } - } - if {! $done} { - catch {set flavor [exec ss_vncviewer -viewerflavor 2>/dev/null]} - } - } - if [regexp {realvnc4} $flavor] { - set realvnc4 1 - } - if [regexp {tightvnc} $flavor] { - set realvnc4 0 - } - if [regexp {realvnc3} $flavor] { - set realvnc4 0 - set realvnc3 1 - } - if {$realvnc4} { - set cmd "$cmd -realvnc4" - } - - set cmd "$cmd $hp" - - set passwdfile "" - if {$vncauth_passwd != ""} { - global use_listen - set footest [mytmp /tmp/.check.[tpid]] - catch {file delete $footest} - global mktemp - set passwdfile "/tmp/.vncauth_tmp.[tpid]" - if {$mktemp == ""} { - set passwdfile "$env(SSVNC_HOME)/.vncauth_tmp.[tpid]" - } - - set passwdfile [mytmp $passwdfile] - catch {exec vncstorepw $vncauth_passwd $passwdfile} - catch {exec chmod 600 $passwdfile} - if {$use_listen} { - global env - set env(SS_VNCVIEWER_RM) $passwdfile - } else { - if {$darwin_cotvnc} { - catch {exec sh -c "sleep 60; rm $passwdfile 2>/dev/null" &} - } else { - catch {exec sh -c "sleep 20; rm $passwdfile 2>/dev/null" &} - } - } - if {$darwin_cotvnc} { - set cmd "$cmd --PasswordFile $passwdfile" - } elseif {$flavor == "unknown"} { - ; - } else { - set cmd "$cmd -passwd $passwdfile" - } - } - - if {$use_viewonly} { - if {$darwin_cotvnc} { - set cmd "$cmd --ViewOnly" - } elseif {$flavor == "unknown"} { - ; - } elseif {$flavor == "ultravnc"} { - set cmd "$cmd /viewonly" - } else { - set cmd "$cmd -viewonly" - } - } - if {$use_fullscreen} { - if {$darwin_cotvnc} { - set cmd "$cmd --FullScreen" - } elseif {$flavor == "ultravnc"} { - set cmd "$cmd /fullscreen" - } elseif {$flavor == "unknown"} { - if [regexp {vinagre} $change_vncviewer_path] { - set cmd "$cmd -f" - } - } else { - set cmd "$cmd -fullscreen" - } - } - if {$use_bgr233} { - if {$realvnc4} { - set cmd "$cmd -lowcolourlevel 1" - } elseif {$flavor == "ultravnc"} { - set cmd "$cmd /8bit" - } elseif {$flavor == "ultravnc"} { - ; - } elseif {$flavor == "unknown"} { - ; - } else { - set cmd "$cmd -bgr233" - } - } - if {$use_nojpeg} { - if {$darwin_cotvnc} { - ; - } elseif {$flavor == "ultravnc"} { - ; - } elseif {$flavor == "unknown"} { - ; - } elseif {! $realvnc4 && ! $realvnc3} { - set cmd "$cmd -nojpeg" - } - } - if {! $use_raise_on_beep} { - if {$darwin_cotvnc} { - ; - } elseif {$flavor == "ultravnc"} { - ; - } elseif {$flavor == "unknown"} { - ; - } elseif {! $realvnc4 && ! $realvnc3} { - set cmd "$cmd -noraiseonbeep" - } - } - if {$use_compresslevel != "" && $use_compresslevel != "default"} { - if {$realvnc3} { - ; - } elseif {$flavor == "ultravnc"} { - ; - } elseif {$flavor == "unknown"} { - ; - } elseif {$realvnc4} { - set cmd "$cmd -zliblevel '$use_compresslevel'" - } else { - set cmd "$cmd -compresslevel '$use_compresslevel'" - } - } - if {$use_quality != "" && $use_quality != "default"} { - if {$darwin_cotvnc} { - ; - } elseif {$flavor == "ultravnc"} { - ; - } elseif {$flavor == "unknown"} { - ; - } elseif {! $realvnc4 && ! $realvnc3} { - set cmd "$cmd -quality '$use_quality'" - } - } - if {$use_ssh || $use_sshssl} { - # realvnc4 -preferredencoding zrle - if {$darwin_cotvnc} { - ; - } elseif {$flavor == "ultravnc"} { - ; - } elseif {$flavor == "unknown"} { - ; - } elseif {$realvnc4} { - set cmd "$cmd -preferredencoding zrle" - } else { - set cmd "$cmd -encodings 'copyrect tight zrle zlib hextile'" - } - } - - global ycrop_string - global sbwid_string - catch {unset env(VNCVIEWER_SBWIDTH)} - catch {unset env(VNCVIEWER_YCROP)} - if {[info exists ycrop_string] && $ycrop_string != ""} { - set t $ycrop_string - if [regexp {,sb=([0-9][0-9]*)} $t m mv1] { - set env(VNCVIEWER_SBWIDTH) $mv1 - } - regsub {,sb=([0-9][0-9]*)} $t "" t - if {$t != ""} { - set env(VNCVIEWER_YCROP) $t - } - } - if {[info exists sbwid_string] && $sbwid_string != ""} { - set t $sbwid_string - set env(VNCVIEWER_SBWIDTH) $sbwid_string - if {$t != ""} { - set env(VNCVIEWER_SBWIDTH) $t - } - } - - catch {destroy .o} - catch {destroy .oa} - catch {destroy .os} - update - - if {$use_sound && $sound_daemon_local_start && $sound_daemon_local_cmd != ""} { - mesg "running: $sound_daemon_local_cmd" - global sound_daemon_local_pid - set sound_daemon_local_pid "" - #exec sh -c "$sound_daemon_local_cmd " >& /dev/null </dev/null & - set sound_daemon_local_pid [exec sh -c "echo \$\$; exec $sound_daemon_local_cmd </dev/null 1>/dev/null 2>/dev/null &"] - update - after 500 - } - - if {$pk_hp == ""} { - set pk_hp $hp - } - if {! $did_port_knock} { - if {! [do_port_knock $pk_hp start]} { - wm deiconify . - update - reset_stunnel_extra_opts - return - } - set did_port_knock 1 - } - - init_unixpw $hp - - if {! $do_direct} { - vencrypt_tutorial_mesg - } - - wm withdraw . - update - - set geometry [xterm_center_geometry] - set xrm1 "*.srinterCommand:true" - set xrm2 $xrm1 - set xrm3 $xrm1 - if {[info exists env(SSVNC_GUI_CMD)]} { - set xrm1 "*.printerCommand:env XTERM_PRINT=1 $env(SSVNC_GUI_CMD)" - set xrm2 "XTerm*VT100*translations:#override Shift<Btn3Down>:print()\\nCtrl<Key>N:print()" - set xrm3 "*mainMenu*print*Label: New SSVNC_GUI" - } - set m "Done. You Can X-out or Ctrl-C this Terminal if you like. Use Ctrl-\\\\ to pause." - global uname - if {$uname == "Darwin"} { - regsub {X-out or } $m "" m - } - set te "set -xv; " - if {$ts_only} { - set te "" - } - - global extra_sleep - set ssvnc_extra_sleep_save "" - if {$extra_sleep != ""} { - if [info exists env(SSVNC_EXTRA_SLEEP)] { - set ssvnc_extra_sleep_save $env(SSVNC_EXTRA_SLEEP) - } - set env(SSVNC_EXTRA_SLEEP) $extra_sleep - } - - set sstx "SSL/SSH VNC Viewer" - set hptx $hp - global use_listen - if {$use_listen} { - set sstx "SSVNC" - set hptx "$hp (Press Ctrl-C to Stop Listening)" - } - - - set s1 5 - set s2 4 - if [info exists env(SSVNC_FINISH_SLEEP)] { - set s1 $env(SSVNC_FINISH_SLEEP); - set s2 $s1 - } - - unix_terminal_cmd $geometry "$sstx $hptx" \ - "$te$cmd; set +xv; ulimit -c 0; trap 'printf \"Paused. Press Enter to exit:\"; read x' QUIT; echo; echo $m; echo; echo sleep $s1; echo; sleep $s2" 0 $xrm1 $xrm2 $xrm3 - - set env(SS_VNCVIEWER_SSH_CMD) "" - set env(SS_VNCVIEWER_USE_C) "" - - if {$extra_sleep != ""} { - if {$ssvnc_extra_sleep_save != ""} { - set env(SSVNC_EXTRA_SLEEP) $ssvnc_extra_sleep_save - } else { - catch {unset env(SSVNC_EXTRA_SLEEP)} - } - } - - if {$use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} { - # XXX need to kill just one... - set daemon [string trim $sound_daemon_local_cmd] - regsub {^gw[ \t]*} $daemon "" daemon - regsub {[ \t].*$} $daemon "" daemon - regsub {^.*/} $daemon "" daemon - mesg "killing sound daemon: $daemon" - global sound_daemon_local_pid - if {$sound_daemon_local_pid != ""} { -#puts pid=$sound_daemon_local_pid - catch {exec sh -c "kill $sound_daemon_local_pid" >/dev/null 2>/dev/null </dev/null &} - incr sound_daemon_local_pid - catch {exec sh -c "kill $sound_daemon_local_pid" >/dev/null 2>/dev/null </dev/null &} - set sound_daemon_local_pid "" - } elseif {$daemon != ""} { - catch {exec sh -c "killall $daemon" >/dev/null 2>/dev/null </dev/null &} - catch {exec sh -c "pkill -x $daemon" >/dev/null 2>/dev/null </dev/null &} - } - } - if {$passwdfile != ""} { - catch {file delete $passwdfile} - } - wm deiconify . - mac_raise - mesg "Disconnected from $hp" - if {[regexp {FINISH} $port_knocking_list]} { - do_port_knock $pk_hp finish - } - - reset_stunnel_extra_opts - - fini_unixpw -} - -proc kill_stunnel {pids} { - set count 0 - foreach pid $pids { - mesg "killing STUNNEL pid: $pid" - winkill $pid - if {$count == 0} { - after 600 - } else { - after 300 - } - incr count - } -} - -proc get_task_list {} { - global is_win9x - - set output1 "" - set output2 "" - if {! $is_win9x} { - # try for tasklist on XP pro - catch {set output1 [exec tasklist.exe]} - } - catch {set output2 [exec w98/tlist.exe]} - - set output $output1 - append output "\n" - append output $output2 - - return $output -} - -proc note_stunnel_pids {when} { - global is_win9x pids_before pids_after pids_new - - if {$when == "before"} { - array unset pids_before - array unset pids_after - set pids_new {} - set pids_before(none) "none" - set pids_after(none) "none" - } - - set output [get_task_list] - - foreach line [split $output "\n\r"] { - set m 0 - if [regexp -nocase {stunnel} $line] { - set m 1 - } elseif [regexp -nocase {connect_br} $line] { - set m 1 - } - if {$m} { - if [regexp {(-?[0-9][0-9]*)} $line m p] { - if {$when == "before"} { - set pids_before($p) $line - } else { - set pids_after($p) $line - } - } - } - } - if {$when == "after"} { - foreach new [array names pids_after] { - if {! [info exists pids_before($new)]} { - lappend pids_new $new - } - } - } -} - -proc del_launch_windows_ssh_files {} { - global launch_windows_ssh_files - global env - - if {[info exists env(SSVNC_NO_DELETE)]} { - return - } - - if {$launch_windows_ssh_files != ""} { - foreach tf [split $launch_windows_ssh_files] { - if {$tf == ""} { - continue - } - catch {file delete $tf} - } - } -} - -proc launch_shell_only {} { - global is_windows - global skip_pre - global use_ssl use_ssh use_sshssl - - set hp [get_vncdisplay] - regsub {cmd=.*$} $hp "" hp - set hp [string trim $hp] - if {$is_windows} { - append hp " cmd=PUTTY" - } else { - append hp " cmd=SHELL" - } - set use_ssl_save $use_ssl - set use_ssh_save $use_ssh - set use_sshssl_save $use_sshssl - set skip_pre 1 - if {! $use_ssh && ! $use_sshssl} { - set use_ssh 1 - set use_ssl 1 - } - launch $hp - - set use_ssl $use_ssl_save - set use_ssh $use_ssh_save - set use_sshssl $use_sshssl_save -} - -proc to_sshonly {} { - global ssh_only ts_only env - global showing_no_encryption - #if {$showing_no_encryption} { - # toggle_no_encryption - #} - if {$ssh_only && !$ts_only} { - return - } - if {[info exists env(SSVNC_TS_ALWAYS)]} { - return - } - set ssh_only 1 - set ts_only 0 - - set t "SSH VNC Viewer" - wm title . $t - catch {pack forget .f4} - catch {pack forget .b.certs} - catch {.l configure -text $t} - - global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd - set vncdisplay "" - set vncauth_passwd "" - set unixpw_username "" - set vncproxy "" - set remote_ssh_cmd "" - - set_defaults -} - -proc toggle_tsonly {} { - global ts_only env - if {$ts_only} { - if {![info exists env(SSVNC_TS_ALWAYS)]} { - to_ssvnc - } - } else { - to_tsonly - } -} - -proc toggle_sshonly {} { - global ssh_only env - if {$ssh_only} { - to_ssvnc - } else { - to_sshonly - } -} - -proc to_tsonly {} { - global ts_only - global showing_no_encryption - #if {$showing_no_encryption} { - # toggle_no_encryption - #} - if {$ts_only} { - return - } - set ts_only 1 - set ssh_only 1 - - set t "Terminal Services VNC Viewer" - wm title . $t - catch {pack forget .f4} - catch {pack forget .f3} - catch {pack forget .f1} - catch {pack forget .b.certs} - catch {.l configure -text $t} - catch {.f0.l configure -text "VNC Terminal Server:"} - - global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd - set vncdisplay "" - set vncauth_passwd "" - set unixpw_username "" - set vncproxy "" - set remote_ssh_cmd "" - - set_defaults -} - -proc to_ssvnc {} { - global ts_only ssh_only env - - if {!$ts_only && !$ssh_only} { - return; - } - if {[info exists env(SSVNC_TS_ALWAYS)]} { - return - } - set ts_only 0 - set ssh_only 0 - - set t "SSL/SSH VNC Viewer" - wm title . $t - catch {pack configure .f1 -after .f0 -side top -fill x} - catch {pack configure .f3 -after .f2 -side top -fill x} - catch {pack configure .f4 -after .f3 -side top -fill x} - catch {pack configure .b.certs -before .b.opts -side left -expand 1 -fill x} - catch {.l configure -text $t} - catch {.f0.l configure -text "VNC Host:Display"} - - #global started_with_noenc - #if {$started_with_noenc} { - # toggle_no_encryption - #} - - global vncdisplay vncauth_passwd unixpw_username vncproxy remote_ssh_cmd - set vncdisplay "" - set vncauth_passwd "" - set unixpw_username "" - set vncproxy "" - set remote_ssh_cmd "" - - set_defaults -} - -proc launch {{hp ""}} { - global tcl_platform is_windows - global mycert svcert crtdir crlfil - global pids_before pids_after pids_new - global env - global use_ssl use_ssh use_sshssl sshssl_sw use_listen disable_ssl_workarounds - global vncdisplay - - set debug 0 - if {$hp == ""} { - set hp [get_vncdisplay] - } - - set hpt [string trim $hp] - regsub {[ ].*$} $hpt "" hpt - - - if {[regexp {^HOME=} $hpt] || [regexp {^SSVNC_HOME=} $hpt]} { - set t $hpt - regsub {^.*HOME=} $t "" t - set t [string trim $t] - set env(SSVNC_HOME) $t - mesg "Set SSVNC_HOME to $t" - set vncdisplay "" - return 0 - } - if {[regexp {^DISPLAY=} $hpt] || [regexp {^SSVNC_DISPLAY=} $hpt]} { - set t $hpt - regsub {^.*DISPLAY=} $t "" t - set t [string trim $t] - set env(DISPLAY) $t - mesg "Set DISPLAY to $t" - set vncdisplay "" - global uname darwin_cotvnc - if {$uname == "Darwin"} { - if {$t != ""} { - set darwin_cotvnc 0 - } else { - set darwin_cotvnc 1 - } - } - return 0 - } - if {[regexp {^DYLD_LIBRARY_PATH=} $hpt] || [regexp {^SSVNC_DYLD_LIBRARY_PATH=} $hpt]} { - set t $hpt - regsub {^.*DYLD_LIBRARY_PATH=} $t "" t - set t [string trim $t] - set env(DYLD_LIBRARY_PATH) $t - set env(SSVNC_DYLD_LIBRARY_PATH) $t - mesg "Set DYLD_LIBRARY_PATH to $t" - set vncdisplay "" - return 0 - } - if {[regexp {^SLEEP=} $hpt] || [regexp {^SSVNC_EXTRA_SLEEP=} $hpt]} { - set t $hpt - regsub {^.*SLEEP=} $t "" t - set t [string trim $t] - set env(SSVNC_EXTRA_SLEEP) $t - mesg "Set SSVNC_EXTRA_SLEEP to $t" - set vncdisplay "" - return 0 - } - if {[regexp {^SSH=} $hpt]} { - set t $hpt - regsub {^.*SSH=} $t "" t - set t [string trim $t] - set env(SSH) $t - mesg "Set SSH to $t" - set vncdisplay "" - return 0 - } - if {[regexp {^FINISH=} $hpt] || [regexp {^SSVNC_FINISH_SLEEP=} $hpt]} { - set t $hpt - regsub {^.*=} $t "" t - set t [string trim $t] - set env(SSVNC_FINISH_SLEEP) $t - mesg "Set SSVNC_FINISH_SLEEP to $t" - set vncdisplay "" - return 0 - } - if {[regexp {^NO_DELETE=} $hpt] || [regexp {^SSVNC_NO_DELETE=} $hpt]} { - set t $hpt - regsub {^.*=} $t "" t - set t [string trim $t] - set env(SSVNC_NO_DELETE) $t - mesg "Set SSVNC_NO_DELETE to $t" - set vncdisplay "" - return 0 - } - if {[regexp {^BAT_SLEEP=} $hpt] || [regexp {^SSVNC_BAT_SLEEP=} $hpt]} { - set t $hpt - regsub {^.*=} $t "" t - set t [string trim $t] - set env(SSVNC_BAT_SLEEP) $t - mesg "Set SSVNC_BAT_SLEEP to $t" - set vncdisplay "" - return 0 - } - if {[regexp {^DEBUG_NETSTAT=} $hpt]} { - set t $hpt - regsub {^.*DEBUG_NETSTAT=} $t "" t - global debug_netstat - set debug_netstat $t - mesg "Set DEBUG_NETSTAT to $t" - set vncdisplay "" - return 0 - } - if {[regexp {^REPEATER_FORCE=} $hpt]} { - set t $hpt - regsub {^.*REPEATER_FORCE=} $t "" t - set env(REPEATER_FORCE) $t - mesg "Set REPEATER_FORCE to $t" - set vncdisplay "" - return 0 - } - if {[regexp -nocase {^SSH.?ONLY} $hpt]} { - global ssh_only - if {$ssh_only} { - return 0; - } - to_sshonly - - return 0 - } - if {[regexp -nocase {^TS.?ONLY} $hpt]} { - global ts_only - if {$ts_only} { - return 0; - } - to_tsonly - - return 0 - } - if {[regexp -nocase {^IPV6=([01])} $hpt mv val]} { - global env have_ipv6 - set have_ipv6 $val - set env(SSVNC_IPV6) $val - mesg "Set have_ipv6 to $val" - set vncdisplay "" - return 0 - } - if {[regexp {^ENV=([A-z0-9][A-z0-9]*)=(.*)$} $hpt mv var val]} { - global env - if {$val == ""} { - catch {unset env($var)} - mesg "Unset $var" - } else { - set env($var) "$val" - mesg "Set $var to $val" - } - set vncdisplay "" - return 0 - } - - regsub {[ ]*cmd=.*$} $hp "" tt - - if {[regexp {^[ ]*$} $tt]} { - mesg "No host:disp supplied." - bell - catch {raise .} - mac_raise - return - } - if {[regexp -- {--nohost--} $tt]} { - mesg "No host:disp supplied." - bell - catch {raise .} - mac_raise - return - } - # XXX host_part - if {! [regexp ":" $hp]} { - if {! [regexp {cmd=} $hp]} { - set s [string trim $hp] - if {! [regexp { } $s]} { - append hp ":0" - } else { - regsub { } $hp ":0 " hp - } - } - } - - if {!$use_ssl && !$use_ssh && !$use_sshssl && $sshssl_sw == "none"} { - regsub -nocase {^[a-z0-9+]*://} $hp "" hp - set hp "Vnc://$hp" - } - - mesg "Using: $hp" - after 600 - - set sc [get_ssh_cmd $hp] - if {[regexp {^KNOCK} $sc]} { - if [regexp {^KNOCKF} $sc] { - port_knock_only $hp "FINISH" - } else { - port_knock_only $hp "KNOCK" - } - return - } - - if {$debug} { - mesg "\"$tcl_platform(os)\" | \"$tcl_platform(osVersion)\"" - after 1000 - } - - if [regexp {V[Nn][Cc]://} $hp] { - set env(SSVNC_NO_ENC_WARN) 1 - regsub {V[Nn][Cc]://} $hp "vnc://" hp - } - regsub -nocase {^vnc://} $hp "vnc://" hp - regsub -nocase {^vncs://} $hp "vncs://" hp - regsub -nocase {^vncssl://} $hp "vncssl://" hp - regsub -nocase {^vnc\+ssl://} $hp "vnc+ssl://" hp - regsub -nocase {^vncssh://} $hp "vncssh://" hp - regsub -nocase {^vnc\+ssh://} $hp "vnc+ssh://" hp - - if {! $is_windows} { - launch_unix $hp - return - } - - ############################################################## - # WINDOWS BELOW: - - if [regexp {^vnc://} $hp] { - if {! [info exists env(SSVNC_NO_ENC_WARN)]} { - direct_connect_msg - } - regsub {^vnc://} $hp "" hp - direct_connect_windows $hp - return - } elseif [regexp {^vncs://} $hp] { - set use_ssl 1 - set use_ssh 0 - regsub {^vncs://} $hp "" hp - sync_use_ssl_ssh - } elseif [regexp {^vncssl://} $hp] { - set use_ssl 1 - set use_ssh 0 - regsub {^vncssl://} $hp "" hp - sync_use_ssl_ssh - } elseif [regexp {^vnc\+ssl://} $hp] { - set use_ssl 1 - set use_ssh 0 - regsub {^vnc\+ssl://} $hp "" hp - sync_use_ssl_ssh - } elseif [regexp {^vncssh://} $hp] { - set use_ssh 1 - set use_ssl 0 - regsub {vncssh://} $hp "" hp - sync_use_ssl_ssh - } elseif [regexp {^vnc\+ssh://} $hp] { - set use_ssh 1 - set use_ssl 0 - regsub {^vnc\+ssh://} $hp "" hp - sync_use_ssl_ssh - } - - check_ssh_needed - - if {! $use_ssh} { - if {$mycert != ""} { - if {! [file exists $mycert]} { - mesg "MyCert does not exist: $mycert" - bell - return - } - } - if {$svcert != ""} { - if {! [file exists $svcert]} { - mesg "ServerCert does not exist: $svcert" - bell - return - } - } elseif {$crtdir != ""} { - if {! [file exists $crtdir] && $crtdir != "ACCEPTED_CERTS"} { - mesg "CertsDir does not exist: $crtdir" - bell - return - } - } - if {$crlfil != ""} { - if {! [file exists $crlfil]} { - mesg "CRL File does not exist: $crlfil" - bell - return - } - } - } - - # VF - set prefix "stunnel-vnc" - set suffix "conf" - if {$use_ssh || $use_sshssl} { - set prefix "plink_vnc" - set suffix "bat" - } - - set file1 "" - set n1 "" - set file2 "" - set n2 "" - set n3 "" - set n4 "" - set now [clock seconds] - - set proxy [get_ssh_proxy $hp] - if {$use_sshssl} { - set proxy "" - } - if {! [repeater_proxy_check $proxy]} { - return - } - - global port_slot - if {$port_slot != ""} { - set file1 "$prefix-$port_slot.$suffix" - set n1 $port_slot - set ps [expr $port_slot + 200] - set file2 "$prefix-$ps.$suffix" - set n2 $ps - mesg "Using Port Slot: $port_slot" - after 700 - } - - for {set i 30} {$i <= 99} {incr i} { - set try "$prefix-$i.$suffix" - if {$i == $port_slot} { - continue - } - if {[file exists $try]} { - set mt [file mtime $try] - set age [expr "$now - $mt"] - set week [expr "7 * 3600 * 24"] - if {$age > $week} { - catch {file delete $try} - } - } - if {! [file exists $try]} { - if {$file1 == ""} { - set file1 $try - set n1 $i - } elseif {$file2 == ""} { - set file2 $try - set n2 $i - } else { - break - } - } - } - - if {$file1 == ""} { - mesg "could not find free stunnel file" - bell - return - } - - if {$n1 == ""} { - set n1 10 - } - if {$n2 == ""} { - set n2 11 - } - set n3 [expr $n1 + 100] - set n4 [expr $n2 + 100] - - global launch_windows_ssh_files - set launch_windows_ssh_files "" - - set did_port_knock 0 - - global listening_name - set listening_name "" - - if {$use_ssh} { - ; - } elseif {$use_sshssl} { - ; - } elseif {$use_ssl} { - if {$proxy != "" && [regexp {@} $proxy]} { - mesg "Error: proxy contains '@' Did you mean to use SSH mode?" - bell - return - } - if [regexp {@} $hp] { - mesg "Error: host contains '@' Did you mean to use SSH mode?" - bell - return - } - } - - global ssh_ipv6_pid - set ssh_ipv6_pid "" - - if {$use_sshssl} { - set rc [launch_windows_ssh $hp $file2 $n2] - if {$rc == 0} { - if {![info exists env(SSVNC_NO_DELETE)]} { - catch {file delete $file1} - catch {file delete $file2} - } - del_launch_windows_ssh_files - return - } - set did_port_knock 1 - } elseif {$use_ssh} { - launch_windows_ssh $hp $file1 $n1 - # WE ARE DONE. - return - } - - set host [host_part $hp]; - set host_orig $host - - global win_localhost - - if {$host == ""} { - set host $win_localhost - } - - if [regexp {^.*@} $host match] { - catch {raise .; update} - mesg "Trimming \"$match\" from hostname" - after 700 - regsub {^.*@} $host "" host - } - - set disp [port_part $hp] - if {[regexp {^-[0-9][0-9]*$} $disp]} { - ; - } elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} { - set disp 0 - } - - if {$disp < 0} { - set port [expr "- $disp"] - } elseif {$disp < 200} { - if {$use_listen} { - set port [expr "$disp + 5500"] - } else { - set port [expr "$disp + 5900"] - } - } else { - set port $disp - } - - if {$debug} { - mesg "file: $file1" - after 1000 - } - - listen_verify_all_dialog $hp - - if {$use_listen && $mycert == ""} { - if {! [check_for_listen_ssl_cert]} { - return; - } - } - - set fail 0 - - set fh [open $file1 "w"] - - if {$use_listen} { - puts $fh "client = no" - } else { - puts $fh "client = yes" - } - global disable_ssl_workarounds disable_ssl_workarounds_type - if {$disable_ssl_workarounds} { - if {$disable_ssl_workarounds_type == "noempty"} { - puts $fh "options = DONT_INSERT_EMPTY_FRAGMENTS" - } - } else { - puts $fh "options = ALL" - } - - puts $fh "taskbar = yes" - puts $fh "RNDbytes = 2048" - puts $fh "RNDfile = bananarand.bin" - puts $fh "RNDoverwrite = yes" - puts $fh "debug = 6" - - if {$mycert != ""} { - if {! [file exists $mycert]} { - mesg "MyCert does not exist: $mycert" - bell - set fail 1 - } - puts $fh "cert = $mycert" - } elseif {$use_listen} { - # see above, this should not happen. - puts $fh "cert = _nocert_" - } - if {$crlfil != ""} { - if [file isdirectory $crlfil] { - puts $fh "CRLpath = $crlfil" - } else { - puts $fh "CRLfile = $crlfil" - } - } - - set did_check 0 - - if {$svcert != ""} { - if {! [file exists $svcert]} { - mesg "ServerCert does not exist: $svcert" - bell - set fail 1 - } - puts $fh "CAfile = $svcert" - puts $fh "verify = 2" - } elseif {$crtdir != ""} { - if {$crtdir == "ACCEPTED_CERTS"} { - global skip_verify_accepted_certs - set skip_verify_accepted_certs 0 - set did_check 1 - if {$use_sshssl} { - set skip_verify_accepted_certs 1 - set did_check 0 - } elseif {! [check_accepted_certs 0]} { - set fail 1 - } - if {! $skip_verify_accepted_certs} { - set adir [get_idir_certs ""] - set adir "$adir/accepted" - catch {file mkdir $adir} - puts $fh "CApath = $adir" - puts $fh "verify = 2" - } - } else { - if {! [file exists $crtdir]} { - mesg "CertsDir does not exist: $crtdir" - bell - set fail 1 - } - puts $fh "CApath = $crtdir" - puts $fh "verify = 2" - } - } - - if {!$did_check} { - check_accepted_certs 1 - } - - if {$use_sshssl} { - set p [expr "$n2 + 5900"] - set proxy [maybe_add_vencrypt $proxy "$win_localhost:$p"] - } else { - set proxy [maybe_add_vencrypt $proxy $hp] - } - - set ipv6_pid "" - global have_ipv6 - if {$have_ipv6} { - if {$proxy == "" && $use_ssl} { - # stunnel can handle ipv6 - } else { - set res [ipv6_proxy $proxy $host $port] - set proxy [lindex $res 0] - set host [lindex $res 1] - set port [lindex $res 2] - set ipv6_pid [lindex $res 3] - } - } - - set p_reverse 0 - - if {$proxy != ""} { - if {$use_sshssl} { - ; - } elseif [regexp {@} $proxy] { - bell - catch {raise .; update} - mesg "WARNING: SSL proxy contains \"@\" sign" - after 1500 - } - set env(SSVNC_PROXY) $proxy - set env(SSVNC_DEST) "$host:$port" - if {$use_listen} { - set env(SSVNC_REVERSE) "$win_localhost:$port" - set env(CONNECT_BR_SLEEP) 3 - set p_reverse 1 - } else { - if {$use_sshssl && [regexp {vencrypt:} $proxy]} { - set env(SSVNC_LISTEN) [expr "$n4 + 5900"] - } else { - set env(SSVNC_LISTEN) [expr "$n2 + 5900"] - } - } - if {[info exists env(PROXY_DEBUG)]} { - foreach var [list SSVNC_PROXY SSVNC_DEST SSVNC_REVERSE CONNECT_BR_SLEEP SSVNC_LISTEN] { - if [info exists env($var)] { - mesg "$var $env($var)"; after 2500; - } - } - } - } - - global anon_dh_detected server_anondh - if {$anon_dh_detected || $server_anondh} { - puts $fh "ciphers = ALL:RC4+RSA:+SSLv2:@STRENGTH" - set anon_dh_detected 0 - } - - - puts $fh "\[vnc$n1\]" - set port2 "" - set port3 "" - if {! $use_listen} { - set port2 [expr "$n1 + 5900"] - if [regexp {vencrypt:} $proxy] { - set port3 [expr "$n3 + 5900"] - set port2 $port3 - puts $fh "accept = $win_localhost:$port3" - } else { - puts $fh "accept = $win_localhost:$port2" - } - - if {$use_sshssl && [regexp {vencrypt:} $proxy]} { - set port [expr "$n4 + 5900"] - puts $fh "connect = $win_localhost:$port" - } elseif {$use_sshssl || $proxy != ""} { - set port [expr "$n2 + 5900"] - puts $fh "connect = $win_localhost:$port" - } else { - puts $fh "connect = $host:$port" - } - } else { - set port2 [expr "$n1 + 5500"] - set hloc "" - if {$use_ssh} { - # not reached? - set hloc "$win_localhost:" - set listening_name "$win_localhost:$port (on remote SSH side)" - } else { - set hn [get_hostname] - if {$hn == ""} { - set hn "this-computer" - } - set listening_name "$hn:$port (or nn.nn.nn.nn:$port, etc.)" - } - if {$host_orig != "" && $hloc == ""} { - set hloc "$host_orig:" - } - puts $fh "accept = $hloc$port" - puts $fh "connect = $win_localhost:$port2" - } - - puts $fh "delay = no" - puts $fh "" - close $fh - - if {! $did_port_knock} { - if {! [do_port_knock $host start]} { - set fail 1 - } - set did_port_knock 1 - } - - if {$fail} { - if {![info exists env(SSVNC_NO_DELETE)]} { - catch {file delete $file1} - } - catch { unset env(SSVNC_PROXY) } - catch { unset env(SSVNC_LISTEN) } - catch { unset env(SSVNC_REVERSE) } - catch { unset env(SSVNC_DEST) } - catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) } - catch { unset env(CONNECT_BR_SLEEP) } - winkill $ipv6_pid - winkill $ssh_ipv6_pid - set ssh_ipv6_pid "" - return - } - - note_stunnel_pids "before" - - set proxy_pid "" - set proxy_pid2 "" - - if {$use_listen} { - windows_listening_message $n1 - } - - if {$proxy != ""} { - if [regexp {vencrypt:} $proxy] { - set vport [expr "$n1 + 5900"] - mesg "Starting VeNCrypt helper on port $vport,$port3 ..." - after 500 - if {![info exists env(SSVNC_NO_DELETE)]} { - catch {file delete "$file1.pre"} - } - set env(SSVNC_PREDIGESTED_HANDSHAKE) "$file1.pre" - set env(SSVNC_VENCRYPT_VIEWER_BRIDGE) "$vport,$port3" - set proxy_pid2 [exec "connect_br.exe" &] - catch { unset env(SSVNC_VENCRYPT_VIEWER_BRIDGE) } - } - mesg "Starting TCP helper on port $port ..." - after 400 - # ssl br case: - set proxy_pid [exec "connect_br.exe" &] - catch { unset env(SSVNC_PROXY) } - catch { unset env(SSVNC_LISTEN) } - catch { unset env(SSVNC_REVERSE) } - catch { unset env(SSVNC_DEST) } - catch { unset env(SSVNC_PREDIGESTED_HANDSHAKE) } - catch { unset env(CONNECT_BR_SLEEP) } - } - - mesg "Starting STUNNEL on port $port2 ..." - after 500 - - set pids [exec stunnel $file1 &] - - if {! $p_reverse} { - after 300 - set vtm [vencrypt_tutorial_mesg] - if {$vtm == ""} { - after 300 - } - } - - note_stunnel_pids "after" - - if {$debug} { - after 1000 - mesg "pids $pids" - after 1000 - } else { - catch {destroy .o} - catch {destroy .oa} - catch {destroy .os} - wm withdraw . - } - - do_viewer_windows $n1 - - del_launch_windows_ssh_files - - if {![info exists env(SSVNC_NO_DELETE)]} { - catch {file delete $file1} - } - - if {$debug} { - ; - } else { - wm deiconify . - } - mesg "Disconnected from $hp." - - global port_knocking_list - if [regexp {FINISH} $port_knocking_list] { - do_port_knock $host finish - } - - if {[llength $pids_new] > 0} { - set plist [join $pids_new ", "] - global terminate_pids - set terminate_pids "" - global kill_stunnel - if {$kill_stunnel} { - set terminate_pids yes - } else { - win_kill_msg $plist - update - vwait terminate_pids - } - if {$terminate_pids == "yes"} { - kill_stunnel $pids_new - } - } else { - win_nokill_msg - } - mesg "Disconnected from $hp." - winkill $ipv6_pid - winkill $ssh_ipv6_pid - set ssh_ipv6_pid "" - - global is_win9x use_sound sound_daemon_local_kill sound_daemon_local_cmd - if {! $is_win9x && $use_sound && $sound_daemon_local_kill && $sound_daemon_local_cmd != ""} { - windows_stop_sound_daemon - } -} - -proc direct_connect_windows {{hp ""}} { - global tcl_platform is_windows - global env use_listen - - set proxy [get_ssh_proxy $hp] - - set did_port_knock 0 - - global listening_name - set listening_name "" - - set host [host_part $hp] - - set host_orig $host - - global win_localhost - if {$host == ""} { - set host $win_localhost - } - - if [regexp {^.*@} $host match] { - catch {raise .; update} - mesg "Trimming \"$match\" from hostname" - after 700 - regsub {^.*@} $host "" host - } - - set disp [port_part $hp] - if {[regexp {^-[0-9][0-9]*$} $disp]} { - ; - } elseif {$disp == "" || ! [regexp {^[0-9][0-9]*$} $disp]} { - set disp 0 - } - - if {$disp < 0} { - set port [expr "- $disp"] - } elseif {$disp < 200} { - if {$use_listen} { - set port [expr "$disp + 5500"] - } else { - set port [expr "$disp + 5900"] - } - } else { - set port $disp - } - - global have_ipv6 - set ipv6_pid "" - if {$have_ipv6 && !$use_listen} { - set res [ipv6_proxy $proxy $host $port] - set proxy [lindex $res 0] - set host [lindex $res 1] - set port [lindex $res 2] - set ipv6_pid [lindex $res 3] - } - - if {$proxy != ""} { - if [regexp {@} $proxy] { - bell - catch {raise .; update} - mesg "WARNING: SSL proxy contains \"@\" sign" - after 1500 - } - set n2 45 - - set env(SSVNC_PROXY) $proxy - set env(SSVNC_LISTEN) [expr "$n2 + 5900"] - set env(SSVNC_DEST) "$host:$port" - - set port [expr $n2 + 5900] - set host $win_localhost - } - - set fail 0 - if {! $did_port_knock} { - if {! [do_port_knock $host start]} { - set fail 1 - } - set did_port_knock 1 - } - - if {$fail} { - catch { unset env(SSVNC_PROXY) } - catch { unset env(SSVNC_LISTEN) } - catch { unset env(SSVNC_DEST) } - winkill $ipv6_pid - return - } - - set proxy_pid "" - if {$proxy != ""} { - mesg "Starting Proxy TCP helper on port $port ..." - after 400 - # unencrypted br case: - set proxy_pid [exec "connect_br.exe" &] - catch { unset env(SSVNC_PROXY) } - catch { unset env(SSVNC_LISTEN) } - catch { unset env(SSVNC_DEST) } - } - - vencrypt_tutorial_mesg - - catch {destroy .o} - catch {destroy .oa} - catch {destroy .os} - wm withdraw . - - if {$use_listen} { - set n $port - if {$n >= 5500} { - set n [expr $n - 5500] - } - global direct_connect_reverse_host_orig - set direct_connect_reverse_host_orig $host_orig - - do_viewer_windows "$n" - - set direct_connect_reverse_host_orig "" - } else { - if {$port >= 5900 && $port < 6100} { - set port [expr $port - 5900] - } - do_viewer_windows "$host:$port" - } - - wm deiconify . - - mesg "Disconnected from $hp." - - winkill $ipv6_pid - - global port_knocking_list - if [regexp {FINISH} $port_knocking_list] { - do_port_knock $host finish - } - - mesg "Disconnected from $hp." -} - -proc get_idir_certs {str} { - global is_windows env - set idir "" - if {$str != ""} { - if [file isdirectory $str] { - set idir $str - } else { - set idir [file dirname $str] - } - if {$is_windows} { - regsub -all {\\} $idir "/" idir - regsub -all {//*} $idir "/" idir - } - } - if {$idir == ""} { - if {$is_windows} { - if [info exists env(SSVNC_HOME)] { - set t "$env(SSVNC_HOME)/ss_vnc" - regsub -all {\\} $t "/" t - regsub -all {//*} $t "/" t - if {! [file isdirectory $t]} { - catch {file mkdir $t} - } - set t "$env(SSVNC_HOME)/ss_vnc/certs" - regsub -all {\\} $t "/" t - regsub -all {//*} $t "/" t - if {! [file isdirectory $t]} { - catch {file mkdir $t} - } - if [file isdirectory $t] { - set idir $t - } - } - if {$idir == ""} { - set t [file dirname [pwd]] - set t "$t/certs" - if [file isdirectory $t] { - set idir $t - } - } - } - if {$idir == ""} { - if [info exists env(SSVNC_HOME)] { - set t "$env(SSVNC_HOME)/.vnc" - if {! [file isdirectory $t]} { - catch {file mkdir $t} - } - set t "$env(SSVNC_HOME)/.vnc/certs" - if {! [file isdirectory $t]} { - catch {file mkdir $t} - } - if [file isdirectory $t] { - set idir $t - } - } - } - } - if {$idir == ""} { - if {$is_windows} { - set idir [get_profiles_dir] - } - if {$idir == ""} { - set idir [pwd] - } - } - return $idir -} - -proc delete_cert {{parent "."}} { - set idir [get_idir_certs ""] - set f "" - unix_dialog_resize $parent - if {$idir != ""} { - set f [tk_getOpenFile -parent $parent -initialdir $idir] - } else { - set f [tk_getOpenFile -parent $parent] - } - if {$f != "" && [file exists $f]} { - set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f"] - if {$reply == "yes"} { - global mycert svcert crlfil - set f_text [read_file $f] - set f2 "" - catch {file delete $f} - if {$f == $mycert} { set mycert "" } - if {$f == $svcert} { set svcert "" } - if {$f == $crlfil} { set crlfil "" } - if [regexp {\.crt$} $f] { - regsub {\.crt$} $f ".pem" f2 - } elseif [regexp {\.pem$} $f] { - regsub {\.pem$} $f ".crt" f2 - } - if {$f2 != "" && [file exists $f2]} { - set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Cert" -message "Delete $f2"] - if {$reply == "yes"} { - catch {file delete $f2} - if {$f2 == $mycert} { set mycert "" } - if {$f2 == $svcert} { set svcert "" } - if {$f2 == $crlfil} { set crlfil "" } - } - } - set dir [file dirname $f] - if {$f_text != "" && [regexp {accepted$} $dir]} { - foreach crt [glob -nocomplain -directory $dir {*.crt} {*.pem} {*.[0-9]}] { - #puts "try $crt" - set c_text [read_file $crt] - if {$c_text == ""} { - continue - } - if {$c_text != $f_text} { - continue - } - set reply [tk_messageBox -parent $parent -type yesno -icon question -title "Delete Identical Cert" -message "Delete Identical $crt"] - if {$reply == "yes"} { - catch {file delete $crt} - } - } - } - } - } - catch {wm deiconify .c} - update -} - -proc set_mycert {{parent "."}} { - global mycert - set idir [get_idir_certs $mycert] - set t "" - unix_dialog_resize $parent - if {$idir != ""} { - set t [tk_getOpenFile -parent $parent -initialdir $idir] - } else { - set t [tk_getOpenFile -parent $parent] - } - if {$t != ""} { - set mycert $t - } - catch {wm deiconify .c} - v_mycert - update -} - -proc set_crlfil {{parent "."}} { - global crlfil - set idir [get_idir_certs $crlfil] - set t "" - unix_dialog_resize $parent - if {$idir != ""} { - set t [tk_getOpenFile -parent $parent -initialdir $idir] - } else { - set t [tk_getOpenFile -parent $parent] - } - if {$t != ""} { - set crlfil $t - } - catch {wm deiconify .c} - v_crlfil - update -} - -proc set_ultra_dsm_file {{parent "."}} { - global ultra_dsm_file - set idir [get_idir_certs $ultra_dsm_file] - set t "" - unix_dialog_resize $parent - if {$idir != ""} { - set t [tk_getOpenFile -parent $parent -initialdir $idir] - } else { - set t [tk_getOpenFile -parent $parent] - } - if {$t != ""} { - set ultra_dsm_file $t - } - update -} - -proc set_ssh_known_hosts_file {{parent "."}} { - global ssh_known_hosts_filename is_windows uname - - if {$ssh_known_hosts_filename == ""} { - set pdir [get_profiles_dir] - set pdir "$pdir/ssh_known_hosts" - catch {file mkdir $pdir} - - global last_load - if {![info exists last_load]} { - set last_load "" - } - if {$last_load != ""} { - set dispf [string trim $last_load] - set dispf [file tail $dispf] - - regsub {\.vnc$} $dispf "" dispf - if {![regexp {\.known$} $dispf]} { - set dispf "$dispf.known" - } - set guess $dispf - } else { - set vncdisp [get_vncdisplay] - set dispf [string trim $vncdisp] - if {$dispf != ""} { - regsub {[ ].*$} $dispf "" dispf - regsub -all {/} $dispf "" dispf - } else { - set dispf "unique-name-here" - } - if {$is_windows || $uname == "Darwin"} { - regsub -all {:} $dispf "-" dispf - } else { - regsub -all {:} $dispf "-" dispf - } - if {![regexp {\.known$} $dispf]} { - set dispf "$dispf.known" - } - set guess $dispf - } - } else { - set pdir [file dirname $ssh_known_hosts_filename] - set guess [file tail $ssh_known_hosts_filename] - } - - set t "" - unix_dialog_resize $parent - if {$pdir != ""} { - set t [tk_getSaveFile -parent $parent -initialdir $pdir -initialfile $guess] - } else { - set t [tk_getSaveFile -parent $parent -initialfile $guess] - } - if {$t != ""} { - set ssh_known_hosts_filename $t - } - update -} - -proc show_cert {crt} { - if {$crt == ""} { - bell - return - } - if {! [file exists $crt]} { - bell - return - } - set info "" - catch {set info [get_x509_info $crt]} - if {$info == ""} { - bell - return - } - - set w .show_certificate - toplev $w - scroll_text $w.f - button $w.b -text Dismiss -command "destroy $w" - bind $w <Escape> "destroy $w" - $w.f.t insert end $info - - pack $w.b -side bottom -fill x - pack $w.f -side top -fill both -expand 1 - center_win $w - catch {raise $w} -} - -proc show_crl {crl} { - if {$crl == ""} { - bell - return - } - if {! [file exists $crl]} { - bell - return - } - - set flist [list] - - if [file isdirectory $crl] { - foreach cfile [glob -nocomplain -directory $crl "*"] { - if [file isfile $cfile] { - lappend flist $cfile - } - } - } else { - lappend flist $crl - } - - set ossl [get_openssl] - set info "" - - foreach cfile $flist { - catch { - set ph [open "| $ossl crl -fingerprint -text -noout -in \"$cfile\"" "r"] - while {[gets $ph line] > -1} { - append info "$line\n" - } - close $ph - append info "\n" - } - } - - set w .show_crl - toplev $w - scroll_text $w.f - button $w.b -text Dismiss -command "destroy $w" - bind $w <Escape> "destroy $w" - $w.f.t insert end $info - - pack $w.b -side bottom -fill x - pack $w.f -side top -fill both -expand 1 - center_win $w - catch {raise $w} -} - -proc v_svcert {} { - global svcert - if {$svcert == "" || ! [file exists $svcert]} { - catch {.c.svcert.i configure -state disabled} - } else { - catch {.c.svcert.i configure -state normal} - } - no_certs_tutorial_mesg - return 1 -} - -proc v_mycert {} { - global mycert - if {$mycert == "" || ! [file exists $mycert]} { - catch {.c.mycert.i configure -state disabled} - } else { - catch {.c.mycert.i configure -state normal} - } - return 1 -} - -proc v_crlfil {} { - global crlfil - if {$crlfil == "" || ! [file exists $crlfil]} { - catch {.c.crlfil.i configure -state disabled} - } else { - catch {.c.crlfil.i configure -state normal} - } - return 1 -} - -proc show_mycert {} { - global mycert - show_cert $mycert -} - -proc show_svcert {} { - global svcert - show_cert $svcert -} - -proc show_crlfil {} { - global crlfil - show_crl $crlfil -} - -proc set_svcert {{parent "."}} { - global svcert crtdir - set idir [get_idir_certs $svcert] - set t "" - unix_dialog_resize $parent - if {$idir != ""} { - set t [tk_getOpenFile -parent $parent -initialdir $idir] - } else { - set t [tk_getOpenFile -parent $parent] - } - if {$t != ""} { - set crtdir "" - set svcert $t - } - catch {wm deiconify .c} - v_svcert - update -} - -proc set_crtdir {{parent "."}} { - global svcert crtdir - set idir "" - if {$crtdir == "ACCEPTED_CERTS"} { - set idir [get_idir_certs ""] - } else { - set idir [get_idir_certs $crtdir] - } - set t "" - unix_dialog_resize $parent - if {$idir != ""} { - set t [tk_chooseDirectory -parent $parent -initialdir $idir] - } else { - set t [tk_chooseDirectory -parent $parent] - } - if {$t != ""} { - set svcert "" - set crtdir $t - } - catch {wm deiconify .c} - update -} - -proc set_createcert_file {} { - global ccert - if {[info exists ccert(FILE)]} { - set idir [get_idir_certs $ccert(FILE)] - } - unix_dialog_resize .ccrt - if {$idir != ""} { - set t [tk_getSaveFile -parent .ccrt -defaultextension ".pem" -initialdir $idir] - } else { - set t [tk_getSaveFile -parent .ccrt -defaultextension ".pem"] - } - if {$t != ""} { - set ccert(FILE) $t - } - catch {raise .ccrt} - update -} - -proc check_pp {} { - global ccert - if {$ccert(ENC)} { - catch {.ccrt.pf.e configure -state normal} - catch {focus .ccrt.pf.e} - catch {.ccrt.pf.e icursor end} - } else { - catch {.ccrt.pf.e configure -state disabled} - } -} - -proc get_openssl {} { - global is_windows - if {$is_windows} { - set ossl "openssl.exe" - } else { - set ossl "openssl" - } -} - -proc get_x509_info {crt} { - set ossl [get_openssl] - set info "" - update - set ph [open "| $ossl x509 -text -fingerprint -in \"$crt\"" "r"] - while {[gets $ph line] > -1} { - append info "$line\n" - } - close $ph - return $info -} - -proc do_oss_create {} { - global is_windows is_win9x - - set cfg { -[ req ] -default_bits = 2048 -encrypt_key = yes -distinguished_name = req_distinguished_name - -[ req_distinguished_name ] -countryName = Country Name (2 letter code) -countryName_default = %CO -countryName_min = 2 -countryName_max = 2 - -stateOrProvinceName = State or Province Name (full name) -stateOrProvinceName_default = %ST - -localityName = Locality Name (eg, city) -localityName_default = %LOC - -0.organizationName = Organization Name (eg, company) -0.organizationName_default = %ON - -organizationalUnitName = Organizational Unit Name (eg, section) -organizationalUnitName_default = %OUN - -commonName = Common Name (eg, YOUR name) -commonName_default = %CN -commonName_max = 64 - -emailAddress = Email Address -emailAddress_default = %EM -emailAddress_max = 64 -} - - global ccert - - if {$ccert(FILE) == ""} { - catch {destroy .c} - mesg "No output cert file supplied" - bell - return - } - if {! [regexp {\.pem$} $ccert(FILE)]} { - append ccert(FILE) ".pem" - } - set pem $ccert(FILE) - regsub {\.pem$} $ccert(FILE) ".crt" crt - - if {$ccert(ENC)} { - if {[string length $ccert(PASS)] < 4} { - catch {destroy .c} - mesg "Passphrase must be at least 4 characters long." - bell - return - } - } - if {[string length $ccert(CO)] != 2} { - catch {destroy .c} - mesg "Country Name must be at exactly 2 characters long." - bell - return - } - if {[string length $ccert(CN)] > 64} { - catch {destroy .c} - mesg "Common Name must be less than 65 characters long." - bell - return - } - if {[string length $ccert(EM)] > 64} { - catch {destroy .c} - mesg "Email Address must be less than 65 characters long." - bell - return - } - - foreach t {EM CN OUN ON LOC ST CO} { - - set val $ccert($t) - if {$val == ""} { - set val "none" - } - regsub "%$t" $cfg "$val" cfg - } - - global is_windows - - if {$is_windows} { - # VF - set tmp "cert.cfg" - } else { - set tmp "/tmp/cert.cfg.[tpid]" - set tmp [mytmp $tmp] - catch {set fh [open $tmp "w"]} - catch {exec chmod 600 $tmp} - if {! [file exists $tmp]} { - catch {destroy .c} - mesg "cannot create: $tmp" - bell - return - } - } - set fh "" - catch {set fh [open $tmp "w"]} - if {$fh == ""} { - catch {destroy .c} - mesg "cannot create: $tmp" - bell - catch {file delete $tmp} - return - } - - puts $fh $cfg - close $fh - - set ossl [get_openssl] - - set cmd "$ossl req -config $tmp -nodes -new -newkey rsa:2048 -x509 -batch" - if {$ccert(DAYS) != ""} { - set cmd "$cmd -days $ccert(DAYS)" - } - if {$is_windows} { - set cmd "$cmd -keyout {$pem} -out {$crt}" - } else { - set cmd "$cmd -keyout \"$pem\" -out \"$crt\"" - } - - if {$is_windows} { - set emess "" - if {$is_win9x} { - catch {file delete $pem} - catch {file delete $crt} - update - eval exec $cmd & - catch {raise .} - set sl 0 - set max 100 - #if {$ccert(ENC)} { - # set max 100 - #} - set maxms [expr $max * 1000] - while {$sl < $maxms} { - set s2 [expr $sl / 1000] - mesg "running openssl ... $s2/$max" - if {[file exists $pem] && [file exists $crt]} { - after 2000 - break - } - after 500 - set sl [expr $sl + 500] - } - mesg "" - } else { - update - set rc [catch {eval exec $cmd} emess] - if {$rc != 0 && [regexp -nocase {error:} $emess]} { - raise . - tk_messageBox -type ok -icon error -message $emess -title "OpenSSL req command failed" - return - } - } - } else { - set geometry [xterm_center_geometry] - update - unix_terminal_cmd $geometry "Running OpenSSL" "$cmd" - catch {file attributes $pem -permissions go-rw} - catch {file attributes $crt -permissions go-w} - } - catch {file delete $tmp} - - set bad "" - if {! [file exists $pem]} { - set bad "$pem " - } - if {! [file exists $crt]} { - set bad "$crt" - } - if {$bad != ""} { - raise . - tk_messageBox -type ok -icon error -message "Not created: $bad" -title "OpenSSL could not create cert" - catch {raise .c} - return - } - - if {$ccert(ENC) && $ccert(PASS) != ""} { - set cmd "$ossl rsa -in \"$pem\" -des3 -out \"$pem\" -passout stdin" - set ph "" - set emess "" - update - set rc [catch {set ph [open "| $cmd" "w"]} emess] - if {$rc != 0 || $ph == ""} { - raise . - tk_messageBox -type ok -icon error -message $emess -title "Could not encrypt private key" - catch {file delete $pem} - catch {file delete $crt} - return - } - puts $ph $ccert(PASS) - set emess "" - set rc [catch {close $ph} emess] - #puts $emess - #puts $rc - } - - set in [open $crt "r"] - set out [open $pem "a"] - while {[gets $in line] > -1} { - puts $out $line - } - close $in - close $out - - catch {raise .c} - set p . - if [winfo exists .c] { - set p .c - } - - set reply [tk_messageBox -parent $p -type yesno -title "View Cert" -message "View Certificate and Info?"] - catch {raise .c} - if {$reply == "yes"} { - set w .view_cert - toplev $w - scroll_text $w.f - set cert "" - set fh "" - catch {set fh [open $crt "r"]} - if {$fh != ""} { - while {[gets $fh line] > -1} { - append cert "$line\n" - } - catch {close $fh} - } - - global yegg - set yegg "" - button $w.b -text Dismiss -command "destroy $w; set yegg 1" - pack $w.b -side bottom -fill x - bind $w <Escape> "destroy $w; set yegg 1" - - $w.f.t insert end "\n" - $w.f.t insert end "$crt:\n" - $w.f.t insert end "\n" - $w.f.t insert end $cert - $w.f.t insert end "\n" - - set info [get_x509_info $crt] - $w.f.t insert end $info - - pack $w.f -side top -fill both -expand 1 - center_win $w - catch {raise $w} - vwait yegg - catch {raise .c} - } - - set p . - if [winfo exists .c] { - set p .c - } - set reply [tk_messageBox -parent $p -type yesno -title "View Private Key" -message "View Private Key?"] - catch {raise .c} - if {$reply == "yes"} { - set w .view_key - toplev $w - scroll_text $w.f - set key "" - set fh [open $pem "r"] - while {[gets $fh line] > -1} { - append key "$line\n" - } - close $fh - - global yegg - set yegg "" - button $w.b -text Dismiss -command "destroy $w; set yegg 1" - pack $w.b -side bottom -fill x - bind $w <Escape> "destroy $w; set yegg 1" - - $w.f.t insert end "\n" - $w.f.t insert end "$pem:\n" - $w.f.t insert end "\n" - $w.f.t insert end $key - $w.f.t insert end "\n" - - pack $w.f -side top -fill both -expand 1 - center_win $w - catch {raise $w} - vwait yegg - catch {raise .c} - } -} - -proc create_cert {{name ""}} { - - toplev .ccrt - wm title .ccrt "Create SSL Certificate" - - global uname - set h 27 - if [small_height] { - set h 14 - } elseif {$uname == "Darwin"} { - set h 20 - } - scroll_text .ccrt.f 80 $h - - set msg { - This dialog helps you to create a simple Self-Signed SSL certificate. - - On Unix the openssl(1) program must be installed and in $PATH. - On Windows, a copy of the openssl program is provided for convenience. - - The resulting certificate files can be used for either: - - 1) authenticating yourself (VNC Viewer) to a VNC Server - or 2) your verifying the identity of a remote VNC Server. - - In either case you will need to safely copy one of the generated key or - certificate files to the remote VNC Server and have the VNC Server use - it. Or you could send it to the system administrator of the VNC Server. - - For the purpose of description, assume that the filename selected in the - "Save to file" entry is "vnccert.pem". That file will be generated - by this process and so will the "vnccert.crt" file. "vnccert.pem" - contains both the Private Key and the Public Certificate. "vnccert.crt" - only contains the Public Certificate. - - For case 1) you would copy "vnccert.crt" to the VNC Server side and - instruct the server to use it. For x11vnc it would be for example: - - x11vnc -sslverify /path/to/vnccert.crt -ssl SAVE ... - - (it is also possible to handle many client certs at once in a directory, - see the -sslverify documentation). Then you would use "vnccert.pem" - as the MyCert entry in the SSL Certificates dialog. - - For case 2) you would copy "vnccert.pem" to the VNC Server side and - instruct the server to use it. For x11vnc it would be for example: - - x11vnc -ssl /path/to/vnccert.pem - - Then you would use "vnccert.crt" as the as the ServerCert entry in the - "SSL Certificates" dialog. - - - Creating the Certificate: - - Choose a output filename (ending in .pem) in the "Save to file" entry. - - Then fill in the identification information (Country, State or Province, - etc). - - The click on "Create" to generate the certificate files. - - Encrypting the Private Key: It is a very good idea to encrypt the - Private Key that goes in the "vnccert.pem". The downside is that - whenever that key is used (e.g. starting up x11vnc using it) then - the passphrase will need to be created. If you do not encrypt it and - somebody steals a copy of the "vnccert.pem" file then they can pretend - to be you. - - After you have created the certificate files, you must copy and import - either "vnccert.pem" or "vnccert.pem" to the remote VNC Server and - also select the other file in the "SSL Certificates" dialog. - See the description above. - - For more information see: - - http://www.karlrunge.com/x11vnc/ssl.html - http://www.karlrunge.com/x11vnc/faq.html#faq-ssl-tunnel-int - - The first one describes how to use x11vnc to create Certificate - Authority (CA) certificates in addition to Self-Signed ones. - - - Tip: if you choose the "Common Name" to be the internet hostname - (e.g. gateway.mydomain.com) that connections will be made to or - from that will avoid many dialogs when connecting mentioning that - the hostname does not match the Common Name. -} - .ccrt.f.t insert end $msg - - global ccert ccert_init tcert - - - if {! [info exists ccert_init]} { - set ccert_init 1 - set ccert(CO) "US" - set ccert(ST) "Massachusetts" - set ccert(LOC) "Boston" - set ccert(ON) "My Company" - set ccert(OUN) "Product Development" - set ccert(CN) "www.nowhere.none" - set ccert(EM) "admin@nowhere.none" - set ccert(DAYS) "730" - set ccert(FILE) "" - } - - set ccert(ENC) 0 - set ccert(PASS) "" - - set tcert(CO) "Country Name (2 letter code):" - set tcert(ST) "State or Province Name (full name):" - set tcert(LOC) "Locality Name (eg, city):" - set tcert(ON) "Organization Name (eg, company):" - set tcert(OUN) "Organizational Unit Name (eg, section):" - set tcert(CN) "Common Name (eg, YOUR name):" - set tcert(EM) "Email Address:" - set tcert(DAYS) "Days until expiration:" - - set idir [get_idir_certs ""] - if {$name != ""} { - if {[regexp {/} $name] || [regexp {\.pem$} $name] || [regexp {\.crt$} $name]} { - set ccert(FILE) $name - } else { - set ccert(FILE) "$idir/$name.pem" - } - } elseif {$ccert(FILE) == ""} { - set ccert(FILE) "$idir/vnccert.pem" - } - - button .ccrt.cancel -text "Cancel" -command {destroy .ccrt; catch {raise .c}} - bind .ccrt <Escape> {destroy .ccrt; catch {raise .c}} - wm protocol .ccrt WM_DELETE_WINDOW {destroy .ccrt; catch {raise .c}} - - button .ccrt.create -text "Generate Cert" -command {destroy .ccrt; catch {raise .c}; do_oss_create} - - pack .ccrt.create .ccrt.cancel -side bottom -fill x - - set ew 40 - - set w .ccrt.pf - frame $w - checkbutton $w.check -anchor w -variable ccert(ENC) -text \ - "Encrypt Key with Passphrase" -command {check_pp} - - entry $w.e -width $ew -textvariable ccert(PASS) -state disabled \ - -show * - - pack $w.e -side right - pack $w.check -side left -expand 1 -fill x - pack $w -side bottom -fill x - - set w .ccrt.fl - frame $w - label $w.l -anchor w -text "Save to file:" - - entry $w.e -width $ew -textvariable ccert(FILE) - button $w.b -text "Browse..." -command {set_createcert_file; catch {raise .ccrt}} - if {$name != ""} { - $w.b configure -state disabled - } - - pack $w.e -side right - pack $w.b -side right - pack $w.l -side left -expand 1 -fill x - pack $w -side bottom -fill x - - set i 0 - foreach t {DAYS EM CN OUN ON LOC ST CO} { - set w .ccrt.f$i - frame $w - label $w.l -anchor w -text "$tcert($t)" - entry $w.e -width $ew -textvariable ccert($t) - pack $w.e -side right - pack $w.l -side left -expand 1 -fill x - pack $w -side bottom -fill x - incr i - } - - pack .ccrt.f -side top -fill both -expand 1 - - center_win .ccrt -} - -proc import_check_mode {w} { - global import_mode - if {$import_mode == "paste"} { - $w.mf.b configure -state disabled - $w.mf.e configure -state disabled - $w.plab configure -state normal - $w.paste.t configure -state normal - } else { - $w.mf.b configure -state normal - $w.mf.e configure -state normal - $w.plab configure -state disabled - $w.paste.t configure -state disabled - } -} - -proc import_browse {par} { - global import_file - - set idir "" - if {$import_file != ""} { - set idir [get_idir_certs $import_file] - } - unix_dialog_resize $par - if {$idir != ""} { - set t [tk_getOpenFile -parent $par -initialdir $idir] - } else { - set t [tk_getOpenFile -parent $par] - } - if {$t != ""} { - set import_file $t - } - catch {raise $par} - update -} - -proc import_save_browse {{par ".icrt"}} { - global import_save_file - - set idir "" - if {$import_save_file != ""} { - set idir [get_idir_certs $import_save_file] - } - if {$idir == ""} { - set idir [get_idir_certs ""] - } - unix_dialog_resize $par - if {$idir != ""} { - set t [tk_getSaveFile -parent $par -defaultextension ".crt" -initialdir $idir] - } else { - set t [tk_getSaveFile -parent $par -defaultextension ".crt"] - } - if {$t != ""} { - set import_save_file $t - } - catch {raise $par} - update -} - -proc do_save {par} { - global import_mode import_file import_save_file - global also_save_to_accepted_certs - - if {![info exists also_save_to_accepted_certs]} { - set also_save_to_accepted_certs 0 - } - - if {$import_save_file == "" && ! $also_save_to_accepted_certs} { - tk_messageBox -parent $par -type ok -icon error \ - -message "No Save File supplied" -title "Save File" - return - } - - set str "" - set subject_issuer "" - if {$import_mode == "save_cert_text"} { - global save_cert_text - set str $save_cert_text - set i 0 - foreach line [split $str "\n"] { - incr i - if {$i > 50} { - break - } - if [regexp {^- subject: *(.*)$} $line m val] { - set subject_issuer "${subject_issuer}subject:$val\n" - } - if [regexp {^- (issuer[0-9][0-9]*): *(.*)$} $line m is val] { - set subject_issuer "${subject_issuer}$is:$val\n" - } - if [regexp {^INFO: SELF_SIGNED=(.*)$} $line m val] { - set subject_issuer "${subject_issuer}SELF_SIGNED:$val\n" - } - } - } elseif {$import_mode == "paste"} { - set str [$par.paste.t get 1.0 end] - } else { - if {! [file exists $import_file]} { - tk_messageBox -parent $par -type ok -icon error \ - -message "Input file \"$import_file\" does not exist." -title "Import File" - return - } - set fh "" - set emess "" - set rc [catch {set fh [open $import_file "r"]} emess] - if {$rc != 0 || $fh == ""} { - tk_messageBox -parent $par -type ok -icon error \ - -message $emess -title "Import File: $import_file" - return - } - while {[gets $fh line] > -1} { - append str "$line\n" - } - close $fh - } - - if {! [regexp {BEGIN CERTIFICATE} $str]} { - tk_messageBox -parent $par -type ok -icon error \ - -message "Import Text does not contain \"BEGIN CERTIFICATE\"" -title "Imported Text" - return - } - if {! [regexp {END CERTIFICATE} $str]} { - tk_messageBox -parent $par -type ok -icon error \ - -message "Import Text does not contain \"END CERTIFICATE\"" -title "Imported Text" - return - } - - global is_windows - set fh "" - set emess "" - set deltmp "" - if {$import_save_file == ""} { - if {! $is_windows} { - set deltmp /tmp/import.[tpid] - } else { - set deltmp import.[tpid] - } - set deltmp [mytmp $deltmp] - set import_save_file $deltmp - } - set rc [catch {set fh [open $import_save_file "w"]} emess] - if {$rc != 0 || $fh == ""} { - tk_messageBox -parent $par -type ok -icon error \ - -message $emess -title "Save File: $import_save_file" - return - } - if {! $is_windows} { - catch {file attributes $import_save_file -permissions go-w} - if {[regexp {PRIVATE} $str] || [regexp {\.pem$} $import_save_file]} { - catch {file attributes $import_save_file -permissions go-rw} - } - } - - puts -nonewline $fh $str - close $fh - - global do_save_saved_it - set do_save_saved_it 1 - - if {$also_save_to_accepted_certs} { - set ossl [get_openssl] - set fp_txt "" - set fp_txt [exec $ossl x509 -fingerprint -noout -in $import_save_file] - - set adir [get_idir_certs ""] - set adir "$adir/accepted" - catch {file mkdir $adir} - - set fingerprint "" - set fingerline "" - - set i 0 - foreach line [split $fp_txt "\n"] { - incr i - if {$i > 5} { - break - } - if [regexp -nocase {Fingerprint=(.*)} $line mv str] { - set fingerline $line - set fingerprint [string trim $str] - } - } - - set fingerprint [string tolower $fingerprint] - regsub -all {:} $fingerprint "-" fingerprint - regsub -all {[\\/=]} $fingerprint "_" fingerprint - - if {$subject_issuer == ""} { - set si_txt "" - set si_txt [exec $ossl x509 -subject -issuer -noout -in $import_save_file] - set sub "" - set iss "" - foreach line [split $si_txt "\n"] { - if [regexp -nocase {^subject= *(.*)$} $line mv str] { - set str [string trim $str] - set sub $str - } elseif [regexp -nocase {^issuer= *(.*)$} $line mv str] { - set str [string trim $str] - set iss $str - } - } - if {$sub != "" && $iss != ""} { - set subject_issuer "subject:$sub\nissuer1:$iss\n" - if {$sub == $iss} { - set subject_issuer "${subject_issuer}SELF_SIGNED:1\n" - } else { - set subject_issuer "${subject_issuer}SELF_SIGNED:0\n" - } - } - } - - global vncdisplay - set from [get_ssh_hp $vncdisplay] - if {$from == ""} { - set from [file tail $import_save_file] - regsub {\..*$} $from "" from - } - if {$from == ""} { - set from "import" - } - if [regexp -- {^:[0-9][0-9]*$} $from] { - set from "listen$from" - } - set hp $from - - set from [string tolower $from] - regsub -all {^[+a-z]*://} $from "" from - regsub -all {:} $from "-" from - regsub -all {[\\/=]} $from "_" from - regsub -all {[ ]} $from "_" from - - set crt "$adir/$from=$fingerprint.crt" - catch {file copy -force $import_save_file $crt} - - global do_save_saved_hash_it - set do_save_saved_hash_it 1 - save_hash $crt $adir $hp $fingerline $from $fingerprint $subject_issuer - } - - catch {destroy $par} - set p .c - if {![winfo exists .c]} { - global accepted_cert_dialog_in_progress - if {! $accepted_cert_dialog_in_progress} { - if {$deltmp == ""} { - getcerts - update - } - } - } - if {![winfo exists .c]} { - set p . - } - catch {raise .c} - catch {destroy .scrt} - if {$deltmp != ""} { - catch {file delete $deltmp} - set import_save_file "" - return; - } - tk_messageBox -parent $p -type ok -icon info \ - -message "Saved to file: $import_save_file" -title "Save File: $import_save_file" -} - -proc import_cert {} { - - toplev .icrt - wm title .icrt "Import SSL Certificate" - - global scroll_text_focus - set scroll_text_focus 0 - global uname - set h 19 - if [small_height] { - set h 12 - } elseif {$uname == "Darwin"} { - set h 16 - } - scroll_text .icrt.f 90 $h - set scroll_text_focus 1 - - set msg { - This dialog lets you import a SSL Certificate by either pasting one in or by - loading from another file. Choose which input mode you want to use by the toggle - "Paste / Read from File". - - There are two types of files we use 1) Certificate only, and 2) Private Key - and Certificate. - - Type 1) would be used to verify the identity of a remote VNC Server, whereas - type 2) would be used to authenticate ourselves to the remote VNC Server. - - A type 1) by convention ends with file suffix ".crt" and looks like: - ------BEGIN CERTIFICATE----- -MIID2jCCAsKgAwIBAgIJALKypfV8BItCMA0GCSqGSIb3DQEBBAUAMIGgMQswCQYD -(more lines) ... -TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam ------END CERTIFICATE----- - - A type 2) by convention ends with file suffix ".pem" and looks like: - ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEA4sApd7WaPKQRWnFe9T04D4pglQB0Ti0/dCVHxg8WEVQ8OdcW -(more lines) ... -9kBmNotUiTpvRM+e7E/zRemhvY9qraFooqMWzi9JrgYfeLfSvvFfGw== ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIID2jCCAsKgAwIBAgIJALKypfV8BItCMA0GCSqGSIb3DQEBBAUAMIGgMQswCQYD -(more lines) ... -TCQ+tbQ/DOiTXGKx1nlcKoPdkG+QVQVJthlQcpam ------END CERTIFICATE----- - - You do not need to use the ".crt" or ".pem" convention if you do not want to. - - First, either paste in the text or set the "Read from File" filename. - - Next, set the "Save to File" name to the file where the imported certificate - will be saved. - - Then, click on "Save" to save the imported Certificate. - - After you have imported the Certificate (or Key + Certificate), select it to - use for a connection via the "MyCert" or "ServerCert" dialog. -} - .icrt.f.t insert end $msg - - global icert import_mode - - set import_mode "paste" - - set w .icrt.mf - frame $w - - radiobutton $w.p -pady 1 -anchor w -variable import_mode -value paste \ - -text "Paste" -command "import_check_mode .icrt" - - radiobutton $w.f -pady 1 -anchor w -variable import_mode -value file \ - -text "Read from File:" -command "import_check_mode .icrt" - - global import_file - set import_file "" - entry $w.e -width 40 -textvariable import_file - - button $w.b -pady 1 -anchor w -text "Browse..." -command {import_browse .icrt} - pack $w.b -side right - pack $w.p $w.f -side left - pack $w.e -side left -expand 1 -fill x - - $w.b configure -state disabled - $w.e configure -state disabled - - label .icrt.plab -anchor w -text "Paste Certificate here: (extra blank lines above or below are OK)" - set h 22 - if [small_height] { - set h 11 - } elseif {$uname == "Darwin"} { - set h 11 - } - scroll_text .icrt.paste 90 $h - - button .icrt.cancel -text "Cancel" -command {destroy .icrt; catch {raise .c}} - bind .icrt <Escape> {destroy .icrt; catch {raise .c}} - wm protocol .icrt WM_DELETE_WINDOW {destroy .icrt; catch {raise .c}} - - button .icrt.save -text "Save" -command {do_save .icrt} - - set w .icrt.sf - frame $w - - label $w.l -text "Save to File:" -anchor w - global import_save_file - set import_save_file "" - entry $w.e -width 40 -textvariable import_save_file - button $w.b -pady 1 -anchor w -text "Browse..." -command import_save_browse - - global also_save_to_accepted_certs - set also_save_to_accepted_certs 0 - checkbutton .icrt.ac -anchor w -variable also_save_to_accepted_certs -text \ - "Also Save to the 'Accepted Certs' directory" -relief raised - - pack $w.b -side right - pack $w.l -side left - pack $w.e -side left -expand 1 -fill x - - pack .icrt.save .icrt.cancel .icrt.ac .icrt.sf .icrt.mf -side bottom -fill x - pack .icrt.paste .icrt.plab -side bottom -fill x - - pack .icrt.f -side top -fill both -expand 1 - - .icrt.paste.t insert end "" - - focus .icrt.paste.t - - center_win .icrt -} - -proc save_cert {hp} { - - global cert_text - - toplev .scrt - wm title .scrt "Import/Save SSL Certificate" - - global scroll_text_focus - set scroll_text_focus 0 - global uname - - global accepted_cert_dialog_in_progress - set h 20 - if {$accepted_cert_dialog_in_progress} { - set mode "accepted" - set h 15 - if [small_height] { - set h 11 - } - } else { - set mode "normal" - set h 20 - if [small_height] { - set h 16 - } - } - scroll_text .scrt.f 90 $h - - set scroll_text_focus 1 - - set msg1 { - This dialog lets you import a SSL Certificate retrieved from a VNC server. - - Be sure to have verified its authenticity via an external means (checking - the MD5 hash value sent to you by the administrator, etc) - - Set "Save to File" to the filename where the imported cert will be saved. - - If you also want the Certificate to be saved to the pool of certs in the - 'Accepted Certs' directory, select the checkbox. By default all Servers are - verified against the certificates in this pool. - - Then, click on "Save" to save the imported Certificate. - - After you have imported the Certificate it will be automatically selected as - the "ServerCert" for the next connection to this host: %HOST - - To make the ServerCert setting to the imported cert file PERMANENT, select - 'Save' to save it in the profile for this host. -} - - set msg2 { - This dialog lets you import a SSL Certificate retrieved from a VNC server. - - Be sure to have verified its authenticity via an external means (checking - the MD5 hash value sent to you by the administrator, etc) - - It will be added to the 'Accepted Certs' directory. The "Save to File" - below is already set to the correct directory and file name. - - Click on "Save" to add it to the Accepted Certs. - - It, and the other certs in that directory, will be used to authenticate - any VNC Server that has "ACCEPTED_CERTS" as the "CertsDir" value in the - "Certs..." dialog. This is the default checking policy. -} - - set msg "" - if {$mode == "normal"} { - set msg $msg1 - } else { - set msg $msg2 - } - - regsub {%HOST} $msg "$hp" msg - .scrt.f.t insert end $msg - - set w .scrt.mf - frame $w - - global import_file - set import_file "" - entry $w.e -width 40 -textvariable import_file - - set h 22 - if [small_height] { - set h 10 - } - scroll_text .scrt.paste 90 $h - - button .scrt.cancel -text "Cancel" -command {destroy .scrt; catch {raise .c}} - bind .scrt <Escape> {destroy .scrt; catch {raise .c}} - wm protocol .scrt WM_DELETE_WINDOW {destroy .scrt; catch {raise .c}} - - global import_save_file - if {$mode == "normal"} { - button .scrt.save -text "Save" -command {do_save .scrt; set svcert $import_save_file} - } else { - button .scrt.save -text "Save" -command {do_save .scrt} - } - - if [regexp -nocase -- {ACCEPT} $cert_text] { - if [regexp -nocase -- {Client certificate} $cert_text] { - if [regexp -- {^:[0-9][0-9]*$} $hp] { - if [regexp -nocase {subject=.*CN=([^/][^/]*)/} $cert_text mv0 mv1] { - regsub -all {[ ]} $mv1 "" mv1 - set hp "$mv1$hp" - } else { - set hp "listen$hp" - } - } - } - } - - set w .scrt.sf - frame $w - - label $w.l -text "Save to File:" -anchor w - set import_save_file "server:$hp.crt" - global is_windows - regsub -all {:} $import_save_file "-" import_save_file - - set import_save_file [get_idir_certs ""]/$import_save_file - - global fetch_cert_filename - if {$fetch_cert_filename != ""} { - set import_save_file $fetch_cert_filename - } - - entry $w.e -width 40 -textvariable import_save_file - button $w.b -pady 1 -anchor w -text "Browse..." -command {import_save_browse .scrt} - - pack $w.b -side right - pack $w.l -side left - pack $w.e -side left -expand 1 -fill x - - global also_save_to_accepted_certs - set also_save_to_accepted_certs 0 - if [regexp -nocase -- {ACCEPT} $cert_text] { - if [regexp -nocase -- {Client certificate} $cert_text] { - set also_save_to_accepted_certs 1 - } - } - checkbutton .scrt.ac -anchor w -variable also_save_to_accepted_certs -text \ - "Also Save to the 'Accepted Certs' directory" -relief raised - - if {$mode == "normal"} { - pack .scrt.cancel .scrt.save .scrt.sf .scrt.ac .scrt.mf -side bottom -fill x - } else { - pack .scrt.cancel .scrt.save .scrt.sf .scrt.mf -side bottom -fill x - } - pack .scrt.paste -side bottom -fill x - - pack .scrt.f -side top -fill both -expand 1 - - set text "" - set on 0 - foreach line [split $cert_text "\n"] { - if [regexp -- {-----BEGIN CERTIFICATE-----} $line] { - incr on - } - if {$on != 1} { - continue; - } - append text "$line\n" - if [regexp -- {-----END CERTIFICATE-----} $line] { - set on 2 - } - } - global save_cert_text - set save_cert_text $text - .scrt.paste.t insert end "$text" - global import_mode - set import_mode "save_cert_text" - - focus .scrt.paste.t - - center_win .scrt -} - - -proc getcerts {} { - global mycert svcert crtdir crlfil - global use_ssh use_sshssl - toplev .c - wm title .c "SSL Certificates" - frame .c.mycert - frame .c.svcert - frame .c.crtdir - frame .c.crlfil - label .c.mycert.l -anchor w -width 12 -text "MyCert:" - label .c.svcert.l -anchor w -width 12 -text "ServerCert:" - label .c.crtdir.l -anchor w -width 12 -text "CertsDir:" - label .c.crlfil.l -anchor w -width 12 -text "CRL File:" - - entry .c.mycert.e -width 32 -textvariable mycert -vcmd v_mycert - entry .c.svcert.e -width 32 -textvariable svcert -vcmd v_svcert - entry .c.crtdir.e -width 32 -textvariable crtdir - entry .c.crlfil.e -width 32 -textvariable crlfil -vcmd v_crlfil - - bind .c.mycert.e <Enter> {.c.mycert.e validate} - bind .c.mycert.e <Leave> {.c.mycert.e validate} - bind .c.svcert.e <Enter> {.c.svcert.e validate} - bind .c.svcert.e <Leave> {.c.svcert.e validate} - - button .c.mycert.b -text "Browse..." -command {set_mycert .c; catch {raise .c}} - button .c.svcert.b -text "Browse..." -command {set_svcert .c; catch {raise .c}} - button .c.crtdir.b -text "Browse..." -command {set_crtdir .c; catch {raise .c}} - button .c.crlfil.b -text "Browse..." -command {set_crlfil .c; catch {raise .c}} - - button .c.mycert.i -text "Info" -command {show_mycert} - button .c.svcert.i -text "Info" -command {show_svcert} - button .c.crtdir.i -text "Info" -command {} - button .c.crlfil.i -text "Info" -command {show_crlfil} - - bind .c.mycert.b <Enter> "v_mycert" - bind .c.svcert.b <Enter> "v_svcert" - bind .c.crlfil.b <Enter> "v_crlfil" - - .c.mycert.i configure -state disabled - .c.svcert.i configure -state disabled - .c.crtdir.i configure -state disabled - .c.crlfil.i configure -state disabled - - bind .c.mycert.b <B3-ButtonRelease> "show_mycert" - bind .c.svcert.b <B3-ButtonRelease> "show_svcert" - bind .c.crlfil.b <B3-ButtonRelease> "show_crlfil" - - set do_crl 1 - set do_row 1 - - set c .c - if {$do_row} { - frame .c.b0 - set c .c.b0 - } - - button $c.create -text "Create Certificate ..." -command {create_cert} - button $c.import -text "Import Certificate ..." -command {import_cert} - button $c.delete -text "Delete Certificate ..." -command {delete_cert .c} - - if {$c != ".c"} { - pack $c.create $c.import $c.delete -fill x -expand 1 -side left - } - - frame .c.b - button .c.b.done -text "Done" -command {catch {destroy .c}} - bind .c <Escape> {destroy .c} - button .c.b.help -text "Help" -command help_certs - pack .c.b.help .c.b.done -fill x -expand 1 -side left - - set wlist [list mycert svcert crtdir] - lappend wlist crlfil - - foreach w $wlist { - pack .c.$w.l -side left - pack .c.$w.e -side left -expand 1 -fill x - pack .c.$w.b -side left - pack .c.$w.i -side left - bind .c.$w.e <Return> ".c.$w.b invoke" - if {$use_ssh} { - .c.$w.l configure -state disabled - .c.$w.e configure -state disabled - .c.$w.b configure -state disabled - } - } - - global svcert_default_force mycert_default_force crlfil_default_force - if {$mycert_default_force} { - .c.mycert.e configure -state readonly - .c.mycert.b configure -state disabled - } - if {$svcert_default_force} { - .c.svcert.e configure -state readonly - .c.svcert.b configure -state disabled - .c.crtdir.e configure -state readonly - .c.crtdir.b configure -state disabled - } - if {$crlfil_default_force} { - .c.crlfil.e configure -state readonly - .c.crlfil.b configure -state disabled - } - - if {$mycert != ""} { - v_mycert - } - if {$svcert != ""} { - v_svcert - } - if {$crlfil != ""} { - v_crlfil - } - - set wlist [list .c.mycert .c.svcert .c.crtdir] - if {$do_crl} { - lappend wlist .c.crlfil - } - if {$c != ".c"} { - lappend wlist $c - } else { - lappend wlist .c.create .c.import .c.delete - } - lappend wlist .c.b - - eval pack $wlist -side top -fill x - - center_win .c - wm resizable .c 1 0 - - focus .c -} - -proc get_profiles_dir {} { - global env is_windows - - set dir "" - if {$is_windows} { - if [info exists env(SSVNC_HOME)] { - set t "$env(SSVNC_HOME)/ss_vnc" - regsub -all {\\} $t "/" t - regsub -all {//*} $t "/" t - if {! [file isdirectory $t]} { - catch {file mkdir $t} - } - if [file isdirectory $t] { - set dir $t - set s "$t/profiles" - if {! [file exists $s]} { - catch {file mkdir $s} - } - } - } - if {$dir == ""} { - set t [file dirname [pwd]] - set t "$t/profiles" - if [file isdirectory $t] { - set dir $t - } - } - } elseif [info exists env(SSVNC_HOME)] { - set t "$env(SSVNC_HOME)/.vnc" - catch {file mkdir $t} - if [file isdirectory $t] { - set dir $t - set s "$t/profiles" - if {! [file exists $s]} { - catch {file mkdir $s} - } - } - } - - if {$dir != ""} { - - } elseif [info exists env(SSVNC_BASEDIR)] { - set dir $env(SSVNC_BASEDIR) - } else { - set dir [pwd] - } - if [file isdirectory "$dir/profiles"] { - set dir "$dir/profiles" - } - return $dir -} - -proc globalize {} { - global defs - foreach var [array names defs] { - uplevel global $var - } -} - -proc load_include {include dir} { - global include_vars defs - - if [info exists include_vars] { - unset include_vars - } - - foreach inc [split $include ", "] { - set f [string trim $inc] -#puts "f=$f"; - if {$f == ""} { - continue - } - set try "" - if {[regexp {/} $f] || [regexp {\\} $f]} { - set try $f; - } else { - set try "$dir/$f" - } - if {! [file exists $try]} { - set try "$dir/$f.vnc" - } -#puts "try: $try" - if [file exists $try] { - set fh "" - catch {set fh [open $try "r"]} - if {$fh == ""} { - continue - } - mesg "Applying template: $inc" - after 100 - while {[gets $fh line] > -1} { - append inc_str "$line\n" - if [regexp {^([^=]*)=(.*)$} $line m var val] { - if {! [info exists defs($var)]} { - continue - } - if {$var == "include_list"} { - continue - } - set pct 0 - if {$var == "smb_mount_list"} { - set pct 1 - } - if {$var == "port_knocking_list"} { - set pct 1 - } - if {$pct} { - regsub -all {%%%} $val "\n" val - } - if {$val != $defs($var)} { -#puts "include_vars $var $val" - set include_vars($var) $val - } - } - } - catch {close $fh} - } - } -} - -proc unix_dialog_resize {{w .}} { - global env is_windows uname unix_dialog_size - set ok 0 - set width 600 - set height 300 - if {[info exists env(SSVNC_BIGGER_DIALOG)]} { - set ok 1 - if {[regexp {([0-9][0-9]*)x([0-9][0-9]*)} $env(SSVNC_BIGGER_DIALOG) m wi he]} { - set width $wi; - set height $he; - } - } elseif {[info exists env(USER)] && $env(USER) == "runge"} { - set ok 1 - } - if {$ok} { - # this is a personal hack because tk_getOpenFile size is not configurable. - if {!$is_windows && $uname != "Darwin"} { - if {$w == "."} { - set w2 .__tk_filedialog - } else { - set w2 $w.__tk_filedialog - } - set w3 $w2.icons.canvas - global udr_w4 - set udr_w4 $w2.f2.cancel - if {! [info exists unix_dialog_size($w)]} { - after 50 {global udr_w4; catch {$udr_w4 invoke}} - tk_getOpenFile -parent $w -initialdir / - set unix_dialog_size($w) 1 - } - if [winfo exists $w3] { - catch {$w3 configure -width $width} - catch {$w3 configure -height $height} - } - } - } -} - -proc delete_profile {{parent "."}} { - - globalize - - set dir [get_profiles_dir] - - unix_dialog_resize $parent - set file [tk_getOpenFile -parent $parent -initialdir $dir -title "DELETE VNC Profile"] - - if {$file == ""} { - return - } - - set tail [file tail $file] - - set ans [tk_messageBox -type okcancel -title "Delete $tail" -message "Really Delete $file?" -icon warning] - - if {$ans == "ok"} { - catch {file delete $file} - mesg "Deleted $tail" - } else { - mesg "Delete Skipped." - } -} - -proc load_profile {{parent "."} {infile ""}} { - global profdone - global vncdisplay - - globalize - - set dir [get_profiles_dir] - - if {$infile != ""} { - set file $infile - } else { - unix_dialog_resize - set file [tk_getOpenFile -parent $parent -defaultextension \ - ".vnc" -initialdir $dir -title "Load VNC Profile"] - } - - if {$file == ""} { - set profdone 1 - return - } - set fh [open $file "r"] - if {! [info exists fh]} { - set profdone 1 - return - } - - set goto_mode ""; - set str "" - set include "" - set sw 1 - while {[gets $fh line] > -1} { - append str "$line\n" - if [regexp {^include_list=(.*)$} $line m val] { - set include $val - } - global ssh_only ts_only - if {$ssh_only || $ts_only} { - if [regexp {use_ssh=0} $line] { - if {$sw} { - mesg "Switching to SSVNC mode." - set goto_mode "ssvnc" - update - after 300 - } else { - bell - mesg "Cannot Load an SSL profile in SSH-ONLY mode." - set profdone 1 - close $fh - return - } - } - } - if {! $ts_only} { - if [regexp {ts_mode=1} $line] { - if {$sw} { - mesg "Switching to Terminal Services mode." - set goto_mode "tsonly" - update - after 300 - } else { - bell - mesg "Cannot Load a Terminal Svcs profile SSVNC mode." - set profdone 1 - close $fh - return - } - } - } else { - if [regexp {ts_mode=0} $line] { - if {$sw} { - mesg "Switching to SSVNC mode." - set goto_mode "ssvnc" - update - after 300 - } else { - bell - mesg "Cannot Load a Terminal Svcs profile SSVNC mode." - set profdone 1 - close $fh - return - } - } - } - } - close $fh - - if {$include != ""} { - load_include $include $dir - } - - if {$goto_mode == "tsonly"} { - to_tsonly - } elseif {$goto_mode == "ssvnc"} { - to_ssvnc - } elseif {$goto_mode == "sshvnc"} { - to_sshvnc - } - set_defaults - - global include_vars - if [info exists include_vars] { - foreach var [array names include_vars] { - set $var $include_vars($var) - } - } - - - global use_ssl use_ssh use_sshssl - set use_ssl 0 - set use_ssh 0 - set use_sshssl 0 - - global defs - foreach line [split $str "\n"] { - set line [string trim $line] - if [regexp {^#} $line] { - continue - } - if [regexp {^([^=]*)=(.*)$} $line m var val] { - if {$var == "disp"} { - set vncdisplay $val - continue - } - if [info exists defs($var)] { - set pct 0 - if {$var == "smb_mount_list"} { - set pct 1 - } - if {$var == "port_knocking_list"} { - set pct 1 - } - if {$pct} { - regsub -all {%%%} $val "\n" val - } - set $var $val - } - } - } - - init_vncdisplay - if {! $use_ssl && ! $use_ssh && ! $use_sshssl} { - if {! $disable_all_encryption} { - set use_ssl 1 - } - } - if {$use_ssl} { - set use_ssh 0 - set use_sshssl 0 - } elseif {$use_ssh && $use_sshssl} { - set use_ssh 0 - } - sync_use_ssl_ssh - - set compresslevel_text "Compress Level: $use_compresslevel" - set quality_text "Quality: $use_quality" - - set profdone 1 - putty_pw_entry check - listen_adjust - unixpw_adjust - - global last_load - set last_load [file tail $file] - - global uname darwin_cotvnc - if {$uname == "Darwin"} { - if {$use_x11_macosx} { - set darwin_cotvnc 0; - } else { - set darwin_cotvnc 1; - } - } - - mesg "Loaded [file tail $file]" -} - -proc sync_use_ssl_ssh {} { - global use_ssl use_ssh use_sshssl - global disable_all_encryption - if {$use_ssl} { - ssl_ssh_adjust ssl - } elseif {$use_ssh} { - ssl_ssh_adjust ssh - } elseif {$use_sshssl} { - ssl_ssh_adjust sshssl - } elseif {$disable_all_encryption} { - ssl_ssh_adjust none - } else { - ssl_ssh_adjust ssl - } -} - -proc save_profile {{parent "."}} { - global is_windows uname - global profdone - global include_vars defs - global ts_only - global last_load - - globalize - - set dir [get_profiles_dir] - - set vncdisp [get_vncdisplay] - - set dispf [string trim $vncdisp] - if {$dispf != ""} { - regsub {[ ].*$} $dispf "" dispf - regsub -all {/} $dispf "" dispf - } else { - global ts_only - if {$ts_only} { - mesg "No VNC Terminal Server supplied." - } else { - mesg "No VNC Host:Disp supplied." - } - bell - return - } - if {$is_windows || $uname == "Darwin"} { - regsub -all {:} $dispf "-" dispf - } else { - regsub -all {:} $dispf "-" dispf - } - regsub -all {[\[\]]} $dispf "" dispf - if {$ts_only && ![regexp {^TS-} $dispf]} { - set dispf "TS-$dispf" - } - if {![regexp {\.vnc$} $dispf]} { - set dispf "$dispf.vnc" - } - - set guess $dispf - if {$last_load != ""} { - set guess $last_load - } - - unix_dialog_resize - set file [tk_getSaveFile -parent $parent -defaultextension ".vnc" \ - -initialdir $dir -initialfile "$guess" -title "Save VNC Profile"] - if {$file == ""} { - set profdone 1 - return - } - set fh [open $file "w"] - if {! [info exists fh]} { - set profdone 1 - return - } - set h [string trim $vncdisp] - set p $h - # XXX host_part - regsub {:[0-9][0-9]*$} $h "" h - set host $h - regsub {[ ].*$} $p "" p - regsub {^.*:} $p "" p - regsub { .*$} $p "" p - if {$p == ""} { - set p 0 - } elseif {![regexp {^[-0-9][0-9]*$} $p]} { - set p 0 - } - if {$p < 0} { - set port $p - } elseif {$p < 200} { - set port [expr $p + 5900] - } else { - set port $p - } - - set h [string trim $vncdisp] - regsub {cmd=.*$} $h "" h - set h [string trim $h] - if {! [regexp {[ ]} $h]} { - set h "" - } else { - regsub {^.*[ ]} $h "" h - } - if {$h == ""} { - set proxy "" - set proxyport "" - } else { - set p $h - regsub {:[0-9][0-9]*$} $h "" h - set proxy $h - regsub {[ ].*$} $p "" p - regsub {^.*:} $p "" p - if {$p == ""} { - set proxyport 0 - } else { - set proxyport $p - } - } - - puts $fh "\[connection\]" - puts $fh "host=$host" - puts $fh "port=$port" - puts $fh "proxyhost=$proxy" - puts $fh "proxyport=$proxyport" - puts $fh "disp=$vncdisp" - puts $fh "\n\[options\]" - puts $fh "# parameters commented out with '#' indicate the default setting." - - if {$include_list != ""} { - load_include $include_list [get_profiles_dir] - } - global sshssl_sw - if {! $use_ssl && ! $use_ssh && ! $use_sshssl} { - if {$sshssl_sw == "none"} { - set disable_all_encryption 1 - } - } - - global ts_only ssh_only - if {$ts_only} { - set ts_mode 1 - } else { - set ts_mode 0 - } - foreach var [lsort [array names defs]] { - eval set val \$$var - set pre "" - if {$val == $defs($var)} { - set pre "#" - } - if {$ssh_only && $var == "use_ssh"} { - set pre "" - } - set pct 0 - if {$var == "smb_mount_list"} { - set pct 1 - } - if {$var == "port_knocking_list"} { - set pct 1 - } - if {$include_list != "" && [info exists include_vars($var)]} { - if {$val == $include_vars($var)} { - if {$pct} { - regsub -all "\n" $val "%%%" val - } - puts $fh "#from include: $var=$val" - continue - } - } - if {$pct} { - regsub -all "\n" $val "%%%" val - } - puts $fh "$pre$var=$val" - } - - close $fh - - mesg "Saved Profile: [file tail $file]" - - set last_load [file tail $file] - - set profdone 1 -} - -proc set_ssh {} { - global use_ssl - if {$use_ssl} { - ssl_ssh_adjust ssh - } -} - -proc expand_IP {redir} { - if {! [regexp {:IP:} $redir]} { - return $redir - } - if {! [regexp {(-R).*:IP:} $redir]} { - return $redir - } - - set ip [guess_ip] - set ip [string trim $ip] - if {$ip == ""} { - return $redir - } - - regsub -all {:IP:} $redir ":$ip:" redir - return $redir -} - -proc rand_port {} { - global rand_port_list - - set p "" - for {set i 0} {$i < 30} {incr i} { - set p [expr 25000 + 35000 * rand()] - set p [expr round($p)] - if {![info exists rand_port_list($p)]} { - break - } - } - if {$p == ""} { - unset rand_port_list - set p [expr 25000 + 35000 * rand()] - set p [expr round($p)] - } - set rand_port_list($p) 1 - return $p -} - -proc get_cups_redir {} { - global cups_local_server cups_remote_port - global cups_local_smb_server cups_remote_smb_port - - regsub -all {[ ]} $cups_local_server "" cups_local_server - regsub -all {[ ]} $cups_remote_port "" cups_remote_port - regsub -all {[ ]} $cups_local_smb_server "" cups_local_smb_server - regsub -all {[ ]} $cups_remote_smb_port "" cups_remote_smb_port - - set redir "" - - if {$cups_local_server != "" && $cups_remote_port != ""} { - set redir "$cups_remote_port:$cups_local_server" - regsub -all {['" ]} $redir {} redir; #" - set redir " -R $redir" - } - if {$cups_local_smb_server != "" && $cups_remote_smb_port != ""} { - set redir2 "$cups_remote_smb_port:$cups_local_smb_server" - regsub -all {['" ]} $redir2 {} redir2; #" - set redir "$redir -R $redir2" - } - set redir [expand_IP $redir] - return $redir -} - -proc get_additional_redir {} { - global additional_port_redirs additional_port_redirs_list - global ts_only choose_x11vnc_opts - if {! $additional_port_redirs || $additional_port_redirs_list == ""} { - return "" - } - if {$ts_only && !$choose_x11vnc_opts} { - return "" - } - set redir [string trim $additional_port_redirs_list] - regsub -all {['"]} $redir {} redir; #" - set redir " $redir" - set redir [expand_IP $redir] - return $redir -} - -proc get_sound_redir {} { - global sound_daemon_remote_port sound_daemon_local_port - global sound_daemon_x11vnc - - regsub -all {[ ]} $sound_daemon_remote_port "" sound_daemon_remote_port - regsub -all {[ ]} $sound_daemon_local_port "" sound_daemon_local_port - - set redir "" - if {$sound_daemon_local_port == "" || $sound_daemon_remote_port == ""} { - return $redir - } - - set loc $sound_daemon_local_port - if {! [regexp {:} $loc]} { - global uname - if {$uname == "Darwin"} { - set loc "127.0.0.1:$loc" - } else { - global is_windows - if {$is_windows} { - global win_localhost - set loc "$win_localhost:$loc" - } else { - set loc "localhost:$loc" - } - } - } - set redir "$sound_daemon_remote_port:$loc" - regsub -all {['" ]} $redir {} redir; #" - set redir " -R $redir" - set redir [expand_IP $redir] - return $redir -} - -proc get_smb_redir {} { - global smb_mount_list - - set s [string trim $smb_mount_list] - if {$s == ""} { - return "" - } - - set did(0) 1 - set redir "" - set mntlist "" - - foreach line [split $s "\r\n"] { - set str [string trim $line] - if {$str == ""} { - continue - } - if {[regexp {^#} $str]} { - continue - } - - set port "" - if [regexp {^([0-9][0-9]*)[ \t][ \t]*(.*)} $str mvar port rest] { - # leading port - set str [string trim $rest] - } - - # grab: //share /dest [host[:port]] - set share "" - set dest "" - set hostport "" - foreach item [split $str] { - if {$item == ""} { - continue - } - if {$share == ""} { - set share [string trim $item] - } elseif {$dest == ""} { - set dest [string trim $item] - } elseif {$hostport == ""} { - set hostport [string trim $item] - } - } - - regsub {^~/} $dest {$HOME/} dest - - # work out the local host:port - set lhost "" - set lport "" - if {$hostport != ""} { - if [regexp {(.*):([0-9][0-9]*)} $hostport mvar lhost lport] { - ; - } else { - set lhost $hostport - set lport 139 - } - } else { - if [regexp {//([^/][^/]*)/} $share mvar h] { - if [regexp {(.*):([0-9][0-9]*)} $h mvar lhost lport] { - ; - } else { - set lhost $h - set lport 139 - } - } else { - global is_windows win_localhost - set lhost "localhost" - if {$is_windows} { - set lhost $win_localhost - } - set lport 139 - } - } - - if {$port == ""} { - if [info exists did("$lhost:$lport")] { - # reuse previous one: - set port $did("$lhost:$lport") - } else { - # choose one at random: - for {set i 0} {$i < 3} {incr i} { - set port [expr 20100 + 9000 * rand()] - set port [expr round($port)] - if { ! [info exists did($port)] } { - break - } - } - } - set did($port) 1 - } - - if {$mntlist != ""} { - append mntlist " " - } - append mntlist "$share,$dest,$port" - - if { ! [info exists did("$lhost:$lport")] } { - append redir " -R $port:$lhost:$lport" - set did("$lhost:$lport") $port - } - } - - regsub -all {['"]} $redir {} redir; #" - set redir [expand_IP $redir] - - regsub -all {['"]} $mntlist {} mntlist; #" - - set l [list] - lappend l $redir - lappend l $mntlist - return $l -} - -proc ugly_setup_scripts {mode tag} { - -set cmd(1) { - SSHD_PID="" - FLAG=$HOME/.vnc-helper-flag__PID__ - - if [ "X$USER" = "X" ]; then - USER=$LOGNAME - fi - - DO_CUPS=0 - cups_dir=$HOME/.cups - cups_cfg=$cups_dir/client.conf - cups_host=localhost - cups_port=NNNN - - DO_SMB=0 - DO_SMB_SU=0 - DO_SMB_WAIT=0 - smb_mounts= - DONE_PORT_CHECK=NNNN - smb_script=$HOME/.smb-mounts__PID__.sh - - DO_SOUND=0 - DO_SOUND_KILL=0 - DO_SOUND_RESTART=0 - sound_daemon_remote_prog= - sound_daemon_remote_args= - - findpid() { - db=0 - back=30 - touch $FLAG - tty=`tty | sed -e "s,/dev/,,"` - - if [ "X$TOPPID" = "X" ]; then - TOPPID=$$ - if [ $db = 1 ]; then echo "set TOPPID to $TOPPID"; fi - back=70 - fi - #back=5 - if [ $db = 1 ]; then echo "TOPPID=$TOPPID THISPID=$$ back=$back"; fi - - i=1 - while [ $i -lt $back ] - do - try=`expr $TOPPID - $i` - if [ $try -lt 1 ]; then - try=`expr 32768 + $try` - fi - if [ $db = 1 ]; then echo try-1=$try; ps $try; fi - if ps $try 2>/dev/null | grep "sshd.*$USER" | grep "$tty" >/dev/null; then - if [ $db = 1 ]; then echo Found=$try; fi - SSHD_PID="$try" - echo - ps $try - echo - break - fi - i=`expr $i + 1` - done - - if [ "X$SSHD_PID" = "X" ]; then - back=`expr $back + 20` - #back=5 - - for fallback in 2 3 - do - i=1 - while [ $i -lt $back ] - do - try=`expr $TOPPID - $i` - if [ $try -lt 1 ]; then - try=`expr 32768 + $try` - fi - match="sshd.*$USER" - if [ $fallback = 3 ]; then - match="sshd" - fi - if [ $db = 1 ]; then echo "try-$fallback=$try match=$match"; ps $try; fi - if ps $try 2>/dev/null | grep "$match" >/dev/null; then - if [ $db = 1 ]; then echo Found=$try; fi - SSHD_PID="$try" - echo - ps $try - echo - break - fi - i=`expr $i + 1` - done - if [ "X$SSHD_PID" != "X" ]; then - break - fi - done - fi - #curlie} -}; - -set cmd(2) { - #curlie{ - if [ "X$SSHD_PID" = "X" ]; then - if [ $db = 1 ]; then - echo - pstr=`ps -elf | grep "$USER" | grep "$tty" | grep -v grep | grep -v PID | grep -v "ps -elf"` - echo "$pstr" - fi - plist=`ps -elf | grep "$USER" | grep "$tty" | grep -v grep | grep -v PID | grep -v "ps -elf" | awk "{print \\\$4}" | sort -n` - if [ $db = 1 ]; then - echo - echo "$plist" - fi - for try in $plist - do - if [ $db = 1 ]; then echo try-final=$try; ps $try; fi - if echo "$try" | grep "^[0-9][0-9]*\\\$" > /dev/null; then - : - else - continue - fi - if ps $try | egrep vnc-helper > /dev/null; then - : - else - if [ $db = 1 ]; then echo Found=$try; fi - SSHD_PID=$try - echo - ps $try - echo - break - fi - done - fi - if [ "X$SSHD_PID" = "X" ]; then - #ugh - SSHD_PID=$$ - fi - - echo "vnc-helper: [for cups/smb/esd] SSHD_PID=$SSHD_PID MY_PID=$$ TTY=$tty" - echo "vnc-helper: To force me to finish: rm $FLAG" - } - - wait_til_ssh_gone() { - try_perl="" - if type perl >/dev/null 2>&1; then - if [ -d /proc -a -e /proc/$$ ]; then - try_perl="1" - fi - fi - if [ "X$try_perl" = "X1" ]; then - # try to avoid wasting pids: - perl -e "while (1) {if(-d \"/proc\" && ! -e \"/proc/$SSHD_PID\"){exit} if(! -f \"$FLAG\"){exit} sleep 1;}" - else - while [ 1 ] - do - ps $SSHD_PID > /dev/null 2>&1 - if [ $? != 0 ]; then - break - fi - if [ ! -f $FLAG ]; then - break - fi - sleep 1 - done - fi - rm -f $FLAG - if [ "X$DO_SMB_WAIT" = "X1" ]; then - rm -f $smb_script - fi - } -}; - -set cmd(3) { - update_client_conf() { - mkdir -p $cups_dir - - if [ ! -f $cups_cfg.back ]; then - touch $cups_cfg.back - fi - if [ ! -f $cups_cfg ]; then - touch $cups_cfg - fi - - if grep ssvnc-auto $cups_cfg > /dev/null; then - : - else - cp -p $cups_cfg $cups_cfg.back - fi - - echo "#-ssvnc-auto:" > $cups_cfg - sed -e "s/^ServerName/#-ssvnc-auto-#ServerName/" $cups_cfg.back >> $cups_cfg - echo "ServerName $cups_host:$cups_port" >> $cups_cfg - - echo - echo "-----------------------------------------------------------------" - echo "On `hostname`:" - echo - echo "The CUPS $cups_cfg config file has been set to:" - echo - cat $cups_cfg | grep -v "^#-ssvnc-auto:" | sed -e "s/^/ /" - echo - echo "If there are problems automatically restoring it, edit or remove" - echo "the file to go back to the local CUPS settings." - echo - echo "A backup has been placed in: $cups_cfg.back" - echo - echo "See the SSVNC CUPS dialog for more details on printing." - if type lpstat >/dev/null 2>&1; then - echo - echo "lpstat -a output:" - echo - (lpstat -a 2>&1 | sed -e "s/^/ /") & - sleep 0.5 >/dev/null 2>&1 - fi - echo "-----------------------------------------------------------------" - echo - } - - reset_client_conf() { - cp $cups_cfg $cups_cfg.tmp - grep -v "^ServerName" $cups_cfg.tmp | grep -v "^#-ssvnc-auto:" | sed -e "s/^#-ssvnc-auto-#ServerName/ServerName/" > $cups_cfg - rm -f $cups_cfg.tmp - } - - cupswait() { - trap "" INT QUIT HUP - trap "reset_client_conf; rm -f $FLAG; exit" TERM - wait_til_ssh_gone - reset_client_conf - } -}; - -# if [ "X$DONE_PORT_CHECK" != "X" ]; then -# if type perl >/dev/null 2>&1; then -# perl -e "use IO::Socket::INET; \$SIG{INT} = \"IGNORE\"; \$SIG{QUIT} = \"IGNORE\"; \$SIG{HUP} = \"INGORE\"; my \$client = IO::Socket::INET->new(Listen => 5, LocalAddr => \"localhost\", LocalPort => $DONE_PORT_CHECK, Proto => \"tcp\")->accept(); \$line = <\$client>; close \$client; unlink \"$smb_script\";" </dev/null >/dev/null 2>/dev/null & -# if [ $? = 0 ]; then -# have_perl_done="1" -# fi -# fi -# fi - -set cmd(4) { - smbwait() { - trap "" INT QUIT HUP - wait_til_ssh_gone - } - do_smb_mounts() { - if [ "X$smb_mounts" = "X" ]; then - return - fi - echo > $smb_script - have_perl_done="" - echo "echo" >> $smb_script - dests="" - for mnt in $smb_mounts - do - smfs=`echo "$mnt" | awk -F, "{print \\\$1}"` - dest=`echo "$mnt" | awk -F, "{print \\\$2}"` - port=`echo "$mnt" | awk -F, "{print \\\$3}"` - dest=`echo "$dest" | sed -e "s,__USER__,$USER,g" -e "s,__HOME__,$HOME,g"` - if [ ! -d $dest ]; then - mkdir -p $dest - fi - echo "echo SMBMOUNT:" >> $smb_script - echo "echo smbmount $smfs $dest -o uid=$USER,ip=127.0.0.1,port=$port" >> $smb_script - echo "smbmount \"$smfs\" \"$dest\" -o uid=$USER,ip=127.0.0.1,port=$port" >> $smb_script - echo "echo; df \"$dest\"; echo" >> $smb_script - dests="$dests $dest" - done - #curlie} -}; - -set cmd(5) { - echo "(" >> $smb_script - echo "un_mnt() {" >> $smb_script - for dest in $dests - do - echo " echo smbumount $dest" >> $smb_script - echo " smbumount \"$dest\"" >> $smb_script - done - echo "}" >> $smb_script - echo "trap \"\" INT QUIT HUP" >> $smb_script - echo "trap \"un_mnt; exit\" TERM" >> $smb_script - - try_perl="" - if type perl >/dev/null 2>&1; then - try_perl=1 - fi - uname=`uname` - if [ "X$uname" != "XLinux" -a "X$uname" != "XSunOS" -a "X$uname" != "XDarwin" ]; then - try_perl="" - fi - - if [ "X$try_perl" = "X" ]; then - echo "while [ -f $smb_script ]" >> $smb_script - echo "do" >> $smb_script - echo " sleep 1" >> $smb_script - echo "done" >> $smb_script - else - echo "perl -e \"while (-f \\\"$smb_script\\\") {sleep 1;} exit 0;\"" >> $smb_script - fi - echo "un_mnt" >> $smb_script - echo ") &" >> $smb_script - echo "-----------------------------------------------------------------" - echo "On `hostname`:" - echo - if [ "$DO_SMB_SU" = "0" ]; then - echo "We now run the smbmount script as user $USER" - echo - echo sh $smb_script - sh $smb_script - rc=0 - elif [ "$DO_SMB_SU" = "1" ]; then - echo "We now run the smbmount script via su(1)" - echo - echo "The first \"Password:\" will be for that of root to run the smbmount script." - echo - echo "Subsequent \"Password:\" will be for the SMB share(s) (hit Return if no passwd)" - echo - echo SU: - echo "su root -c \"sh $smb_script\"" - su root -c "sh $smb_script" - rc=$? - elif [ "$DO_SMB_SU" = "2" ]; then - echo "We now run the smbmount script via sudo(8)" - echo - echo "The first \"Password:\" will be for that of the sudo(8) password." - echo - echo "Subsequent \"Password:\" will be for the SMB shares (hit enter if no passwd)" - echo - echo SUDO: - sd="sudo" - echo "$sd sh $smb_script" - $sd sh $smb_script - rc=$? - fi -}; - -set cmd(6) { - #curlie{ - echo - if [ "$rc" = 0 ]; then - if [ "X$have_perl_done" = "X1" -o 1 = 1 ] ; then - echo - echo "Your SMB shares will be unmounted when the VNC connection closes," - echo "*AS LONG AS* No Applications have any of the share files opened or are" - echo "cd-ed into any of the share directories." - echo - echo "Try to make sure nothing is accessing the SMB shares before disconnecting" - echo "the VNC session. If you fail to do that follow these instructions:" - fi - echo - echo "To unmount your SMB shares make sure no applications are still using any of" - echo "the files and no shells are still cd-ed into the share area, then type:" - echo - echo " rm -f $smb_script" - echo - echo "In the worst case run: smbumount /path/to/mount/point for each mount as root" - echo - echo "Even with the remote redirection gone the kernel should umount after a timeout." - else - echo - if [ "$DO_SMB_SU" = "1" ]; then - echo "su(1) to run smbmount(8) failed." - elif [ "$DO_SMB_SU" = "2" ]; then - echo "sudo(8) to run smbmount(8) failed." - fi - rm -f $smb_script - fi - echo "-----------------------------------------------------------------" - echo - } -}; - -set cmd(7) { - - setup_sound() { - dpid="" - d=$sound_daemon_remote_prog - if type pgrep >/dev/null 2>/dev/null; then - dpid=`pgrep -U $USER -x $d | head -1` - else - dpid=`env PATH=/usr/ucb:$PATH ps wwwwaux | grep -w $USER | grep -w $d | grep -v grep | head -1` - fi - echo "-----------------------------------------------------------------" - echo "On `hostname`:" - echo - echo "Setting up Sound: pid=$dpid" - if [ "X$dpid" != "X" ]; then - dcmd=`env PATH=/usr/ucb:$PATH ps wwwwaux | grep -w $USER | grep -w $d | grep -w $dpid | grep -v grep | head -1 | sed -e "s/^.*$d/$d/"` - if [ "X$DO_SOUND_KILL" = "X1" ]; then - echo "Stopping sound daemon: $sound_daemon_remote_prog $dpid" - echo "sound cmd: $dcmd" - kill -TERM $dpid - fi - fi - echo "-----------------------------------------------------------------" - echo - } - - reset_sound() { - if [ "X$DO_SOUND_RESTART" = "X1" ]; then - d=$sound_daemon_remote_prog - a=$sound_daemon_remote_args - echo "Restaring sound daemon: $d $a" - $d $a </dev/null >/dev/null 2>&1 & - fi - } - - soundwait() { - trap "" INT QUIT HUP - trap "reset_sound; rm -f $FLAG; exit" TERM - wait_til_ssh_gone - reset_sound - } - - - findpid - - if [ $DO_SMB = 1 ]; then - do_smb_mounts - fi - - waiter=0 - - if [ $DO_CUPS = 1 ]; then - update_client_conf - cupswait </dev/null >/dev/null 2>/dev/null & - waiter=1 - fi - - if [ $DO_SOUND = 1 ]; then - setup_sound - soundwait </dev/null >/dev/null 2>/dev/null & - waiter=1 - fi - if [ $DO_SMB_WAIT = 1 ]; then - if [ $waiter != 1 ]; then - smbwait </dev/null >/dev/null 2>/dev/null & - waiter=1 - fi - fi - - - #FINMSG - echo "--main-vnc-helper-finished--" - #cat $0 - rm -f $0 - exit 0 -}; - - set cmdall "" - - for {set i 1} {$i <= 7} {incr i} { - set v $cmd($i); - regsub -all "\n" $v "%" v - regsub -all {.curlie.} $v "" v - set cmd($i) $v - append cmdall "echo " - if {$i == 1} { - append cmdall {TOPPID=$$ %} - } - append cmdall {'} - append cmdall $cmd($i) - append cmdall {' | tr '%' '\n'} - if {$i == 1} { - append cmdall {>} - } else { - append cmdall {>>} - } - append cmdall {$HOME/.vnc-helper-cmd__PID__; } - } - append cmdall {sh $HOME/.vnc-helper-cmd__PID__; } - - regsub -all {vnc-helper-cmd} $cmdall "vnc-helper-cmd-$mode" cmdall - if {$tag == ""} { - set tag [pid] - } - regsub -all {__PID__} $cmdall "$tag" cmdall - - set orig $cmdall - - global use_cups cups_local_server cups_remote_port cups_manage_rcfile ts_only ts_cups_manage_rcfile cups_x11vnc - regsub -all {[ ]} $cups_local_server "" cups_local_server - regsub -all {[ ]} $cups_remote_port "" cups_remote_port - if {$use_cups} { - set dorc 0 - if {$ts_only} { - if {$ts_cups_manage_rcfile} { - set dorc 1 - } - } else { - if {$cups_manage_rcfile} { - set dorc 1 - } - } - if {$dorc && $mode == "post"} { - if {$cups_local_server != "" && $cups_remote_port != ""} { - regsub {DO_CUPS=0} $cmdall {DO_CUPS=1} cmdall - regsub {cups_port=NNNN} $cmdall "cups_port=$cups_remote_port" cmdall - } - } - } - - global use_smbmnt smb_su_mode smb_mounts - if {$use_smbmnt} { - if {$smb_mounts != ""} { - set smbm $smb_mounts - regsub -all {%USER} $smbm "__USER__" smbm - regsub -all {%HOME} $smbm "__HOME__" smbm - if {$mode == "pre"} { - regsub {DO_SMB=0} $cmdall {DO_SMB=1} cmdall - if {$smb_su_mode == "su"} { - regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=1} cmdall - } elseif {$smb_su_mode == "sudo"} { - regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=2} cmdall - } elseif {$smb_su_mode == "none"} { - regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=0} cmdall - } else { - regsub {DO_SMB_SU=0} $cmdall {DO_SMB_SU=1} cmdall - } - regsub {smb_mounts=} $cmdall "smb_mounts=\"$smbm\"" cmdall - } elseif {$mode == "post"} { - regsub {DO_SMB_WAIT=0} $cmdall {DO_SMB_WAIT=1} cmdall - } - } - } - - global use_sound - if {$use_sound} { - if {$mode == "pre"} { - global sound_daemon_remote_cmd sound_daemon_kill sound_daemon_restart - if {$sound_daemon_kill} { - regsub {DO_SOUND_KILL=0} $cmdall {DO_SOUND_KILL=1} cmdall - regsub {DO_SOUND=0} $cmdall {DO_SOUND=1} cmdall - } - if {$sound_daemon_restart} { - regsub {DO_SOUND_RESTART=0} $cmdall {DO_SOUND_RESTART=1} cmdall - regsub {DO_SOUND=0} $cmdall {DO_SOUND=1} cmdall - } - set sp [string trim $sound_daemon_remote_cmd] - regsub {[ \t].*$} $sp "" sp - set sa [string trim $sound_daemon_remote_cmd] - regsub {^[^ \t][^ \t]*[ \t][ \t]*} $sa "" sa - regsub {sound_daemon_remote_prog=} $cmdall "sound_daemon_remote_prog=\"$sp\"" cmdall - regsub {sound_daemon_remote_args=} $cmdall "sound_daemon_remote_args=\"$sa\"" cmdall - } - } - - if {$mode == "pre"} { - set dopre 0 - if {$use_smbmnt && $smb_mounts != ""} { - set dopre 1 - } - if {$use_sound && $sound_daemon_kill} { - set dopre 1 - } - if {$dopre} { - global is_windows - if {$is_windows} { - regsub {#FINMSG} $cmdall {echo "Now Go Click on the Label to Start the 2nd SSH"} cmdall - } else { - regsub {#FINMSG} $cmdall {echo "Finished with the 1st SSH tasks, the 2nd SSH should start shortly..."} cmdall - } - } - } - - set cmdstr $cmdall - - if {"$orig" == "$cmdall"} { - set cmdstr "" - } - global env - if [info exists env(SSVNC_DEBUG_CUPS)] { - regsub -all {db=0} $cmdstr "db=1" cmdstr - set pout "" - regsub -all {%} $cmdstr "\n" pout - puts stderr "\nSERVICE REDIR COMMAND:\n\n$pout\n" - } - return $cmdstr -} - -proc ts_unixpw_dialog {} { - - toplev .uxpw - wm title .uxpw "Use unixpw" - - scroll_text .uxpw.f 80 14 - - global ts_unixpw - - set msg { - This enables the x11vnc unixpw mode. A Login: and Password: dialog - will be presented in the VNC Viewer for the user to provide any Unix - username and password whose session he wants to connect to. So this - may require typing in the password a 2nd time after the one for SSH. - - This mode is useful if a shared terminal services user (e.g. 'tsuser') - is used for the SSH login part (say via the SSH authorized_keys - mechanism and all users share the same private SSH key for 'tsuser'). - - Note, However that the default usage of a per-user SSH login should - be the simplest and also sufficient for most situations, in which - case this "Use unixpw" option should NOT be selected. -} - .uxpw.f.t insert end $msg - - button .uxpw.cancel -text "Cancel" -command {destroy .uxpw; set ts_unixpw 0} - bind .uxpw <Escape> {destroy .uxpw; set ts_unixpw 0} - wm protocol .uxpw WM_DELETE_WINDOW {destroy .uxpw; set ts_unixpw 0} - - button .uxpw.done -text "Done" -command {destroy .uxpw; set ts_unixpw 1} - - pack .uxpw.done .uxpw.cancel -side bottom -fill x - pack .uxpw.f -side top -fill both -expand 1 - - center_win .uxpw -} - -proc ts_vncshared_dialog {} { - - toplev .vncs - wm title .vncs "VNC Shared" - - scroll_text .vncs.f 80 23 - - global ts_vncshared - - set msg { - Normal use of this program, 'tsvnc', *ALREADY* allows simultaneous - shared access of the remote desktop: You simply log in as many - times from as many different locations with 'tsvnc' as you like. - - However, doing it that way starts up a new x11vnc for each connection. - In some circumstances you may want a single x11vnc running but allow - multiple VNC viewers to access it simultaneously. - - This option (VNC Shared) enables that rarer usage case by passing - '-shared' to the remote x11vnc command. - - With this option enabled, the new shared connections must - still connect to the Terminal Server via SSH for encryption and - authentication. They must also do the normal SSH port redirection - to access the x11vnc port (usually 5900, but look for the PORT= - output for the actual value). - - They could use SSVNC for that, or do it manually in terminal - windows, more information: - - http://www.karlrunge.com/x11vnc/#tunnelling -} - .vncs.f.t insert end $msg - - button .vncs.cancel -text "Cancel" -command {destroy .vncs; set ts_vncshared 0} - bind .vncs <Escape> {destroy .vncs; set ts_vncshared 0} - wm protocol .vncs WM_DELETE_WINDOW {destroy .vncs; set ts_vncshared 0} - button .vncs.done -text "Done" -command {destroy .vncs; set ts_vncshared 1} - - pack .vncs.done .vncs.cancel -side bottom -fill x - pack .vncs.f -side top -fill both -expand 1 - - center_win .vncs -} - -proc ts_multi_dialog {} { - - toplev .mult - wm title .mult "Multiple Sessions" - - scroll_text .mult.f 80 21 - - global ts_multisession choose_multisession - - set msg { - Normally in Terminal Services mode (tsvnc) your user account (the - one you SSH in as) can only have a single Terminal Services X session - running at a time on one server machine. - - This is simply because x11vnc chooses the first Desktop (X session) - of yours that it can find. It will never create a 2nd X session - because it keeps finding the 1st one. - - To have Multiple Sessions for one username on a single machine, - choose a unique Session "Tag", that will be associated with the X - session and x11vnc will only choose the one that has this Tag. - - For this to work ALL of your sessions on the server machine must - have a different tag (that is, if you have an existing session with - no tag, x11vnc might find a tagged one first instead of it). - - The tag must be made of only letters, numbers, dash, or underscore. - - Examples: KDE_SMALL, gnome-2, test1 -} - .mult.f.t insert end $msg - - frame .mult.c - label .mult.c.l -anchor w -text "Tag:" - entry .mult.c.e -width 20 -textvariable ts_multisession - pack .mult.c.l -side left - pack .mult.c.e -side left -expand 1 -fill x - - button .mult.cancel -text "Cancel" -command {destroy .mult; set choose_multisession 0} - bind .mult <Escape> {destroy .mult; set choose_multisession 0} - wm protocol .mult WM_DELETE_WINDOW {destroy .mult; set choose_multisession 0} - - bind .mult.c.e <Return> {destroy .mult; set choose_multisession 1} - button .mult.done -text "Done" -command {destroy .mult; set choose_multisession 1} - - pack .mult.done .mult.cancel .mult.c -side bottom -fill x - pack .mult.f -side top -fill both -expand 1 - - center_win .mult - focus .mult.c.e -} - -proc ts_xlogin_dialog {} { - - toplev .xlog - wm title .xlog "X Login Greeter" - - set h 33 - if [small_height] { - set h 28 - } - scroll_text .xlog.f 80 $h - - global ts_xlogin - - set msg { - If you have root (sudo(1)) permission on the remote machine, you - can have x11vnc try to connect to a X display(s) that has No One - Logged In Yet. This is most likely the login greeter running on - the Physical console. sudo(1) is used to run x11vnc with FD_XDM=1. - - This is different from tsvnc's regular Terminal Services mode where - usually a virtual (RAM only, e.g. Xvfb) X server used. With this option - it is the physical graphics hardware that will be connected to. - - Note that if your user is ALREADY logged into the physical display, - you don't need to use this X Login option because x11vnc should find - it in its normal find-display procedure and not need sudo(1). - - An initial ssh running 'sudo id' is performed to try to 'prime' - sudo so the 2nd one that runs x11vnc does not need a password. - This may not always succeed... - - Note that if someone is already logged into the display console - via XDM (GDM, KDM etc.) you will see and control their X session. - - Otherwise, you will get the Greeter X login screen where you can - log in via username and password. Your SSVNC 'Terminal Services' - Desktop Type, Size, Printing etc. settings will be ignored in this - case of course because XDM, GDM, or KDM is creating your X session, - not x11vnc. - - Note that the GDM display manager has a setting KillInitClients in - gdm.conf that will kill x11vnc right after you log in, and so you would - have to repeat the whole process ('Connect' button) to attach to your - session. See http://www.karlrunge.com/x11vnc/faq.html#faq-display-manager - for more info. -} - .xlog.f.t insert end $msg - - button .xlog.cancel -text "Cancel" -command {destroy .xlog; set ts_xlogin 0} - bind .xlog <Escape> {destroy .xlog; set ts_xlogin 0} - wm protocol .xlog WM_DELETE_WINDOW {destroy .xlog; set ts_xlogin 0} - - button .xlog.done -text "Done" -command {destroy .xlog; set ts_xlogin 1} - - pack .xlog.done .xlog.cancel -side bottom -fill x - pack .xlog.f -side top -fill both -expand 1 - - center_win .xlog -} - - -proc ts_othervnc_dialog {} { - - toplev .ovnc - wm title .ovnc "Other VNC Server" - - scroll_text .ovnc.f 80 21 - - global ts_othervnc choose_othervnc - - set msg { - The x11vnc program running on the remote machine can be instructed to - immediately redirect to some other (3rd party, e.g. Xvnc or vnc.so) - VNC server. - - It should be a little faster to have x11vnc forward the VNC protocol - rather than having it poll the corresponding X server for changes - in the way it normally does and translate to VNC. - - This mode also enables a simple way to add SSL or find X display - support to a 3rd party VNC Server lacking these features. - - In the entry box put the other vnc display, e.g. "localhost:0" or - "somehost:5". - - The string "find" in the entry will have x11vnc try to find an X - display in its normal way, and then redirect to the corresponding VNC - server port. This assumes if the X display is, say, :2 (i.e. port - 6002) then the VNC display is also :2 (i.e. port 5902). This mode is - the same as an "X Server Type" of "Xvnc.redirect" (and overrides it). -} - .ovnc.f.t insert end $msg - - frame .ovnc.c - label .ovnc.c.l -anchor w -text "Other VNC Server:" - entry .ovnc.c.e -width 20 -textvariable ts_othervnc - pack .ovnc.c.l -side left - pack .ovnc.c.e -side left -expand 1 -fill x - - button .ovnc.cancel -text "Cancel" -command {destroy .ovnc; set choose_othervnc 0} - bind .ovnc <Escape> {destroy .ovnc; set choose_othervnc 0} - wm protocol .ovnc WM_DELETE_WINDOW {destroy .ovnc; set choose_othervnc 0} - button .ovnc.done -text "Done" -command {destroy .ovnc; set choose_othervnc 1} - bind .ovnc.c.e <Return> {destroy .ovnc; set choose_othervnc 1} - - if {$ts_othervnc == ""} { - set ts_othervnc "find" - } - - pack .ovnc.done .ovnc.cancel .ovnc.c -side bottom -fill x - pack .ovnc.f -side top -fill both -expand 1 - - center_win .ovnc - focus .ovnc.c.e -} - -proc ts_sleep_dialog {} { - - toplev .eslp - wm title .eslp "Extra Sleep" - - scroll_text .eslp.f 80 5 - - global extra_sleep - - set msg { - Sleep: Enter a number to indicate how many extra seconds to sleep - while waiting for the VNC viewer to start up. On Windows this - can give extra time to enter the Putty/Plink password, etc. -} - .eslp.f.t insert end $msg - - frame .eslp.c - label .eslp.c.l -anchor w -text "Extra Sleep:" - entry .eslp.c.e -width 20 -textvariable extra_sleep - pack .eslp.c.l -side left - pack .eslp.c.e -side left -expand 1 -fill x - - button .eslp.cancel -text "Cancel" -command {destroy .eslp; set choose_sleep 0} - bind .eslp <Escape> {destroy .eslp; set choose_sleep 0} - wm protocol .eslp WM_DELETE_WINDOW {destroy .eslp; set choose_sleep 0} - button .eslp.done -text "Done" -command {destroy .eslp; set choose_sleep 1} - bind .eslp.c.e <Return> {destroy .eslp; set choose_sleep 1} - - global choose_sleep - if {! $choose_sleep} { - set extra_sleep "" - } - - pack .eslp.done .eslp.cancel .eslp.c -side bottom -fill x - pack .eslp.f -side top -fill both -expand 1 - - center_win .eslp - focus .eslp.c.e -} - -proc ts_putty_args_dialog {} { - - toplev .parg - wm title .parg "Putty Args" - - scroll_text .parg.f 80 5 - - global putty_args - - set msg { - Putty Args: Enter a string to be added to every plink.exe and putty.exe - command line. For example: -i C:\mykey.ppk -} - .parg.f.t insert end $msg - - frame .parg.c - label .parg.c.l -anchor w -text "Putty Args:" - entry .parg.c.e -width 20 -textvariable putty_args - pack .parg.c.l -side left - pack .parg.c.e -side left -expand 1 -fill x - - button .parg.cancel -text "Cancel" -command {destroy .parg; set choose_parg 0} - bind .parg <Escape> {destroy .parg; set choose_parg 0} - wm protocol .parg WM_DELETE_WINDOW {destroy .parg; set choose_parg 0} - button .parg.done -text "Done" -command {destroy .parg; set choose_parg 1} - bind .parg.c.e <Return> {destroy .parg; set choose_parg 1} - - global choose_parg - if {! $choose_parg} { - set putty_args "" - } - - pack .parg.done .parg.cancel .parg.c -side bottom -fill x - pack .parg.f -side top -fill both -expand 1 - - center_win .parg - focus .parg.c.e -} - -proc ts_ncache_dialog {} { - - toplev .nche - wm title .nche "Client-Side Caching" - - scroll_text .nche.f 80 22 - - global ts_ncache choose_ncache - - set msg { - This enables the *experimental* x11vnc client-side caching mode. - It often gives nice speedups, but can sometimes lead to painting - errors or window "flashing". (you can repaint the screen by tapping - the Left Alt key 3 times in a row) - - It is a very simple but hoggy method: uncompressed image pixmaps are - stored in the viewer in a large (20-100MB) display region beneath - the actual display screen. You may need also to adjust your VNC Viewer - to not show this region (the SSVNC Unix viewer does it automatically). - - The scheme uses a lot of RAM, but at least it has the advantage that - it works with every VNC Viewer. Otherwise the VNC protocol would - need to be modified, changing both the server and the viewer. - - Set the x11vnc "-ncache" parameter to an even integer between 2 - and 20. This is the increase in area factor over the normal screen - for the caching region. So 10 means use 10 times the RAM to store - pixmaps. The default is 8. - - More info: http://www.karlrunge.com/x11vnc/faq.html#faq-client-caching -} - .nche.f.t insert end $msg - - frame .nche.c - label .nche.c.l -anchor w -text "ncache:" - radiobutton .nche.c.r2 -text "2" -variable ts_ncache -value "2" - radiobutton .nche.c.r4 -text "4" -variable ts_ncache -value "4" - radiobutton .nche.c.r6 -text "6" -variable ts_ncache -value "6" - radiobutton .nche.c.r8 -text "8" -variable ts_ncache -value "8" - radiobutton .nche.c.r10 -text "10" -variable ts_ncache -value "10" - radiobutton .nche.c.r12 -text "12" -variable ts_ncache -value "12" - radiobutton .nche.c.r14 -text "14" -variable ts_ncache -value "14" - radiobutton .nche.c.r16 -text "16" -variable ts_ncache -value "16" - radiobutton .nche.c.r18 -text "18" -variable ts_ncache -value "18" - radiobutton .nche.c.r20 -text "20" -variable ts_ncache -value "20" - pack .nche.c.l -side left - pack .nche.c.r2 .nche.c.r4 .nche.c.r6 .nche.c.r8 .nche.c.r10 \ - .nche.c.r12 .nche.c.r14 .nche.c.r16 .nche.c.r18 .nche.c.r20 -side left - button .nche.cancel -text "Cancel" -command {destroy .nche; set choose_ncache 0} - bind .nche <Escape> {destroy .nche; set choose_ncache 0} - wm protocol .nche WM_DELETE_WINDOW {destroy .nche; set choose_ncache 0} - button .nche.done -text "Done" -command {destroy .nche; set choose_ncache 1} - - pack .nche.done .nche.cancel .nche.c -side bottom -fill x - pack .nche.f -side top -fill both -expand 1 - - center_win .nche -} - -proc ts_x11vnc_opts_dialog {} { - - toplev .x11v - wm title .x11v "x11vnc Options" - - set h 23 - if [small_height] { - set h 21 - } - scroll_text .x11v.f 80 $h - - global ts_x11vnc_opts ts_x11vnc_path ts_x11vnc_autoport choose_x11vnc_opts - global additional_port_redirs_list - - set msg { - If you are an expert with x11vnc's endless options and tweaking - parameters feel free to specify any you want here in "Options". - - Also, if you need to specify the path to the x11vnc program on the - remote side because it will not be in $PATH, put it in the "Full - Path" entry. - - Port Redirs are additional SSH "-L port:host:port" or "-R port:host:port" - (forward or reverse, resp.) port redirections you want. In SSVNC mode, - see the detailed description under: Options -> Advanced -> Port Redirs. - - Some potentially useful options: - - -solid -scale -scale_cursor - -passwd -rfbauth -http - -xrandr -rotate -noxdamage - -xkb -skip_lockkeys -nomodtweak - -repeat -cursor -wmdt - -nowireframe -ncache_cr -speeds - - More info: http://www.karlrunge.com/x11vnc/faq.html#faq-cmdline-opts -} -# In Auto Port put a starting port for x11vnc to try autoprobing -# instead of the default 5900. It starts at the value you supply and -# works upward until a free one is found. (x11vnc 0.9.3 or later). - - .x11v.f.t insert end $msg - - frame .x11v.c - label .x11v.c.l -width 10 -anchor w -text "Options:" - entry .x11v.c.e -textvariable ts_x11vnc_opts - pack .x11v.c.l -side left - pack .x11v.c.e -side left -expand 1 -fill x - - frame .x11v.c2 - label .x11v.c2.l -width 10 -anchor w -text "Full Path:" - entry .x11v.c2.e -textvariable ts_x11vnc_path - pack .x11v.c2.l -side left - pack .x11v.c2.e -side left -expand 1 -fill x - -# frame .x11v.c3 -# label .x11v.c3.l -width 10 -anchor w -text "Auto Port:" -# entry .x11v.c3.e -textvariable ts_x11vnc_autoport -# pack .x11v.c3.l -side left -# pack .x11v.c3.e -side left -expand 1 -fill x - - frame .x11v.c4 - label .x11v.c4.l -width 10 -anchor w -text "Port Redirs:" - entry .x11v.c4.e -textvariable additional_port_redirs_list - pack .x11v.c4.l -side left - pack .x11v.c4.e -side left -expand 1 -fill x - - button .x11v.cancel -text "Cancel" -command {destroy .x11v; set choose_x11vnc_opts 0} - bind .x11v <Escape> {destroy .x11v; set choose_x11vnc_opts 0} - wm protocol .x11v WM_DELETE_WINDOW {destroy .x11v; set choose_x11vnc_opts 0} - button .x11v.done -text "Done" -command {destroy .x11v; set choose_x11vnc_opts 1; - if {$additional_port_redirs_list != ""} {set additional_port_redirs 1} else {set additional_port_redirs 0}} - -# pack .x11v.done .x11v.cancel .x11v.c4 .x11v.c3 .x11v.c2 .x11v.c -side bottom -fill x - pack .x11v.done .x11v.cancel .x11v.c4 .x11v.c2 .x11v.c -side bottom -fill x - pack .x11v.f -side top -fill both -expand 1 - - center_win .x11v - focus .x11v.c.e -} - - -proc ts_filexfer_dialog {} { - - toplev .xfer - wm title .xfer "File Transfer" - global choose_filexfer ts_filexfer - - scroll_text .xfer.f 70 13 - - set msg { - x11vnc supports both the UltraVNC and TightVNC file transfer - extensions. On Windows both viewers support their file transfer - protocol. On Unix only the SSVNC VNC Viewer can do filexfer; it - supports the UltraVNC flavor via a Java helper program (and so - java(1) is required on the viewer-side). - - Choose the one you want based on VNC viewer you will use. - The defaults for the SSVNC viewer package are TightVNC on - Windows and UltraVNC on Unix. - - For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-filexfer -} - .xfer.f.t insert end $msg - - global is_windows - if {$ts_filexfer == ""} { - if {$is_windows} { - set ts_filexfer "tight" - } else { - set ts_filexfer "ultra" - } - } - - frame .xfer.c - radiobutton .xfer.c.tight -text "TightVNC" -variable ts_filexfer -value "tight" -relief ridge - radiobutton .xfer.c.ultra -text "UltraVNC" -variable ts_filexfer -value "ultra" -relief ridge - - pack .xfer.c.ultra .xfer.c.tight -side left -fill x -expand 1 - - button .xfer.cancel -text "Cancel" -command {destroy .xfer; set choose_filexfer 0} - bind .xfer <Escape> {destroy .xfer; set choose_filexfer 0} - wm protocol .xfer WM_DELETE_WINDOW {destroy .xfer; set choose_filexfer 0} - button .xfer.done -text "Done" -command {destroy .xfer; set choose_filexfer 1} - - pack .xfer.done .xfer.cancel -side bottom -fill x - pack .xfer.c -side bottom -fill x -expand 1 - pack .xfer.f -side top -fill both -expand 1 - - center_win .xfer -} - -proc ts_cups_dialog {} { - - toplev .cups - wm title .cups "CUPS and SMB Printing" - global cups_local_server cups_remote_port cups_manage_rcfile ts_cups_manage_rcfile cups_x11vnc - global cups_local_smb_server cups_remote_smb_port - - set h 30 - if [small_height] { - set h 24 - } - scroll_text .cups.f 80 $h - - - set msg { - This method requires a working CUPS Desktop setup on the remote side - of the connection and working CUPS (or possibly Windows SMB or IPP) - printing on the local viewer-side of the connection. - - For CUPS printing redirection to work properly, you MUST enable it for - the connection that *creates* your terminal services X session (i.e. the - first connection.) You cannot retroactively enable CUPS redirection - on an already existing terminal services X session. (See CUPS printing - for normal SSVNC mode for how you might do that.) - - Enter the VNC Viewer side (i.e. where you are sitting) CUPS server - under "Local CUPS Server". Use "localhost:631" if there is one - on your viewer machine (normally the case if you set up a printer - on your unix or macosx system), or, e.g., "my-print-srv:631" for a - nearby CUPS print server. Note that 631 is the default CUPS port. - - (On MacOSX it seems better to use "127.0.0.1" instead of "localhost".) - - The SSVNC Terminal Services created remote Desktop session will have - the variables CUPS_SERVER and IPP_PORT set so all printing applications - will be redirected to your local CUPS server. So your locally available - printers should appear in the remote print dialogs. - - - Windows/SMB Printers: Under "Local SMB Print Server" you can set a - port redirection for a Windows (non-CUPS) SMB printer. If localhost:139 - does not work, try the literal string "IP:139", or use the known value - of the IP address manually. 139 is the default SMB port; nowadays 445 - might be a better possibility. - - For Windows/SMB Printers if there is no local CUPS print server, it is - usually a very good idea to make the CUPS Server setting EMPTY (to avoid - desktop apps trying incessantly to reach the nonexistent CUPS server.) - - On the remote side, in the Desktop session the variables $SMB_SERVER, - $SMB_HOST, and $SMB_PORT will be set for you to use. - - Unfortunately, printing to Windows may only ve partially functional due - to the general lack PostScript support on Windows. - - If you have print admin permission on the remote machine you can - configure CUPS to know about your Windows printer via lpadmin(8) or - a GUI tool. You give it the URI: - - smb://localhost:port/printername - - or possibly: - - smb://localhost:port/computer/printername - - "port" will be found in the $SMB_PORT. You also need to identify - the printer type. NOTE: You will leave "Local CUPS Server" blank in - this case. The smbspool(1) command should also work as well, at least - for PostScript printers. - - A similar thing can be done with CUPS printers if you are having problems - with the above default mechanism. Use - - http://localhost:port/printers/printername - - For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups -} - -# The "Manage 'ServerName' in .cups/client.conf for me" setting is usually -# NOT needed unless you are using Terminal Services to connect to an -# existing Session that did NOT have CUPS print redirection set at session -# start time (i.e. IPP_PORT and CUPS_SERVER were not set up). In that -# case, select this option as a workaround: NOTE that the client.conf -# setting will REDIRECT ALL PRINTING for apps with the same $HOME/.cups -# directory (which you probably do not want), however it will be reset -# when the SSVNC viewer disconnects. - - .cups.f.t insert end $msg - - global uname - if {$cups_local_server == ""} { - if {$uname == "Darwin"} { - set cups_local_server "127.0.0.1:631" - } else { - set cups_local_server "localhost:631" - } - } - if {$cups_remote_port == ""} { - set cups_remote_port [expr "6731 + int(1000 * rand())"] - } - if {$cups_local_smb_server == ""} { - global is_windows - if {$is_windows} { - set cups_local_smb_server "IP:139" - } elseif {$uname == "Darwin"} { - set cups_local_smb_server "127.0.0.1:139" - } else { - set cups_local_smb_server "localhost:139" - } - } - if {$cups_remote_smb_port == ""} { - set cups_remote_smb_port [expr "7731 + int(1000 * rand())"] - } - - frame .cups.serv - label .cups.serv.l -anchor w -text "Local CUPS Server: " - entry .cups.serv.e -width 40 -textvariable cups_local_server - pack .cups.serv.e -side right - pack .cups.serv.l -side left -expand 1 -fill x - - frame .cups.smbs - label .cups.smbs.l -anchor w -text "Local SMB Print Server: " - entry .cups.smbs.e -width 40 -textvariable cups_local_smb_server - pack .cups.smbs.e -side right - pack .cups.smbs.l -side left -expand 1 -fill x - - # not working with x11vnc: - checkbutton .cups.cupsrc -anchor w -variable ts_cups_manage_rcfile -text \ - "Manage 'ServerName' in the remote \$HOME/.cups/client.conf file for me" - - button .cups.cancel -text "Cancel" -command {destroy .cups; set use_cups 0} - bind .cups <Escape> {destroy .cups; set use_cups 0} - wm protocol .cups WM_DELETE_WINDOW {destroy .cups; set use_cups 0} - button .cups.done -text "Done" -command {destroy .cups; if {$use_cups} {set_ssh}} - - pack .cups.done .cups.cancel .cups.smbs .cups.serv -side bottom -fill x - pack .cups.f -side top -fill both -expand 1 - - center_win .cups - focus .cups.serv.e -} - - -proc cups_dialog {} { - - toplev .cups - wm title .cups "CUPS Tunnelling" - global cups_local_server cups_remote_port cups_manage_rcfile cups_x11vnc - global cups_local_smb_server cups_remote_smb_port - global ts_only - if {$ts_only} { - ts_cups_dialog - return - } - - global uname - set h 33 - if [small_height] { - set h 17 - } elseif {$uname == "Darwin"} { - set h 24 - } - scroll_text .cups.f 80 $h - - - set msg { - CUPS Printing requires SSH be used to set up the CUPS Print service TCP - port redirection. This will be either of the "Use SSH" or "SSH+SSL" modes. - NOTE: For pure SSL tunnelling it currently will not work. - - This method requires working CUPS software setups on BOTH the remote - and local sides of the connection. - - If the remote VNC server is Windows you probably cannot SSH into it - anyway... If you can, you will still need to set up a special printer - TCP port redirection on your own. Perhaps adding and configuring a - "Unix Printer" under Windows (like Method #2 below) will work. - - If the local machine (SSVNC side) is Windows, see the bottom of this - help for redirecting to SMB printers. - - If the remote VNC server is Mac OS X this method may or may not work. - Sometimes applications need to be restarted to get them to notice the - new printers. Adding and configuring a special "Unix Printer", - (Method #2) below, might yield more reliable results at the cost of - additional setup and permissions. - - For Unix/Linux remote VNC servers, applications may also need to be - restarted to notice the new printers. The only case known to work - well is the one where the remote side has no CUPS printers configured. - As mentioned above, see Method #2 for another method. - - ************************************************************************* - *** Directions: - - You choose your own remote CUPS redir port below under "Use Remote - CUPS Port". 6631 is our default and is used in the examples below. - Use it or some random value greater than 1024. Note that the standard - CUPS server port is 631. - - The port you choose must be unused on the VNC server machine (it is NOT - checked for you). Print requests connecting to it are redirected to - your local VNC viewer-side CUPS server through the SSH tunnel. - - (Note: root SSH login permission is needed for ports less than 1024, - e.g. 631; this is not recommended, use something around 6631 instead). - - Then enter the VNC Viewer side (i.e. where you are sitting) CUPS server - into "Local CUPS Server". A good choice is the default "localhost:631" - if there is a cups server on your viewer machine (this is usually the case - if you have set up a printer). Otherwise enter, e.g., "my-print-srv:631" - for your nearby (viewer-side) CUPS print server. - - - The "Manage 'ServerName' in the $HOME/.cups/client.conf file for me" - setting below is enabled by default. It should handle most situations. - - What it does is modify the .cups/client.conf file on the VNC server-side - to redirect the print requests while the SSVNC viewer is connected. When - SSVNC disconnects .cups/client.conf is restored to its previous setting. - - If, for some reason, the SSVNC CUPS script fails to restore this file - after SSVNC disconnects, run this command on the remote machine: - - cp $HOME/.cups/client.conf.back $HOME/.cups/client.conf - - to regain your initial printing configuration. - - - You can also use CUPS on the VNC server-side to redirect to Windows - (SMB) printers. See the additional info for Windows Printing at the - bottom of this help. - - - In case the default method (automatic .cups/client.conf modification) - fails, we describe below all of the possible methods that can be tried. - - As noted above, you may need to restart applications for them to notice - the new printers or for them to revert to the original printers. If this - is not acceptable, consider Method #2 below if you have the permission - and ability to alter the print queues for this. - - - ************************************************************************* - *** Method #1: Manually create or edit the file $HOME/.cups/client.conf - on the VNC server side by putting in something like this in it: - - ServerName localhost:6631 - - based on the port you set in this dialog's entry box. - - After the remote VNC Connection is finished, to go back to the non-SSH - tunnelled CUPS server and either remove the client.conf file or comment - out the ServerName line. This restores the normal CUPS server for - you on the remote VNC server machine. - - Select "Manage 'ServerName' in the $HOME/.cups/client.conf file for me" - to do this editing of the VNC server-side CUPS config file for you - automatically. NOTE: It is now on by default (deselect it if you want - to manage the file manually; e.g. you print through the tunnel only very - rarely, or often print locally when the tunnel is up, etc.) - - Select "Pass -env FD_CUPS=<Port> to x11vnc command line" if you are - starting x11vnc as the Remote SSH Command, and x11vnc is running in - -create mode (i.e. FINDCREATEDISPLAY). That way, when your X session - is created IPP_PORT will be set correctly for the entire session. - This is the mode used for 'Terminal Services' printing. - - NOTE: You probably would never select both of the above two options - at the same time, since they conflict with each other to some degree. - - - ************************************************************************* - *** Method #2: If you have admin permission on the VNC Server machine - you can likely "Add a Printer" via a GUI dialog, a Wizard, CUPS Web - interface (i.e. http://localhost:631/), lpadmin(8), etc. - - You will need to tell the dialog that the network printer located - is at, e.g., localhost:6631, and anything else needed to identify - the printer (type, model, etc). NOTE: sometimes it is best to set - the model/type as "Generic / Postscript Printer" to avoid problems - with garbage being printed out. - - For the URI to use, we have successfully used ones like this with CUPS: - - http://localhost:6631/printers/Deskjet-3840 - ipp://localhost:6631/printers/Deskjet-3840 - - for an HP Deskjet-3840 printer. See the CUPS documentation for more - about the URI syntax and pathname. - - This mode makes the client.conf ServerName parameter unnecessary - (BE SURE TO DISABLE the "Manage 'ServerName' ... for me" option.) - - - ************************************************************************* - *** Method #3: Restarting individual applications with the IPP_PORT - set will enable redirected printing for them, e.g.: - - env IPP_PORT=6631 firefox - - If you can only get this method to work, an extreme application would - be to run the whole desktop, e.g. "env IPP_PORT=6631 gnome-session", but - then you would need some sort of TCP redirector (ssh -L comes to mind), - to direct it to 631 when not connected remotely. - - - ************************************************************************* - *** Windows/SMB Printers: Under "Local SMB Print Server" you can set - a port redirection for a Windows (non-CUPS) SMB printer. E.g. port - 6632 -> localhost:139. - - If localhost:139 does not work, try the literal string "IP:139", or - insert the actual IP address manually. NOTE: Nowadays on Windows port - 445 might be a better choice. - - For Windows printers, if there is no local CUPS print server, set the - 'Local CUPS Server' and 'Use Remote CUPS Port' to be EMPTY (to avoid - desktop apps trying incessantly to reach the nonexistent CUPS server.) - - You must enable Sharing for your local Windows Printer. Use Windows - Printer configuration dialogs to do this. - - Next, you need to have sudo or print admin permission so that you can - configure the *remote* CUPS to know about this Windows printer via - lpadmin(8) or GUI Printer Configuration dialog, etc (Method #2 above). - You basically give it the URI: - - smb://localhost:6632/printername - - For example, we have had success with GNOME CUPS printing configuration - using: - - smb://localhost:6632/HPOffice - smb://localhost:6632/COMPUTERNAME/HPOffice - - where "HPOffice" was the name Windows shares the printer as. - - Also with this SMB port redir mode, as a last resort you can often print - using the smbspool(8) program like this: - - smbspool smb://localhost:6632/printer job user title 1 "" myfile.ps - - You could put this in a script. For this URI, it appears only the number - of copies ("1" above) and the file itself are important. - - If on the local (SSVNC viewer) side there is some nearby CUPS print server - that knows about your Windows printer, you might have better luck with - that instead of using SMB. Set 'Local CUPS Server' to it. - - For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-cups -} - .cups.f.t insert end $msg - - global uname - set something_set 0 - - if {$cups_local_server != ""} { - set something_set 1 - } - if {$cups_local_smb_server != ""} { - set something_set 1 - } - - if {$cups_local_server == "" && ! $something_set} { - if {$uname == "Darwin"} { - set cups_local_server "127.0.0.1:631" - } else { - set cups_local_server "localhost:631" - } - } - if {$cups_remote_port == "" && ! $something_set} { - set cups_remote_port "6631" - } - if {$cups_local_smb_server == "" && ! $something_set} { - global is_windows - if {$is_windows} { - set cups_local_smb_server "IP:139" - } elseif {$uname == "Darwin"} { - set cups_local_smb_server "127.0.0.1:139" - } else { - set cups_local_smb_server "localhost:139" - } - } - if {$cups_remote_smb_port == "" && ! $something_set} { - set cups_remote_smb_port "6632" - } - - frame .cups.serv - label .cups.serv.l -anchor w -text "Local CUPS Server: " - entry .cups.serv.e -width 40 -textvariable cups_local_server - pack .cups.serv.e -side right - pack .cups.serv.l -side left -expand 1 -fill x - - frame .cups.port - label .cups.port.l -anchor w -text "Use Remote CUPS Port:" - entry .cups.port.e -width 40 -textvariable cups_remote_port - pack .cups.port.e -side right - pack .cups.port.l -side left -expand 1 -fill x - - frame .cups.smbs - label .cups.smbs.l -anchor w -text "Local SMB Print Server: " - entry .cups.smbs.e -width 40 -textvariable cups_local_smb_server - pack .cups.smbs.e -side right - pack .cups.smbs.l -side left -expand 1 -fill x - - frame .cups.smbp - label .cups.smbp.l -anchor w -text "Use Remote SMB Print Port:" - entry .cups.smbp.e -width 40 -textvariable cups_remote_smb_port - pack .cups.smbp.e -side right - pack .cups.smbp.l -side left -expand 1 -fill x - - checkbutton .cups.cupsrc -anchor w -variable cups_manage_rcfile -text \ - "Manage 'ServerName' in the remote \$HOME/.cups/client.conf file for me" - - checkbutton .cups.x11vnc -anchor w -variable cups_x11vnc -text \ - "Pass -env FD_CUPS=<Port> to x11vnc command line." - - button .cups.cancel -text "Cancel" -command {destroy .cups; set use_cups 0} - bind .cups <Escape> {destroy .cups; set use_cups 0} - wm protocol .cups WM_DELETE_WINDOW {destroy .cups; set use_cups 0} - button .cups.done -text "Done" -command {destroy .cups; if {$use_cups} {set_ssh}} - - button .cups.guess -text "Help me decide ..." -command {} - .cups.guess configure -state disabled - - pack .cups.done .cups.cancel .cups.guess .cups.x11vnc .cups.cupsrc .cups.smbp .cups.smbs .cups.port .cups.serv -side bottom -fill x - pack .cups.f -side top -fill both -expand 1 - - center_win .cups - focus .cups.serv.e -} - -proc ts_sound_dialog {} { - - global is_windows - global ts_only - - toplev .snd - wm title .snd "Sound Tunnelling" - - scroll_text .snd.f 80 21 - - set msg { - Your remote Desktop will be started in an Enlightenment Sound Daemon - (ESD) environment (esddsp(1), which must be installed on the remote - machine), and a local ESD sound daemon (esd(1)) will be started to - play the sounds for you to hear. - - In the entry box below you can choose the port that the local esd - will use to listen on. The default ESD port is 16001. You will - need to choose different values if you will have more than one esd - running locally. - - The command run (with port replaced by your choice) will be: - - %RCMD - - Note: Unfortunately not all applications work with ESD. - And esd's LD_PRELOAD is broken on 64+32bit Linux (x86_64). - And so this mode is not working well currently... - - For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound -} - - - global sound_daemon_remote_port sound_daemon_local_port sound_daemon_local_cmd - global sound_daemon_local_start sound_daemon_local_kill - - set sound_daemon_local_start 1 - set sound_daemon_local_kill 1 - - if {$sound_daemon_remote_port == ""} { - set sound_daemon_remote_port 16010 - } - if {$sound_daemon_local_port == ""} { - set sound_daemon_local_port 16010 - } - - if {$sound_daemon_local_cmd == ""} { - global is_windows - if {$is_windows} { - set sound_daemon_local_cmd {esound\esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1} - } else { - set sound_daemon_local_cmd {esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1} - } - } - regsub {%PORT} $sound_daemon_local_cmd $sound_daemon_local_port sound_daemon_local_cmd - - regsub {%RCMD} $msg $sound_daemon_local_cmd msg - .snd.f.t insert end $msg - - frame .snd.lport - label .snd.lport.l -anchor w -text "Local Sound Port: " - entry .snd.lport.e -width 45 -textvariable sound_daemon_local_port - pack .snd.lport.e -side right - pack .snd.lport.l -side left -expand 1 -fill x - - button .snd.cancel -text "Cancel" -command {destroy .snd; set use_sound 0} - bind .snd <Escape> {destroy .snd; set use_sound 0} - wm protocol .snd WM_DELETE_WINDOW {destroy .snd; set use_sound 0} - button .snd.done -text "Done" -command {destroy .snd; if {$use_sound} {set_ssh}} - bind .snd.lport.e <Return> {destroy .snd; if {$use_sound} {set_ssh}} - - pack .snd.done .snd.cancel .snd.lport -side bottom -fill x - pack .snd.f -side bottom -fill both -expand 1 - - center_win .snd - focus .snd.lport.e -} - -proc sound_dialog {} { - - global is_windows - global ts_only - if {$ts_only} { - ts_sound_dialog; - return - } - - toplev .snd - wm title .snd "ESD/ARTSD Sound Tunnelling" - - global uname - set h 28 - if [small_height] { - set h 14 - } elseif {$uname == "Darwin"} { - set h 20 - } - scroll_text .snd.f 80 $h - - set msg { - Sound tunnelling to a sound daemon requires SSH be used to set up the - service port redirection. This will be either of the "Use SSH" or - "SSH+SSL" modes. NOTE: For pure SSL tunnelling it currently will not work. - - This method requires working Sound daemon (e.g. ESD or ARTSD) software - setups on BOTH the remote and local sides of the connection. - - Often this means you want to run your ENTIRE remote desktop with ALL - applications instructed to use the sound daemon's network port. E.g. - - esddsp -s localhost:16001 startkde - esddsp -s localhost:16001 gnome-session - - and similarly for artsdsp, etc. You put this in your ~/.xession, - or other startup file. This is non standard. If you do not want to - do this you still can direct *individual* sound applications through - the tunnel, for example "esddsp -s localhost:16001 soundapp", where - "soundapp" is some application that makes noise (say xmms or mpg123). - - Select "Pass -env FD_ESD=<Port> to x11vnc command line." if you are - starting x11vnc as the Remote SSH Command, and x11vnc is running in - -create mode (i.e. FINDCREATEDISPLAY). That way, your X session is - started via "esddsp -s ... <session>" and the ESD variables will be - set correctly for the entire session. (This mode make most sense for - a virtual, e.g. Xvfb or Xdummy session, not one a physical display). - - Also, usually the remote Sound daemon must be killed BEFORE the SSH port - redir is established (because it is listening on the port we want to use - for the SSH redir), and, presumably, restarted when the VNC connection - finished. - - One may also want to start and kill a local sound daemon that will - play the sound received over the network on the local machine. - - You can indicate the remote and local Sound daemon commands below and - how they should be killed and/or restart. Some examples: - - esd -promiscuous -as 5 -port 16001 -tcp -bind 127.0.0.1 - artsd -n -p 7265 -F 10 -S 4096 -n -s 5 -m artsmessage -l 3 -f - - or you can leave some or all blank and kill/start them manually. - - For convenience, a Windows port of ESD is provided in the util/esound - directory, and so this might work for a Local command: - - esound\esd -promiscuous -as 5 -port 16001 -tcp -bind 127.0.0.1 - - NOTE: If you indicate "Remote Sound daemon: Kill at start." below, - then THERE WILL BE TWO SSH'S: THE FIRST ONE TO KILL THE DAEMON. - So you may need to supply TWO SSH PASSWORDS, unless you are using - something like ssh-agent(1), the Putty PW setting, etc. - - You will also need to supply the remote and local sound ports for - the SSH redirs. For esd the default port is 16001, but you can choose - another one if you prefer. - - For "Local Sound Port" you can also supply "host:port" instead of just - a numerical port to specify non-localhost connections, e.g. to another - nearby machine. - - For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-sound -} - .snd.f.t insert end $msg - - global sound_daemon_remote_port sound_daemon_local_port sound_daemon_local_cmd - if {$sound_daemon_remote_port == ""} { - set sound_daemon_remote_port 16001 - } - if {$sound_daemon_local_port == ""} { - set sound_daemon_local_port 16001 - } - - if {$sound_daemon_local_cmd == ""} { - global is_windows - if {$is_windows} { - set sound_daemon_local_cmd {esound\esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1} - } else { - set sound_daemon_local_cmd {esd -promiscuous -as 5 -port %PORT -tcp -bind 127.0.0.1} - } - regsub {%PORT} $sound_daemon_local_cmd $sound_daemon_local_port sound_daemon_local_cmd - } - - - frame .snd.remote - label .snd.remote.l -anchor w -text "Remote Sound daemon cmd: " - entry .snd.remote.e -width 45 -textvariable sound_daemon_remote_cmd - pack .snd.remote.e -side right - pack .snd.remote.l -side left -expand 1 -fill x - - frame .snd.local - label .snd.local.l -anchor w -text "Local Sound daemon cmd: " - entry .snd.local.e -width 45 -textvariable sound_daemon_local_cmd - pack .snd.local.e -side right - pack .snd.local.l -side left -expand 1 -fill x - - frame .snd.rport - label .snd.rport.l -anchor w -text "Remote Sound Port: " - entry .snd.rport.e -width 45 -textvariable sound_daemon_remote_port - pack .snd.rport.e -side right - pack .snd.rport.l -side left -expand 1 -fill x - - frame .snd.lport - label .snd.lport.l -anchor w -text "Local Sound Port: " - entry .snd.lport.e -width 45 -textvariable sound_daemon_local_port - pack .snd.lport.e -side right - pack .snd.lport.l -side left -expand 1 -fill x - - - checkbutton .snd.sdk -anchor w -variable sound_daemon_kill -text \ - "Remote Sound daemon: Kill at start." - - checkbutton .snd.sdr -anchor w -variable sound_daemon_restart -text \ - "Remote Sound daemon: Restart at end." - - checkbutton .snd.sdsl -anchor w -variable sound_daemon_local_start -text \ - "Local Sound daemon: Run at start." - - checkbutton .snd.sdkl -anchor w -variable sound_daemon_local_kill -text \ - "Local Sound daemon: Kill at end." - - checkbutton .snd.x11vnc -anchor w -variable sound_daemon_x11vnc -text \ - "Pass -env FD_ESD=<Port> to x11vnc command line." - - button .snd.guess -text "Help me decide ..." -command {} - .snd.guess configure -state disabled - - global is_win9x - if {$is_win9x} { - .snd.local.e configure -state disabled - .snd.local.l configure -state disabled - .snd.sdsl configure -state disabled - .snd.sdkl configure -state disabled - } - - button .snd.cancel -text "Cancel" -command {destroy .snd; set use_sound 0} - bind .snd <Escape> {destroy .snd; set use_sound 0} - wm protocol .snd WM_DELETE_WINDOW {destroy .snd; set use_sound 0} - button .snd.done -text "Done" -command {destroy .snd; if {$use_sound} {set_ssh}} - - pack .snd.done .snd.cancel .snd.guess .snd.x11vnc .snd.sdkl .snd.sdsl .snd.sdr .snd.sdk .snd.lport .snd.rport \ - .snd.local .snd.remote -side bottom -fill x - pack .snd.f -side bottom -fill both -expand 1 - - center_win .snd - focus .snd.remote.e -} - -# Share ideas. -# -# Unix: -# -# if type smbclient -# first parse smbclient -L localhost -N -# and/or smbclient -L `hostname` -N -# Get Sharenames and Servers and Domain. -# -# loop over servers, doing smbclient -L server -N -# pile this into a huge list, sep by disk and printers. -# -# WinXP: -# -# parse "NET VIEW" output similarly. -# -# Have checkbox for each disk. Set default root to /var/tmp/${USER}-mnts -# Let them change that at once and have it populate. -# -# use //hostname/share /var/tmp/runge-mnts/hostname/share -# -# -# Printers, hmmm. Can't add to remote cups list... I guess have the list -# ready for CUPS dialog to suggest which SMB servers they want to redirect -# to... - -proc get_hostname {} { - global is_windows is_win9x - set str "" - if {$is_windows} { - if {1} { - catch {set str [exec hostname]} - regsub -all {[\r]} $str "" str - } else { - catch {set str [exec net config]} - if [regexp -nocase {Computer name[ \t]+\\\\([^ \t]+)} $str mv str] { - ; - } else { - set str "" - } - } - } else { - catch {set str [exec hostname]} - } - set str [string trim $str] - return $str -} - -proc smb_list_windows {smbhost} { - global smb_local smb_local_hosts smb_this_host - global is_win9x - set dbg 0 - - set domain "" - - if {$is_win9x} { - # exec net view ... doesn't work. - set smb_this_host "unknown" - return - } - - set this_host [get_hostname] - set This_host [string toupper $this_host] - set smb_this_host $This_host - - if {$smbhost == $smb_this_host} { - catch {set out0 [exec net view]} - regsub -all {[\r]} $out0 "" out0 - foreach line [split $out0 "\n"] { - if [regexp -nocase {in workgroup ([^ \t]+)} $line mv wg] { - regsub -all {[.]} $wg "" wg - set domain $wg - } elseif [regexp {^\\\\([^ \t]+)[ \t]*(.*)} $line mv host comment] { - set smb_local($smbhost:server:$host) $comment - } - } - } - - set out1 "" - set h "\\\\$smbhost" - catch {set out1 [exec net view $h]} - regsub -all {[\r]} $out1 "" out1 - - if {$dbg} {puts "SMBHOST: $smbhost"} - - set mode "" - foreach line [split $out1 "\n"] { - if [regexp {^[ \t]*---} $line] { - continue - } - if [regexp -nocase {The command} $line] { - continue - } - if [regexp -nocase {Shared resources} $line] { - continue - } - if [regexp -nocase {^[ \t]*Share[ \t]*name} $line] { - set mode "shares" - continue - } - set line [string trim $line] - if {$line == ""} { - continue - } - if {$mode == "shares"} { - if [regexp {^([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)$} $line mv name type comment] { - if {$dbg} { - puts "SHR: $name" - puts "---: $type" - puts "---: $comment" - } - if [regexp -nocase {^Disk$} $type] { - set smb_local($smbhost:disk:$name) $comment - } elseif [regexp -nocase {^Print} $type] { - set smb_local($smbhost:printer:$name) $comment - } - } - } - } - - set smb_local($smbhost:domain) $domain -} - -proc smb_list_unix {smbhost} { - global smb_local smb_local_hosts smb_this_host - set smbclient [in_path smbclient] - if {[in_path smbclient] == ""} { - return "" - } - set dbg 0 - - set this_host [get_hostname] - set This_host [string toupper $this_host] - set smb_this_host $This_host - - set out1 "" - catch {set out1 [exec smbclient -N -L $smbhost 2>@ stdout]} - - if {$dbg} {puts "SMBHOST: $smbhost"} - if {$smbhost == $this_host || $smbhost == $This_host} { - if {$out1 == ""} { - catch {set out1 [exec smbclient -N -L localhost 2>@ stdout]} - } - } - - set domain "" - set mode "" - foreach line [split $out1 "\n"] { - if [regexp {^[ \t]*---} $line] { - continue - } - if [regexp {Anonymous login} $line] { - continue - } - if {$domain == "" && [regexp {Domain=\[([^\]]+)\]} $line mv domain]} { - if {$dbg} {puts "DOM: $domain"} - continue - } - if [regexp {^[ \t]*Sharename} $line] { - set mode "shares" - continue - } - if [regexp {^[ \t]*Server} $line] { - set mode "server" - continue - } - if [regexp {^[ \t]*Workgroup} $line] { - set mode "workgroup" - continue - } - set line [string trim $line] - if {$mode == "shares"} { - if [regexp {^([^ \t]+)[ \t]+([^ \t]+)[ \t]*(.*)$} $line mv name type comment] { - if {$dbg} { - puts "SHR: $name" - puts "---: $type" - puts "---: $comment" - } - if [regexp -nocase {^Disk$} $type] { - set smb_local($smbhost:disk:$name) $comment - } elseif [regexp -nocase {^Printer$} $type] { - set smb_local($smbhost:printer:$name) $comment - } - } - } elseif {$mode == "server"} { - if [regexp {^([^ \t]+)[ \t]*(.*)$} $line mv host comment] { - if {$dbg} { - puts "SVR: $host" - puts "---: $comment" - } - set smb_local($smbhost:server:$host) $comment - } - } elseif {$mode == "workgroup"} { - if [regexp {^([^ \t]+)[ \t]+(.*)$} $line mv work host] { - if {$dbg} { - puts "WRK: $work" - puts "---: $host" - } - if {$host != ""} { - set smb_local($smbhost:master:$work) $host - } - } - } - } - - set smb_local($smbhost:domain) $domain -} - -proc smb_list {} { - global is_windows smb_local smb_local_hosts - global smb_host_list - - set smb_local(null) "" - - if {! [info exists smb_host_list]} { - set smb_host_list "" - } - if [info exists smb_local] { - unset smb_local - } - if [info exists smb_local_hosts] { - unset smb_local_hosts - } - - set this_host [get_hostname] - set this_host [string toupper $this_host] - if {$is_windows} { - smb_list_windows $this_host - } else { - smb_list_unix $this_host - } - set did($this_host) 1 - set keys [array names smb_local] - foreach item [split $smb_host_list] { - if {$item != ""} { - set item [string toupper $item] - lappend keys "$this_host:server:$item" - } - } - foreach key $keys { - if [regexp "^$this_host:server:(.*)\$" $key mv host] { - if {$host == ""} { - continue - } - set smb_local_hosts($host) 1 - if {! [info exists did($host)]} { - if {$is_windows} { - smb_list_windows $host - } else { - smb_list_unix $host - } - set did($host) 1 - } - } - } -} - -proc smb_check_selected {} { - global smbmount_exists smbmount_sumode - global smb_selected smb_selected_mnt smb_selected_cb smb_selected_en - - set ok 0 - if {$smbmount_exists && $smbmount_sumode != "dontknow"} { - set ok 1 - } - set state disabled - if {$ok} { - set state normal - } - - foreach cb [array names smb_selected_cb] { - catch {$cb configure -state $state} - } - foreach en [array names smb_selected_en] { - catch {$en configure -state $state} - } -} - -proc make_share_widgets {w} { - - set share_label $w.f.hl - catch {$share_label configure -text "Share Name: PROBING ..."} - update - - smb_list - - set saw_f 0 - foreach child [winfo children $w] { - if {$child == "$w.f"} { - set saw_f 1 - continue - } - catch {destroy $child} - } - - set w1 47 - set w2 44 - - if {! $saw_f} { - set wf $w.f - frame $wf - label $wf.hl -width $w1 -text "Share Name:" -anchor w - label $wf.hr -width $w2 -text " Mount Point:" -anchor w - - pack $wf.hl $wf.hr -side left -expand 1 - pack $wf -side top -fill x - - .smbwiz.f.t window create end -window $w - } - - global smb_local smb_local_hosts smb_this_host smb_selected smb_selected_mnt - global smb_selected_host smb_selected_name - global smb_selected_cb smb_selected_en - global smb_host_list - if [info exists smb_selected] {array unset smb_selected } - if [info exists smb_selected_mnt] {array unset smb_selected_mnt} - if [info exists smb_selected_cb] {array unset smb_selected_cb} - if [info exists smb_selected_en] {array unset smb_selected_en} - if [info exists smb_selected_host] {array unset smb_selected_host} - if [info exists smb_selected_name] {array unset smb_selected_name} - - set hosts [list $smb_this_host] - lappend hosts [lsort [array names smb_local_hosts]] - - set smb_host_list "" - set i 0 - - global smb_mount_prefix - set smb_mount_prefix "/var/tmp/%USER-mnts" - - foreach host [lsort [array names smb_local_hosts]] { - - if [info exists did($host)] { - continue - } - set did($host) 1 - - append smb_host_list "$host " - - foreach key [lsort [array names smb_local]] { - if [regexp {^([^:]+):([^:]+):(.*)$} $key mv host2 type name] { - if {$host2 != $host} { - continue - } - if {$type != "disk"} { - continue - } - set wf $w.f$i - frame $wf - checkbutton $wf.c -anchor w -width $w1 -variable smb_selected($i) \ - -text "//$host/$name" -relief ridge - if {! [info exists smb_selected($i)]} { - set smb_selected($i) 0 - } - - entry $wf.e -width $w2 -textvariable smb_selected_mnt($i) - set smb_selected_mnt($i) "$smb_mount_prefix/$host/$name" - - set smb_selected_host($i) $host - set smb_selected_name($i) $name - - set smb_selected_cb($wf.c) $i - set smb_selected_en($wf.e) $i - set comment $smb_local($key) - - bind $wf.c <Enter> "$share_label configure -text {Share Name: $comment}" - bind $wf.c <Leave> "$share_label configure -text {Share Name:}" - - $wf.c configure -state disabled - $wf.e configure -state disabled - - pack $wf.c $wf.e -side left -expand 1 - pack $wf -side top -fill x - incr i - } - } - } - if {$i == 0} { - global is_win9x - $share_label configure -text {Share Name: No SMB Share Hosts were found!} - if {$is_win9x} { - .smbwiz.f.t insert end "\n(this feature does not work on Win9x you have have to enter them manually: //HOST/share /var/tmp/mymnt)\n" - } - } else { - $share_label configure -text "Share Name: Found $i SMB Shares" - } - smb_check_selected -} - -proc smb_help_me_decide {} { - global is_windows - global smb_local smb_local_hosts smb_this_host smb_selected smb_selected_mnt - global smb_selected_host smb_selected_name - global smb_selected_cb smb_selected_en - global smb_host_list - - toplev .smbwiz - set title "SMB Filesystem Tunnelling -- Help Me Decide" - wm title .smbwiz $title - set id " " - - set h 40 - if [small_height] { - set h 30 - } - scroll_text .smbwiz.f 100 $h - - set msg { -For now you will have to verify the following information manually. - -You can do this by either logging into the remote machine to find the info or asking the sysadmin for it. - -} - - if {! $is_windows} { - .smbwiz.f.t configure -font {Helvetica -12 bold} - } - .smbwiz.f.t insert end $msg - - set w .smbwiz.f.t.f1 - frame $w -bd 1 -relief ridge -cursor {top_left_arrow} - - .smbwiz.f.t insert end "\n" - - .smbwiz.f.t insert end "1) Indicate the existence of the 'smbmount' command on the remote system:\n" - .smbwiz.f.t insert end "\n$id" - global smbmount_exists - set smbmount_exists 0 - - checkbutton $w.smbmount_exists -pady 1 -anchor w -variable smbmount_exists \ - -text "Yes, the 'smbmount' command exists on the remote system." \ - -command smb_check_selected - - pack $w.smbmount_exists - .smbwiz.f.t window create end -window $w - - .smbwiz.f.t insert end "\n\n\n" - - set w .smbwiz.f.t.f2 - frame $w -bd 1 -relief ridge -cursor {top_left_arrow} - - .smbwiz.f.t insert end "2) Indicate your authorization to run 'smbmount' on the remote system:\n" - .smbwiz.f.t insert end "\n$id" - global smbmount_sumode - set smbmount_sumode "dontknow" - - radiobutton $w.dk -pady 1 -anchor w -variable smbmount_sumode -value dontknow \ - -text "I do not know if I can mount SMB shares on the remote system via 'smbmount'" \ - -command smb_check_selected - pack $w.dk -side top -fill x - - radiobutton $w.su -pady 1 -anchor w -variable smbmount_sumode -value su \ - -text "I know the Password to run commands as root on the remote system via 'su'" \ - -command smb_check_selected - pack $w.su -side top -fill x - - radiobutton $w.sudo -pady 1 -anchor w -variable smbmount_sumode -value sudo \ - -text "I know the Password to run commands as root on the remote system via 'sudo'" \ - -command smb_check_selected - pack $w.sudo -side top -fill x - - radiobutton $w.ru -pady 1 -anchor w -variable smbmount_sumode -value none \ - -text "I do not need to be root on the remote system to mount SMB shares via 'smbmount'" \ - -command smb_check_selected - pack $w.ru -side top -fill x - - .smbwiz.f.t window create end -window $w - - global smb_wiz_done - set smb_wiz_done 0 - - button .smbwiz.cancel -text "Cancel" -command {set smb_wiz_done 1} - button .smbwiz.done -text "Done" -command {set smb_wiz_done 1} - pack .smbwiz.done -side bottom -fill x - pack .smbwiz.f -side top -fill both -expand 1 - - wm protocol .smbwiz WM_DELETE_WINDOW {set smb_wiz_done 1} - center_win .smbwiz - - wm title .smbwiz "Searching for Local SMB shares..." - update - wm title .smbwiz $title - - global smb_local smb_this_host - .smbwiz.f.t insert end "\n\n\n" - - set w .smbwiz.f.t.f3 - catch {destroy $w} - frame $w -bd 1 -relief ridge -cursor {top_left_arrow} - - .smbwiz.f.t insert end "3) Select SMB shares to mount and their mount point on the remote system:\n" - .smbwiz.f.t insert end "\n${id}" - - make_share_widgets $w - - .smbwiz.f.t insert end "\n(%USER will be expanded to the username on the remote system and %HOME the home directory)\n" - - .smbwiz.f.t insert end "\n\n\n" - - .smbwiz.f.t insert end "You can change the list of Local SMB hosts to probe and the mount point prefix here:\n" - .smbwiz.f.t insert end "\n$id" - set w .smbwiz.f.t.f4 - frame $w -bd 1 -relief ridge -cursor {top_left_arrow} - set wf .smbwiz.f.t.f4.f - frame $wf - label $wf.l -text "SMB Hosts: " -anchor w - entry $wf.e -textvariable smb_host_list -width 60 - button $wf.b -text "Apply" -command {make_share_widgets .smbwiz.f.t.f3} - bind $wf.e <Return> "$wf.b invoke" - pack $wf.l $wf.e $wf.b -side left - pack $wf - pack $w - - .smbwiz.f.t window create end -window $w - - .smbwiz.f.t insert end "\n$id" - - set w .smbwiz.f.t.f5 - frame $w -bd 1 -relief ridge -cursor {top_left_arrow} - set wf .smbwiz.f.t.f5.f - frame $wf - label $wf.l -text "Mount Prefix:" -anchor w - entry $wf.e -textvariable smb_mount_prefix -width 60 - button $wf.b -text "Apply" -command {apply_mount_point_prefix .smbwiz.f.t.f5.f.e} - bind $wf.e <Return> "$wf.b invoke" - pack $wf.l $wf.e $wf.b -side left - pack $wf - pack $w - - .smbwiz.f.t window create end -window $w - - .smbwiz.f.t insert end "\n\n\n" - - .smbwiz.f.t see 1.0 - .smbwiz.f.t configure -state disabled - update - - vwait smb_wiz_done - catch {destroy .smbwiz} - - if {! $smbmount_exists || $smbmount_sumode == "dontknow"} { - tk_messageBox -type ok -parent .oa -icon warning -message "Sorry we couldn't help out!\n'smbmount' info on the remote system is required for SMB mounting" -title "SMB mounting -- aborting" - global use_smbmnt - set use_smbmnt 0 - catch {raise .oa} - return - } - global smb_su_mode - set smb_su_mode $smbmount_sumode - - set max 0 - foreach en [array names smb_selected_en] { - set i $smb_selected_en($en) - set host $smb_selected_host($i) - set name $smb_selected_name($i) - - set len [string length "//$host/$name"] - if {$len > $max} { - set max $len - } - } - - set max [expr $max + 8] - - set strs "" - foreach en [array names smb_selected_en] { - set i $smb_selected_en($en) - if {! $smb_selected($i)} { - continue - } - set host $smb_selected_host($i) - set name $smb_selected_name($i) - set mnt $smb_selected_mnt($i) - - set share "//$host/$name" - set share [format "%-${max}s" $share] - - lappend strs "$share $mnt" - } - set text "" - foreach str [lsort $strs] { - append text "$str\n" - } - - global smb_mount_list - set smb_mount_list $text - - smb_dialog -} - -proc apply_mount_point_prefix {w} { - global smb_selected_host smb_selected_name - global smb_selected_en smb_selected_mnt - - set prefix "" - catch {set prefix [$w get]} - if {$prefix == ""} { - mesg "No mount prefix." - bell - return - } - - foreach en [array names smb_selected_en] { - set i $smb_selected_en($en) - set host $smb_selected_host($i) - set name $smb_selected_name($i) - set smb_selected_mnt($i) "$prefix/$host/$name" - } -} - -proc smb_dialog {} { - toplev .smb - wm title .smb "SMB Filesystem Tunnelling" - global smb_su_mode smb_mount_list - global use_smbmnt - - global help_font - - global uname - set h 33 - if [small_height] { - set h 17 - } elseif {$uname == "Darwin"} { - set h 24 - } - scroll_text .smb.f 80 $h - - set msg { - Windows/Samba Filesystem mounting requires SSH be used to set up the SMB - service port redirection. This will be either of the "Use SSH" or - "SSH+SSL" modes. NOTE: For pure SSL tunnelling it currently will not work. - - This method requires a working Samba software setup on the remote - side of the connection (VNC server) and existing Samba or Windows file - server(s) on the local side (VNC viewer). - - The smbmount(8) program MUST be installed on the remote side. This - evidently limits the mounting to Linux systems. Let us know of similar - utilities on other Unixes. Mounting onto remote Windows machines is - currently not supported (our SSH mode with services setup only works - to Unix). On Debian and Ubuntu the smbmount program is currently in - the package named 'smbfs'. - - Depending on how smbmount is configured you may be able to run it - as a regular user, or it may require running under su(1) or sudo(8) - (root password or user password required, respectively). You select - which one you want via the checkbuttons below. - - In addition to a possible su(1) or sudo(8) password, you may ALSO - need to supply passwords to mount each SMB share. This is an SMB passwd. - If it has no password just hit enter after the "Password:" prompt. - - The passwords are supplied when the 1st SSH connection starts up; - be prepared to respond to them. - - NOTE: USE OF SMB TUNNELLING MODE WILL REQUIRE TWO SSH'S, AND SO YOU - MAY NEED TO SUPPLY TWO LOGIN PASSWORDS UNLESS YOU ARE USING SOMETHING - LIKE ssh-agent(1) or the Putty PW setting. - %WIN - - To indicate the Windows/Samba shares to mount enter them one per line - in one of the forms: - - //machine1/share ~/Desktop/my-mount1 - //machine2/fubar /var/tmp/my-foobar2 192.168.100.53:3456 - 1139 //machine3/baz /var/tmp/baz [...] - - The first part is the standard SMB host and share name //hostname/dir - (note this share is on the local viewer-side not on the remote end). - A leading '#' will cause the entire line to be skipped. - - The second part, e.g. /var/tmp/my-foobar2, is the directory to mount - the share on the remote (VNC Server) side. You must be able to - write to this directory. It will be created if it does not exist. - A leading character ~ will be expanded to $HOME. So will the string - %HOME. The string %USER will get expanded to the remote username. - - An optional part like 192.168.100.53:3456 is used to specify the real - hostname or IP address, and possible non-standard port, on the local - side if for some reason the //hostname is not sufficient. - - An optional leading numerical value, 1139 in the above example, indicates - which port to use on the Remote side to SSH redirect to the local side. - Otherwise a random one is tried (a unique one is needed for each SMB - server:port combination). A fixed one is preferred: choose a free - remote port. - - The standard SMB service ports (local side) are 445 and 139. 139 is - used by this application. - - Sometimes "localhost" will not work on Windows machines for a share - hostname, and you will have to specify a different network interface - (e.g. the machine's IP address). If you use the literal string "IP" - it will be attempted to replace it with the numerical IP address, e.g.: - - //machine1/share ~/Desktop/my-mount1 IP - - VERY IMPORTANT: Before terminating the VNC Connection, make sure no - applications are using any of the SMB shares (or shells are cd-ed - into the share). This way the shares will be automatically unmounted. - Otherwise you will need to log in again, stop processes from using - the share, become root and umount the shares manually ("smbumount - /path/to/share", etc.) - - For more info see: http://www.karlrunge.com/x11vnc/faq.html#faq-smb-shares -} - - set msg2 { - To speed up moving to the next step, iconify the first SSH console - when you are done entering passwords, etc. and then click on the - main panel 'VNC Host:Display' label. -} - - global is_windows - if {! $is_windows} { - regsub { *%WIN} $msg "" msg - } else { - set msg2 [string trim $msg2] - regsub { *%WIN} $msg " $msg2" msg - } - .smb.f.t insert end $msg - - frame .smb.r - label .smb.r.l -text "smbmount(8) auth mode:" -relief ridge - radiobutton .smb.r.none -text "None" -variable smb_su_mode -value "none" - radiobutton .smb.r.su -text "su(1)" -variable smb_su_mode -value "su" - radiobutton .smb.r.sudo -text "sudo(8)" -variable smb_su_mode -value "sudo" - - pack .smb.r.l .smb.r.none .smb.r.sudo .smb.r.su -side left -fill x - - label .smb.info -text "Supply the mounts (one per line) below:" -anchor w -relief ridge - - eval text .smb.mnts -width 80 -height 5 $help_font - .smb.mnts insert end $smb_mount_list - - button .smb.guess -text "Help me decide ..." -command {destroy .smb; smb_help_me_decide} - - button .smb.cancel -text "Cancel" -command {set use_smbmnt 0; destroy .smb} - bind .smb <Escape> {set use_smbmnt 0; destroy .smb} - wm protocol .smb WM_DELETE_WINDOW {set use_smbmnt 0; destroy .smb} - button .smb.done -text "Done" -command {if {$use_smbmnt} {set_ssh; set smb_mount_list [.smb.mnts get 1.0 end]}; destroy .smb} - - pack .smb.done .smb.cancel .smb.guess .smb.mnts .smb.info .smb.r -side bottom -fill x - pack .smb.f -side top -fill both -expand 1 - - center_win .smb -} - -proc help_advanced_opts {} { - toplev .ah - - scroll_text_dismiss .ah.f - - center_win .ah - - wm title .ah "Advanced Options Help" - - set msg { - These Advanced Options that may require extra software installed on - the VNC server-side (the remote server machine) and/or on the VNC - client-side (where this gui is running). - - The Service redirection options, CUPS, ESD/ARTSD, and SMB will - require that you use SSH for tunneling so that they can use the -R - port redirection will be enabled for each service. I.e. "Use SSH" - or "SSH + SSL" mode. - - These options may also require additional configuration to get them - to work properly. Please submit bug reports if it appears it should - be working for your setup but is not. - - Brief (and some not so brief) descriptions: - - CUPS Print tunnelling: - - Redirect localhost:6631 (say) on the VNC server to your local - CUPS server. SSH mode is required. - - ESD/ARTSD Audio tunnelling: - - Redirect localhost:16001 (say) on the VNC server to your local - ESD, etc. sound server. SSH mode is required. - - SMB mount tunnelling: - - Redirect localhost:1139 (say) on the VNC server and through that - mount SMB file shares from your local server. The remote machine - must be Linux with smbmount installed. SSH mode is required. - - Additional Port Redirs (via SSH): - - Specify additional -L port:host:port and -R port:host:port - cmdline options for SSH to enable additional services. - SSH mode is required. - - Automatically Find X Login/Greeter: - - This mode is similar to "Automatically Find X Session" except - that it will attach to a X Login/Greeter screen that no one - has logged into yet. It requires root privileges via sudo(1) - on the remote machine. SSH mode is required. - - As with "Automatically Find X Session" it works only with SSH - mode and requires x11vnc be installed on the remote computer. - - It simply sets the Remote SSH Command to: - - PORT= sudo x11vnc -find -localhost -env FD_XDM=1 - - An initial ssh running 'sudo id' is performed to try to - 'prime' sudo so the 2nd one that runs x11vnc does not need - a password. This may not always succeed... please mail us - the details if it doesn't. - - See the 'X Login' description in 'Terminal Services' Mode - Help for more info. - - Private SSH KnownHosts file: - - On Unix in SSH mode, let the user specify a non-default - ssh known_hosts file to be used only by the current profile. - This is the UserKnownHostsFile ssh option and is described in the - ssh_config(1) man page. This is useful to avoid proxy 'localhost' - SSH key collisions. - - Normally one should simply let ssh use its default file - ~/.ssh/known_hosts for tracking SSH keys. The only problem that - happens is when multiple SSVNC connections use localhost tunnel - port redirections. These make ssh connect to 'localhost' on some - port (where the proxy is listening.) Then the different keys - from the multiple ssh servers collide when ssh saves them under - 'localhost' in ~/.ssh/known_hosts. - - So if you are using a proxy with SSVNC or doing a "double SSH - gateway" your ssh will connect to a proxy port on localhost, and you - should set a private KnownHosts file for that connection profile. - This is secure and avoids man-in-the-middle attack (as long as - you actually verify the initial save of the SSH key!) - - The default file location will be: - - ~/.vnc/ssh_known_hosts/profile-name.known - - but you can choose any place you like. It must of course be - unique and not shared with another ssh connection otherwise they - both may complain about the key for 'localhost' changing, etc. - - SSH Local Port Protections: - - An LD_PRELOAD hack to limit the number of SSH port redirections - to 1 and within the first 35 seconds. So there is a smaller - window when the user can try to use your tunnel compared to - the duration of your session. SSH mode is required. - - STUNNEL Local Port Protections: - - Try to prevent Untrusted Local Users (see the main Help panel) - from using your STUNNEL tunnel to connect to the remote VNC - Server. - - Change VNC Viewer: - - Specify a non-bundled VNC Viewer (e.g. UltraVNC or RealVNC) - to run instead of the bundled TightVNC Viewer. - - Port Knocking: - - For "closed port" services, first "knock" on the firewall ports - in a certain way to open the door for SSH or SSL. The port - can also be closed when the encrypted VNC connection finishes. - - UltraVNC DSM Encryption Plugin: - - On Unix only, by using the supplied tool, ultravnc_dsm_helper, - encrypted connections to UltraVNC servers using their plugins - is enabled. Support for secret key encryption to Non-UltraVNC - DSM servers is also supported, e.g. x11vnc -enc blowfish:my.key - - Do not Probe for VeNCrypt: - - Disable VeNCrypt auto-detection probe when not needed. - - By default in SSL mode an initial probe for the use of the - VeNCrypt or ANONTLS protocol is performed. This is done - during the initial fetch-cert action. Once auto-detected in - the initial probe, the real connection to the VNC Server will - use this information to switch to SSL/TLS at the right point in - the VeNCrypt/ANONTLS handshake. - - In "Verify All Certs" mode initial the fetch-cert action is - required so the automatic probing for VeNCrypt is always done. - The fetch-cert is not needed if you specified a ServerCert or if - you disabled "Verify All Certs". But by default the fetch-cert - is done anyway to try to auto-detect VeNCrypt/ANONTLS. - - Set 'Do not Probe for VeNCrypt' to skip this unneeded fetch-cert - action (and hence speed up connecting.) Use this if you - know the VNC Server uses normal SSL and not VeNCrypt/ANONTLS. - - See also the next option, 'Server uses VeNCrypt SSL encryption' - to if you know it uses VeNCrypt/ANONTLS (the probing will also - be skipped if that option is set.) - - Server uses VeNCrypt SSL encryption: - - Indicate that the VNC server uses the VeNCrypt extension to VNC; - it switches to an SSL/TLS tunnel at a certain point in the - VNC Handshake. This is in constrast to the default ssvnc/x11vnc - SSL tunnel behavior where the *entire* VNC traffic goes through - SSL (i.e. it is vncs:// in the way https:// uses SSL) - - Enable this option if you know the server supports VeNCrypt. - Also use this option for the older ANONTLS extension (vino). - Doing so will give the quickest and most reliable connection - to VeNCrypt/ANONTLS servers. If set, any probing to try to - auto-detect VeNCrypt/ANONTLS will be skipped. - - Some VNC servers supporting VeNCrypt: VeNCrypt, QEMU, ggi, - virt-manager, and Xen. Vino supports ANONTLS. - - The SSVNC VeNCrypt/ANONTLS support even works with 3rd party - VNC Viewers you specify via 'Change VNC Viewer' (e.g. RealVNC, - TightVNC, UltraVNC etc.) that do not directly support it. - - Note: many VeNCrypt servers only support Anonymous Diffie Hellman - TLS which has NO built in authentication and you will also need - to set the option described in the next section. - - If you are using VeNCrypt or ANONTLS for REVERSE connections - (Listen) then you *MUST* set this 'Server uses VeNCrypt SSL - encryption' option. Note also that REVERSE connections using - VeNCrypt/ANONTLS currently do not work on Windows. - - Also, if you are using the "Use SSH+SSL" double tunnel to a - VeNCrypt/ANONTLS server, you MUST set 'Server uses VeNCrypt - SSL encryption' because "Verify All Certs" is disabled in - SSH+SSL mode. - - Server uses Anonymous Diffie-Hellman - - Anonymous Diffie-Hellman can be used for SSL/TLS connections but - there are no Certificates for authentication. Therefore only - passive eavesdropping attacks are prevented, not Man-In-The-Middle - attacks. Not recommended; try to use verified X509 certs instead. - - Enable this option if you know the server only supports Anon DH. - When you do so, remember that ALL Certificate checking will be - skipped (even if you have 'Verify All Certs' selected or set - a ServerCert.) - - SSVNC may be able to autodetect Anon DH even if you haven't - selected 'Server uses Anonymous Diffie-Hellman'. Once detected, it - will prompt you whether it should continue. Set the 'Server uses - Anonymous Diffie-Hellman' option to avoid trying autodetection - (i.e. forcing the issue.) - - Note that most Anonymous Diffie-Hellman VNC Servers do so - via the VeNCrypt or ANONTLS VNC extensions (see the previous - section.) For these servers if you select 'Server uses Anonymous - Diffie-Hellman' you *MUST* ALSO select 'Server uses VeNCrypt SSL - encryption', otherwise SSVNC may have no chance to auto-detect - the VeNCrypt/ANONTLS protocol. - - Also note, if you are using the "Use SSH+SSL" double tunnel to - a VeNCrypt/ANONTLS server using Anon DH you MUST set 'Server - uses Anonymous Diffie-Hellman' because "Verify All Certs" - is disabled in SSH+SSL mode. - - Include: - - Default settings and Include Templates: - - Before explaining how Include works, first note that if you - do not prefer some of SSVNC's default settings you can start - up SSVNC and then change the settings for the options that you - want to have a different default value. Then type "defaults" - in VNC Host:Display entry box and press "Save" to save them in - the "defaults.vnc" profile. After this, SSVNC will initialize - all of the default values and then apply your override values - in "defaults". - - For example, suppose you always want to use a different, 3rd - party VNC Viewer. Set Options -> Advanced -> Change VNC Viewer - to what you want, and then save it as the "defaults" profile. - Now that default setting will apply to all profiles, and SSVNC - in its startup state. - - To edit the defaults Load it, make changes, and then Save it. - Delete the "defaults" profile to go back to no modifications. - Note that defaults created and saved while defaults.vnc existed - will NOT be automatically adjusted. - - Include Templates: - - Now suppose you have a certain class of settings that you do - not want to always be applied, but you want them to apply to a - group of profiles. - - For example, suppose you have some settings for very low - bandwidth connections (e.g. low color modes and/or aggressive - compression and quality settings.) Set these values in SSVNC - and then in the VNC Host:Display entry box type in, say, - "slowlink" and then press Save. This will save those settings - in the template profile named "slowlink.vnc". - - Now to create a real profile that uses this template type the - host:disp in "VNC Host:Display" and in Options -> Advanced - -> Includes type in "slowlink". Then press Save to save the - host profile. Then re-Load it. The "slowlink" settings will - be applied after the defaults. Make any other changes to the - setting for this profile and Save it again. Next time you load - it in, the Include template settings will override the defaults - and then the profile itself is read in. - - You may supply a comma or space separated list of templates - to include. They are applied in the order listed. They can be - full path names or basenames relative to the profiles directory. - You do not need to supply the .vnc suffix. The non-default - settings in them will be applied first, and then any values in - the loaded Profile will override them. - - Sleep: - - Enter a number to indicate how many extra seconds to sleep - while waiting for the VNC viewer to start up. On Windows this - can give extra time to enter the Putty/Plink password, etc. - - Putty Args: - - Windows only, supply a string to be added to all plink.exe - and putty.exe commands. Example: -i C:\mykey.ppk - - Launch Putty Pagent: - - Windows only, launch the Putty key agent tool (pageant) to hold - your SSH private keys for automatic logging in by putty/plink. - - Launch Putty Key-Gen: - - Windows only, launch the Putty key generation tool (puttygen) - to create new SSH private keys. - - Unix ssvncviewer: - - Display a popup menu with options that apply to the special - Unix SSVNC VNC Viewer (perhaps called 'ssvncviewer') provided by - this SSVNC package. This only applies to Unix or Mac OS X. - - Use ssh-agent: - - On Unix only: restart the GUI in the presence of ssh-agent(1) - (e.g. in case you forgot to start your agent before starting - this GUI). An xterm will be used to enter passphrases, etc. - This can avoid repeatedly entering passphrases for the SSH logins - (note this requires setting up and distributing SSH keys). - - - About the CheckButtons: - - Ahem, Well...., yes quite a klunky UI: you have to toggle the - CheckButton to pull up the Dialog box a 2nd, etc. time... don't - worry your settings will still be there! -} - - .ah.f.t insert end $msg - jiggle_text .ah.f.t -} - -proc help_ssvncviewer_opts {} { - toplev .av - - scroll_text_dismiss .av.f - - center_win .av - - wm title .av "Unix SSVNC viewer Options Help" - - set msg { - These Unix SSVNC VNC Viewer Options apply only on Unix or Mac OS X - when using the viewer (ssvncviewer) supplied by this SSVNC package. - - Brief descriptions: - - Multiple LISTEN Connections: - - Allow multiple VNC servers to reverse connect at the same time - and so display each of their desktops on your screen at the - same time. - - Listen Once: - - Try to have the VNC Viewer exit after the first listening - connection. (It may not always be detected; use Ctrl-C to exit) - - Listen Accept Popup Dialog: - - In -listen (reverse connection listening) mode when a reverse - VNC connection comes in show a popup asking whether to Accept - or Reject the connection. (-acceptpopup vncviewer option.) - - Accept Popup UltraVNC Single Click: - - As in 'Listen Accept Popup Dialog', except assume the remote - VNC server is UltraVNC Single Click and force the execution of - the protocol to retrieve the extra remote-side info (Windows - User, ComputerName, etc) which is then also displayed in the - Popup window. (-acceptpopupsc vncviewer option.) - - Use X11 Cursor: - - When drawing the mouse cursor shape locally, use an X11 cursor - instead of drawing it directly into the framebuffer. This - can sometimes give better response, and avoid problems under - 'Scaling'. - - Disable Bell: - - Disable beeps coming from remote side. - - Use Raw Local: - - Use the VNC Raw encoding for 'localhost' connections (instead - of assuming there is a local tunnel, SSL or SSH, going to the - remote machine. - - Avoid Using Terminal: - - By default the Unix ssvncviewer will prompt for usernames, - passwords, etc. in the terminal it is running inside of. - Set this option to use windows for messages and prompting as - much as possible. Messages will also go to the terminal, but - all prompts will be done via popup window. - - Note that stunnel(1) may prompt for a passphrase to unlock a - private SSL key. This is fairly rare because it is usually - for Client-side SSL authentication. stunnel will prompt from - the terminal; there seems to be no way around this. - - Also, note that ssh(1) may prompt for an ssh key passphrase - or Unix password. This can be avoided in a number of ways, - the simplest one is to use ssh-agent(1) and ssh-add(1). - However ssh(1) may also prompt you to accept a new public key - for a host or warn you if the key has changed, etc. - - Use Popup Fix: - - Enable a fix that warps the popup (F8) to the mouse pointer. - - Use XGrabServer (for fullscreen): - - On Unix only, use the XGrabServer workaround for older window - managers. Sometimes also needed on recent (2008) GNOME. This - workaround can make going into/out-of Fullscreen work better. - - Cursor Alphablending: - - Use the x11vnc alpha hack for translucent cursors (requires Unix, - 32bpp and same endianness) - - TurboVNC: - - If available on your platform, use a ssvncviewer compiled with - TurboVNC support. This is based on the VirtualGL project: - http://www.sourceforge.net/projects/virtualgl You will need - to install the VirtualGL's TurboJPEG library too. - - Currently (May/2009) only Linux.i686, Linux.x86_64, and - Darwin.i386 have vncviewer.turbovnc binaries shipped in the - ssvnc bundles. See the build instructions for how you might - compile your own. - - Disable Pipelined Updates: - - Disable the TurboVNC-like pipelined updates mode. Pipelined - updates is the default even when not TurboVNC enabled. They - ask for the next screen update before the current one has - finished downloading, and so this might reduce the slowdown - due to high latency or low bandwidth by 2X or so. Disable - them if they cause problems with the remote VNC Server or - use too much bandwidth. - - Send CLIPBOARD not PRIMARY: - - When sending locally selected text to the VNC server side, - send the CLIPBOARD selection instead of the PRIMARY selection. - - Send Selection Every time: - - Send selected text to the VNC server side every time the mouse - focus enters the main VNC Viewer window instead only when it - appears to have changed since the last send. - - Scaling: - - Use viewer-side (i.e. local) scaling of the VNC screen. Supply - a fraction, e.g. 0.75 or 3/4, or a WxH geometry, e.g. 1280x1024, - or the string 'fit' to fill the current screen. Use 'auto' - to scale the desktop to match the viewer window size. - - If you observe mouse trail painting errors try using X11 Cursor. - - Note that since the local scaling is done in software it can - be slow. Since ZRLE is better than Tight in this regard, when - scaling is detected, the encoding will be switched to ZRLE. - Use the Popup to go back to Tight if you want to, or set the - env. var. SSVNC_PRESERVE_ENCODING=1 to disable the switch. - - For additional speedups under local scaling: try having a solid - desktop background on the remote side (either manually or using - 'x11vnc -solid ...'); and also consider using client side caching - 'x11vnc -ncache 10 ...' if the remote server is x11vnc. - - Escape Keys: - - Enable 'Escape Keys', a set of modifier keys that, if all are - pressed down, enable local Hot Key actions. Set to 'default' - to use the default (Alt_L,Super_L on unix, Control_L,Meta_L - on macosx) or set to a list of modifier keys. - - Y Crop: - - This is for x11vnc's -ncache client side caching scheme with our - Unix TightVNC viewer. Sets the Y value to "crop" the viewer - size at (below the cut is the pixel cache region you do not - want to see). If the screen is tall (H > 2*W) ycropping will - be autodetected, or you can set to -1 to force autodection. - Otherwise, set it to the desired Y value. You can also set - the scrollbar width (very thin by default) by appending ",sb=N" - (or use ",sb=N" by itself to just set the scrollbar width). - - ScrollBar Width: - - This is for x11vnc's -ncache client side caching scheme with our - Unix TightVNC viewer. For Y-Crop mode, set the size of the - scrollbars (often one want it to be very narrow, e.g. 2 pixels - to be less distracting. - - RFB Version: - - Set the numerical version of RFB (VNC) protocol to pretend to - be, 3.x. Usually only needed with UltraVNC servers. - - Encodings: - - List encodings in preferred order, for example - 'copyrect zrle tight' The list of encodings is: - copyrect tight zrle zywrle hextile zlib corre rre raw - - Extra Options: - - String of extra Unix ssvncviewer command line options. I.e. for - ones like -16bpp that cannot be set inside this SSVNC GUI. For a - list click Help then 'SSVNC vncviewer -help Output'. - - - These are environment variables one may set to affect the options - of the SSVNC vncviewer and also the ss_vncviewer wrapper script - (and hence may apply to 3rd party vncviewers too) - - VNCVIEWER_ALPHABLEND (-alpha, see Cursor Alphablending above) - VNCVIEWER_POPUP_FIX (-popupfix, warp popup to mouse location) - VNCVIEWER_GRAB_SERVER (-graball, see Use XGrabServer above) - VNCVIEWER_YCROP (-ycrop, see Y Crop above) - VNCVIEWER_SBWIDTH (-sbwidth, see ScrollBar Width above) - VNCVIEWER_RFBVERSION (-rfbversion, e.g. 3.6) - VNCVIEWER_ENCODINGS (-encodings, e.g. "copyrect zrle hextile") - VNCVIEWER_NOBELL (-nobell) - VNCVIEWER_X11CURSOR (-x11cursor, see Use X11 Cursor above) - VNCVIEWER_RAWLOCAL (-rawlocal, see Use Raw Local above) - VNCVIEWER_NOTTY (-notty, see Avoid Using Terminal above) - VNCVIEWER_ESCAPE (-escape, see Escape Keys above) - VNCVIEWER_ULTRADSM (-ultradsm) - VNCVIEWER_PIPELINE_UPDATES (-pipeline, see above) - VNCVIEWER_SEND_CLIPBOARD (-sendclipboard) - VNCVIEWER_SEND_ALWAYS (-sendalways) - VNCVIEWER_RECV_TEXT (-recvtext clipboard/primary/both) - VNCVIEWER_NO_CUTBUFFER (do not send CUTBUFFER0 as fallback) - VNCVIEWER_NO_PIPELINE_UPDATES (-nopipeline) - VNCVIEWER_ALWAYS_RECENTER (set to avoid(?) recentering on resize) - VNCVIEWER_IS_REALVNC4 (indicate vncviewer is realvnc4 flavor.) - VNCVIEWER_NO_IPV4 (-noipv4) - VNCVIEWER_NO_IPV6 (-noipv6) - VNCVIEWER_FORCE_UP (force raise on fullscreen graball) - VNCVIEWER_PASSWORD (danger: set vnc passwd via env. var.) - VNCVIEWER_MIN_TITLE (minimum window title (appshare)) - - VNCVIEWERCMD (unix viewer command, default vncviewer) - VNCVIEWERCMD_OVERRIDE (force override of VNCVIEWERCMD) - VNCVIEWERCMD_EXTRA_OPTS (extra options to pass to VNCVIEWERCMD) - VNCVIEWER_LISTEN_LOCALHOST (force ssvncviewer to -listen on localhost) - VNCVIEWER_NO_SEC_TYPE_TIGHT(force ssvncviewer to skip rfbSecTypeTight) - HEXTILE_YCROP_TOO (testing: nosync_ycrop for hextile updates.) - - SS_DEBUG (very verbose debug printout by script.) - SS_VNCVIEWER_LISTEN_PORT (force listen port.) - SS_VNCVIEWER_NO_F (no -f for SSH.) - SS_VNCVIEWER_NO_T (no -t for SSH.) - SS_VNCVIEWER_USE_C (force -C compression for SSH.) - SS_VNCVIEWER_SSH_CMD (override SSH command to run.) - SS_VNCVIEWER_NO_MAXCONN (no maxconn for stunnel (obsolete)) - SS_VNCVIEWER_RM (file containing vnc passwd to remove.) - SS_VNCVIEWER_SSH_ONLY (run the SSH command, then exit.) - - SSVNC_MULTIPLE_LISTEN (-multilisten, see Multiple LISTEN above) - SSVNC_ACCEPT_POPUP (-acceptpopup, see Accept Popup Dialog) - SSVNC_ACCEPT_POPUP_SC (-acceptpopupsc, see Accept Popup Dialog) - SSVNC_TURBOVNC (see TurboVNC above) - SSVNC_UNIXPW (-unixpw) - SSVNC_UNIXPW_NOESC (do not send escape in -unixpw mode) - SSVNC_SCALE (-scale, see Scaling above) - SSVNC_NOSOLID (do not do solid region speedup in - scaling mode.) - SSVNC_PRESERVE_ENCODING (do not switch to ZRLE when scaling) - SSVNC_FINISH_SLEEP (on unix/macosx sleep this many seconds - before exiting the terminal, default 5) - - Misc (special usage or debugging or ss_vncviewer settings): - - SSVNC_MESG_DELAY (sleep this many millisec between messages) - SSVNC_NO_ENC_WARN (do not print out a NO ENCRYPTION warning) - SSVNC_EXTRA_SLEEP (same as Sleep: window) - SSVNC_NO_ULTRA_DSM (disable ultravnc dsm encryption) - SSVNC_ULTRA_DSM (the ultravnc_dsm_helper command) - SSVNC_ULTRA_FTP_JAR (file location of ultraftp.jar jar file) - SSVNC_KNOWN_HOSTS_FILE (file for per-connection ssh known hosts) - SSVNC_SCALE_STATS (print scaling stats) - SSVNC_NOSOLID (disable solid special case while scaling) - SSVNC_DEBUG_RELEASE (debug printout for keyboard modifiers.) - SSVNC_DEBUG_ESCAPE_KEYS (debug printout for escape keys) - SSVNC_NO_MAYBE_SYNC (skip XSync() calls in certain painting) - SSVNC_MAX_LISTEN (number of time to listen for reverse conn.) - SSVNC_LISTEN_ONCE (listen for reverse conn. only once) - STUNNEL_LISTEN (stunnel interface for reverse conn. - SSVNC_NO_MESSAGE_POPUP (do not place info messages in popup.) - SSVNC_SET_SECURITY_TYPE (force VeNCrypt security type) - SSVNC_PREDIGESTED_HANDSHAKE (string used for VeNCrypt, etc. connect) - SSVNC_SKIP_RFB_PROTOCOL_VERSION (force viewer to be RFB 3.8) - SSVNC_DEBUG_SEC_TYPES (debug security types for VeNCrypt) - SSVNC_DEBUG_MSLOGON (extra printout for ultravnc mslogon proto) - SSVNC_DEBUG_RECTS (printout debug for RFB rectangles.) - SSVNC_DEBUG_CHAT (printout debug info for chat mode.) - SSVNC_DELAY_SYNC (faster local drawing delaying XSync) - SSVNC_DEBUG_SELECTION (printout debug for selection/clipboard) - SSVNC_REPEATER (URL-ish sslrepeater:// thing for UltraVNC) - SSVNC_VENCRYPT_DEBUG (debug printout for VeNCrypt mode.) - SSVNC_VENCRYPT_USERPASS (force VeNCrypt user:pass) - SSVNC_STUNNEL_DEBUG (increase stunnel debugging printout) - SSVNC_STUNNEL_VERIFY3 (increase stunnel verify from 2 to 3) - SSVNC_LIM_ACCEPT_PRELOAD (preload library to limit accept(2)) - SSVNC_SOCKS5 (socks5 for x11vnc PORT= mode, default) - SSVNC_SOCKS4 (socks4 for x11vnc PORT= mode) - SSVNC_NO_IPV6_PROXY (do not setup a ipv6:// proxy) - SSVNC_NO_IPV6_PROXY_DIRECT (do not setup a ipv6:// proxy unencrypted) - SSVNC_PORT_IPV6 (x11vnc PORT= mode is to ipv6-only) - SSVNC_IPV6 (0 to disable ss_vncviewer ipv6 check) - SSVNC_FETCH_TIMEOUT (ss_vncviewer cert fetch timeout) - SSVNC_USE_S_CLIENT (force cert fetch to be 'openssl s_client') - SSVNC_SHOWCERT_EXIT_0 (force showcert to exit with success) - SSVNC_SSH_LOCALHOST_AUTH (force SSH localhost auth check.) - SSVNC_TEST_SEC_TYPE (force PPROXY VeNCrypt type; testing) - SSVNC_TEST_SEC_SUBTYPE (force PPROXY VeNCrypt subtype; testing) - SSVNC_EXIT_DEBUG (testing: prompt to exit at end.) - SSVNC_UP_DEBUG (gui user/passwd debug mode.) - SSVNC_UP_FILE (gui user/passwd file.) - - STUNNEL_EXTRA_OPTS (extra options for stunnel.) - - X11VNC_APPSHARE_DEBUG (for debugging -appshare mode.) - NO_X11VNC_APPSHARE (shift down for escape keys.) - DEBUG_HandleFileXfer (ultravnc filexfer) - DEBUG_RFB_SMSG (RFB server message debug.) -} - - .av.f.t insert end $msg - button .av.htext -text "SSVNC vncviewer -help Output" -command show_viewer_help - pack .av.htext -side bottom -fill x - jiggle_text .av.f.t -} - -proc show_viewer_help {} { - toplev .vhlp - - set h 35 - if [small_height] { - set h 30 - } - scroll_text_dismiss .vhlp.f 83 $h - - center_win .vhlp - wm resizable .vhlp 1 0 - - wm title .vhlp "SSVNC vncviewer -help Output" - - set msg "-- No Help Output --" - catch {set msg [exec ss_vncviewer -viewerhelp 2>/dev/null]} - - .vhlp.f.t insert end $msg - jiggle_text .vhlp.f.t -} - -proc set_viewer_path {} { - global change_vncviewer_path - unix_dialog_resize .chviewer - set change_vncviewer_path [tk_getOpenFile -parent .chviewer] - catch {raise .chviewer} - update -} - -proc change_vncviewer_dialog {} { - global change_vncviewer change_vncviewer_path vncviewer_realvnc4 - global ts_only - - toplev .chviewer - wm title .chviewer "Change VNC Viewer" - - global help_font - if {$ts_only} { - eval text .chviewer.t -width 90 -height 16 $help_font - } else { - eval text .chviewer.t -width 90 -height 27 $help_font - } - apply_bg .chviewer.t - - set msg { - To use your own VNC Viewer (i.e. one installed by you, not included in this - package), e.g. UltraVNC or RealVNC, type in the program name, or browse for - the full path to it. You can put command line arguments after the program. - - Note that due to incompatibilities with respect to command line options - there may be issues, especially if many command line options are supplied. - You can specify your own command line options below if you like (and try to - avoid setting any others in this GUI under "Options"). - - If the path to the program name has spaces it in, surround it with double quotes: - - "C:\Program Files\My Vnc Viewer\VNCVIEWER.EXE" - - Make sure the very first character is a quote. You should quote the command - even if it is only the command line arguments that need extra protection: - - "wine" -- "/home/fred/Program Flies/UltraVNC-1.0.2.exe" /64colors - - Since the command line options differ between them greatly, if you know it - is of the RealVNC 4.x flavor, indicate on the check box. Otherwise we guess. - - To have SSVNC act as a general STUNNEL redirector (no VNC) set the viewer to be - "xmessage OK" or "xmessage <port>" or "sleep n" or "sleep n <port>" (or "NOTEPAD" - on Windows). The default listen port is 5930. The destination is set in "VNC - Host:Display" (for a remote port less than 200 use the negative of the port value). -} - - if {$ts_only} { - regsub {Note that due(.|\n)*If the} $msg "If the" msg - regsub {To have SSVNC act(.|\n)*} $msg "" msg - } - .chviewer.t insert end $msg - - frame .chviewer.path - label .chviewer.path.l -text "VNC Viewer:" - entry .chviewer.path.e -width 40 -textvariable change_vncviewer_path - button .chviewer.path.b -text "Browse..." -command set_viewer_path - checkbutton .chviewer.path.r -anchor w -variable vncviewer_realvnc4 -text \ - "RealVNC 4.x" - - pack .chviewer.path.l -side left - pack .chviewer.path.e -side left -expand 1 -fill x - pack .chviewer.path.b -side left - pack .chviewer.path.r -side left - - button .chviewer.cancel -text "Cancel" -command {destroy .chviewer; set change_vncviewer 0} - bind .chviewer <Escape> {destroy .chviewer; set change_vncviewer 0} - wm protocol .chviewer WM_DELETE_WINDOW {destroy .chviewer; set change_vncviewer 0} - button .chviewer.done -text "Done" -command {destroy .chviewer; catch {raise .oa}} - bind .chviewer.path.e <Return> {destroy .chviewer; catch {raise .oa}} - - pack .chviewer.t .chviewer.path .chviewer.cancel .chviewer.done -side top -fill x - - center_win .chviewer - wm resizable .chviewer 1 0 - - focus .chviewer.path.e -} - -proc port_redir_dialog {} { - global additional_port_redirs additional_port_redirs_list - - toplev .redirs - wm title .redirs "Additional Port Redirections (via SSH)" - - global help_font uname - set h 35 - if [small_height] { - set h 27 - } - eval text .redirs.t -width 80 -height $h $help_font - apply_bg .redirs.t - - set msg { - Specify any additional SSH port redirections you desire for the - connection. Put as many as you want separated by spaces. These only - apply to SSH and SSH+SSL connections, they do not apply to Pure SSL - connections. - - -L port1:host:port2 will listen on port1 on the local machine (where - you are sitting) and redirect them to port2 on - "host". "host" is relative to the remote side - (VNC Server). Use "localhost" for the remote - machine itself. - - -R port1:host:port2 will listen on port1 on the remote machine - (where the VNC server is running) and redirect - them to port2 on "host". "host" is relative - to the local side (where you are sitting). - Use "localhost" for this machine. - - Perhaps you want a redir to a web server inside an intranet: - - -L 8001:web-int:80 - - Or to redir a remote port to your local SSH daemon: - - -R 5022:localhost:22 - - etc. There are many interesting possibilities. - - Sometimes, especially for Windows Shares, you cannot do a -R redir to - localhost, but need to supply the IP address of the network interface - (e.g. by default the Shares do not listen on localhost:139). As a - convenience you can do something like -R 1139:IP:139 (for any port - numbers) and the IP will be attempted to be expanded. If this fails - for some reason you will have to use the actual numerical IP address. -} - .redirs.t insert end $msg - - frame .redirs.path - label .redirs.path.l -text "Port Redirs:" - entry .redirs.path.e -width 40 -textvariable additional_port_redirs_list - - pack .redirs.path.l -side left - pack .redirs.path.e -side left -expand 1 -fill x - - button .redirs.cancel -text "Cancel" -command {set additional_port_redirs 0; destroy .redirs} - bind .redirs <Escape> {set additional_port_redirs 0; destroy .redirs} - wm protocol .redirs WM_DELETE_WINDOW {set additional_port_redirs 0; destroy .redirs} - button .redirs.done -text "Done" -command {destroy .redirs} - - pack .redirs.t .redirs.path .redirs.cancel .redirs.done -side top -fill x - - center_win .redirs - wm resizable .redirs 1 0 - - focus .redirs.path.e -} - -proc stunnel_sec_dialog {} { - global stunnel_local_protection - - toplev .stlsec - wm title .stlsec "STUNNEL Local Port Protections" - - global help_font uname - - set h 37 - if [small_height] { - set h 26 - } - scroll_text .stlsec.f 82 $h - - apply_bg .stlsec.f - - set msg { - See the discussion of "Untrusted Local Users" in the main 'Help' - panel for info about users who are able to log into the workstation - you run SSVNC on and might try to use your encrypted tunnel to gain - access to the remote VNC machine. - - On Unix, for STUNNEL SSL tunnels we provide two options as extra - safeguards against untrusted local users. Both only apply to Unix/MacOSX. - Note that Both options are *IGNORED* in reverse connection (Listen) mode. - - 1) The first one 'Use stunnel EXEC mode' (it is mutually exclusive with - option 2). For this case the modified SSVNC Unix viewer must be - used: it execs the stunnel program instead of connecting to it via - TCP/IP. Thus there is no localhost listening port involved at all. - - This is the best solution for SSL stunnel tunnels, it works well and - is currently enabled by default. Disable it if there are problems. - - 2) The second one 'Use stunnel IDENT check', uses the stunnel(8) - 'ident = username' to use the local identd daemon (IDENT RFC 1413 - http://www.ietf.org/rfc/rfc1413.txt) to check that the locally - connecting program (the SSVNC vncviewer) is being run by your userid. - See the stunnel(8) man page for details. - - Normally the IDENT check service cannot be trusted much when used - *remotely* (the remote host may be have installed a modified daemon). - However when using the IDENT check service *locally* it should be - reliable. If not, it means the local machine (where you run SSVNC) - has already been root compromised and you have a serious problem. - - Enabling 'Use stunnel IDENT check' requires a working identd on the - local machine. Often it is not installed or enabled (because it is not - deemed to be useful, etc). identd is usually run out of the inetd(8) - super-server. Even when installed and running it is often configured - incorrectly. On a Debian/lenny system we actually found that the - kernel module 'tcp_diag' needed to be loaded! ('modprobe tcp_diag') -} - .stlsec.f.t insert end $msg - - radiobutton .stlsec.ident -relief ridge -anchor w -variable stunnel_local_protection_type -value "ident" -text "Use stunnel IDENT check" - radiobutton .stlsec.exec -relief ridge -anchor w -variable stunnel_local_protection_type -value "exec" -text "Use stunnel EXEC mode" - - button .stlsec.cancel -text "Cancel" -command {set stunnel_local_protection 0; destroy .stlsec} - bind .stlsec <Escape> {set stunnel_local_protection 0; destroy .stlsec} - wm protocol .stlsec WM_DELETE_WINDOW {set stunnel_local_protection 0; destroy .stlsec} - button .stlsec.done -text "Done" -command {if {$stunnel_local_protection_type == "none"} {set stunnel_local_protection 0}; destroy .stlsec} - - pack .stlsec.f .stlsec.exec .stlsec.ident .stlsec.cancel .stlsec.done -side top -fill x - - center_win .stlsec - wm resizable .stlsec 1 0 -} - -proc disable_ssl_workarounds_dialog {} { - global disable_ssl_workarounds disable_ssl_workarounds_type - - toplev .sslwrk - wm title .sslwrk "Disable SSL Workarounds" - - global help_font uname - set h 36 - if [small_height] { - set h 24 - } - scroll_text .sslwrk.f 86 $h - - apply_bg .sslwrk.f - - set msg { - Some SSL implementations are incomplete or buggy or do not work properly - with other implementations. SSVNC uses STUNNEL for its SSL encryption, - and STUNNEL uses the OpenSSL SSL implementation. - - This causes some problems with non-OpenSSL implementations on the VNC server - side. The most noticable one is the UltraVNC Single Click III (SSL) server: - - http://www.uvnc.com/pchelpware/SCIII/index.html - - It can make a reverse connection to SSVNC via an encrypted SSL tunnel. - - Unfortunately, in the default operation with STUNNEL the connection will be - dropped after 2-15 minutes due to an unexpected packet. - - Because of this, by default SSVNC will enable some SSL workarounds to make - connections like these work. This is the STUNNEL 'options = ALL' setting: - it enables a basic set of SSL workarounds. - - You can read all about these workarounds in the stunnel(8) manpage and the - OpenSSL SSL_CTX_set_options(3) manpage. - - Why are we mentioning this? STUNNELS's 'options = ALL' lowers the SSL - security a little bit. If you know you do not have an incompatible SSL - implementation on the server side (e.g. any one using OpenSSL is compatible, - x11vnc in particular), then you can regain that little bit of security by - selecting the "Disable SSL Workarounds" option. - - "Disable All SSL Workarounds" selected below will do that. On the other hand, - choose "Keep the DONT_INSERT_EMPTY_FRAGMENTS Workaround" to retain that one, - commonly needed workaround. - - BTW, you can set the environment variable STUNNEL_EXTRA_OPTS_USER to add - any lines to the STUNNEL global config that you want to. See the stunnel(8) - man page for more details. -} - .sslwrk.f.t insert end $msg - - radiobutton .sslwrk.none -relief ridge -anchor w -variable disable_ssl_workarounds_type -value "none" -text "Disable All Workarounds" - radiobutton .sslwrk.noempty -relief ridge -anchor w -variable disable_ssl_workarounds_type -value "noempty" -text "Keep the DONT_INSERT_EMPTY_FRAGMENTS Workaround" - - button .sslwrk.cancel -text "Cancel" -command {set disable_ssl_workarounds 0; destroy .sslwrk} - bind .sslwrk <Escape> {set disable_ssl_workarounds 0; destroy .sslwrk} - wm protocol .sslwrk WM_DELETE_WINDOW {set disable_ssl_workarounds 0; destroy .sslwrk} - button .sslwrk.done -text "Done" -command {destroy .sslwrk} - - pack .sslwrk.f .sslwrk.none .sslwrk.noempty .sslwrk.cancel .sslwrk.done -side top -fill x - - center_win .sslwrk - wm resizable .sslwrk 1 0 -} - -proc update_no_ultra_dsm {} { - global ultra_dsm_noultra - global ultra_dsm_type - - foreach b {bf des3 aes aes256 l e} { - if {! $ultra_dsm_noultra} { - .ultradsm.nou.$b configure -state disabled - } else { - .ultradsm.nou.$b configure -state normal - } - } - if {! $ultra_dsm_noultra} { - if {$ultra_dsm_type == "arc4"} { - ; - } elseif {$ultra_dsm_type == "aesv2"} { - ; - } elseif {$ultra_dsm_type == "msrc4"} { - ; - } elseif {$ultra_dsm_type == "msrc4_sc"} { - ; - } elseif {$ultra_dsm_type == "securevnc"} { - ; - } else { - set ultra_dsm_type guess - } - catch {.ultradsm.key.securevnc configure -state normal} - catch {.ultradsm.key.msrc4_sc configure -state normal} - } else { - catch {.ultradsm.key.securevnc configure -state disabled} - catch {.ultradsm.key.msrc4_sc configure -state disabled} - } -} - -proc ultra_dsm_dialog {} { - global ultra_dsm ultra_dsm_file ultra_dsm_type - - toplev .ultradsm - wm title .ultradsm "UltraVNC DSM Encryption Plugin" - - global help_font - set h 40 - if [small_height] { - set h 22 - } - scroll_text .ultradsm.f 85 $h - - set msg { - On Unix and MacOSX with the provided SSVNC vncviewer, you can connect to an - UltraVNC server that is using one of its DSM encryption plugins: MSRC4, ARC4, - AESV2, and SecureVNC. More info at: http://www.uvnc.com/features/encryption.html - - IMPORTANT: The UltraVNC DSM MSRC4, ARC4, and AESV2 implementations contain - unfixed errors that could allow an eavesdropper to recover the session - key or traffic easily. They often do not provide strong encryption, but - only provide basic obscurity instead. Do not use them with critical data. - The newer SecureVNC Plugin does not suffer from these problems. - - See the bottom of this help text for how to use symmetric encryption with - Non-UltraVNC servers (for example, x11vnc 0.9.5 or later). This mode does not - suffer the shortcomings of the UltraVNC MSRC4, ARC4, and AESV2 implementations. - - You will need to specify the corresponding UltraVNC encryption key (created - by you using an UltraVNC server or viewer). It is usually called 'rc4.key' - (for MSRC4), 'arc4.key' (for ARC4), and 'aesv2.key' (for AESV2). Specify the - path to it or Browse for it. Also, specify which type of plugin it is (or use - 'guess' to have it guess via the before mentioned filenames). - - The choice "UVNC SC" enables a special workaround for use with UltraVNC Single - Click and the MSRC4 plugin. It may not be needed on recent SC (e.g. from - ~2009 and later; select "MSRC4" for these newer ones.) - - You can also specify pw=my-password instead of a keyfile. Use single quotes - pw='....' if the password contains shell meta-characters `!$&*(){}[]|;<>? - - Use the literal string 'pw=VNCPASSWD' to have the VNC password that you - entered into the 'VNC Password:' be used for the pw=... - - SSL and SSH tunnels do not apply in this mode (any settings are ignored.) - - Proxying works in this mode, as well as Reverse Connections (Listen) - - The choice "SecureVNC" refers to the SecureVNC Plugin using 128 bit AES or - ARC4 with 2048 bit RSA key exchange described here: - - http://adamwalling.com/SecureVNC - - Note in its default mode SecureVNC is *Vulnerable* to Man-In-The-Middle attacks - (encryption but no server authentication) so do not use it with critical data. - In SecureVNC mode you do not need to supply a 'Ultra DSM Keyfile'. However, - if you DO supply a keyfile filename (recommended) if that file does not exist - you will be prompted if you want to save the UltraVNC server's RSA key in it. - The key's MD5 checksum is displayed so that you can verify that the key is - trusted. One way to print out the SecureVNC public key MD5 checksum is: - - openssl rsa -inform DER -outform DER -pubout -in ./Server_SecureVNC.pkey | dd bs=1 skip=24 | md5sum - - Then on subsequent connections, if you continue to specify this filename, the - SecureVNCPlugin server's RSA key will be checked against the file's contents - and if they differ the connection will be dropped. - - NOTE, However, if the SecureVNC keyfile ends in the string 'ClientAuth.pkey' - then its contents are used for SecureVNC's normal Client Authentication dialog - (you need to use Windows SecureVNCPlugin to generate this file on the server - side, it is usually called "Viewer_ClientAuth.pkey", and then safely copy it - to the viewer side.) If you want to do BOTH Client Auth and server RSA key - storing (recommended), have the keyfile end in 'ClientAuth.pkey.rsa'; that way - the file will be used for storing the server RSA key and then the '.rsa' is - trimmed off and the remainder used for the SecureVNC Client Auth data filename. - - Note that despite its intentions, Client Authentication in the FIRST release of - SecureVNC is still susceptible to Man-In-The-Middle attacks. Even when that - is fixed, SecureVNC Client Authentication is still susceptible to "spoofing" - attacks where the viewer user may be tricked into revealing his VNC or MS-Logon - password if his connection is intercepted. It is recommended you verify and - save the Server key (see above) in addition to using Client Authentication. - - UltraVNC DSM encryption modes are currently experimental because unfortunately - the UltraVNC DSM plugin also modifies the RFB protocol(!), and so the SSVNC - vncviewer had to be modified to support it. The tight, zlib, and some minor - encodings currently do not work in this mode and are disabled. - - Note that this mode also requires the utility tool named 'ultravnc_dsm_helper' - that should be included in your SSVNC kit. - - Select 'Non-Ultra DSM' to use symmetric encryption to a Non-UltraVNC server via - a supported symmetric key cipher. x11vnc supports symmetric encryption via, - e.g., "x11vnc -enc aesv2:./my.key". Extra ciphers are enabled for this mode - (e.g. blowfish and 3des). 'UVNC SC' and SecureVNC do not apply in this mode. - - Note for the Non-Ultra DSM case it will also work with any VNC Viewer - (i.e. selected by Options -> Advanced -> Change VNC Viewer) not only the - supplied SSVNC vncviewer. - - For experts: You can also set the random salt size and initialization vector - size in Salt,IV for example "8,16". See the x11vnc and 'ultravnc_dsm_helper - -help' documentation for more info on this. -} - - .ultradsm.f.t insert end $msg - - frame .ultradsm.path - label .ultradsm.path.l -text "Ultra DSM Keyfile:" - entry .ultradsm.path.e -width 40 -textvariable ultra_dsm_file - button .ultradsm.path.b -text "Browse..." -command {set_ultra_dsm_file .ultradsm} - - pack .ultradsm.path.l -side left - pack .ultradsm.path.e -side left -expand 1 -fill x - pack .ultradsm.path.b -side left - - frame .ultradsm.key - label .ultradsm.key.l -text "Type of Key: " - radiobutton .ultradsm.key.guess -pady 1 -anchor w -variable ultra_dsm_type -value guess \ - -text "Guess" - radiobutton .ultradsm.key.arc4 -pady 1 -anchor w -variable ultra_dsm_type -value arc4 \ - -text "ARC4" - - radiobutton .ultradsm.key.aesv2 -pady 1 -anchor w -variable ultra_dsm_type -value aesv2 \ - -text "AESV2" - - radiobutton .ultradsm.key.msrc4 -pady 1 -anchor w -variable ultra_dsm_type -value msrc4 \ - -text "MSRC4" - - radiobutton .ultradsm.key.msrc4_sc -pady 1 -anchor w -variable ultra_dsm_type -value msrc4_sc \ - -text "UVNC SC" - - radiobutton .ultradsm.key.securevnc -pady 1 -anchor w -variable ultra_dsm_type -value securevnc \ - -text "SecureVNC" - - pack .ultradsm.key.l -side left - pack .ultradsm.key.guess -side left - pack .ultradsm.key.arc4 -side left - pack .ultradsm.key.aesv2 -side left - pack .ultradsm.key.msrc4 -side left - pack .ultradsm.key.msrc4_sc -side left - pack .ultradsm.key.securevnc -side left - - frame .ultradsm.nou - checkbutton .ultradsm.nou.cb -text "Non-Ultra DSM" -variable ultra_dsm_noultra -command update_no_ultra_dsm - radiobutton .ultradsm.nou.bf -pady 1 -anchor w -variable ultra_dsm_type -value blowfish \ - -text "Blowfish" - - radiobutton .ultradsm.nou.des3 -pady 1 -anchor w -variable ultra_dsm_type -value 3des \ - -text "3DES" - - radiobutton .ultradsm.nou.aes -pady 1 -anchor w -variable ultra_dsm_type -value "aes-cfb" \ - -text "AES-CFB" - - radiobutton .ultradsm.nou.aes256 -pady 1 -anchor w -variable ultra_dsm_type -value "aes256" \ - -text "AES-256" - - label .ultradsm.nou.l -text " Salt,IV" - entry .ultradsm.nou.e -width 6 -textvariable ultra_dsm_salt - - pack .ultradsm.nou.cb -side left - pack .ultradsm.nou.bf -side left - pack .ultradsm.nou.des3 -side left - pack .ultradsm.nou.aes -side left - pack .ultradsm.nou.aes256 -side left - pack .ultradsm.nou.l -side left - pack .ultradsm.nou.e -side left -expand 0 - - update_no_ultra_dsm - - button .ultradsm.cancel -text "Cancel" -command {destroy .ultradsm; set ultra_dsm 0} - bind .ultradsm <Escape> {destroy .ultradsm; set ultra_dsm 0} - wm protocol .ultradsm WM_DELETE_WINDOW {destroy .ultradsm; set ultra_dsm 0} - button .ultradsm.done -text "Done" -command {destroy .ultradsm; catch {raise .oa}} - bind .ultradsm.path.e <Return> {destroy .ultradsm; catch {raise .oa}} - - pack .ultradsm.f .ultradsm.path .ultradsm.key .ultradsm.nou .ultradsm.cancel .ultradsm.done -side top -fill x - - center_win .ultradsm - wm resizable .ultradsm 1 0 - - focus .ultradsm.path.e -} - -proc ssh_known_hosts_dialog {} { - global ssh_known_hosts ssh_known_hosts_filename - - toplev .sshknownhosts - wm title .sshknownhosts "Private SSH KnownHosts file" - - global help_font - set h 31 - if [small_height] { - set h 23 - } - scroll_text .sshknownhosts.f 80 $h - - set msg { - Private SSH KnownHosts file: - - On Unix in SSH mode, let the user specify a non-default - ssh known_hosts file to be used only by the current profile. - This is the UserKnownHostsFile ssh option and is described in the - ssh_config(1) man page. This is useful to avoid proxy 'localhost' - SSH key collisions. - - Normally one should simply let ssh use its default file - ~/.ssh/known_hosts for tracking SSH keys. The only problem with - that happens when multiple SSVNC connections use localhost tunnel - port redirections. These make ssh connect to 'localhost' on some - port (where the proxy is listening.) Then the different keys - from the multiple ssh servers collide when ssh saves them under - 'localhost' in ~/.ssh/known_hosts. - - So if you are using a proxy with SSVNC or doing a "double SSH - gateway" your ssh will connect to a proxy port on localhost, and you - should set a private KnownHosts file for that connection profile. - This is secure and avoids man-in-the-middle attack (as long as - you actually verify the initial save of the SSH key!) - - The default file location will be: - - ~/.vnc/ssh_known_hosts/profile-name.known - - but you can choose any place you like. It must of course be - unique and not shared with another ssh connection otherwise they - both may complain about the key for 'localhost' changing, etc. -} - - .sshknownhosts.f.t insert end $msg - - frame .sshknownhosts.path - label .sshknownhosts.path.l -text "SSH KnownHosts file:" - entry .sshknownhosts.path.e -width 40 -textvariable ssh_known_hosts_filename - button .sshknownhosts.path.b -text "Browse..." -command {set_ssh_known_hosts_file .sshknownhosts} - - pack .sshknownhosts.path.l -side left - pack .sshknownhosts.path.e -side left -expand 1 -fill x - pack .sshknownhosts.path.b -side left - - button .sshknownhosts.cancel -text "Cancel" -command {destroy .sshknownhosts; set ssh_known_hosts 0} - bind .sshknownhosts <Escape> {destroy .sshknownhosts; set ssh_known_hosts 0} - wm protocol .sshknownhosts WM_DELETE_WINDOW {destroy .sshknownhosts; set ssh_known_hosts 0} - button .sshknownhosts.done -text "Done" -command {destroy .sshknownhosts; catch {raise .oa}} - bind .sshknownhosts.path.e <Return> {destroy .sshknownhosts; catch {raise .oa}} - - pack .sshknownhosts.f .sshknownhosts.path .sshknownhosts.cancel .sshknownhosts.done -side top -fill x - - center_win .sshknownhosts - wm resizable .sshknownhosts 1 0 - - focus .sshknownhosts.path.e -} - -proc ssh_sec_dialog {} { - global ssh_local_protection - - toplev .sshsec - wm title .sshsec "SSH Local Port Protections" - - global help_font - eval text .sshsec.t -width 80 -height 28 $help_font - - apply_bg .sshsec.t - - set msg { - See the discussion of "Untrusted Local Users" in the main 'Help' - panel for info about users who are able to log into the workstation - you run SSVNC on and might try to use your encrypted tunnel to gain - access to the remote VNC machine. - - On Unix, for SSH tunnels we have an LD_PRELOAD hack (lim_accept.so) - that will limit ssh from accepting any local redirection connections - after the first one or after 35 seconds, whichever comes first. - The first SSH port redirection connection is intended to be the one - that tunnels your VNC Viewer to reach the remote server. - - You can adjust these defaults LIM_ACCEPT=1 LIM_ACCEPT_TIME=35 by - setting those env. vars. to different values. - - Note that there is still a window of a few seconds the Untrusted - Local User can try to connect before your VNC Viewer does. So this - method is far from perfect. But once your VNC session is established, - he should be blocked out. Test to make sure blocking is taking place. - - Do not use this option if you are doing SSH Service redirections - 'Additional Port Redirections (via SSH)' that redirect a local port - to the remote server via ssh -L. - - Note that if the shared object "lim_accept.so" cannot be found, - this option has no effect. Watch the output in the terminal for - the "SSVNC_LIM_ACCEPT_PRELOAD" setting. -} - .sshsec.t insert end $msg - - button .sshsec.cancel -text "Cancel" -command {set ssh_local_protection 0; destroy .sshsec} - bind .sshsec <Escape> {set ssh_local_protection 0; destroy .sshsec} - wm protocol .sshsec WM_DELETE_WINDOW {set ssh_local_protection 0; destroy .sshsec} - button .sshsec.done -text "Done" -command {destroy .sshsec} - - pack .sshsec.t .sshsec.cancel .sshsec.done -side top -fill x - - center_win .sshsec - wm resizable .sshsec 1 0 -} - -proc multilisten_dialog {} { - global multiple_listen - - toplev .multil - wm title .multil "Multiple LISTEN Connections" - - global help_font - set h 36 - if [small_height] { - set h 30 - } - eval text .multil.t -width 84 -height $h $help_font - - apply_bg .multil.t - - set msg { - Set this option to allow SSVNC (when in LISTEN / Reverse connections - mode) to allow multiple VNC servers to connect at the same time and - so display each of their desktops on your screen at the same time. - - This option only applies on Unix or MaOSX when using the supplied - SSVNC vncviewer. If you specify your own VNC Viewer it has no effect. - - On Windows (only the stock TightVNC viewer is provided) it has no effect - because the Windows SSVNC can ONLY do "Multiple LISTEN Connections". - Similarly on MacOSX if the COTVNC viewer is used there is no effect. - - Rationale: To play it safe, the Unix vncviewer provided by SSVNC - (ssvncviewer) only allows one LISTEN reverse connection at a time. - This is to prohibit malicious people on the network from depositing - as many desktops on your screen as he likes, even if you are already - connected to VNC server you desire. - - For example, perhaps the malicious user could trick you into typing - a password into the desktop he displays on your screen. - - This protection is not perfect, because the malicious user could - try to reverse connect to you before the correct VNC server reverse - connects to you. This is even more of a problem if you keep your - SSVNC viewer in LISTEN mode but unconnected for long periods of time. - Pay careful attention in this case if you are to supplying sensitive - information to the remote desktop. - - Enable 'Multiple LISTEN Connections' if you want to disable the default - protection in the Unix SSVNC vncviewer; i.e. allow multiple reverse - connections simultaneously (all vnc viewers we know of do this by default) - - For more control, do not select 'Multiple LISTEN Connections', but - rather set the env. var SSVNC_MULTIPLE_LISTEN=MAX:n to limit the number - of simultaneous reverse connections to "n" -} - .multil.t insert end $msg - - button .multil.cancel -text "Cancel" -command {set multiple_listen 0; destroy .multil} - bind .multil <Escape> {set multiple_listen 0; destroy .multil} - wm protocol .multil WM_DELETE_WINDOW {set multiple_listen 0; destroy .multil} - button .multil.done -text "Done" -command {destroy .multil} - - pack .multil.t .multil.cancel .multil.done -side top -fill x - - center_win .multil - wm resizable .multil 1 0 -} - -proc use_grab_dialog {} { - global usg_grab - - toplev .usegrb - wm title .usegrb "Use XGrabServer (for fullscreen)" - - global help_font - eval text .usegrb.t -width 85 -height 29 $help_font - - apply_bg .usegrb.t - - set msg { - On Unix, some Window managers and some Desktops make it difficult for the - SSVNC Unix VNC viewer to go into full screen mode (F9) and/or return. - - Sometimes one can go into full screen mode, but then your keystrokes or - Mouse actions do not get through. This can leave you trapped because you - cannot inject input (F9 again) to get out of full screen mode. (Tip: - press Ctrl-Alt-F2 for a console login shell; then kill your vncviewer - process, e.g. pkill vncviewer; then Alt-F7 to get back to your desktop) - - We have seen this in some very old Window managers (e.g. fvwm2 circa - 1998) and some very new Desktops (e.g. GNOME circa 2008). We try - to work around the problem on recent desktops by using the NEW_WM - interface, but if you use Fullscreen, you may need to use this option. - - The default for the SSVNC Unix VNC viewer is '-grabkbd' mode where it will - try to exclusively grab the keyboard. This often works correctly. - - However if Fullscreen is not working properly, try setting this - 'Use XGrabServer' option to enable '-graball' mode where it tries to grab - the entire X server. This usually works, but can be a bit flakey. - - Sometimes toggling F9 a few times gets lets the vncviewer fill the whole - screen. Sometimes tapping F9 very quickly gets it to snap in. If GNOME - (or whatever desktop) is still showing its taskbars, it is recommended - you toggle F9 until it isn't. Otherwise, it is not clear who gets the input. - - Best of luck. -} - .usegrb.t insert end $msg - - button .usegrb.cancel -text "Cancel" -command {set use_grab 0; destroy .usegrb} - bind .usegrb <Escape> {set use_grab 0; destroy .usegrb} - wm protocol .usegrb WM_DELETE_WINDOW {set use_grab 0; destroy .usegrb} - button .usegrb.done -text "Done" -command {destroy .usegrb} - - pack .usegrb.t .usegrb.cancel .usegrb.done -side top -fill x - - center_win .usegrb - wm resizable .usegrb 1 0 -} - - -proc find_netcat {} { - global is_windows - - set nc "" - - if {! $is_windows} { - set nc [in_path "netcat"] - if {$nc == ""} { - set nc [in_path "nc"] - } - } else { - set try "netcat.exe" - if [file exists $try] { - set nc $try - } - } - return $nc -} - -proc pk_expand {cmd host} { - global tcl_platform - set secs [clock seconds] - set msecs [clock clicks -milliseconds] - set user $tcl_platform(user) - if [regexp {%IP} $cmd] { - set ip [guess_ip] - if {$ip == ""} { - set ip "unknown" - } - regsub -all {%IP} $cmd $ip cmd - } - if [regexp {%NAT} $cmd] { - set ip [guess_nat_ip] - regsub -all {%NAT} $cmd $ip cmd - } - regsub -all {%HOST} $cmd $host cmd - regsub -all {%USER} $cmd $user cmd - regsub -all {%SECS} $cmd $secs cmd - regsub -all {%MSECS} $cmd $msecs cmd - - return $cmd -} - -proc backtick_expand {str} { - set str0 $str - set collect "" - set count 0 - while {[regexp {^(.*)`([^`]+)`(.*)$} $str mv p1 cmd p2]} { - set out [eval exec $cmd] - set str "$p1$out$p2" - incr count - if {$count > 10} { - break - } - } - return $str -} - -proc read_from_pad {file} { - set fh "" - if {[catch {set fh [open $file "r"]}] != 0} { - return "FAIL" - } - - set accum "" - set match "" - while {[gets $fh line] > -1} { - if [regexp {^[ \t]*#} $line] { - append accum "$line\n" - } elseif [regexp {^[ \t]*$} $line] { - append accum "$line\n" - } elseif {$match == ""} { - set match $line - append accum "# $line\n" - } else { - append accum "$line\n" - } - } - - close $fh - - if {$match == ""} { - return "FAIL" - } - - if {[catch {set fh [open $file "w"]}] != 0} { - return "FAIL" - } - - puts -nonewline $fh $accum - - return $match -} - -proc do_port_knock {hp mode} { - global use_port_knocking port_knocking_list - global is_windows - - if {! $use_port_knocking} { - return 1 - } - if {$port_knocking_list == ""} { - return 1 - } - set list $port_knocking_list - - if {$mode == "finish"} { - if {! [regexp {FINISH} $list]} { - mesg "PortKnock(finish): done" - return 1 - } else { - regsub {^.*FINISH} $list "" list - } - } elseif {$mode == "start"} { - if {[regexp {FINISH} $list]} { - regsub {FINISH.*$} $list "" list - } - } - - set default_delay 150 - - set host [string trim $hp] - # XXX host_part - regsub {^vnc://} $host "" host - regsub {^.*@} $host "" host - regsub {:[0-9][0-9]*$} $host "" host - set host0 [string trim $host] - - if {$host0 == ""} { - bell - mesg "PortKnock: No host: $hp" - return 0 - } - - set m "" - - if [regexp {PAD=([^\n]+)} $list mv padfile] { - set tlist [read_from_pad $padfile] - set tlist [string trim $tlist] - if {$tlist == "" || $tlist == "FAIL"} { - raise . - tk_messageBox -type ok -icon error \ - -message "Failed to read entry from $padfile" \ - -title "Error: Padfile $padfile" - return 0 - } - regsub -all {PAD=([^\n]+)} $list $tlist list - } - - set spl ",\n\r" - if [regexp {CMD=} $list] {set spl "\n\r"} - if [regexp {CMDX=} $list] {set spl "\n\r"} - if [regexp {SEND=} $list] {set spl "\n\r"} - if [regexp {SENDX=} $list] {set spl "\n\r"} - - set i 0 - set pi 0 - - foreach line [split $list $spl] { - set line [string trim $line] - set line0 $line - - if {$line == ""} { - continue - } - if [regexp {^#} $line] { - continue - } - - if [regexp {^sleep[ \t][ \t]*([0-9][0-9]*)} $line mv sl] { - set m "PortKnock: sleep $sl" - mesg $m - after $sl - continue - } - if [regexp {^delay[ \t][ \t]*([0-9][0-9]*)} $line mv sl] { - set m "PortKnock: delay=$sl" - mesg $m - set default_delay $sl - continue - } - - if [regexp {^CMD=(.*)} $line mv cmd] { - set m "PortKnock: CMD: $cmd" - mesg $m - eval exec $cmd - continue - } - if [regexp {^CMDX=(.*)} $line mv cmd] { - set cmd [pk_expand $cmd $host0] - set m "PortKnock: CMDX: $cmd" - mesg $m - eval exec $cmd - continue - } - - if [regexp {`} $line] { - #set line [backtick_expand $line] - } - - set snd "" - if [regexp {^(.*)SEND=(.*)$} $line mv line snd] { - set line [string trim $line] - set snd [string trim $snd] - regsub -all {%NEWLINE} $snd "\n" snd - } elseif [regexp {^(.*)SENDX=(.*)$} $line mv line snd] { - set line [string trim $line] - set snd [string trim $snd] - set snd [pk_expand $snd $host0] - regsub -all {%NEWLINE} $snd "\n" snd - } - - set udp 0 - if [regexp -nocase {[/:]udp} $line] { - set udp 1 - regsub -all -nocase {[/:]udp} $line " " line - set line [string trim $line] - } - regsub -all -nocase {[/:]tcp} $line " " line - set line [string trim $line] - - set delay 0 - if [regexp {^(.*)[ \t][ \t]*([0-9][0-9]*)$} $line mv first delay] { - set line [string trim $first] - } - - if {[regexp {^(.*):([0-9][0-9]*)$} $line mv host port]} { - ; - } else { - set host $host0 - set port $line - } - set host [string trim $host] - set port [string trim $port] - - if {$host == ""} { - set host $host0 - } - - if {$port == ""} { - bell - set m "PortKnock: No port found: \"$line0\"" - mesg $m - return 0 - } - if {! [regexp {^[0-9][0-9]*$} $port]} { - bell - set m "PortKnock: Invalid port: \"$port\"" - mesg $m - return 0 - } - regsub {,.*$} $host "" host - if {[regexp {[ \t]} $host]} { - bell - set m "PortKnock: Invalid host: \"$host\"" - mesg $m - return 0 - } - if {! [regexp {^[-A-z0-9_.][-A-z0-9_.]*$} $host]} { - bell - set m "PortKnock: Invalid host: \"$host\"" - mesg $m - return 0 - } - - set nc "" - if {$udp || $snd != ""} { - set nc [find_netcat] - if {$nc == ""} { - bell - set m "PortKnock: UDP: netcat(1) not found" - mesg $m - after 1000 - continue - } - } - - if {$snd != ""} { - global env - set pfile "payload$pi.txt" - if {! $is_windows} { - set pfile "$env(SSVNC_HOME)/.$pfile" - } - set pfiles($pi) $pfile - incr pi - set fh [open $pfile "w"] - puts -nonewline $fh "$snd" - close $fh - - set m "PortKnock: SEND: $host $port" - mesg $m - if {$is_windows} { - if {$udp} { - catch {exec $nc -d -u -w 1 "$host" "$port" < $pfile &} - } else { - catch {exec $nc -d -w 1 "$host" "$port" < $pfile &} - } - } else { - if {$udp} { - catch {exec $nc -u -w 1 "$host" "$port" < $pfile &} - } else { - catch {exec $nc -w 1 "$host" "$port" < $pfile &} - } - } - catch {after 50; file delete $pfile} - - } elseif {$udp} { - set m "PortKnock: UDP: $host $port" - mesg $m - if {! $is_windows} { - catch {exec echo a | $nc -u -w 1 "$host" "$port" &} - } else { - set fh [open "nc_in.txt" "w"] - puts $fh "a" - close $fh - catch {exec $nc -d -u -w 1 "$host" "$port" < "nc_in.txt" &} - } - } else { - set m "PortKnock: TCP: $host $port" - mesg $m - set s "" - set emess "" - set rc [catch {set s [socket -async $host $port]} emess] - if {$rc != 0} { - raise . - tk_messageBox -type ok -icon error -message $emess -title "Error: socket -async $host $port" - } - set sockets($i) $s - # seems we have to close it immediately to avoid multiple SYN's. - # does not help on Win9x. - catch {after 30; close $s}; - incr i - } - - if {$delay == 0} { - if {$default_delay > 0} { - after $default_delay - } - } elseif {$delay > 0} { - after $delay - } - } - - if {0} { - for {set j 0} {$j < $i} {incr j} { - set $s $sockets($j) - if {$s != ""} { - catch {close $s} - } - } - } - for {set j 0} {$j < $pi} {incr j} { - set f $pfiles($j) - if {$f != ""} { - if [file exists $f] { - after 100 - } - catch {file delete $f} - } - } - if {$is_windows} { - catch {file delete "nc_in.txt"} - } - if {$m != ""} { - set m "$m," - } - if {$mode == "finish"} { - mesg "PortKnock(finish): done" - } else { - mesg "PortKnock: done" - } - return 1 -} - -proc port_knocking_dialog {} { - toplev .pk - wm title .pk "Port Knocking" - global use_port_knocking port_knocking_list - - global help_font - - global uname - - set h 35 - if [small_height] { - set h 22 - } elseif {$uname == "Darwin"} { - set h 25 - } - scroll_text .pk.f 85 $h - - set msg { - Description: - - Port Knocking is where a network connection to a service is not provided - to just any client, but rather only to those that immediately prior to - connecting send a more or less secret pattern of connections to other - ports on the firewall. - - Somewhat like "knocking" on the door with the correct sequence before it - being opened (but not necessarily letting you in yet). It is also possible - to have a single encrypted packet (e.g. UDP) payload communicate with the - firewall instead of knocking on a sequence of ports. - - Only after the correct sequence of ports is observed by the firewall does - it allow the IP address of the client to attempt to connect to the service. - - So, for example, instead of allowing any host on the internet to connect - to your SSH service and then try to login with a username and password, the - client first must "tickle" your firewall with the correct sequence of ports. - Only then will it be allowed to connect to your SSH service at all. - - This does not replace the authentication and security of SSH, it merely - puts another layer of protection around it. E.g., suppose an exploit for - SSH was discovered, you would most likely have more time to fix/patch - the problem than if any client could directly connect to your SSH server. - - For more information http://www.portknocking.org/ and - http://www.linuxjournal.com/article/6811 - - - Tip: - - If you just want to use the Port Knocking for an SSH shell and not - for a VNC tunnel, then specify something like "user@hostname cmd=SHELL" - (or "user@hostname cmd=PUTTY" on Windows) in the VNC Host:Display entry box - on the main panel. This will do everything short of starting the viewer. - A shortcut for this is Ctrl-S as long as user@hostname is present. - - - Specifying the Knocks: - - In the text area below "Supply port knocking pattern" you put in the pattern - of "knocks" needed for this connection. You can separate the knocks by - commas or put them one per line. - - Each "knock" is of this form: - - [host:]port[/udp] [delay] - - In the simplest form just a numerical port, e.g. 5433, is supplied. - Items inside [...] are optional and described below. - - The packet is sent to the same host that the VNC (or SSH) connection will - be made to. If you want it to go to a different host or IP use the [host:] - prefix. It can be either a hostname or numerical IP. - - A TCP packet is sent by default. - - If you need to send a UDP packet, the netcat (aka "nc") program must be - installed on Unix (tcl/tk does not support udp connections). Indicate this - with "/udp" following the port number (you can also use "/tcp", but since - it is the default it is not necessary). (You can also use ":udp" to match - the knockd syntax). See the example below. For convenience a Windows netcat - binary is supplied. - - The last field, [delay], is an optional number of milliseconds to delay - before continuing on to the next knock. - - - Examples: - - 5433, 12321, 1661 - - fw.example.com:5433, 12321/udp 3000, 1661 2000 - - fw.example.com:5433 - 12321/udp 3000 - 1661 2000 - - Note how the first two examples separate their knocks via commas ",". - The 3rd example is equivalent to the 2nd and splits them up by new lines. - - Note for each knock any second number (e.g. the "2000" in "1661 2000") is - a DELAY in milliseconds, not a port number. If you had a comma separating - them: "1661, 2000" that would mean two separate knocks: one to port 1661 - followed by one to 2000 (with basically no delay between them). - - In examples 2 and 3, "fw.example.com" represents some machine other than - the VNC/SSH host. By default, the VNC/SSH host is the one the packet is - sent to. - - If one of the items is the string "FINISH", then the part before it is - used prior to connecting and the part after is used once the connection - is finished. This can be used, say, to close the firewall port. Example: - - 5433, 12321, FINISH, 7659, 2314 - - (or one can split them up via lines as above.) - - - Advanced port knock actions: - - If the string in the text field contains anywhere the strings "CMD=", "CMDX=", - or "SEND=", then splitting on commas is not done: it is only split on lines. - - Then, if a line begins CMD=... the string after the = is run as an - external command. The command could be anything you want, e.g. it could - be a port-knocking client that does the knocking, perhaps encrypting the - "knocks" pattern somehow or using a Single Packet Authorization method such - as http://www.cipherdyne.com/fwknop/ - - Extra quotes (sometimes "'foo bar'") may be needed to preserve spaces in - command line arguments because the tcl/tk eval(n) command is used. You - can also use {...} for quoting strings with spaces. - - If a line begins CMDX=... then before the command is run the following - tokens are expanded to strings: - - %IP Current machine's IP address (NAT may make this not useful). - %NAT Try to get effective IP by contacting http://www.whatismyip.com - %HOST The remote host of the connection. - %USER The current user. - %SECS The current time in seconds (platform dependent). - %MSECS Platform dependent time having at least millisecond granularity. - - Lines not matching CMD= or CMDX= are treated as normal port knocks but with - one exception. If a line ends in SEND=... (i.e. after the [host:]port, - etc., part) then the string after the = is sent as a payload for the tcp - or udp connection to [host:]port. netcat is used for these SEND cases - (and must be available on Unix). If newlines (\n) are needed in the - SEND string, use %NEWLINE. Sending binary data is not yet supported; - use CMD= with your own program. - - - Advanced Examples: - - CMD=port_knock_client -password wombat33 - CMDX=port_knock_client -password wombat33 -host %HOST -src %NAT - - fw.example.com:5433/udp SEND=ASDLFKSJDF - - - More tricks: - - To temporarily "comment out" a knock, insert a leading "#" character. - - Use "sleep N" to insert a raw sleep for N milliseconds (e.g. between - CMD=... items or at the very end of the knocks to wait). - - If a knock entry matches "delay N" the default delay is set to - N milliseconds (it is 150 initially). - - - One Time Pads: - - If the text contains a (presumably single) line of the form: - - PAD=/path/to/a/one/time/pad/file - - then that file is opened and the first non-blank line not beginning - with "#" is used as the knock pattern. The pad file is rewritten - with that line starting with a "#" (so it will be skipped next time). - - The PAD=... string is replaced with the read-in knock pattern line. - So, if needed, one can preface the PAD=... with "delay N" to set the - default delay, and one can also put a "sleep N" after the PAD=... - line to indicate a final sleep. One can also surround the PAD= - line with other knock and CMD= CMDX= lines, but that usage sounds - a bit rare. Example: - - delay 1000 - PAD=C:\My Pads\work-pad1.txt - sleep 4000 - - - Port knock only: - - If, in the 'VNC Host:Display' entry, you use "user@hostname cmd=KNOCK" - then only the port-knocking is performed. A shortcut for this is - Ctrl-P as long as hostname is present in the entry box. If it - matches cmd=KNOCKF, i.e. an extra "F", then the port-knocking - "FINISH" sequence is sent, if any. A shortcut for this Shift-Ctrl-P - as long as hostname is present. -} - .pk.f.t insert end $msg - - label .pk.info -text "Supply port knocking pattern:" -anchor w -relief ridge - - eval text .pk.rule -width 80 -height 5 $help_font - .pk.rule insert end $port_knocking_list - - button .pk.cancel -text "Cancel" -command {set use_port_knocking 0; destroy .pk} - bind .pk <Escape> {set use_port_knocking 0; destroy .pk} - wm protocol .pk WM_DELETE_WINDOW {set use_port_knocking 0; destroy .pk} - button .pk.done -text "Done" -command {if {$use_port_knocking} {set port_knocking_list [.pk.rule get 1.0 end]}; destroy .pk} - - pack .pk.done .pk.cancel .pk.rule .pk.info -side bottom -fill x - pack .pk.f -side top -fill both -expand 1 - - center_win .pk -} - -proc choose_desktop_dialog {} { - toplev .sd - wm title .sd "Desktop Type" - global ts_desktop_type choose_desktop - - global ts_desktop_type_def - set def "kde" - if {$ts_desktop_type_def != ""} { - set def $ts_desktop_type_def - } - - if {$ts_desktop_type == ""} { - set ts_desktop_type $def - } - - label .sd.l1 -anchor w -text "Select the type of remote Desktop" - label .sd.l2 -anchor w -text "for your session (default: $def)" - - radiobutton .sd.b1 -anchor w -variable ts_desktop_type -value kde -text kde - radiobutton .sd.b2 -anchor w -variable ts_desktop_type -value gnome -text gnome - radiobutton .sd.b3 -anchor w -variable ts_desktop_type -value Xsession -text cde - radiobutton .sd.b4 -anchor w -variable ts_desktop_type -value mwm -text mwm - radiobutton .sd.b5 -anchor w -variable ts_desktop_type -value wmaker -text wmaker - radiobutton .sd.b6 -anchor w -variable ts_desktop_type -value xfce -text xfce - radiobutton .sd.b7 -anchor w -variable ts_desktop_type -value enlightenment -text enlightenment - radiobutton .sd.b8 -anchor w -variable ts_desktop_type -value twm -text twm - radiobutton .sd.b9 -anchor w -variable ts_desktop_type -value failsafe -text failsafe - - button .sd.cancel -text "Cancel" -command {destroy .sd; set choose_desktop 0; set ts_desktop_type ""} - bind .sd <Escape> {destroy .sd; set choose_desktop 0; set ts_desktop_type ""} - wm protocol .sd WM_DELETE_WINDOW {destroy .sd; set choose_desktop 0; set ts_desktop_type ""} - button .sd.done -text "Done" -command {destroy .sd} - - pack .sd.l1 .sd.l2 .sd.b1 .sd.b2 .sd.b3 .sd.b4 .sd.b5 .sd.b6 .sd.b7 .sd.b8 .sd.b9 .sd.cancel .sd.done -side top -fill x - - center_win .sd -} - -proc choose_size_dialog {} { - toplev .sz - wm title .sz "Desktop Size" - global ts_desktop_size ts_desktop_depth choose_desktop_geom - - set def1 "1280x1024" - set def2 "16" - - global ts_desktop_size_def ts_desktop_depth_def - if {$ts_desktop_size_def != ""} { - set def1 $ts_desktop_size_def - } - if {$ts_desktop_depth_def != ""} { - set def2 $ts_desktop_depth_def - } - - if {$ts_desktop_size == ""} { - set ts_desktop_size $def1 - } - if {$ts_desktop_depth == ""} { - set ts_desktop_depth $def2 - } - - label .sz.l1 -anchor w -text "Select the Size and Color depth" - label .sz.l2 -anchor w -text "for your Desktop session." - label .sz.l3 -anchor w -text "Default: $def1 and $def2 bits/pixel." - - label .sz.g0 -anchor w -text "Width x Height:" -relief groove - - radiobutton .sz.g1 -anchor w -variable ts_desktop_size -value "640x480" -text " 640x480" - radiobutton .sz.g2 -anchor w -variable ts_desktop_size -value "800x600" -text " 800x600" - radiobutton .sz.g3 -anchor w -variable ts_desktop_size -value "1024x768" -text " 1024x768" - radiobutton .sz.g4 -anchor w -variable ts_desktop_size -value "1280x1024" -text "1280x1024" - radiobutton .sz.g5 -anchor w -variable ts_desktop_size -value "1400x1050" -text "1400x1050" - radiobutton .sz.g6 -anchor w -variable ts_desktop_size -value "1600x1200" -text "1600x1200" - radiobutton .sz.g7 -anchor w -variable ts_desktop_size -value "1920x1200" -text "1920x1200" - - frame .sz.c - label .sz.c.l -anchor w -text "Custom:" - entry .sz.c.e -width 10 -textvariable ts_desktop_size - pack .sz.c.l -side left - pack .sz.c.e -side left -expand 1 -fill x - bind .sz.c.e <Return> {destroy .sz} - - label .sz.d0 -anchor w -text "Color Depth:" -relief groove - - radiobutton .sz.d1 -anchor w -variable ts_desktop_depth -value "8" -text " 8 bits/pixel" - radiobutton .sz.d2 -anchor w -variable ts_desktop_depth -value "16" -text "16 bits/pixel" - radiobutton .sz.d3 -anchor w -variable ts_desktop_depth -value "24" -text "24 bits/pixel" - - button .sz.cancel -text "Cancel" -command {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""} - bind .sz <Escape> {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""} - wm protocol .sz WM_DELETE_WINDOW {destroy .sz; set choose_desktop_geom 0; set ts_desktop_size ""; set ts_desktop_depth ""} - button .sz.done -text "Done" -command {destroy .sz} - - pack .sz.l1 .sz.l2 .sz.l3 \ - .sz.g0 .sz.g1 .sz.g2 .sz.g3 .sz.g4 .sz.g5 .sz.g6 .sz.g7 \ - .sz.c \ - .sz.d0 .sz.d1 .sz.d2 .sz.d3 \ - .sz.cancel .sz.done -side top -fill x - - center_win .sz - focus .sz.c.e -} - -proc choose_xserver_dialog {} { - toplev .st - wm title .st "X Server Type" - global ts_xserver_type choose_xserver - - set def "Xvfb" - global ts_xserver_type_def - if {$ts_xserver_type_def != ""} { - set def $ts_xserver_type_def - } - - if {$ts_xserver_type == ""} { - set ts_xserver_type $def - } - - label .st.l1 -anchor w -text "Select the type of remote X server" - label .st.l2 -anchor w -text "for your session (default: $def)" - - radiobutton .st.b1 -anchor w -variable ts_xserver_type -value Xvfb -text "Xvfb" - - radiobutton .st.b2 -anchor w -variable ts_xserver_type -value Xdummy -text "Xdummy" - - radiobutton .st.b3 -anchor w -variable ts_xserver_type -value Xvnc -text "Xvnc" - - radiobutton .st.b4 -anchor w -variable ts_xserver_type -value Xvnc.redirect -text "Xvnc.redirect" - - button .st.cancel -text "Cancel" -command {destroy .st; set choose_xserver 0; set ts_xserver_type ""} - bind .st <Escape> {destroy .st; set choose_xserver 0; set ts_xserver_type ""} - wm protocol .st WM_DELETE_WINDOW {destroy .st; set choose_xserver 0; set ts_xserver_type ""} - button .st.done -text "Done" -command {destroy .st} - - pack .st.l1 .st.l2 .st.b1 .st.b2 .st.b3 .st.b4 .st.cancel .st.done -side top -fill x - - center_win .st -} - -proc set_ts_options {} { - global use_cups use_sound use_smbmnt - global change_vncviewer choose_xserver - global ts_only is_windows - global darwin_cotvnc use_x11_macosx uname - if {! $ts_only} { - return - } - catch {destroy .o} - toplev .ot - wm title .ot "Options" - - set i 1 - - checkbutton .ot.b$i -anchor w -variable choose_desktop -text \ - "Desktop Type" \ - -command {if {$choose_desktop} {choose_desktop_dialog}} - incr i - - checkbutton .ot.b$i -anchor w -variable choose_desktop_geom -text \ - "Desktop Size" \ - -command {if {$choose_desktop_geom} {choose_size_dialog}} - incr i - - checkbutton .ot.b$i -anchor w -variable choose_xserver -text \ - "X Server Type" \ - -command {if {$choose_xserver} {choose_xserver_dialog}} - incr i - - checkbutton .ot.b$i -anchor w -variable use_cups -text \ - "Enable Printing" \ - -command {if {$use_cups} {cups_dialog}} - incr i - - checkbutton .ot.b$i -anchor w -variable use_sound -text \ - "Enable Sound" \ - -command {if {$use_sound} {sound_dialog}} - incr i - -# checkbutton .ot.b$i -anchor w -variable use_smbmnt -text \ -# "Enable SMB mount tunnelling" \ -# -command {if {$use_smbmnt} {smb_dialog}} -# incr i - - checkbutton .ot.b$i -anchor w -variable choose_filexfer -text \ - "File Transfer" \ - -command {if {$choose_filexfer} {ts_filexfer_dialog}} - incr i - - checkbutton .ot.b$i -anchor w -variable use_viewonly -text \ - "View Only" - incr i - - checkbutton .ot.b$i -anchor w -variable change_vncviewer -text \ - "Change VNC Viewer" \ - -command change_vncviewer_dialog_wrap - incr i - - if {!$is_windows && $uname == "Darwin"} { - checkbutton .ot.b$i -anchor w -variable use_x11_macosx -text \ - "X11 viewer MacOSX" \ - -command {if {$use_x11_macosx} {set darwin_cotvnc 0} else {set darwin_cotvnc 1}; set_darwin_cotvnc_buttons} - incr i - } - - button .ot.b$i -anchor w -text " Delete Profile..." \ - -command {destroy .ot; delete_profile} - incr i - - button .ot.b$i -anchor w -text " Advanced ..." -command {set_ts_adv_options} - incr i - - for {set j 1} {$j < $i} {incr j} { - pack .ot.b$j -side top -fill x - } - - frame .ot.b - button .ot.b.done -text "Done" -command {destroy .ot} - button .ot.b.help -text "Help" -command help_ts_opts - pack .ot.b.help .ot.b.done -fill x -expand 1 -side left - - bind .ot <Escape> {destroy .ot} - wm protocol .ot WM_DELETE_WINDOW {destroy .ot} - - pack .ot.b -side top -fill x - - center_win .ot - wm resizable .ot 1 0 - focus .ot -} - -proc set_ts_adv_options {} { - global ts_only ts_unixpw ts_vncshared - global ts_ncache ts_multisession - global choose_othervnc darwin_cotvnc choose_sleep - global is_windows - - if {! $ts_only} { - return - } - catch {destroy .ot} - toplev .ot2 - wm title .ot2 "Advanced" - - set i 1 - - checkbutton .ot2.b$i -anchor w -variable ts_vncshared -text \ - "VNC Shared" \ - -command {if {$ts_vncshared} {ts_vncshared_dialog}} - incr i - - checkbutton .ot2.b$i -anchor w -variable choose_multisession -text \ - "Multiple Sessions" \ - -command {if {$choose_multisession} {ts_multi_dialog}} - incr i - - checkbutton .ot2.b$i -anchor w -variable ts_xlogin -text \ - "X Login Greeter" \ - -command {if {$ts_xlogin} {ts_xlogin_dialog}} - incr i - - checkbutton .ot2.b$i -anchor w -variable choose_othervnc -text \ - "Other VNC Server" \ - -command {if {$choose_othervnc} {ts_othervnc_dialog}} - incr i - - checkbutton .ot2.b$i -anchor w -variable ts_unixpw -text \ - "Use unixpw" \ - -command {if {$ts_unixpw} {ts_unixpw_dialog}} - incr i - - checkbutton .ot2.b$i -anchor w -variable use_bgr233 -text \ - "Client 8bit Color" - if {$darwin_cotvnc} {.ot2.b$i configure -state disabled} - global darwin_cotvnc_blist - set darwin_cotvnc_blist(.ot2.b$i) 1 - incr i - - checkbutton .ot2.b$i -anchor w -variable choose_ncache -text \ - "Client-Side Caching" \ - -command {if {$choose_ncache} {ts_ncache_dialog}} - incr i - - checkbutton .ot2.b$i -anchor w -variable choose_x11vnc_opts -text \ - "X11VNC Options" \ - -command {if {$choose_x11vnc_opts} {ts_x11vnc_opts_dialog}} - incr i - - checkbutton .ot2.b$i -anchor w -variable choose_sleep -text \ - "Extra Sleep" \ - -command {if {$choose_sleep} {ts_sleep_dialog}} - incr i - - if {$is_windows} { - checkbutton .ot2.b$i -anchor w -variable choose_parg -text \ - "Putty Args" \ - -command {if {$choose_parg} {ts_putty_args_dialog}} - incr i - } - - if {!$is_windows} { - checkbutton .ot2.b$i -anchor w -variable ssh_local_protection -text \ - "SSH Local Protections" \ - -command {if {$ssh_local_protection} {ssh_sec_dialog}} - if {$is_windows} {.ot2.b$i configure -state disabled} - incr i - - checkbutton .ot2.b$i -anchor w -variable ssh_known_hosts -text \ - "SSH KnownHosts file" \ - -command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}} - if {$is_windows} {.ot2.b$i configure -state disabled} - incr i - } - - if {$is_windows} { - button .ot2.b$i -anchor w -text " Putty Agent" \ - -command {catch {exec pageant.exe &}} - incr i - - button .ot2.b$i -anchor w -text " Putty Key-Gen" \ - -command {catch {exec puttygen.exe &}} - incr i - } - - global env - if {![info exists env(SSVNC_TS_ALWAYS)]} { - button .ot2.b$i -anchor w -text " SSVNC Mode" \ - -command {destroy .ot2; to_ssvnc} - incr i - } - - if {!$is_windows} { - button .ot2.b$i -anchor w -text " Unix ssvncviewer ..." \ - -command {set_ssvncviewer_options} - if {$is_windows} { - .ot2.b$i configure -state disabled - } - global change_vncviewer - if {$change_vncviewer} { - .ot2.b$i configure -state disabled - } - global ts_uss_button - set ts_uss_button .ot2.b$i - incr i - } - - for {set j 1} {$j < $i} {incr j} { - pack .ot2.b$j -side top -fill x - } - - frame .ot2.b - button .ot2.b.done -text "Done" -command {destroy .ot2} - button .ot2.b.help -text "Help" -command help_ts_opts - pack .ot2.b.help .ot2.b.done -fill x -expand 1 -side left - - bind .ot2 <Escape> {destroy .ot2} - wm protocol .ot2 WM_DELETE_WINDOW {destroy .ot2} - - pack .ot2.b -side top -fill x - - center_win .ot2 - wm resizable .ot2 1 0 - focus .ot2 -} - -proc change_vncviewer_dialog_wrap {} { - global change_vncviewer ts_uss_button is_windows - if {$change_vncviewer} { - change_vncviewer_dialog - catch {tkwait window .chviewer} - } - if {$change_vncviewer || $is_windows} { - catch {.oa.ss configure -state disabled} - } else { - catch {.oa.ss configure -state normal} - } - if [info exists ts_uss_button] { - if {$change_vncviewer || $is_windows} { - catch {$ts_uss_button configure -state disabled} - } else { - catch {$ts_uss_button configure -state normal} - } - } -} - -proc set_advanced_options {} { - global use_cups use_sound use_smbmnt - global change_vncviewer - global use_port_knocking port_knocking_list - global is_windows darwin_cotvnc - global use_ssh use_sshssl - global use_x11_macosx - global adv_ssh - global showing_no_encryption - global x11vnc_xlogin_widget - - catch {destroy .o} - toplev .oa - wm title .oa "Advanced Options" - - set i 1 - - checkbutton .oa.b$i -anchor w -variable use_cups -text \ - "Enable CUPS Print tunnelling" \ - -command {if {$use_cups} {cups_dialog}} - if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} - set adv_ssh(cups) .oa.b$i - incr i - - checkbutton .oa.b$i -anchor w -variable use_sound -text \ - "Enable ESD/ARTSD Audio tunnelling" \ - -command {if {$use_sound} {sound_dialog}} - if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} - set adv_ssh(snd) .oa.b$i - incr i - - checkbutton .oa.b$i -anchor w -variable use_smbmnt -text \ - "Enable SMB mount tunnelling" \ - -command {if {$use_smbmnt} {smb_dialog}} - if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} - set adv_ssh(smb) .oa.b$i - incr i - - checkbutton .oa.b$i -anchor w -variable use_x11vnc_xlogin -text \ - "Automatically Find X Login/Greeter" -command {x11vnc_find_adjust "xlogin"} - if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} - set x11vnc_xlogin_widget ".oa.b$i" - incr i - - checkbutton .oa.b$i -anchor w -variable additional_port_redirs -text \ - "Additional Port Redirs (via SSH)" \ - -command {if {$additional_port_redirs} {port_redir_dialog}} - if {!$use_ssh && !$use_sshssl} {.oa.b$i configure -state disabled} - set adv_ssh(redirs) .oa.b$i - incr i - - global use_ssl use_ssh use_sshssl - - if {!$is_windows} { - checkbutton .oa.b$i -anchor w -variable ssh_known_hosts -text \ - "Private SSH KnownHosts file" \ - -command {if {$ssh_known_hosts} {ssh_known_hosts_dialog}} - set adv_ssh(knownhosts) .oa.b$i - if {$use_ssl} {.oa.b$i configure -state disabled} - if {$is_windows} {.oa.b$i configure -state disabled} - incr i - - checkbutton .oa.b$i -anchor w -variable ssh_local_protection -text \ - "SSH Local Port Protections" \ - -command {if {$ssh_local_protection} {ssh_sec_dialog}} - global ssh_local_protection_button - set ssh_local_protection_button .oa.b$i - if {$use_ssl} {.oa.b$i configure -state disabled} - if {$is_windows} {.oa.b$i configure -state disabled} - incr i - } - - global ssh_only - if {!$ssh_only} { - if {!$is_windows} { - checkbutton .oa.b$i -anchor w -variable stunnel_local_protection -text \ - "STUNNEL Local Port Protections" \ - -command {if {$stunnel_local_protection} {stunnel_sec_dialog}} - global stunnel_local_protection_button - set stunnel_local_protection_button .oa.b$i - if {$use_ssh} {.oa.b$i configure -state disabled} - if {$is_windows} {.oa.b$i configure -state disabled} - incr i - } - - checkbutton .oa.b$i -anchor w -variable disable_ssl_workarounds -text \ - "Disable SSL Workarounds" \ - -command {if {$disable_ssl_workarounds} {disable_ssl_workarounds_dialog}} - global disable_ssl_workarounds_button - set disable_ssl_workarounds_button .oa.b$i - if {$use_ssh} {.oa.b$i configure -state disabled} - incr i - - if {!$is_windows} { - checkbutton .oa.b$i -anchor w -variable ultra_dsm -text \ - "UltraVNC DSM Encryption Plugin" \ - -command {if {$ultra_dsm} {ultra_dsm_dialog}} - global ultra_dsm_button - set ultra_dsm_button .oa.b$i - if {$is_windows} {.oa.b$i configure -state disabled} - if {$use_ssh} {.oa.b$i configure -state disabled} - incr i - } - - checkbutton .oa.b$i -anchor w -variable no_probe_vencrypt -text \ - "Do not Probe for VeNCrypt" - global no_probe_vencrypt_button - set no_probe_vencrypt_button .oa.b$i - if {$use_ssh} {.oa.b$i configure -state disabled} - incr i - - checkbutton .oa.b$i -anchor w -variable server_vencrypt -text \ - "Server uses VeNCrypt SSL encryption" - global vencrypt_button - set vencrypt_button .oa.b$i - if {$use_ssh} {.oa.b$i configure -state disabled} - incr i - - checkbutton .oa.b$i -anchor w -variable server_anondh -text \ - "Server uses Anonymous Diffie-Hellman" -command no_certs_tutorial_mesg - global anondh_button - set anondh_button .oa.b$i - if {$use_ssh} {.oa.b$i configure -state disabled} - incr i - } - - checkbutton .oa.b$i -anchor w -variable change_vncviewer -text \ - "Change VNC Viewer" \ - -command change_vncviewer_dialog_wrap - incr i - - checkbutton .oa.b$i -anchor w -variable use_port_knocking -text \ - "Port Knocking" \ - -command {if {$use_port_knocking} {port_knocking_dialog}} - incr i - - for {set j 1} {$j < $i} {incr j} { - pack .oa.b$j -side top -fill x - } - - global include_list extra_sleep - frame .oa.fis - frame .oa.fis.fL - frame .oa.fis.fR - label .oa.fis.fL.la -anchor w -text "Include:" - label .oa.fis.fL.lb -anchor w -text "Sleep:" - if {$is_windows} { - label .oa.fis.fL.lc -anchor w -text "Putty Args:" - pack .oa.fis.fL.la .oa.fis.fL.lb .oa.fis.fL.lc -side top -fill x - } else { - pack .oa.fis.fL.la .oa.fis.fL.lb -side top -fill x - } - - entry .oa.fis.fR.ea -width 10 -textvariable include_list - entry .oa.fis.fR.eb -width 10 -textvariable extra_sleep - if {$is_windows} { - entry .oa.fis.fR.ec -width 10 -textvariable putty_args - pack .oa.fis.fR.ea .oa.fis.fR.eb .oa.fis.fR.ec -side top -fill x - } else { - pack .oa.fis.fR.ea .oa.fis.fR.eb -side top -fill x - } - - pack .oa.fis.fL -side left - pack .oa.fis.fR -side right -expand 1 -fill x - - pack .oa.fis -side top -fill x - - - if {!$is_windows} { - global uname - set t1 " Unix ssvncviewer ..." - if {$uname == "Darwin" } { regsub {^ *} $t1 "" t1 } - button .oa.ss -anchor w -text $t1 -command set_ssvncviewer_options - pack .oa.ss -side top -fill x - if {$is_windows} { - .oa.ss configure -state disabled - } - global change_vncviewer - if {$change_vncviewer} { - .oa.ss configure -state disabled - } - - set t2 " Use ssh-agent" - if {$uname == "Darwin" } { regsub {^ *} $t2 "" t2 } - - button .oa.sa -anchor w -text $t2 -command ssh_agent_restart - pack .oa.sa -side top -fill x - if {$is_windows} { - .oa.sa configure -state disabled - } - } else { - set t1 " Launch Putty Agent" - button .oa.pa -anchor w -text $t1 -command {catch {exec pageant.exe &}} - pack .oa.pa -side top -fill x - - set t2 " Launch Putty Key-Gen" - button .oa.pg -anchor w -text $t2 -command {catch {exec puttygen.exe &}} - pack .oa.pg -side top -fill x - } - - frame .oa.b - button .oa.b.done -text "Done" -command {destroy .oa} - bind .oa <Escape> {destroy .oa} - wm protocol .oa WM_DELETE_WINDOW {destroy .oa} - button .oa.b.help -text "Help" -command help_advanced_opts - - global use_listen - if {$use_listen} { - button .oa.b.connect -text "Listen" -command launch - } else { - button .oa.b.connect -text "Connect" -command launch - } - - pack .oa.b.help .oa.b.connect .oa.b.done -fill x -expand 1 -side left - - pack .oa.b -side top -fill x - - center_win .oa - wm resizable .oa 1 0 - focus .oa -} - -proc set_ssvncviewer_options {} { - global is_windows darwin_cotvnc - global use_ssh use_sshssl use_x11cursor use_rawlocal use_notty use_popupfix use_alpha use_turbovnc disable_pipeline use_grab use_nobell - global use_send_clipboard use_send_always - global ssvnc_scale ssvnc_escape - global server_vencrypt server_anondh - - if {$is_windows} { - return - } - - catch {destroy .oa} - toplev .os - wm title .os "Unix ssvncviewer Options" - - set darwinlist [list] - - set f0 .os.f - frame $f0 - set fl $f0.fl - frame $fl - set fr $f0.fr - frame $fr - - set i 1 - set j 1 - - checkbutton $fl.b$i -anchor w -variable multiple_listen -text \ - "Multiple LISTEN Connections" \ - -command {if {$multiple_listen} {multilisten_dialog}} - global multiple_listen_button use_listen - set multiple_listen_button $fl.b$i - if {$is_windows} {$fl.b$i configure -state disabled} - if {!$use_listen} {$fl.b$i configure -state disabled} - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable listen_once -text \ - "Listen Once" - global listen_once_button - set listen_once_button $fl.b$i - if {!$use_listen} {$fl.b$i configure -state disabled} - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable listen_accept_popup -text \ - "Listen Accept Popup Dialog" \ - -command { if {$listen_accept_popup} { catch {$listen_accept_popup_button_sc configure -state normal} } else { catch {$listen_accept_popup_button_sc configure -state disabled} } } - global listen_accept_popup_button - set listen_accept_popup_button $fl.b$i - if {!$use_listen} {$fl.b$i configure -state disabled} - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - global listen_accept_popup - checkbutton $fl.b$i -anchor w -variable listen_accept_popup_sc -text \ - " Accept Popup UltraVNC Single Click" - global listen_accept_popup_button_sc - set listen_accept_popup_button_sc $fl.b$i - if {!$use_listen} {$fl.b$i configure -state disabled} - if {!$listen_accept_popup} {$fl.b$i configure -state disabled} - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_x11cursor -text \ - "Use X11 Cursor" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_nobell -text \ - "Disable Bell" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_rawlocal -text \ - "Use Raw Local" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_notty -text \ - "Avoid Using Terminal" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_popupfix -text \ - "Use Popup Fix" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_grab -text \ - "Use XGrabServer (for fullscreen)" \ - -command {if {$use_grab} {use_grab_dialog}} - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_alpha -text \ - "Cursor Alphablending (32bpp required) " - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_turbovnc -text \ - "TurboVNC (if available on platform)" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable disable_pipeline -text \ - "Disable Pipelined Updates" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_send_clipboard -text \ - "Send CLIPBOARD not PRIMARY" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - checkbutton $fl.b$i -anchor w -variable use_send_always -text \ - "Send Selection Every time" - lappend darwinlist $fl.b$i; if {$darwin_cotvnc} {$fl.b$i configure -state disabled} - incr i - - set relief ridge - - frame $fr.b$j -height 2; incr j - - frame $fr.b$j -relief $relief -borderwidth 2 - - global ffont - label $fr.b$j.l -font $ffont -anchor w -text "Examples: '0.75', '1024x768', 'fit' (fill screen), or 'auto' "; - - global ssvnc_scale - frame $fr.b$j.f - label $fr.b$j.f.l -text "Scaling: " - lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled} - entry $fr.b$j.f.e -width 10 -textvariable ssvnc_scale - lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled} - pack $fr.b$j.f.l -side left - pack $fr.b$j.f.e -side right -expand 1 -fill x - - pack $fr.b$j.f $fr.b$j.l -side top -fill x - - incr j - - frame $fr.b$j -height 2; incr j - - frame $fr.b$j -relief $relief -borderwidth 2 - - label $fr.b$j.l -font $ffont -anchor w -text "Examples: 'default', 'Control_L,Alt_L', 'never'"; - - global ssvnc_escape - frame $fr.b$j.f - label $fr.b$j.f.l -text "Escape Keys: " - lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled} - entry $fr.b$j.f.e -width 10 -textvariable ssvnc_escape - lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled} - button $fr.b$j.f.b -relief ridge -text Help -command ssvnc_escape_help - lappend darwinlist $fr.b$j.f.b; if {$darwin_cotvnc} {$fr.b$j.f.b configure -state disabled} - pack $fr.b$j.f.l -side left - pack $fr.b$j.f.b -side right - pack $fr.b$j.f.e -side right -expand 1 -fill x - - pack $fr.b$j.f $fr.b$j.l -side top -fill x - - incr j - - frame $fr.b$j -height 2; incr j - - frame $fr.b$j -relief $relief -borderwidth 2 - - label $fr.b$j.l -font $ffont -anchor w -text "Enter the max height in pixels, e.g. '900'"; - - global ycrop_string - frame $fr.b$j.f - label $fr.b$j.f.l -text "Y Crop: " - lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled} - entry $fr.b$j.f.e -width 10 -textvariable ycrop_string - lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled} - pack $fr.b$j.f.l -side left - pack $fr.b$j.f.e -side right -expand 1 -fill x - - pack $fr.b$j.f $fr.b$j.l -side top -fill x - - incr j - - frame $fr.b$j -height 2; incr j - - frame $fr.b$j -relief $relief -borderwidth 2 - - label $fr.b$j.l -font $ffont -anchor w -text "Enter the scrollbar width in pixels, e.g. '4'"; - - global sbwid_string - frame $fr.b$j.f - label $fr.b$j.f.l -text "ScrollBar Width: " - lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled} - entry $fr.b$j.f.e -width 10 -textvariable sbwid_string - lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled} - pack $fr.b$j.f.l -side left - pack $fr.b$j.f.e -side right -expand 1 -fill x - - pack $fr.b$j.f $fr.b$j.l -side top -fill x - - incr j - - frame $fr.b$j -height 2; incr j - - frame $fr.b$j -relief $relief -borderwidth 2 - - label $fr.b$j.l -font $ffont -anchor w -text "Enter the RFB version to pretend to be using, e.g. '3.4'"; - label $fr.b$j.l2 -font $ffont -anchor w -text "Sometimes needed for UltraVNC: 3.4, 3.6, 3.14, 3.16"; - - global rfbversion - frame $fr.b$j.f - label $fr.b$j.f.l -text "RFB Version: " - lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled} - entry $fr.b$j.f.e -width 10 -textvariable rfbversion - lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled} - pack $fr.b$j.f.l -side left - pack $fr.b$j.f.e -side right -expand 1 -fill x - - pack $fr.b$j.f $fr.b$j.l $fr.b$j.l2 -side top -fill x - - incr j - - frame $fr.b$j -height 2; incr j - - frame $fr.b$j -relief $relief -borderwidth 2 - - label $fr.b$j.l1 -font $ffont -anchor w -text "List encodings in preferred order, for example"; - label $fr.b$j.l2 -font $ffont -anchor w -text "'copyrect zrle tight' The full list of encodings is:"; - label $fr.b$j.l3 -font $ffont -anchor w -text "copyrect tight zrle zywrle hextile zlib corre rre raw"; - - global ssvnc_encodings - frame $fr.b$j.f - label $fr.b$j.f.l -text "Encodings: " - lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled} - entry $fr.b$j.f.e -width 10 -textvariable ssvnc_encodings - lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled} - pack $fr.b$j.f.l -side left - pack $fr.b$j.f.e -side right -expand 1 -fill x - - pack $fr.b$j.f $fr.b$j.l1 $fr.b$j.l2 $fr.b$j.l3 -side top -fill x - - incr j - - frame $fr.b$j -height 2; incr j - - frame $fr.b$j -relief $relief -borderwidth 2 - - label $fr.b$j.l1 -font $ffont -anchor w -text "Add any extra options for ssvncviewer that you want."; - label $fr.b$j.l2 -font $ffont -anchor w -text "For example: -16bpp -appshare -noshm etc. See Help for a list."; - - global ssvnc_extra_opts - frame $fr.b$j.f - label $fr.b$j.f.l -text "Extra Options: " - lappend darwinlist $fr.b$j.f.l; if {$darwin_cotvnc} {$fr.b$j.f.l configure -state disabled} - entry $fr.b$j.f.e -width 10 -textvariable ssvnc_extra_opts - lappend darwinlist $fr.b$j.f.e; if {$darwin_cotvnc} {$fr.b$j.f.e configure -state disabled} - pack $fr.b$j.f.l -side left - pack $fr.b$j.f.e -side right -expand 1 -fill x - - pack $fr.b$j.f $fr.b$j.l1 $fr.b$j.l2 -side top -fill x - - incr j - - frame $fr.b$j -height 2; incr j - - for {set k 1} {$k < $i} {incr k} { - pack $fl.b$k -side top -fill x - } - for {set k 1} {$k < $j} {incr k} { - pack $fr.b$k -side top -fill x - } - - pack $fl -side left -fill both - pack $fr -side left -fill both -expand 1 - - pack $f0 -side top -fill both - - frame .os.b - button .os.b.done -text "Done" -command {destroy .os} - bind .os <Escape> {destroy .os} - wm protocol .os WM_DELETE_WINDOW {destroy .os} - button .os.b.help -text "Help" -command help_ssvncviewer_opts - - global use_listen - if {$use_listen} { - button .os.b.connect -text "Listen" -command launch - } else { - button .os.b.connect -text "Connect" -command launch - } - - pack .os.b.help .os.b.connect .os.b.done -fill x -expand 1 -side left - - pack .os.b -side top -fill x - - global darwin_cotvnc_blist - foreach b $darwinlist { - set darwin_cotvnc_blist($b) 1 - } - - center_win .os - wm resizable .os 1 0 - wm minsize .os [winfo reqwidth .os] [winfo reqheight .os] - focus .os -} - - -proc in_path {cmd} { - global env - set p $env(PATH) - foreach dir [split $p ":"] { - set try "$dir/$cmd" - if [file exists $try] { - return "$try" - } - } - return "" -} - -proc ssh_agent_restart {} { - global env - - set got_ssh_agent 0 - set got_ssh_add 0 - set got_ssh_agent2 0 - set got_ssh_add2 0 - - if {[in_path "ssh-agent"] != ""} {set got_ssh_agent 1} - if {[in_path "ssh-agent2"] != ""} {set got_ssh_agent2 1} - if {[in_path "ssh-add"] != ""} {set got_ssh_add 1} - if {[in_path "ssh-add2"] != ""} {set got_ssh_add2 1} - - set ssh_agent "" - set ssh_add "" - if {[info exists env(USER)] && $env(USER) == "runge"} { - if {$got_ssh_agent2} { - set ssh_agent "ssh-agent2" - } - if {$got_ssh_add2} { - set ssh_add "ssh-add2" - } - } - if {$ssh_agent == "" && $got_ssh_agent} { - set ssh_agent "ssh-agent" - } - if {$ssh_add == "" && $got_ssh_add} { - set ssh_add "ssh-add" - } - if {$ssh_agent == ""} { - bell - mesg "could not find ssh-agent in PATH" - return - } - if {$ssh_add == ""} { - bell - mesg "could not find ssh-add in PATH" - return - } - set tmp $env(SSVNC_HOME)/.vnc-sa[tpid] - set tmp [mytmp $tmp] - set fh "" - catch {set fh [open $tmp "w"]} - if {$fh == ""} { - bell - mesg "could not open tmp file $tmp" - return - } - - puts $fh "#!/bin/sh" - puts $fh "eval `$ssh_agent -s`" - puts $fh "$ssh_add" - puts $fh "SSVNC_GUI_CHILD=\"\"" - puts $fh "export SSVNC_GUI_CHILD" - - global buck_zero - set cmd $buck_zero - - if [info exists env(SSVNC_GUI_CMD)] { - set cmd $env(SSVNC_GUI_CMD) - } - #puts $fh "$cmd </dev/null 1>/dev/null 2>/dev/null &" - puts $fh "nohup $cmd &" - puts $fh "sleep 1" - puts $fh "rm -f $tmp" - close $fh - - wm withdraw . - catch {wm withdraw .o} - catch {wm withdraw .oa} - - unix_terminal_cmd "+200+200" "Restarting with ssh-agent/ssh-add" "sh $tmp" 1 - after 10000 - destroy . - exit -} - -proc putty_pw_entry {mode} { - if {$mode == "check"} { - global use_sshssl use_ssh - if {$use_sshssl || $use_ssh} { - putty_pw_entry enable - } else { - putty_pw_entry disable - } - return - } - if {$mode == "disable"} { - catch {.o.pw.l configure -state disabled} - catch {.o.pw.e configure -state disabled} - } else { - catch {.o.pw.l configure -state normal} - catch {.o.pw.e configure -state normal} - } -} -proc adv_ssh_tog {on} { - global adv_ssh - foreach b {cups snd smb redirs knownhosts} { - if [info exists adv_ssh($b)] { - if {$on} { - catch {$adv_ssh($b) configure -state normal} - } else { - catch {$adv_ssh($b) configure -state disabled} - } - } - } -} - -proc adv_listen_ssl_tog {on} { - global stunnel_local_protection_button is_windows - global disable_ssl_workarounds_button - global vencrypt_button no_probe_vencrypt_button anondh_button ultra_dsm_button - - set blist [list] - if [info exists stunnel_local_protection_button] { - lappend blist $stunnel_local_protection_button - } - if [info exists disable_ssl_workarounds_button] { - lappend blist $disable_ssl_workarounds_button - } - if [info exists ultra_dsm_button] { - lappend blist $ultra_dsm_button - } - if [info exists no_probe_vencrypt_button] { - lappend blist $no_probe_vencrypt_button - } - if [info exists vencrypt_button] { - lappend blist $vencrypt_button - } - if [info exists anondh_button] { - lappend blist $anondh_button - } - foreach b $blist { - if {$on} { - catch {$b configure -state normal} - } else { - catch {$b configure -state disabled} - } - } - - if {$is_windows} { - catch {$stunnel_local_protection_button configure -state disabled} - catch {$ultra_dsm_button configure -state disabled} - } -} - -proc adv_listen_ssh_tog {on} { - global ssh_local_protection_button is_windows - if [info exists ssh_local_protection_button] { - if {$on} { - catch {$ssh_local_protection_button configure -state normal} - } else { - catch {$ssh_local_protection_button configure -state disabled} - } - } - if {$is_windows} { - catch {$ssh_local_protection_button configure -state disabled} - } -} - -proc ssl_ssh_adjust {which} { - global use_ssl use_ssh use_sshssl sshssl_sw - global remote_ssh_cmd_list - global x11vnc_find_widget x11vnc_xlogin_widget uvnc_bug_widget - - if {$which == "ssl"} { - set use_ssl 1 - set use_ssh 0 - set use_sshssl 0 - set sshssl_sw "ssl" - catch {.f4.getcert configure -state normal} - catch {.f4.always configure -state normal} - if [info exists x11vnc_find_widget] { - catch {$x11vnc_find_widget configure -state disabled} - } - if [info exists x11vnc_xlogin_widget] { - catch {$x11vnc_xlogin_widget configure -state disabled} - } - if [info exists uvnc_bug_widget] { - catch {$uvnc_bug_widget configure -state normal} - } - adv_ssh_tog 0 - adv_listen_ssl_tog 1 - adv_listen_ssh_tog 0 - } elseif {$which == "none"} { - set use_ssl 0 - set use_ssh 0 - set use_sshssl 0 - set sshssl_sw "none" - catch {.f4.getcert configure -state disabled} - catch {.f4.always configure -state disabled} - if [info exists x11vnc_find_widget] { - catch {$x11vnc_find_widget configure -state disabled} - } - if [info exists x11vnc_xlogin_widget] { - catch {$x11vnc_xlogin_widget configure -state disabled} - } - if [info exists uvnc_bug_widget] { - catch {$uvnc_bug_widget configure -state normal} - } - adv_ssh_tog 0 - adv_listen_ssl_tog 0 - adv_listen_ssh_tog 0 - } elseif {$which == "ssh"} { - set use_ssl 0 - set use_ssh 1 - set use_sshssl 0 - set sshssl_sw "ssh" - catch {.f4.getcert configure -state disabled} - catch {.f4.always configure -state disabled} - if [info exists x11vnc_find_widget] { - catch {$x11vnc_find_widget configure -state normal} - } - if [info exists x11vnc_xlogin_widget] { - catch {$x11vnc_xlogin_widget configure -state normal} - } - if [info exists uvnc_bug_widget] { - catch {$uvnc_bug_widget configure -state disabled} - } - adv_ssh_tog 1 - adv_listen_ssl_tog 0 - adv_listen_ssh_tog 1 - } elseif {$which == "sshssl"} { - set use_ssl 0 - set use_ssh 0 - set use_sshssl 1 - set sshssl_sw "sshssl" - catch {.f4.getcert configure -state disabled} - catch {.f4.always configure -state disabled} - if [info exists x11vnc_find_widget] { - catch {$x11vnc_find_widget configure -state normal} - } - if [info exists x11vnc_xlogin_widget] { - catch {$x11vnc_xlogin_widget configure -state normal} - } - if [info exists uvnc_bug_widget] { - catch {$uvnc_bug_widget configure -state normal} - } - adv_ssh_tog 1 - adv_listen_ssl_tog 1 - adv_listen_ssh_tog 1 - } - - if [info exists remote_ssh_cmd_list] { - if {$use_ssh || $use_sshssl} { - foreach w $remote_ssh_cmd_list { - $w configure -state normal - } - } - if {$use_ssl || $sshssl_sw == "none"} { - foreach w $remote_ssh_cmd_list { - $w configure -state disabled - } - } - } - - if {! $use_ssl && ! $use_ssh && ! $use_sshssl} { - if {$sshssl_sw != "none"} { - set use_ssl 1 - set sshssl_sw "ssl" - } - } - global ssh_only ts_only - if {$ssh_only || $ts_only} { - set use_ssl 0 - set use_sshssl 0 - set use_ssh 1 - set sshssl_sw "ssh" - } - - putty_pw_entry check -} - -proc listen_adjust {} { - global use_listen revs_button multiple_listen_button is_windows - global listen_once_button listen_accept_popup_button listen_accept_popup_button_sc - if {![info exists multiple_listen_button]} { - set multiple_listen_button "none" - } - if {$use_listen} { - catch {.b.conn configure -text "Listen"} - catch {.o.b.connect configure -text "Listen"} - catch {$multiple_listen_button configure -state normal} - catch {$listen_once_button configure -state normal} - catch {$listen_accept_popup_button configure -state normal} - catch {$listen_accept_popup_button_sc configure -state normal} - catch {mesg "Listen :N -> Port 5500+N, i.e. :0 -> 5500, :1 -> 5501, :2 -> 5502 ..."} - } else { - catch {.b.conn configure -text "Connect"} - catch {.o.b.connect configure -text "Connect"} - catch {$multiple_listen_button configure -state disabled} - catch {$listen_once_button configure -state disabled} - catch {$listen_accept_popup_button configure -state disabled} - catch {$listen_accept_popup_button_sc configure -state disabled} - catch {mesg "Switched to Forward Connection mode."} - } - if {$is_windows} { - catch {$multiple_listen_button configure -state disabled} - catch {$listen_once_button configure -state disabled} - catch {$listen_accept_popup_button configure -state disabled} - catch {$listen_accept_popup_button_sc configure -state disabled} - } -} - -proc unixpw_adjust {} { - global is_windows use_unixpw darwin_cotvnc - if {$is_windows || $darwin_cotvnc} { - return; - } - if {$use_unixpw} { - pack configure .fu -after .f1 -fill x - catch {focus .fu.e} - } else { - pack forget .fu - } -} - -proc x11vnc_find_adjust {which} { - global remote_ssh_cmd - global use_x11vnc_find x11vnc_find_widget - global use_x11vnc_xlogin x11vnc_xlogin_widget - - if {$which == "find"} { - if {$use_x11vnc_find} { - set use_x11vnc_xlogin 0 - } - } elseif {$which == "xlogin"} { - if {$use_x11vnc_xlogin} { - set use_x11vnc_find 0 - } - } - if {! $use_x11vnc_find && ! $use_x11vnc_xlogin} { - set remote_ssh_cmd ""; - return - } - if {![regexp {x11vnc} $remote_ssh_cmd]} { - set remote_ssh_cmd ""; - } - regsub {^[ ]*PORT= [ ]*} $remote_ssh_cmd "" remote_ssh_cmd - regsub {^[ ]*P= [ ]*} $remote_ssh_cmd "" remote_ssh_cmd - regsub {^[ ]*sudo x11vnc[ ]*} $remote_ssh_cmd "" remote_ssh_cmd - regsub {^[ ]*x11vnc[ ]*} $remote_ssh_cmd "" remote_ssh_cmd - regsub -all {[ ]*-find[ ]*} $remote_ssh_cmd " " remote_ssh_cmd - regsub -all {[ ]*-localhost[ ]*} $remote_ssh_cmd " " remote_ssh_cmd - regsub -all {[ ]*-env FD_XDM=1[ ]*} $remote_ssh_cmd " " remote_ssh_cmd - if {$use_x11vnc_find} { - set remote_ssh_cmd "PORT= x11vnc -find -localhost -nopw $remote_ssh_cmd" - } else { - set remote_ssh_cmd "PORT= sudo x11vnc -find -localhost -env FD_XDM=1 -nopw $remote_ssh_cmd" - } - regsub {[ ]*$} $remote_ssh_cmd "" remote_ssh_cmd - regsub {^[ ]*} $remote_ssh_cmd "" remote_ssh_cmd - regsub -all {[ ][ ]*} $remote_ssh_cmd " " remote_ssh_cmd -} - -proc set_darwin_cotvnc_buttons {} { - global darwin_cotvnc uname darwin_cotvnc_blist - - if {$uname == "Darwin" && [info exists darwin_cotvnc_blist]} { - foreach b [array names darwin_cotvnc_blist] { - if {$darwin_cotvnc} { - catch {$b configure -state disabled} - } else { - catch {$b configure -state normal} - } - } - } -} - -proc disable_encryption {} { - global env - if {[info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} { - set s $env(SSVNC_DISABLE_ENCRYPTION_BUTTON) - if {$s != "" && $s != "0"} { - return 1; - } - } - return 0; -} -proc set_options {} { - global use_alpha use_grab use_ssh use_sshssl use_viewonly use_fullscreen use_bgr233 - global use_nojpeg use_raise_on_beep use_compresslevel use_quality use_x11_macosx - global use_send_clipboard use_send_always - global compresslevel_text quality_text - global env is_windows darwin_cotvnc uname - global use_listen - global use_x11vnc_find x11vnc_find_widget - global use_x11vnc_xlogin x11vnc_xlogin_widget uvnc_bug_widget - global ts_only - global darwin_cotvnc_blist - global showing_no_encryption no_enc_button no_enc_prev - - if {$ts_only} { - set_ts_options - return - } - - toplev .o - wm title .o "SSL/SSH VNC Options" - - set i 1 - - radiobutton .o.b$i -anchor w -variable sshssl_sw -value ssl -text \ - "Use SSL" -command {ssl_ssh_adjust ssl} - incr i - - radiobutton .o.b$i -anchor w -variable sshssl_sw -value ssh -text \ - "Use SSH" -command {ssl_ssh_adjust ssh} - incr i - - radiobutton .o.b$i -anchor w -variable sshssl_sw -value sshssl -text \ - "Use SSH+SSL" -command {ssl_ssh_adjust sshssl} - set iss $i - set no_enc_prev .o.b$i - incr i - - radiobutton .o.b$i -anchor w -variable sshssl_sw -value none -text \ - "No Encryption" -command {ssl_ssh_adjust none} - set no_enc_button .o.b$i - set ine $i - incr i - - checkbutton .o.b$i -anchor w -variable use_x11vnc_find -text \ - "Automatically Find X Session" -command {x11vnc_find_adjust "find"} - if {!$use_ssh && !$use_sshssl} {.o.b$i configure -state disabled} - set x11vnc_find_widget ".o.b$i" - incr i - - if {! $is_windows} { - checkbutton .o.b$i -anchor w -variable use_unixpw -text \ - "Unix Username & Password" -command {unixpw_adjust} - if {$darwin_cotvnc} {.o.b$i configure -state disabled} - set darwin_cotvnc_blist(.o.b$i) 1 - incr i - } - - checkbutton .o.b$i -anchor w -variable use_listen -text \ - "Reverse VNC Connection (-LISTEN)" -command {listen_adjust; if {$vncdisplay == ""} {set vncdisplay ":0"} else {set vncdisplay ""}; if {0 && $use_listen} {destroy .o}} - #if {$is_windows} {.o.b$i configure -state disabled} - #if {$darwin_cotvnc} {.o.b$i configure -state disabled} - #set darwin_cotvnc_blist(.o.b$i) 1 - incr i - - checkbutton .o.b$i -anchor w -variable use_viewonly -text \ - "View Only" - incr i - - checkbutton .o.b$i -anchor w -variable use_fullscreen -text \ - "Fullscreen" - incr i - - checkbutton .o.b$i -anchor w -variable use_raise_on_beep -text \ - "Raise On Beep" - if {$darwin_cotvnc} {.o.b$i configure -state disabled} - set darwin_cotvnc_blist(.o.b$i) 1 - incr i - - checkbutton .o.b$i -anchor w -variable use_bgr233 -text \ - "Use 8bit color (-bgr233)" - if {$darwin_cotvnc} {.o.b$i configure -state disabled} - set darwin_cotvnc_blist(.o.b$i) 1 - incr i - - checkbutton .o.b$i -anchor w -variable use_nojpeg -text \ - "Do not use JPEG (-nojpeg)" - if {$darwin_cotvnc} {.o.b$i configure -state disabled} - set darwin_cotvnc_blist(.o.b$i) 1 - incr i - - if {$uname == "Darwin"} { - checkbutton .o.b$i -anchor w -variable use_x11_macosx -text \ - "Use X11 vncviewer on MacOSX" \ - -command {if {$use_x11_macosx} {set darwin_cotvnc 0} else {set darwin_cotvnc 1}; set_darwin_cotvnc_buttons} - if {$uname != "Darwin"} {.o.b$i configure -state disabled} - incr i - } - - if {$is_windows} { - global kill_stunnel - checkbutton .o.b$i -anchor w -variable kill_stunnel -text \ - "Kill Stunnel Automatically" - incr i - } - - - menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable compresslevel_text -relief groove - set compresslevel_text "Compress Level: $use_compresslevel" - if {$darwin_cotvnc} {.o.b$i configure -state disabled} - set darwin_cotvnc_blist(.o.b$i) 1 - - menu .o.b$i.m -tearoff 0 - for {set j -1} {$j < 10} {incr j} { - set v $j - set l $j - if {$j == -1} { - set v "default" - set l "default" - } - .o.b$i.m add radiobutton -variable use_compresslevel \ - -value $v -label $l -command \ - {set compresslevel_text "Compress Level: $use_compresslevel"} - } - incr i - - menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable quality_text -relief groove - set quality_text "Quality: $use_quality" - if {$darwin_cotvnc} {.o.b$i configure -state disabled} - set darwin_cotvnc_blist(.o.b$i) 1 - - menu .o.b$i.m -tearoff 0 - for {set j -1} {$j < 10} {incr j} { - set v $j - set l $j - if {$j == -1} { - set v "default" - set l "default" - } - .o.b$i.m add radiobutton -variable use_quality \ - -value $v -label $l -command \ - {set quality_text "Quality: $use_quality"} - } - incr i - - global use_mode ts_only ssh_only - if {$ts_only} { - set use_mode "Terminal Services (tsvnc)" - } elseif {$ssh_only} { - set use_mode "SSH-Only (sshvnc)" - } else { - set use_mode "SSVNC" - } - global mode_text - set mode_text "Mode: $use_mode" - - menubutton .o.b$i -anchor w -menu .o.b$i.m -textvariable mode_text -relief groove - - menu .o.b$i.m -tearoff 0 - .o.b$i.m add radiobutton -variable use_mode -value "SSVNC" \ - -label "SSVNC" -command { if {$ts_only || $ssh_only} {to_ssvnc; set mode_text "Mode: SSVNC"; destroy .o}} - .o.b$i.m add radiobutton -variable use_mode -value "SSH-Only (sshvnc)" \ - -label "SSH-Only (sshvnc)" -command { if {$ts_only || ! $ssh_only} {to_sshonly; set mode_text "Mode: SSH-Only (sshvnc)"; destroy .o}} - .o.b$i.m add radiobutton -variable use_mode -value "Terminal Services (tsvnc)" \ - -label "Terminal Services (tsvnc)" -command {to_tsonly; set mode_text "Mode: Terminal Services (tsvnc)"; destroy .o} - incr i - - global started_with_noenc - - if {0 && $started_with_noenc && $showing_no_encryption} { - ; - } elseif {$ssh_only} { - ; - } else { - checkbutton .o.b$i -anchor w -variable showing_no_encryption -text \ - "Show 'No Encryption' Option" -pady 5 \ - -command {toggle_no_encryption 1} - # -relief raised - incr i - } - - for {set j 1} {$j < $i} {incr j} { - global ssh_only ts_only - if {$ssh_only && $j <= 3} { - continue; - } - if {$ts_only && $j <= 3} { - continue; - } - if {!$showing_no_encryption && $j == $ine} { - continue; - } - - pack .o.b$j -side top -fill x - } - - if {$is_windows} { - global port_slot putty_pw - - frame .o.pp - frame .o.pp.fL - frame .o.pp.fR - label .o.pp.fL.la -anchor w -text "Putty PW:" - label .o.pp.fL.lb -anchor w -text "Port Slot:" - pack .o.pp.fL.la .o.pp.fL.lb -side top -fill x - - entry .o.pp.fR.ea -width 10 -show * -textvariable putty_pw - entry .o.pp.fR.eb -width 10 -textvariable port_slot - pack .o.pp.fR.ea .o.pp.fR.eb -side top -fill x - - pack .o.pp.fL -side left - pack .o.pp.fR -side right -expand 1 -fill x - - pack .o.pp -side top -fill x - - putty_pw_entry check - } - - global uname - set t1 " Advanced ..." - set t2 " Use Defaults" - set t3 " Delete Profile ..." - if {$uname == "Darwin"} { - regsub {^ *} $t1 "" t1 - regsub {^ *} $t2 "" t2 - regsub {^ *} $t3 "" t3 - } - - button .o.advanced -anchor w -text $t1 -command set_advanced_options - button .o.clear -anchor w -text $t2 -command {set_defaults; init_vncdisplay} - button .o.delete -anchor w -text $t3 -command {destroy .o; delete_profile} - - pack .o.clear -side top -fill x - pack .o.delete -side top -fill x - pack .o.advanced -side top -fill x - -# pack .o.s_prof -side top -fill x -# pack .o.l_prof -side top -fill x - - frame .o.b - button .o.b.done -text "Done" -command {destroy .o} - bind .o <Escape> {destroy .o} - wm protocol .o WM_DELETE_WINDOW {destroy .o} - button .o.b.help -text "Help" -command help_opts - global use_listen - if {$use_listen} { - button .o.b.connect -text "Listen" -command launch - } else { - button .o.b.connect -text "Connect" -command launch - } - - pack .o.b.help .o.b.connect .o.b.done -fill x -expand 1 -side left - - pack .o.b -side top -fill x - - center_win .o - wm resizable .o 1 0 - focus .o -} - -proc check_writable {} { - set test test[pid].txt - catch {set f [open $test "w"]; puts $f "test"; close $f} - - ###catch {file delete -force $test} # testing. - - if ![file exists $test] { - global env - if [info exists env(SSVNC_HOME)] { - set dir "$env(SSVNC_HOME)/ss_vnc/cache" - catch {file mkdir $dir} - if ![file exists $dir] { - return - } - foreach f [glob -type f * */* */*/*] { - set dest "$dir/$f" - set dirn [file dirname $dest] - catch {file mkdir $dirn} - catch {file copy -force -- $f $dest} - } - cd $dir - ###catch {set f [open $test "w"]; puts $f "test"; close $f} - } - } else { - catch {file delete -force $test} - } -} - -proc print_help {} { - - global help_main help_prox help_misc help_tips - set b "\n============================================================================\n" - help - #set str [.h.f.t get 1.0 end] - #puts "${b}Help:\n$str" - puts "${b}Help Main:\n$help_main" - puts "${b}Help Proxies:\n$help_prox" - puts "${b}Help Misc:\n$help_misc" - puts "${b}Help Tips:\n$help_tips" - destroy .h - - help_opts - set str [.oh.f.t get 1.0 end] - puts "${b}SSL/SSH Viewer Options Help:\n$str" - destroy .oh - - help_advanced_opts - set str [.ah.f.t get 1.0 end] - puts "${b}Advanced Options Help:\n$str" - destroy .ah - - help_ssvncviewer_opts - set str [.av.f.t get 1.0 end] - puts "${b}ssvncviewer Options Help:\n$str" - destroy .av - - help_certs - set str [.ch.f.t get 1.0 end] - puts "${b}SSL Certificates Help:\n$str" - destroy .ch - - help_fetch_cert - set str [.fh.f.t get 1.0 end] - puts "${b}Fetch Certificates Help:\n$str" - destroy .fh - - create_cert - set str [.ccrt.f.t get 1.0 end] - puts "${b}Create SSL Certificate Dialog:\n$str" - destroy .ccrt - - import_cert - set str [.icrt.f.t get 1.0 end] - puts "${b}Import SSL Certificate Dialog:\n$str" - destroy .icrt - - global cert_text - set cert_text "empty" - save_cert "help:0" - set str [.scrt.f.t get 1.0 end] - puts "${b}Save SSL Certificate Dialog:\n$str" - destroy .scrt - - ts_help - set str [.h.f.t get 1.0 end] - puts "${b}Terminal Services Help:\n$str" - destroy .h - - help_ts_opts - set str [.oh.f.t get 1.0 end] - puts "${b}Terminal Services VNC Options Help:\n$str" - destroy .oh - - ts_unixpw_dialog - set str [.uxpw.f.t get 1.0 end] - puts "${b}Terminal Services Use unixpw Dialog:\n$str" - destroy .uxpw - - ts_vncshared_dialog - set str [.vncs.f.t get 1.0 end] - puts "${b}Terminal Services VNC Shared Dialog:\n$str" - destroy .vncs - - ts_multi_dialog - set str [.mult.f.t get 1.0 end] - puts "${b}Terminal Services Multiple Sessions Dialog:\n$str" - destroy .mult - - ts_xlogin_dialog - set str [.xlog.f.t get 1.0 end] - puts "${b}Terminal Services X Login Dialog:\n$str" - destroy .xlog - - ts_othervnc_dialog - set str [.ovnc.f.t get 1.0 end] - puts "${b}Terminal Services Other VNC Server Dialog:\n$str" - destroy .ovnc - - ts_ncache_dialog - set str [.nche.f.t get 1.0 end] - puts "${b}Terminal Services Client-Side Caching Dialog:\n$str" - destroy .nche - - ts_x11vnc_opts_dialog - set str [.x11v.f.t get 1.0 end] - puts "${b}Terminal Services x11vnc Options Dialog:\n$str" - destroy .x11v - - ts_filexfer_dialog - set str [.xfer.f.t get 1.0 end] - puts "${b}Terminal Services File Transfer Dialog:\n$str" - destroy .xfer - - ts_sound_dialog - set str [.snd.f.t get 1.0 end] - puts "${b}Terminal Services Sound Tunnelling Dialog:\n$str" - destroy .snd - - ts_cups_dialog - set str [.cups.f.t get 1.0 end] - puts "${b}Terminal Services CUPS Dialog:\n$str" - destroy .cups - - help_ssvncviewer_opts - set str [.av.f.t get 1.0 end] - puts "${b}Unix SSVNC viewer Options Help:\n$str" - destroy .av - - change_vncviewer_dialog - set str [.chviewer.t get 1.0 end] - puts "${b}Unix Change VNC Viewer Dialog:\n$str" - destroy .chviewer - - cups_dialog - set str [.cups.f.t get 1.0 end] - puts "${b}CUPS Dialog:\n$str" - destroy .cups - - sound_dialog - set str [.snd.f.t get 1.0 end] - puts "${b}ESD Audio Tunnelling Dialog:\n$str" - destroy .snd - - smb_dialog - set str [.smb.f.t get 1.0 end] - puts "${b}SMB Mounting Dialog:\n$str" - destroy .smb - - port_redir_dialog - set str [.redirs.t get 1.0 end] - puts "${b}Additional Port Redirections Dialog:\n$str" - destroy .redirs - - port_knocking_dialog - set str [.pk.f.t get 1.0 end] - puts "${b}Port Knocking Dialog:\n$str" - destroy .pk - - ssvnc_escape_help - set str [.ekh.f.t get 1.0 end] - puts "${b}SSVNC Escape Keys Help:\n$str" - destroy .ekh - - stunnel_sec_dialog - set str [.stlsec.f.t get 1.0 end] - puts "${b}STUNNEL Local Port Protections Dialog:\n$str" - destroy .stlsec - - disable_ssl_workarounds_dialog - set str [.sslwrk.f.t get 1.0 end] - puts "${b}Disable SSL Workarounds Dialog:\n$str" - destroy .sslwrk - - ultra_dsm_dialog - set str [.ultradsm.f.t get 1.0 end] - puts "${b}UltraVNC DSM Encryption Plugin Dialog:\n$str" - destroy .ultradsm - - ssh_known_hosts_dialog - set str [.sshknownhosts.f.t get 1.0 end] - puts "${b}Private SSH KnownHosts file Dialog:\n$str" - destroy .sshknownhosts - - ssh_sec_dialog - set str [.sshsec.t get 1.0 end] - puts "${b}SSH Local Port Protections Dialog:\n$str" - destroy .sshsec - - multilisten_dialog - set str [.multil.t get 1.0 end] - puts "${b}Multiple LISTEN Connections Dialog:\n$str" - destroy .multil - - use_grab_dialog - set str [.usegrb.t get 1.0 end] - puts "${b}Use XGrabServer (for fullscreen) Dialog:\n$str" - destroy .usegrb -} - -proc zeroconf_fill {b m} { - global is_windows zeroconf_command last_post - - if {$is_windows} { - return; - } - - if {![info exists last_post]} { - set last_post 0 - } - set now [clock seconds] - if {$now < [expr $last_post + 10]} { - # cache menu for 10 secs. - return - } - - . config -cursor {watch} - $b config -cursor {watch} - $b configure -state disabled - - $m delete 0 end - update - - set emsg "" - set output "" - set none "No VNC servers detected" - - set rc 1 - set rd 0 - if {$zeroconf_command == "avahi-browse"} { - set rc [catch {set output [exec avahi-browse -r -t -p -k _rfb._tcp 2>/dev/null]} emsg] - } elseif {$zeroconf_command == "dns-sd"} { - set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec dns-sd -B _rfb._tcp} 2>/dev/null]} emsg] - set rd 1 - } elseif {$zeroconf_command == "mDNS"} { - set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec mDNS -B _rfb._tcp} 2>/dev/null]} emsg] - set rd 1 - } - - #puts "rc=$rc output=$output" - if {$rd == 1 && $rc != 0} { - if [regexp {_rfb} $emsg] { - set rc 0 - set output $emsg - } - } - - set count 0 - - if {$rc != 0} { - $m add command -label $none - incr count - - } elseif {$output == "" || [regexp {^[ \t\n]*$} $output]} { - $m add command -label $none - incr count - - } elseif {$zeroconf_command == "avahi-browse"} { - set lines [split $output "\n"] - set saw("__none__") 1 - foreach line $lines { - set items [split $line ";"] - if {[llength $items] != 10} { - continue - } - if {[lindex $items 0] != "="} { - continue - } - - # =;eth0;IPv4;tmp2\0582;_rfb._tcp;local;tmp2.local;10.0.2.252;5902; - set eth [lindex $items 1] - set ipv [lindex $items 2] - set name [lindex $items 3] - set type [lindex $items 4] - set loc [lindex $items 5] - set host [lindex $items 6] - set ip [lindex $items 7] - set port [lindex $items 8] - - if {![regexp -nocase {ipv4} $ipv]} { - continue - } - - set name0 $name - regsub -all {\\\\} $name "__bockslosh__" name - regsub -all {\\\.} $name "." name - - set n 0 - while {1} { - incr n - if {$n > 100} { - break - } - if {[regexp {\\[0-9][0-9][0-9]} $name match]} { - #puts "match1=$match" - regsub {\\} $match "" match - set d $match - regsub {^0*} $d "" d - set c [format "%c" $d] - if {"$c" == "&"} { - set c "\\$c" - } - regsub "\\\\$match" $name $c name - #puts "match: $match c='$c'\nname=$name" - } else { - break - } - } - - regsub -all {__bockslosh__} $name "\\" name - - set hp $host - if {$port >= 5900 && $port <= 6100} { - set d [expr $port - 5900] - set hp "$host:$d" - } else { - set hp "$host:$port" - } - if {![info exists saw($name)]} { - regsub -all {[^[:alnum:],./:@%_=+-]} $hp "" hp - $m add command -label "$name - $hp" -command "set vncdisplay \"$hp\"" - incr count - set p $port - if {$p <= 200} { - set p "-$port" - } - regsub -all {[^[:alnum:],./:@%_=+-]} "$ip:$p" "" ipp - $m add command -label "$name - $ipp" -command "set vncdisplay \"$ipp\"" - incr count - set saw($name) 1 - } - } - } else { - set lines [split $output "\n"] - set saw("__none__") 1 - global dns_sd_cache last_dns_sd - if {![info exists last_dns_sd]} { - set last_dns_sd 0 - } - if {[clock seconds] > [expr $last_dns_sd + 1800]} { - catch { unset dns_sd_cache } - set last_dns_sd [clock seconds] - } - foreach line $lines { - if [regexp -nocase {^Browsing} $line] { - continue; - } - if [regexp -nocase {^Timestamp} $line] { - continue; - } - if [regexp -nocase {killed:} $line] { - continue; - } - if {![regexp {_rfb\._tcp} $line]} { - continue; - } - regsub {[ \t\n]*$} $line "" line - regsub {^.*_rfb\._tcp[^ ]* *} $line "" name - - if {[info exists saw($name)]} { - continue - } - set saw($name) 1 - - set hp "$name" - if {[info exists dns_sd_cache($name)]} { - set hp $dns_sd_cache($name) - } else { - global env - regsub -all {"} $name "" name2 - set env(DNS_SD_LU) $name2 - set emsg "" - if {$zeroconf_command == "dns-sd"} { - set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec dns-sd -L "$DNS_SD_LU" _rfb._tcp .} 2>/dev/null]} emsg] - } elseif {$zeroconf_command == "mDNS"} { - set rc [catch {set output [exec /bin/sh -c {pid=$$; export pid; (sleep 1; kill $pid) & exec mDNS -L "$DNS_SD_LU" _rfb._tcp .} 2>/dev/null]} emsg] - regsub -all {[ \t][ \t]*:} $emsg ":" emsg - } - regsub -all { *} $emsg " " emsg - if [regexp -nocase {be reached at *([^ \t\n][^ \t\n]*)} $emsg match hpm] { - if [regexp {^(.*):([0-9][0-9]*)$} $hpm mv hm pm] { - if {$pm >= 5900 && $pm <= 6100} { - set pm [expr $pm - 5900] - } - set hp "$hm:$pm" - } else { - set hp $hpm - } - set dns_sd_cache($name) $hp - } else { - set hp "$name" - if {![regexp {:[0-9][0-9]*$} $hp]} { - set hp "$name:0" - } - } - } - regsub -all {[^[:alnum:],./:@%_=+-]} $hp "" hp - $m add command -label "$name - $hp" -command "set vncdisplay \"$hp\"" - incr count - } - } - $b configure -state normal - . config -cursor {} - $b config -cursor {} - if {$count == 0} { - $m add command -label $none - } - set last_post [clock seconds] -} - -proc check_zeroconf_browse {} { - global is_windows zeroconf_command - - set zeroconf_command "" - if {$is_windows} { - return 0; - } - set p "" - set r [catch {set p [exec /bin/sh -c {type avahi-browse}]}] - if {$r == 0} { - regsub {^.* is *} $p "" p - regsub -all {[ \t\n\r]} $p "" p - if [file exists $p] { - set zeroconf_command "avahi-browse" - return 1 - } - } - set p "" - set r [catch {set p [exec /bin/sh -c {type dns-sd}]}] - if {$r == 0} { - regsub {^.* is *} $p "" p - regsub -all {[ \t\n\r]} $p "" p - if [file exists $p] { - set zeroconf_command "dns-sd" - global env - if [info exists env(USE_MDNS)] { - # testing - set zeroconf_command "mDNS" - } - return 1 - } - } - set p "" - set r [catch {set p [exec /bin/sh -c {type mDNS}]}] - if {$r == 0} { - regsub {^.* is *} $p "" p - regsub -all {[ \t\n\r]} $p "" p - if [file exists $p] { - set zeroconf_command "mDNS" - return 1 - } - } - return 0 -} - -proc toggle_no_encryption {{rev 0}} { - global showing_no_encryption - global no_enc_button no_enc_prev - global ts_only ssh_only - global use_ssl use_ssh use_sshssl - - if {$rev} { - # reverse it first - if {$showing_no_encryption} { - set showing_no_encryption 0 - } else { - set showing_no_encryption 1 - } - } - - if {$showing_no_encryption} { - catch {pack forget .f4.none} - catch {pack forget $no_enc_button} - if {!$use_ssl && !$use_ssh && !$use_sshssl} { - set use_ssl 1 - sync_use_ssl_ssh - } - set showing_no_encryption 0 - } else { - if {$ts_only || $ssh_only} { - return - } - catch {pack .f4.none -side left} - if {![info exists no_enc_button]} { - catch {destroy .o} - } elseif {![winfo exists $no_enc_button]} { - catch {destroy .o} - } else { - catch {pack $no_enc_button -after $no_enc_prev -fill x} - } - set showing_no_encryption 1 - } -} - -proc toggle_vnc_prefix {} { - global vncdisplay - if [regexp -nocase {^vnc://} $vncdisplay] { - regsub -nocase {^vnc://} $vncdisplay "" vncdisplay - } else { - regsub -nocase {^[a-z0-9+]*://} $vncdisplay "" vncdisplay - set vncdisplay "Vnc://$vncdisplay" - } - catch {.f0.e icursor end} -} - -############################################ - -global env - -if {[regexp -nocase {Windows.9} $tcl_platform(os)]} { - set is_win9x 1 -} else { - set is_win9x 0 -} - -set is_windows 0 -if { [regexp -nocase {Windows} $tcl_platform(os)]} { - set is_windows 1 -} - -set uname "" -if {! $is_windows} { - catch {set uname [exec uname]} -} - -set ffont "fixed" - -global have_ipv6 -set have_ipv6 "" -check_for_ipv6 - -# need to check if "fixed" font under XFT on tk8.5 is actually fixed width!! -if {$tcl_platform(platform) == "unix"} { - set ls "" - catch {set ls [font metrics $ffont -linespace]} - set fs "" - catch {set fs [font metrics $ffont -fixed]} - set redo 0 - if {$fs != "" && $fs != "1"} { - set redo 1 - } - if {$ls != "" && $ls > 14} { - set redo 1 - } - if {$redo} { - foreach fn [font names] { - if {$fn == "TkFixedFont"} { - set ffont $fn - break - } - } - } - catch {option add *Dialog.msg.font {helvetica -14 bold}} - catch {option add *Dialog.msg.wrapLength 4i} -} - -if {$uname == "Darwin"} { - set ffont "Monaco 10" - - #option add *Button.font Helvetica widgetDefault - catch {option add *Button.font {System 10} widgetDefault} -} - -# set SSVNC_HOME to HOME in case we modify it for mobile use: -if [info exists env(HOME)] { - if {! [info exists env(SSVNC_HOME)]} { - set env(SSVNC_HOME) $env(HOME) - } -} - -# For mobile use, e.g. from a USB flash drive, we look for a "home" or "Home" -# directory relative to this script where the profiles and certs will be kept -# by default. -if [file exists $buck_zero] { - #puts "$buck_zero" - set up [file dirname $buck_zero] - - if {$up == "."} { - # this is actually bad news on windows because we cd'd to util. - set up ".." - } else { - set up [file dirname $up] - } - set dirs [list $up] - - if {! $is_windows && $up != ".."} { - # get rid of bin - set up [file dirname $up] - lappend dirs $up - } - - for {set i 0} {$i < $argc} {incr i} { - set it0 [lindex $argv $i] - if {$it0 == "."} { - if {![file isdirectory "$up/home"] && ![file isdirectory "$up/Home"]} { - catch {file mkdir "$up/Home"} - } - break - } - } - - set gotone 0 - - foreach d $dirs { - set try "$d/home" - #puts "$try" - if [file isdirectory $try] { - set env(SSVNC_HOME) $try - set gotone 1 - break - } - set try "$d/Home" - #puts "$try" - if [file isdirectory $try] { - set env(SSVNC_HOME) $try - set gotone 1 - break - } - } - if {$gotone} { - set b "" - if {$is_windows} { - set b "$env(SSVNC_HOME)/ss_vnc" - } else { - set b "$env(SSVNC_HOME)/.vnc" - } - catch {file mkdir $b} - catch {file mkdir "$b/certs"} - catch {file mkdir "$b/profiles"} - } - #puts "HOME: $env(SSVNC_HOME)" -} - -global svcert_default mycert_default crlfil_default -global svcert_default_force mycert_default_force crlfil_default_force -set svcert_default "" -set mycert_default "" -set crlfil_default "" -set svcert_default_force 0 -set mycert_default_force 0 -set crlfil_default_force 0 - -set saw_ts_only 0 -set saw_ssh_only 0 - -set ssvncrc $env(SSVNC_HOME)/.ssvncrc -if {$is_windows} { - set ssvncrc $env(SSVNC_HOME)/ssvnc_rc -} - -global ts_desktop_size_def ts_desktop_depth_def ts_desktop_type_def ts_xserver_type_def -set ts_desktop_size_def "" -set ts_desktop_depth_def "" -set ts_desktop_type_def "" -set ts_xserver_type_def "" - -global win_localhost -set win_localhost "127.0.0.1" - -global kill_stunnel -set kill_stunnel 1 - -global started_with_noenc - -if {! [info exists env(SSVNC_DISABLE_ENCRYPTION_BUTTON)]} { - set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1 - set started_with_noenc 1 -} else { - if {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "0"} { - set started_with_noenc 0 - } elseif {$env(SSVNC_DISABLE_ENCRYPTION_BUTTON) == "1"} { - set started_with_noenc 1 - } else { - set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1 - set started_with_noenc 1 - } -} - -if [file exists $ssvncrc] { - set fh "" - catch {set fh [open $ssvncrc "r"]} - if {$fh != ""} { - while {[gets $fh line] > -1} { - set str [string trim $line] - if [regexp {^#} $str] { - continue - } - if [regexp {^mode=tsvnc} $str] { - set saw_ts_only 1 - set saw_ssh_only 0 - } elseif [regexp {^mode=sshvnc} $str] { - set saw_ts_only 0 - set saw_ssh_only 1 - } elseif [regexp {^mode=ssvnc} $str] { - set saw_ts_only 0 - set saw_ssh_only 0 - } - if [regexp {^desktop_type=(.*)$} $str m val] { - set val [string trim $val] - set ts_desktop_type_def $val - } - if [regexp {^desktop_size=(.*)$} $str m val] { - set val [string trim $val] - set ts_desktop_size_def $val - } - if [regexp {^desktop_depth=(.*)$} $str m val] { - set val [string trim $val] - set ts_desktop_depth_def $val - } - if [regexp {^xserver_type=(.*)$} $str m val] { - set val [string trim $val] - set ts_xserver_type_def $val - } - if [regexp {^font_default=(.*)$} $str m val] { - set val [string trim $val] - catch {option add *font $val} - catch {option add *Dialog.msg.font $val} - } - if [regexp {^font_fixed=(.*)$} $str m val] { - set val [string trim $val] - set ffont $val - } - if [regexp {^noenc=1} $str] { - global env - set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1 - set started_with_noenc 1 - } - if [regexp {^noenc=0} $str] { - global env - set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0 - set started_with_noenc 0 - } - if [regexp {^cotvnc=1} $str] { - global env - set env(SSVNC_COTVNC) 1 - } - if [regexp {^cotvnc=0} $str] { - global env - set env(SSVNC_COTVNC) 0 - } - if [regexp {^killstunnel=1} $str] { - set kill_stunnel 1 - } - if [regexp {^killstunnel=0} $str] { - set kill_stunnel 0 - } - global have_ipv6 - if [regexp {^ipv6=1} $str] { - set have_ipv6 1 - set env(SSVNC_IPV6) 1 - } - if [regexp {^ipv6=0} $str] { - set have_ipv6 0 - set env(SSVNC_IPV6) 0 - } - if [regexp {^mycert=(.*)$} $str m val] { - set val [string trim $val] - set mycert_default $val - } - if [regexp {^cert=(.*)$} $str m val] { - set val [string trim $val] - set mycert_default $val - } - if [regexp {^cacert=(.*)$} $str m val] { - set val [string trim $val] - set svcert_default $val - } - if [regexp {^ca=(.*)$} $str m val] { - set val [string trim $val] - set svcert_default $val - } - if [regexp {^crl=(.*)$} $str m val] { - set val [string trim $val] - set crlfil_default $val - } - if [regexp {^env=([^=]*)=(.*)$} $str m var val] { - global env - set env($var) $val - } - } - close $fh - } -} - -for {set i 0} {$i < $argc} {incr i} { - set item [lindex $argv $i] - regsub {^--} $item "-" item - if {$item == "-profiles" || $item == "-list"} { - set dir [get_profiles_dir] - #puts stderr "VNC Profiles:" - #puts stderr " " - if {[info exists env(SSVNC_TS_ONLY)]} { - set saw_ts_only 1 - } elseif {[info exists env(SSVNC_SSH_ONLY)]} { - set saw_ssh_only 1 - } - set profs [list] - foreach prof [glob -nocomplain -directory $dir "*.vnc"] { - set s [file tail $prof] - regsub {\.vnc$} $s "" s - if {$saw_ts_only || $saw_ssh_only} { - set ok 0; - set tsok 0; - set fh "" - catch {set fh [open $prof "r"]} - if {$fh != ""} { - while {[gets $fh line] > -1} { - if {[regexp {use_ssh=1} $line]} { - set ok 1 - } - if {[regexp {ts_mode=1} $line]} { - set tsok 1 - } - } - close $fh - } - if {$saw_ts_only && !$tsok} { - continue; - } elseif {! $ok} { - continue - } - } - lappend profs $s - } - foreach prof [lsort $profs] { - puts "$prof" - } - exit - } elseif {$item == "-nvb"} { - global env - set env(SSVNC_NO_VERIFY_ALL_BUTTON) 1 - } elseif {$item == "-noenc"} { - global env - set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 1 - set started_with_noenc 1 - } elseif {$item == "-enc"} { - global env - set env(SSVNC_DISABLE_ENCRYPTION_BUTTON) 0 - } elseif {$item == "-bigger"} { - global env - if {![info exists env(SSVNC_BIGGER_DIALOG)]} { - set env(SSVNC_BIGGER_DIALOG) 1 - } - } elseif {$item == "-ssh"} { - set saw_ssh_only 1 - set saw_ts_only 0 - } elseif {$item == "-ts"} { - set saw_ts_only 1 - set saw_ssh_only 0 - } elseif {$item == "-ssl" || $item == "-ss"} { - set saw_ts_only 0 - set saw_ssh_only 0 - } elseif {$item == "-tso"} { - global env - set env(SSVNC_TS_ALWAYS) 1 - set saw_ts_only 1 - } elseif {$item == "-killstunnel"} { - set kill_stunnel 1 - } elseif {$item == "-nokillstunnel"} { - set kill_stunnel 0 - } elseif {$item == "-mycert" || $item == "-cert"} { - incr i - set mycert_default [lindex $argv $i] - } elseif {$item == "-cacert" || $item == "-ca"} { - incr i - set svcert_default [lindex $argv $i] - } elseif {$item == "-crl"} { - incr i - set crlfil_default [lindex $argv $i] - } -} - -if [info exists env(SSVNC_FONT_FIXED)] { - set ffont $env(SSVNC_FONT_FIXED) -} - -if [info exists env(SSVNC_FONT_DEFAULT)] { - catch {option add *font $env(SSVNC_FONT_DEFAULT)} - catch {option add *Dialog.msg.font $env(SSVNC_FONT_DEFAULT)} -} - -if [regexp {[ ]} $ffont] { - set help_font "-font \"$ffont\"" -} else { - set help_font "-font $ffont" -} - -if { [regexp -nocase {Windows} $tcl_platform(os)]} { - cd util - if {$help_font == "-font fixed"} { - set help_font "" - } -} - -if {$saw_ts_only && $saw_ssh_only} { - set saw_ssh_only 0 -} - -global ssh_only -set ssh_only 0 -if {[info exists env(SSVNC_SSH_ONLY)] || $saw_ssh_only} { - set ssh_only 1 -} - -global ts_only -set ts_only 0 -if {[info exists env(SSVNC_TS_ONLY)] || $saw_ts_only} { - set ts_only 1 -} - -if {$mycert_default != ""} { - if [regexp -nocase {^FORCE:} $mycert_default] { - set mycert_default_force 1 - regsub -nocase {^FORCE:} $mycert_default "" mycert_default - } - if {![file exists $mycert_default]} { - set idir [get_idir_certs ""] - set mycert_default "$idir/$mycert_default" - } -} - -if {$svcert_default != ""} { - if [regexp -nocase {^FORCE:} $svcert_default] { - set svcert_default_force 1 - regsub -nocase {^FORCE:} $svcert_default "" svcert_default - } - if {![file exists $svcert_default]} { - set idir [get_idir_certs ""] - if {$svcert_default == "CA"} { - set svcert_default "$idir/CA/cacert.pem" - } else { - set svcert_default "$idir/$svcert_default" - } - } -} - -if {$crlfil_default != ""} { - if [regexp -nocase {^FORCE:} $crlfil_default] { - set crlfil_default_force 1 - regsub -nocase {^FORCE:} $crlfil_default "" crlfil_default - } - if {![file exists $crlfil_default]} { - set idir [get_idir_certs ""] - set crlfil_default "$idir/$crlfil_default" - } -} - -if {$is_windows} { - check_writable -} - - -set darwin_cotvnc 0 -if {$uname == "Darwin"} { - if {! [info exists env(DISPLAY)]} { - set darwin_cotvnc 1 - } elseif {[regexp {/tmp/} $env(DISPLAY)]} { - set darwin_cotvnc 1 - } - if [info exists env(SSVNC_HOME)] { - set t "$env(SSVNC_HOME)/.vnc" - if {! [file exists $t]} { - catch {file mkdir $t} - } - } -} - -##for testing macosx -if [info exists env(FORCE_DARWIN)] { - set uname Darwin - set darwin_cotvnc 1 -} - -set putty_pw "" - -global scroll_text_focus -set scroll_text_focus 1 - -set multientry 1 - -wm withdraw . -if {$ssh_only} { - wm title . "SSH VNC Viewer" -} elseif {$ts_only} { - wm title . "Terminal Services VNC Viewer" -} else { - wm title . "SSL/SSH VNC Viewer" -} - -wm resizable . 1 0 - -set_defaults -if {$uname == "Darwin"} { - if [info exists use_x11_macosx] { - if {$use_x11_macosx} { - set darwin_cotvnc 0 - } - } -} -set skip_pre 0 - -set vncdisplay "" -set last_load "" -set vncproxy "" -set remote_ssh_cmd "" -set vncauth_passwd "" - -global did_listening_message -set did_listening_message 0 - -global accepted_cert_dialog_in_progress -set accepted_cert_dialog_in_progress 0 - -global fetch_cert_filename -set fetch_cert_filename "" - -set vhd "VNC Host:Display" -if {$ssh_only} { - label .l -text "SSH VNC Viewer" -relief ridge -} elseif {$ts_only} { - label .l -text "Terminal Services VNC Viewer" -relief ridge - set vhd "VNC Terminal Server:" -} else { - label .l -text "SSL/SSH VNC Viewer" -relief ridge -} - -set wl 21 -set we 40 -frame .f0 -if {$multientry} { - label .f0.l -width $wl -anchor w -text "$vhd" -relief ridge -} else { - label .f0.l -anchor w -text "$vhd" -relief ridge -} -entry .f0.e -width $we -textvariable vncdisplay -pack .f0.l -side left -bind .f0.e <Return> launch -bind .f0.e <Control-E> {toggle_vnc_prefix} -pack .f0.e -side left -expand 1 -fill x - -if {[check_zeroconf_browse]} { - menubutton .f0.mb -relief ridge -menu .f0.mb.m -text "Find" - menu .f0.mb.m -tearoff 0 -postcommand {zeroconf_fill .f0.mb .f0.mb.m} - pack .f0.mb -side left -} - -frame .f1 -label .f1.l -width $wl -anchor w -text "VNC Password:" -relief ridge -entry .f1.e -width $we -textvariable vncauth_passwd -show * -pack .f1.l -side left -pack .f1.e -side left -expand 1 -fill x -bind .f1.e <Return> launch - -frame .fu -label .fu.l -width $wl -anchor w -text "Unix Username:" -relief ridge -entry .fu.e -width 14 -textvariable unixpw_username -label .fu.m -anchor w -text "Unix Password:" -relief ridge -entry .fu.f -textvariable unixpw_passwd -show * -pack .fu.l -side left -pack .fu.e .fu.m -side left -pack .fu.f -side left -expand 1 -fill x -bind .fu.f <Return> launch - -frame .f2 -label .f2.l -width $wl -anchor w -text "Proxy/Gateway:" -relief ridge -entry .f2.e -width $we -textvariable vncproxy -pack .f2.l -side left -pack .f2.e -side left -expand 1 -fill x -bind .f2.e <Return> launch - -frame .f3 -label .f3.l -width $wl -anchor w -text "Remote SSH Command:" -relief ridge -entry .f3.e -width $we -textvariable remote_ssh_cmd -pack .f3.l -side left -pack .f3.e -side left -expand 1 -fill x -.f3.l configure -state disabled -.f3.e configure -state disabled -bind .f3.e <Return> launch - -set remote_ssh_cmd_list {.f3.e .f3.l} - -frame .f4 -radiobutton .f4.ssl -anchor w -variable sshssl_sw -value ssl -command {ssl_ssh_adjust ssl} -text "Use SSL" -radiobutton .f4.ssh -anchor w -variable sshssl_sw -value ssh -command {ssl_ssh_adjust ssh} -text "Use SSH" -radiobutton .f4.sshssl -anchor w -variable sshssl_sw -value sshssl -command {ssl_ssh_adjust sshssl} -text "SSH+SSL" -pack .f4.ssl .f4.ssh .f4.sshssl -side left -fill x - -set showing_no_encryption 0 -radiobutton .f4.none -anchor w -variable sshssl_sw -value none -command {ssl_ssh_adjust none} -text "None " -if [disable_encryption] { - pack .f4.none -side left - set showing_no_encryption 1 -} - -global skip_verify_accepted_certs -set skip_verify_accepted_certs 0 -global anon_dh_detected -set anon_dh_detected 0 -global vencrypt_detected -set vencrypt_detected "" - -global always_verify_ssl -set always_verify_ssl 1; -if {[info exists env(SSVNC_NO_VERIFY_ALL)]} { - set always_verify_ssl 0; -} - -if {$uname == "Darwin"} { - button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert" -} else { - button .f4.getcert -command {fetch_cert 1} -text "Fetch Cert" -padx 3 -} -checkbutton .f4.always -variable always_verify_ssl -text "Verify All Certs" -command no_certs_tutorial_mesg -pack .f4.getcert -side right -fill x -if {[info exists env(SSVNC_NO_VERIFY_ALL_BUTTON)]} { - set always_verify_ssl 0; -} else { - pack .f4.always -side right -fill x -} - -if {$ssh_only || $ts_only} { - ssl_ssh_adjust ssh -} else { - ssl_ssh_adjust ssl -} - -frame .b -button .b.help -text "Help" -command help -button .b.certs -text "Certs ..." -command getcerts -button .b.opts -text "Options ..." -command set_options -button .b.load -text "Load" -command {load_profile} -button .b.save -text "Save" -command {save_profile} -button .b.conn -text "Connect" -command launch -button .b.exit -text "Exit" -command {destroy .; exit} - - -if {$ssh_only || $ts_only} { - pack .b.opts .b.save .b.load .b.conn .b.help .b.exit -side left -expand 1 -fill x -} else { - pack .b.certs .b.opts .b.save .b.load .b.conn .b.help .b.exit -side left -expand 1 -fill x -} - -if {$multientry} { - if {! $is_windows} { - if {$ssh_only} { - pack .l .f0 .f1 .f2 .f3 .b -side top -fill x - } elseif {$ts_only} { - pack .l .f0 .f2 .b -side top -fill x - } else { - pack .l .f0 .f1 .f2 .f3 .f4 .b -side top -fill x - } - } else { - if {$ssh_only} { - pack .l .f0 .f2 .f3 .b -side top -fill x - } elseif {$ts_only} { - pack .l .f0 .f2 .b -side top -fill x - } else { - pack .l .f0 .f2 .f3 .f4 .b -side top -fill x - } - } -} else { - pack .l .f0 .b -side top -fill x -} -if {![info exists env(SSVNC_GUI_CHILD)] || $env(SSVNC_GUI_CHILD) == ""} { - center_win . -} -focus .f0.e - -wm deiconify . - -global system_button_face -set system_button_face "" -foreach item [.b.help configure -bg] { - set system_button_face $item -} - -if {[info exists env(SSVNC_GUI_CMD)]} { - set env(SSVNC_GUI_CHILD) 1 - bind . <Control-n> "exec $env(SSVNC_GUI_CMD) &" -} -bind . <Control-q> "destroy .; exit" -bind . <Shift-Escape> "destroy .; exit" -bind . <Control-s> "launch_shell_only" -bind . <Control-p> {port_knock_only "" "KNOCK"} -bind . <Control-P> {port_knock_only "" "FINISH"} -bind . <Control-l> {load_profile} -bind . <B3-ButtonRelease> {load_profile} - -bind . <Control-t> {toggle_tsonly} -bind . <Control-d> {delete_profile} -bind . <Shift-B3-ButtonRelease> {toggle_tsonly} -bind . <Shift-B2-ButtonRelease> {toggle_tsonly} -bind .l <Shift-ButtonRelease> {toggle_tsonly} -bind . <Control-h> {toggle_sshonly} -bind . <Control-T> {to_ssvnc} -bind . <Control-a> {set_advanced_options} -bind . <Control-o> {set_options} -bind . <Control-u> {set_ssvncviewer_options} -bind . <Control-e> {toggle_no_encryption} - -global entered_gui_top button_gui_top -set entered_gui_top 0 -set button_gui_top 0 -bind . <Enter> {set entered_gui_top 1} -bind .l <ButtonPress> {set button_gui_top 1} -bind .f0.l <ButtonPress> {set button_gui_top 1} - -update - -mac_raise - -set didload 0 - -for {set i 0} {$i < $argc} {incr i} { - set item [lindex $argv $i] - regsub {^--} $item "-" item - if {$item == "."} { - ; - } elseif {$item == "-nv"} { - set always_verify_ssl 0 - } elseif {$item == "-help"} { - help - } elseif {$item == "-ssh"} { - ; - } elseif {$item == "-bigger"} { - ; - } elseif {$item == "-ts"} { - ; - } elseif {$item == "-ss"} { - ; - } elseif {$item == "-ssl"} { - ; - } elseif {$item == "-tso"} { - ; - } elseif {$item == "-mycert" || $item == "-cert"} { - incr i - } elseif {$item == "-cacert" || $item == "-ca"} { - incr i - } elseif {$item == "-crl"} { - incr i - } elseif {$item == "-printhelp"} { - print_help - exit; - } elseif {$item != ""} { - if {[file exists $item] && [file isfile $item]} { - set didload 1 - load_profile . $item - } else { - set ok 0 - set dir [get_profiles_dir] - set try "$dir/$item" - foreach try [list $dir/$item $dir/$item.vnc] { - if {[file exists $try] && [file isfile $try]} { - load_profile . $try - set ok 1 - break; - } - } - if {! $ok && [regexp {:[0-9][0-9]*$} $item]} { - global vncdisplay - set vncdisplay $item - set ok 1 - } - - if {! $ok} { - if {$ts_only || $ssh_only} { - global vncdisplay - set vncdisplay $item - set ok 1 - } - } - if {$ok} { - update - set didload 1 - if [info exists env(SSVNC_PROFILE_LOADONLY)] { - if {$env(SSVNC_PROFILE_LOADONLY) == "1"} { - set ok 0 - } - } - if {$ok} { - after 750 - launch - } - } - } - } -} diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf b/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf deleted file mode 100644 index 327327a..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf +++ /dev/null @@ -1,38 +0,0 @@ -# -# Example SSL stunnel SERVER configuration file. (e.g. for your VNC -# server on this same machine.) -# -# To use this file you may need to edit it. Then you will need -# to manually start up stunnel using it. -# (e.g. /path/to/stunnel stunnel-server.conf) -# -# NOTE: You MUST specify a cert = PEM file line for server mode. -# SSVNC or x11vnc can be used to create one if you like. -# -# This is just an example and is not used by the tools in this package. -# It is here in case you wanted to see how to add SSL support to any -# VNC server you have. -# -RNDbytes = 2048 -RNDfile = bananarand.bin -RNDoverwrite = yes -# -# Remote client certs could go here: -# CApath = /path/to/.../crt-dir -# CAfile = /path/to/.../foo.crt -# verify = 2 -# -# The server cert goes here (**IT MUST BE SPECIFIED IN SERVER MODE**): -# cert = /path/to/.../my.pem -# -[vnc] -# -# Set to local listening port number (e.g. 5901 for vnc display 1): -# so the remote viewers would connect to: yourmachine:1 -# -accept = 5901 -# -# Set to localhost:port to connect to VNC server on this same machine: -# (E.g. you run WinVNC on :0, preferably listening on localhost). -# -connect = localhost:5900 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/build.unix b/x11vnc/misc/enhanced_tightvnc_viewer/build.unix deleted file mode 100755 index f84ef78..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/build.unix +++ /dev/null @@ -1,482 +0,0 @@ -#!/bin/sh - -# See the README in this directory for more info on using this script -# (build.unix). Search for SSVNC_BUILD. -# -# Notes: to customize locations, e.g. for libjpeg, set LDFLAGS_OS and/or -# CPPFLAGS_OS -# -# e.g. on Darwin we did: -# -# env LDFLAGS_OS="-L/Volumes/someplace/common/lib" CPPFLAGS_OS="-I /Volumes/someplace/common/include" ./build.unix -# - - -# Add useful directories to PATH: -# -PATH=$PATH:/usr/bin:/bin:/usr/local/bin:/usr/X11R6/bin:/usr/bin/X11:/usr/openwin/bin:/opt/SUNWspro/bin:/usr/sfw/bin:/usr/ccs/bin -export PATH - -# Check location: -# -thisdir=`dirname "$0"` -if [ ! -d ./bin -o ! -d src/patches -o ! -f ./build.unix ]; then - echo "" - echo "You must run this script from: $thisdir" - echo "" - echo "Maybe:" - echo "" - echo " cd $thisdir" - echo " ./build.unix" - if [ "X$BUILD_UNIX" != "X" ]; then - sleep 2 - exit 1 - fi - echo "" - sleep 1 - printf "Do you want me to run those for you? y/[n] " - read x - if [ "X$x" = "Xy" ]; then - BUILD_UNIX=1 - export BUILD_UNIX - cd "$thisdir" || exit 1 - echo "pwd:" - pwd - sleep 1 - ./build.unix - fi - - exit $? -fi - -pline() { - echo "------------------------------------------------------------------" -} - -# Try to find osname.arch -# -name=$UNAME -if [ "X$name" = "X" ]; then - name=`uname -sm | sed -e 's/ /./g' -e 's/Linux\.i.86/Linux.i686/'` -fi -if [ "X$name" = "X" ]; then - echo "cannot determine platform: os.arch, e.g. Linux.i686" - echo "set \$UNAME manually and retry." - exit 1 -fi - -LDD="ldd" -if [ `uname` = "Darwin" ]; then - LDD="otool -L" -fi - -# Create a tmp dir for this build: -# -tmp=./src/tmp/$name.$$ -if [ "X$TMPDIR" != "X" ]; then - tmp="$TMPDIR/$tmp" -fi -mkdir -p $tmp || exit 1 - -# Do ultraftp Java viewer (only): -# -if [ "X$SSVNC_BUILD_ULTRAFTP" != "X" ]; then - ultraftp_tar=`ls -td ./src/zips/ultraftp.tar* | head -1` - if [ ! -f $ultraftp_tar ]; then - echo "could not locate ultraftp java vnc viewer source" - exit 1 - fi - echo "" - pline - echo "BUILDING THE ULTRAFTP HELPER JAR" - echo "" - sleep 1 - - cat $ultraftp_tar | (cd $tmp; tar xvf -) || exit 1 - cd $tmp/ultraftp || exit 1 - pwd - echo - make install - - exit 0 # DONE -fi - -# Work out main destination: -# -dest=./bin/$name -if [ -d $dest ]; then - if [ "X$SSVNC_BUILD_FORCE_OVERWRITE" = "X" ]; then - printf "$dest exists. overwrite in it? [y]/n " - read x - if [ "X$x" = "Xn" ]; then - exit - fi - else - echo "$dest exists. overwriting in it." - fi - if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" ]; then - if [ `uname` = "Darwin" ]; then - rm -f $dest/vncviewer.x11* - else - rm -f $dest/vncviewer* - fi - fi - if [ "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then - rm -f $dest/stunnel* - fi -fi -mkdir -p $dest || exit 1 - - -# Try to find some static archives of various libraries: -# -libs="$tmp/libs" -mkdir -p $libs || exit 1 -for liba in libz.a libjpeg.a libssl.a libcrypto.a -do - if [ "X$SSVNC_BUILD_STATIC" = "X" ]; then - break - fi - for dir in $SSVNC_STATIC_DIRS /usr/lib /lib /usr/local/lib /usr/pkg/lib /usr/sfw/lib /usr/openwin/lib - do - if [ "X$dir" = "X" ]; then - continue - fi - if [ "$name" = "Linux.x86_64" -o "$name" = "Linux.ppc64" ] ; then - dir64=`echo "$dir" | sed -e 's,lib,lib64,'` - if [ "X$SSVNC_BUILD_NO_LINUX64" != "X" ]; then - : - elif [ -d $dir64 ]; then - dir=$dir64 - fi - fi - try="$dir/$liba" - if [ -f $try ]; then - echo cp -p "$try" $libs - cp -p "$try" $libs - break - fi - done -done -if [ "X$SSVNC_BUILD_STATIC" != "X" ]; then - echo "Found these static archive libraries, will try to use them..." - ls -ld $libs - ls -l $libs - echo -fi - -have_gcc="" -if type gcc > /dev/null; then - have_gcc=1 -fi -have_cc="" -if type cc > /dev/null; then - have_cc=1 -fi - -if [ "X$have_cc" = "X" ]; then - if [ "X$have_gcc" = "X1" ]; then - cat > $tmp/cc <<END -#!/bin/sh -gcc "\$@" -END - chmod 755 $tmp/cc - PATH=$PATH:`pwd`/$tmp - type cc - type gcc - fi -fi - -if [ -d /var/tmp/LIBS -a "X$SSVNC_BUILD_STATIC" != "X" ]; then - LDFLAGS_OS="$LDFLAGS_OS -L/var/tmp/LIBS" -fi - -if [ `uname` = "SunOS" ]; then - LDFLAGS_OS="$LDFLAGS_OS -L/usr/sfw/lib -R/usr/sfw/lib" - CPPFLAGS_OS="$CPPFLAGS_OS -I /usr/sfw/include" -elif uname | grep -i bsd > /dev/null; then - LDFLAGS_OS="$LDFLAGS_OS -L/usr/local/lib -L/usr/pkg/lib" - CPPFLAGS_OS="$CPPFLAGS_OS -I /usr/local/include -I /usr/pkg/include" -fi - -cnt=`ls ./src/patches/*.patch | wc -c` -if [ $cnt -lt 1 ]; then - echo "Could not find any patches in ./src/patches. Is your tarball missing them?" - exit 1 -fi - -pline() { - echo "------------------------------------------------------------------" -} - -# Do tightvnc viewer: -# -if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" ]; then - tight_src=`ls -td ./src/vnc_unixsrc* | head -1` - if [ ! -d $tight_src ]; then - echo "could not locate tight vnc viewer source" - exit 1 - fi - echo "" - pline - echo "BUILDING THE VNCVIEWER" - echo "" - sleep 1 - - cp -pR "$tight_src" "$tmp/vnc_unixsrc" || exit 1 - - echo "applying tight vnc patches:" - start=`pwd` - cd $tmp; - failed=0 - count=0 - patches="../../patches/tight-vncviewer-full.patch" - if [ ! -f "$patches" ]; then - patches=`ls ../../patches/tight* | grep -v 'tight-vncviewer-full.patch'` - fi - for patch in $patches - do - if [ ! -f "$patch" ]; then - continue - fi - if [ "X$PATCH_FAIL" != "X" ]; then - failed=1 - break - fi - echo PATCHING WITH: "$patch" - ls -l "$patch" - sleep 1 - patch -p0 < "$patch" - if [ $? != 0 ]; then - failed=`expr $failed + 1` - else - count=`expr $count + 1` - fi - done - sleep 1 - cd "$start" - if [ $failed != 0 -o $count = 0 ]; then - ball=src/zips/vnc_unixsrc_vncviewer.patched.tar - echo "patches failed, trying to use backup tarball:" - ls -l $ball - sleep 2 - cat $ball | (cd $tmp; tar -xvf -) - fi - echo - - - cd $tmp/vnc_unixsrc - xmkmf - make Makefiles - mv vncviewer/Makefile vncviewer/Makefile.orig - sed -e "s,EXTRA_LDOPTIONS =,EXTRA_LDOPTIONS = -L$start/$libs $LDFLAGS_OS," \ - -e "s,CCOPTIONS =,CCOPTIONS = $CPPFLAGS_OS," \ - vncviewer/Makefile.orig > vncviewer/Makefile - - if [ `uname` = "SunOS" ]; then - for d in vncviewer libvncauth vncconnect vncpasswd - do - mv $d/Makefile $d/Makefile.orig - sed -e "s,CCOPTIONS =.*\$,CCOPTIONS = $CPPFLAGS_OS," \ - $d/Makefile.orig > $d/Makefile - done - fi - - make depend - echo $PATH - if [ "X$TURBOVNC" = "X" ]; then - make all - else - make CCOPTIONS="-DTURBOVNC $CPPFLAGS_OS" EXTRA_LIBRARIES="$TURBOVNC" all - fi - ls -l vncviewer/vncviewer - cd "$start" - src=$tmp/vnc_unixsrc/vncviewer/vncviewer - sync - sleep 2 - sync - strip $src - sync - sleep 2 - sync - wc $src - sum $src - sleep 2 - - suff="" - if [ `uname` = "Darwin" ]; then - suff=".x11" - fi - if [ "X$TURBOVNC" != "X" ]; then - suff="$suff.turbovnc" - fi - echo cp -p $src $dest/vncviewer$suff - sleep 1 - cp -p $src $dest/vncviewer$suff || exit 1 - - echo - pline - echo "LISTING, HELP, and LDD THE VNCVIEWER:" - echo - sleep 1 - - ls -l $src $dest/vncviewer$suff - echo - echo $dest/vncviewer$suff -h - echo - $dest/vncviewer$suff -h - echo - echo $LDD $dest/vncviewer$suff - echo - $LDD $dest/vncviewer$suff - echo "" -fi - -# Do stunnel: -# -if [ "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then - stunnel_src=`ls -td ./src/stunnel* | head -1` - if [ ! -d $stunnel_src ]; then - echo "could not locate stunnel source" - exit 1 - fi - echo "" - pline - echo "BUILDING THE STUNNEL" - echo "" - sleep 1 - - cp -pR "$stunnel_src" "$tmp/stunnel" || exit 1 - - echo "applying stunnel patches:" - start=`pwd` - cd $tmp; - failed=0 - count=0 - for patch in ../../patches/stunnel* - do - if [ ! -f "$patch" ]; then - continue - fi - if [ "X$PATCH_FAIL" != "X" ]; then - failed=1 - break - fi - echo PATCHING WITH: "$patch" - ls -l "$patch" - sleep 1 - patch -p0 < $patch - if [ $? != 0 ]; then - failed=`expr $failed + 1` - else - count=`expr $count + 1` - fi - done - sleep 1 - cd "$start" - if [ $failed != 0 -o $count = 0 ]; then - ball=src/zips/stunnel.patched.tar - echo "patches failed, trying to use backup tarball:" - ls -l $ball - sleep 2 - cat $ball | (cd $tmp; tar -xvf -) - fi - echo - - - cd $tmp/stunnel - if [ `uname` = "SunOS" ]; then - cp configure configure.orig - sed -e "s,maindir in,maindir in /usr/sfw," configure.orig > configure - fi - env LDFLAGS="-L$start/$libs $LDFLAGS_OS" CPPFLAGS="$CPPFLAGS_OS" ./configure --disable-libwrap --enable-ipv6 - make - ls -l src/stunnel - cd "$start" - src=$tmp/stunnel/src/stunnel - sync - sleep 2 - sync - strip $src - sync - sleep 2 - sync - wc $src - sum $src - sleep 2 - echo cp -p $src $dest/stunnel - cp -p $src $dest/stunnel || exit 1 - sleep 1 - cp -p $src $dest/stunnel || exit 1 - - echo - pline - echo "LISTING, HELP, and LDD THE STUNNEL:" - echo - sleep 1 - - ls -l $src $dest/stunnel - echo - echo $dest/stunnel -help - echo - $dest/stunnel -help - echo - echo $LDD $dest/stunnel - echo - $LDD $dest/stunnel - echo "" -fi - -# Do vncstorepw and ld preload friends: -# -if [ "X$SSVNC_BUILD_SKIP_VNCSTOREPW" = "X" ]; then - vncpw_tar=`ls -td ./src/zips/vncstorepw* | head -1` - if [ ! -f $vncpw_tar ]; then - echo "could not locate vncstorepw source" - exit 1 - fi - echo "" - pline - echo "BUILDING THE VNCSTOREPW AND FRIENDS" - echo "" - sleep 1 - - cat "$vncpw_tar" | (cd $tmp; tar xvf -) - - cd $tmp/vncstorepw - make - - cd "$start" - cp -p $tmp/vncstorepw/vncstorepw $tmp/vncstorepw/lim_accept.so $dest - echo "" - - cd $tmp/vncstorepw - make clean - - env LD_SSL="-L$start/$libs $LDFLAGS_OS $LD_SSL" CPP_SSL="$CPPFLAGS_OS" make ultravnc_dsm_helper - - cd "$start" - cp -p $tmp/vncstorepw/ultravnc_dsm_helper $dest - echo "" -fi - - -if [ "X$SSVNC_BUILD_SKIP_VIEWER" = "X" -a "X$SSVNC_BUILD_SKIP_STUNNEL" = "X" ]; then - # list the viewer again. - - echo - pline - echo "LISTING, HELP, and LDD THE VNCVIEWER (again):" - echo - sleep 1 - - ls -l $dest/vncviewer$suff - echo - echo $dest/vncviewer$suff -h - echo - $dest/vncviewer$suff -h - echo - echo $LDD $dest/vncviewer$suff - echo - $LDD $dest/vncviewer$suff -fi diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt b/x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt deleted file mode 100644 index d104f25..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt +++ /dev/null @@ -1,280 +0,0 @@ -3277703 4 drwxr-xr-x 6 runge runge 4096 Sep 13 21:28 . -3277704 4 drwxr-xr-x 7 runge runge 4096 Aug 2 10:05 ./src -3277781 4 drwxr-xr-x 2 runge runge 4096 Aug 2 10:09 ./src/zips -3277782 484 -rw-r--r-- 1 runge runge 488512 Jul 25 15:09 ./src/zips/stunnel-4.14.tar.gz -3277783 212 -rw-r--r-- 1 runge runge 209149 Jul 25 15:10 ./src/zips/tightvnc-1.3dev7_x86_viewer.zip -3277784 2136 -rw-r--r-- 1 runge runge 2182134 Jul 25 15:11 ./src/zips/tightvnc-1.3dev7_unixsrc.tar.gz -3277792 4 -rw-r--r-- 1 runge runge 753 Aug 2 10:09 ./src/zips/README -3277786 364 -rw-r--r-- 1 runge runge 368640 Jul 27 19:06 ./src/zips/vnc_unixsrc_vncviewer.patched.tar -3277787 1996 -rw-r--r-- 1 runge runge 2037760 Jul 31 23:42 ./src/zips/stunnel.patched.tar -2982849 4 drwxr-xr-x 2 runge runge 4096 Sep 10 14:37 ./src/patches -2982852 4 -rw-r--r-- 1 runge runge 3750 Feb 5 2005 ./src/patches/tight-vncviewer-alphahack.patch -2982854 4 -rw-r--r-- 1 runge runge 1143 Jul 25 15:25 ./src/patches/tight-vncviewer-fullscreen.patch -2982865 8 -rw-r--r-- 1 runge runge 7633 Jul 27 19:01 ./src/patches/tight-vncviewer-newfbsize.patch -2982955 4 -rwxr-xr-x 1 runge runge 1529 Sep 10 12:07 ./src/patches/_bundle -2982877 4 -rwxr-xr-x 1 runge runge 78 Jul 27 14:41 ./src/patches/_getpatches -2983012 4 -rw-r--r-- 1 runge runge 4072 Jul 31 22:59 ./src/patches/stunnel-maxconn.patch -2982878 4 -rwxr-xr-x 1 runge runge 117 Jul 27 19:06 ./src/patches/_vncpatchapplied -2982880 4 -rw-r--r-- 1 runge runge 223 Aug 24 10:11 ./src/patches/README -2982850 4 drwxr-xr-x 8 runge runge 4096 Jul 25 15:21 ./src/vnc_unixsrc -2982885 4 -rw-r--r-- 1 runge runge 356 Apr 30 2002 ./src/vnc_unixsrc/Imakefile -2982886 20 -rw-r--r-- 1 runge runge 18000 Jun 11 2000 ./src/vnc_unixsrc/LICENCE.TXT -2982887 12 -rw-r--r-- 1 runge runge 8341 Jul 4 2005 ./src/vnc_unixsrc/README -2982888 12 -rw-r--r-- 1 runge runge 9682 Jul 4 2005 ./src/vnc_unixsrc/tightvnc.spec -2982889 4 -rw-r--r-- 1 runge runge 486 Aug 30 2002 ./src/vnc_unixsrc/vnc-xclients.patch -2982890 4 -rwxr-xr-x 1 runge runge 2042 Mar 19 2002 ./src/vnc_unixsrc/vncinstall -2982891 16 -rwxr-xr-x 1 runge runge 15239 Jul 4 2005 ./src/vnc_unixsrc/vncserver -2982892 4 -rwxr-xr-x 1 runge runge 1726 Aug 30 2002 ./src/vnc_unixsrc/vncserver.init -2982893 4 -rw-r--r-- 1 runge runge 3070 Aug 7 2002 ./src/vnc_unixsrc/vncserver.man -4359127 4 drwxr-xr-x 2 runge runge 4096 Jul 27 16:25 ./src/vnc_unixsrc/classes -2851413 4 drwxr-xr-x 2 runge runge 4096 Jul 5 2005 ./src/vnc_unixsrc/include -2851414 44 -rw-r--r-- 1 runge runge 43296 May 27 2004 ./src/vnc_unixsrc/include/rfbproto.h -2851415 4 -rw-r--r-- 1 runge runge 1166 Jun 11 2000 ./src/vnc_unixsrc/include/vncauth.h -2851416 4 drwxr-xr-x 2 runge runge 4096 Jul 5 2005 ./src/vnc_unixsrc/libvncauth -2851417 4 -rw-r--r-- 1 runge runge 199 Apr 30 2002 ./src/vnc_unixsrc/libvncauth/Imakefile -2851418 16 -rw-r--r-- 1 runge runge 15487 Jun 11 2000 ./src/vnc_unixsrc/libvncauth/d3des.c -2851419 4 -rw-r--r-- 1 runge runge 1618 Jun 11 2000 ./src/vnc_unixsrc/libvncauth/d3des.h -2851420 8 -rw-r--r-- 1 runge runge 5879 Mar 1 2003 ./src/vnc_unixsrc/libvncauth/vncauth.c -2851421 4 drwxr-xr-x 2 runge runge 4096 Jul 5 2005 ./src/vnc_unixsrc/vncconnect -2851422 4 -rw-r--r-- 1 runge runge 163 Apr 30 2002 ./src/vnc_unixsrc/vncconnect/Imakefile -2851423 4 -rw-r--r-- 1 runge runge 1167 Nov 10 2000 ./src/vnc_unixsrc/vncconnect/vncconnect.c -2851424 4 -rw-r--r-- 1 runge runge 1083 Feb 5 2003 ./src/vnc_unixsrc/vncconnect/vncconnect.man -2851425 4 drwxr-xr-x 2 runge runge 4096 Jul 5 2005 ./src/vnc_unixsrc/vncpasswd -2851426 4 -rw-r--r-- 1 runge runge 256 Apr 30 2002 ./src/vnc_unixsrc/vncpasswd/Imakefile -2851427 8 -rw-r--r-- 1 runge runge 7681 Mar 1 2003 ./src/vnc_unixsrc/vncpasswd/vncpasswd.c -2851428 4 -rw-r--r-- 1 runge runge 3222 Mar 1 2003 ./src/vnc_unixsrc/vncpasswd/vncpasswd.man -2851429 4 drwxr-xr-x 2 runge runge 4096 Aug 3 19:10 ./src/vnc_unixsrc/vncviewer -2851430 4 -rw-r--r-- 1 runge runge 1057 Mar 12 2003 ./src/vnc_unixsrc/vncviewer/Imakefile -2851431 16 -rw-r--r-- 1 runge runge 12375 Jul 4 2005 ./src/vnc_unixsrc/vncviewer/README -2851432 4 -rw-r--r-- 1 runge runge 3198 Feb 7 2003 ./src/vnc_unixsrc/vncviewer/Vncviewer -2851433 16 -rw-r--r-- 1 runge runge 14159 Jul 4 2005 ./src/vnc_unixsrc/vncviewer/argsresources.c -2851434 8 -rw-r--r-- 1 runge runge 5362 Apr 1 2003 ./src/vnc_unixsrc/vncviewer/caps.c -2851435 4 -rw-r--r-- 1 runge runge 2074 Apr 1 2003 ./src/vnc_unixsrc/vncviewer/caps.h -2851436 16 -rw-r--r-- 1 runge runge 15568 Apr 30 2002 ./src/vnc_unixsrc/vncviewer/colour.c -2851437 4 -rw-r--r-- 1 runge runge 2295 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/corre.c -2851438 16 -rw-r--r-- 1 runge runge 14504 Jan 15 2003 ./src/vnc_unixsrc/vncviewer/cursor.c -2851439 12 -rw-r--r-- 1 runge runge 11832 May 28 2004 ./src/vnc_unixsrc/vncviewer/desktop.c -2851440 4 -rw-r--r-- 1 runge runge 2621 Oct 26 2000 ./src/vnc_unixsrc/vncviewer/dialogs.c -2851441 12 -rw-r--r-- 1 runge runge 11671 Oct 9 2003 ./src/vnc_unixsrc/vncviewer/fullscreen.c -2851442 4 -rw-r--r-- 1 runge runge 3639 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/hextile.c -2851443 8 -rw-r--r-- 1 runge runge 7463 Jan 16 2001 ./src/vnc_unixsrc/vncviewer/listen.c -2851444 12 -rw-r--r-- 1 runge runge 9120 Jan 15 2003 ./src/vnc_unixsrc/vncviewer/misc.c -2851445 4 -rw-r--r-- 1 runge runge 2749 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/popup.c -2851446 40 -rw-r--r-- 1 runge runge 38923 Mar 11 2004 ./src/vnc_unixsrc/vncviewer/rfbproto.c -2851447 4 -rw-r--r-- 1 runge runge 2411 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/rre.c -2851448 12 -rw-r--r-- 1 runge runge 9985 Mar 3 2004 ./src/vnc_unixsrc/vncviewer/selection.c -2851449 4 -rw-r--r-- 1 runge runge 2439 Jun 11 2000 ./src/vnc_unixsrc/vncviewer/shm.c -2851450 12 -rw-r--r-- 1 runge runge 9253 Jan 14 2001 ./src/vnc_unixsrc/vncviewer/sockets.c -2851451 16 -rw-r--r-- 1 runge runge 16069 Apr 30 2002 ./src/vnc_unixsrc/vncviewer/tight.c -2851452 8 -rw-r--r-- 1 runge runge 6695 Jul 31 2003 ./src/vnc_unixsrc/vncviewer/tunnel.c -2851453 4 -rw-r--r-- 1 runge runge 4040 Jan 13 2004 ./src/vnc_unixsrc/vncviewer/vncviewer.c -2851454 8 -rw-r--r-- 1 runge runge 7236 Mar 11 2004 ./src/vnc_unixsrc/vncviewer/vncviewer.h -2851455 16 -rw-r--r-- 1 runge runge 14478 Mar 11 2004 ./src/vnc_unixsrc/vncviewer/vncviewer.man -2851456 8 -rw-r--r-- 1 runge runge 4437 Jan 16 2001 ./src/vnc_unixsrc/vncviewer/zlib.c -2982894 36 -rw-r--r-- 1 runge runge 34369 Jul 5 2005 ./src/vnc_unixsrc/WhatsNew -2982895 84 -rw-r--r-- 1 runge runge 80366 Jul 5 2005 ./src/vnc_unixsrc/ChangeLog -2670933 4 drwxr-xr-x 6 runge runge 4096 Aug 2 09:03 ./src/stunnel-4.14 -3621575 4 drwxr-xr-x 2 runge runge 4096 Nov 2 2005 ./src/stunnel-4.14/auto -3621576 44 -rwxr-xr-x 1 runge runge 43609 Aug 10 2004 ./src/stunnel-4.14/auto/config.guess -3621577 32 -rwxr-xr-x 1 runge runge 31160 Aug 10 2004 ./src/stunnel-4.14/auto/config.sub -3621578 16 -rwxr-xr-x 1 runge runge 13866 Aug 10 2004 ./src/stunnel-4.14/auto/depcomp -3621579 8 -rwxr-xr-x 1 runge runge 7122 Aug 10 2004 ./src/stunnel-4.14/auto/install-sh -3621580 184 -rw-r--r-- 1 runge runge 184019 Aug 10 2004 ./src/stunnel-4.14/auto/ltmain.sh -3621581 12 -rwxr-xr-x 1 runge runge 10266 Aug 10 2004 ./src/stunnel-4.14/auto/missing -3621582 4 -rwxr-xr-x 1 runge runge 1988 Aug 10 2004 ./src/stunnel-4.14/auto/mkinstalldirs -5456722 4 drwxr-xr-x 2 runge runge 4096 Jul 31 22:47 ./src/stunnel-4.14/src -5456723 4 -rw-r--r-- 1 runge runge 1594 Oct 15 2005 ./src/stunnel-4.14/src/Makefile.am -5456724 20 -rw-r--r-- 1 runge runge 19314 Oct 25 2005 ./src/stunnel-4.14/src/Makefile.in -5456725 4 -rwxr-xr-x 1 runge runge 2954 Apr 20 2005 ./src/stunnel-4.14/src/stunnel3.in -5456727 4 -rw-r--r-- 1 runge runge 2376 Dec 31 2004 ./src/stunnel-4.14/src/env.c -5456728 8 -rw-r--r-- 1 runge runge 7878 Oct 21 2005 ./src/stunnel-4.14/src/common.h -5456775 12 -rw-r--r-- 1 runge runge 10893 Oct 27 2005 ./src/stunnel-4.14/src/prototypes.h -5456776 40 -rw-r--r-- 1 runge runge 36917 Oct 24 2005 ./src/stunnel-4.14/src/client.c -5456777 12 -rw-r--r-- 1 runge runge 9827 Sep 28 2005 ./src/stunnel-4.14/src/log.c -5456778 44 -rw-r--r-- 1 runge runge 43728 Oct 20 2005 ./src/stunnel-4.14/src/options.c -5456779 12 -rw-r--r-- 1 runge runge 9137 Apr 11 2005 ./src/stunnel-4.14/src/protocol.c -5456780 20 -rw-r--r-- 1 runge runge 19335 Oct 30 2005 ./src/stunnel-4.14/src/network.c -5456781 16 -rw-r--r-- 1 runge runge 12947 Feb 28 2005 ./src/stunnel-4.14/src/resolver.c -5456782 28 -rw-r--r-- 1 runge runge 25216 Oct 27 2005 ./src/stunnel-4.14/src/ssl.c -5456783 12 -rw-r--r-- 1 runge runge 9935 Oct 19 2005 ./src/stunnel-4.14/src/sthreads.c -5456784 16 -rw-r--r-- 1 runge runge 14074 Nov 2 2005 ./src/stunnel-4.14/src/stunnel.c -5456785 12 -rw-r--r-- 1 runge runge 8254 Jun 13 2005 ./src/stunnel-4.14/src/pty.c -5456786 32 -rw-r--r-- 1 runge runge 28682 Sep 29 2005 ./src/stunnel-4.14/src/gui.c -5456787 4 -rw-r--r-- 1 runge runge 227 Nov 5 2002 ./src/stunnel-4.14/src/resources.h -5456788 4 -rw-r--r-- 1 runge runge 1441 Oct 21 2005 ./src/stunnel-4.14/src/resources.rc -5456789 8 -rw-r--r-- 1 runge runge 4710 Jul 18 2002 ./src/stunnel-4.14/src/stunnel.ico -5456791 4 -rw-r--r-- 1 runge runge 76 Jul 18 2002 ./src/stunnel-4.14/src/make.bat -5456792 4 -rw-r--r-- 1 runge runge 1001 Oct 15 2005 ./src/stunnel-4.14/src/Makefile.w32 -3670989 4 drwxr-xr-x 2 runge runge 4096 Nov 2 2005 ./src/stunnel-4.14/tools -3670990 4 -rw-r--r-- 1 runge runge 1448 Sep 14 2005 ./src/stunnel-4.14/tools/Makefile.am -3670991 12 -rw-r--r-- 1 runge runge 12178 Oct 25 2005 ./src/stunnel-4.14/tools/Makefile.in -3670992 4 -rw-r--r-- 1 runge runge 1436 Sep 22 2005 ./src/stunnel-4.14/tools/stunnel.conf-sample.in -3670993 4 -rw-r--r-- 1 runge runge 966 Oct 25 2005 ./src/stunnel-4.14/tools/stunnel.init.in -3670994 4 -rw-r--r-- 1 runge runge 1121 Jul 18 2002 ./src/stunnel-4.14/tools/ca.html -3670995 4 -rwxr-xr-x 1 runge runge 1793 Jul 18 2002 ./src/stunnel-4.14/tools/ca.pl -3670996 4 -rw-r--r-- 1 runge runge 409 Jul 18 2002 ./src/stunnel-4.14/tools/importCA.html -3670997 4 -rwxr-xr-x 1 runge runge 105 Jul 18 2002 ./src/stunnel-4.14/tools/importCA.sh -3670998 4 -rwxr-xr-x 1 runge runge 223 Apr 23 2004 ./src/stunnel-4.14/tools/script.sh -3670999 4 -rw-r--r-- 1 runge runge 2618 Oct 21 2005 ./src/stunnel-4.14/tools/stunnel.spec -3671000 4 -rw-r--r-- 1 runge runge 2989 Jul 6 2005 ./src/stunnel-4.14/tools/stunnel.mak -3671001 4 -rw-r--r-- 1 runge runge 1175 Sep 1 2002 ./src/stunnel-4.14/tools/stunnel.cnf -3671002 4 -rw-r--r-- 1 runge runge 3285 Oct 21 2005 ./src/stunnel-4.14/tools/stunnel.nsi -3671003 4 -rw-r--r-- 1 runge runge 1148 Sep 22 2005 ./src/stunnel-4.14/tools/stunnel.conf -2670934 4 -rw-r--r-- 1 runge runge 725 Aug 12 2002 ./src/stunnel-4.14/README -2670935 12 -rw-r--r-- 1 runge runge 8824 Oct 25 2005 ./src/stunnel-4.14/configure.ac -2670936 240 -rw-r--r-- 1 runge runge 239347 Oct 25 2005 ./src/stunnel-4.14/aclocal.m4 -2670937 4 -rw-r--r-- 1 runge runge 1273 Sep 14 2005 ./src/stunnel-4.14/Makefile.am -2670938 24 -rw-r--r-- 1 runge runge 20876 Oct 25 2005 ./src/stunnel-4.14/Makefile.in -2670939 768 -rwxr-xr-x 1 runge runge 780103 Oct 25 2005 ./src/stunnel-4.14/configure -2670940 4 -rw-r--r-- 1 runge runge 99 Aug 12 2002 ./src/stunnel-4.14/AUTHORS -2670941 4 -rw-r--r-- 1 runge runge 788 Sep 13 2002 ./src/stunnel-4.14/COPYING -2670942 28 -rw-r--r-- 1 runge runge 25682 Nov 2 2005 ./src/stunnel-4.14/ChangeLog -2670943 4 -rw-r--r-- 1 runge runge 1066 Aug 10 2002 ./src/stunnel-4.14/INSTALL -2670944 4 -rw-r--r-- 1 runge runge 955 Aug 12 2002 ./src/stunnel-4.14/NEWS -2670945 4 -rw-r--r-- 1 runge runge 1461 Jul 27 2005 ./src/stunnel-4.14/TODO -2670946 4 -rw-r--r-- 1 runge runge 222 Jul 18 2002 ./src/stunnel-4.14/PORTS -2670947 4 -rw-r--r-- 1 runge runge 270 Aug 9 2004 ./src/stunnel-4.14/BUGS -2671491 20 -rw-r--r-- 1 runge runge 17982 Jul 18 2002 ./src/stunnel-4.14/COPYRIGHT.GPL -2671492 4 -rw-r--r-- 1 runge runge 199 Jul 18 2002 ./src/stunnel-4.14/CREDITS -2671493 4 -rw-r--r-- 1 runge runge 687 Jul 21 2005 ./src/stunnel-4.14/INSTALL.W32 -5653462 4 drwxr-xr-x 4 runge runge 4096 Jul 30 17:46 ./src/stunnel-4.14/doc -5653463 4 -rw-r--r-- 1 runge runge 1009 Jan 15 2005 ./src/stunnel-4.14/doc/Makefile.am -5653464 12 -rw-r--r-- 1 runge runge 12152 Oct 25 2005 ./src/stunnel-4.14/doc/Makefile.in -5653465 16 -rw-r--r-- 1 runge runge 16341 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.pod -5653466 20 -rw-r--r-- 1 runge runge 18829 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.pl.pod -5653467 20 -rw-r--r-- 1 runge runge 17798 Dec 25 2004 ./src/stunnel-4.14/doc/stunnel.fr.pod -5653468 24 -rw-r--r-- 1 runge runge 23885 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.8 -5653469 28 -rw-r--r-- 1 runge runge 26536 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.pl.8 -5653470 28 -rw-r--r-- 1 runge runge 24864 Jan 15 2005 ./src/stunnel-4.14/doc/stunnel.fr.8 -5653471 28 -rw-r--r-- 1 runge runge 26128 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.html -5653472 32 -rw-r--r-- 1 runge runge 28753 Sep 29 2005 ./src/stunnel-4.14/doc/stunnel.pl.html -5653473 28 -rw-r--r-- 1 runge runge 27205 Jan 15 2005 ./src/stunnel-4.14/doc/stunnel.fr.html -4342742 4 drwxr-xr-x 2 runge runge 4096 Jul 18 2002 ./src/stunnel-4.14/doc/en -4342743 12 -rw-r--r-- 1 runge runge 8414 Jul 18 2002 ./src/stunnel-4.14/doc/en/VNC_StunnelHOWTO.html -4342744 4 -rw-r--r-- 1 runge runge 4045 Jul 18 2002 ./src/stunnel-4.14/doc/en/transproxy.txt -4342745 4 drwxr-xr-x 2 runge runge 4096 Jul 18 2002 ./src/stunnel-4.14/doc/pl -4342746 36 -rw-r--r-- 1 runge runge 36360 Jul 18 2002 ./src/stunnel-4.14/doc/pl/tworzenie_certyfikatow.html -4342747 8 -rw-r--r-- 1 runge runge 5068 Jul 18 2002 ./src/stunnel-4.14/doc/pl/faq.stunnel-2.html -3653836 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:44 ./src/tmp -3277788 4 -rw-r--r-- 1 runge runge 301 Aug 2 10:05 ./src/README -2851457 4 drwxr-xr-x 12 runge runge 4096 Aug 29 16:32 ./bin -2261930 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:00 ./bin/Linux.i686 -2261967 196 -rwxr-xr-x 1 runge runge 193076 Jul 31 22:59 ./bin/Linux.i686/vncviewer -2261999 80 -rwxr-xr-x 1 runge runge 77148 Jul 31 23:00 ./bin/Linux.i686/stunnel -5538622 4 drwxr-xr-x 2 runge runge 4096 Sep 12 21:24 ./bin/util -5538759 12 -rwxr-xr-x 1 runge runge 12148 Sep 12 21:24 ./bin/util/ss_vncviewer -5538760 136 -rwxr-xr-x 1 runge runge 132853 Sep 12 21:17 ./bin/util/ssvnc.tcl -5538641 4 -rw-r--r-- 1 runge runge 981 Aug 4 09:27 ./bin/util/stunnel-server.conf -2851794 4 -rwxr-xr-x 1 runge runge 3581 Jul 31 23:00 ./bin/ssvnc_cmd -2851592 4 -rwxr-xr-x 1 runge runge 3752 Jul 31 23:01 ./bin/tightvncviewer -2425590 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:30 ./bin/Linux.alpha -2425595 100 -rwxr-xr-x 1 runge runge 97504 Jul 31 23:30 ./bin/Linux.alpha/stunnel -2425596 272 -rwxr-xr-x 1 runge runge 274312 Jul 31 23:24 ./bin/Linux.alpha/vncviewer -3883808 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:24 ./bin/Linux.x86_64 -3883809 84 -rwxr-xr-x 1 runge runge 77896 Jul 31 23:24 ./bin/Linux.x86_64/stunnel -3883810 112 -rwxr-xr-x 1 runge runge 109656 Jul 31 23:23 ./bin/Linux.x86_64/vncviewer -3883811 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:27 ./bin/FreeBSD.i386 -3883812 68 -rwxr-xr-x 1 runge runge 64660 Jul 31 23:27 ./bin/FreeBSD.i386/stunnel -3883813 180 -rwxr-xr-x 1 runge runge 176796 Jul 31 23:24 ./bin/FreeBSD.i386/vncviewer -3687167 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:27 ./bin/OpenBSD.i386 -3687164 76 -rwxr-xr-x 1 runge runge 72260 Jul 31 23:27 ./bin/OpenBSD.i386/stunnel -3687165 180 -rwxr-xr-x 1 runge runge 179036 Jul 31 23:24 ./bin/OpenBSD.i386/vncviewer -4359128 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:27 ./bin/NetBSD.i386 -4359129 72 -rwxr-xr-x 1 runge runge 69064 Jul 31 23:27 ./bin/NetBSD.i386/stunnel -4359130 176 -rwxr-xr-x 1 runge runge 172624 Jul 31 23:24 ./bin/NetBSD.i386/vncviewer -2851458 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:25 ./bin/Linux.ppc64 -2851459 76 -rwxr-xr-x 1 runge runge 72856 Jul 31 23:25 ./bin/Linux.ppc64/stunnel -2851460 196 -rwxr-xr-x 1 runge runge 196112 Jul 31 23:24 ./bin/Linux.ppc64/vncviewer -3064794 4 drwxr-xr-x 2 runge runge 4096 Jul 31 23:47 ./bin/SunOS.sun4u -3064795 108 -rwxr-xr-x 1 runge runge 106260 Jul 31 23:45 ./bin/SunOS.sun4u/vncviewer -3064796 76 -rwxr-xr-x 1 runge runge 71748 Jul 31 23:47 ./bin/SunOS.sun4u/stunnel -2851711 4 -rwxr-xr-x 1 runge runge 1310 Aug 29 16:29 ./bin/ssvnc -2851793 4 -rwxr-xr-x 1 runge runge 640 Jul 31 17:22 ./bin/.linkin -3293942 4 drwxr-xr-x 2 runge runge 4096 Aug 1 22:14 ./bin/profiles -3277791 8 -rwxr-xr-x 1 runge runge 4814 Jul 30 17:54 ./build.unix -3277785 20 -rw-r--r-- 1 runge runge 18043 Aug 1 2001 ./COPYING -3277827 8 -rw-r--r-- 1 runge runge 7222 Sep 10 16:04 ./README -5063553 4 drwxr-xr-x 3 runge runge 4096 Jul 27 16:32 ./man -5063554 4 drwxr-xr-x 2 runge runge 4096 Jul 27 16:33 ./man/man1 -5063556 16 -rw-r--r-- 1 runge runge 14478 Jul 27 16:32 ./man/man1/vncviewer.1 -5063557 24 -rw-r--r-- 1 runge runge 23885 Jul 27 16:33 ./man/man1/stunnel.1 -5538624 4 drwxr-xr-x 4 runge runge 4096 Sep 6 16:30 ./Windows -5538633 2312 -rw-r--r-- 1 runge runge 2361922 Sep 12 22:27 ./Windows/ssvnc.exe -5538576 4 -rw-r--r-- 1 runge runge 2149 Aug 2 09:42 ./Windows/README.txt -3293943 4 drwxr-xr-x 2 runge runge 4096 Aug 1 22:14 ./Windows/profiles -4621136 4 drwxr-xr-x 5 runge runge 4096 Sep 6 16:30 ./Windows/util -5096237 4 drwxr-xr-x 2 runge runge 4096 Sep 2 16:06 ./Windows/util/esound -5096238 148 -rw-rw-rw- 1 runge runge 146432 Jun 26 2004 ./Windows/util/esound/cygaudiofile.dll -5096239 60 -rw-rw-rw- 1 runge runge 53270 Feb 19 2003 ./Windows/util/esound/cygesd.dll -5096241 1132 -rw-rw-rw- 1 runge runge 1153417 May 26 2004 ./Windows/util/esound/cygwin1.dll -5096242 68 -rw-r--r-- 1 runge runge 65385 Feb 19 2003 ./Windows/util/esound/esd.exe -5096248 24 -rw-r--r-- 1 runge runge 21282 Feb 19 2003 ./Windows/util/esound/esdcat.exe -5096249 32 -rw-r--r-- 1 runge runge 32330 Feb 19 2003 ./Windows/util/esound/esdctl.exe -5096251 24 -rw-r--r-- 1 runge runge 21428 Feb 19 2003 ./Windows/util/esound/esdfilt.exe -5096252 24 -rw-r--r-- 1 runge runge 22643 Feb 19 2003 ./Windows/util/esound/esdloop.exe -5096253 24 -rw-r--r-- 1 runge runge 21264 Feb 19 2003 ./Windows/util/esound/esdmon.exe -5096254 28 -rw-r--r-- 1 runge runge 24835 Feb 19 2003 ./Windows/util/esound/esdplay.exe -5096255 24 -rw-r--r-- 1 runge runge 21288 Feb 19 2003 ./Windows/util/esound/esdrec.exe -5096256 28 -rw-r--r-- 1 runge runge 25151 Feb 19 2003 ./Windows/util/esound/esdsample.exe -5096258 4 -rw-r--r-- 1 runge runge 51 Sep 2 16:05 ./Windows/util/esound/example.bat -4621144 1132 -rwxr-xr-x 1 runge runge 1153024 Mar 23 2005 ./Windows/util/openssl.exe -5538626 1548 -rwxr-xr-x 1 runge runge 1578787 Mar 23 2005 ./Windows/util/libeay32.dll -5538629 624 -rwxr-xr-x 1 runge runge 632226 Mar 23 2005 ./Windows/util/libssl32.dll -4621310 128 -rw-r--r-- 1 runge runge 126976 Sep 4 10:56 ./Windows/util/pageant.exe -4621311 164 -rw-r--r-- 1 runge runge 163840 Sep 4 10:57 ./Windows/util/puttygen.exe -5538631 76 -rwxr-xr-x 1 runge runge 73728 Feb 26 2006 ./Windows/util/stunnel.exe -5538625 360 -rwxr-xr-x 1 runge runge 364544 Jul 5 2005 ./Windows/util/vncviewer.exe -4621143 260 -rw-r--r-- 1 runge runge 262144 Sep 2 21:19 ./Windows/util/plink.exe -3293944 4 drwxr-xr-x 8 runge runge 4096 Sep 5 20:57 ./Windows/util/info -3293945 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:40 ./Windows/util/info/vncviewer -5538627 20 -rw-r--r-- 1 runge runge 18340 Jul 6 2005 ./Windows/util/info/vncviewer/LICENCE.txt -5538628 4 -rw-r--r-- 1 runge runge 1238 Jul 6 2005 ./Windows/util/info/vncviewer/README.txt -3294015 4 -rw-r--r-- 1 runge runge 24 Aug 2 09:39 ./Windows/util/info/vncviewer/location.url -3294016 4 -rw-r--r-- 1 runge runge 38 Aug 2 09:39 ./Windows/util/info/vncviewer/download.url -3293947 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:38 ./Windows/util/info/stunnel -3293948 4 -rw-r--r-- 1 runge runge 99 Aug 12 2002 ./Windows/util/info/stunnel/AUTHORS -3293949 4 -rw-r--r-- 1 runge runge 788 Sep 13 2002 ./Windows/util/info/stunnel/COPYING -3293950 20 -rw-r--r-- 1 runge runge 17982 Jul 18 2002 ./Windows/util/info/stunnel/COPYRIGHT.GPL -3293951 4 -rw-r--r-- 1 runge runge 199 Jul 18 2002 ./Windows/util/info/stunnel/CREDITS -3293952 4 -rw-r--r-- 1 runge runge 687 Jul 21 2005 ./Windows/util/info/stunnel/INSTALL.W32 -3293953 4 -rw-r--r-- 1 runge runge 725 Aug 12 2002 ./Windows/util/info/stunnel/README -3293954 28 -rw-r--r-- 1 runge runge 25682 Nov 2 2005 ./Windows/util/info/stunnel/ChangeLog -3293955 4 -rw-r--r-- 1 runge runge 1066 Aug 10 2002 ./Windows/util/info/stunnel/INSTALL -3293956 4 -rw-r--r-- 1 runge runge 955 Aug 12 2002 ./Windows/util/info/stunnel/NEWS -3293958 4 -rw-r--r-- 1 runge runge 222 Jul 18 2002 ./Windows/util/info/stunnel/PORTS -3293959 4 -rw-r--r-- 1 runge runge 1461 Jul 27 2005 ./Windows/util/info/stunnel/TODO -3293960 28 -rw-r--r-- 1 runge runge 26128 Sep 29 2005 ./Windows/util/info/stunnel/stunnel.html -3293969 16 -rw-r--r-- 1 runge runge 14638 Aug 2 09:37 ./Windows/util/info/stunnel/download.html -3294011 4 -rw-r--r-- 1 runge runge 47 Aug 2 09:15 ./Windows/util/info/stunnel/download.url -3294012 24 -rw-r--r-- 1 runge runge 21815 Aug 2 09:13 ./Windows/util/info/stunnel/location.html -3294013 4 -rw-r--r-- 1 runge runge 46 Aug 2 09:13 ./Windows/util/info/stunnel/location.url -3293961 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:37 ./Windows/util/info/openssl -3293965 4 -rw-r--r-- 1 runge runge 47 Aug 2 09:15 ./Windows/util/info/openssl/download.url -3293963 4 -rw-r--r-- 1 runge runge 46 Aug 2 09:13 ./Windows/util/info/openssl/location.url -3293964 4 -rw-r--r-- 1 runge runge 3489 Nov 28 2005 ./Windows/util/info/openssl/COPYRIGHT.SSLeay -3293967 16 -rw-r--r-- 1 runge runge 14638 Aug 2 09:37 ./Windows/util/info/openssl/download.html -3293962 24 -rw-r--r-- 1 runge runge 21815 Aug 2 09:13 ./Windows/util/info/openssl/location.html -2261824 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:36 ./Windows/util/info/plink -3293966 4 -rw-r--r-- 1 runge runge 3549 Aug 2 09:35 ./Windows/util/info/plink/licence.html -3293968 4 -rw-r--r-- 1 runge runge 65 Aug 2 09:35 ./Windows/util/info/plink/licence.url -2261825 28 -rw-r--r-- 1 runge runge 24744 Aug 2 09:35 ./Windows/util/info/plink/download.html -2261826 4 -rw-r--r-- 1 runge runge 66 Aug 2 09:35 ./Windows/util/info/plink/download.url -2229126 4 drwxr-xr-x 2 runge runge 4096 Sep 3 12:09 ./Windows/util/info/esound -2229127 20 -rw-r--r-- 1 runge runge 17992 Sep 3 12:09 ./Windows/util/info/esound/COPYING -2229128 4 -rw-r--r-- 1 runge runge 40 Sep 3 12:07 ./Windows/util/info/esound/download.url -2229129 28 -rw-r--r-- 1 runge runge 25265 Sep 3 12:09 ./Windows/util/info/esound/COPYING.LIB -2229130 4 -rw-r--r-- 1 runge runge 2153 Sep 3 12:09 ./Windows/util/info/esound/AUTHORS -2229131 4 -rw-r--r-- 1 runge runge 1936 Sep 3 12:09 ./Windows/util/info/esound/README -2229132 4 -rw-r--r-- 1 runge runge 178 Sep 3 12:09 ./Windows/util/info/esound/MAINTAINERS -3113803 4 drwxr-xr-x 2 runge runge 4096 Sep 5 20:58 ./Windows/util/info/netcat -3113804 8 -rw-r--r-- 1 runge runge 6833 Dec 27 2004 ./Windows/util/info/netcat/readme.txt -3113805 20 -rw-r--r-- 1 runge runge 18009 Dec 27 2004 ./Windows/util/info/netcat/license.txt -3064790 4 drwxr-xr-x 2 runge runge 4096 Aug 2 09:40 ./Windows/util/w98 -4621137 120 -rw-r--r-- 1 runge runge 118524 Feb 26 1997 ./Windows/util/w98/kill.exe -4621138 116 -rw-r--r-- 1 runge runge 114240 Feb 26 1997 ./Windows/util/w98/tlist.exe -3064797 24 -rw-r--r-- 1 runge runge 24576 Apr 30 1998 ./Windows/util/w98/README.DOC -3064799 4 -rw-r--r-- 1 runge runge 75 Aug 2 08:56 ./Windows/util/w98/location.url -4621140 4 -rw-r--r-- 1 runge runge 981 Aug 4 09:27 ./Windows/util/stunnel-server.conf -4621142 4 -rw-r--r-- 1 runge runge 1173 Aug 4 09:27 ./Windows/util/stunnel-client.conf -4621312 64 -rw-r--r-- 1 runge runge 61440 Dec 29 2004 ./Windows/util/netcat.exe -5538607 416 -rw-r--r-- 1 runge runge 421888 Sep 6 14:14 ./Windows/util/putty.exe diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1 b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1 deleted file mode 100644 index 60c60de..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1 +++ /dev/null @@ -1,233 +0,0 @@ -'\" t -.\" ** The above line should force tbl to be a preprocessor ** -.\" Man page for the SSVNC vncviewer -.\" -.\" Copyright (C) 2006-2009 Karl J. Runge <runge@karlrunge.com> -.\" -.\" You may distribute under the terms of the GNU General Public -.\" License as specified in the file LICENCE.TXT that comes with the -.\" TightVNC distribution. -.\" -.TH ssvnc 1 "December 2009" "" "SSVNC" -.SH NAME -ssvnc \- a GUI wrapper for SSL and SSH VNC connections. -.SH SYNOPSIS -.B ssvnc -.br -.B ssvnc -.RI [\| host \|][\| :display \|] -.br -.B ssvnc -.RI [\| saved-profile-name \|] -.br -.B ssvnc -.RI [\| options \|]\ [\| host-or-profile \] -.br -.B ssvnc -.IR \-cmd -.RI [\| ssvnc_cmd-args \|] -.br -.B ssvnc -.IR \--help -.br -.SH DESCRIPTION -.B ssvnc -is a tcl/tk gui wrapper that runs on Unix, MacOSX, and Windows. -It sets up an SSL or SSH tunnel to the remote VNC Server and then launches -the VNC viewer (either the one provided or another one that you have -specified) to use that encrypted tunnel to connect to the VNC Server. -The use of Proxies and Gateways to make the connections is implemented. - -Once you have started the SSVNC gui, you can click on the buttons -"Help", "Options -> Help", "Certs -> Help", etc. for much information -on how to use and configure the tool. - -In short, you supply a VNC server "hostname:display" in the -"VNC Host:Display" entry box and then press the "Connect" button to -connect to the server via SSL (stunnel). E.g. "far-away.east:0". -Port numbers are also allowed, e.g. far-away.east:5905. - -Or supply user@hostname:display and click on the "Use SSH" option, then -press the "Connect" button to connect to the server via an SSH tunnel. -E.g. "fred@far-away.east:0". - -Note it is also possible to disable the use of SSL/SSH -encryption tunnels by using a vnc:// or Vnc:// prefix before -host:display. Shift+Ctrl-E is a short-cut to add/remove it. -See also the \fB-noenc\fR option below for the 'No Encryption' button. - -Normally you do not specify any command line options. You simply -run \fBssvnc\fR and use the GUI that starts up. - -However, as shortcuts you can supply a VNC host:display (or host:port) -on the command line to connect to immediately (the GUI is started -and the connection is initiated). For example, "\fBssvnc far-away.east:0\fR" -Instead of a host:display, you can specify the name of a saved profile to -automatically load that profile and then connect to its server. -For example "\fBssvnc far\fR", if you named the profile "far". -You can use the \fB-profiles\fR option to list the profiles you have saved. - -The related commands \fBsshvnc\fR and \fBtsvnc\fR start up the GUI in -simplified modes: SSH Only Mode, and Terminal Services Mode, respectively. -See below and the application Help for more information on the modes. - -You can also place certain settings in your ~/.ssvncrc, see the -SSVNC Help panel ('Tips') for more info. - -The \fB-cmd\fR option does not start the GUI, it runs the command -line utility \fBssvnc_cmd\fR directly with the given arguments. -\fBssvnc_cmd\fR can launch the viewer directly (\fB-viewer ...\fR) -or, by default, the \fBss_vncviewer\fR SSL/SSH tunnel wrapper script. -See its help output for more information. - -There are also some command line options described as follows. -.SH OPTIONS -.TP -\fB\-help\fR, \fB\-h\fR -Prints out to the terminal a brief description and the options. -.TP -\fB\--help\fR -Starts up the GUI as though the 'Help' button was pressed to show the -main Help panel. -.TP -\fB\-cmd\fR \fI[ssvnc_cmd-args]\fR -Launch the ssvnc_cmd utility command directly (no GUI) with the given -arguments (for use when ssvnc_cmd is not in one's PATH.) If neither -ssvnc_cmd nor ssvncviewer is in PATH, one can launch the viewer -directly via: ssvnc -cmd -viewer [viewer-args] -.TP -\fB\-profiles\fR -List the saved SSVNC profiles you have created. A profile -is a destination host with specific parameter settings. -.TP -\fB\-list\fR -Same as \fB\-profiles\fR -.TP -\fB\-ssh\fR -Start in "SSH Only Mode". No SSL aspects are shown. -Same as running the command \fBsshvnc\fR -.TP -\fB\-ts\fR -Start in "Terminal Services Mode". This is like "SSH Only Mode", but -simpler and assumes \fBx11vnc\fR is available on the remote side -to start and manage X and VNC sessions. -Same as running the command \fBtsvnc\fR -.TP -\fB\-tso\fR -Same as \fB-ts\fR "Terminal Services Mode", however never let the -user leave this mode (no button to switch modes is provided.) -Same as SSVNC_TS_ALWAYS=1. -.TP -\fB\-ssl\fR -Force the full GUI Mode: both SSL and SSH. This is the default. -Same as \fB-ss\fR. -.TP -\fB\-nv\fR -Toggle the "Verify All Certs" button to be off at startup. -.TP -\fB\-nvb\fR -Never show the "Verify All Certs" button. -Same as SSVNC_NO_VERIFY_ALL_BUTTON=1. -.TP -\fB\-bigger\fR -Make the Profile Selection Dialog window bigger. -Same as SSVNC_BIGGER_DIALOG=1. -.TP -\fB\-noenc\fR -Start off in a mode where a 'No Encryption' check button is present. -You can toggle the mode with Ctrl-E. -Same as SSVNC_DISABLE_ENCRYPTION_BUTTON=1. Or \fInoenc=1\fR in ~/.ssvncrc. -Selecting no encryption is the same as the vnc:// and Vnc:// prefixes -described below. The \fB\-noenc\fR mode is now the default, use \fB-enc\fR -or \fInoenc=0\fR for the opposite behavior. -.TP -\fB\-killstunnel\fR -On Windows, automatically terminate the STUNNEL process when the viewer -exits instead of prompting you (same as \fIkillstunnel=1\fR in ssvnc_rc or -toggle in Options menu) -.TP -\fB\-nokillstunnel\fR -On Windows, disable \fB-killstunnel\fR mode. -Same as \fIkillstunnel=0\fR in ssvnc_rc or -toggle in Options menu. Note that \fB-killstunnel\fR mode is now the default. -.TP -\fB\-mycert\fR \fI/path/to/mycert.pem\fR -Set the default "MyCert" to be \fI/path/to/mycert.pem\fR. -Same as \fB-cert\fR. -If the file does not exist, ~/.vnc/certs is prefixed and tried. -You can also set \fImycert=/path/to/mycert.pem\fR in ~/.ssvncrc. -.TP -\fB\-cacert\fR \fI/path/to/cacert.crt\fR -Set the default "ServerCert" to be \fI/path/to/cacert.crt\fR. -Same as \fB-ca\fR. -If the file does not exist, ~/.vnc/certs is prefixed and tried. -You can also set \fIcacert=/path/to/cacert.crt\fR in ~/.ssvncrc. -.TP -\fB\-crl\fR \fI/path/to/mycrl.pem\fR -Set the default Certificate Revocation List to be \fI/path/to/mycrl.pem\fR. -If the file does not exist, ~/.vnc/certs is prefixed and tried. -You can also set \fIcrl=/path/to/mycrl.pem\fR in ~/.ssvncrc. -.SH URL NOTATION -Here are all of our URL-like prefixes that you can put in front of -host:display (or host:port): - -For SSL: vncs:// vncssl:// and vnc+ssl:// - -For SSH: vncssh:// and vnc+ssh:// - -For No Encryption: vnc:// and Vnc:// - -Examples: - -To quickly make an SSL connection: \fBssvnc vncs://snoopy.com:0\fR - -To quickly make an SSH connection: \fBssvnc vnc+ssh://fred@snoopy.com:0\fR - -To quickly make a direct connection: \fBssvnc Vnc://snoopy.com:0\fR - -The above will also work in the "VNC Host:Display" entry box in the GUI. -Press the "Connect" button after entering them. - -The difference between vnc:// and Vnc:// is that the latter one will not -prompt you whether you really want to make an unencrypted connection -or not. -.SH FILES -Your SSVNC vnc profiles are stored in the \fB$HOME/.vnc/profiles\fR -directory. They end in suffix \fB.vnc\fR - -Your SSVNC vnc certificates and keys are stored in the \fB$HOME/.vnc/certs\fR -directory. They typically end in \fB.pem\fR (both certificate and -private key) or \fB.crt\fR (certificate only). - -You can put a few global parameters (e.g. mode=sshvnc) in your -\fB$HOME/.ssvncrc\fR file (\fBssvnc_rc\fR on Windows); see the -application Help for more information. - -.SH FONTS - -The following is from Tip 18 in the Help panel. - -Fonts: To change the tk fonts, set these environment variables -before starting up ssvnc: SSVNC_FONT_DEFAULT and SSVNC_FONT_FIXED. -For example: - -% env SSVNC_FONT_DEFAULT='helvetica -20 bold' ssvnc - -% env SSVNC_FONT_FIXED='courier -14' ssvnc - -or set both of them at once. - -To achieve the same effect, you can also -set parameters in your ~/.ssvncrc file, for example: - -font_default=helvetica -20 bold - -font_fixed=courier -14 - -.SH SEE ALSO -\fBssvncviewer\fB(1), \fBvncviewer\fR(1), \fBstunnel\fR(8), \fBssh\fR(1), \fBx11vnc\fR(1), \fBvncserver\fR(1) -http://www.karlrunge.com/x11vnc http://www.karlrunge.com/x11vnc/ssvnc.html -.SH AUTHORS -Karl J. Runge <runge@karlrunge.com> wrote the SSVNC gui (tcl/tk) and -associated wrapper scripts, and added features to the unix vncviewer -source code. diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 b/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 deleted file mode 100644 index cdfc7ae..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1 +++ /dev/null @@ -1,829 +0,0 @@ -'\" t -.\" ** The above line should force tbl to be a preprocessor ** -.\" Man page for X vncviewer -.\" -.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de -.\" Copyright (C) 2000,2001 Red Hat, Inc. -.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru> -.\" Copyright (C) 2006-2010 Karl J. Runge <runge@karlrunge.com> -.\" -.\" You may distribute under the terms of the GNU General Public -.\" License as specified in the file LICENCE.TXT that comes with the -.\" TightVNC distribution. -.\" -.TH ssvncviewer 1 "April 2010" "" "SSVNC" -.SH NAME -ssvncviewer \- an X viewer client for VNC -.SH SYNOPSIS -.B ssvncviewer -.RI [\| options \|] -.RI [\| host \|][\| :display \|] -.br -.B ssvncviewer -.RI [\| options \|] -.RI [\| host \|][\| ::port \|] -.br -.B ssvncviewer -.RI [\| options \|] -.RI exec=[\| cmd+args... \|] -.br -.B ssvncviewer -.RI [\| options \|] -.RI fd=n -.br -.B ssvncviewer -.RI [\| options \|] -.RI /path/to/unix/socket -.br -.B ssvncviewer -.RI [\| options \|] -.IR \-listen -.RI [\| display \|] -.br -.B ssvncviewer -.IR \-help -.br -.SH DESCRIPTION -.B ssvncviewer -is an Xt\-based client application for the VNC (Virtual Network -Computing) system. It can connect to any VNC\-compatible server such -as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment -of a different machine. - -ssvncviewer is an enhanced version of the tightvnc unix viewer that can -take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers. -See below for the description of these features. - -You can use F8 to display a pop\-up utility menu. Press F8 twice to -pass single F8 to the remote side. -.SH OPTIONS -.TP -\fB\-help\fR -Prints a short usage notice to stderr. -.TP -\fB\-listen\fR -Make the viewer listen on port 5500+\fIdisplay\fR for reverse -connections from a server. WinVNC supports reverse connections using -the "Add New Client" menu option, or the \-connect command line -option. \fBXvnc\fR requires the use of the helper program -\fBvncconnect\fR. -.TP -\fB\-via\fR \fIgateway\fR -Automatically create encrypted TCP tunnel to the \fIgateway\fR machine -before connection, connect to the \fIhost\fR through that tunnel -(TightVNC\-specific). By default, this option invokes SSH local port -forwarding, assuming that SSH client binary can be accessed as -/usr/bin/ssh. Note that when using the \fB\-via\fR option, the host -machine name should be specified as known to the gateway machine, e.g. -"localhost" denotes the \fIgateway\fR, not the machine where vncviewer -was launched. See the ENVIRONMENT section below for the information on -configuring the \fB\-via\fR option. -.TP -\fB\-shared\fR -When connecting, specify that a shared connection is requested. In -TightVNC, this is the default mode, allowing you to share the desktop -with other clients already using it. -.TP -\fB\-noshared\fR -When connecting, specify that the session may not be shared. This -would either disconnect other connected clients or refuse your -connection, depending on the server configuration. -.TP -\fB\-viewonly\fR -Disable transfer of mouse and keyboard events from the client to the -server. -.TP -\fB\-fullscreen\fR -Start in full\-screen mode. Please be aware that operating in -full\-screen mode may confuse X window managers. Typically, such -conflicts cause incorrect handling of input focus or make the viewer -window disappear mysteriously. See the grabKeyboard setting in the -RESOURCES section below for a method to solve input focus problem. -.TP -\fB\-noraiseonbeep\fR -By default, the viewer shows and raises its window on remote beep -(bell) event. This option disables such behaviour -(TightVNC\-specific). -.TP -\fB\-user\fR \fIusername\fR -User name for Unix login authentication. Default is to use current -Unix user name. If this option was given, the viewer will prefer Unix -login authentication over the standard VNC authentication. -.TP -\fB\-passwd\fR \fIpasswd\-file\fR -File from which to get the password (as generated by the -\fBvncpasswd\fR(1) program). This option affects only the standard VNC -authentication. -.TP -\fB\-encodings\fR \fIencoding\-list\fR -TightVNC supports several different compression methods to encode -screen updates; this option specifies a set of them to use in order of -preference. Encodings are specified separated with spaces, and must -thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces. -Available encodings, in default order for a remote connection, are -"copyrect tight hextile zlib corre rre raw". For a local connection -(to the same machine), the default order to try is "raw copyrect tight -hextile zlib corre rre". Raw encoding is always assumed as a last option -if no other encoding can be used for some reason. For more information -on encodings, see the section ENCODINGS below. -.TP -\fB\-bgr233\fR -Always use the BGR233 format to encode pixel data. This reduces -network traffic, but colors may be represented inaccurately. The -bgr233 format is an 8\-bit "true color" format, with 2 bits blue, 3 -bits green, and 3 bits red. -.TP -\fB\-owncmap\fR -Try to use a PseudoColor visual and a private colormap. This allows -the VNC server to control the colormap. -.TP -\fB\-truecolour\fR, \fB\-truecolor\fR -Try to use a TrueColor visual. -.TP -\fB\-depth\fR \fIdepth\fR -On an X server which supports multiple TrueColor visuals of different -depths, attempt to use the specified one (in bits per pixel); if -successful, this depth will be requested from the VNC server. -.TP -\fB\-compresslevel \fIlevel\fR -Use specified compression \fIlevel\fR (0..9) for "tight" and "zlib" -encodings (TightVNC\-specific). Level 1 uses minimum of CPU time and -achieves weak compression ratios, while level 9 offers best -compression but is slow in terms of CPU time consumption on the server -side. Use high levels with very slow network connections, and low -levels when working over high\-speed LANs. It's not recommended to use -compression level 0, reasonable choices start from the level 1. -.TP -\fB\-quality \fIlevel\fR -Use the specified JPEG quality \fIlevel\fR (0..9) for the "tight" -encoding (TightVNC\-specific). Quality level 0 denotes bad image -quality but very impressive compression ratios, while level 9 offers -very good image quality at lower compression ratios. Note that the -"tight" encoder uses JPEG to encode only those screen areas that look -suitable for lossy compression, so quality level 0 does not always -mean unacceptable image quality. -.TP -\fB\-nojpeg\fR -Disable lossy JPEG compression in Tight encoding (TightVNC\-specific). -Disabling JPEG compression is not a good idea in typical cases, as -that makes the Tight encoder less efficient. You might want to use -this option if it's absolutely necessary to achieve perfect image -quality (see also the \fB\-quality\fR option). -.TP -\fB\-nocursorshape\fR -Disable cursor shape updates, protocol extensions used to handle -remote cursor movements locally on the client side -(TightVNC\-specific). Using cursor shape updates decreases delays with -remote cursor movements, and can improve bandwidth usage dramatically. -.TP -\fB\-x11cursor\fR -Use a real X11 cursor with X-style cursor shape updates, instead of -drawing the remote cursor on the framebuffer. This option also -disables the dot cursor, and disables cursor position updates in -non-fullscreen mode. -.TP -\fB\-autopass\fR -Read a plain-text password from stdin. This option affects only the -standard VNC authentication. - -.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS -.TP -Enhanced TightVNC Viewer (SSVNC) web page is located at: -.TP -http://www.karlrunge.com/x11vnc/ssvnc.html -.TP -Note: ZRLE and ZYWRLE encodings are now supported. -.TP -Note: F9 is shortcut to Toggle FullScreen mode. -.TP -Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1 -to allow more than one incoming VNC server at a time. -This is the same as -multilisten described below. Set -SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than "n" -simultaneous reverse connections. - -If the host:port is specified as "exec=command args..." -then instead of making a TCP/IP socket connection to the -remote VNC server, "command args..." is executed and the -viewer is attached to its stdio. This enables tunnelling -established via an external command, e.g. an stunnel(8) -that does not involve a listening socket. -This mode does not work for -listen reverse connections. - -If the host:port is specified as "fd=n" then it is assumed -n is an already opened file descriptor to the socket. (i.e -the parent did fork+exec) - -If the host:port contains a '/' it is interpreted as a -unix-domain socket (AF_LOCAL insead of AF_INET) -.TP -\fB\-multilisten\fR -As in -listen (reverse connection listening) except -allow more than one incoming VNC server to be connected -at a time. The default for -listen of only one at a -time tries to play it safe by not allowing anyone on -the network to put (many) desktops on your screen over -a long window of time. Use -multilisten for no limit. -.TP -\fB\-acceptpopup\fR -In \fB\-listen\fR (reverse connection listening) mode when -a reverse VNC connection comes in show a popup asking -whether to Accept or Reject the connection. The IP -address of the connecting host is shown. Same as -setting the env. var. SSVNC_ACCEPT_POPUP=1. -.TP -\fB\-acceptpopupsc\fR -As in \fB\-acceptpopup\fR except assume UltraVNC Single -Click (SC) server. Retrieve User and ComputerName -info from UltraVNC Server and display in the Popup. -.TP -\fB\-use64\fR -In \fB\-bgr233\fR mode, use 64 colors instead of 256. -.TP -\fB\-bgr222\fR -Same as \fB\-use64\fR. -.TP -\fB\-use8\fR -In \fB\-bgr233\fR mode, use 8 colors instead of 256. -.TP -\fB\-bgr111\fR -Same as \fB\-use8\fR. -.TP -\fB\-16bpp\fR -If the vnc viewer X display is depth 24 at 32bpp -request a 16bpp format from the VNC server to cut -network traffic by up to 2X, then tranlate the -pixels to 32bpp locally. -.TP -\fB\-bgr565\fR -Same as \fB\-16bpp\fR. -.TP -\fB\-grey\fR -Use a grey scale for the 16- and 8\fB\-bpp\fR modes. -.TP -\fB\-alpha\fR -Use alphablending transparency for local cursors -requires: x11vnc server, both client and server -must be 32bpp and same endianness. -.TP -\fB\-scale\fR \fIstr\fR -Scale the desktop locally. The string "str" can -a floating point ratio, e.g. "0.9", or a fraction, -e.g. "3/4", or WxH, e.g. 1280x1024. Use "fit" -to fit in the current screen size. Use "auto" to -fit in the window size. "str" can also be set by -the env. var. SSVNC_SCALE. - -If you observe mouse trail painting errors, enable -X11 Cursor mode (either via Popup or \fB\-x11cursor\fR.) - -Note that scaling is done in software and so can be -slow and requires more memory. Some speedup Tips: - -ZRLE is faster than Tight in this mode. When -scaling is first detected, the encoding will -be automatically switched to ZRLE. Use the -Popup menu if you want to go back to Tight. -Set SSVNC_PRESERVE_ENCODING=1 to disable this. - -Use a solid background on the remote side. -(e.g. manually or via x11vnc \fB\-solid\fR ...) - -If the remote server is x11vnc, try client -side caching: x11vnc \fB\-ncache\fR 10 ... -.TP -\fB\-ycrop\fR n -Only show the top n rows of the framebuffer. For -use with x11vnc \fB\-ncache\fR client caching option -to help "hide" the pixel cache region. -Use a negative value (e.g. \fB\-1\fR) for autodetection. -Autodetection will always take place if the remote -fb height is more than 2 times the width. -.TP -\fB\-sbwidth\fR n -Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR), -default is very narrow: 2 pixels, it is narrow to -avoid distraction in \fB\-ycrop\fR mode. -.TP -\fB\-nobell\fR -Disable bell. -.TP -\fB\-rawlocal\fR -Prefer raw encoding for localhost, default is -no, i.e. assumes you have a SSH tunnel instead. -.TP -\fB\-notty\fR -Try to avoid using the terminal for interactive -responses: use windows for messages and prompting -instead. Messages will also be printed to terminal. -.TP -\fB\-sendclipboard\fR -Send the X CLIPBOARD selection (i.e. Ctrl+C, -Ctrl+V) instead of the X PRIMARY selection (mouse -select and middle button paste.) -.TP -\fB\-sendalways\fR -Whenever the mouse enters the VNC viewer main -window, send the selection to the VNC server even if -it has not changed. This is like the Xt resource -translation SelectionToVNC(always) -.TP -\fB\-recvtext\fR -str When cut text is received from the VNC server, -ssvncviewer will set both the X PRIMARY and the -X CLIPBOARD local selections. To control which -is set, specify 'str' as 'primary', 'clipboard', -or 'both' (the default.) -.TP -\fB\-graball\fR -Grab the entire X server when in fullscreen mode, -needed by some old window managers like fvwm2. -.TP -\fB\-popupfix\fR -Warp the popup back to the pointer position, -needed by some old window managers like fvwm2. -.TP -\fB\-grabkbd\fR -Grab the X keyboard when in fullscreen mode, -needed by some window managers. Same as \fB\-grabkeyboard\fR. -\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable. -.TP -\fB\-bs\fR, \fB\-nobs\fR -Whether or not to use X server Backingstore for the -main viewer window. The default is to not, mainly -because most Linux, etc, systems X servers disable -*all* Backingstore by default. To re\fB\-enable\fR it put - -Option "Backingstore" - -in the Device section of /etc/X11/xorg.conf. -In \fB\-bs\fR mode with no X server backingstore, whenever an -area of the screen is re\fB\-exposed\fR it must go out to the -VNC server to retrieve the pixels. This is too slow. - -In \fB\-nobs\fR mode, memory is allocated by the viewer to -provide its own backing of the main viewer window. This -actually makes some activities faster (changes in large -regions) but can appear to "flash" too much. -.TP -\fB\-noshm\fR -Disable use of MIT shared memory extension (not recommended) -.TP -\fB\-termchat\fR -Do the UltraVNC chat in the terminal vncviewer is in -instead of in an independent window. -.TP -\fB\-unixpw\fR \fIstr\fR -Useful for logging into x11vnc in \fB\-unixpw\fR mode. "str" is a -string that allows many ways to enter the Unix Username -and Unix Password. These characters: username, newline, -password, newline are sent to the VNC server after any VNC -authentication has taken place. Under x11vnc they are -used for the \fB\-unixpw\fR login. Other VNC servers could do -something similar. - -You can also indicate "str" via the environment -variable SSVNC_UNIXPW. - -Note that the Escape key is actually sent first to tell -x11vnc to not echo the Unix Username back to the VNC -viewer. Set SSVNC_UNIXPW_NOESC=1 to override this. - -If str is ".", then you are prompted at the command line -for the username and password in the normal way. If str is -"-" the stdin is read via getpass(3) for username@password. -Otherwise if str is a file, it is opened and the first line -read is taken as the Unix username and the 2nd as the -password. If str prefixed by "rm:" the file is removed -after reading. Otherwise, if str has a "@" character, -it is taken as username@password. Otherwise, the program -exits with an error. Got all that? -.TP -\fB-repeater\fR \fIstr\fR -This is for use with UltraVNC repeater proxy described -here: http://www.uvnc.com/addons/repeater.html. The "str" -is the ID string to be sent to the repeater. E.g. ID:1234 -It can also be the hostname and port or display of the VNC -server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when -using -repeater, the host:dpy on the cmdline is the repeater -server, NOT the VNC server. The repeater will connect you. - -Example: vncviewer ... -repeater ID:3333 repeat.host:5900 - -Example: vncviewer ... -repeater vhost:0 repeat.host:5900 - -Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a -Single Click III (SSL) repeater (repeater_SSL.exe) and you -are passing the SSL part of the connection through stunnel, socat, etc. -This way the magic UltraVNC string 'testB' needed to work with the -repeater is sent to it. -.TP -\fB-rfbversion\fR \fIstr\fR -Set the advertised RFB version. E.g.: -rfbversion 3.6 For some -servers, e.g. UltraVNC this needs to be done. -.TP -\fB-ultradsm\fR -UltraVNC has symmetric private encryption DSM plugins. See -http://www.uvnc.com/features/encryption.html. It is assumed -you are using a unix program (e.g. our ultravnc_dsm_helper) to -encrypt and decrypt the UltraVNC DSM stream. IN ADDITION TO -THAT supply -ultradsm to tell THIS viewer to modify the RFB -data sent so as to work with the UltraVNC Server. For some -reason, each RFB msg type must be sent twice under DSM. -.TP -\fB\-mslogon\fR \fIuser\fR -Use Windows MS Logon to an UltraVNC server. Supply the -username or "1" to be prompted. The default is to -autodetect the UltraVNC MS Logon server and prompt for -the username and password. - -IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman -exchange is very weak and can be brute forced to recover -your username and password in a few seconds of CPU -time. To be safe, be sure to use an additional encrypted -tunnel (e.g. SSL or SSH) for the entire VNC session. -.TP -\fB\-chatonly\fR -Try to be a client that only does UltraVNC text chat. This -mode is used by x11vnc to present a chat window on the physical -X11 console (i.e. to chat with the person at the display). -.TP -\fB-env\fR \fIVAR=VALUE\fR -To save writing a shell script to set environment -variables, specify as many as you need on the command line. For example, --env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi -.TP -\fB\-noipv6\fR -Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1. -.TP -\fB\-noipv4\fR -Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1. -.TP -\fB\-printres\fR -Print out the Ssvnc X resources (appdefaults) and -then exit. You can save them to a file and customize them (e.g. the -keybindings and Popup menu) Then point to the file via -XENVIRONMENT or XAPPLRESDIR. -.TP -\fB\-pipeline\fR -Like TurboVNC, request the next framebuffer update as soon -as possible instead of waiting until the end of the current -framebuffer update coming in. Helps 'pipeline' the updates. -This is currently the default, use \fB-nopipeline\fR to disable. -.TP -\fB\-appshare\fR -Enable features for use with x11vnc's \fB\-appshare\fR mode where -instead of sharing the full desktop only the application's -windows are shared. Viewer multilisten mode is used to -create the multiple windows: \fB\-multilisten\fR is implied. -See 'x11vnc \fB\-appshare\fR \fB\-help\fR' more information on the mode. -Features enabled in the viewer under \fB\-appshare\fR are: -Minimum extra text in the title, auto \fB\-ycrop\fR is disabled, -x11vnc \fB\-remote_prefix\fR X11VNC_APPSHARE_CMD: message channel, -x11vnc initial window position hints. See also Escape Keys -below for additional key and mouse bindings. -.TP -\fB\-escape \fR\fIstr\fR -This sets the 'Escape Keys' modifier sequence and enables -escape keys mode. When the modifier keys escape sequence -is held down, the next keystroke is interpreted locally -to perform a special action instead of being sent to the -remote VNC server. - -Use '\fB\-escape\fR default' for the default modifier sequence. -(Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L) - -Here are the 'Escape Keys: Help+Set' instructions from the Popup: - -Escape Keys: Enter a comma separated list of modifier keys to be the 'escape -sequence'. When these keys are held down, the next keystroke is -interpreted locally to invoke a special action instead of being sent to -the remote VNC server. In other words, a set of 'Hot Keys'. - -Here is the list of local key mappings to special actions: - -r: refresh desktop b: toggle bell c: toggle full-color - -f: file transfer x: x11cursor z: toggle Tight/ZRLE - -l: full screen g: graball e: escape keys dialog - -s: scale dialog +: scale up (=) -: scale down (_) - -t: text chat a: alphablend cursor - -V: toggle viewonly Q: quit viewer 123456: UltraVNC scale 1/n - -Arrow keys: pan the viewport about 10% for each keypress. - -PageUp/PageDown: pan the viewport by a screenful vertically. - -Home/End: pan the viewport by a screenful horizontally. - -KeyPad Arrows: pan the viewport by 1 pixel for each keypress. - -Dragging the Mouse with Button1 pressed also pans the viewport. - -Clicking Mouse Button3 brings up the Popup Menu. - -The above mappings are \fBalways\fR active in ViewOnly mode, unless you set -the Escape Keys value to 'never'. - -x11vnc -appshare hot-keys: x11vnc has a simple application sharing mode -that enables the viewer-side to move, resize, or raise the remote toplevel -windows. To enable it, hold down Shift + the Escape Keys and press these: - -Arrow keys: move the remote window around in its desktop. - -PageUp/PageDn/Home/End: resize the remote window. - -+/-: raise or lower the remote window. - -M or Button1 move win to local position; D or Button3: delete remote win. - -If the Escape Keys value below is set to 'default' then a default list of -of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it -is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag -on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side -of the keyboard. - -On Unix the default is Alt and Windows keys on Left side of keyboard. -On MacOSX the default is Control and Command keys on Left side of keyboard. - -Example: Press and hold the Alt and Windows keys on the LEFT side of the -keyboard and then press 'c' to toggle the full-color state. Or press 't' -to toggle the ultravnc Text Chat window, etc. - -To use something besides the default, supply a comma separated list (or a -single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L -Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch. -.TP -\fB New Popup actions:\fR - - ViewOnly: ~ -viewonly - Disable Bell: ~ -nobell - Cursor Shape: ~ -nocursorshape - X11 Cursor: ~ -x11cursor - Cursor Alphablend: ~ -alpha - Toggle Tight/Hextile: ~ -encodings hextile... - Toggle Tight/ZRLE: ~ -encodings zrle... - Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... - Quality Level ~ -quality (both Tight and ZYWRLE) - Compress Level ~ -compresslevel - Disable JPEG: ~ -nojpeg (Tight) - Pipeline Updates ~ -pipeline - - Full Color as many colors as local screen allows. - Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only. - 16 bit color (BGR565) ~ -16bpp / -bgr565 - 8 bit color (BGR233) ~ -bgr233 - 256 colors ~ -bgr233 default # of colors. - 64 colors ~ -bgr222 / -use64 - 8 colors ~ -bgr111 / -use8 - Scale Viewer ~ -scale - Escape Keys: Toggle ~ -escape - Escape Keys: Help+Set ~ -escape - Set Y Crop (y-max) ~ -ycrop - Set Scrollbar Width ~ -sbwidth - XGrabServer ~ -graball - - UltraVNC Extensions: - - Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n. - Text Chat Ultravnc ext. Do Text Chat. - File Transfer Ultravnc ext. File xfer via Java helper. - Single Window Ultravnc ext. Grab and view a single window. - (select then click on the window you want). - Disable Remote Input Ultravnc ext. Try to prevent input and - viewing of monitor at physical display. - - Note: the Ultravnc extensions only apply to servers that support - them. x11vnc/libvncserver supports some of them. - - Send Clipboard not Primary ~ -sendclipboard - Send Selection Every time ~ -sendalways - -.SH ENCODINGS -The server supplies information in whatever format is desired by the -client, in order to make the client as easy as possible to implement. -If the client represents itself as able to use multiple formats, the -server will choose one. - -.I Pixel format -refers to the representation of an individual pixel. The most common -formats are 24 and 16 bit "true\-color" values, and 8\-bit "color map" -representations, where an arbitrary map converts the color number to -RGB values. - -.I Encoding -refers to how a rectangle of pixels are sent (all pixel information in -VNC is sent as rectangles). All rectangles come with a header giving -the location and size of the rectangle and an encoding type used by -the data which follows. These types are listed below. -.TP -.B Raw -The raw encoding simply sends width*height pixel values. All clients -are required to support this encoding type. Raw is also the fastest -when the server and viewer are on the same machine, as the connection -speed is essentially infinite and raw encoding minimizes processing -time. -.TP -.B CopyRect -The Copy Rectangle encoding is efficient when something is being -moved; the only data sent is the location of a rectangle from which -data should be copied to the current location. Copyrect could also be -used to efficiently transmit a repeated pattern. -.TP -.B RRE -The Rise\-and\-Run\-length\-Encoding is basically a 2D version of -run\-length encoding (RLE). In this encoding, a sequence of identical -pixels are compressed to a single value and repeat count. In VNC, this -is implemented with a background color, and then specifications of an -arbitrary number of subrectangles and color for each. This is an -efficient encoding for large blocks of constant color. -.TP -.B CoRRE -This is a minor variation on RRE, using a maximum of 255x255 pixel -rectangles. This allows for single\-byte values to be used, reducing -packet size. This is in general more efficient, because the savings -from sending 1\-byte values generally outweighs the losses from the -(relatively rare) cases where very large regions are painted the same -color. -.TP -.B Hextile -Here, rectangles are split up in to 16x16 tiles, which are sent in a -predetermined order. The data within the tiles is sent either raw or -as a variant on RRE. Hextile encoding is usually the best choice for -using in high\-speed network environments (e.g. Ethernet local\-area -networks). -.TP -.B Zlib -Zlib is a very simple encoding that uses zlib library to compress raw -pixel data. This encoding achieves good compression, but consumes a -lot of CPU time. Support for this encoding is provided for -compatibility with VNC servers that might not understand Tight -encoding which is more efficient than Zlib in nearly all real\-life -situations. -.TP -.B Tight -Like Zlib encoding, Tight encoding uses zlib library to compress the -pixel data, but it pre\-processes data to maximize compression ratios, -and to minimize CPU usage on compression. Also, JPEG compression may -be used to encode color\-rich screen areas (see the description of -\-quality and \-nojpeg options above). Tight encoding is usually the -best choice for low\-bandwidth network environments (e.g. slow modem -connections). -.TP -.B ZRLE -The SSVNC viewer has ported the RealVNC (www.realvnc.com) ZRLE encoding -to the unix tightvnc viewer. -.TP -.B ZYWRLE -The SSVNC viewer has ported the Hitachi lossy wavelet based ZRLE -encoding from http://mobile.hitachi-system.co.jp/publications/ZYWRLE/ -to the unix tightvnc viewer. -.SH RESOURCES -X resources that \fBvncviewer\fR knows about, aside from the -normal Xt resources, are as follows: -.TP -.B shareDesktop -Equivalent of \fB\-shared\fR/\fB\-noshared\fR options. Default true. -.TP -.B viewOnly -Equivalent of \fB\-viewonly\fR option. Default false. -.TP -.B fullScreen -Equivalent of \fB\-fullscreen\fR option. Default false. -.TP -.B grabKeyboard -Grab keyboard in full-screen mode. This can help to solve problems -with losing keyboard focus. Default false. -.TP -.B raiseOnBeep -Equivalent of \fB\-noraiseonbeep\fR option, when set to false. Default -true. -.TP -.B passwordFile -Equivalent of \fB\-passwd\fR option. -.TP -.B userLogin -Equivalent of \fB\-user\fR option. -.TP -.B passwordDialog -Whether to use a dialog box to get the password (true) or get it from -the tty (false). Irrelevant if \fBpasswordFile\fR is set. Default -false. -.TP -.B encodings -Equivalent of \fB\-encodings\fR option. -.TP -.B compressLevel -Equivalent of \fB\-compresslevel\fR option (TightVNC\-specific). -.TP -.B qualityLevel -Equivalent of \fB\-quality\fR option (TightVNC\-specific). -.TP -.B enableJPEG -Equivalent of \fB\-nojpeg\fR option, when set to false. Default true. -.TP -.B useRemoteCursor -Equivalent of \fB\-nocursorshape\fR option, when set to false -(TightVNC\-specific). Default true. -.TP -.B useBGR233 -Equivalent of \fB\-bgr233\fR option. Default false. -.TP -.B nColours -When using BGR233, try to allocate this many "exact" colors from the -BGR233 color cube. When using a shared colormap, setting this resource -lower leaves more colors for other X clients. Irrelevant when using -truecolor. Default is 256 (i.e. all of them). -.TP -.B useSharedColours -If the number of "exact" BGR233 colors successfully allocated is less -than 256 then the rest are filled in using the "nearest" colors -available. This resource says whether to only use the "exact" BGR233 -colors for this purpose, or whether to use other clients' "shared" -colors as well. Default true (i.e. use other clients' colors). -.TP -.B forceOwnCmap -Equivalent of \fB\-owncmap\fR option. Default false. -.TP -.B forceTrueColour -Equivalent of \fB\-truecolour\fR option. Default false. -.TP -.B requestedDepth -Equivalent of \fB\-depth\fR option. -.TP -.B useSharedMemory -Use MIT shared memory extension if on the same machine as the X -server. Default true. -.TP -.B wmDecorationWidth, wmDecorationHeight -The total width and height taken up by window manager decorations. -This is used to calculate the maximum size of the VNC viewer window. -Default is width 4, height 24. -.TP -.B bumpScrollTime, bumpScrollPixels -When in full screen mode and the VNC desktop is bigger than the X -display, scrolling happens whenever the mouse hits the edge of the -screen. The maximum speed of scrolling is bumpScrollPixels pixels -every bumpScrollTime milliseconds. The actual speed of scrolling will -be slower than this, of course, depending on how fast your machine is. -Default 20 pixels every 25 milliseconds. -.TP -.B popupButtonCount -The number of buttons in the popup window. See the README file for -more information on how to customize the buttons. -.TP -.B debug -For debugging. Default false. -.TP -.B rawDelay, copyRectDelay -For debugging, see the README file for details. Default 0 (off). -.SH ENVIRONMENT -When started with the \fB\-via\fR option, vncviewer reads the -\fBVNC_VIA_CMD\fR environment variable, expands patterns beginning -with the "%" character, and executes result as a command assuming that -it would create TCP tunnel that should be used for VNC connection. If -not set, this environment variable defaults to "/usr/bin/ssh -f -L -%L:%H:%R %G sleep 20". - -The following patterns are recognized in the \fBVNC_VIA_CMD\fR (note -that all the patterns %G, %H, %L and %R must be present in the command -template): -.TP -.B %% -A literal "%"; -.TP -.B %G -gateway host name; -.TP -.B %H -remote VNC host name, as known to the gateway; -.TP -.B %L -local TCP port number; -.TP -.B %R -remote TCP port number. -.SH SEE ALSO -\fBvncserver\fR(1), \fBx11vnc\fR(1), \fBssvnc\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1), -\fBvncconnect\fR(1), \fBssh\fR(1), http://www.karlrunge.com/x11vnc, http://www.karlrunge.com/x11vnc/ssvnc.html -.SH AUTHORS -Original VNC was developed in AT&T Laboratories Cambridge. TightVNC -additions was implemented by Constantin Kaplinsky. Many other people -participated in development, testing and support. Karl J. Runge -added all of the SSVNC related features and improvements. - -\fBMan page authors:\fR -.br -Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>, -.br -Terran Melconian <terran@consistent.org>, -.br -Tim Waugh <twaugh@redhat.com>, -.br -Constantin Kaplinsky <const@ce.cctpu.edu.ru> -.br -Karl J. Runge <runge@karlrunge.com> diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/README b/x11vnc/misc/enhanced_tightvnc_viewer/src/README deleted file mode 100644 index 6630db9..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/README +++ /dev/null @@ -1,7 +0,0 @@ - -In this directory we have source zip/tgz files in zip/, the patches -we created in patches/, a temporary build dir (used by build.unix) -in tmp/, and unpacked sources in vnc_unixsrc/ and stunnel-4.14/ (used -by the build.unix script). - -See the README in the directory one level up for more information. diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README deleted file mode 100644 index 9451e7e..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README +++ /dev/null @@ -1,6 +0,0 @@ -All of the patch files and scripts in this directory are - - Copyright (c) 2006 by Karl J. Runge <runge@karlrunge.com> - -and are licensed by the GPL. See the README and COPYING files two -directories up for more information. diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle deleted file mode 100755 index 60fc7c3..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle +++ /dev/null @@ -1,103 +0,0 @@ -#!/bin/sh - -rm -rf ./src/tmp/* || exit 1 -vers=1.0.28 - -cd .. || exit 1 - -cp -p ssvnc/bin/ssvnc_cmd ssvnc/bin/tightvncviewer - -########################################### -dest=./t.unix_only -rm -rf $dest -mkdir -p $dest || exit 1 - -tar cvf - ssvnc/{README,COPYING,ssvnc.desktop} ssvnc/bin ssvnc/Unix | (cd $dest; tar xvf -) -rm -f $dest/ssvnc/bin/.linkin - -tar=ssvnc_unix_only-${vers}.tar.gz -(cd $dest; tar czvf ../$tar ssvnc) -ls -l $tar -rm -rf $dest - -########################################### -dest=./t.unix_minimal -rm -rf $dest -mkdir -p $dest || exit 1 - -tar cvf - ssvnc/{README,COPYING,ssvnc.desktop} ssvnc/bin/{ss*,util/ss*} | (cd $dest; tar xvf -) - -tar=ssvnc_unix_minimal-${vers}.tar.gz -(cd $dest; tar czvf ../$tar ssvnc) -ls -l $tar -rm -rf $dest - -top='#!/bin/sh -n=11 -tmp=`mktemp -d "/tmp/ssvnc.XXXXXX"` || exit 1 -if [ "X$tmp" = "X" -o ! -d "$tmp" ]; then exit 1; fi -trap "cd /tmp; rm -rf $tmp" 0 2 15 - -tail +$n "$0" | (cd $tmp; tar xf -) || exit 1 -$tmp/bin/ssvnc "$@" -exit 0 -data__() {' - -scr=./ssvnc.sh -echo "$top" > $scr -(cd ssvnc; tar cvf - README COPYING ssvnc.desktop bin/{ss*,util/ss*}) >> $scr -chmod 755 $scr -ls -l $scr - -if [ "X$1" = "Xquick" ]; then - exit 0 -fi - -########################################### -rm -f ssvnc_all-$vers.zip -rm -f ssvnc-$vers.zip -zip -9 -r ssvnc_all-$vers.zip ssvnc -zip -9 -r ssvnc-$vers.zip ssvnc -x '*.zip' '*.tar.gz' -tar cvf - --exclude='*.zip' --exclude='*.tar.gz' ssvnc | gzip -9 > ssvnc-$vers.tar.gz -tar cvf - --exclude='*.zip' --exclude='*.tar.gz' --exclude='*.dll' --exclude='*.exe' --exclude ssvnc/Windows/util ssvnc | gzip -9 > ssvnc_no_windows-$vers.tar.gz - -echo -ls -l ssvnc*-$vers.* -echo - - -########################################### -dest=./t.windows_only -rm -rf ${dest} -mkdir -p $dest || exit 1 - -cp -pR ssvnc $dest -rm -rf $dest/ssvnc/{src,bin,man} -rm -rf $dest/ssvnc/MacOSX -rm -rf $dest/ssvnc/Unix -rm -f $dest/ssvnc/build.unix -rm -f $dest/ssvnc/filelist.txt -cp -p ssvnc/bin/util/ssvnc.tcl $dest/ssvnc/Windows/util - -zip=ssvnc_windows_only-${vers}.zip -rm -f $zip -(cd $dest; zip -9 -r ../$zip ssvnc) - -ls -l $zip -rm -rf $dest - - -sync -echo -for g in ssvnc*-$vers*.gz -do - md5sum $g - gzip -t $g || (tput bel; sleep 2) -done -for g in ssvnc*-$vers*.zip -do - md5sum $g -done - -sleep 3 -echo diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches deleted file mode 100755 index d12e1d1..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -if [ ! -f ./_getpatches ]; then - ls -l ./_getpatches - exit 1 -fi - -cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/tight-vncviewer*patch . -cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/vnc_unixsrc_vncviewer.patched.tar ../zips/ - -cp -p /dist/src/apps/VNC/etc/libvncserver_cvs/expts/java_ssl/ultra/ultraftp.tar ../zips/ -cp -p /dist/src/apps/VNC/etc/libvncserver_cvs/expts/vncstorepw.tar ../zips/ - -cp -p /dist/src/apps/VNC/tight_vnc_1.3dev5/vnc_unixsrc/vncviewer/vncviewer.man ../../man/man1/ssvncviewer.1 diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied deleted file mode 100755 index 0ff1931..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -make clean -rm -f *.o -cd ../.. -tar -cvf ../../zips/vnc_unixsrc_vncviewer.patched.tar vnc_unixsrc/vncviewer diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.patch deleted file mode 100644 index 42657d8..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff -Naur stunnel.orig/src/client.c stunnel/src/client.c ---- stunnel.orig/src/client.c 2010-04-04 17:00:29.000000000 -0400 -+++ stunnel/src/client.c 2010-04-12 17:12:47.000000000 -0400 -@@ -187,6 +187,7 @@ - enter_critical_section(CRIT_CLIENTS); /* for multi-cpu machines */ - s_log(LOG_DEBUG, "Service %s finished (%d left)", c->opt->servname, - --num_clients); -+ if (getenv("STUNNEL_ONCE")) {fprintf(stderr, "stunnel: exiting.\n"); exit(0);} - leave_critical_section(CRIT_CLIENTS); - #endif - } -diff -Naur stunnel.orig/src/network.c stunnel/src/network.c ---- stunnel.orig/src/network.c 2010-02-04 05:31:45.000000000 -0500 -+++ stunnel/src/network.c 2010-04-12 17:13:53.000000000 -0400 -@@ -437,6 +437,7 @@ - if((pid=wait(&status))>0) { - --num_clients; /* one client less */ - #endif -+ if (getenv("STUNNEL_ONCE")) exit(0); - #ifdef WIFSIGNALED - if(WIFSIGNALED(status)) { - s_log(LOG_DEBUG, "Process %d terminated on signal %d (%d left)", -diff -Naur stunnel.orig/src/options.c stunnel/src/options.c ---- stunnel.orig/src/options.c 2010-04-05 14:44:43.000000000 -0400 -+++ stunnel/src/options.c 2010-04-12 17:19:18.000000000 -0400 -@@ -470,6 +470,7 @@ - switch(cmd) { - case CMD_INIT: - new_global_options.option.syslog=1; -+ if (getenv("STUNNEL_NO_SYSLOG")) new_global_options.option.syslog=0; - break; - case CMD_EXEC: - if(strcasecmp(opt, "syslog")) -diff -Naur stunnel.orig/src/stunnel.c stunnel/src/stunnel.c ---- stunnel.orig/src/stunnel.c 2010-02-25 04:57:11.000000000 -0500 -+++ stunnel/src/stunnel.c 2010-04-12 17:16:33.000000000 -0400 -@@ -306,6 +306,7 @@ - max_clients=0; - s_log(LOG_NOTICE, "No limit detected for the number of clients"); - } -+ if (getenv("STUNNEL_MAX_CLIENTS")) max_clients = atoi(getenv("STUNNEL_MAX_CLIENTS")); - } - - #ifdef HAVE_CHROOT diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch deleted file mode 100644 index e37dd31..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch +++ /dev/null @@ -1,24370 +0,0 @@ -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/Vncviewer vnc_unixsrc/vncviewer/Vncviewer ---- vnc_unixsrc.orig/vncviewer/Vncviewer 2003-02-07 05:30:57.000000000 -0500 -+++ vnc_unixsrc/vncviewer/Vncviewer 2008-08-24 16:26:01.000000000 -0400 -@@ -1,20 +1,22 @@ - ! --! Application defaults file for vncviewer. -+! Application defaults file for SSVNC vncviewer. -+! -+! N.B.: You will need to rename this file to be "Ssvnc" instead of "Vncviewer" - ! - - - ! - ! The title of the main window. "%s" will be replaced by the desktop name. --! -+! - --Vncviewer.title: TightVNC: %s -+Ssvnc.title: SSVNC: %s Press F8 for Menu - - - ! - ! Translations on the main window. - ! - --Vncviewer.translations:\ -+Ssvnc.translations:\ - <Enter>: SelectionToVNC()\n\ - <Leave>: SelectionFromVNC() - -@@ -23,7 +25,7 @@ - ! Uncomment to grab the keyboard in full-screen mode. - ! - --! Vncviewer.grabKeyboard: True -+! Ssvnc.grabKeyboard: True - - - ! -@@ -43,6 +45,9 @@ - *viewport.useRight: True - *viewport*Scrollbar*thumb: None - -+*viewport.horizontal.height: 6 -+*viewport.vertical.width: 6 -+ - - ! - ! Default translations on desktop window. -@@ -50,89 +55,591 @@ - - *desktop.baseTranslations:\ - <Key>F8: ShowPopup()\n\ -+ <Key>F9: ToggleFullScreen()\n\ - <ButtonPress>: SendRFBEvent()\n\ - <ButtonRelease>: SendRFBEvent()\n\ - <Motion>: SendRFBEvent()\n\ - <KeyPress>: SendRFBEvent()\n\ - <KeyRelease>: SendRFBEvent() - -+*viewport.horizontal.translations: #override\n\ -+ <KeyPress>Right: StartScroll(Forward)\n\ -+ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Left: StartScroll(Backward)\n\ -+ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Next: StartScroll(Forward)\n\ -+ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Prior: StartScroll(Backward)\n\ -+ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>z: StartScroll(Forward)\n\ -+ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>a: StartScroll(Backward)\n\ -+ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>f: StartScroll(Forward)\n\ -+ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>b: StartScroll(Backward)\n\ -+ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Down: StartScroll(Forward)\n\ -+ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Up: StartScroll(Backward)\n\ -+ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll() -+ -+*viewport.vertical.translations: #override\n\ -+ <KeyPress>Down: StartScroll(Forward)\n\ -+ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Up: StartScroll(Backward)\n\ -+ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Next: StartScroll(Forward)\n\ -+ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Prior: StartScroll(Backward)\n\ -+ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>z: StartScroll(Forward)\n\ -+ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>a: StartScroll(Backward)\n\ -+ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>f: StartScroll(Forward)\n\ -+ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>b: StartScroll(Backward)\n\ -+ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Right: StartScroll(Forward)\n\ -+ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\n\ -+ <KeyPress>Left: StartScroll(Backward)\n\ -+ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll() -+ - - ! - ! Dialog boxes - ! - - *serverDialog.dialog.label: VNC server: -+ - *serverDialog.dialog.value: -+ - *serverDialog.dialog.value.translations: #override\n\ -- <Key>Return: ServerDialogDone() -+ <Key>Return: ServerDialogDone() -+ -+*ycropDialog.dialog.label: Y Crop (max-height in pixels): -+ -+*ycropDialog.dialog.value: -+ -+*ycropDialog.dialog.value.translations: #override\n\ -+ <Key>Return: YCropDialogDone() -+ -+*scbarDialog.dialog.label: Scroll Bars width: -+ -+*scbarDialog.dialog.value: -+ -+*scbarDialog.dialog.value.translations: #override\n\ -+ <Key>Return: ScbarDialogDone() -+ -+*scaleDialog.dialog.label: Integer n for 1/n server scaling: -+ -+*scaleDialog.dialog.value: -+ -+*scaleDialog.dialog.value.translations: #override\n\ -+ <Key>Return: ScaleDialogDone() - - *passwordDialog.dialog.label: Password: -+ - *passwordDialog.dialog.value: -+ - *passwordDialog.dialog.value.AsciiSink.echo: False -+ - *passwordDialog.dialog.value.translations: #override\n\ -- <Key>Return: PasswordDialogDone() -+ <Key>Return: PasswordDialogDone() - - - ! - ! Popup window appearance - ! - --*popup.title: TightVNC popup -+*popup.title: SSVNC popup -+ - *popup*background: grey --*popup*font: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-* --*popup.buttonForm.Command.borderWidth: 0 --*popup.buttonForm.Toggle.borderWidth: 0 -+ -+*popup*font_old: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-* -+ -+*popup*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* -+ -+*popup.buttonForm*.Command.borderWidth: 0 -+ -+*popup.buttonForm*.Toggle.borderWidth: 0 -+ -+*scaleN.title: 1/n scale -+ -+*scaleN*background: grey -+ -+*scaleN*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* -+ -+*scaleN.buttonForm.Command.borderWidth: 0 -+ -+*scaleN.buttonForm.Toggle.borderWidth: 0 -+ -+*quality.title: quality -+ -+*quality*background: grey -+ -+*quality*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* -+ -+*quality.buttonForm.Command.borderWidth: 0 -+ -+*quality.buttonForm.Toggle.borderWidth: 0 -+ -+*compress.title: compress -+ -+*compress*background: grey -+ -+*compress*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-* -+ -+*compress.buttonForm.Command.borderWidth: 0 -+ -+*compress.buttonForm.Toggle.borderWidth: 0 -+ - - ! - ! Translations on popup window - send key presses through - ! - - *popup.translations: #override <Message>WM_PROTOCOLS: HidePopup() -+ - *popup.buttonForm.translations: #override\n\ -- <KeyPress>: SendRFBEvent() HidePopup() -+ <KeyPress>: SendRFBEvent() HidePopup() - - - ! - ! Popup buttons - ! - --*popupButtonCount: 8 -+*popupButtonCount: 38 -+ -+*popupButtonBreak: 19 - - *popup*button1.label: Dismiss popup -+ - *popup*button1.translations: #override\n\ -- <Btn1Down>,<Btn1Up>: HidePopup() -+ <Btn1Down>,<Btn1Up>: HidePopup() - - *popup*button2.label: Quit viewer -+ - *popup*button2.translations: #override\n\ -- <Btn1Down>,<Btn1Up>: Quit() -+ <Btn1Down>,<Btn1Up>: Quit() -+ -+*popup*button3.label: Full screen (also F9) - --*popup*button3.label: Full screen - *popup*button3.type: toggle -+ - *popup*button3.translations: #override\n\ -- <Visible>: SetFullScreenState()\n\ -- <Btn1Down>,<Btn1Up>: toggle() HidePopup() ToggleFullScreen() -+ <Visible>: SetFullScreenState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullScreen() HidePopup() - - *popup*button4.label: Clipboard: local -> remote -+ - *popup*button4.translations: #override\n\ -- <Btn1Down>,<Btn1Up>: SelectionToVNC(always) HidePopup() -+ <Btn1Down>,<Btn1Up>: SelectionToVNC(always) HidePopup() - - *popup*button5.label: Clipboard: local <- remote -+ - *popup*button5.translations: #override\n\ -- <Btn1Down>,<Btn1Up>: SelectionFromVNC(always) HidePopup() -+ <Btn1Down>,<Btn1Up>: SelectionFromVNC(always) HidePopup() - - *popup*button6.label: Request refresh -+ - *popup*button6.translations: #override\n\ -- <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate) HidePopup() -+ <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate) HidePopup() - - *popup*button7.label: Send ctrl-alt-del -+ - *popup*button7.translations: #override\n\ -- <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\ -- SendRFBEvent(keydown,Alt_L)\ -- SendRFBEvent(key,Delete)\ -- SendRFBEvent(keyup,Alt_L)\ -- SendRFBEvent(keyup,Control_L)\ -- HidePopup() -+ <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L) SendRFBEvent(keydown,Alt_L) SendRFBEvent(key,Delete) SendRFBEvent(keyup,Alt_L) SendRFBEvent(keyup,Control_L) HidePopup() - - *popup*button8.label: Send F8 -+ - *popup*button8.translations: #override\n\ -- <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup() -+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup() -+ -+*popup*button9.label: Send F9 -+ -+*popup*button9.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F9) HidePopup() -+ -+*popup*button10.label: ViewOnly -+ -+*popup*button10.type: toggle -+ -+*popup*button10.translations: #override\n\ -+ <Visible>: SetViewOnlyState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleViewOnly() HidePopup() -+ -+*popup*button11.label: Disable Bell -+ -+*popup*button11.type: toggle -+ -+*popup*button11.translations: #override\n\ -+ <Visible>: SetBellState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleBell() HidePopup() -+ -+*popup*button12.label: Cursor Shape -+ -+*popup*button12.type: toggle -+ -+*popup*button12.translations: #override\n\ -+ <Visible>: SetCursorShapeState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorShape() HidePopup() -+ -+*popup*button13.label: X11 Cursor -+ -+*popup*button13.type: toggle -+ -+*popup*button13.translations: #override\n\ -+ <Visible>: SetX11CursorState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleX11Cursor() HidePopup() -+ -+*popup*button14.label: Cursor Alphablend -+ -+*popup*button14.type: toggle -+ -+*popup*button14.translations: #override\n\ -+ <Visible>: SetCursorAlphaState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorAlpha() HidePopup() -+ -+*popup*button15.label: Toggle Tight/ZRLE -+ -+*popup*button15.type: toggle -+ -+*popup*button15.translations: #override\n\ -+ <Visible>: SetZRLEState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightZRLE() HidePopup() -+ -+*popup*button16.label: Toggle ZRLE/ZYWRLE -+ -+*popup*button16.type: toggle -+ -+*popup*button16.translations: #override\n\ -+ <Visible>: SetZYWRLEState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleZRLEZYWRLE() HidePopup() -+ -+*popup*button17.label: Quality Level -+ -+*popup*button17.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() ShowQuality() -+ -+*popup*button18.label: Compress Level -+ -+*popup*button18.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() ShowCompress() -+ -+*popup*button19.label: Disable JPEG -+ -+*popup*button19.type: toggle -+ -+*popup*button19.translations: #override\n\ -+ <Visible>: SetNOJPEGState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleJPEG() HidePopup() -+ -+*popup*button20.label: Full Color -+ -+*popup*button20.type: toggle -+ -+*popup*button20.translations: #override\n\ -+ <Visible>: SetFullColorState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullColor() HidePopup() -+ -+*popup*button21.label: Grey Scale (16 & 8-bpp) -+ -+*popup*button21.type: toggle -+ -+*popup*button21.translations: #override\n\ -+ <Visible>: SetGreyScaleState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleGreyScale() HidePopup() -+ -+*popup*button22.label: 16 bit color (BGR565) -+ -+*popup*button22.type: toggle -+ -+*popup*button22.translations: #override\n\ -+ <Visible>: Set16bppState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle16bpp() HidePopup() -+ -+*popup*button23.label: 8 bit color (BGR233) -+ -+*popup*button23.type: toggle -+ -+*popup*button23.translations: #override\n\ -+ <Visible>: Set8bppState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle8bpp() HidePopup() -+ -+*popup*button24.label: - 256 colors -+ -+*popup*button24.type: toggle -+ -+*popup*button24.translations: #override\n\ -+ <Visible>: Set256ColorsState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle256Colors() HidePopup() -+ -+*popup*button25.label: - 64 colors -+ -+*popup*button25.type: toggle -+ -+*popup*button25.translations: #override\n\ -+ <Visible>: Set64ColorsState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle64Colors() HidePopup() -+ -+*popup*button26.label: - 8 colors -+ -+*popup*button26.type: toggle -+ -+*popup*button26.translations: #override\n\ -+ <Visible>: Set8ColorsState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle8Colors() HidePopup() -+ -+*popup*button27.label: Set Y Crop (y-max) -+ -+*popup*button27.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() SetYCrop() -+ -+*popup*button28.label: Set Scrollbar Width -+ -+*popup*button28.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() SetScbar() -+ -+*popup*button29.label: UltraVNC Extensions: -+ -+*popup*button29.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() -+ -+*popup*button30.label: - Set 1/n Server Scale -+ -+*popup*button30.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() ShowScaleN() -+ -+*popup*button31.label: - Text Chat -+ -+*popup*button31.type: toggle -+ -+*popup*button31.translations: #override\n\ -+ <Visible>: SetTextChatState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleTextChat() HidePopup() -+ -+*popup*button32.label: - File Transfer -+ -+*popup*button32.type: toggle -+ -+*popup*button32.translations: #override\n\ -+ <Visible>: SetFileXferState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleFileXfer() HidePopup() -+ -+*popup*button33.label: - Single Window -+ -+*popup*button33.type: toggle -+ -+*popup*button33.translations: #override\n\ -+ <Visible>: SetSingleWindowState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleSingleWindow() HidePopup() -+ -+*popup*button34.label: - Disable Remote Input -+ -+*popup*button34.type: toggle -+ -+*popup*button34.translations: #override\n\ -+ <Visible>: SetServerInputState()\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleServerInput() HidePopup() -+ -+*popup*button35.label: -+ -+*popup*button36.label: -+ -+*popup*button37.label: -+ -+*popup*button38.label: -+ -+*scaleN*button0.label: Dismiss -+ -+*scaleN*button0.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HideScaleN() -+ -+*scaleN*button1.label: 1/1 -+ -+*scaleN*button1.translations: #override\n\ -+ <Visible>: SetScaleNState(1)\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(1) HideScaleN() -+ -+*scaleN*button2.label: 1/2 -+ -+*scaleN*button2.translations: #override\n\ -+ <Visible>: SetScaleNState(2)\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(2) HideScaleN() -+ -+*scaleN*button3.label: 1/3 -+ -+*scaleN*button3.translations: #override\n\ -+ <Visible>: SetScaleNState(3)\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(3) HideScaleN() -+ -+*scaleN*button4.label: 1/4 -+ -+*scaleN*button4.translations: #override\n\ -+ <Visible>: SetScaleNState(4)\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(4) HideScaleN() -+ -+*scaleN*button5.label: 1/5 -+ -+*scaleN*button5.translations: #override\n\ -+ <Visible>: SetScaleNState(5)\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(5) HideScaleN() -+ -+*scaleN*button6.label: Other -+ -+*scaleN*button6.translations: #override\n\ -+ <Visible>: SetScaleNState(6)\n\ -+ <Btn1Down>,<Btn1Up>: HideScaleN() DoServerScale() -+ -+*quality*buttonD.label: Dismiss -+ -+*quality*buttonD.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HideQuality() -+ -+*quality*button0.label: 0 -+ -+*quality*button0.type: toggle -+ -+*quality*button0.translations: #override\n\ -+ <Visible>: SetQualityState(0)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(0) HideQuality() -+ -+*quality*button1.label: 1 -+ -+*quality*button1.type: toggle -+ -+*quality*button1.translations: #override\n\ -+ <Visible>: SetQualityState(1)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(1) HideQuality() -+ -+*quality*button2.label: 2 -+ -+*quality*button2.type: toggle -+ -+*quality*button2.translations: #override\n\ -+ <Visible>: SetQualityState(2)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(2) HideQuality() -+ -+*quality*button3.label: 3 -+ -+*quality*button3.type: toggle -+ -+*quality*button3.translations: #override\n\ -+ <Visible>: SetQualityState(3)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(3) HideQuality() -+ -+*quality*button4.label: 4 -+ -+*quality*button4.type: toggle -+ -+*quality*button4.translations: #override\n\ -+ <Visible>: SetQualityState(4)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(4) HideQuality() -+ -+*quality*button5.label: 5 -+ -+*quality*button5.type: toggle -+ -+*quality*button5.translations: #override\n\ -+ <Visible>: SetQualityState(5)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(5) HideQuality() -+ -+*quality*button6.label: 6 -+ -+*quality*button6.type: toggle -+ -+*quality*button6.translations: #override\n\ -+ <Visible>: SetQualityState(6)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(6) HideQuality() -+ -+*quality*button7.label: 7 -+ -+*quality*button7.type: toggle -+ -+*quality*button7.translations: #override\n\ -+ <Visible>: SetQualityState(7)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(7) HideQuality() -+ -+*quality*button8.label: 8 -+ -+*quality*button8.type: toggle -+ -+*quality*button8.translations: #override\n\ -+ <Visible>: SetQualityState(8)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(8) HideQuality() -+ -+*quality*button9.label: 9 -+ -+*quality*button9.type: toggle -+ -+*quality*button9.translations: #override\n\ -+ <Visible>: SetQualityState(9)\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(9) HideQuality() -+ -+*compress*buttonD.label: Dismiss -+ -+*compress*buttonD.translations: #override\n\ -+ <Btn1Down>,<Btn1Up>: HideCompress() -+ -+*compress*button0.label: 0 -+ -+*compress*button0.translations: #override\n\ -+ <Visible>: SetCompressState(0)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(0) HideCompress() -+ -+*compress*button1.label: 1 -+ -+*compress*button1.translations: #override\n\ -+ <Visible>: SetCompressState(1)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(1) HideCompress() -+ -+*compress*button2.label: 2 -+ -+*compress*button2.translations: #override\n\ -+ <Visible>: SetCompressState(2)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(2) HideCompress() -+ -+*compress*button3.label: 3 -+ -+*compress*button3.translations: #override\n\ -+ <Visible>: SetCompressState(3)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(3) HideCompress() -+ -+*compress*button4.label: 4 -+ -+*compress*button4.translations: #override\n\ -+ <Visible>: SetCompressState(4)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(4) HideCompress() -+ -+*compress*button5.label: 5 -+ -+*compress*button5.translations: #override\n\ -+ <Visible>: SetCompressState(5)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(5) HideCompress() -+ -+*compress*button6.label: 6 -+ -+*compress*button6.translations: #override\n\ -+ <Visible>: SetCompressState(6)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(6) HideCompress() -+ -+*compress*button7.label: 7 -+ -+*compress*button7.translations: #override\n\ -+ <Visible>: SetCompressState(7)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(7) HideCompress() -+ -+*compress*button8.label: 8 -+ -+*compress*button8.translations: #override\n\ -+ <Visible>: SetCompressState(8)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(8) HideCompress() -+ -+*compress*button9.label: 9 -+ -+*compress*button9.translations: #override\n\ -+ <Visible>: SetCompressState(9)\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(9) HideCompress() -+ -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/argsresources.c vnc_unixsrc/vncviewer/argsresources.c ---- vnc_unixsrc.orig/vncviewer/argsresources.c 2007-02-04 17:10:31.000000000 -0500 -+++ vnc_unixsrc/vncviewer/argsresources.c 2010-04-18 12:39:55.000000000 -0400 -@@ -31,9 +31,9 @@ - - char *fallback_resources[] = { - -- "Vncviewer.title: TightVNC: %s", -+ "Ssvnc.title: SSVNC: %s - Press F8 for Menu", - -- "Vncviewer.translations:\ -+ "Ssvnc.translations:\ - <Enter>: SelectionToVNC()\\n\ - <Leave>: SelectionFromVNC()", - -@@ -45,8 +45,60 @@ - "*viewport.useRight: True", - "*viewport*Scrollbar*thumb: None", - -+ "*viewport.horizontal.height: 6 ", -+ "*viewport.vertical.width: 6 ", -+ "ssvnc*viewport.horizontal.height: 6 ", -+ "ssvnc*viewport.vertical.width: 6 ", -+ -+ "*viewport.horizontal.translations: #override\\n\ -+ <KeyPress>Right: StartScroll(Forward)\\n\ -+ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Left: StartScroll(Backward)\\n\ -+ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Next: StartScroll(Forward)\\n\ -+ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Prior: StartScroll(Backward)\\n\ -+ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>z: StartScroll(Forward)\\n\ -+ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>a: StartScroll(Backward)\\n\ -+ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>f: StartScroll(Forward)\\n\ -+ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>b: StartScroll(Backward)\\n\ -+ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Down: StartScroll(Forward)\\n\ -+ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Up: StartScroll(Backward)\\n\ -+ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll()", -+ -+ "*viewport.vertical.translations: #override\\n\ -+ <KeyPress>Down: StartScroll(Forward)\\n\ -+ <KeyRelease>Down: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Up: StartScroll(Backward)\\n\ -+ <KeyRelease>Up: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Next: StartScroll(Forward)\\n\ -+ <KeyRelease>Next: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Prior: StartScroll(Backward)\\n\ -+ <KeyRelease>Prior: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>z: StartScroll(Forward)\\n\ -+ <KeyRelease>z: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>a: StartScroll(Backward)\\n\ -+ <KeyRelease>a: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>f: StartScroll(Forward)\\n\ -+ <KeyRelease>f: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>b: StartScroll(Backward)\\n\ -+ <KeyRelease>b: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Right: StartScroll(Forward)\\n\ -+ <KeyRelease>Right: NotifyScroll(FullLength) EndScroll()\\n\ -+ <KeyPress>Left: StartScroll(Backward)\\n\ -+ <KeyRelease>Left: NotifyScroll(FullLength) EndScroll()", -+ - "*desktop.baseTranslations:\ -- <Key>F8: ShowPopup()\\n\ -+ <KeyPress>F8: ShowPopup()\\n\ -+ <KeyRelease>F8: Noop()\\n\ -+ <KeyPress>F9: ToggleFullScreen()\\n\ -+ <KeyRelease>F9: Noop()\\n\ - <ButtonPress>: SendRFBEvent()\\n\ - <ButtonRelease>: SendRFBEvent()\\n\ - <Motion>: SendRFBEvent()\\n\ -@@ -55,26 +107,137 @@ - - "*serverDialog.dialog.label: VNC server:", - "*serverDialog.dialog.value:", -+ "*serverDialog.dialog.value.width: 150", - "*serverDialog.dialog.value.translations: #override\\n\ - <Key>Return: ServerDialogDone()", - -- "*passwordDialog.dialog.label: Password:", -+ "*userDialog.dialog.label: SSVNC: Enter Username", -+ "*userDialog.dialog.value:", -+ "*userDialog.dialog.value.width: 150", -+ "*userDialog.dialog.value.translations: #override\\n\ -+ <Key>Return: UserDialogDone()", -+ -+ "*scaleDialog.dialog.label: Scale: Enter 'none' (same as '1' or '1.0'),\\na geometry WxH (e.g. 1280x1024), or\\na fraction (e.g. 0.75 or 3/4).\\nUse 'fit' for full screen size.\\nUse 'auto' to match window size.\\nCurrent value:", -+ "*scaleDialog.dialog.value:", -+ "*scaleDialog.dialog.value.translations: #override\\n\ -+ <KeyRelease>Return: ScaleDialogDone()", -+ -+ "*escapeDialog.dialog.label: Escape Keys: Enter a comma separated list of modifier keys to be the\\n" -+ "'escape sequence'. When these keys are held down, the next keystroke is\\n" -+ "interpreted locally to invoke a special action instead of being sent to\\n" -+ "the remote VNC server. In other words, a set of 'Hot Keys'.\\n" -+ "\\n" -+ "To enable or disable this, click on 'Escape Keys: Toggle' in the Popup.\\n" -+ "\\n" -+ "Here is the list of hot-key mappings to special actions:\\n" -+ "\\n" -+ " r: refresh desktop b: toggle bell c: toggle full-color\\n" -+ " f: file transfer x: x11cursor z: toggle Tight/ZRLE\\n" -+ " l: full screen g: graball e: escape keys dialog\\n" -+ " s: scale dialog +: scale up (=) -: scale down (_)\\n" -+ " t: text chat a: alphablend cursor\\n" -+ " V: toggle viewonly Q: quit viewer 1 2 3 4 5 6: UltraVNC scale 1/n\\n" -+ "\\n" -+ " Arrow keys: pan the viewport about 10% for each keypress.\\n" -+ " PageUp / PageDown: pan the viewport by a screenful vertically.\\n" -+ " Home / End: pan the viewport by a screenful horizontally.\\n" -+ " KeyPad Arrow keys: pan the viewport by 1 pixel for each keypress.\\n" -+ " Dragging the Mouse with Button1 pressed also pans the viewport.\\n" -+ " Clicking Mouse Button3 brings up the Popup Menu.\\n" -+ "\\n" -+ "The above mappings are *always* active in ViewOnly mode, unless you set the\\n" -+ "Escape Keys value to 'never'.\\n" -+ "\\n" -+ "x11vnc -appshare hot-keys: x11vnc has a simple application sharing mode\\n" -+ "that enables the viewer-side to move, resize, or raise the remote toplevel\\n" -+ "windows. To enable it, hold down Shift + the Escape Keys and press these:\\n" -+ "\\n" -+ " Arrow keys: move the remote window around in its desktop.\\n" -+ " PageUp/PageDn/Home/End: resize the remote window.\\n" -+ " +/- raise or lower the remote window.\\n" -+ " M or Button1 move win to local position; D or Button3: delete remote win.\\n" -+ "\\n" -+ "If the Escape Keys value below is set to 'default' then a fixed list of\\n" -+ "modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it is\\n" -+ "Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag.\\n" -+ "Also note the _L and _R mean the key is on the LEFT or RIGHT side of keyboard.\\n" -+ "\\n" -+ "On Unix the default is Alt and Windows keys on Left side of keyboard.\\n" -+ "On MacOSX the default is Control and Command keys on Left side of keyboard.\\n" -+ "\\n" -+ "Example: Press and hold the Alt and Windows keys on the LEFT side of the\\n" -+ "keyboard and then press 'c' to toggle the full-color state. Or press 't'\\n" -+ "to toggle the ultravnc Text Chat window, etc.\\n" -+ "\\n" -+ "To use something besides the default, supply a comma separated list (or a\\n" -+ "single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L\\n" -+ "Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.\\n" -+ "\\n" -+ "Current Escape Keys Value:", -+ "*escapeDialog.dialog.value:", -+ "*escapeDialog.dialog.value.width: 280", -+ "*escapeDialog.dialog.value.translations: #override\\n\ -+ <KeyRelease>Return: EscapeDialogDone()", -+ -+ "*ycropDialog.dialog.label: Y Crop (max-height in pixels):", -+ "*ycropDialog.dialog.value:", -+ "*ycropDialog.dialog.value.translations: #override\\n\ -+ <KeyRelease>Return: YCropDialogDone()", -+ -+ "*scbarDialog.dialog.label: Scroll Bars width:", -+ "*scbarDialog.dialog.value:", -+ "*scbarDialog.dialog.value.translations: #override\\n\ -+ <KeyRelease>Return: ScbarDialogDone()", -+ -+ "*scaleNDialog.dialog.label: Integer n for 1/n server scaling:", -+ "*scaleNDialog.dialog.value:", -+ "*scaleNDialog.dialog.value.translations: #override\\n\ -+ <KeyRelease>Return: ScaleNDialogDone()", -+ -+ "*passwordDialog.dialog.label: SSVNC: Enter Password", - "*passwordDialog.dialog.value:", -+ "*passwordDialog.dialog.value.width: 150", - "*passwordDialog.dialog.value.AsciiSink.echo: False", - "*passwordDialog.dialog.value.translations: #override\\n\ - <Key>Return: PasswordDialogDone()", - -- "*popup.title: TightVNC popup", -+ "*popup.title: SSVNC popup", - "*popup*background: grey", -- "*popup*font: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*", -- "*popup.buttonForm.Command.borderWidth: 0", -- "*popup.buttonForm.Toggle.borderWidth: 0", -+ "*popup*font_old: -*-helvetica-bold-r-*-*-16-*-*-*-*-*-*-*", -+ "*popup*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*", -+ "*popup.buttonForm*.Command.borderWidth: 0", -+ "*popup.buttonForm*.Toggle.borderWidth: 0", -+ -+ "*scaleN.title: 1/n scale", -+ "*scaleN*background: grey", -+ "*scaleN*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*", -+ "*scaleN.buttonForm.Command.borderWidth: 0", -+ "*scaleN.buttonForm.Toggle.borderWidth: 0", -+ -+ "*turboVNC.title: TurboVNC", -+ "*turboVNC*background: grey", -+ "*turboVNC*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*", -+ "*turboVNC.buttonForm.Command.borderWidth: 0", -+ "*turboVNC.buttonForm.Toggle.borderWidth: 0", -+ -+ "*quality.title: quality", -+ "*quality*background: grey", -+ "*quality*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*", -+ "*quality.buttonForm.Command.borderWidth: 0", -+ "*quality.buttonForm.Toggle.borderWidth: 0", -+ -+ "*compress.title: compress", -+ "*compress*background: grey", -+ "*compress*font: -*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-*", -+ "*compress.buttonForm.Command.borderWidth: 0", -+ "*compress.buttonForm.Toggle.borderWidth: 0", - - "*popup.translations: #override <Message>WM_PROTOCOLS: HidePopup()", - "*popup.buttonForm.translations: #override\\n\ - <KeyPress>: SendRFBEvent() HidePopup()", - -- "*popupButtonCount: 8", -+ "*popupButtonCount: 44", -+ "*popupButtonBreak: 22", - - "*popup*button1.label: Dismiss popup", - "*popup*button1.translations: #override\\n\ -@@ -84,7 +247,7 @@ - "*popup*button2.translations: #override\\n\ - <Btn1Down>,<Btn1Up>: Quit()", - -- "*popup*button3.label: Full screen", -+ "*popup*button3.label: Full screen (also F9)", - "*popup*button3.type: toggle", - "*popup*button3.translations: #override\\n\ - <Visible>: SetFullScreenState()\\n\ -@@ -105,16 +268,426 @@ - "*popup*button7.label: Send ctrl-alt-del", - "*popup*button7.translations: #override\\n\ - <Btn1Down>,<Btn1Up>: SendRFBEvent(keydown,Control_L)\ -- SendRFBEvent(keydown,Alt_L)\ -- SendRFBEvent(key,Delete)\ -- SendRFBEvent(keyup,Alt_L)\ -- SendRFBEvent(keyup,Control_L)\ -- HidePopup()", -+ SendRFBEvent(keydown,Alt_L)\ -+ SendRFBEvent(key,Delete)\ -+ SendRFBEvent(keyup,Alt_L)\ -+ SendRFBEvent(keyup,Control_L)\ -+ HidePopup()", - - "*popup*button8.label: Send F8", - "*popup*button8.translations: #override\\n\ - <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F8) HidePopup()", - -+ "*popup*button9.label: Send F9", -+ "*popup*button9.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SendRFBEvent(key,F9) HidePopup()", -+ -+ "*popup*button10.label: ViewOnly", -+ "*popup*button10.type: toggle", -+ "*popup*button10.translations: #override\\n\ -+ <Visible>: SetViewOnlyState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleViewOnly() HidePopup()", -+ -+ "*popup*button11.label: Disable Bell", -+ "*popup*button11.type: toggle", -+ "*popup*button11.translations: #override\\n\ -+ <Visible>: SetBellState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleBell() HidePopup()", -+ -+ "*popup*button12.label: Cursor Shape", -+ "*popup*button12.type: toggle", -+ "*popup*button12.translations: #override\\n\ -+ <Visible>: SetCursorShapeState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorShape() HidePopup()", -+ -+ "*popup*button13.label: X11 Cursor", -+ "*popup*button13.type: toggle", -+ "*popup*button13.translations: #override\\n\ -+ <Visible>: SetX11CursorState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleX11Cursor() HidePopup()", -+ -+ "*popup*button14.label: Cursor Alphablend", -+ "*popup*button14.type: toggle", -+ "*popup*button14.translations: #override\\n\ -+ <Visible>: SetCursorAlphaState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleCursorAlpha() HidePopup()", -+ -+ "*popup*button15.label: Toggle Tight/Hextile", -+ "*popup*button15.type: toggle", -+ "*popup*button15.translations: #override\\n\ -+ <Visible>: SetHextileState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightHextile() HidePopup()", -+ -+ "*popup*button16.label: Toggle Tight/ZRLE", -+ "*popup*button16.type: toggle", -+ "*popup*button16.translations: #override\\n\ -+ <Visible>: SetZRLEState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleTightZRLE() HidePopup()", -+ -+ "*popup*button17.label: Toggle ZRLE/ZYWRLE", -+ "*popup*button17.type: toggle", -+ "*popup*button17.translations: #override\\n\ -+ <Visible>: SetZYWRLEState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleZRLEZYWRLE() HidePopup()", -+ -+ "*popup*button18.label: Quality Level", -+ "*popup*button18.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() ShowQuality()", -+ -+ "*popup*button19.label: Compress Level", -+ "*popup*button19.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() ShowCompress()", -+ -+ "*popup*button20.label: Disable JPEG", -+ "*popup*button20.type: toggle", -+ "*popup*button20.translations: #override\\n\ -+ <Visible>: SetNOJPEGState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleJPEG() HidePopup()", -+ -+ "*popup*button21.label: TurboVNC Settings", -+ "*popup*button21.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() ShowTurboVNC()", -+ -+ "*popup*button22.label: Pipeline Updates", -+ "*popup*button22.type: toggle", -+ "*popup*button22.translations: #override\\n\ -+ <Visible>: SetPipelineUpdates()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() TogglePipelineUpdates() HidePopup()", -+ -+ "*popup*button23.label: Full Color", -+ "*popup*button23.type: toggle", -+ "*popup*button23.translations: #override\\n\ -+ <Visible>: SetFullColorState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleFullColor() HidePopup()", -+ -+ "*popup*button24.label: Grey Scale (16 & 8-bpp)", -+ "*popup*button24.type: toggle", -+ "*popup*button24.translations: #override\\n\ -+ <Visible>: SetGreyScaleState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleGreyScale() HidePopup()", -+ -+ "*popup*button25.label: 16 bit color (BGR565)", -+ "*popup*button25.type: toggle", -+ "*popup*button25.translations: #override\\n\ -+ <Visible>: Set16bppState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle16bpp() HidePopup()", -+ -+ "*popup*button26.label: 8 bit color (BGR233)", -+ "*popup*button26.type: toggle", -+ "*popup*button26.translations: #override\\n\ -+ <Visible>: Set8bppState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle8bpp() HidePopup()", -+ -+ "*popup*button27.label: - 256 colors", -+ "*popup*button27.type: toggle", -+ "*popup*button27.translations: #override\\n\ -+ <Visible>: Set256ColorsState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle256Colors() HidePopup()", -+ -+ "*popup*button28.label: - 64 colors", -+ "*popup*button28.type: toggle", -+ "*popup*button28.translations: #override\\n\ -+ <Visible>: Set64ColorsState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle64Colors() HidePopup()", -+ -+ "*popup*button29.label: - 8 colors", -+ "*popup*button29.type: toggle", -+ "*popup*button29.translations: #override\\n\ -+ <Visible>: Set8ColorsState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() Toggle8Colors() HidePopup()", -+ -+ "*popup*button30.label: Scale Viewer", -+ "*popup*button30.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() SetScale()", -+ -+ "*popup*button31.label: Escape Keys: Toggle", -+ "*popup*button31.type: toggle", -+ "*popup*button31.translations: #override\\n\ -+ <Visible>: SetEscapeKeysState()\\n\ -+ <Btn1Down>, <Btn1Up>: toggle() ToggleEscapeActive() HidePopup()", -+ -+ "*popup*button32.label: Escape Keys: Help+Set", -+ "*popup*button32.translations: #override\\n\ -+ <Btn1Down>, <Btn1Up>: HidePopup() SetEscapeKeys()", -+ -+ "*popup*button33.label: Set Y Crop (y-max)", -+ "*popup*button33.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() SetYCrop()", -+ -+ "*popup*button34.label: Set Scrollbar Width", -+ "*popup*button34.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() SetScbar()", -+ -+ "*popup*button35.label: XGrabServer", -+ "*popup*button35.type: toggle", -+ "*popup*button35.translations: #override\\n\ -+ <Visible>: SetXGrabState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleXGrab() HidePopup()", -+ -+ "*popup*button36.label: UltraVNC Extensions:", -+ "*popup*button36.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup()", -+ -+ "*popup*button37.label: - Set 1/n Server Scale", -+ "*popup*button37.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HidePopup() ShowScaleN()", -+ -+ "*popup*button38.label: - Text Chat", -+ "*popup*button38.type: toggle", -+ "*popup*button38.translations: #override\\n\ -+ <Visible>: SetTextChatState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleTextChat() HidePopup()", -+ -+ "*popup*button39.label: - File Transfer", -+ "*popup*button39.type: toggle", -+ "*popup*button39.translations: #override\\n\ -+ <Visible>: SetFileXferState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleFileXfer() HidePopup()", -+ -+ "*popup*button40.label: - Single Window", -+ "*popup*button40.type: toggle", -+ "*popup*button40.translations: #override\\n\ -+ <Visible>: SetSingleWindowState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleSingleWindow() HidePopup()", -+ -+ "*popup*button41.label: - Disable Remote Input", -+ "*popup*button41.type: toggle", -+ "*popup*button41.translations: #override\\n\ -+ <Visible>: SetServerInputState()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleServerInput() HidePopup()", -+ -+ "*popup*button42.label: Send Clipboard not Primary", -+ "*popup*button42.type: toggle", -+ "*popup*button42.translations: #override\\n\ -+ <Visible>: SetSendClipboard()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleSendClipboard() HidePopup()", -+ -+ "*popup*button43.label: Send Selection Every time", -+ "*popup*button43.type: toggle", -+ "*popup*button43.translations: #override\\n\ -+ <Visible>: SetSendAlways()\\n\ -+ <Btn1Down>,<Btn1Up>: toggle() ToggleSendAlways() HidePopup()", -+ -+ "*popup*button44.label: ", -+ -+ "*turboVNC*button0.label: Dismiss", -+ "*turboVNC*button0.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HideTurboVNC()", -+ -+ "*turboVNC*button1.label: High Quality (LAN)", -+ "*turboVNC*button1.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(1)", -+ -+ "*turboVNC*button2.label: Medium Quality", -+ "*turboVNC*button2.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(2)", -+ -+ "*turboVNC*button3.label: Low Quality (WAN)", -+ "*turboVNC*button3.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(3)", -+ -+ "*turboVNC*button4.label: Lossless (Gigabit)", -+ "*turboVNC*button4.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(4)", -+ -+ "*turboVNC*button5.label: Lossless Zlib (WAN)", -+ "*turboVNC*button5.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(5)", -+ -+ "*turboVNC*button6.label: Subsampling:", -+ -+ "*turboVNC*button7.label: - None", -+ "*turboVNC*button7.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(6)", -+ -+ "*turboVNC*button8.label: - 2X", -+ "*turboVNC*button8.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(7)", -+ -+ "*turboVNC*button9.label: - 4X", -+ "*turboVNC*button9.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(8)", -+ -+ "*turboVNC*button10.label: - Gray", -+ "*turboVNC*button10.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(9)", -+ -+ "*turboVNC*button11.label: Lossless Refresh", -+ "*turboVNC*button11.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SetTurboVNC(10)", -+ -+ "*turboVNC*button12.label: Lossy Refresh", -+ "*turboVNC*button12.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: SendRFBEvent(fbupdate)", -+ -+ "*turboVNC*buttonNone.label: Not Compiled with\\nTurboVNC Support.", -+ "*turboVNC*buttonNone.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HideTurboVNC()", -+ -+ "*qualLabel.label: JPEG Image Quality:", -+ "*qualBar.length: 100", -+ "*qualBar.width: 130", -+ "*qualBar.orientation: horizontal", -+ "*qualBar.translations: #override\\n\ -+ <Btn1Down>: StartScroll(Continuous) MoveThumb() NotifyThumb()\\n\ -+ <Btn1Motion>: MoveThumb() NotifyThumb()\\n\ -+ <Btn3Down>: StartScroll(Continuous) MoveThumb() NotifyThumb()\\n\ -+ <Btn3Motion>: MoveThumb() NotifyThumb()", -+ -+ "*qualText.label: 000", -+ -+ "*scaleN*button0.label: Dismiss", -+ "*scaleN*button0.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HideScaleN()", -+ -+ "*scaleN*button1.label: 1/1", -+ "*scaleN*button1.translations: #override\\n\ -+ <Visible>: SetScaleNState(1)\\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(1) HideScaleN()", -+ -+ "*scaleN*button2.label: 1/2", -+ "*scaleN*button2.translations: #override\\n\ -+ <Visible>: SetScaleNState(2)\\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(2) HideScaleN()", -+ -+ "*scaleN*button3.label: 1/3", -+ "*scaleN*button3.translations: #override\\n\ -+ <Visible>: SetScaleNState(3)\\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(3) HideScaleN()", -+ -+ "*scaleN*button4.label: 1/4", -+ "*scaleN*button4.translations: #override\\n\ -+ <Visible>: SetScaleNState(4)\\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(4) HideScaleN()", -+ -+ "*scaleN*button5.label: 1/5", -+ "*scaleN*button5.translations: #override\\n\ -+ <Visible>: SetScaleNState(5)\\n\ -+ <Btn1Down>,<Btn1Up>: SetScaleN(5) HideScaleN()", -+ -+ "*scaleN*button6.label: Other", -+ "*scaleN*button6.translations: #override\\n\ -+ <Visible>: SetScaleNState(6)\\n\ -+ <Btn1Down>,<Btn1Up>: HideScaleN() DoServerScale()", -+ -+ "*quality*buttonD.label: Dismiss", -+ "*quality*buttonD.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HideQuality()", -+ -+ "*quality*button0.label: 0", -+ "*quality*button0.type: toggle", -+ "*quality*button0.translations: #override\\n\ -+ <Visible>: SetQualityState(0)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(0) HideQuality()", -+ -+ "*quality*button1.label: 1", -+ "*quality*button1.type: toggle", -+ "*quality*button1.translations: #override\\n\ -+ <Visible>: SetQualityState(1)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(1) HideQuality()", -+ -+ "*quality*button2.label: 2", -+ "*quality*button2.type: toggle", -+ "*quality*button2.translations: #override\\n\ -+ <Visible>: SetQualityState(2)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(2) HideQuality()", -+ -+ "*quality*button3.label: 3", -+ "*quality*button3.type: toggle", -+ "*quality*button3.translations: #override\\n\ -+ <Visible>: SetQualityState(3)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(3) HideQuality()", -+ -+ "*quality*button4.label: 4", -+ "*quality*button4.type: toggle", -+ "*quality*button4.translations: #override\\n\ -+ <Visible>: SetQualityState(4)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(4) HideQuality()", -+ -+ "*quality*button5.label: 5", -+ "*quality*button5.type: toggle", -+ "*quality*button5.translations: #override\\n\ -+ <Visible>: SetQualityState(5)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(5) HideQuality()", -+ -+ "*quality*button6.label: 6", -+ "*quality*button6.type: toggle", -+ "*quality*button6.translations: #override\\n\ -+ <Visible>: SetQualityState(6)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(6) HideQuality()", -+ -+ "*quality*button7.label: 7", -+ "*quality*button7.type: toggle", -+ "*quality*button7.translations: #override\\n\ -+ <Visible>: SetQualityState(7)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(7) HideQuality()", -+ -+ "*quality*button8.label: 8", -+ "*quality*button8.type: toggle", -+ "*quality*button8.translations: #override\\n\ -+ <Visible>: SetQualityState(8)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(8) HideQuality()", -+ -+ "*quality*button9.label: 9", -+ "*quality*button9.type: toggle", -+ "*quality*button9.translations: #override\\n\ -+ <Visible>: SetQualityState(9)\\n\ -+ <Btn1Down>,<Btn1Up>: SetQuality(9) HideQuality()", -+ -+ "*compress*buttonD.label: Dismiss", -+ "*compress*buttonD.translations: #override\\n\ -+ <Btn1Down>,<Btn1Up>: HideCompress()", -+ -+ "*compress*button0.label: 0", -+ "*compress*button0.translations: #override\\n\ -+ <Visible>: SetCompressState(0)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(0) HideCompress()", -+ -+ "*compress*button1.label: 1", -+ "*compress*button1.translations: #override\\n\ -+ <Visible>: SetCompressState(1)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(1) HideCompress()", -+ -+ "*compress*button2.label: 2", -+ "*compress*button2.translations: #override\\n\ -+ <Visible>: SetCompressState(2)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(2) HideCompress()", -+ -+ "*compress*button3.label: 3", -+ "*compress*button3.translations: #override\\n\ -+ <Visible>: SetCompressState(3)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(3) HideCompress()", -+ -+ "*compress*button4.label: 4", -+ "*compress*button4.translations: #override\\n\ -+ <Visible>: SetCompressState(4)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(4) HideCompress()", -+ -+ "*compress*button5.label: 5", -+ "*compress*button5.translations: #override\\n\ -+ <Visible>: SetCompressState(5)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(5) HideCompress()", -+ -+ "*compress*button6.label: 6", -+ "*compress*button6.translations: #override\\n\ -+ <Visible>: SetCompressState(6)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(6) HideCompress()", -+ -+ "*compress*button7.label: 7", -+ "*compress*button7.translations: #override\\n\ -+ <Visible>: SetCompressState(7)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(7) HideCompress()", -+ -+ "*compress*button8.label: 8", -+ "*compress*button8.translations: #override\\n\ -+ <Visible>: SetCompressState(8)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(8) HideCompress()", -+ -+ "*compress*button9.label: 9", -+ "*compress*button9.translations: #override\\n\ -+ <Visible>: SetCompressState(9)\\n\ -+ <Btn1Down>,<Btn1Up>: SetCompress(9) HideCompress()", -+ - NULL - }; - -@@ -124,7 +697,7 @@ - * from a dialog box. - */ - --char vncServerHost[256]; -+char vncServerHost[1024]; - int vncServerPort = 0; - - -@@ -135,6 +708,7 @@ - */ - - AppData appData; -+AppData appDataNew; - - static XtResource appDataResourceList[] = { - {"shareDesktop", "ShareDesktop", XtRBool, sizeof(Bool), -@@ -155,14 +729,44 @@ - {"userLogin", "UserLogin", XtRString, sizeof(String), - XtOffsetOf(AppData, userLogin), XtRImmediate, (XtPointer) 0}, - -+ {"unixPW", "UnixPW", XtRString, sizeof(String), -+ XtOffsetOf(AppData, unixPW), XtRImmediate, (XtPointer) 0}, -+ -+ {"msLogon", "MSLogon", XtRString, sizeof(String), -+ XtOffsetOf(AppData, msLogon), XtRImmediate, (XtPointer) 0}, -+ -+ {"repeaterUltra", "RepeaterUltra", XtRString, sizeof(String), -+ XtOffsetOf(AppData, repeaterUltra), XtRImmediate, (XtPointer) 0}, -+ -+ {"ultraDSM", "UltraDSM", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, ultraDSM), XtRImmediate, (XtPointer) False}, -+ -+ {"acceptPopup", "AcceptPopup", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, acceptPopup), XtRImmediate, (XtPointer) False}, -+ -+ {"rfbVersion", "RfbVersion", XtRString, sizeof(String), -+ XtOffsetOf(AppData, rfbVersion), XtRImmediate, (XtPointer) 0}, -+ - {"passwordDialog", "PasswordDialog", XtRBool, sizeof(Bool), - XtOffsetOf(AppData, passwordDialog), XtRImmediate, (XtPointer) False}, - - {"encodings", "Encodings", XtRString, sizeof(String), - XtOffsetOf(AppData, encodingsString), XtRImmediate, (XtPointer) 0}, - -- {"useBGR233", "UseBGR233", XtRBool, sizeof(Bool), -- XtOffsetOf(AppData, useBGR233), XtRImmediate, (XtPointer) False}, -+ {"useBGR233", "UseBGR233", XtRInt, sizeof(int), -+ XtOffsetOf(AppData, useBGR233), XtRImmediate, (XtPointer) 0}, -+ -+ {"useBGR565", "UseBGR565", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, useBGR565), XtRImmediate, (XtPointer) False}, -+ -+ {"useGreyScale", "UseGreyScale", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, useGreyScale), XtRImmediate, (XtPointer) False}, -+ -+ {"yCrop", "yCrop", XtRInt, sizeof(int), -+ XtOffsetOf(AppData, yCrop), XtRImmediate, (XtPointer) 0}, -+ -+ {"sbWidth", "sbWidth", XtRInt, sizeof(int), -+ XtOffsetOf(AppData, sbWidth), XtRImmediate, (XtPointer) 2}, - - {"nColours", "NColours", XtRInt, sizeof(int), - XtOffsetOf(AppData, nColours), XtRImmediate, (XtPointer) 256}, -@@ -179,9 +783,12 @@ - {"requestedDepth", "RequestedDepth", XtRInt, sizeof(int), - XtOffsetOf(AppData, requestedDepth), XtRImmediate, (XtPointer) 0}, - -- {"useSharedMemory", "UseSharedMemory", XtRBool, sizeof(Bool), -+ {"useShm", "UseShm", XtRBool, sizeof(Bool), - XtOffsetOf(AppData, useShm), XtRImmediate, (XtPointer) True}, - -+ {"termChat", "TermChat", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, termChat), XtRImmediate, (XtPointer) False}, -+ - {"wmDecorationWidth", "WmDecorationWidth", XtRInt, sizeof(int), - XtOffsetOf(AppData, wmDecorationWidth), XtRImmediate, (XtPointer) 4}, - -@@ -191,6 +798,9 @@ - {"popupButtonCount", "PopupButtonCount", XtRInt, sizeof(int), - XtOffsetOf(AppData, popupButtonCount), XtRImmediate, (XtPointer) 0}, - -+ {"popupButtonBreak", "PopupButtonBreak", XtRInt, sizeof(int), -+ XtOffsetOf(AppData, popupButtonBreak), XtRImmediate, (XtPointer) 0}, -+ - {"debug", "Debug", XtRBool, sizeof(Bool), - XtOffsetOf(AppData, debug), XtRImmediate, (XtPointer) False}, - -@@ -206,11 +816,13 @@ - {"bumpScrollPixels", "BumpScrollPixels", XtRInt, sizeof(int), - XtOffsetOf(AppData, bumpScrollPixels), XtRImmediate, (XtPointer) 20}, - -+ /* hardwired compress -1 vs . 7 */ - {"compressLevel", "CompressionLevel", XtRInt, sizeof(int), - XtOffsetOf(AppData, compressLevel), XtRImmediate, (XtPointer) -1}, - -+ /* hardwired quality was 6 */ - {"qualityLevel", "QualityLevel", XtRInt, sizeof(int), -- XtOffsetOf(AppData, qualityLevel), XtRImmediate, (XtPointer) 6}, -+ XtOffsetOf(AppData, qualityLevel), XtRImmediate, (XtPointer) -1}, - - {"enableJPEG", "EnableJPEG", XtRBool, sizeof(Bool), - XtOffsetOf(AppData, enableJPEG), XtRImmediate, (XtPointer) True}, -@@ -218,14 +830,97 @@ - {"useRemoteCursor", "UseRemoteCursor", XtRBool, sizeof(Bool), - XtOffsetOf(AppData, useRemoteCursor), XtRImmediate, (XtPointer) True}, - -+ {"useCursorAlpha", "UseCursorAlpha", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, useCursorAlpha), XtRImmediate, (XtPointer) False}, -+ -+ {"useRawLocal", "UseRawLocal", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, useRawLocal), XtRImmediate, (XtPointer) False}, -+ -+ {"notty", "NoTty", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, notty), XtRImmediate, (XtPointer) False}, -+ - {"useX11Cursor", "UseX11Cursor", XtRBool, sizeof(Bool), - XtOffsetOf(AppData, useX11Cursor), XtRImmediate, (XtPointer) False}, - -+ {"useBell", "UseBell", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, useBell), XtRImmediate, (XtPointer) True}, -+ - {"grabKeyboard", "GrabKeyboard", XtRBool, sizeof(Bool), -- XtOffsetOf(AppData, grabKeyboard), XtRImmediate, (XtPointer) False}, -+ XtOffsetOf(AppData, grabKeyboard), XtRImmediate, (XtPointer) True}, - - {"autoPass", "AutoPass", XtRBool, sizeof(Bool), -- XtOffsetOf(AppData, autoPass), XtRImmediate, (XtPointer) False} -+ XtOffsetOf(AppData, autoPass), XtRImmediate, (XtPointer) False}, -+ -+ {"grabAll", "GrabAll", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, grabAll), XtRImmediate, (XtPointer) False}, -+ -+ {"useXserverBackingStore", "UseXserverBackingStore", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, useXserverBackingStore), XtRImmediate, (XtPointer) False}, -+ -+ {"overrideRedir", "OverrideRedir", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, overrideRedir), XtRImmediate, (XtPointer) True}, -+ -+ {"serverInput", "ServerInput", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, serverInput), XtRImmediate, (XtPointer) True}, -+ -+ {"singleWindow", "SingleWindow", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, singleWindow), XtRImmediate, (XtPointer) False}, -+ -+ {"serverScale", "ServerScale", XtRInt, sizeof(int), -+ XtOffsetOf(AppData, serverScale), XtRImmediate, (XtPointer) 1}, -+ -+ {"chatActive", "ChatActive", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, chatActive), XtRImmediate, (XtPointer) False}, -+ -+ {"chatOnly", "ChatOnly", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, chatOnly), XtRImmediate, (XtPointer) False}, -+ -+ {"fileActive", "FileActive", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, fileActive), XtRImmediate, (XtPointer) False}, -+ -+ {"popupFix", "PopupFix", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, popupFix), XtRImmediate, (XtPointer) False}, -+ -+ {"scale", "Scale", XtRString, sizeof(String), -+ XtOffsetOf(AppData, scale), XtRImmediate, (XtPointer) 0}, -+ -+ {"pipelineUpdates", "PipelineUpdates", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, pipelineUpdates), XtRImmediate, (XtPointer) -+#ifdef TURBOVNC -+ True}, -+#else -+#if 0 -+ False}, -+#else -+ True}, -+#endif -+#endif -+ -+ {"noipv4", "noipv4", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, noipv4), XtRImmediate, (XtPointer) False}, -+ -+ {"noipv6", "noipv6", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, noipv6), XtRImmediate, (XtPointer) False}, -+ -+ {"sendClipboard", "SendClipboard", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, sendClipboard), XtRImmediate, (XtPointer) False}, -+ -+ {"sendAlways", "SendAlways", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, sendAlways), XtRImmediate, (XtPointer) False}, -+ -+ {"recvText", "RecvText", XtRString, sizeof(String), -+ XtOffsetOf(AppData, recvText), XtRImmediate, (XtPointer) 0}, -+ -+ {"appShare", "AppShare", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, appShare), XtRImmediate, (XtPointer) False}, -+ -+ {"escapeKeys", "EscapeKeys", XtRString, sizeof(String), -+ XtOffsetOf(AppData, escapeKeys), XtRImmediate, (XtPointer) 0}, -+ -+ {"escapeActive", "EscapeActive", XtRBool, sizeof(Bool), -+ XtOffsetOf(AppData, escapeActive), XtRImmediate, (XtPointer) False} -+ -+ /* check commas */ - }; - - -@@ -242,8 +937,29 @@ - {"-noraiseonbeep", "*raiseOnBeep", XrmoptionNoArg, "False"}, - {"-passwd", "*passwordFile", XrmoptionSepArg, 0}, - {"-user", "*userLogin", XrmoptionSepArg, 0}, -+ {"-unixpw", "*unixPW", XrmoptionSepArg, 0}, -+ {"-mslogon", "*msLogon", XrmoptionSepArg, 0}, -+ {"-repeater", "*repeaterUltra", XrmoptionSepArg, 0}, -+ {"-ultradsm", "*ultraDSM", XrmoptionNoArg, "True"}, -+ {"-acceptpopup", "*acceptPopup", XrmoptionNoArg, "True"}, -+ {"-acceptpopupsc", "*acceptPopup", XrmoptionNoArg, "True"}, -+ {"-rfbversion", "*rfbVersion", XrmoptionSepArg, 0}, - {"-encodings", "*encodings", XrmoptionSepArg, 0}, -- {"-bgr233", "*useBGR233", XrmoptionNoArg, "True"}, -+ {"-bgr233", "*useBGR233", XrmoptionNoArg, "256"}, -+ {"-use64", "*useBGR233", XrmoptionNoArg, "64"}, -+ {"-bgr222", "*useBGR233", XrmoptionNoArg, "64"}, -+ {"-use8", "*useBGR233", XrmoptionNoArg, "8"}, -+ {"-bgr111", "*useBGR233", XrmoptionNoArg, "8"}, -+ {"-16bpp", "*useBGR565", XrmoptionNoArg, "True"}, -+ {"-bgr565", "*useBGR565", XrmoptionNoArg, "True"}, -+ {"-grey", "*useGreyScale", XrmoptionNoArg, "True"}, -+ {"-gray", "*useGreyScale", XrmoptionNoArg, "True"}, -+ {"-sbwidth", "*sbwidth", XrmoptionSepArg, 0}, -+ {"-env", "*envDummy", XrmoptionSepArg, 0}, -+ {"-ycrop", "*yCrop", XrmoptionSepArg, 0}, -+ {"-rawlocal", "*useRawLocal", XrmoptionNoArg, "True"}, -+ {"-notty", "*notty", XrmoptionNoArg, "True"}, -+ {"-alpha", "*useCursorAlpha", XrmoptionNoArg, "True"}, - {"-owncmap", "*forceOwnCmap", XrmoptionNoArg, "True"}, - {"-truecolor", "*forceTrueColour", XrmoptionNoArg, "True"}, - {"-truecolour", "*forceTrueColour", XrmoptionNoArg, "True"}, -@@ -253,8 +969,30 @@ - {"-nojpeg", "*enableJPEG", XrmoptionNoArg, "False"}, - {"-nocursorshape", "*useRemoteCursor", XrmoptionNoArg, "False"}, - {"-x11cursor", "*useX11Cursor", XrmoptionNoArg, "True"}, -- {"-autopass", "*autoPass", XrmoptionNoArg, "True"} -- -+ {"-nobell", "*useBell", XrmoptionNoArg, "False"}, -+ {"-autopass", "*autoPass", XrmoptionNoArg, "True"}, -+ {"-graball", "*grabAll", XrmoptionNoArg, "True"}, -+ {"-grabkbd", "*grabKeyboard", XrmoptionNoArg, "True"}, -+ {"-nograbkbd", "*grabKeyboard", XrmoptionNoArg, "False"}, -+ {"-grabkeyboard", "*grabKeyboard", XrmoptionNoArg, "True"}, -+ {"-nograbkeyboard","*grabKeyboard", XrmoptionNoArg, "False"}, -+ {"-nooverride", "*overrideRedir", XrmoptionNoArg, "False"}, -+ {"-bs", "*useXserverBackingStore", XrmoptionNoArg, "True"}, -+ {"-nobs", "*useXserverBackingStore", XrmoptionNoArg, "False"}, -+ {"-popupfix", "*popupFix", XrmoptionNoArg, "True"}, -+ {"-noshm", "*useShm", XrmoptionNoArg, "False"}, -+ {"-termchat", "*termChat", XrmoptionNoArg, "True"}, -+ {"-chatonly", "*chatOnly", XrmoptionNoArg, "True"}, -+ {"-scale", "*scale", XrmoptionSepArg, 0}, -+ {"-appshare", "*appShare", XrmoptionNoArg, "True"}, -+ {"-escape", "*escapeKeys", XrmoptionSepArg, 0}, -+ {"-sendclipboard", "*sendClipboard", XrmoptionNoArg, "True"}, -+ {"-sendalways", "*sendAlways", XrmoptionNoArg, "True"}, -+ {"-recvtext", "*recvText", XrmoptionSepArg, 0}, -+ {"-pipeline", "*pipelineUpdates", XrmoptionNoArg, "True"}, -+ {"-nopipeline", "*pipelineUpdates", XrmoptionNoArg, "False"}, -+ {"-noipv4", "*noipv4", XrmoptionNoArg, "True"}, -+ {"-noipv6", "*noipv6", XrmoptionNoArg, "True"} - }; - - int numCmdLineOptions = XtNumber(cmdLineOptions); -@@ -267,16 +1005,100 @@ - static XtActionsRec actions[] = { - {"SendRFBEvent", SendRFBEvent}, - {"ShowPopup", ShowPopup}, -+ {"Noop", Noop}, - {"HidePopup", HidePopup}, -+ {"HideScaleN", HideScaleN}, -+ {"HideTurboVNC", HideTurboVNC}, -+ {"HideQuality", HideQuality}, -+ {"HideCompress", HideCompress}, - {"ToggleFullScreen", ToggleFullScreen}, -+ {"JumpLeft", JumpLeft}, -+ {"JumpRight", JumpRight}, -+ {"JumpUp", JumpUp}, -+ {"JumpDown", JumpDown}, - {"SetFullScreenState", SetFullScreenState}, - {"SelectionFromVNC", SelectionFromVNC}, - {"SelectionToVNC", SelectionToVNC}, - {"ServerDialogDone", ServerDialogDone}, -+ {"UserDialogDone", UserDialogDone}, -+ {"YCropDialogDone", YCropDialogDone}, -+ {"ScbarDialogDone", ScbarDialogDone}, -+ {"ScaleNDialogDone", ScaleNDialogDone}, -+ {"ScaleDialogDone", ScaleDialogDone}, - {"PasswordDialogDone", PasswordDialogDone}, - {"Pause", Pause}, - {"RunCommand", RunCommand}, - {"Quit", Quit}, -+ {"HideChat", HideChat}, -+ {"Toggle8bpp", Toggle8bpp}, -+ {"Toggle16bpp", Toggle16bpp}, -+ {"ToggleFullColor", ToggleFullColor}, -+ {"Toggle256Colors", Toggle256Colors}, -+ {"Toggle64Colors", Toggle64Colors}, -+ {"Toggle8Colors", Toggle8Colors}, -+ {"ToggleGreyScale", ToggleGreyScale}, -+ {"ToggleTightZRLE", ToggleTightZRLE}, -+ {"ToggleTightHextile", ToggleTightHextile}, -+ {"ToggleZRLEZYWRLE", ToggleZRLEZYWRLE}, -+ {"ToggleViewOnly", ToggleViewOnly}, -+ {"ToggleJPEG", ToggleJPEG}, -+ {"ToggleCursorShape", ToggleCursorShape}, -+ {"ToggleCursorAlpha", ToggleCursorAlpha}, -+ {"ToggleX11Cursor", ToggleX11Cursor}, -+ {"ToggleBell", ToggleBell}, -+ {"ToggleRawLocal", ToggleRawLocal}, -+ {"ToggleServerInput", ToggleServerInput}, -+ {"TogglePipelineUpdates", TogglePipelineUpdates}, -+ {"ToggleSendClipboard", ToggleSendClipboard}, -+ {"ToggleSendAlways", ToggleSendAlways}, -+ {"ToggleSingleWindow", ToggleSingleWindow}, -+ {"ToggleTextChat", ToggleTextChat}, -+ {"ToggleFileXfer", ToggleFileXfer}, -+ {"ToggleXGrab", ToggleXGrab}, -+ {"DoServerScale", DoServerScale}, -+ {"SetScale", SetScale}, -+ {"SetYCrop", SetYCrop}, -+ {"SetScbar", SetScbar}, -+ {"ShowScaleN", ShowScaleN}, -+ {"ShowTurboVNC", ShowTurboVNC}, -+ {"ShowQuality", ShowQuality}, -+ {"ShowCompress", ShowCompress}, -+ {"SetScaleN", SetScaleN}, -+ {"SetTurboVNC", SetTurboVNC}, -+ {"SetQuality", SetQuality}, -+ {"SetCompress", SetCompress}, -+ {"Set8bppState", Set8bppState}, -+ {"Set16bppState", Set16bppState}, -+ {"SetFullColorState", SetFullColorState}, -+ {"Set256ColorsState", Set256ColorsState}, -+ {"Set64ColorsState", Set64ColorsState}, -+ {"Set8ColorsState", Set8ColorsState}, -+ {"SetGreyScaleState", SetGreyScaleState}, -+ {"SetZRLEState", SetZRLEState}, -+ {"SetHextileState", SetHextileState}, -+ {"SetZYWRLEState", SetZYWRLEState}, -+ {"SetNOJPEGState", SetNOJPEGState}, -+ {"SetScaleNState", SetScaleNState}, -+ {"SetQualityState", SetQualityState}, -+ {"SetCompressState", SetCompressState}, -+ {"SetViewOnlyState", SetViewOnlyState}, -+ {"SetCursorShapeState", SetCursorShapeState}, -+ {"SetCursorAlphaState", SetCursorAlphaState}, -+ {"SetX11CursorState", SetX11CursorState}, -+ {"SetBellState", SetBellState}, -+ {"SetRawLocalState", SetRawLocalState}, -+ {"SetServerInputState", SetServerInputState}, -+ {"SetPipelineUpdates", SetPipelineUpdates}, -+ {"SetSendClipboard", SetSendClipboard}, -+ {"SetSendAlways", SetSendAlways}, -+ {"SetSingleWindowState", SetSingleWindowState}, -+ {"SetTextChatState", SetTextChatState}, -+ {"SetFileXferState", SetFileXferState}, -+ {"SetXGrabState", SetXGrabState}, -+ {"SetEscapeKeysState", SetEscapeKeysState}, -+ {"ToggleEscapeActive", ToggleEscapeActive}, -+ {"EscapeDialogDone", EscapeDialogDone}, -+ {"SetEscapeKeys", SetEscapeKeys} - }; - - -@@ -302,11 +1124,14 @@ - void - usage(void) - { -- fprintf(stderr, -- "TightVNC viewer version 1.3dev7\n" -+ fprintf(stdout, -+ "SSVNC Viewer (based on TightVNC viewer version 1.3.9)\n" - "\n" - "Usage: %s [<OPTIONS>] [<HOST>][:<DISPLAY#>]\n" - " %s [<OPTIONS>] [<HOST>][::<PORT#>]\n" -+ " %s [<OPTIONS>] exec=[CMD ARGS...]\n" -+ " %s [<OPTIONS>] fd=n\n" -+ " %s [<OPTIONS>] /path/to/unix/socket\n" - " %s [<OPTIONS>] -listen [<DISPLAY#>]\n" - " %s -help\n" - "\n" -@@ -319,7 +1144,7 @@ - " -noraiseonbeep\n" - " -passwd <PASSWD-FILENAME> (standard VNC authentication)\n" - " -user <USERNAME> (Unix login authentication)\n" -- " -encodings <ENCODING-LIST> (e.g. \"tight copyrect\")\n" -+ " -encodings <ENCODING-LIST> (e.g. \"tight,copyrect\")\n" - " -bgr233\n" - " -owncmap\n" - " -truecolour\n" -@@ -332,10 +1157,390 @@ - " -autopass\n" - "\n" - "Option names may be abbreviated, e.g. -bgr instead of -bgr233.\n" -- "See the manual page for more information." -- "\n", programName, programName, programName, programName); -+ "See the manual page for more information.\n" -+ "\n" -+ "\n" -+ "Enhanced TightVNC viewer (SSVNC) options:\n" -+ "\n" -+ " URL http://www.karlrunge.com/x11vnc/ssvnc.html\n" -+ "\n" -+ " Note: ZRLE and ZYWRLE encodings are now supported.\n" -+ "\n" -+ " Note: F9 is shortcut to Toggle FullScreen mode.\n" -+ "\n" -+ " Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1\n" -+ " to allow more than one incoming VNC server at a time.\n" -+ " This is the same as -multilisten described below. Set\n" -+ " SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than \"n\"\n" -+ " simultaneous reverse connections.\n" -+ "\n" -+ " Note: If the host:port is specified as \"exec=command args...\"\n" -+ " then instead of making a TCP/IP socket connection to the\n" -+ " remote VNC server, \"command args...\" is executed and the\n" -+ " viewer is attached to its stdio. This enables tunnelling\n" -+ " established via an external command, e.g. an stunnel(8)\n" -+ " that does not involve a listening socket. This mode does\n" -+ " not work for -listen reverse connections.\n" -+ "\n" -+ " If the host:port is specified as \"fd=n\" then it is assumed\n" -+ " n is an already opened file descriptor to the socket. (i.e\n" -+ " the parent did fork+exec)\n" -+ "\n" -+ " If the host:port contains a '/' it is interpreted as a\n" -+ " unix-domain socket (AF_LOCAL insead of AF_INET)\n" -+ "\n" -+ " -multilisten As in -listen (reverse connection listening) except\n" -+ " allow more than one incoming VNC server to be connected\n" -+ " at a time. The default for -listen of only one at a\n" -+ " time tries to play it safe by not allowing anyone on\n" -+ " the network to put (many) desktops on your screen over\n" -+ " a long window of time. Use -multilisten for no limit.\n" -+ "\n" -+ " -acceptpopup In -listen (reverse connection listening) mode when\n" -+ " a reverse VNC connection comes in show a popup asking\n" -+ " whether to Accept or Reject the connection. The IP\n" -+ " address of the connecting host is shown. Same as\n" -+ " setting the env. var. SSVNC_ACCEPT_POPUP=1.\n" -+ "\n" -+ " -acceptpopupsc As in -acceptpopup except assume UltraVNC Single\n" -+ " Click (SC) server. Retrieve User and ComputerName\n" -+ " info from UltraVNC Server and display in the Popup.\n" -+ "\n" -+ " -use64 In -bgr233 mode, use 64 colors instead of 256.\n" -+ " -bgr222 Same as -use64.\n" -+ "\n" -+ " -use8 In -bgr233 mode, use 8 colors instead of 256.\n" -+ " -bgr111 Same as -use8.\n" -+ "\n" -+ " -16bpp If the vnc viewer X display is depth 24 at 32bpp\n" -+ " request a 16bpp format from the VNC server to cut\n" -+ " network traffic by up to 2X, then tranlate the\n" -+ " pixels to 32bpp locally.\n" -+ " -bgr565 Same as -16bpp.\n" -+ "\n" -+ " -grey Use a grey scale for the 16- and 8-bpp modes.\n" -+ "\n" -+ " -alpha Use alphablending transparency for local cursors\n" -+ " requires: x11vnc server, both client and server\n" -+ " must be 32bpp and same endianness.\n" -+ "\n" -+ " -scale str Scale the desktop locally. The string \"str\" can\n" -+ " a floating point ratio, e.g. \"0.9\", or a fraction,\n" -+ " e.g. \"3/4\", or WxH, e.g. 1280x1024. Use \"fit\"\n" -+ " to fit in the current screen size. Use \"auto\" to\n" -+ " fit in the window size. \"str\" can also be set by\n" -+ " the env. var. SSVNC_SCALE.\n" -+ "\n" -+ " If you observe mouse trail painting errors, enable\n" -+ " X11 Cursor mode (either via Popup or -x11cursor.)\n" -+ "\n" -+ " Note that scaling is done in software and so can be\n" -+ " slow and requires more memory. Some speedup Tips:\n" -+ "\n" -+ " ZRLE is faster than Tight in this mode. When\n" -+ " scaling is first detected, the encoding will\n" -+ " be automatically switched to ZRLE. Use the\n" -+ " Popup menu if you want to go back to Tight.\n" -+ " Set SSVNC_PRESERVE_ENCODING=1 to disable this.\n" -+ "\n" -+ " Use a solid background on the remote side.\n" -+ " (e.g. manually or via x11vnc -solid ...)\n" -+ "\n" -+ " If the remote server is x11vnc, try client\n" -+ " side caching: x11vnc -ncache 10 ...\n" -+ "\n" -+ " -ycrop n Only show the top n rows of the framebuffer. For\n" -+ " use with x11vnc -ncache client caching option\n" -+ " to help \"hide\" the pixel cache region.\n" -+ " Use a negative value (e.g. -1) for autodetection.\n" -+ " Autodetection will always take place if the remote\n" -+ " fb height is more than 2 times the width.\n" -+ "\n" -+ " -sbwidth n Scrollbar width for x11vnc -ncache mode (-ycrop),\n" -+ " default is very narrow: 2 pixels, it is narrow to\n" -+ " avoid distraction in -ycrop mode.\n" -+ "\n" -+ " -nobell Disable bell.\n" -+ "\n" -+ " -rawlocal Prefer raw encoding for localhost, default is\n" -+ " no, i.e. assumes you have a SSH tunnel instead.\n" -+ "\n" -+ " -notty Try to avoid using the terminal for interactive\n" -+ " responses: use windows for messages and prompting\n" -+ " instead. Messages will also be printed to terminal.\n" -+ "\n" -+ " -sendclipboard Send the X CLIPBOARD selection (i.e. Ctrl+C,\n" -+ " Ctrl+V) instead of the X PRIMARY selection (mouse\n" -+ " select and middle button paste.)\n" -+ "\n" -+ " -sendalways Whenever the mouse enters the VNC viewer main\n" -+ " window, send the selection to the VNC server even if\n" -+ " it has not changed. This is like the Xt resource\n" -+ " translation SelectionToVNC(always)\n" -+ "\n" -+ " -recvtext str When cut text is received from the VNC server,\n" -+ " ssvncviewer will set both the X PRIMARY and the\n" -+ " X CLIPBOARD local selections. To control which\n" -+ " is set, specify 'str' as 'primary', 'clipboard',\n" -+ " or 'both' (the default.)\n" -+ "\n" -+ " -graball Grab the entire X server when in fullscreen mode,\n" -+ " needed by some old window managers like fvwm2.\n" -+ "\n" -+ " -popupfix Warp the popup back to the pointer position,\n" -+ " needed by some old window managers like fvwm2.\n" -+ " -sendclipboard Send the X CLIPBOARD selection (i.e. Ctrl+C,\n" -+ " Ctrl+V) instead of the X PRIMARY selection (mouse\n" -+ " select and middle button paste.)\n" -+ "\n" -+ " -sendalways Whenever the mouse enters the VNC viewer main\n" -+ " window, send the selection to the VNC server even if\n" -+ " it has not changed. This is like the Xt resource\n" -+ " translation SelectionToVNC(always)\n" -+ "\n" -+ " -recvtext str When cut text is received from the VNC server,\n" -+ " ssvncviewer will set both the X PRIMARY and the\n" -+ " X CLIPBOARD local selections. To control which\n" -+ " is set, specify 'str' as 'primary', 'clipboard',\n" -+ " or 'both' (the default.)\n" -+ "\n" -+ " -graball Grab the entire X server when in fullscreen mode,\n" -+ " needed by some old window managers like fvwm2.\n" -+ "\n" -+ " -popupfix Warp the popup back to the pointer position,\n" -+ " needed by some old window managers like fvwm2.\n" -+ "\n" -+ " -grabkbd Grab the X keyboard when in fullscreen mode,\n" -+ " needed by some window managers. Same as -grabkeyboard.\n" -+ " -grabkbd is the default, use -nograbkbd to disable.\n" -+ "\n" -+ " -bs, -nobs Whether or not to use X server Backingstore for the\n" -+ " main viewer window. The default is to not, mainly\n" -+ " because most Linux, etc, systems X servers disable\n" -+ " *all* Backingstore by default. To re-enable it put\n" -+ "\n" -+ " Option \"Backingstore\"\n" -+ "\n" -+ " in the Device section of /etc/X11/xorg.conf.\n" -+ " In -bs mode with no X server backingstore, whenever an\n" -+ " area of the screen is re-exposed it must go out to the\n" -+ " VNC server to retrieve the pixels. This is too slow.\n" -+ "\n" -+ " In -nobs mode, memory is allocated by the viewer to\n" -+ " provide its own backing of the main viewer window. This\n" -+ " actually makes some activities faster (changes in large\n" -+ " regions) but can appear to \"flash\" too much.\n" -+ "\n" -+ " -noshm Disable use of MIT shared memory extension (not recommended)\n" -+ "\n" -+ " -termchat Do the UltraVNC chat in the terminal vncviewer is in\n" -+ " instead of in an independent window.\n" -+ "\n" -+ " -unixpw str Useful for logging into x11vnc in -unixpw mode. \"str\" is a\n" -+ " string that allows many ways to enter the Unix Username\n" -+ " and Unix Password. These characters: username, newline,\n" -+ " password, newline are sent to the VNC server after any VNC\n" -+ " authentication has taken place. Under x11vnc they are\n" -+ " used for the -unixpw login. Other VNC servers could do\n" -+ " something similar.\n" -+ "\n" -+ " You can also indicate \"str\" via the environment\n" -+ " variable SSVNC_UNIXPW.\n" -+ "\n" -+ " Note that the Escape key is actually sent first to tell\n" -+ " x11vnc to not echo the Unix Username back to the VNC\n" -+ " viewer. Set SSVNC_UNIXPW_NOESC=1 to override this.\n" -+ "\n" -+ " If str is \".\", then you are prompted at the command line\n" -+ " for the username and password in the normal way. If str is\n" -+ " \"-\" the stdin is read via getpass(3) for username@password.\n" -+ " Otherwise if str is a file, it is opened and the first line\n" -+ " read is taken as the Unix username and the 2nd as the\n" -+ " password. If str prefixed by \"rm:\" the file is removed\n" -+ " after reading. Otherwise, if str has a \"@\" character,\n" -+ " it is taken as username@password. Otherwise, the program\n" -+ " exits with an error. Got all that?\n" -+ "\n" -+ " -repeater str This is for use with UltraVNC repeater proxy described\n" -+ " here: http://www.uvnc.com/addons/repeater.html. The \"str\"\n" -+ " is the ID string to be sent to the repeater. E.g. ID:1234\n" -+ " It can also be the hostname and port or display of the VNC\n" -+ " server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when\n" -+ " using -repeater, the host:dpy on the cmdline is the repeater\n" -+ " server, NOT the VNC server. The repeater will connect you.\n" -+ "\n" -+ " Example: vncviewer ... -repeater ID:3333 repeat.host:5900\n" -+ " Example: vncviewer ... -repeater vhost:0 repeat.host:5900\n" -+ "\n" -+ " Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a\n" -+ " Single Click III (SSL) repeater (repeater_SSL.exe) and you\n" -+ " are passing the SSL part of the connection through stunnel,\n" -+ " socat, etc. This way the magic UltraVNC string 'testB'\n" -+ " needed to work with the repeater is sent to it.\n" -+ "\n" -+ " -rfbversion str Set the advertised RFB version. E.g.: -rfbversion 3.6\n" -+ " For some servers, e.g. UltraVNC this needs to be done.\n" -+ "\n" -+ " -ultradsm UltraVNC has symmetric private key encryption DSM plugins:\n" -+ " http://www.uvnc.com/features/encryption.html. It is assumed\n" -+ " you are using a unix program (e.g. our ultravnc_dsm_helper)\n" -+ " to encrypt and decrypt the UltraVNC DSM stream. IN ADDITION\n" -+ " TO THAT supply -ultradsm to tell THIS viewer to modify the\n" -+ " RFB data sent so as to work with the UltraVNC Server. For\n" -+ " some reason, each RFB msg type must be sent twice under DSM.\n" -+ "\n" -+ " -mslogon user Use Windows MS Logon to an UltraVNC server. Supply the\n" -+ " username or \"1\" to be prompted. The default is to\n" -+ " autodetect the UltraVNC MS Logon server and prompt for\n" -+ " the username and password.\n" -+ "\n" -+ " IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman\n" -+ " exchange is very weak and can be brute forced to recover\n" -+ " your username and password in a few seconds of CPU time.\n" -+ " To be safe, be sure to use an additional encrypted tunnel\n" -+ " (e.g. SSL or SSH) for the entire VNC session.\n" -+ "\n" -+ " -chatonly Try to be a client that only does UltraVNC text chat. This\n" -+ " mode is used by x11vnc to present a chat window on the\n" -+ " physical X11 console (i.e. chat with the person at the\n" -+ " display).\n" -+ "\n" -+ " -env VAR=VALUE To save writing a shell script to set environment variables,\n" -+ " specify as many as you need on the command line. For\n" -+ " example, -env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi\n" -+ "\n" -+ " -noipv6 Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1.\n" -+ "\n" -+ " -noipv4 Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1.\n" -+ "\n" -+ " -printres Print out the Ssvnc X resources (appdefaults) and then exit\n" -+ " You can save them to a file and customize them (e.g. the\n" -+ " keybindings and Popup menu) Then point to the file via\n" -+ " XENVIRONMENT or XAPPLRESDIR.\n" -+ "\n" -+ " -pipeline Like TurboVNC, request the next framebuffer update as soon\n" -+ " as possible instead of waiting until the end of the current\n" -+ " framebuffer update coming in. Helps 'pipeline' the updates.\n" -+ " This is currently the default, use -nopipeline to disable.\n" -+ "\n" -+ " -appshare Enable features for use with x11vnc's -appshare mode where\n" -+ " instead of sharing the full desktop only the application's\n" -+ " windows are shared. Viewer multilisten mode is used to\n" -+ " create the multiple windows: -multilisten is implied.\n" -+ " See 'x11vnc -appshare -help' more information on the mode.\n" -+ "\n" -+ " Features enabled in the viewer under -appshare are:\n" -+ " Minimum extra text in the title, auto -ycrop is disabled,\n" -+ " x11vnc -remote_prefix X11VNC_APPSHARE_CMD: message channel,\n" -+ " x11vnc initial window position hints. See also Escape Keys\n" -+ " below for additional key and mouse bindings.\n" -+ "\n" -+ " -escape str This sets the 'Escape Keys' modifier sequence and enables\n" -+ " escape keys mode. When the modifier keys escape sequence\n" -+ " is held down, the next keystroke is interpreted locally\n" -+ " to perform a special action instead of being sent to the\n" -+ " remote VNC server.\n" -+ "\n" -+ " Use '-escape default' for the default modifier sequence.\n" -+ " (Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L)\n" -+ "\n" -+ " Here are the 'Escape Keys: Help+Set' instructions from the Popup Menu:\n" -+ "\n" -+ " Escape Keys: Enter a comma separated list of modifier keys to be the\n" -+ " 'escape sequence'. When these keys are held down, the next keystroke is\n" -+ " interpreted locally to invoke a special action instead of being sent to\n" -+ " the remote VNC server. In other words, a set of 'Hot Keys'.\n" -+ " \n" -+ " To enable or disable this, click on 'Escape Keys: Toggle' in the Popup.\n" -+ " \n" -+ " Here is the list of hot-key mappings to special actions:\n" -+ " \n" -+ " r: refresh desktop b: toggle bell c: toggle full-color\n" -+ " f: file transfer x: x11cursor z: toggle Tight/ZRLE\n" -+ " l: full screen g: graball e: escape keys dialog\n" -+ " s: scale dialog +: scale up (=) -: scale down (_)\n" -+ " t: text chat a: alphablend cursor\n" -+ " V: toggle viewonly Q: quit viewer 1 2 3 4 5 6: UltraVNC scale 1/n\n" -+ " \n" -+ " Arrow keys: pan the viewport about 10%% for each keypress.\n" -+ " PageUp / PageDown: pan the viewport by a screenful vertically.\n" -+ " Home / End: pan the viewport by a screenful horizontally.\n" -+ " KeyPad Arrow keys: pan the viewport by 1 pixel for each keypress.\n" -+ " Dragging the Mouse with Button1 pressed also pans the viewport.\n" -+ " Clicking Mouse Button3 brings up the Popup Menu.\n" -+ " \n" -+ " The above mappings are *always* active in ViewOnly mode, unless you set the\n" -+ " Escape Keys value to 'never'.\n" -+ " \n" -+ " If the Escape Keys value below is set to 'default' then a default list of\n" -+ " of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it\n" -+ " is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag\n" -+ " on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side\n" -+ " of the keyboard.\n" -+ " \n" -+ " On Unix the default is Alt and Windows keys on Left side of keyboard.\n" -+ " On MacOSX the default is Control and Command keys on Left side of keyboard.\n" -+ " \n" -+ " Example: Press and hold the Alt and Windows keys on the LEFT side of the\n" -+ " keyboard and then press 'c' to toggle the full-color state. Or press 't'\n" -+ " to toggle the ultravnc Text Chat window, etc.\n" -+ " \n" -+ " To use something besides the default, supply a comma separated list (or a\n" -+ " single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L\n" -+ " Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch.\n" -+ "\n" -+ "\n" -+ " New Popup actions:\n" -+ "\n" -+ " ViewOnly: ~ -viewonly\n" -+ " Disable Bell: ~ -nobell\n" -+ " Cursor Shape: ~ -nocursorshape\n" -+ " X11 Cursor: ~ -x11cursor\n" -+ " Cursor Alphablend: ~ -alpha\n" -+ " Toggle Tight/Hextile: ~ -encodings hextile...\n" -+ " Toggle Tight/ZRLE: ~ -encodings zrle...\n" -+ " Toggle ZRLE/ZYWRLE: ~ -encodings zywrle...\n" -+ " Quality Level ~ -quality (both Tight and ZYWRLE)\n" -+ " Compress Level ~ -compresslevel\n" -+ " Disable JPEG: ~ -nojpeg (Tight)\n" -+ " Pipeline Updates ~ -pipeline\n" -+ "\n" -+ " Full Color as many colors as local screen allows.\n" -+ " Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only.\n" -+ " 16 bit color (BGR565) ~ -16bpp / -bgr565\n" -+ " 8 bit color (BGR233) ~ -bgr233\n" -+ " 256 colors ~ -bgr233 default # of colors.\n" -+ " 64 colors ~ -bgr222 / -use64\n" -+ " 8 colors ~ -bgr111 / -use8\n" -+ " Scale Viewer ~ -scale\n" -+ " Escape Keys: Toggle ~ -escape\n" -+ " Escape Keys: Help+Set ~ -escape\n" -+ " Set Y Crop (y-max) ~ -ycrop\n" -+ " Set Scrollbar Width ~ -sbwidth\n" -+ " XGrabServer ~ -graball\n" -+ "\n" -+ " UltraVNC Extensions:\n" -+ "\n" -+ " Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n.\n" -+ " Text Chat Ultravnc ext. Do Text Chat.\n" -+ " File Transfer Ultravnc ext. File xfer via Java helper.\n" -+ " Single Window Ultravnc ext. Grab and view a single window.\n" -+ " (select then click on the window you want).\n" -+ " Disable Remote Input Ultravnc ext. Try to prevent input and\n" -+ " viewing of monitor at physical display.\n" -+ "\n" -+ " Note: the Ultravnc extensions only apply to servers that support\n" -+ " them. x11vnc/libvncserver supports some of them.\n" -+ "\n" -+ " Send Clipboard not Primary ~ -sendclipboard\n" -+ " Send Selection Every time ~ -sendalways\n" -+ "\n" -+ "\n", programName, programName, programName, programName, programName, programName, programName); - exit(1); - } -+#if 0 -+ " -nooverride Do not apply OverrideRedirect in fullscreen mode.\n" -+#endif - - - /* -@@ -343,77 +1548,247 @@ - * not already processed by XtVaAppInitialize(). It sets vncServerHost and - * vncServerPort and all the fields in appData. - */ -+extern int saw_appshare; - - void - GetArgsAndResources(int argc, char **argv) - { -- int i; -- char *vncServerName, *colonPos; -- int len, portOffset; -+ char *vncServerName = NULL, *colonPos, *bracketPos; -+ int len, portOffset; -+ int disp; - - /* Turn app resource specs into our appData structure for the rest of the - program to use */ - -- XtGetApplicationResources(toplevel, &appData, appDataResourceList, -- XtNumber(appDataResourceList), 0, 0); -+ XtGetApplicationResources(toplevel, &appData, appDataResourceList, -+ XtNumber(appDataResourceList), 0, 0); -+ -+ /* -+ * we allow setting of some by env, to avoid clash with other -+ * viewer's cmdlines (e.g. change viewer in SSVNC). -+ */ -+ if (getenv("VNCVIEWER_ALPHABLEND")) { -+ appData.useCursorAlpha = True; -+ } -+ if (getenv("VNCVIEWER_POPUP_FIX")) { -+ if (getenv("NOPOPUPFIX")) { -+ ; -+ } else if (!strcmp(getenv("VNCVIEWER_POPUP_FIX"), "0")) { -+ ; -+ } else { -+ appData.popupFix = True; -+ } -+ } -+ if (getenv("VNCVIEWER_GRAB_SERVER")) { -+ appData.grabAll = True; -+ } -+ if (getenv("VNCVIEWER_YCROP")) { -+ int n = atoi(getenv("VNCVIEWER_YCROP")); -+ if (n != 0) { -+ appData.yCrop = n; -+ } -+ } -+ if (getenv("VNCVIEWER_RFBVERSION") && strcmp(getenv("VNCVIEWER_RFBVERSION"), "")) { -+ appData.rfbVersion = strdup(getenv("VNCVIEWER_RFBVERSION")); -+ } -+ if (getenv("VNCVIEWER_ENCODINGS") && strcmp(getenv("VNCVIEWER_ENCODINGS"), "")) { -+ appData.encodingsString = strdup(getenv("VNCVIEWER_ENCODINGS")); -+ } -+ if (getenv("VNCVIEWER_NOBELL")) { -+ appData.useBell = False; -+ } -+ if (getenv("VNCVIEWER_X11CURSOR")) { -+ appData.useX11Cursor = True; -+ } -+ if (getenv("VNCVIEWER_RAWLOCAL")) { -+ appData.useRawLocal = True; -+ } -+ if (getenv("VNCVIEWER_NOTTY") || getenv("SSVNC_VNCVIEWER_NOTTY")) { -+ appData.notty = True; -+ } -+ if (getenv("VNCVIEWER_SBWIDTH")) { -+ int n = atoi(getenv("VNCVIEWER_SBWIDTH")); -+ if (n != 0) { -+ appData.sbWidth = n; -+ } -+ } -+ if (getenv("VNCVIEWER_ULTRADSM")) { -+ appData.ultraDSM = True; -+ } -+ if (getenv("SSVNC_ULTRA_DSM") && strcmp(getenv("SSVNC_ULTRA_DSM"), "")) { -+ appData.ultraDSM = True; -+ } -+ if (getenv("SSVNC_NO_ULTRA_DSM")) { -+ appData.ultraDSM = False; -+ } -+ if (getenv("SSVNC_SCALE") && strcmp(getenv("SSVNC_SCALE"), "")) { -+ if (appData.scale == NULL) { -+ appData.scale = strdup(getenv("SSVNC_SCALE")); -+ } -+ } -+ if (getenv("VNCVIEWER_ESCAPE") && strcmp(getenv("VNCVIEWER_ESCAPE"), "")) { -+ if (appData.escapeKeys == NULL) { -+ appData.escapeKeys = strdup(getenv("VNCVIEWER_ESCAPE")); -+ } -+ } -+ if (saw_appshare) { -+ appData.appShare = True; -+ } -+ if (appData.appShare && appData.escapeKeys == NULL) { -+ appData.escapeKeys = strdup("default"); -+ } -+ if (appData.escapeKeys != NULL) { -+ appData.escapeActive = True; -+ } -+ if (getenv("VNCVIEWER_SEND_CLIPBOARD")) { -+ appData.sendClipboard = True; -+ } -+ if (getenv("VNCVIEWER_SEND_ALWAYS")) { -+ appData.sendAlways = True; -+ } -+ if (getenv("VNCVIEWER_RECV_TEXT")) { -+ char *s = getenv("VNCVIEWER_RECV_TEXT"); -+ if (!strcasecmp(s, "clipboard")) { -+ appData.recvText = strdup("clipboard"); -+ } else if (!strcasecmp(s, "primary")) { -+ appData.recvText = strdup("primary"); -+ } else if (!strcasecmp(s, "both")) { -+ appData.recvText = strdup("both"); -+ } -+ } -+ if (getenv("VNCVIEWER_PIPELINE_UPDATES")) { -+ appData.pipelineUpdates = True; -+ } else if (getenv("VNCVIEWER_NO_PIPELINE_UPDATES")) { -+ appData.pipelineUpdates = False; -+ } -+ -+ if (getenv("VNCVIEWER_NO_IPV4")) { -+ appData.noipv4 = True; -+ } -+ if (getenv("VNCVIEWER_NO_IPV6")) { -+ appData.noipv6 = True; -+ } -+ -+ if (appData.useBGR233 && appData.useBGR565) { -+ appData.useBGR233 = 0; -+ } -+ -+ if (getenv("SSVNC_ULTRA_FTP_JAR") == NULL && programName != NULL) { -+ int len = strlen(programName) + 200; -+ char *q, *jar = (char *) malloc(len); -+ -+ sprintf(jar, "%s", programName); -+ q = strrchr(jar, '/'); -+ if (q) { -+ struct stat sb; -+ *(q+1) = '\0'; -+ strcat(jar, "../lib/ssvnc/util/ultraftp.jar"); -+ if (stat(jar, &sb) == 0) { -+ char *put = (char *) malloc(len); -+ sprintf(put, "SSVNC_ULTRA_FTP_JAR=%s", jar); -+ fprintf(stderr, "Setting: %s\n\n", put); -+ putenv(put); -+ } else { -+ sprintf(jar, "%s", programName); -+ q = strrchr(jar, '/'); -+ *(q+1) = '\0'; -+ strcat(jar, "util/ultraftp.jar"); -+ if (stat(jar, &sb) == 0) { -+ char *put = (char *) malloc(len); -+ sprintf(put, "SSVNC_ULTRA_FTP_JAR=%s", jar); -+ fprintf(stderr, "Setting: %s\n\n", put); -+ putenv(put); -+ } -+ } -+ } -+ free(jar); -+ } -+ - - /* Add our actions to the actions table so they can be used in widget - resource specs */ - -- XtAppAddActions(appContext, actions, XtNumber(actions)); -+ XtAppAddActions(appContext, actions, XtNumber(actions)); - - /* Check any remaining command-line arguments. If -listen was specified - there should be none. Otherwise the only argument should be the VNC - server name. If not given then pop up a dialog box and wait for the - server name to be entered. */ - -- if (listenSpecified) { -- if (argc != 1) { -- fprintf(stderr,"\n%s -listen: invalid command line argument: %s\n", -- programName, argv[1]); -- usage(); -- } -- return; -- } -- -- if (argc == 1) { -- vncServerName = DoServerDialog(); -- appData.passwordDialog = True; -- } else if (argc != 2) { -- usage(); -- } else { -- vncServerName = argv[1]; -- -- if (!isatty(0)) -- appData.passwordDialog = True; -- if (vncServerName[0] == '-') -- usage(); -- } -- -- if (strlen(vncServerName) > 255) { -- fprintf(stderr,"VNC server name too long\n"); -- exit(1); -- } -- -- colonPos = strchr(vncServerName, ':'); -- if (colonPos == NULL) { -- /* No colon -- use default port number */ -- strcpy(vncServerHost, vncServerName); -- vncServerPort = SERVER_PORT_OFFSET; -- } else { -- memcpy(vncServerHost, vncServerName, colonPos - vncServerName); -- vncServerHost[colonPos - vncServerName] = '\0'; -- len = strlen(colonPos + 1); -- portOffset = SERVER_PORT_OFFSET; -- if (colonPos[1] == ':') { -- /* Two colons -- interpret as a port number */ -- colonPos++; -- len--; -- portOffset = 0; -- } -- if (!len || strspn(colonPos + 1, "0123456789") != len) { -- usage(); -- } -- vncServerPort = atoi(colonPos + 1) + portOffset; -- } -+ if (listenSpecified) { -+ if (argc != 1) { -+ fprintf(stderr,"\n%s -listen: invalid command line argument: %s\n", -+ programName, argv[1]); -+ usage(); -+ } -+ return; -+ } -+ -+ if (argc == 1) { -+ vncServerName = DoServerDialog(); -+ if (!use_tty()) { -+ appData.passwordDialog = True; -+ } -+ } else if (argc != 2) { -+ usage(); -+ } else { -+ vncServerName = argv[1]; -+ -+ if (!use_tty()) { -+ appData.passwordDialog = True; -+ } -+ if (vncServerName[0] == '-') { -+ usage(); -+ } -+ } -+ -+ if (strlen(vncServerName) > 255) { -+ fprintf(stderr,"VNC server name too long\n"); -+ exit(1); -+ } -+ -+ colonPos = strrchr(vncServerName, ':'); -+ bracketPos = strrchr(vncServerName, ']'); -+ if (strstr(vncServerName, "exec=") == vncServerName) { -+ /* special exec-external-command case */ -+ strcpy(vncServerHost, vncServerName); -+ vncServerPort = SERVER_PORT_OFFSET; -+ } else if (strstr(vncServerName, "fd=") == vncServerName) { -+ /* special exec-external-command case */ -+ strcpy(vncServerHost, vncServerName); -+ vncServerPort = SERVER_PORT_OFFSET; -+ } else if (colonPos == NULL) { -+ /* No colon -- use default port number */ -+ strcpy(vncServerHost, vncServerName); -+ vncServerPort = SERVER_PORT_OFFSET; -+ } else if (bracketPos != NULL && colonPos < bracketPos) { -+ strcpy(vncServerHost, vncServerName); -+ vncServerPort = SERVER_PORT_OFFSET; -+ } else { -+ if (colonPos > vncServerName && *(colonPos - 1) == ':') { -+ colonPos--; -+ } -+ memcpy(vncServerHost, vncServerName, colonPos - vncServerName); -+ vncServerHost[colonPos - vncServerName] = '\0'; -+ len = strlen(colonPos + 1); -+ portOffset = SERVER_PORT_OFFSET; -+ if (colonPos[1] == ':') { -+ /* Two colons -- interpret as a port number */ -+ colonPos++; -+ len--; -+ portOffset = 0; -+ } -+ if (!len || strspn(colonPos + 1, "0123456789") != (size_t) len) { -+ usage(); -+ } -+#if 0 -+ vncServerPort = atoi(colonPos + 1) + portOffset; -+#else -+ disp = atoi(colonPos + 1); -+ if (portOffset != 0 && disp >= 100) { -+ portOffset = 0; -+ } -+ vncServerPort = disp + portOffset; -+#endif -+ } - } -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/colour.c vnc_unixsrc/vncviewer/colour.c ---- vnc_unixsrc.orig/vncviewer/colour.c 2002-04-30 09:07:31.000000000 -0400 -+++ vnc_unixsrc/vncviewer/colour.c 2010-02-25 22:02:19.000000000 -0500 -@@ -31,9 +31,12 @@ - #define BGR233_SIZE 256 - unsigned long BGR233ToPixel[BGR233_SIZE]; - -+#define BGR565_SIZE 65536 -+unsigned long BGR565ToPixel[BGR565_SIZE]; -+ - Colormap cmap; - Visual *vis; --unsigned int visdepth, visbpp; -+unsigned int visdepth, visbpp, isLSB; - Bool allocColorFailed = False; - - static int nBGR233ColoursAllocated; -@@ -45,6 +48,8 @@ - static void AllocateExactBGR233Colours(); - static Bool AllocateBGR233Colour(int r, int g, int b); - -+static void SetupBGR565Map(unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask); -+ - - /* - * SetVisualAndCmap() deals with the wonderful world of X "visuals" (which are -@@ -97,6 +102,44 @@ - visbpp = GetBPPForDepth(visdepth); - cmap = DefaultColormap(dpy,DefaultScreen(dpy)); - -+ if (ImageByteOrder(dpy) == LSBFirst) { -+ isLSB = 1; -+ } else { -+ isLSB = 0; -+ } -+ if (visbpp == 24) { -+ if (!appData.useBGR233) { -+ fprintf(stderr, "Warning: for 24bpp enabling -bgr565 -- Don't use FullColor!\n"); -+ appData.useBGR565 = True; -+ } else { -+ fprintf(stderr, "Warning: for 24bpp using -bgr233 -- Don't use FullColor!\n"); -+ } -+ } -+ -+ if (appData.useBGR565) { -+ if (visdepth < 24 || visbpp < 24 || vis->class != TrueColor) { -+ fprintf(stderr, "disabling -16bpp BGR565 on non-depth 24 machine\n"); -+ appData.useBGR565 = False; -+ } else { -+ myFormat.bitsPerPixel = 16; -+ myFormat.depth = 16; -+ myFormat.trueColour = 1; -+ myFormat.bigEndian = 0; -+ myFormat.redMax = 31; -+ myFormat.greenMax = 63; -+ myFormat.blueMax = 31; -+ myFormat.redShift = 11; -+ myFormat.greenShift = 5; -+ myFormat.blueShift = 0; -+ -+ fprintf(stderr, "Using default colormap and translating from BGR565 (65536 colors). Pixel format:\n"); -+ PrintPixelFormat(&myFormat); -+ -+ SetupBGR565Map(vis->red_mask, vis->green_mask, vis->blue_mask); -+ return; -+ } -+ } -+ - if (!appData.useBGR233 && (vis->class == TrueColor)) { - - myFormat.bitsPerPixel = visbpp; -@@ -116,21 +159,42 @@ - return; - } - -- appData.useBGR233 = True; -+ if (appData.useBGR233 == 0) { -+ appData.useBGR233 = 256; -+ } - - myFormat.bitsPerPixel = 8; - myFormat.depth = 8; - myFormat.trueColour = 1; - myFormat.bigEndian = 0; -- myFormat.redMax = 7; -+ myFormat.redMax = 7; - myFormat.greenMax = 7; -- myFormat.blueMax = 3; -- myFormat.redShift = 0; -+ myFormat.blueMax = 3; -+ myFormat.redShift = 0; - myFormat.greenShift = 3; -- myFormat.blueShift = 6; -+ myFormat.blueShift = 6; -+ -+ if (appData.useBGR233 == 64) { -+ /* BGR222 */ -+ myFormat.redMax = 3; -+ myFormat.greenMax = 3; -+ myFormat.blueMax = 3; -+ myFormat.redShift = 0; -+ myFormat.greenShift = 2; -+ myFormat.blueShift = 4; -+ } -+ if (appData.useBGR233 == 8) { -+ /* BGR111 */ -+ myFormat.redMax = 2; -+ myFormat.greenMax = 2; -+ myFormat.blueMax = 2; -+ myFormat.redShift = 0; -+ myFormat.greenShift = 1; -+ myFormat.blueShift = 2; -+ } - - fprintf(stderr, -- "Using default colormap and translating from BGR233. Pixel format:\n"); -+ "Using default colormap and translating from BGR233 (%d colors). Pixel format:\n", appData.useBGR233); - PrintPixelFormat(&myFormat); - - SetupBGR233Map(); -@@ -282,8 +346,12 @@ - XFree(format); - - if (bpp != 1 && bpp != 8 && bpp != 16 && bpp != 32) { -- fprintf(stderr,"Can't cope with %d bits-per-pixel. Sorry.\n", bpp); -- exit(1); -+ if (bpp == 24) { -+ fprintf(stderr,"Warning: 24 bits-per-pixel may have problems...\n"); -+ } else { -+ fprintf(stderr,"Can't cope with %d bits-per-pixel. Sorry.\n", bpp); -+ exit(1); -+ } - } - - return bpp; -@@ -374,7 +442,7 @@ - if (!exactBGR233[i] && - XAllocColor(dpy, cmap, &cmapEntry[i])) { - -- if (cmapEntry[i].pixel == i) { -+ if ((long) cmapEntry[i].pixel == i) { - - shared[i] = True; /* probably shared */ - -@@ -394,16 +462,43 @@ - for (r = 0; r < 8; r++) { - for (g = 0; g < 8; g++) { - for (b = 0; b < 4; b++) { -- if (BGR233ToPixel[(b<<6) | (g<<3) | r] == INVALID_PIXEL) { -+ int bs = 6, gs = 3, rs = 0; -+ int bm = 3, gm = 7, rm = 7; -+ if (appData.useBGR233 == 64) { -+ bs = 4; gs = 2; rs = 0; -+ bm = 3; gm = 3; rm = 3; -+ } -+ if (appData.useBGR233 == 8) { -+ bs = 2; gs = 1; rs = 0; -+ bm = 1; gm = 1; rm = 1; -+ } -+ if ((b > bm || g > gm || r > rm)) { -+ continue; -+ } -+ if (BGR233ToPixel[(b<<bs) | (g<<gs) | (r<<rs)] == INVALID_PIXEL) { - - unsigned long minDistance = ULONG_MAX; - - for (i = 0; i < cmapSize; i++) { - if (exactBGR233[i] || shared[i]) { -- unsigned long distance -- = (abs(cmapEntry[i].red - r * 65535 / 7) -- + abs(cmapEntry[i].green - g * 65535 / 7) -- + abs(cmapEntry[i].blue - b * 65535 / 3)); -+ unsigned long distance; -+ int r1, g1, b1; -+ if (appData.useGreyScale) { -+ int ave; -+ ave = (r + g + 2*b)/3; -+ r1 = ave; -+ g1 = ave; -+ b1 = ave/2; -+ } else { -+ r1 = r; -+ g1 = g; -+ b1 = b; -+ } -+ distance -+ = ( abs(cmapEntry[i].red - r1 * 65535 / rm) -+ + abs(cmapEntry[i].green - g1 * 65535 / gm) -+ + abs(cmapEntry[i].blue - b1 * 65535 / bm)); -+ - - if (distance < minDistance) { - minDistance = distance; -@@ -412,7 +507,7 @@ - } - } - -- BGR233ToPixel[(b<<6) | (g<<3) | r] = nearestPixel; -+ BGR233ToPixel[(b<<bs) | (g<<gs) | (r<<rs)] = nearestPixel; - if (shared[nearestPixel] && !usedAsNearest[nearestPixel]) - nSharedUsed++; - usedAsNearest[nearestPixel] = True; -@@ -433,6 +528,59 @@ - } - } - -+static void -+SetupBGR565Map(unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask) -+{ -+ int r, g, b; -+ int r2, g2, b2; -+ long idx; -+ int cnt = 0; -+ unsigned long pixel = 0; -+ -+ for (r = 0; r < 32; r++) { -+ for (g = 0; g < 64; g++) { -+ for (b = 0; b < 32; b++) { -+ int bs = 0, gs = 5, rs = 11; -+ int bm = 31, gm = 63, rm = 31; -+ if ((b > bm || g > gm || r > rm)) { -+ continue; -+ } -+ r2 = (255 * r) / rm; -+ g2 = (255 * g) / gm; -+ b2 = (255 * b) / bm; -+ -+ pixel = (r2 << 16) | (g2 << 8) | (b2 << 0); -+ if (appData.useGreyScale) { -+ int ave; -+ int r1, g1, b1; -+ ave = (2*r + g + 2*b)/3; -+ r1 = ave/2; -+ g1 = ave; -+ b1 = ave/2; -+ -+ r2 = (255 * r1) / rm; -+ g2 = (255 * g1) / gm; -+ b2 = (255 * b1) / bm; -+ -+ pixel = (r2 << 16) | (g2 << 8) | (b2 << 0); -+ } -+ -+ if (red_mask == 0xff) { -+ idx = (r<<bs) | (g<<gs) | (b<<rs); -+ } else { -+ idx = (b<<bs) | (g<<gs) | (r<<rs); -+ } -+ if (0) fprintf(stderr, "cnt: %5d idx: %lu pixel: 0x%08x\n", cnt, idx, (unsigned int) pixel); -+ BGR565ToPixel[idx] = pixel; -+ cnt++; -+ } -+ } -+ } -+ green_mask = 0; -+ blue_mask = 0; -+} -+ -+ - - /* - * AllocateExactBGR233Colours() attempts to allocate each of the colours in the -@@ -484,8 +632,13 @@ - ri = rn; - for (gi = 0; gi < gn; gi++) { - for (bi = 0; bi < bn; bi++) { -- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) -- return; -+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) { -+ nBGR233ColoursAllocated++; -+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) { -+ nBGR233ColoursAllocated++; -+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) { -+ return; -+ } - } - } - rn++; -@@ -496,8 +649,13 @@ - gi = gn; - for (ri = 0; ri < rn; ri++) { - for (bi = 0; bi < bn; bi++) { -- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) -- return; -+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) { -+ nBGR233ColoursAllocated++; -+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) { -+ nBGR233ColoursAllocated++; -+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) { -+ return; -+ } - } - } - gn++; -@@ -507,8 +665,13 @@ - bi = bn; - for (ri = 0; ri < rn; ri++) { - for (gi = 0; gi < gn; gi++) { -- if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) -- return; -+ if (appData.useBGR233 == 64 && (bv[bi] > 3 || gv[gi] > 3 || rv[ri] > 3)) { -+ nBGR233ColoursAllocated++; -+ } else if (appData.useBGR233 == 8 && (bv[bi] > 1 || gv[gi] > 1 || rv[ri] > 1)) { -+ nBGR233ColoursAllocated++; -+ } else if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi])) { -+ return; -+ } - } - } - bn++; -@@ -529,18 +692,36 @@ - AllocateBGR233Colour(int r, int g, int b) - { - XColor c; -+ int bs = 6, gs = 3, rs = 0; -+ int bm = 3, gm = 7, rm = 7; - - if (nBGR233ColoursAllocated >= appData.nColours) - return False; - -- c.red = r * 65535 / 7; -- c.green = g * 65535 / 7; -- c.blue = b * 65535 / 3; -+ if (appData.useBGR233 == 64) { -+ bs = 4; gs = 2, rs = 0; -+ bm = 3; gm = 3; rm = 3; -+ } -+ if (appData.useBGR233 == 8) { -+ bs = 2; gs = 1, rs = 0; -+ bm = 1; gm = 1; rm = 1; -+ } -+ -+ c.red = r * 65535 / rm; -+ c.green = g * 65535 / gm; -+ c.blue = b * 65535 / bm; -+ if (appData.useGreyScale) { -+ int ave; -+ ave = (c.red + c.green + c.blue)/3; -+ c.red = ave; -+ c.green = ave; -+ c.blue = ave; -+ } - - if (!XAllocColor(dpy, cmap, &c)) - return False; - -- BGR233ToPixel[(b<<6) | (g<<3) | r] = c.pixel; -+ BGR233ToPixel[(b<<bs) | (g<<gs) | r] = c.pixel; - - nBGR233ColoursAllocated++; - -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/corre.c vnc_unixsrc/vncviewer/corre.c ---- vnc_unixsrc.orig/vncviewer/corre.c 2000-06-11 08:00:53.000000000 -0400 -+++ vnc_unixsrc/vncviewer/corre.c 2008-10-05 15:16:01.000000000 -0400 -@@ -29,6 +29,18 @@ - #define HandleCoRREBPP CONCAT2E(HandleCoRRE,BPP) - #define CARDBPP CONCAT2E(CARD,BPP) - -+#define FillRectangle(x, y, w, h, color) \ -+ { \ -+ XGCValues _gcv; \ -+ _gcv.foreground = color; \ -+ if (!appData.useXserverBackingStore) { \ -+ FillScreen(x, y, w, h, _gcv.foreground); \ -+ } else { \ -+ XChangeGC(dpy, gc, GCForeground, &_gcv); \ -+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \ -+ } \ -+ } -+ - static Bool - HandleCoRREBPP (int rx, int ry, int rw, int rh) - { -@@ -50,11 +62,19 @@ - #if (BPP == 8) - gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix); - #else -+#if (BPP == 16) -+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix); -+#else - gcv.foreground = pix; - #endif -+#endif - -+#if 0 - XChangeGC(dpy, gc, GCForeground, &gcv); - XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh); -+#else -+ FillRectangle(rx, ry, rw, rh, gcv.foreground); -+#endif - - if (!ReadFromRFBServer(buffer, hdr.nSubrects * (4 + (BPP / 8)))) - return False; -@@ -72,12 +92,22 @@ - #if (BPP == 8) - gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix); - #else -+#if (BPP == 16) -+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix); -+#else - gcv.foreground = pix; - #endif -+#endif - -+#if 0 - XChangeGC(dpy, gc, GCForeground, &gcv); - XFillRectangle(dpy, desktopWin, gc, rx + x, ry + y, w, h); -+#else -+ FillRectangle(rx + x, ry + y, w, h, gcv.foreground); -+#endif - } - - return True; - } -+ -+#undef FillRectangle -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/cp_it vnc_unixsrc/vncviewer/cp_it ---- vnc_unixsrc.orig/vncviewer/cp_it 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/cp_it 2009-03-06 20:02:05.000000000 -0500 -@@ -0,0 +1,18 @@ -+#!/bin/sh -+ -+dest=/dist/bin/vncviewerz-1.3dev5-resize -+suc "cp -p $dest $dest.back; mv $dest $dest.unlink; mv $dest.back $dest; rm $dest.unlink" -+strip ./vncviewer -+cat ./vncviewer > $dest -+touch -r ./vncviewer $dest -+yy=/dist/src/apps/VNC/etc/libvncserver_cvs/expts/etv/ssvnc/bin/Linux.i686/vncviewer -+mv $yy $yy.unlink -+cp -p ./vncviewer $yy -+mv $yy.turbovnc $yy.unlink.turbovnc -+cp -p ./vncviewer $HOME/etv_col/Linux.i686 -+cp -p ./vncviewer.turbovnc $yy.turbovnc -+cp -p ./vncviewer.turbovnc $HOME/etv_col/Linux.i686/vncviewer.turbovnc -+chmod 755 $yy* -+ -+rm -f $yy.unlink* -+ls -l ./vncviewer* $dest $yy* $HOME/etv_col/Linux.i686/vncviewer* -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/cursor.c vnc_unixsrc/vncviewer/cursor.c ---- vnc_unixsrc.orig/vncviewer/cursor.c 2003-01-15 04:46:52.000000000 -0500 -+++ vnc_unixsrc/vncviewer/cursor.c 2010-02-25 22:04:28.000000000 -0500 -@@ -38,8 +38,11 @@ - - - static Bool prevSoftCursorSet = False; --static Pixmap rcSavedArea; --static CARD8 *rcSource, *rcMask; -+static Pixmap rcSavedArea, rcSavedArea_0; -+static int rcSavedArea_w = -1, rcSavedArea_h = -1; -+static char *rcSavedScale = NULL; -+static int rcSavedScale_len = 0; -+static CARD8 *rcSource = NULL, *rcMask; - static int rcHotX, rcHotY, rcWidth, rcHeight; - static int rcCursorX = 0, rcCursorY = 0; - static int rcLockX, rcLockY, rcLockWidth, rcLockHeight; -@@ -48,8 +51,13 @@ - static Bool SoftCursorInLockedArea(void); - static void SoftCursorCopyArea(int oper); - static void SoftCursorDraw(void); --static void FreeSoftCursor(void); --static void FreeX11Cursor(); -+void FreeSoftCursor(void); -+void FreeX11Cursor(); -+ -+extern XImage *image; -+extern XImage *image_scale; -+extern int scale_x, scale_y; -+int scale_round(int n, double factor); - - /* Copied from Xvnc/lib/font/util/utilbitmap.c */ - static unsigned char _reverse_byte[0x100] = { -@@ -91,6 +99,8 @@ - static Bool prevXCursorSet = False; - static Cursor prevXCursor; - -+extern double scale_factor_x; -+extern double scale_factor_y; - - Bool HandleXCursor(int xhot, int yhot, int width, int height) - { -@@ -124,7 +134,7 @@ - XQueryBestCursor(dpy, dr, width, height, &wret, &hret); - } - -- if (width * height == 0 || wret < width || hret < height) { -+ if (width * height == 0 || (int) wret < width || (int) hret < height) { - /* Free resources */ - if (buf != NULL) - free(buf); -@@ -139,7 +149,7 @@ - fg.green = (unsigned short)colors.foreGreen << 8 | colors.foreGreen; - fg.blue = (unsigned short)colors.foreBlue << 8 | colors.foreBlue; - -- for (i = 0; i < bytesData * 2; i++) -+ for (i = 0; (size_t) i < bytesData * 2; i++) - buf[i] = (char)_reverse_byte[(int)buf[i] & 0xFF]; - - source = XCreateBitmapFromData(dpy, dr, buf, width, height); -@@ -167,148 +177,179 @@ - - Bool HandleCursorShape(int xhot, int yhot, int width, int height, CARD32 enc) - { -- int bytesPerPixel; -- size_t bytesPerRow, bytesMaskData; -- Drawable dr; -- rfbXCursorColors rgb; -- CARD32 colors[2]; -- char *buf; -- CARD8 *ptr; -- int x, y, b; -- -- bytesPerPixel = myFormat.bitsPerPixel / 8; -- bytesPerRow = (width + 7) / 8; -- bytesMaskData = bytesPerRow * height; -- dr = DefaultRootWindow(dpy); -- -- FreeSoftCursor(); -+ int bytesPerPixel; -+ size_t bytesPerRow, bytesMaskData; -+ Drawable dr; -+ rfbXCursorColors rgb; -+ CARD32 colors[2]; -+ char *buf; -+ CARD8 *ptr; -+ int x, y, b; -+ -+ bytesPerPixel = myFormat.bitsPerPixel / 8; -+ bytesPerRow = (width + 7) / 8; -+ bytesMaskData = bytesPerRow * height; -+ dr = DefaultRootWindow(dpy); - -- if (width * height == 0) -- return True; -- -- /* Allocate memory for pixel data and temporary mask data. */ -+ FreeSoftCursor(); - -- rcSource = malloc(width * height * bytesPerPixel); -- if (rcSource == NULL) -- return False; -- -- buf = malloc(bytesMaskData); -- if (buf == NULL) { -- free(rcSource); -- return False; -- } -+ if (width * height == 0) { -+ return True; -+ } - -- /* Read and decode cursor pixel data, depending on the encoding type. */ -+ /* Allocate memory for pixel data and temporary mask data. */ - -- if (enc == rfbEncodingXCursor) { -- if (appData.useX11Cursor) { -- HandleXCursor(xhot, yhot, width, height); -- return True; -- } -+ rcSource = malloc(width * height * bytesPerPixel); -+ if (rcSource == NULL) { -+ return False; -+ } - -- /* Read and convert background and foreground colors. */ -- if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) { -- free(rcSource); -- free(buf); -- return False; -- } -- colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue); -- colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue); -+ buf = malloc(bytesMaskData); -+ if (buf == NULL) { -+ free(rcSource); -+ rcSource = NULL; -+ return False; -+ } - -- /* Read 1bpp pixel data into a temporary buffer. */ -- if (!ReadFromRFBServer(buf, bytesMaskData)) { -- free(rcSource); -- free(buf); -- return False; -- } -+ /* Read and decode cursor pixel data, depending on the encoding type. */ - -- /* Convert 1bpp data to byte-wide color indices. */ -- ptr = rcSource; -- for (y = 0; y < height; y++) { -- for (x = 0; x < width / 8; x++) { -- for (b = 7; b >= 0; b--) { -- *ptr = buf[y * bytesPerRow + x] >> b & 1; -- ptr += bytesPerPixel; -- } -- } -- for (b = 7; b > 7 - width % 8; b--) { -- *ptr = buf[y * bytesPerRow + x] >> b & 1; -- ptr += bytesPerPixel; -- } -- } -+ if (enc == rfbEncodingXCursor) { -+ if (appData.useX11Cursor) { -+ HandleXCursor(xhot, yhot, width, height); -+ return True; -+ } -+ -+ /* Read and convert background and foreground colors. */ -+ if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) { -+ free(rcSource); -+ rcSource = NULL; -+ free(buf); -+ return False; -+ } -+ colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue); -+ colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue); -+ -+ /* Read 1bpp pixel data into a temporary buffer. */ -+ if (!ReadFromRFBServer(buf, bytesMaskData)) { -+ free(rcSource); -+ rcSource = NULL; -+ free(buf); -+ return False; -+ } -+ -+ /* Convert 1bpp data to byte-wide color indices. */ -+ ptr = rcSource; -+ for (y = 0; y < height; y++) { -+ for (x = 0; x < width / 8; x++) { -+ for (b = 7; b >= 0; b--) { -+ *ptr = buf[y * bytesPerRow + x] >> b & 1; -+ ptr += bytesPerPixel; -+ } -+ } -+ for (b = 7; b > 7 - width % 8; b--) { -+ *ptr = buf[y * bytesPerRow + x] >> b & 1; -+ ptr += bytesPerPixel; -+ } -+ } -+ -+ /* Convert indices into the actual pixel values. */ -+ switch (bytesPerPixel) { -+ case 1: -+ for (x = 0; x < width * height; x++) { -+ rcSource[x] = (CARD8)colors[rcSource[x]]; -+ } -+ break; -+ case 2: -+ for (x = 0; x < width * height; x++) { -+ ((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]]; -+ } -+ break; -+ case 4: -+ for (x = 0; x < width * height; x++) { -+ ((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]]; -+ } -+ break; -+ } -+ -+ } else { /* enc == rfbEncodingRichCursor */ -+ if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) { -+ free(rcSource); -+ rcSource = NULL; -+ free(buf); -+ return False; -+ } -+ } - -- /* Convert indices into the actual pixel values. */ -- switch (bytesPerPixel) { -- case 1: -- for (x = 0; x < width * height; x++) -- rcSource[x] = (CARD8)colors[rcSource[x]]; -- break; -- case 2: -- for (x = 0; x < width * height; x++) -- ((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]]; -- break; -- case 4: -- for (x = 0; x < width * height; x++) -- ((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]]; -- break; -- } -+ /* Read and decode mask data. */ - -- } else { /* enc == rfbEncodingRichCursor */ -+ if (!ReadFromRFBServer(buf, bytesMaskData)) { -+ free(rcSource); -+ rcSource = NULL; -+ free(buf); -+ return False; -+ } - -- if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) { -- free(rcSource); -- free(buf); -- return False; -- } -+ rcMask = malloc(width * height); -+ if (rcMask == NULL) { -+ free(rcSource); -+ rcSource = NULL; -+ free(buf); -+ return False; -+ } - -- } -+ ptr = rcMask; -+ for (y = 0; y < height; y++) { -+ for (x = 0; x < width / 8; x++) { -+ for (b = 7; b >= 0; b--) { -+ *ptr++ = buf[y * bytesPerRow + x] >> b & 1; -+ } -+ } -+ for (b = 7; b > 7 - width % 8; b--) { -+ *ptr++ = buf[y * bytesPerRow + x] >> b & 1; -+ } -+ } - -- /* Read and decode mask data. */ -+ free(buf); - -- if (!ReadFromRFBServer(buf, bytesMaskData)) { -- free(rcSource); -- free(buf); -- return False; -- } -+ /* Set remaining data associated with cursor. */ - -- rcMask = malloc(width * height); -- if (rcMask == NULL) { -- free(rcSource); -- free(buf); -- return False; -- } -+ dr = DefaultRootWindow(dpy); - -- ptr = rcMask; -- for (y = 0; y < height; y++) { -- for (x = 0; x < width / 8; x++) { -- for (b = 7; b >= 0; b--) { -- *ptr++ = buf[y * bytesPerRow + x] >> b & 1; -- } -- } -- for (b = 7; b > 7 - width % 8; b--) { -- *ptr++ = buf[y * bytesPerRow + x] >> b & 1; -- } -- } -+ if (scale_x > 0) { -+ int w = scale_round(width, scale_factor_x) + 2; -+ int h = scale_round(height, scale_factor_y) + 2; -+ rcSavedArea = XCreatePixmap(dpy, dr, w, h, visdepth); -+ rcSavedArea_w = w; -+ rcSavedArea_h = h; -+ } else { -+ rcSavedArea = XCreatePixmap(dpy, dr, width, height, visdepth); -+ rcSavedArea_w = width; -+ rcSavedArea_h = height; -+ } -+ rcSavedArea_0 = XCreatePixmap(dpy, dr, width, height, visdepth); - -- free(buf); -+if (0) fprintf(stderr, "rcSavedArea_wh: %d %d scale_x: %d\n", rcSavedArea_w, rcSavedArea_h, scale_x); - -- /* Set remaining data associated with cursor. */ -+ if (rcSavedScale_len < 4 * width * height + 4096) { -+ if (rcSavedScale) { -+ free(rcSavedScale); -+ } -+ rcSavedScale = (char *) malloc(2 * 4 * width * height + 4096); -+ } - -- dr = DefaultRootWindow(dpy); -- rcSavedArea = XCreatePixmap(dpy, dr, width, height, visdepth); -- rcHotX = xhot; -- rcHotY = yhot; -- rcWidth = width; -- rcHeight = height; -+ rcHotX = xhot; -+ rcHotY = yhot; -+ rcWidth = width; -+ rcHeight = height; - -- SoftCursorCopyArea(OPER_SAVE); -- SoftCursorDraw(); -+ SoftCursorCopyArea(OPER_SAVE); -+ SoftCursorDraw(); - -- rcCursorHidden = False; -- rcLockSet = False; -+ rcCursorHidden = False; -+ rcLockSet = False; - -- prevSoftCursorSet = True; -- return True; -+ prevSoftCursorSet = True; -+ return True; - } - - /********************************************************************* -@@ -319,20 +360,27 @@ - - Bool HandleCursorPos(int x, int y) - { -- if (appData.useX11Cursor) { -- if (appData.fullScreen) -- XWarpPointer(dpy, None, desktopWin, 0, 0, 0, 0, x, y); -- -- return True; -- } -+ if (x < 0) x = 0; -+ if (y < 0) y = 0; - -- if (x >= si.framebufferWidth) -- x = si.framebufferWidth - 1; -- if (y >= si.framebufferHeight) -- y = si.framebufferHeight - 1; -+ /* fprintf(stderr, "xy: %d %d\n", x, y); */ - -- SoftCursorMove(x, y); -- return True; -+ if (x >= si.framebufferWidth) { -+ x = si.framebufferWidth - 1; -+ } -+ if (y >= si.framebufferHeight) { -+ y = si.framebufferHeight - 1; -+ } -+ -+ if (appData.useX11Cursor) { -+ if (appData.fullScreen) { -+ XWarpPointer(dpy, None, desktopWin, 0, 0, 0, 0, x, y); -+ } -+ return True; -+ } -+ -+ SoftCursorMove(x, y); -+ return True; - } - - /********************************************************************* -@@ -348,30 +396,31 @@ - { - int newX, newY; - -- if (!prevSoftCursorSet) -- return; -+ if (!prevSoftCursorSet) { -+ return; -+ } - -- if (!rcLockSet) { -- rcLockX = x; -- rcLockY = y; -- rcLockWidth = w; -- rcLockHeight = h; -- rcLockSet = True; -- } else { -- newX = (x < rcLockX) ? x : rcLockX; -- newY = (y < rcLockY) ? y : rcLockY; -- rcLockWidth = (x + w > rcLockX + rcLockWidth) ? -- (x + w - newX) : (rcLockX + rcLockWidth - newX); -- rcLockHeight = (y + h > rcLockY + rcLockHeight) ? -- (y + h - newY) : (rcLockY + rcLockHeight - newY); -- rcLockX = newX; -- rcLockY = newY; -- } -+ if (!rcLockSet) { -+ rcLockX = x; -+ rcLockY = y; -+ rcLockWidth = w; -+ rcLockHeight = h; -+ rcLockSet = True; -+ } else { -+ newX = (x < rcLockX) ? x : rcLockX; -+ newY = (y < rcLockY) ? y : rcLockY; -+ rcLockWidth = (x + w > rcLockX + rcLockWidth) ? -+ (x + w - newX) : (rcLockX + rcLockWidth - newX); -+ rcLockHeight = (y + h > rcLockY + rcLockHeight) ? -+ (y + h - newY) : (rcLockY + rcLockHeight - newY); -+ rcLockX = newX; -+ rcLockY = newY; -+ } - -- if (!rcCursorHidden && SoftCursorInLockedArea()) { -- SoftCursorCopyArea(OPER_RESTORE); -- rcCursorHidden = True; -- } -+ if (!rcCursorHidden && SoftCursorInLockedArea()) { -+ SoftCursorCopyArea(OPER_RESTORE); -+ rcCursorHidden = True; -+ } - } - - /********************************************************************* -@@ -381,15 +430,16 @@ - - void SoftCursorUnlockScreen(void) - { -- if (!prevSoftCursorSet) -- return; -+ if (!prevSoftCursorSet) { -+ return; -+ } - -- if (rcCursorHidden) { -- SoftCursorCopyArea(OPER_SAVE); -- SoftCursorDraw(); -- rcCursorHidden = False; -- } -- rcLockSet = False; -+ if (rcCursorHidden) { -+ SoftCursorCopyArea(OPER_SAVE); -+ SoftCursorDraw(); -+ rcCursorHidden = False; -+ } -+ rcLockSet = False; - } - - /********************************************************************* -@@ -401,19 +451,19 @@ - - void SoftCursorMove(int x, int y) - { -- if (prevSoftCursorSet && !rcCursorHidden) { -- SoftCursorCopyArea(OPER_RESTORE); -- rcCursorHidden = True; -- } -+ if (prevSoftCursorSet && !rcCursorHidden) { -+ SoftCursorCopyArea(OPER_RESTORE); -+ rcCursorHidden = True; -+ } - -- rcCursorX = x; -- rcCursorY = y; -+ rcCursorX = x; -+ rcCursorY = y; - -- if (prevSoftCursorSet && !(rcLockSet && SoftCursorInLockedArea())) { -- SoftCursorCopyArea(OPER_SAVE); -- SoftCursorDraw(); -- rcCursorHidden = False; -- } -+ if (prevSoftCursorSet && !(rcLockSet && SoftCursorInLockedArea())) { -+ SoftCursorCopyArea(OPER_SAVE); -+ SoftCursorDraw(); -+ rcCursorHidden = False; -+ } - } - - -@@ -429,41 +479,169 @@ - rcLockY + rcLockHeight > rcCursorY - rcHotY); - } - --static void SoftCursorCopyArea(int oper) --{ -- int x, y, w, h; -+void new_pixmap(int w, int h) { - -- x = rcCursorX - rcHotX; -- y = rcCursorY - rcHotY; -- if (x >= si.framebufferWidth || y >= si.framebufferHeight) -- return; -- -- w = rcWidth; -- h = rcHeight; -- if (x < 0) { -- w += x; -- x = 0; -- } else if (x + w > si.framebufferWidth) { -- w = si.framebufferWidth - x; -- } -- if (y < 0) { -- h += y; -- y = 0; -- } else if (y + h > si.framebufferHeight) { -- h = si.framebufferHeight - y; -- } -+ XFreePixmap(dpy, rcSavedArea); - -- if (oper == OPER_SAVE) { -- /* Save screen area in memory. */ --#ifdef MITSHM -- if (appData.useShm) -- XSync(dpy, False); --#endif -- XCopyArea(dpy, desktopWin, rcSavedArea, gc, x, y, w, h, 0, 0); -- } else { -- /* Restore screen area. */ -- XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y); -- } -+ if (w > 0 && h > 0) { -+ rcSavedArea = XCreatePixmap(dpy, DefaultRootWindow(dpy), w, h, visdepth); -+ rcSavedArea_w = w; -+ rcSavedArea_h = h; -+ -+ } else if (image_scale != NULL && scale_x > 0) { -+ int w2 = scale_round(rcWidth, scale_factor_x) + 2; -+ int h2 = scale_round(rcHeight, scale_factor_y) + 2; -+ rcSavedArea = XCreatePixmap(dpy, DefaultRootWindow(dpy), w2, h2, visdepth); -+ rcSavedArea_w = w2; -+ rcSavedArea_h = h2; -+ } else { -+ rcSavedArea = XCreatePixmap(dpy, DefaultRootWindow(dpy), rcWidth, rcHeight, visdepth); -+ rcSavedArea_w = rcWidth; -+ rcSavedArea_h = rcHeight; -+ } -+} -+ -+extern int XError_ign; -+ -+static void SoftCursorCopyArea(int oper) { -+ int x, y, w, h; -+ int xs = 0, ys = 0, ws = 0, hs = 0; -+ static int scale_saved = 0, ss_w, ss_h; -+ int db = 0; -+ -+ x = rcCursorX - rcHotX; -+ y = rcCursorY - rcHotY; -+ if (x >= si.framebufferWidth || y >= si.framebufferHeight) { -+ return; -+ } -+ -+ w = rcWidth; -+ h = rcHeight; -+ if (x < 0) { -+ w += x; -+ x = 0; -+ } else if (x + w > si.framebufferWidth) { -+ w = si.framebufferWidth - x; -+ } -+ if (y < 0) { -+ h += y; -+ y = 0; -+ } else if (y + h > si.framebufferHeight) { -+ h = si.framebufferHeight - y; -+ } -+ -+ if (image_scale != NULL && scale_x > 0) { -+ xs = (int) (x * scale_factor_x); -+ ys = (int) (y * scale_factor_y); -+ ws = scale_round(w, scale_factor_x); -+ hs = scale_round(h, scale_factor_y); -+ -+ if (xs > 0) xs -= 1; -+ if (ys > 0) ys -= 1; -+ ws += 2; -+ hs += 2; -+ } -+ -+ XError_ign = 1; -+ -+ if (oper == OPER_SAVE) { -+ /* Save screen area in memory. */ -+ scale_saved = 0; -+ if (appData.useXserverBackingStore) { -+ XSync(dpy, False); -+ XCopyArea(dpy, desktopWin, rcSavedArea, gc, x, y, w, h, 0, 0); -+ } else { -+ if (image_scale != NULL && scale_x > 0) { -+ int Bpp = image_scale->bits_per_pixel / 8; -+ int Bpl = image_scale->bytes_per_line; -+ int i; -+ char *src = image_scale->data + y * Bpl + x * Bpp; -+ char *dst = rcSavedScale; -+ -+ if (ws > rcSavedArea_w || hs > rcSavedArea_h) { -+ new_pixmap(0, 0); -+ } -+ -+if (db) fprintf(stderr, "save: %dx%d+%d+%d\n", ws, hs, xs, ys); -+ -+ XPutImage(dpy, rcSavedArea, gc, image, xs, ys, 0, 0, ws, hs); -+ -+ XPutImage(dpy, rcSavedArea_0, gc, image_scale, x, y, 0, 0, w, h); -+ -+ scale_saved = 1; -+ ss_w = ws; -+ ss_h = hs; -+ -+ for (i=0; i < h; i++) { -+ memcpy(dst, src, Bpp * w); -+ src += Bpl; -+ dst += Bpp * w; -+ } -+ } else { -+if (db) fprintf(stderr, "SAVE: %dx%d+%d+%d\n", w, h, x, y); -+ if (w > rcSavedArea_w || h > rcSavedArea_h) { -+ new_pixmap(0, 0); -+ } -+ -+ XPutImage(dpy, rcSavedArea, gc, image, x, y, 0, 0, w, h); -+ } -+ } -+ } else { -+ -+#define XE(s) if (XError_ign > 1) {fprintf(stderr, "X-%d\n", (s)); db = 1;} -+ -+ /* Restore screen area. */ -+ if (appData.useXserverBackingStore) { -+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y); -+XE(1) -+ XGetSubImage(dpy, rcSavedArea, 0, 0, w, h, AllPlanes, ZPixmap, image, x, y); -+XE(2) -+ -+ } else { -+ if (image_scale != NULL && scale_x > 0) { -+ int Bpp = image_scale->bits_per_pixel / 8; -+ int Bpl = image_scale->bytes_per_line; -+ int i; -+ char *dst = image_scale->data + y * Bpl + x * Bpp; -+ char *src = rcSavedScale; -+ -+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, ws, hs, xs, ys); -+XE(3) -+ XGetSubImage(dpy, rcSavedArea, 0, 0, ws, hs, AllPlanes, ZPixmap, image, xs, ys); -+XE(4) -+if (db) fprintf(stderr, "rstr: %dx%d+%d+%d\n", ws, hs, xs, ys); -+ -+ for (i=0; i < h; i++) { -+ memcpy(dst, src, Bpp * w); -+ src += Bpp * w; -+ dst += Bpl; -+ } -+ } else { -+ -+ if (scale_saved) { -+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, ss_w, ss_h, x, y); -+XE(5) -+ XGetSubImage(dpy, rcSavedArea, 0, 0, ss_w, ss_h, AllPlanes, ZPixmap, image, x, y); -+XE(6) -+ new_pixmap(w, h); -+ } else { -+ XCopyArea(dpy, rcSavedArea, desktopWin, gc, 0, 0, w, h, x, y); -+XE(7) -+ XGetSubImage(dpy, rcSavedArea, 0, 0, w, h, AllPlanes, ZPixmap, image, x, y); -+XE(8) -+ } -+ -+if (db) fprintf(stderr, "RSTR: %dx%d+%d+%d\n", w, h, x, y); -+ -+ } -+ } -+ } -+ -+ if (XError_ign > 1) { -+ fprintf(stderr, "XError_ign: %d, oper: %s\n", XError_ign, oper ? "restore" : "save"); -+ } -+ -+ XError_ign = 0; - } - - static void SoftCursorDraw(void) -@@ -472,43 +650,182 @@ - int offset, bytesPerPixel; - char *pos; - -+#define alphahack -+#ifdef alphahack -+ /* hack to have cursor transparency at 32bpp <runge@karlrunge.com> */ -+ int alphablend = 0; -+ -+ if (!rcSource) { -+ return; -+ } -+ -+ if (appData.useCursorAlpha) { -+ alphablend = 1; -+ } -+ - bytesPerPixel = myFormat.bitsPerPixel / 8; - -- /* FIXME: Speed optimization is possible. */ -- for (y = 0; y < rcHeight; y++) { -- y0 = rcCursorY - rcHotY + y; -- if (y0 >= 0 && y0 < si.framebufferHeight) { -- for (x = 0; x < rcWidth; x++) { -- x0 = rcCursorX - rcHotX + x; -- if (x0 >= 0 && x0 < si.framebufferWidth) { -- offset = y * rcWidth + x; -- if (rcMask[offset]) { -- pos = (char *)&rcSource[offset * bytesPerPixel]; -- CopyDataToScreen(pos, x0, y0, 1, 1); -- } -+ if (alphablend && bytesPerPixel == 4) { -+ unsigned long pixel, put, *upos, *upix; -+ int got_alpha = 0, rsX, rsY, rsW, rsH; -+ static XImage *alpha_image = NULL; -+ static int iwidth = 192; -+ -+ if (! alpha_image) { -+ /* watch out for tiny fb (rare) */ -+ if (iwidth > si.framebufferWidth) { -+ iwidth = si.framebufferWidth; -+ } -+ if (iwidth > si.framebufferHeight) { -+ iwidth = si.framebufferHeight; -+ } -+ -+ /* initialize an XImage with a chunk of desktopWin */ -+ alpha_image = XGetImage(dpy, desktopWin, 0, 0, iwidth, iwidth, -+ AllPlanes, ZPixmap); - } -- } -- } -+ -+ /* first check if there is any non-zero alpha channel data at all: */ -+ for (y = 0; y < rcHeight; y++) { -+ for (x = 0; x < rcWidth; x++) { -+ int alpha; -+ -+ offset = y * rcWidth + x; -+ pos = (char *)&rcSource[offset * bytesPerPixel]; -+ -+ upos = (unsigned long *) pos; -+ alpha = (*upos & 0xff000000) >> 24; -+ if (alpha) { -+ got_alpha = 1; -+ break; -+ } -+ } -+ if (got_alpha) { -+ break; -+ } -+ } -+ -+ if (!got_alpha) { -+ /* no alpha channel data, fallback to the old way */ -+ goto oldway; -+ } -+ -+ /* load the saved fb patch in to alpha_image (faster way?) */ -+ if (image_scale != NULL && scale_x > 0) { -+ XGetSubImage(dpy, rcSavedArea_0, 0, 0, rcWidth, rcHeight, AllPlanes, ZPixmap, alpha_image, 0, 0); -+ } else { -+ XGetSubImage(dpy, rcSavedArea, 0, 0, rcWidth, rcHeight, AllPlanes, ZPixmap, alpha_image, 0, 0); -+ } -+ -+ upix = (unsigned long *)alpha_image->data; -+ -+ /* if the richcursor is clipped, the fb patch will be smaller */ -+ rsW = rcWidth; -+ rsX = 0; /* used to denote a shift from the left side */ -+ x = rcCursorX - rcHotX; -+ if (x < 0) { -+ rsW += x; -+ rsX = -x; -+ } else if (x + rsW > si.framebufferWidth) { -+ rsW = si.framebufferWidth - x; -+ } -+ rsH = rcHeight; -+ rsY = 0; /* used to denote a shift from the top side */ -+ y = rcCursorY - rcHotY; -+ if (y < 0) { -+ rsH += y; -+ rsY = -y; -+ } else if (y + rsH > si.framebufferHeight) { -+ rsH = si.framebufferHeight - y; -+ } -+ -+ /* -+ * now loop over the cursor data, blend in the fb values, -+ * and then overwrite the fb (CopyDataToScreen()) -+ */ -+ for (y = 0; y < rcHeight; y++) { -+ y0 = rcCursorY - rcHotY + y; -+ if (y0 < 0 || y0 >= si.framebufferHeight) { -+ continue; /* clipped */ -+ } -+ for (x = 0; x < rcWidth; x++) { -+ int alpha, color_curs, color_fb, i; -+ -+ x0 = rcCursorX - rcHotX + x; -+ if (x0 < 0 || x0 >= si.framebufferWidth) { -+ continue; /* clipped */ -+ } -+ -+ offset = y * rcWidth + x; -+ pos = (char *)&rcSource[offset * bytesPerPixel]; -+ -+ /* extract secret alpha byte from rich cursor: */ -+ upos = (unsigned long *) pos; -+ alpha = (*upos & 0xff000000) >> 24; /* XXX MSB? */ -+ -+ /* extract the pixel from the fb: */ -+ pixel = *(upix + (y-rsY)*iwidth + (x-rsX)); -+ -+ put = 0; -+ /* for simplicity, blend all 4 bytes */ -+ for (i = 0; i < 4; i++) { -+ int sh = i*8; -+ color_curs = ((0xff << sh) & *upos) >> sh; -+ color_fb = ((0xff << sh) & pixel) >> sh; -+ -+ /* XXX assumes pre-multipled color_curs */ -+ color_fb = color_curs -+ + ((0xff - alpha) * color_fb)/0xff; -+ put |= color_fb << sh; -+ } -+ /* place in the fb: */ -+ CopyDataToScreen((char *)&put, x0, y0, 1, 1); -+ } -+ } -+ return; - } -+oldway: -+#endif -+ -+ bytesPerPixel = myFormat.bitsPerPixel / 8; -+ -+ /* FIXME: Speed optimization is possible. */ -+ for (y = 0; y < rcHeight; y++) { -+ y0 = rcCursorY - rcHotY + y; -+ if (y0 >= 0 && y0 < si.framebufferHeight) { -+ for (x = 0; x < rcWidth; x++) { -+ x0 = rcCursorX - rcHotX + x; -+ if (x0 >= 0 && x0 < si.framebufferWidth) { -+ offset = y * rcWidth + x; -+ if (rcMask[offset]) { -+ pos = (char *)&rcSource[offset * bytesPerPixel]; -+ CopyDataToScreen(pos, x0, y0, 1, 1); -+ } -+ } -+ } -+ } -+ } -+ XSync(dpy, False); - } - --static void FreeSoftCursor(void) -+void FreeSoftCursor(void) - { -- if (prevSoftCursorSet) { -- SoftCursorCopyArea(OPER_RESTORE); -- XFreePixmap(dpy, rcSavedArea); -- free(rcSource); -- free(rcMask); -- prevSoftCursorSet = False; -- } -+ if (prevSoftCursorSet) { -+ SoftCursorCopyArea(OPER_RESTORE); -+ XFreePixmap(dpy, rcSavedArea); -+ XFreePixmap(dpy, rcSavedArea_0); -+ free(rcSource); -+ rcSource = NULL; -+ free(rcMask); -+ prevSoftCursorSet = False; -+ } - } - - --static void FreeX11Cursor() -+void FreeX11Cursor() - { -- if (prevXCursorSet) { -- XFreeCursor(dpy, prevXCursor); -- prevXCursorSet = False; -- } -+ if (prevXCursorSet) { -+ XFreeCursor(dpy, prevXCursor); -+ prevXCursorSet = False; -+ } - } -- -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/desktop.c vnc_unixsrc/vncviewer/desktop.c ---- vnc_unixsrc.orig/vncviewer/desktop.c 2004-05-28 13:29:29.000000000 -0400 -+++ vnc_unixsrc/vncviewer/desktop.c 2010-02-25 22:32:49.000000000 -0500 -@@ -28,28 +28,497 @@ - #include <X11/extensions/XShm.h> - #endif - -+#include <X11/cursorfont.h> -+ - GC gc; - GC srcGC, dstGC; /* used for debugging copyrect */ - Window desktopWin; --Cursor dotCursor; -+Cursor dotCursor3 = None; -+Cursor dotCursor4 = None; -+Cursor bogoCursor = None; -+Cursor waitCursor = None; - Widget form, viewport, desktop; - -+int appshare_0_hint = -10000; -+int appshare_x_hint = -10000; -+int appshare_y_hint = -10000; -+ - static Bool modifierPressed[256]; - --static XImage *image = NULL; -+XImage *image = NULL; -+XImage *image_ycrop = NULL; -+XImage *image_scale = NULL; -+ -+int image_is_shm = 0; - - static Cursor CreateDotCursor(); - static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width,int height); - static void HandleBasicDesktopEvent(Widget w, XtPointer ptr, XEvent *ev, - Boolean *cont); - -+static void CopyBGR565ToScreen(CARD16 *buf, int x, int y, int width,int height); -+ - static XtResource desktopBackingStoreResources[] = { - { -- XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int), 0, -- XtRImmediate, (XtPointer) Always, -+ XtNbackingStore, XtCBackingStore, XtRBackingStore, sizeof(int), 0, -+ XtRImmediate, (XtPointer) Always, - }, - }; - -+double scale_factor_x = 0.0; -+double scale_factor_y = 0.0; -+int scale_x = 0, scale_y = 0; -+int scale_round(int len, double fac); -+ -+double last_rescale = 0.0; -+double last_fullscreen = 0.0; -+double start_time = 0.0; -+ -+int prev_fb_width = -1; -+int prev_fb_height = -1; -+ -+void get_scale_values(double *fx, double *fy) { -+ char *s = appData.scale; -+ double f, frac_x = -1.0, frac_y = -1.0; -+ int n, m; -+ int xmax = si.framebufferWidth; -+ int ymax = si.framebufferHeight; -+ -+ if (appData.yCrop > 0) { -+ ymax = appData.yCrop; -+ } -+ -+ if (sscanf(s, "%d/%d", &n, &m) == 2) { -+ if (m == 0) { -+ frac_x = 1.0; -+ } else { -+ frac_x = ((double) n) / ((double) m); -+ } -+ } -+ if (sscanf(s, "%dx%d", &n, &m) == 2) { -+ frac_x = ((double) n) / ((double) xmax); -+ frac_y = ((double) m) / ((double) ymax); -+ } -+ if (!strcasecmp(s, "fit")) { -+ frac_x = ((double) dpyWidth) / ((double) xmax); -+ frac_y = ((double) dpyHeight) / ((double) ymax); -+ } -+ if (!strcasecmp(s, "auto")) { -+ Dimension w, h; -+ XtVaGetValues(toplevel, XtNheight, &h, XtNwidth, &w, NULL); -+ fprintf(stderr, "auto: %dx%d\n", w, h); -+ if (w > 32 && h > 32) { -+ frac_x = ((double) w) / ((double) xmax); -+ frac_y = ((double) h) / ((double) ymax); -+ } -+ } -+ if (frac_x < 0.0 && sscanf(s, "%lf", &f) == 1) { -+ if (f > 0.0) { -+ frac_x = f; -+ } -+ } -+ -+ if (frac_y < 0.0) { -+ frac_y = frac_x; -+ } -+ -+ if (frac_y > 0.0 && frac_x > 0.0) { -+ if (fx != NULL) { -+ *fx = frac_x; -+ } -+ if (fy != NULL) { -+ *fy = frac_y; -+ } -+ } else { -+ if (appData.scale) { -+ fprintf(stderr, "Invalid scale string: '%s'\n", appData.scale); -+ } else { -+ fprintf(stderr, "Invalid scale string.\n"); -+ } -+ appData.scale = NULL; -+ } -+} -+ -+void try_create_image(void); -+void put_image(int src_x, int src_y, int dst_x, int dst_y, int width, int height, int solid); -+void create_image(); -+ -+/* toplevel -> form -> viewport -> desktop */ -+ -+void adjust_Xt_win(int w, int h) { -+ int x, y, dw, dh, h0 = h; -+ int mw = w, mh = h; -+ int autoscale = 0; -+ -+ if (!appData.fullScreen && appData.scale != NULL && !strcmp(appData.scale, "auto")) { -+ autoscale = 1; -+ mw = dpyWidth; -+ mh = dpyHeight; -+ } -+ -+ if (appData.yCrop > 0) { -+ int ycrop = appData.yCrop; -+ if (image_scale && scale_factor_y > 0.0) { -+ ycrop = scale_round(ycrop, scale_factor_y); -+ if (!autoscale) { -+ mh = ycrop; -+ } -+ } -+ XtVaSetValues(toplevel, XtNmaxWidth, mw, XtNmaxHeight, mh, XtNwidth, w, XtNheight, ycrop, NULL); -+ XtVaSetValues(form, XtNmaxWidth, mw, XtNmaxHeight, mh, XtNwidth, w, XtNheight, ycrop, NULL); -+ h0 = ycrop; -+ } else { -+ XtVaSetValues(toplevel, XtNmaxWidth, mw, XtNmaxHeight, mh, XtNwidth, w, XtNheight, h, NULL); -+ } -+ -+ fprintf(stderr, "adjust_Xt_win: %dx%d & %dx%d\n", w, h, w, h0); -+ -+ XtVaSetValues(desktop, XtNwidth, w, XtNheight, h, NULL); -+ -+ XtResizeWidget(desktop, w, h, 0); -+ -+ if (!autoscale) { -+ dw = appData.wmDecorationWidth; -+ dh = appData.wmDecorationHeight; -+ -+ x = (dpyWidth - w - dw)/2; -+ y = (dpyHeight - h0 - dh)/2; -+ -+ XtConfigureWidget(toplevel, x + dw, y + dh, w, h0, 0); -+ } -+} -+ -+void rescale_image(void) { -+ double frac_x, frac_y; -+ int w, h; -+ -+ if (image == NULL) { -+ create_image(); -+ return; -+ } -+ -+ if (appData.useXserverBackingStore) { -+ create_image(); -+ return; -+ } -+ -+ if (image == NULL && image_scale == NULL) { -+ create_image(); -+ return; -+ } -+ -+ if (appData.scale == NULL) { -+ /* switching to not scaled */ -+ frac_x = frac_y = 1.0; -+ } else { -+ get_scale_values(&frac_x, &frac_y); -+ if (frac_x < 0.0 || frac_y < 0.0) { -+ create_image(); -+ return; -+ } -+ } -+ -+ last_rescale = dnow(); -+ -+ SoftCursorLockArea(0, 0, si.framebufferWidth, si.framebufferHeight); -+ -+ if (image_scale == NULL) { -+ /* switching from not scaled */ -+ int i; -+ int Bpl = image->bytes_per_line; -+ char *dst, *src = image->data; -+ -+ image_scale = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, -+ si.framebufferWidth, si.framebufferHeight, BitmapPad(dpy), 0); -+ -+ image_scale->data = (char *) malloc(image_scale->bytes_per_line * image_scale->height); -+ -+ fprintf(stderr, "rescale_image: switching from not scaled. created image_scale %dx%d\n", image_scale->width, image_scale->height); -+ fprintf(stderr, "rescale_image: copying image -> image_scale %dx%d -> %dx%d\n", image->width, image->height, image_scale->width, image_scale->height); -+ -+ dst = image_scale->data; -+ -+ /* copy from image->data */ -+ for (i=0; i < image->height; i++) { -+ memcpy(dst, src, Bpl); -+ dst += Bpl; -+ src += Bpl; -+ } -+ } -+ -+ /* now destroy image */ -+ if (image && image->data) { -+ if (UsingShm()) { -+ ShmDetach(); -+ } -+ XDestroyImage(image); -+ fprintf(stderr, "rescale_image: destroyed 'image'\n"); -+ if (UsingShm()) { -+ ShmCleanup(); -+ } -+ image = NULL; -+ } -+ if (image_ycrop && image_ycrop->data) { -+ XDestroyImage(image_ycrop); -+ fprintf(stderr, "rescale_image: destroyed 'image_ycrop'\n"); -+ image_ycrop = NULL; -+ } -+ -+ if (frac_x == 1.0 && frac_y == 1.0) { -+ /* switching to not scaled */ -+ fprintf(stderr, "rescale_image: switching to not scaled.\n"); -+ w = si.framebufferWidth; -+ h = si.framebufferHeight; -+ -+ scale_factor_x = 0.0; -+ scale_factor_y = 0.0; -+ scale_x = 0; -+ scale_y = 0; -+ } else { -+ w = scale_round(si.framebufferWidth, frac_x); -+ h = scale_round(si.framebufferHeight, frac_y); -+ -+ scale_factor_x = frac_x; -+ scale_factor_y = frac_y; -+ scale_x = w; -+ scale_y = h; -+ } -+ -+ adjust_Xt_win(w, h); -+ -+ fprintf(stderr, "rescale: %dx%d %.4f %.4f\n", w, h, scale_factor_x, scale_factor_y); -+ -+ try_create_image(); -+ -+ if (image && image->data && image_scale && frac_x == 1.0 && frac_y == 1.0) { -+ /* switched to not scaled */ -+ int i; -+ int Bpl = image->bytes_per_line; -+ char *dst = image->data; -+ char *src = image_scale->data; -+ -+ fprintf(stderr, "rescale_image: switching to not scaled.\n"); -+ -+ for (i=0; i < image->height; i++) { -+ memcpy(dst, src, Bpl); -+ dst += Bpl; -+ src += Bpl; -+ } -+ XDestroyImage(image_scale); -+ fprintf(stderr, "rescale_image: destroyed 'image_scale'\n"); -+ image_scale = NULL; -+ } -+ -+ if (appData.yCrop > 0) { -+ int ycrop = appData.yCrop; -+ /* do the top part first so they can see it earlier */ -+ put_image(0, 0, 0, 0, si.framebufferWidth, ycrop, 0); -+ if (si.framebufferHeight > ycrop) { -+ /* this is a big fb and so will take a long time */ -+ if (waitCursor != None) { -+ XDefineCursor(dpy, desktopWin, waitCursor); -+ XSync(dpy, False); -+ } -+ put_image(0, 0, 0, 0, si.framebufferWidth, si.framebufferHeight - ycrop, 0); -+ if (waitCursor != None) { -+ Xcursors(1); -+ if (appData.useX11Cursor) { -+ XSetWindowAttributes attr; -+ unsigned long valuemask = 0; -+ if (appData.viewOnly) { -+ attr.cursor = dotCursor4; -+ } else { -+ attr.cursor = dotCursor3; -+ } -+ valuemask |= CWCursor; -+ XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr); -+ } -+ } -+ } -+ } else { -+ put_image(0, 0, 0, 0, si.framebufferWidth, si.framebufferHeight, 0); -+ } -+ -+ SoftCursorUnlockScreen(); -+ -+ fprintf(stderr, "rescale: image_scale=%p image=%p image_ycrop=%p\n", (void *) image_scale, (void *) image, (void *) image_ycrop); -+ last_rescale = dnow(); -+ -+} -+ -+void try_create_image(void) { -+ -+ image_is_shm = 0; -+ if (appData.useShm) { -+#ifdef MITSHM -+ image = CreateShmImage(0); -+ if (!image) { -+ if (appData.yCrop > 0) { -+ if (appData.scale != NULL && scale_x > 0) { -+ ; -+ } else { -+ image_ycrop = CreateShmImage(1); -+ if (!image_ycrop) { -+ appData.useShm = False; -+ } else { -+ fprintf(stderr, "created smaller image_ycrop shm image: %dx%d\n", -+ image_ycrop->width, image_ycrop->height); -+ } -+ } -+ } else { -+ appData.useShm = False; -+ } -+ } else { -+ image_is_shm = 1; -+ fprintf(stderr, "created shm image: %dx%d\n", image->width, image->height); -+ } -+#endif -+ } -+ -+ if (!image) { -+ fprintf(stderr, "try_create_image: shm image create fail: image == NULL\n"); -+ if (scale_x > 0) { -+ image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, -+ scale_x, scale_y, BitmapPad(dpy), 0); -+ } else { -+ image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, -+ si.framebufferWidth, si.framebufferHeight, BitmapPad(dpy), 0); -+ } -+ -+ image->data = malloc(image->bytes_per_line * image->height); -+ -+ if (!image->data) { -+ fprintf(stderr, "try_create_image: malloc failed\n"); -+ exit(1); -+ } else { -+ fprintf(stderr, "try_create_image: created *non-shm* image: %dx%d\n", image->width, image->height); -+ } -+ } -+ fprintf(stderr, "try_create_image: image->bytes_per_line: %d\n", image->bytes_per_line); -+} -+ -+void create_image() { -+ image = NULL; -+ image_ycrop = NULL; -+ image_scale = NULL; -+ -+ fprintf(stderr, "create_image()\n"); -+ -+ if (CreateShmImage(-1) == NULL) { -+ appData.useShm = False; -+ } -+ if (appData.scale != NULL) { -+ if (appData.useXserverBackingStore) { -+ fprintf(stderr, "Cannot scale when using X11 backingstore.\n"); -+ } else { -+ double frac_x = -1.0, frac_y = -1.0; -+ -+ get_scale_values(&frac_x, &frac_y); -+ -+ if (frac_x < 0.0 || frac_y < 0.0) { -+ fprintf(stderr, "Cannot figure out scale factor!\n"); -+ goto bork; -+ } -+ -+ scale_factor_x = 0.0; -+ scale_factor_y = 0.0; -+ scale_x = 0; -+ scale_y = 0; -+ -+ -+ if (1) { -+ int w, h, hyc; -+ -+ w = scale_round(si.framebufferWidth, frac_x); -+ h = scale_round(si.framebufferHeight, frac_y); -+ hyc = h; -+ if (appData.yCrop > 0) { -+ hyc = scale_round(appData.yCrop, frac_y); -+ } -+ -+ /* image scale is full framebuffer */ -+ image_scale = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, -+ si.framebufferWidth, si.framebufferHeight, BitmapPad(dpy), 0); -+ -+ image_scale->data = (char *) malloc(image_scale->bytes_per_line * image_scale->height); -+ -+ fprintf(stderr, "create_image: created image_scale %dx%d\n", image_scale->width, image_scale->height); -+ -+ if (!image_scale->data) { -+ fprintf(stderr, "create_image: malloc failed\n"); -+ XDestroyImage(image_scale); -+ fprintf(stderr, "create_image: destroyed 'image_scale'\n"); -+ image_scale = NULL; -+ } else { -+ int h2; -+ scale_factor_x = frac_x; -+ scale_factor_y = frac_y; -+ scale_x = w; -+ scale_y = h; -+ -+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, hyc, NULL); -+ -+ h2 = scale_round(si.framebufferHeight, frac_y); -+ XtVaSetValues(desktop, XtNwidth, w, XtNheight, h2, NULL); -+ -+ } -+ fprintf(stderr, "create_image: scale: %dx%d %.4f %.4f\n", w, h, -+ scale_factor_x, scale_factor_y); -+ } -+ } -+ } -+ bork: -+ try_create_image(); -+} -+ -+int old_width = 0; -+int old_height = 0; -+ -+int guessCrop(void) { -+ int w = si.framebufferWidth; -+ -+ if (w == 320) { -+ return 240; -+ } else if (w == 400) { -+ return 300; -+ } else if (w == 640) { -+ return 480; -+ } else if (w == 800) { -+ return 600; -+ } else if (w == 1024) { -+ return 768; -+ } else if (w == 1152) { -+ return 864; -+ } else if (w == 1280) { -+ return 1024; -+ } else if (w == 1440) { -+ return 900; -+ } else if (w == 1600) { -+ return 1200; -+ } else if (w == 1680) { -+ return 1050; -+ } else if (w == 1920) { -+ return 1200; -+ } else { -+ int h = (3 * w) / 4; -+ return h; -+ } -+} -+ -+void check_tall(void) { -+ if (appData.appShare) { -+ return; -+ } -+ if (! appData.yCrop) { -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+ if (h > 2 * w) { -+ fprintf(stderr, "Tall display (%dx%d) suspect 'x11vnc -ncache' mode,\n", w, h); -+ fprintf(stderr, " setting auto -ycrop detection.\n"); -+ appData.yCrop = -1; -+ } -+ } -+} - - /* - * DesktopInitBeforeRealization creates the "desktop" widget and the viewport -@@ -59,91 +528,1023 @@ - void - DesktopInitBeforeRealization() - { -- int i; -+ int i; -+ int h = si.framebufferHeight; -+ int w = si.framebufferWidth; -+ double frac_x = 1.0, frac_y = 1.0; -+ -+ start_time = dnow(); -+ -+ prev_fb_width = si.framebufferWidth; -+ prev_fb_height = si.framebufferHeight; -+ -+ if (appData.scale != NULL) { -+ get_scale_values(&frac_x, &frac_y); -+ if (frac_x > 0.0 && frac_y > 0.0) { -+ w = scale_round(w, frac_x); -+ h = scale_round(h, frac_y); -+ } else { -+ appData.scale = NULL; -+ } -+ } - -- form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, -- XtNborderWidth, 0, -- XtNdefaultDistance, 0, NULL); -+ form = XtVaCreateManagedWidget("form", formWidgetClass, toplevel, -+ XtNborderWidth, 0, XtNdefaultDistance, 0, NULL); - -- viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form, -- XtNborderWidth, 0, -- NULL); -+ viewport = XtVaCreateManagedWidget("viewport", viewportWidgetClass, form, -+ XtNborderWidth, 0, NULL); - -- desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport, -- XtNborderWidth, 0, -- NULL); -+ desktop = XtVaCreateManagedWidget("desktop", coreWidgetClass, viewport, -+ XtNborderWidth, 0, NULL); - -- XtVaSetValues(desktop, XtNwidth, si.framebufferWidth, -- XtNheight, si.framebufferHeight, NULL); -+ XtVaSetValues(desktop, XtNwidth, w, XtNheight, h, NULL); - -- XtAddEventHandler(desktop, LeaveWindowMask|ExposureMask, -- True, HandleBasicDesktopEvent, NULL); -+ XtAddEventHandler(desktop, LeaveWindowMask|EnterWindowMask|ExposureMask, -+ True, HandleBasicDesktopEvent, NULL); - -- for (i = 0; i < 256; i++) -- modifierPressed[i] = False; -+ if (appData.yCrop) { -+ int hm; -+ if (appData.yCrop < 0) { -+ appData.yCrop = guessCrop(); -+ fprintf(stderr, "Set -ycrop to: %d\n", appData.yCrop); -+ } -+ hm = appData.yCrop; - -- image = NULL; -+ fprintf(stderr, "ycrop h: %d -> %d\n", hm, (int) (hm*frac_y)); - --#ifdef MITSHM -- if (appData.useShm) { -- image = CreateShmImage(); -- if (!image) -- appData.useShm = False; -- } -+ hm *= frac_y; -+ -+ XtVaSetValues(toplevel, XtNmaxHeight, hm, XtNheight, hm, NULL); -+ XtVaSetValues(form, XtNmaxHeight, hm, XtNheight, hm, NULL); -+ XtVaSetValues(viewport, XtNforceBars, False, NULL); -+ XSync(dpy, False); -+ } -+ -+ old_width = si.framebufferWidth; -+ old_height = si.framebufferHeight; -+ -+ for (i = 0; i < 256; i++) { -+ modifierPressed[i] = False; -+ } -+ -+ create_image(); -+} -+ -+#if 0 -+static Widget scrollbar_y = NULL; -+static int xsst = 2; - #endif - -- if (!image) { -- image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, -- si.framebufferWidth, si.framebufferHeight, -- BitmapPad(dpy), 0); -- -- image->data = malloc(image->bytes_per_line * image->height); -- if (!image->data) { -- fprintf(stderr,"malloc failed\n"); -- exit(1); -- } -- } -+#include <X11/Xaw/Scrollbar.h> -+ -+#if 0 -+static XtCallbackProc Scrolled(Widget w, XtPointer closure, XtPointer call_data) { -+ Position x, y; -+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL); -+ if (0) fprintf(stderr, "scrolled by %d pixels x=%d y=%d\n", (int) call_data, x, y); -+ if (xsst == 2) { -+ x = 0; -+ y = 0; -+ XtVaSetValues(desktop, XtNx, x, XtNy, y, NULL); -+ } else if (xsst) { -+ XawScrollbarSetThumb(w, 0.0, 0.0); -+ } else { -+ float t = 0.0; -+ XtVaSetValues(w, XtNtopOfThumb, &t, NULL); -+ } -+ if (closure) {} - } - -+static XtCallbackProc Jumped(Widget w, XtPointer closure, XtPointer call_data) { -+ float top = *((float *) call_data); -+ Position x, y; -+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL); -+ if (0) fprintf(stderr, "thumb value: %.4f x=%d y=%d\n", top, x, y); -+ if (top > 0.01) { -+ if (xsst == 2) { -+ x = 0; -+ y = 0; -+ XtVaSetValues(desktop, XtNx, x, XtNy, y, NULL); -+ } else if (xsst) { -+ XawScrollbarSetThumb(w, 0.0, 0.0); -+ } else { -+ float t = 0.0, s = 1.0; -+ XtVaSetValues(w, XtNtopOfThumb, *(XtArgVal*)&t, XtNshown, *(XtArgVal*)&s, NULL); -+ } -+ } -+ if (closure) {} -+} -+#endif -+ -+extern double dnow(void); -+ -+void check_things() { -+ static int first = 1; -+ static double last_scrollbar = 0.0; -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+ double now = dnow(); -+ static double last = 0; -+ double fac = image_scale ? scale_factor_y : 1.0; -+ -+ if (first) { -+ first = 0; -+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False); -+ } -+ if (appData.yCrop > 0 && appData.yCrop * fac < dpyHeight && h > 2*w && now > last_scrollbar + 0.25) { -+ Widget wv, wh, wc; -+ Position x0, y0; -+ Position x1, y1; -+ Dimension w0, h0, b0; -+ Dimension w1, h1, b1; -+ Dimension w2, h2, b2; -+ -+ wc = XtNameToWidget(viewport, "clip"); -+ wv = XtNameToWidget(viewport, "vertical"); -+ wh = XtNameToWidget(viewport, "horizontal"); -+ if (wc && wv && wh) { -+ int sb = appData.sbWidth; -+ XtVaGetValues(wv, XtNwidth, &w0, XtNheight, &h0, XtNborderWidth, &b0, XtNx, &x0, XtNy, &y0, NULL); -+ XtVaGetValues(wh, XtNwidth, &w1, XtNheight, &h1, XtNborderWidth, &b1, XtNx, &x1, XtNy, &y1, NULL); -+ XtVaGetValues(wc, XtNwidth, &w2, XtNheight, &h2, XtNborderWidth, &b2, NULL); -+ if (!sb) { -+ sb = 2; -+ } -+ if (w0 != sb || h1 != sb) { -+ fprintf(stderr, "Very tall (-ncache) fb, setting scrollbar thickness to: %d pixels (%d/%d)\n\n", sb, w0, h1); -+ -+ XtUnmanageChild(wv); -+ XtUnmanageChild(wh); -+ XtUnmanageChild(wc); -+ -+ XtVaSetValues(wv, XtNwidth, sb, XtNx, x0 + (w0 - sb), NULL); -+ XtVaSetValues(wh, XtNheight, sb, XtNy, y1 + (h1 - sb), NULL); -+ w2 = w2 + (w0 - sb); -+ h2 = h2 + (h1 - sb); -+ if (w2 > 10 && h2 > 10) { -+ XtVaSetValues(wc, XtNwidth, w2, XtNheight, h2, NULL); -+ } -+ -+ XtManageChild(wv); -+ XtManageChild(wh); -+ XtManageChild(wc); -+ -+ appData.sbWidth = sb; -+ } -+ } -+ last_scrollbar = dnow(); -+ } -+ -+ if (now <= last + 0.25) { -+ return; -+ } -+ -+ if (image_scale) { -+ scale_check_zrle(); -+ } -+ -+ /* e.g. xrandr resize */ -+ dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy)); -+ dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy)); -+ -+ if (appData.scale != NULL) { -+ static Dimension last_w = 0, last_h = 0; -+ static double last_resize = 0.0; -+ Dimension w, h; -+ if (last_w == 0) { -+ XtVaGetValues(toplevel, XtNwidth, &last_w, XtNheight, &last_h, NULL); -+ last_resize = now; -+ } -+ if (now < last_resize + 0.5) { -+ ; -+ } else if (appData.fullScreen) { -+ ; -+ } else if (!strcmp(appData.scale, "auto")) { -+ XtVaGetValues(toplevel, XtNwidth, &w, XtNheight, &h, NULL); -+ if (w < 32 || h < 32) { -+ ; -+ } else if (last_w != w || last_h != h) { -+ Window rr, cr, r = DefaultRootWindow(dpy); -+ int rx, ry, wx, wy; -+ unsigned int mask; -+ /* make sure mouse buttons not pressed */ -+ if (XQueryPointer(dpy, r, &rr, &cr, &rx, &ry, &wx, &wy, &mask)) { -+ if (mask == 0) { -+ rescale_image(); -+ last_w = w; -+ last_h = h; -+ last_resize = dnow(); -+ } -+ } -+ } -+ } -+ } -+ -+ last = dnow(); -+} - - /* - * DesktopInitAfterRealization does things which require the X windows to - * exist. It creates some GCs and sets the dot cursor. - */ - -+void Xcursors(int set) { -+ if (dotCursor3 == None) { -+ dotCursor3 = CreateDotCursor(3); -+ } -+ if (dotCursor4 == None) { -+ dotCursor4 = CreateDotCursor(4); -+ } -+ if (set) { -+ XSetWindowAttributes attr; -+ unsigned long valuemask = 0; -+ -+ if (!appData.useX11Cursor) { -+ if (appData.viewOnly) { -+ attr.cursor = dotCursor4; -+ } else { -+ attr.cursor = dotCursor3; -+ } -+ valuemask |= CWCursor; -+ XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr); -+ } -+ } -+} -+ - void - DesktopInitAfterRealization() - { -- XGCValues gcv; -- XSetWindowAttributes attr; -- unsigned long valuemask; -- -- desktopWin = XtWindow(desktop); -- -- gc = XCreateGC(dpy,desktopWin,0,NULL); -- -- gcv.function = GXxor; -- gcv.foreground = 0x0f0f0f0f; -- srcGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv); -- gcv.foreground = 0xf0f0f0f0; -- dstGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv); -- -- XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore, -- NULL, 0); -- -- XtVaGetApplicationResources(desktop, (XtPointer)&attr.backing_store, -- desktopBackingStoreResources, 1, NULL); -- valuemask = CWBackingStore; -- -- if (!appData.useX11Cursor) { -- dotCursor = CreateDotCursor(); -- attr.cursor = dotCursor; -- valuemask |= CWCursor; -- } -+ XGCValues gcv; -+ XSetWindowAttributes attr; -+ XWindowAttributes gattr; -+ unsigned long valuemask = 0; -+ -+ desktopWin = XtWindow(desktop); -+ -+ gc = XCreateGC(dpy,desktopWin,0,NULL); -+ -+ gcv.function = GXxor; -+ gcv.foreground = 0x0f0f0f0f; -+ srcGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv); -+ gcv.foreground = 0xf0f0f0f0; -+ dstGC = XCreateGC(dpy,desktopWin,GCFunction|GCForeground,&gcv); -+ -+ XtAddConverter(XtRString, XtRBackingStore, XmuCvtStringToBackingStore, -+ NULL, 0); -+ -+ if (appData.useXserverBackingStore) { -+ Screen *s = DefaultScreenOfDisplay(dpy); -+ if (DoesBackingStore(s) != Always) { -+ fprintf(stderr, "X server does not do backingstore, disabling it.\n"); -+ appData.useXserverBackingStore = False; -+ } -+ } -+ -+ if (appData.useXserverBackingStore) { -+ XtVaGetApplicationResources(desktop, (XtPointer)&attr.backing_store, -+ desktopBackingStoreResources, 1, NULL); -+ valuemask |= CWBackingStore; -+ } else { -+ attr.background_pixel = BlackPixel(dpy, DefaultScreen(dpy)); -+ valuemask |= CWBackPixel; -+ } -+ -+ Xcursors(0); -+ if (!appData.useX11Cursor) { -+ if (appData.viewOnly) { -+ attr.cursor = dotCursor4; -+ } else { -+ attr.cursor = dotCursor3; -+ } -+ valuemask |= CWCursor; -+ } -+ bogoCursor = XCreateFontCursor(dpy, XC_bogosity); -+ waitCursor = XCreateFontCursor(dpy, XC_watch); -+ -+ XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr); -+ -+ if (XGetWindowAttributes(dpy, desktopWin, &gattr)) { -+#if 0 -+ fprintf(stderr, "desktopWin backingstore: %d save_under: %d\n", gattr.backing_store, gattr.save_under); -+#endif -+ } -+ fprintf(stderr, "\n"); -+} -+ -+extern void FreeX11Cursor(void); -+extern void FreeSoftCursor(void); - -- XChangeWindowAttributes(dpy, desktopWin, valuemask, &attr); -+void -+DesktopCursorOff() -+{ -+ if (dotCursor3 == None) { -+ dotCursor3 = CreateDotCursor(3); -+ dotCursor4 = CreateDotCursor(4); -+ } -+ if (appData.viewOnly) { -+ XDefineCursor(dpy, desktopWin, dotCursor4); -+ } else { -+ XDefineCursor(dpy, desktopWin, dotCursor3); -+ } -+ FreeX11Cursor(); -+ FreeSoftCursor(); -+} -+ -+ -+#define CEIL(x) ( (double) ((int) (x)) == (x) ? \ -+ (double) ((int) (x)) : (double) ((int) (x) + 1) ) -+#define FLOOR(x) ( (double) ((int) (x)) ) -+ -+#if 0 -+static int nfix(int i, int n) { -+ if (i < 0) { -+ i = 0; -+ } else if (i >= n) { -+ i = n - 1; -+ } -+ return i; - } -+#else -+#define nfix(i, n) ( i < 0 ? 0 : ( (i >= n) ? (n - 1) : i ) ) -+#endif -+ -+int scale_round(int len, double fac) { -+ double eps = 0.000001; -+ -+ len = (int) (len * fac + eps); -+ if (len < 1) { -+ len = 1; -+ } -+ return len; -+} -+ -+static void scale_rect(double factor_x, double factor_y, int blend, int interpolate, -+ int *px, int *py, int *pw, int *ph, int solid) { -+ -+ int i, j, i1, i2, j1, j2; /* indices for scaled fb (dest) */ -+ int I, J, I1, I2, J1, J2; /* indices for main fb (source) */ -+ -+ double w, wx, wy, wtot; /* pixel weights */ -+ -+ double x1 = 0, y1, x2 = 0, y2; /* x-y coords for destination pixels edges */ -+ double dx, dy; /* size of destination pixel */ -+ double ddx=0, ddy=0; /* for interpolation expansion */ -+ -+ char *src, *dest; /* pointers to the two framebuffers */ -+ -+ unsigned short us = 0; -+ unsigned char uc = 0; -+ unsigned int ui = 0; -+ -+ int use_noblend_shortcut = 1; -+ int shrink; /* whether shrinking or expanding */ -+ static int constant_weights = -1, mag_int = -1; -+ static int last_Nx = -1, last_Ny = -1, cnt = 0; -+ static double last_factor = -1.0; -+ int b, k; -+ double pixave[4]; /* for averaging pixel values */ -+ -+ /* internal */ -+ -+ int X1, X2, Y1, Y2; - -+ int Nx = si.framebufferWidth; -+ int Ny = si.framebufferHeight; -+ -+ int nx = scale_round(Nx, factor_x); -+ int ny = scale_round(Ny, factor_y); -+ -+ int Bpp = image->bits_per_pixel / 8; -+ int dst_bytes_per_line = image->bytes_per_line; -+ int src_bytes_per_line = image_scale->bytes_per_line; -+ -+ unsigned long main_red_mask = image->red_mask; -+ unsigned long main_green_mask = image->green_mask; -+ unsigned long main_blue_mask = image->blue_mask; -+ int mark = 1; -+ -+ char *src_fb = image_scale->data; -+ char *dst_fb = image->data; -+ -+ static int nosolid = -1; -+ int sbdy = 3; -+ double fmax = factor_x > factor_y ? factor_x : factor_y; -+#if 0 -+ double fmin = factor_x < factor_y ? factor_x : factor_y; -+#endif -+ -+ X1 = *px; -+ X2 = *px + *pw; -+ Y1 = *py; -+ Y2 = *py + *ph; -+ -+ if (fmax > 1.0) { -+ /* try to avoid problems with bleeding... */ -+ sbdy = (int) (2.0 * fmax * sbdy); -+ } -+ -+ /* fprintf(stderr, "scale_rect: %dx%d+%d+%d\n", *pw, *ph, *px, *py); */ -+ -+ *px = (int) (*px * factor_x); -+ *py = (int) (*py * factor_y); -+ *pw = scale_round(*pw, factor_x); -+ *ph = scale_round(*ph, factor_y); -+ -+ if (nosolid < 0) { -+ if (getenv("SSVNC_NOSOLID")) { -+ nosolid = 1; -+ } else { -+ nosolid = 0; -+ } -+ } -+ if (nosolid) solid = 0; -+ -+#define rfbLog printf -+/* Begin taken from x11vnc scale: */ -+ -+ if (factor_x <= 1.0 || factor_y <= 1.0) { -+ shrink = 1; -+ } else { -+ shrink = 0; -+ interpolate = 1; -+ } -+ -+ /* -+ * N.B. width and height (real numbers) of a scaled pixel. -+ * both are > 1 (e.g. 1.333 for -scale 3/4) -+ * they should also be equal but we don't assume it. -+ * -+ * This new way is probably the best we can do, take the inverse -+ * of the scaling factor to double precision. -+ */ -+ dx = 1.0/factor_x; -+ dy = 1.0/factor_y; -+ -+ /* -+ * There is some speedup if the pixel weights are constant, so -+ * let's special case these. -+ * -+ * If scale = 1/n and n divides Nx and Ny, the pixel weights -+ * are constant (e.g. 1/2 => equal on 2x2 square). -+ */ -+ if (factor_x != last_factor || Nx != last_Nx || Ny != last_Ny) { -+ constant_weights = -1; -+ mag_int = -1; -+ last_Nx = Nx; -+ last_Ny = Ny; -+ last_factor = factor_x; -+ } -+ -+ if (constant_weights < 0 && factor_x != factor_y) { -+ constant_weights = 0; -+ mag_int = 0; -+ } else if (constant_weights < 0) { -+ int n = 0; -+ double factor = factor_x; -+ -+ constant_weights = 0; -+ mag_int = 0; -+ -+ for (i = 2; i<=128; i++) { -+ double test = ((double) 1)/ i; -+ double diff, eps = 1.0e-7; -+ diff = factor - test; -+ if (-eps < diff && diff < eps) { -+ n = i; -+ break; -+ } -+ } -+ if (! blend || ! shrink || interpolate) { -+ ; -+ } else if (n != 0) { -+ if (Nx % n == 0 && Ny % n == 0) { -+ static int didmsg = 0; -+ if (mark && ! didmsg) { -+ didmsg = 1; -+ rfbLog("scale_and_mark_rect: using " -+ "constant pixel weight speedup " -+ "for 1/%d\n", n); -+ } -+ constant_weights = 1; -+ } -+ } -+ -+ n = 0; -+ for (i = 2; i<=32; i++) { -+ double test = (double) i; -+ double diff, eps = 1.0e-7; -+ diff = factor - test; -+ if (-eps < diff && diff < eps) { -+ n = i; -+ break; -+ } -+ } -+ if (! blend && factor > 1.0 && n) { -+ mag_int = n; -+ } -+ } -+if (0) fprintf(stderr, "X1: %d Y1: %d X2: %d Y2: %d\n", X1, Y1, X2, Y2); -+ -+ if (mark && !shrink && blend) { -+ /* -+ * kludge: correct for interpolating blurring leaking -+ * up or left 1 destination pixel. -+ */ -+ if (X1 > 0) X1--; -+ if (Y1 > 0) Y1--; -+ } -+ -+ /* -+ * find the extent of the change the input rectangle induces in -+ * the scaled framebuffer. -+ */ -+ -+ /* Left edges: find largest i such that i * dx <= X1 */ -+ i1 = FLOOR(X1/dx); -+ -+ /* Right edges: find smallest i such that (i+1) * dx >= X2+1 */ -+ i2 = CEIL( (X2+1)/dx ) - 1; -+ -+ /* To be safe, correct any overflows: */ -+ i1 = nfix(i1, nx); -+ i2 = nfix(i2, nx) + 1; /* add 1 to make a rectangle upper boundary */ -+ -+ /* Repeat above for y direction: */ -+ j1 = FLOOR(Y1/dy); -+ j2 = CEIL( (Y2+1)/dy ) - 1; -+ -+ j1 = nfix(j1, ny); -+ j2 = nfix(j2, ny) + 1; -+ -+ /* -+ * special case integer magnification with no blending. -+ * vision impaired magnification usage is interested in this case. -+ */ -+ if (mark && ! blend && mag_int && Bpp != 3) { -+ int jmin, jmax, imin, imax; -+ -+ /* outer loop over *source* pixels */ -+ for (J=Y1; J < Y2; J++) { -+ jmin = J * mag_int; -+ jmax = jmin + mag_int; -+ for (I=X1; I < X2; I++) { -+ /* extract value */ -+ src = src_fb + J*src_bytes_per_line + I*Bpp; -+ if (Bpp == 4) { -+ ui = *((unsigned int *)src); -+ } else if (Bpp == 2) { -+ us = *((unsigned short *)src); -+ } else if (Bpp == 1) { -+ uc = *((unsigned char *)src); -+ } -+ imin = I * mag_int; -+ imax = imin + mag_int; -+ /* inner loop over *dest* pixels */ -+ for (j=jmin; j<jmax; j++) { -+ dest = dst_fb + j*dst_bytes_per_line + imin*Bpp; -+ for (i=imin; i<imax; i++) { -+ if (Bpp == 4) { -+ *((unsigned int *)dest) = ui; -+ } else if (Bpp == 2) { -+ *((unsigned short *)dest) = us; -+ } else if (Bpp == 1) { -+ *((unsigned char *)dest) = uc; -+ } -+ dest += Bpp; -+ } -+ } -+ } -+ } -+ goto markit; -+ } -+ -+ /* set these all to 1.0 to begin with */ -+ wx = 1.0; -+ wy = 1.0; -+ w = 1.0; -+ -+ /* -+ * Loop over destination pixels in scaled fb: -+ */ -+ for (j=j1; j<j2; j++) { -+ int jbdy = 1, I1_solid = 0; -+ -+ y1 = j * dy; /* top edge */ -+ if (y1 > Ny - 1) { -+ /* can go over with dy = 1/scale_fac */ -+ y1 = Ny - 1; -+ } -+ y2 = y1 + dy; /* bottom edge */ -+ -+ /* Find main fb indices covered by this dest pixel: */ -+ J1 = (int) FLOOR(y1); -+ J1 = nfix(J1, Ny); -+ -+ if (shrink && ! interpolate) { -+ J2 = (int) CEIL(y2) - 1; -+ J2 = nfix(J2, Ny); -+ } else { -+ J2 = J1 + 1; /* simple interpolation */ -+ ddy = y1 - J1; -+ } -+ -+ /* destination char* pointer: */ -+ dest = dst_fb + j*dst_bytes_per_line + i1*Bpp; -+ -+ if (solid) { -+ if (j1+sbdy <= j && j < j2-sbdy) { -+ jbdy = 0; -+ x1 = (i1+sbdy) * dx; -+ if (x1 > Nx - 1) { -+ x1 = Nx - 1; -+ } -+ I1_solid = (int) FLOOR(x1); -+ if (I1_solid >= Nx) I1_solid = Nx - 1; -+ } -+ } -+ -+ for (i=i1; i<i2; i++) { -+ int solid_skip = 0; -+ -+ if (solid) { -+ /* if the region is solid, we can use the noblend speedup */ -+ if (!jbdy && i1+sbdy <= i && i < i2-sbdy) { -+ solid_skip = 1; -+ /* pixels all the same so use X1: */ -+ I1 = I1_solid; -+ goto jsolid; -+ } -+ } -+ -+ x1 = i * dx; /* left edge */ -+ if (x1 > Nx - 1) { -+ /* can go over with dx = 1/scale_fac */ -+ x1 = Nx - 1; -+ } -+ x2 = x1 + dx; /* right edge */ -+ -+ /* Find main fb indices covered by this dest pixel: */ -+ I1 = (int) FLOOR(x1); -+ if (I1 >= Nx) I1 = Nx - 1; -+ -+ jsolid: -+ cnt++; -+ -+ if ((!blend && use_noblend_shortcut) || solid_skip) { -+ /* -+ * The noblend case involves no weights, -+ * and 1 pixel, so just copy the value -+ * directly. -+ */ -+ src = src_fb + J1*src_bytes_per_line + I1*Bpp; -+ if (Bpp == 4) { -+ *((unsigned int *)dest) -+ = *((unsigned int *)src); -+ } else if (Bpp == 2) { -+ *((unsigned short *)dest) -+ = *((unsigned short *)src); -+ } else if (Bpp == 1) { -+ *(dest) = *(src); -+ } else if (Bpp == 3) { -+ /* rare case */ -+ for (k=0; k<=2; k++) { -+ *(dest+k) = *(src+k); -+ } -+ } -+ dest += Bpp; -+ continue; -+ } -+ -+ if (shrink && ! interpolate) { -+ I2 = (int) CEIL(x2) - 1; -+ if (I2 >= Nx) I2 = Nx - 1; -+ } else { -+ I2 = I1 + 1; /* simple interpolation */ -+ ddx = x1 - I1; -+ } -+#if 0 -+if (first) fprintf(stderr, " I1=%d I2=%d J1=%d J2=%d\n", I1, I2, J1, J2); -+#endif -+ -+ /* Zero out accumulators for next pixel average: */ -+ for (b=0; b<4; b++) { -+ pixave[b] = 0.0; /* for RGB weighted sums */ -+ } -+ -+ /* -+ * wtot is for accumulating the total weight. -+ * It should always sum to 1/(scale_fac * scale_fac). -+ */ -+ wtot = 0.0; -+ -+ /* -+ * Loop over source pixels covered by this dest pixel. -+ * -+ * These "extra" loops over "J" and "I" make -+ * the cache/cacheline performance unclear. -+ * For example, will the data brought in from -+ * src for j, i, and J=0 still be in the cache -+ * after the J > 0 data have been accessed and -+ * we are at j, i+1, J=0? The stride in J is -+ * main_bytes_per_line, and so ~4 KB. -+ * -+ * Typical case when shrinking are 2x2 loop, so -+ * just two lines to worry about. -+ */ -+ for (J=J1; J<=J2; J++) { -+ /* see comments for I, x1, x2, etc. below */ -+ if (constant_weights) { -+ ; -+ } else if (! blend) { -+ if (J != J1) { -+ continue; -+ } -+ wy = 1.0; -+ -+ /* interpolation scheme: */ -+ } else if (! shrink || interpolate) { -+ if (J >= Ny) { -+ continue; -+ } else if (J == J1) { -+ wy = 1.0 - ddy; -+ } else if (J != J1) { -+ wy = ddy; -+ } -+ -+ /* integration scheme: */ -+ } else if (J < y1) { -+ wy = J+1 - y1; -+ } else if (J+1 > y2) { -+ wy = y2 - J; -+ } else { -+ wy = 1.0; -+ } -+ -+ src = src_fb + J*src_bytes_per_line + I1*Bpp; -+ -+ for (I=I1; I<=I2; I++) { -+ -+ /* Work out the weight: */ -+ -+ if (constant_weights) { -+ ; -+ } else if (! blend) { -+ /* -+ * Ugh, PseudoColor colormap is -+ * bad news, to avoid random -+ * colors just take the first -+ * pixel. Or user may have -+ * specified :nb to fraction. -+ * The :fb will force blending -+ * for this case. -+ */ -+ if (I != I1) { -+ continue; -+ } -+ wx = 1.0; -+ -+ /* interpolation scheme: */ -+ } else if (! shrink || interpolate) { -+ if (I >= Nx) { -+ continue; /* off edge */ -+ } else if (I == I1) { -+ wx = 1.0 - ddx; -+ } else if (I != I1) { -+ wx = ddx; -+ } -+ -+ /* integration scheme: */ -+ } else if (I < x1) { -+ /* -+ * source left edge (I) to the -+ * left of dest left edge (x1): -+ * fractional weight -+ */ -+ wx = I+1 - x1; -+ } else if (I+1 > x2) { -+ /* -+ * source right edge (I+1) to the -+ * right of dest right edge (x2): -+ * fractional weight -+ */ -+ wx = x2 - I; -+ } else { -+ /* -+ * source edges (I and I+1) completely -+ * inside dest edges (x1 and x2): -+ * full weight -+ */ -+ wx = 1.0; -+ } -+ -+ w = wx * wy; -+ wtot += w; -+ -+ /* -+ * We average the unsigned char value -+ * instead of char value: otherwise -+ * the minimum (char 0) is right next -+ * to the maximum (char -1)! This way -+ * they are spread between 0 and 255. -+ */ -+ if (Bpp == 4) { -+ /* unroll the loops, can give 20% */ -+ pixave[0] += w * ((unsigned char) *(src )); -+ pixave[1] += w * ((unsigned char) *(src+1)); -+ pixave[2] += w * ((unsigned char) *(src+2)); -+ pixave[3] += w * ((unsigned char) *(src+3)); -+ } else if (Bpp == 2) { -+ /* -+ * 16bpp: trickier with green -+ * split over two bytes, so we -+ * use the masks: -+ */ -+ us = *((unsigned short *) src); -+ pixave[0] += w*(us & main_red_mask); -+ pixave[1] += w*(us & main_green_mask); -+ pixave[2] += w*(us & main_blue_mask); -+ } else if (Bpp == 1) { -+ pixave[0] += w * -+ ((unsigned char) *(src)); -+ } else { -+ for (b=0; b<Bpp; b++) { -+ pixave[b] += w * -+ ((unsigned char) *(src+b)); -+ } -+ } -+ src += Bpp; -+ } -+ } -+ -+ if (wtot <= 0.0) { -+ wtot = 1.0; -+ } -+ wtot = 1.0/wtot; /* normalization factor */ -+ -+ /* place weighted average pixel in the scaled fb: */ -+ if (Bpp == 4) { -+ *(dest ) = (char) (wtot * pixave[0]); -+ *(dest+1) = (char) (wtot * pixave[1]); -+ *(dest+2) = (char) (wtot * pixave[2]); -+ *(dest+3) = (char) (wtot * pixave[3]); -+ } else if (Bpp == 2) { -+ /* 16bpp / 565 case: */ -+ pixave[0] *= wtot; -+ pixave[1] *= wtot; -+ pixave[2] *= wtot; -+ us = (main_red_mask & (int) pixave[0]) -+ | (main_green_mask & (int) pixave[1]) -+ | (main_blue_mask & (int) pixave[2]); -+ *( (unsigned short *) dest ) = us; -+ } else if (Bpp == 1) { -+ *(dest) = (char) (wtot * pixave[0]); -+ } else { -+ for (b=0; b<Bpp; b++) { -+ *(dest+b) = (char) (wtot * pixave[b]); -+ } -+ } -+ dest += Bpp; -+ } -+ } -+ markit: -+/* End taken from x11vnc scale: */ -+ if (0) {} -+} -+ -+void do_scale_stats(int width, int height) { -+ static double calls = 0.0, sum = 0.0, var = 0.0, last = 0.0; -+ double A = width * height; -+ -+ if (last == 0.0) { -+ last = dnow(); -+ } -+ -+ calls += 1.0; -+ sum += A; -+ var += A*A; -+ -+ if (dnow() > last + 4.0) { -+ double cnt = calls; -+ if (cnt <= 0.0) cnt = 1.0; -+ var /= cnt; -+ sum /= cnt; -+ var = var - sum * sum; -+ if (sum > 0.0) { -+ var = var / (sum*sum); -+ } -+ fprintf(stderr, "scale_rect stats: %10d %10.1f ave: %10.3f var-rat: %10.3f\n", (int) calls, sum * cnt, sum, var); -+ -+ calls = 0.0; -+ sum = 0.0; -+ var = 0.0; -+ last = dnow(); -+ } -+} -+ -+void put_image(int src_x, int src_y, int dst_x, int dst_y, int width, -+ int height, int solid) { -+ int db = 0; -+ int xmax = si.framebufferWidth; -+ int ymax = si.framebufferHeight; -+ -+if (db || 0) fprintf(stderr, "put_image(%d %d %d %d %d %d)\n", src_x, src_y, dst_x, dst_y, width, height); -+ -+ if (image_scale) { -+ int i; -+ static int scale_stats = -1; -+ -+ for (i=0; i < 2; i++) { -+ if (src_x > 0) src_x--; -+ if (src_y > 0) src_y--; -+ } -+ for (i=0; i < 4; i++) { -+ if (src_x + width < xmax) width++; -+ if (src_y + height < ymax) height++; -+ } -+ -+ if (db) fprintf(stderr, "put_image(%d %d %d %d %d %d)\n", src_x, src_y, dst_x, dst_y, width, height); -+ if (db) fprintf(stderr, "scale_rect(%d %d %d %d)\n", src_x, src_y, width, height); -+ -+ if (scale_stats < 0) { -+ if (getenv("SSVNC_SCALE_STATS")) { -+ scale_stats = 1; -+ } else { -+ scale_stats = 0; -+ } -+ } -+ if (scale_stats) { -+ do_scale_stats(width, height); -+ } -+ -+ scale_rect(scale_factor_x, scale_factor_y, 1, 0, &src_x, &src_y, &width, &height, solid); -+ dst_x = src_x; -+ dst_y = src_y; -+ } -+ -+#ifdef MITSHM -+ if (appData.useShm) { -+ double fac = image_scale ? scale_factor_y : 1.0; -+ if (image_ycrop == NULL) { -+ if (image_is_shm) { -+ XShmPutImage(dpy, desktopWin, gc, image, src_x, src_y, -+ dst_x, dst_y, width, height, False); -+ } else { -+ XPutImage(dpy, desktopWin, gc, image, src_x, src_y, -+ dst_x, dst_y, width, height); -+ } -+ } else if ((width < 32 && height < 32) || height > appData.yCrop * fac) { -+ XPutImage(dpy, desktopWin, gc, image, src_x, src_y, -+ dst_x, dst_y, width, height); -+ } else { -+ char *src, *dst; -+ int Bpp = image->bits_per_pixel / 8; -+ int Bpl = image->bytes_per_line, h; -+ int Bpl2 = image_ycrop->bytes_per_line; -+ src = image->data + src_y * Bpl + src_x * Bpp; -+ dst = image_ycrop->data; -+ for (h = 0; h < height; h++) { -+ memcpy(dst, src, width * Bpp); -+ src += Bpl; -+ dst += Bpl2; -+ } -+ XShmPutImage(dpy, desktopWin, gc, image_ycrop, 0, 0, -+ dst_x, dst_y, width, height, False); -+ } -+ } else -+#endif -+ { -+ XPutImage(dpy, desktopWin, gc, image, src_x, src_y, -+ dst_x, dst_y, width, height); -+ } -+} -+ -+#if 0 -+fprintf(stderr, "non-shmB image %d %d %d %d %d %d\n", src_x, src_y, dst_x, dst_y, width, height); -+fprintf(stderr, "shm image_ycrop %d %d %d %d %d %d\n", 0, 0, dst_x, dst_y, width, height); -+fprintf(stderr, "non-shmA image %d %d %d %d %d %d\n", src_x, src_y, dst_x, dst_y, width, height); -+#endif -+ -+void releaseAllPressedModifiers(void) { -+ int i; -+ static int debug_release = -1; -+ if (debug_release < 0) { -+ if (getenv("SSVNC_DEBUG_RELEASE")) { -+ debug_release = 1; -+ } else { -+ debug_release = 0; -+ } -+ } -+ if (debug_release) fprintf(stderr, "into releaseAllPressedModifiers()\n"); -+ for (i = 0; i < 256; i++) { -+ if (modifierPressed[i]) { -+ SendKeyEvent(XKeycodeToKeysym(dpy, i, 0), False); -+ modifierPressed[i] = False; -+ if (debug_release) fprintf(stderr, "releasing[%d] %s\n", i, XKeysymToString(XKeycodeToKeysym(dpy, i, 0))); -+ } -+ } -+} -+ -+#define PR_EXPOSE fprintf(stderr, "Expose: %04dx%04d+%04d+%04d %04d/%04d/%04d now: %8.4f rescale: %8.4f fullscreen: %8.4f\n", width, height, x, y, si.framebufferWidth, appData.yCrop, si.framebufferHeight, now - start_time, now - last_rescale, now - last_fullscreen); - - /* - * HandleBasicDesktopEvent - deal with expose and leave events. -@@ -152,42 +1553,529 @@ - static void - HandleBasicDesktopEvent(Widget w, XtPointer ptr, XEvent *ev, Boolean *cont) - { -- int i; -+ int x, y, width, height; -+ double now = dnow(); - -- switch (ev->type) { -+ if (w || ptr || cont) {} -+ -+ if (0) { -+ PR_EXPOSE; -+ } - -+ -+ switch (ev->type) { - case Expose: - case GraphicsExpose: - /* sometimes due to scrollbars being added/removed we get an expose outside - the actual desktop area. Make sure we don't pass it on to the RFB - server. */ -+ x = ev->xexpose.x; -+ y = ev->xexpose.y; -+ width = ev->xexpose.width; -+ height = ev->xexpose.height; -+ -+ if (image_scale) { -+ int i; -+ x /= scale_factor_x; -+ y /= scale_factor_y; -+ width /= scale_factor_x; -+ height /= scale_factor_y; -+ /* make them a little wider to avoid painting errors */ -+ for (i=0; i < 3; i++) { -+ if (x > 0) x--; -+ if (y > 0) y--; -+ } -+ for (i=0; i < 6; i++) { -+ if (x + width < si.framebufferWidth) width++; -+ if (y + height < si.framebufferHeight) height++; -+ } -+ } - -- if (ev->xexpose.x + ev->xexpose.width > si.framebufferWidth) { -- ev->xexpose.width = si.framebufferWidth - ev->xexpose.x; -- if (ev->xexpose.width <= 0) break; -- } -- -- if (ev->xexpose.y + ev->xexpose.height > si.framebufferHeight) { -- ev->xexpose.height = si.framebufferHeight - ev->xexpose.y; -- if (ev->xexpose.height <= 0) break; -- } -- -- SendFramebufferUpdateRequest(ev->xexpose.x, ev->xexpose.y, -- ev->xexpose.width, ev->xexpose.height, False); -- break; -+ if (x + width > si.framebufferWidth) { -+ width = si.framebufferWidth - x; -+ if (width <= 0) { -+ break; -+ } -+ } -+ -+ if (y + height > si.framebufferHeight) { -+ height = si.framebufferHeight - y; -+ if (height <= 0) { -+ break; -+ } -+ } -+ -+ if (appData.useXserverBackingStore) { -+ SendFramebufferUpdateRequest(x, y, width, height, False); -+ } else { -+ int ok = 1; -+ double delay = 2.5; -+ if (appData.fullScreen && now < last_fullscreen + delay) { -+ int xmax = si.framebufferWidth; -+ int ymax = si.framebufferHeight; -+ if (appData.yCrop > 0) { -+ ymax = appData.yCrop; -+ } -+ xmax = scale_round(xmax, scale_factor_x); -+ ymax = scale_round(ymax, scale_factor_y); -+ if (dpyWidth < xmax) { -+ xmax = dpyWidth; -+ } -+ if (dpyHeight < ymax) { -+ ymax = dpyHeight; -+ } -+ if (x != 0 && y != 0) { -+ ok = 0; -+ } -+ if (width < 0.9 * xmax) { -+ ok = 0; -+ } -+ if (height < 0.9 * ymax) { -+ ok = 0; -+ } -+ } -+ if (appData.yCrop > 0) { -+ if (now < last_fullscreen + delay || now < last_rescale + delay) { -+ if (y + height > appData.yCrop) { -+ height = appData.yCrop - y; -+ } -+ } -+ } -+ if (ok) { -+ put_image(x, y, x, y, width, height, 0); -+ XSync(dpy, False); -+ } else { -+ fprintf(stderr, "Skip "); -+ PR_EXPOSE; -+ } -+ } -+ break; - - case LeaveNotify: -- for (i = 0; i < 256; i++) { -- if (modifierPressed[i]) { -- SendKeyEvent(XKeycodeToKeysym(dpy, i, 0), False); -- modifierPressed[i] = False; -- } -- } -- break; -+ releaseAllPressedModifiers(); -+ if (appData.fullScreen) { -+ fs_ungrab(1); -+ } -+ break; -+ case EnterNotify: -+ if (appData.fullScreen) { -+ fs_grab(1); -+ } -+ break; -+ case ClientMessage: -+ if (ev->xclient.window == XtWindow(desktop) && ev->xclient.message_type == XA_INTEGER && -+ ev->xclient.format == 8 && !strcmp(ev->xclient.data.b, "SendRFBUpdate")) { -+ SendIncrementalFramebufferUpdateRequest(); -+ } -+ break; - } -+ check_things(); -+} -+ -+extern Position desktopX, desktopY; -+ -+void x11vnc_appshare(char *cmd) { -+ char send[200], str[100]; -+ char *id = "cmd=id_cmd"; -+ int m_big = 80, m_fine = 15; -+ int resize = 100, db = 0; -+ -+ if (getenv("X11VNC_APPSHARE_DEBUG")) { -+ db = atoi(getenv("X11VNC_APPSHARE_DEBUG")); -+ } -+ -+ if (db) fprintf(stderr, "x11vnc_appshare: cmd=%s\n", cmd); -+ -+ str[0] = '\0'; -+ -+ if (!strcmp(cmd, "left")) { -+ sprintf(str, "%s:move:-%d+0", id, m_big); -+ } else if (!strcmp(cmd, "right")) { -+ sprintf(str, "%s:move:+%d+0", id, m_big); -+ } else if (!strcmp(cmd, "up")) { -+ sprintf(str, "%s:move:+0-%d", id, m_big); -+ } else if (!strcmp(cmd, "down")) { -+ sprintf(str, "%s:move:+0+%d", id, m_big); -+ } else if (!strcmp(cmd, "left-fine")) { -+ sprintf(str, "%s:move:-%d+0", id, m_fine); -+ } else if (!strcmp(cmd, "right-fine")) { -+ sprintf(str, "%s:move:+%d+0", id, m_fine); -+ } else if (!strcmp(cmd, "up-fine")) { -+ sprintf(str, "%s:move:+0-%d", id, m_fine); -+ } else if (!strcmp(cmd, "down-fine")) { -+ sprintf(str, "%s:move:+0+%d", id, m_fine); -+ } else if (!strcmp(cmd, "taller")) { -+ sprintf(str, "%s:resize:+0+%d", id, resize); -+ } else if (!strcmp(cmd, "shorter")) { -+ sprintf(str, "%s:resize:+0-%d", id, resize); -+ } else if (!strcmp(cmd, "wider")) { -+ sprintf(str, "%s:resize:+%d+0", id, resize); -+ } else if (!strcmp(cmd, "narrower")) { -+ sprintf(str, "%s:resize:-%d+0", id, resize); -+ } else if (!strcmp(cmd, "lower")) { -+ sprintf(str, "%s:lower", id); -+ } else if (!strcmp(cmd, "raise")) { -+ sprintf(str, "%s:raise", id); -+ } else if (!strcmp(cmd, "delete")) { -+ sprintf(str, "%s:wm_delete", id); -+ } else if (!strcmp(cmd, "position")) { -+ Position x, y; -+ int xi, yi; -+ -+ XtVaGetValues(toplevel, XtNx, &x, XtNy, &y, NULL); -+ xi = (int) x; -+ yi = (int) y; -+ if (appData.scale) { -+ double fx = 1.0, fy = 1.0; -+ get_scale_values(&fx, &fy); -+ if (fx > 0.0 && fy > 0.0) { -+ xi /= fx; -+ yi /= fx; -+ } -+ } -+ sprintf(str, "%s:geom:0x0+%d+%d", id, xi, yi); -+ fprintf(stderr, "str=%s\n", str); -+ } -+ if (strcmp(str, "")) { -+ Bool vo = appData.viewOnly; -+ strcpy(send, "X11VNC_APPSHARE_CMD:"); -+ strcat(send, str); -+ if (db) fprintf(stderr, "x11vnc_appshare: send=%s\n", send); -+ if (vo) appData.viewOnly = False; -+ SendClientCutText(send, strlen(send)); -+ if (vo) appData.viewOnly = True; -+ } -+} -+ -+void scroll_desktop(int horiz, int vert, double amount) { -+ Dimension h, w; -+ Position x, y; -+ Position x2, y2; -+ static int db = -1; -+ -+ if (db < 0) { -+ if (getenv("SSVNC_DEBUG_ESCAPE_KEYS")) { -+ db = 1; -+ } else { -+ db = 0; -+ } -+ } -+ -+ XtVaGetValues(form, XtNheight, &h, XtNwidth, &w, NULL); -+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL); -+ -+ x2 = -x; -+ y2 = -y; -+ -+ if (amount == -1.0) { -+ int dx = horiz; -+ int dy = vert; -+ if (dx == 0 && dy == 0) { -+ return; -+ } -+ x2 -= dx; -+ y2 -= dy; -+ } else { -+ if (horiz) { -+ int dx = (int) (amount * w); -+ if (dx < 0) dx = -dx; -+ if (amount == 0.0) dx = 1; -+ if (horiz > 0) { -+ x2 += dx; -+ } else { -+ x2 -= dx; -+ } -+ if (x2 < 0) x2 = 0; -+ } -+ if (vert) { -+ int dy = (int) (amount * h); -+ if (amount == 0.0) dy = 1; -+ if (dy < 0) dy = -dy; -+ if (vert < 0) { -+ y2 += dy; -+ } else { -+ y2 -= dy; -+ } -+ if (y2 < 0) y2 = 0; -+ } -+ } -+ -+ if (db) fprintf(stderr, "%d %d %f viewport(%dx%d): %d %d -> %d %d\n", horiz, vert, amount, w, h, -x, -y, x2, y2); -+ XawViewportSetCoordinates(viewport, x2, y2); -+ -+ if (appData.fullScreen) { -+ XSync(dpy, False); -+ XtVaGetValues(desktop, XtNx, &x, XtNy, &y, NULL); -+ desktopX = -x; -+ desktopY = -y; -+ } else if (amount == -1.0) { -+ XSync(dpy, False); -+ } - } - -+void scale_desktop(int bigger, double frac) { -+ double current, new; -+ char tmp[100]; -+ char *s; -+ int fs; -+ -+ if (appData.scale == NULL) { -+ s = "1.0"; -+ } else { -+ s = appData.scale; -+ } -+ if (!strcmp(s, "auto")) { -+ fprintf(stderr, "scale_desktop: skipping scale mode '%s'\n", s); -+ return; -+ } else if (!strcmp(s, "fit")) { -+ fprintf(stderr, "scale_desktop: skipping scale mode '%s'\n", s); -+ return; -+ } else if (strstr(s, "x")) { -+ fprintf(stderr, "scale_desktop: skipping scale mode '%s'\n", s); -+ return; -+ } else if (!strcmp(s, "none")) { -+ s = "1.0"; -+ } -+ -+ if (sscanf(s, "%lf", ¤t) != 1) { -+ fprintf(stderr, "scale_desktop: skipping scale mode '%s'\n", s); -+ return; -+ } -+ if (bigger) { -+ new = current * (1.0 + frac); -+ } else { -+ new = current / (1.0 + frac); -+ } -+ if (0.99 < new && new < 1.01) { -+ new = 1.0; -+ } - -+ if (new > 5.0) { -+ fprintf(stderr, "scale_desktop: not scaling > 5.0: %f\n", new); -+ return; -+ } else if (new < 0.05) { -+ fprintf(stderr, "scale_desktop: not scaling < 0.05: %f\n", new); -+ return; -+ } -+ sprintf(tmp, "%.16f", new); -+ appData.scale = strdup(tmp); -+ -+ fs = 0; -+ if (appData.fullScreen) { -+ fs = 1; -+ FullScreenOff(); -+ } -+ if (1) { -+ double fx, fy; -+ get_scale_values(&fx, &fy); -+ if (fx > 0.0 && fy > 0.0) { -+ rescale_image(); -+ } -+ } -+ if (fs) { -+ FullScreenOn(); -+ } -+} -+ -+static int escape_mods[8]; -+static int escape_drag_in_progress = 0, last_x = 0, last_y = 0; -+static double last_drag = 0.0; -+static double last_key = 0.0; -+ -+static int escape_sequence_pressed(void) { -+ static char *prev = NULL; -+ char *str = "default"; -+ int sum, i, init = 0, pressed; -+ static int db = -1; -+ -+ if (db < 0) { -+ if (getenv("SSVNC_DEBUG_ESCAPE_KEYS")) { -+ db = 1; -+ } else { -+ db = 0; -+ } -+ } -+ -+ if (appData.escapeKeys != NULL) { -+ str = appData.escapeKeys; -+ } -+ if (prev == NULL) { -+ init = 1; -+ prev = strdup(str); -+ } else { -+ if (strcmp(prev, str)) { -+ init = 1; -+ free(prev); -+ prev = strdup(str); -+ } -+ } -+ if (db) fprintf(stderr, "str: %s\n", str); -+ -+ if (init) { -+ char *p, *s; -+ KeySym ks; -+ int k = 0, failed = 0; -+ -+ for (i = 0; i < 8; i++) { -+ escape_mods[i] = -1; -+ } -+ -+ if (!strcasecmp(str, "default")) { -+#if (defined(__MACH__) && defined(__APPLE__)) -+ s = strdup("Control_L,Meta_L"); -+#else -+ s = strdup("Alt_L,Super_L"); -+#endif -+ } else { -+ s = strdup(str); -+ } -+ -+ p = strtok(s, ",+ "); -+ while (p) { -+ ks = XStringToKeysym(p); -+ if (ks == XK_Shift_L || ks == XK_Shift_R) { -+ putenv("NO_X11VNC_APPSHARE=1"); -+ } -+ if (k >= 8) { -+ fprintf(stderr, "EscapeKeys: more than 8 modifier keys.\n"); -+ failed = 1; -+ break; -+ } -+ if (ks == NoSymbol) { -+ fprintf(stderr, "EscapeKeys: failed lookup for '%s'\n", p); -+ failed = 1; -+ break; -+ } else if (!IsModifierKey(ks)) { -+ fprintf(stderr, "EscapeKeys: not a modifier key '%s'\n", p); -+ failed = 1; -+ break; -+ } else { -+ KeyCode kc = XKeysymToKeycode(dpy, ks); -+ if (kc == NoSymbol) { -+ fprintf(stderr, "EscapeKeys: no keycode for modifier key '%s'\n", p); -+ failed = 1; -+ break; -+ } -+ if (db) fprintf(stderr, "set: %d %d\n", k, kc); -+ escape_mods[k++] = kc; -+ } -+ -+ p = strtok(NULL, ",+ "); -+ } -+ free(s); -+ -+ if (failed) { -+ for (i = 0; i < 8; i++) { -+ escape_mods[i] = -1; -+ } -+ } -+ } -+ -+ pressed = 1; -+ sum = 0; -+ for (i = 0; i < 8; i++) { -+ int kc = escape_mods[i]; -+ if (kc != -1 && kc < 256) { -+ if (db) fprintf(stderr, "try1: %d %d = %d\n", i, kc, modifierPressed[kc]); -+ if (!modifierPressed[kc]) { -+ pressed = 0; -+ break; -+ } else { -+ sum++; -+ } -+ } -+ } -+ if (sum == 0) pressed = 0; -+ -+ if (!pressed) { -+ /* user may have dragged mouse outside of toplevel window */ -+ int i, k; -+ int keystate[256]; -+ char keys[32]; -+ -+ /* so query server instead of modifierPressed[] */ -+ XQueryKeymap(dpy, keys); -+ for (i=0; i<32; i++) { -+ char c = keys[i]; -+ -+ for (k=0; k < 8; k++) { -+ if (c & 0x1) { -+ keystate[8*i + k] = 1; -+ } else { -+ keystate[8*i + k] = 0; -+ } -+ c = c >> 1; -+ } -+ } -+ -+ /* check again using keystate[] */ -+ pressed = 2; -+ sum = 0; -+ for (i = 0; i < 8; i++) { -+ int kc = escape_mods[i]; -+ if (kc != -1 && kc < 256) { -+ if (db) fprintf(stderr, "try2: %d %d = %d\n", i, kc, keystate[kc]); -+ if (!keystate[kc]) { -+ pressed = 0; -+ break; -+ } else { -+ sum++; -+ } -+ } -+ } -+ if (sum == 0) pressed = 0; -+ } -+ -+ return pressed; -+} -+ -+static int shift_is_down(void) { -+ int shift_down = 0; -+ KeyCode kc; -+ -+ if (appData.viewOnly) { -+ int i, k; -+ char keys[32]; -+ int keystate[256]; -+ -+ XQueryKeymap(dpy, keys); -+ for (i=0; i<32; i++) { -+ char c = keys[i]; -+ -+ for (k=0; k < 8; k++) { -+ if (c & 0x1) { -+ keystate[8*i + k] = 1; -+ } else { -+ keystate[8*i + k] = 0; -+ } -+ c = c >> 1; -+ } -+ } -+ -+ kc = XKeysymToKeycode(dpy, XK_Shift_L); -+ if (kc != NoSymbol && keystate[kc]) { -+ shift_down = 1; -+ } else { -+ kc = XKeysymToKeycode(dpy, XK_Shift_R); -+ if (kc != NoSymbol && keystate[kc]) { -+ shift_down = 1; -+ } -+ } -+ return shift_down; -+ } else { -+ kc = XKeysymToKeycode(dpy, XK_Shift_L); -+ if (kc != NoSymbol && modifierPressed[kc]) { -+ shift_down = 1; -+ } else { -+ kc = XKeysymToKeycode(dpy, XK_Shift_R); -+ if (kc != NoSymbol && modifierPressed[kc]) { -+ shift_down = 1; -+ } -+ } -+ return shift_down; -+ } -+} -+ - /* - * SendRFBEvent is an action which sends an RFB event. It can be used in two - * ways. Without any parameters it simply sends an RFB event corresponding to -@@ -201,127 +2089,406 @@ - * button2 down, 3 for both, etc). - */ - -+extern Bool selectingSingleWindow; -+ -+extern Cursor dotCursor3; -+extern Cursor dotCursor4; -+ -+extern void set_server_scale(int); -+ - void - SendRFBEvent(Widget w, XEvent *ev, String *params, Cardinal *num_params) - { -- KeySym ks; -- char keyname[256]; -- int buttonMask, x, y; -- -- if (appData.fullScreen && ev->type == MotionNotify) { -- if (BumpScroll(ev)) -- return; -- } -+ KeySym ks; -+ char keyname[256]; -+ int buttonMask, x, y; -+ int do_escape; -+ static int db = -1; -+ char *ek = appData.escapeKeys; -+ -+ if (db < 0) { -+ if (getenv("SSVNC_DEBUG_ESCAPE_KEYS")) { -+ db = 1; -+ } else { -+ db = 0; -+ } -+ } -+ -+ if (ev->type == MotionNotify || ev->type == KeyRelease) { -+ static double last = 0.0; -+ double now = dnow(); -+ if (now > last + 0.25) { -+ check_things(); -+ last = now; -+ } -+ } -+ -+ if (selectingSingleWindow && ev->type == ButtonPress) { -+ selectingSingleWindow = False; -+ SendSingleWindow(ev->xbutton.x, ev->xbutton.y); -+ if (appData.viewOnly) { -+ XDefineCursor(dpy, desktopWin, dotCursor4); -+ } else { -+ XDefineCursor(dpy, desktopWin, dotCursor3); -+ } -+ return; -+ } - -- if (appData.viewOnly) return; -+ if (appData.fullScreen && ev->type == MotionNotify && !escape_drag_in_progress) { -+ if (BumpScroll(ev)) { -+ return; -+ } -+ } -+ -+ do_escape = 0; -+ if (ek != NULL && (ek[0] == 'n' || ek[0] == 'N') && !strcasecmp(ek, "never")) { -+ ; -+ } else if (appData.viewOnly) { -+ do_escape = 1; -+ } else if (appData.escapeActive) { -+ int skip = 0, is_key = 0; -+ -+ if (ev->type == KeyPress || ev->type == KeyRelease) { -+ is_key = 1; -+ XLookupString(&ev->xkey, keyname, 256, &ks, NULL); -+ if (IsModifierKey(ks)) { -+ skip = 1; -+ } -+ } -+ if (!skip) { -+ int es = escape_sequence_pressed(); -+ if (es == 1) { -+ do_escape = 1; -+ } else if (es == 2) { -+ if (is_key) { -+ if (dnow() < last_key + 5.0) { -+ do_escape = 1; -+ } -+ } else { -+ if (dnow() < last_drag + 5.0) { -+ do_escape = 1; -+ } -+ } -+ } -+ } -+ } -+ if (!do_escape) { -+ escape_drag_in_progress = 0; -+ } -+ if (db) fprintf(stderr, "do_escape: %d\n", do_escape); -+ -+ if (do_escape) { -+ int W = si.framebufferWidth; -+ int H = si.framebufferHeight; -+ int shift_down = 0; -+ -+ if (!getenv("NO_X11VNC_APPSHARE")) { -+ shift_down = shift_is_down(); -+ } -+ if (db) fprintf(stderr, "shift_down: %d\n", shift_down); -+ -+ if (*num_params != 0) { -+ if (strcasecmp(params[0],"fbupdate") == 0) { -+ SendFramebufferUpdateRequest(0, 0, W, H, False); -+ } -+ } -+ if (ev->type == ButtonRelease) { -+ XButtonEvent *b = (XButtonEvent *) ev; -+ if (db) fprintf(stderr, "ButtonRelease: %d %d %d\n", b->x_root, b->y_root, b->state); -+ if (b->button == 3) { -+ if (shift_down) { -+ x11vnc_appshare("delete"); -+ } else { -+ ShowPopup(w, ev, params, num_params); -+ } -+ } else if (escape_drag_in_progress && b->button == 1) { -+ escape_drag_in_progress = 0; -+ } -+ } else if (ev->type == ButtonPress) { -+ XButtonEvent *b = (XButtonEvent *) ev; -+ if (db) fprintf(stderr, "ButtonPress: %d %d %d\n", b->x_root, b->y_root, b->state); -+ if (b->button == 1) { -+ if (shift_down) { -+ x11vnc_appshare("position"); -+ } else { -+ escape_drag_in_progress = 1; -+ last_x = b->x_root; -+ last_y = b->y_root; -+ } -+ } else { -+ escape_drag_in_progress = 0; -+ } -+ } else if (ev->type == MotionNotify) { -+ XMotionEvent *m = (XMotionEvent *) ev; -+ if (escape_drag_in_progress) { -+ if (db) fprintf(stderr, "MotionNotify: %d %d %d\n", m->x_root, m->y_root, m->state); -+ scroll_desktop(m->x_root - last_x, m->y_root - last_y, -1.0); -+ last_x = m->x_root; -+ last_y = m->y_root; -+ } -+ } else if (ev->type == KeyRelease) { -+ int did = 1; -+ -+ XLookupString(&ev->xkey, keyname, 256, &ks, NULL); -+ if (ks == XK_1 || ks == XK_KP_1) { -+ set_server_scale(1); -+ } else if (ks == XK_2 || ks == XK_KP_2) { -+ set_server_scale(2); -+ } else if (ks == XK_3 || ks == XK_KP_3) { -+ set_server_scale(3); -+ } else if (ks == XK_4 || ks == XK_KP_4) { -+ set_server_scale(4); -+ } else if (ks == XK_5 || ks == XK_KP_5) { -+ set_server_scale(5); -+ } else if (ks == XK_6 || ks == XK_KP_6) { -+ set_server_scale(6); -+ } else if (ks == XK_r || ks == XK_R) { -+ SendFramebufferUpdateRequest(0, 0, W, H, False); -+ } else if (ks == XK_b || ks == XK_B) { -+ ToggleBell(w, ev, params, num_params); -+ } else if (ks == XK_c || ks == XK_C) { -+ Toggle8bpp(w, ev, params, num_params); -+ } else if (ks == XK_x || ks == XK_X) { -+ ToggleX11Cursor(w, ev, params, num_params); -+ } else if (ks == XK_z || ks == XK_Z) { -+ ToggleTightZRLE(w, ev, params, num_params); -+ } else if (ks == XK_h || ks == XK_H) { -+ ToggleTightHextile(w, ev, params, num_params); -+ } else if (ks == XK_f || ks == XK_F) { -+ ToggleFileXfer(w, ev, params, num_params); -+ } else if (ks == XK_V) { -+ ToggleViewOnly(w, ev, params, num_params); -+ } else if (ks == XK_Q) { -+ Quit(w, ev, params, num_params); -+ } else if (ks == XK_l || ks == XK_L) { -+ ToggleFullScreen(w, ev, params, num_params); -+ } else if (ks == XK_a || ks == XK_A) { -+ ToggleCursorAlpha(w, ev, params, num_params); -+ } else if (ks == XK_s || ks == XK_S) { -+ SetScale(w, ev, params, num_params); -+ } else if (ks == XK_t || ks == XK_T) { -+ ToggleTextChat(w, ev, params, num_params); -+ } else if (ks == XK_e || ks == XK_E) { -+ SetEscapeKeys(w, ev, params, num_params); -+ } else if (ks == XK_g || ks == XK_G) { -+ ToggleXGrab(w, ev, params, num_params); -+ } else if (ks == XK_D) { -+ if (shift_down || appData.appShare) { -+ x11vnc_appshare("delete"); -+ } -+ } else if (ks == XK_M) { -+ if (shift_down || appData.appShare) { -+ x11vnc_appshare("position"); -+ } -+ } else if (ks == XK_Left) { -+ if (shift_down) { -+ x11vnc_appshare("left"); -+ } else { -+ scroll_desktop(-1, 0, 0.1); -+ } -+ } else if (ks == XK_Right) { -+ if (shift_down) { -+ x11vnc_appshare("right"); -+ } else { -+ scroll_desktop(+1, 0, 0.1); -+ } -+ } else if (ks == XK_Up) { -+ if (shift_down) { -+ x11vnc_appshare("up"); -+ } else { -+ scroll_desktop(0, +1, 0.1); -+ } -+ } else if (ks == XK_Down) { -+ if (shift_down) { -+ x11vnc_appshare("down"); -+ } else { -+ scroll_desktop(0, -1, 0.1); -+ } -+ } else if (ks == XK_KP_Left) { -+ if (shift_down) { -+ x11vnc_appshare("left-fine"); -+ } else { -+ scroll_desktop(-1, 0, 0.0); -+ } -+ } else if (ks == XK_KP_Right) { -+ if (shift_down) { -+ x11vnc_appshare("right-fine"); -+ } else { -+ scroll_desktop(+1, 0, 0.0); -+ } -+ } else if (ks == XK_KP_Up) { -+ if (shift_down) { -+ x11vnc_appshare("up-fine"); -+ } else { -+ scroll_desktop(0, +1, 0.0); -+ } -+ } else if (ks == XK_KP_Down) { -+ if (shift_down) { -+ x11vnc_appshare("down-fine"); -+ } else { -+ scroll_desktop(0, -1, 0.0); -+ } -+ } else if (ks == XK_Next || ks == XK_KP_Next) { -+ if (shift_down && ks == XK_Next) { -+ x11vnc_appshare("shorter"); -+ } else { -+ scroll_desktop(0, -1, 1.0); -+ } -+ } else if (ks == XK_Prior || ks == XK_KP_Prior) { -+ if (shift_down && ks == XK_Prior) { -+ x11vnc_appshare("taller"); -+ } else { -+ scroll_desktop(0, +1, 1.0); -+ } -+ } else if (ks == XK_End || ks == XK_KP_End) { -+ if (shift_down && ks == XK_End) { -+ x11vnc_appshare("narrower"); -+ } else { -+ scroll_desktop(+1, 0, 1.0); -+ } -+ } else if (ks == XK_Home || ks == XK_KP_Home) { -+ if (shift_down && ks == XK_Home) { -+ x11vnc_appshare("wider"); -+ } else { -+ scroll_desktop(-1, 0, 1.0); -+ } -+ } else if (ks == XK_equal || ks == XK_plus) { -+ if (shift_down) { -+ x11vnc_appshare("raise"); -+ } else { -+ scale_desktop(1, 0.1); -+ } -+ } else if (ks == XK_underscore || ks == XK_minus) { -+ if (shift_down) { -+ x11vnc_appshare("lower"); -+ } else { -+ scale_desktop(0, 0.1); -+ } -+ } else { -+ did = 0; -+ } -+ if (did) { -+ last_key = dnow(); -+ } -+ } -+ if (escape_drag_in_progress) { -+ last_drag = dnow(); -+ } -+ return; -+ } -+ if (appData.viewOnly) { -+ return; -+ } -+ -+ if (*num_params != 0) { -+ if (strncasecmp(params[0],"key",3) == 0) { -+ if (*num_params != 2) { -+ fprintf(stderr, "Invalid params: " -+ "SendRFBEvent(key|keydown|keyup,<keysym>)\n"); -+ return; -+ } -+ ks = XStringToKeysym(params[1]); -+ if (ks == NoSymbol) { -+ fprintf(stderr,"Invalid keysym '%s' passed to " -+ "SendRFBEvent\n", params[1]); -+ return; -+ } -+ if (strcasecmp(params[0],"keydown") == 0) { -+ SendKeyEvent(ks, 1); -+ } else if (strcasecmp(params[0],"keyup") == 0) { -+ SendKeyEvent(ks, 0); -+ } else if (strcasecmp(params[0],"key") == 0) { -+ SendKeyEvent(ks, 1); -+ SendKeyEvent(ks, 0); -+ } else { -+ fprintf(stderr,"Invalid event '%s' passed to " -+ "SendRFBEvent\n", params[0]); -+ return; -+ } -+ } else if (strcasecmp(params[0],"fbupdate") == 0) { -+ if (*num_params != 1) { -+ fprintf(stderr, "Invalid params: " -+ "SendRFBEvent(fbupdate)\n"); -+ return; -+ } -+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, -+ si.framebufferHeight, False); -+ -+ } else if (strcasecmp(params[0],"ptr") == 0) { -+ if (*num_params == 4) { -+ x = atoi(params[1]); -+ y = atoi(params[2]); -+ buttonMask = atoi(params[3]); -+ SendPointerEvent(x, y, buttonMask); -+ } else if (*num_params == 2) { -+ switch (ev->type) { -+ case ButtonPress: -+ case ButtonRelease: -+ x = ev->xbutton.x; -+ y = ev->xbutton.y; -+ break; -+ case KeyPress: -+ case KeyRelease: -+ x = ev->xkey.x; -+ y = ev->xkey.y; -+ break; -+ default: -+ fprintf(stderr, "Invalid event caused " -+ "SendRFBEvent(ptr,<buttonMask>)\n"); -+ return; -+ } -+ buttonMask = atoi(params[1]); -+ SendPointerEvent(x, y, buttonMask); -+ } else { -+ fprintf(stderr, "Invalid params: " -+ "SendRFBEvent(ptr,<x>,<y>,<buttonMask>)\n" -+ " or SendRFBEvent(ptr,<buttonMask>)\n"); -+ return; -+ } -+ } else { -+ fprintf(stderr,"Invalid event '%s' passed to " -+ "SendRFBEvent\n", params[0]); -+ } -+ return; -+ } - -- if (*num_params != 0) { -- if (strncasecmp(params[0],"key",3) == 0) { -- if (*num_params != 2) { -- fprintf(stderr, -- "Invalid params: SendRFBEvent(key|keydown|keyup,<keysym>)\n"); -- return; -- } -- ks = XStringToKeysym(params[1]); -- if (ks == NoSymbol) { -- fprintf(stderr,"Invalid keysym '%s' passed to SendRFBEvent\n", -- params[1]); -- return; -- } -- if (strcasecmp(params[0],"keydown") == 0) { -- SendKeyEvent(ks, 1); -- } else if (strcasecmp(params[0],"keyup") == 0) { -- SendKeyEvent(ks, 0); -- } else if (strcasecmp(params[0],"key") == 0) { -- SendKeyEvent(ks, 1); -- SendKeyEvent(ks, 0); -- } else { -- fprintf(stderr,"Invalid event '%s' passed to SendRFBEvent\n", -- params[0]); -- return; -- } -- } else if (strcasecmp(params[0],"fbupdate") == 0) { -- if (*num_params != 1) { -- fprintf(stderr, "Invalid params: SendRFBEvent(fbupdate)\n"); -- return; -- } -- SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, -- si.framebufferHeight, False); -- } else if (strcasecmp(params[0],"ptr") == 0) { -- if (*num_params == 4) { -- x = atoi(params[1]); -- y = atoi(params[2]); -- buttonMask = atoi(params[3]); -- SendPointerEvent(x, y, buttonMask); -- } else if (*num_params == 2) { - switch (ev->type) { -+ case MotionNotify: -+ while (XCheckTypedWindowEvent(dpy, desktopWin, MotionNotify, ev)) { -+ ; /* discard all queued motion notify events */ -+ } -+ -+ SendPointerEvent(ev->xmotion.x, ev->xmotion.y, -+ (ev->xmotion.state & 0x1f00) >> 8); -+ return; -+ - case ButtonPress: -+ SendPointerEvent(ev->xbutton.x, ev->xbutton.y, -+ (((ev->xbutton.state & 0x1f00) >> 8) | -+ (1 << (ev->xbutton.button - 1)))); -+ return; -+ - case ButtonRelease: -- x = ev->xbutton.x; -- y = ev->xbutton.y; -- break; -+ SendPointerEvent(ev->xbutton.x, ev->xbutton.y, -+ (((ev->xbutton.state & 0x1f00) >> 8) & -+ ~(1 << (ev->xbutton.button - 1)))); -+ return; -+ - case KeyPress: - case KeyRelease: -- x = ev->xkey.x; -- y = ev->xkey.y; -- break; -- default: -- fprintf(stderr, -- "Invalid event caused SendRFBEvent(ptr,<buttonMask>)\n"); -- return; -- } -- buttonMask = atoi(params[1]); -- SendPointerEvent(x, y, buttonMask); -- } else { -- fprintf(stderr, -- "Invalid params: SendRFBEvent(ptr,<x>,<y>,<buttonMask>)\n" -- " or SendRFBEvent(ptr,<buttonMask>)\n"); -- return; -- } -- -- } else { -- fprintf(stderr,"Invalid event '%s' passed to SendRFBEvent\n", params[0]); -- } -- return; -- } -- -- switch (ev->type) { -+ XLookupString(&ev->xkey, keyname, 256, &ks, NULL); - -- case MotionNotify: -- while (XCheckTypedWindowEvent(dpy, desktopWin, MotionNotify, ev)) -- ; /* discard all queued motion notify events */ -- -- SendPointerEvent(ev->xmotion.x, ev->xmotion.y, -- (ev->xmotion.state & 0x1f00) >> 8); -- return; -- -- case ButtonPress: -- SendPointerEvent(ev->xbutton.x, ev->xbutton.y, -- (((ev->xbutton.state & 0x1f00) >> 8) | -- (1 << (ev->xbutton.button - 1)))); -- return; -- -- case ButtonRelease: -- SendPointerEvent(ev->xbutton.x, ev->xbutton.y, -- (((ev->xbutton.state & 0x1f00) >> 8) & -- ~(1 << (ev->xbutton.button - 1)))); -- return; -- -- case KeyPress: -- case KeyRelease: -- XLookupString(&ev->xkey, keyname, 256, &ks, NULL); -- -- if (IsModifierKey(ks)) { -- ks = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0); -- modifierPressed[ev->xkey.keycode] = (ev->type == KeyPress); -- } -+ if (IsModifierKey(ks)) { -+ ks = XKeycodeToKeysym(dpy, ev->xkey.keycode, 0); -+ modifierPressed[ev->xkey.keycode] = (ev->type == KeyPress); -+ } - -- SendKeyEvent(ks, (ev->type == KeyPress)); -- return; -+ SendKeyEvent(ks, (ev->type == KeyPress)); -+ return; - -- default: -- fprintf(stderr,"Invalid event passed to SendRFBEvent\n"); -- } -+ default: -+ fprintf(stderr,"Invalid event passed to SendRFBEvent\n"); -+ } - } - - -@@ -329,68 +2496,255 @@ - * CreateDotCursor. - */ - -+#ifndef very_small_dot_cursor - static Cursor --CreateDotCursor() -+CreateDotCursor(int which) - { -- Cursor cursor; -- Pixmap src, msk; -- static char srcBits[] = { 0, 14,14,14, 0 }; -- static char mskBits[] = { 14,31,31,31,14 }; -- XColor fg, bg; -- -- src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits, 5, 5); -- msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits, 5, 5); -- XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black", -- &fg, &fg); -- XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white", -- &bg, &bg); -- cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 2, 2); -- XFreePixmap(dpy, src); -- XFreePixmap(dpy, msk); -+ Cursor cursor; -+ Pixmap src, msk; -+ static char srcBits3[] = { 0x00, 0x02, 0x00 }; -+ static char mskBits3[] = { 0x02, 0x07, 0x02 }; -+ static char srcBits4[] = { 0x00, 0x06, 0x06, 0x00 }; -+ static char mskBits4[] = { 0x06, 0x0f, 0x0f, 0x06 }; -+ XColor fg, bg; -+ -+ if (which == 3) { -+ src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits3, 3, 3); -+ msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits3, 3, 3); -+ } else { -+ src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits4, 4, 4); -+ msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits4, 4, 4); -+ } -+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black", -+ &fg, &fg); -+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white", -+ &bg, &bg); -+ cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 1, 1); -+ XFreePixmap(dpy, src); -+ XFreePixmap(dpy, msk); - -- return cursor; -+ return cursor; - } -+#else -+static Cursor -+CreateDotCursor() -+{ -+ Cursor cursor; -+ Pixmap src, msk; -+ static char srcBits[] = { 0, 14, 0 }; -+ static char mskBits[] = { 14,31,14 }; -+ XColor fg, bg; -+ -+ src = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), srcBits, 3, 3); -+ msk = XCreateBitmapFromData(dpy, DefaultRootWindow(dpy), mskBits, 3, 3); -+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "black", -+ &fg, &fg); -+ XAllocNamedColor(dpy, DefaultColormap(dpy,DefaultScreen(dpy)), "white", -+ &bg, &bg); -+ cursor = XCreatePixmapCursor(dpy, src, msk, &fg, &bg, 1, 1); -+ XFreePixmap(dpy, src); -+ XFreePixmap(dpy, msk); - -+ return cursor; -+} -+#endif - -+int skip_maybe_sync = 0; -+void maybe_sync(int width, int height) { -+ static int singles = 0, always_skip = -1; -+ int singles_max = 64; -+ -+ if (always_skip < 0) { -+ if (getenv("SSVNC_NO_MAYBE_SYNC")) { -+ always_skip = 1; -+ } else { -+ always_skip = 0; -+ } -+ } -+ if (skip_maybe_sync || always_skip) { -+ return; -+ } -+#if 0 -+ if (width > 1 || height > 1) { -+ XSync(dpy, False); -+ singles = 0; -+ } else { -+ if (++singles >= singles_max) { -+ singles = 0; -+ XSync(dpy, False); -+ } -+ } -+#else -+ if (width * height >= singles_max) { -+ XSync(dpy, False); -+ singles = 0; -+ } else { -+ singles += width * height; -+ if (singles >= singles_max) { -+ XSync(dpy, False); -+ singles = 0; -+ } -+ } -+#endif -+} - /* -- * CopyDataToScreen. -+ * FillImage. - */ - - void --CopyDataToScreen(char *buf, int x, int y, int width, int height) -+FillScreen(int x, int y, int width, int height, unsigned long fill) - { -- if (appData.rawDelay != 0) { -- XFillRectangle(dpy, desktopWin, gc, x, y, width, height); -+ XImage *im = image_scale ? image_scale : image; -+ int bpp = im->bits_per_pixel; -+ int Bpp = im->bits_per_pixel / 8; -+ int Bpl = im->bytes_per_line; -+ int h, widthInBytes = width * Bpp; -+ static char *buf = NULL; -+ static int buflen = 0; -+ unsigned char *ucp; -+ unsigned short *usp; -+ unsigned int *uip; -+ char *scr; -+ int b0, b1, b2; - -- XSync(dpy,False); -+#if 0 -+fprintf(stderr, "FillImage bpp=%d %04dx%04d+%04d+%04d -- 0x%x\n", bpp, width, height, x, y, fill); -+#endif -+ if (appData.chatOnly) { -+ return; -+ } - -- usleep(appData.rawDelay * 1000); -- } -+ if (widthInBytes > buflen || !buf) { -+ if (buf) { -+ free(buf); -+ } -+ buflen = widthInBytes * 2; -+ buf = (char *)malloc(buflen); -+ } -+ ucp = (unsigned char*) buf; -+ usp = (unsigned short*) buf; -+ uip = (unsigned int*) buf; -+ -+ if (isLSB) { -+ b0 = 0; b1 = 1; b2 = 2; -+ } else { -+ b0 = 2; b1 = 1; b2 = 0; -+ } - -- if (!appData.useBGR233) { -- int h; -- int widthInBytes = width * myFormat.bitsPerPixel / 8; -- int scrWidthInBytes = si.framebufferWidth * myFormat.bitsPerPixel / 8; -- -- char *scr = (image->data + y * scrWidthInBytes -- + x * myFormat.bitsPerPixel / 8); -- -- for (h = 0; h < height; h++) { -- memcpy(scr, buf, widthInBytes); -- buf += widthInBytes; -- scr += scrWidthInBytes; -- } -- } else { -- CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height); -- } -+ for (h = 0; h < width; h++) { -+ if (bpp == 8) { -+ *(ucp+h) = (unsigned char) fill; -+ } else if (bpp == 16) { -+ *(usp+h) = (unsigned short) fill; -+ } else if (bpp == 24) { -+ *(ucp + 3*h + b0) = (unsigned char) ((fill & 0x0000ff) >> 0); -+ *(ucp + 3*h + b1) = (unsigned char) ((fill & 0x00ff00) >> 8); -+ *(ucp + 3*h + b2) = (unsigned char) ((fill & 0xff0000) >> 16); -+ } else if (bpp == 32) { -+ *(uip+h) = (unsigned int) fill; -+ } -+ } - --#ifdef MITSHM -- if (appData.useShm) { -- XShmPutImage(dpy, desktopWin, gc, image, x, y, x, y, width, height, False); -- return; -- } -+ scr = im->data + y * Bpl + x * Bpp; -+ -+ for (h = 0; h < height; h++) { -+ memcpy(scr, buf, widthInBytes); -+ scr += Bpl; -+ } -+ put_image(x, y, x, y, width, height, 1); -+ maybe_sync(width, height); -+} -+ -+void copy_rect(int x, int y, int width, int height, int src_x, int src_y) { -+ char *src, *dst; -+ int i; -+ XImage *im = image_scale ? image_scale : image; -+ int Bpp = im->bits_per_pixel / 8; -+ int Bpl = im->bytes_per_line; -+ int did2 = 0; -+ -+#if 0 -+fprintf(stderr, "copy_rect: %04dx%04d+%04d+%04d -- %04d %04d Bpp=%d Bpl=%d\n", width, height, x, y, src_x, src_y, Bpp, Bpl); - #endif -- XPutImage(dpy, desktopWin, gc, image, x, y, x, y, width, height); -+ copyrect2: -+ -+ if (y < src_y) { -+ src = im->data + src_y * Bpl + src_x * Bpp; -+ dst = im->data + y * Bpl + x * Bpp; -+ for (i = 0; i < height; i++) { -+ memmove(dst, src, Bpp * width); -+ src += Bpl; -+ dst += Bpl; -+ } -+ } else { -+ src = im->data + (src_y + height - 1) * Bpl + src_x * Bpp; -+ dst = im->data + (y + height - 1) * Bpl + x * Bpp; -+ for (i = 0; i < height; i++) { -+ memmove(dst, src, Bpp * width); -+ src -= Bpl; -+ dst -= Bpl; -+ } -+ } -+ -+ if (image_scale && !did2) { -+ im = image; -+ Bpp = im->bits_per_pixel / 8; -+ Bpl = im->bytes_per_line; -+ -+ x *= scale_factor_x; -+ y *= scale_factor_y; -+ src_x *= scale_factor_x; -+ src_y *= scale_factor_y; -+ width = scale_round(width, scale_factor_x); -+ height = scale_round(height, scale_factor_y); -+ -+ did2 = 1; -+ goto copyrect2; -+ } -+} -+ -+ -+/* -+ * CopyDataToScreen. -+ */ -+ -+void -+CopyDataToScreen(char *buf, int x, int y, int width, int height) -+{ -+ if (appData.chatOnly) { -+ return; -+ } -+ if (appData.rawDelay != 0) { -+ XFillRectangle(dpy, desktopWin, gc, x, y, width, height); -+ XSync(dpy,False); -+ usleep(appData.rawDelay * 1000); -+ } -+ -+ if (appData.useBGR233) { -+ CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height); -+ } else if (appData.useBGR565) { -+ CopyBGR565ToScreen((CARD16 *)buf, x, y, width, height); -+ } else { -+ int h; -+ int widthInBytes = width * myFormat.bitsPerPixel / 8; -+ int scrWidthInBytes = si.framebufferWidth * myFormat.bitsPerPixel / 8; -+ char *scr; -+ XImage *im = image_scale ? image_scale : image; -+ -+ if (scrWidthInBytes != im->bytes_per_line) scrWidthInBytes = im->bytes_per_line; -+ -+ scr = (im->data + y * scrWidthInBytes -+ + x * myFormat.bitsPerPixel / 8); -+ -+ for (h = 0; h < height; h++) { -+ memcpy(scr, buf, widthInBytes); -+ buf += widthInBytes; -+ scr += scrWidthInBytes; -+ } -+ } -+ -+ put_image(x, y, x, y, width, height, 0); -+ maybe_sync(width, height); - } - - -@@ -401,62 +2755,338 @@ - static void - CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height) - { -- int p, q; -- int xoff = 7 - (x & 7); -- int xcur; -- int fbwb = si.framebufferWidth / 8; -- CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8; -- CARD8 *scrt; -- CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x; -- CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x; -- CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x; -+ XImage *im = image_scale ? image_scale : image; -+ int p, q; -+ int xoff = 7 - (x & 7); -+ int xcur; -+ int fbwb = si.framebufferWidth / 8; -+ int src_width8 = im->bytes_per_line/1; -+ int src_width16 = im->bytes_per_line/2; -+ int src_width32 = im->bytes_per_line/4; -+ CARD8 *src1 = ((CARD8 *)im->data) + y * fbwb + x / 8; -+ CARD8 *srct; -+ CARD8 *src8 = ( (CARD8 *)im->data) + y * src_width8 + x; -+ CARD16 *src16 = ((CARD16 *)im->data) + y * src_width16 + x; -+ CARD32 *src32 = ((CARD32 *)im->data) + y * src_width32 + x; -+ int b0, b1, b2; - -- switch (visbpp) { -+ switch (visbpp) { - - /* thanks to Chris Hooper for single bpp support */ - -- case 1: -- for (q = 0; q < height; q++) { -- xcur = xoff; -- scrt = scr1; -- for (p = 0; p < width; p++) { -- *scrt = ((*scrt & ~(1 << xcur)) -- | (BGR233ToPixel[*(buf++)] << xcur)); -- -- if (xcur-- == 0) { -- xcur = 7; -- scrt++; -- } -- } -- scr1 += fbwb; -- } -- break; -- -- case 8: -- for (q = 0; q < height; q++) { -- for (p = 0; p < width; p++) { -- *(scr8++) = BGR233ToPixel[*(buf++)]; -- } -- scr8 += si.framebufferWidth - width; -- } -- break; -- -- case 16: -- for (q = 0; q < height; q++) { -- for (p = 0; p < width; p++) { -- *(scr16++) = BGR233ToPixel[*(buf++)]; -- } -- scr16 += si.framebufferWidth - width; -- } -- break; -- -- case 32: -- for (q = 0; q < height; q++) { -- for (p = 0; p < width; p++) { -- *(scr32++) = BGR233ToPixel[*(buf++)]; -- } -- scr32 += si.framebufferWidth - width; -- } -- break; -- } -+ case 1: -+ for (q = 0; q < height; q++) { -+ xcur = xoff; -+ srct = src1; -+ for (p = 0; p < width; p++) { -+ *srct = ((*srct & ~(1 << xcur)) -+ | (BGR233ToPixel[*(buf++)] << xcur)); -+ -+ if (xcur-- == 0) { -+ xcur = 7; -+ srct++; -+ } -+ } -+ src1 += fbwb; -+ } -+ break; -+ -+ case 8: -+ for (q = 0; q < height; q++) { -+ for (p = 0; p < width; p++) { -+ *(src8++) = BGR233ToPixel[*(buf++)]; -+ } -+ src8 += src_width8 - width; -+ } -+ break; -+ -+ case 16: -+ for (q = 0; q < height; q++) { -+ for (p = 0; p < width; p++) { -+ *(src16++) = BGR233ToPixel[*(buf++)]; -+ } -+ src16 += src_width16 - width; -+ } -+ break; -+ -+ case 24: -+ if (isLSB) { -+ b0 = 0; b1 = 1; b2 = 2; -+ } else { -+ b0 = 2; b1 = 1; b2 = 0; -+ } -+ src8 = ((CARD8 *)im->data) + (y * si.framebufferWidth + x) * 3; -+ for (q = 0; q < height; q++) { -+ for (p = 0; p < width; p++) { -+ CARD32 v = BGR233ToPixel[*(buf++)]; -+ *(src8 + b0) = (unsigned char) ((v & 0x0000ff) >> 0); -+ *(src8 + b1) = (unsigned char) ((v & 0x00ff00) >> 8); -+ *(src8 + b2) = (unsigned char) ((v & 0xff0000) >> 16); -+ src8 += 3; -+ } -+ src8 += (si.framebufferWidth - width) * 3; -+ } -+ break; -+ -+ case 32: -+ for (q = 0; q < height; q++) { -+ for (p = 0; p < width; p++) { -+ *(src32++) = BGR233ToPixel[*(buf++)]; -+ } -+ src32 += src_width32 - width; -+ } -+ break; -+ } -+} -+ -+static void -+BGR565_24bpp(CARD16 *buf, int x, int y, int width, int height) -+{ -+ int p, q; -+ int b0, b1, b2; -+ XImage *im = image_scale ? image_scale : image; -+ unsigned char *src= (unsigned char *)im->data + (y * si.framebufferWidth + x) * 3; -+ -+ if (isLSB) { -+ b0 = 0; b1 = 1; b2 = 2; -+ } else { -+ b0 = 2; b1 = 1; b2 = 0; -+ } -+ -+ /* case 24: */ -+ for (q = 0; q < height; q++) { -+ for (p = 0; p < width; p++) { -+ CARD32 v = BGR565ToPixel[*(buf++)]; -+ *(src + b0) = (unsigned char) ((v & 0x0000ff) >> 0); -+ *(src + b1) = (unsigned char) ((v & 0x00ff00) >> 8); -+ *(src + b2) = (unsigned char) ((v & 0xff0000) >> 16); -+ src += 3; -+ } -+ src += (si.framebufferWidth - width) * 3; -+ } -+} -+ -+static void -+CopyBGR565ToScreen(CARD16 *buf, int x, int y, int width, int height) -+{ -+ int p, q; -+ XImage *im = image_scale ? image_scale : image; -+ int src_width32 = im->bytes_per_line/4; -+ CARD32 *src32 = ((CARD32 *)im->data) + y * src_width32 + x; -+ -+ if (visbpp == 24) { -+ BGR565_24bpp(buf, x, y, width, height); -+ return; -+ } -+ -+ /* case 32: */ -+ for (q = 0; q < height; q++) { -+ for (p = 0; p < width; p++) { -+ *(src32++) = BGR565ToPixel[*(buf++)]; -+ } -+ src32 += src_width32 - width; -+ } -+} -+ -+static void reset_image(void) { -+ if (UsingShm()) { -+ ShmDetach(); -+ } -+ if (image && image->data) { -+ XDestroyImage(image); -+ fprintf(stderr, "reset_image: destroyed 'image'\n"); -+ } -+ image = NULL; -+ if (image_ycrop && image_ycrop->data) { -+ XDestroyImage(image_ycrop); -+ fprintf(stderr, "reset_image: destroyed 'image_ycrop'\n"); -+ } -+ image_ycrop = NULL; -+ if (image_scale && image_scale->data) { -+ XDestroyImage(image_scale); -+ fprintf(stderr, "reset_image: destroyed 'image_scale'\n"); -+ } -+ image_scale = NULL; -+ -+ if (UsingShm()) { -+ ShmCleanup(); -+ } -+ create_image(); -+ XFlush(dpy); -+} -+ -+void ReDoDesktop(void) { -+ int w, w0, h, h0, x, y, dw, dh; -+ int fs = 0; -+ int autoscale = 0; -+ Position x_orig, y_orig; -+ Dimension w_orig, h_orig; -+ -+ if (!appData.fullScreen && appData.scale != NULL && !strcmp(appData.scale, "auto")) { -+ autoscale = 1; -+ } -+ -+ fprintf(stderr, "ReDoDesktop: ycrop: %d\n", appData.yCrop); -+ -+ XtVaGetValues(toplevel, XtNx, &x_orig, XtNy, &y_orig, NULL); -+ XtVaGetValues(toplevel, XtNheight, &h_orig, XtNwidth, &w_orig, NULL); -+ -+ check_tall(); -+ -+ if (appData.yCrop) { -+ if (appData.yCrop < 0 || old_width <= 0) { -+ appData.yCrop = guessCrop(); -+ fprintf(stderr, "Set -ycrop to: %d\n", appData.yCrop); -+ } else { -+ int w1 = si.framebufferWidth; -+ appData.yCrop = (w1 * appData.yCrop) / old_width; -+ if (appData.yCrop <= 100) { -+ appData.yCrop = guessCrop(); -+ fprintf(stderr, "Set small -ycrop to: %d\n", appData.yCrop); -+ } -+ } -+ fprintf(stderr, "Using -ycrop: %d\n", appData.yCrop); -+ } -+ -+ old_width = si.framebufferWidth; -+ old_height = si.framebufferHeight; -+ -+ if (appData.fullScreen) { -+ if (prev_fb_width != si.framebufferWidth || prev_fb_height != si.framebufferHeight) { -+ int xmax = si.framebufferWidth; -+ int ymax = si.framebufferHeight; -+ if (appData.yCrop > 0) { -+ ymax = appData.yCrop; -+ } -+ if (scale_x > 0) { -+ xmax = scale_round(xmax, scale_factor_x); -+ ymax = scale_round(ymax, scale_factor_y); -+ } -+ if (xmax < dpyWidth || ymax < dpyHeight) { -+ FullScreenOff(); -+ fs = 1; -+ } -+ } -+ } -+ -+ prev_fb_width = si.framebufferWidth; -+ prev_fb_height = si.framebufferHeight; -+ -+ if (appData.fullScreen) { -+ -+ int xmax = si.framebufferWidth; -+ int ymax = si.framebufferHeight; -+ if (scale_x > 0) { -+ xmax = scale_round(xmax, scale_factor_x); -+ ymax = scale_round(ymax, scale_factor_y); -+ } -+ -+ if (image && image->data) { -+ int len; -+ int h = image->height; -+ int w = image->width; -+ len = image->bytes_per_line * image->height; -+ /* black out window first: */ -+ memset(image->data, 0, len); -+ XPutImage(dpy, XtWindow(desktop), gc, image, 0, 0, 0, 0, w, h); -+ XFlush(dpy); -+ } -+ -+ /* XXX scaling?? */ -+ XtResizeWidget(desktop, xmax, ymax, 0); -+ -+ XSync(dpy, False); -+ usleep(100*1000); -+ FullScreenOn(); -+ XSync(dpy, False); -+ usleep(100*1000); -+ reset_image(); -+ return; -+ } -+ -+ dw = appData.wmDecorationWidth; -+ dh = appData.wmDecorationHeight; -+ -+ w = si.framebufferWidth; -+ h = si.framebufferHeight; -+ w0 = w; -+ h0 = h; -+ if (appData.yCrop > 0) { -+ h = appData.yCrop; -+ } -+ if (image_scale) { -+ w = scale_round(w, scale_factor_x); -+ h = scale_round(h, scale_factor_y); -+ w0 = scale_round(w0, scale_factor_x); -+ h0 = scale_round(h0, scale_factor_y); -+ } -+ -+ if (w + dw >= dpyWidth) { -+ w = dpyWidth - dw; -+ } -+ if (h + dh >= dpyHeight) { -+ h = dpyHeight - dh; -+ } -+ -+ if (!autoscale) { -+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, h, NULL); -+ } else { -+ XtVaSetValues(toplevel, XtNmaxWidth, dpyWidth, XtNmaxHeight, dpyHeight, NULL); -+ } -+ -+ XtVaSetValues(desktop, XtNwidth, w0, XtNheight, h0, NULL); -+ -+ XtResizeWidget(desktop, w0, h0, 0); -+ -+ if (appData.yCrop > 0) { -+ int ycrop = appData.yCrop; -+ if (image_scale) { -+ ycrop *= scale_factor_y; -+ } -+ XtVaSetValues(toplevel, XtNmaxHeight, ycrop, NULL); -+ XtVaSetValues(form, XtNmaxHeight, ycrop, NULL); -+ } -+ -+ x = (dpyWidth - w - dw)/2; -+ y = (dpyHeight - h - dh)/2; -+ -+ if (!autoscale) { -+ -+ if (!getenv("VNCVIEWER_ALWAYS_RECENTER")) { -+ int x_cm_old, y_cm_old; -+ int x_cm_new, y_cm_new; -+ int x_try, y_try; -+ -+ x_cm_old = (int) x_orig + ((int) w_orig)/2; -+ y_cm_old = (int) y_orig + ((int) h_orig)/2; -+ -+ x_cm_new = dpyWidth/2; -+ y_cm_new = dpyHeight/2; -+ -+ x_try = x + (x_cm_old - x_cm_new); -+ y_try = y + (y_cm_old - y_cm_new); -+ if (x_try < 0) { -+ x_try = 0; -+ } -+ if (y_try < 0) { -+ y_try = 0; -+ } -+ if (x_try + w + dw > dpyWidth) { -+ x_try = dpyWidth - w - dw; -+ } -+ if (y_try + h + dh > dpyHeight) { -+ y_try = dpyHeight - h - dh; -+ } -+ x = x_try; -+ y = y_try; -+ } -+ -+ XtConfigureWidget(toplevel, x + dw, y + dh, w, h, 0); -+ } -+ -+ reset_image(); -+ -+ if (fs) { -+ FullScreenOn(); -+ } - } -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/dialogs.c vnc_unixsrc/vncviewer/dialogs.c ---- vnc_unixsrc.orig/vncviewer/dialogs.c 2000-10-26 15:19:19.000000000 -0400 -+++ vnc_unixsrc/vncviewer/dialogs.c 2010-02-25 22:33:06.000000000 -0500 -@@ -25,75 +25,564 @@ - #include <X11/Xaw/Dialog.h> - - static Bool serverDialogDone = False; -+static Bool userDialogDone = False; - static Bool passwordDialogDone = False; -+static Bool ycropDialogDone = False; -+static Bool scaleDialogDone = False; -+static Bool escapeDialogDone = False; -+static Bool scbarDialogDone = False; -+static Bool scaleNDialogDone = False; -+static Bool qualityDialogDone = False; -+static Bool compressDialogDone = False; -+ -+extern void popupFixer(Widget wid); -+ -+int use_tty(void) { -+ if (appData.notty) { -+ return 0; -+ } else if (!isatty(0)) { -+ return 0; -+ } -+ return 1; -+} -+ -+void -+ScaleDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ scaleDialogDone = True; -+ if (w || event || params || num_params) {} -+} -+ -+void -+EscapeDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ escapeDialogDone = True; -+ if (w || event || params || num_params) {} -+} -+ -+void dialog_over(Widget wid) { -+ if (appData.fullScreen) { -+ if (!net_wm_supported()) { -+ XtVaSetValues(wid, XtNoverrideRedirect, True, NULL); -+ XSync(dpy, True); -+ } -+ } -+} -+ -+extern int XError_ign; -+ -+void dialog_input(Widget wid) { -+ XError_ign = 1; -+ XSetInputFocus(dpy, XtWindow(wid), RevertToParent, CurrentTime); -+ XSync(dpy, False); -+ usleep(30 * 1000); -+ XSync(dpy, False); -+ usleep(20 * 1000); -+ XSync(dpy, False); -+ XError_ign = 0; -+} -+ -+static void rmNL(char *s) { -+ int len; -+ if (s == NULL) { -+ return; -+ } -+ len = strlen(s); -+ if (len > 0 && s[len-1] == '\n') { -+ s[len-1] = '\0'; -+ } -+} -+ -+static void wm_delete(Widget w, char *func) { -+ char str[1024]; -+ Atom wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False); -+ XSetWMProtocols(dpy, XtWindow(w), &wmDeleteWindow, 1); -+ if (func) { -+ sprintf(str, "<Message>WM_PROTOCOLS: %s", func); -+ XtOverrideTranslations(w, XtParseTranslationTable (str)); -+ } -+} -+ -+static void xtmove(Widget w) { -+ XtMoveWidget(w, WidthOfScreen(XtScreen(w))*2/5, HeightOfScreen(XtScreen(w))*2/5); -+} -+ -+char * -+DoScaleDialog() -+{ -+ Widget pshell, dialog; -+ char *scaleValue; -+ char *valueString; -+ -+ pshell = XtVaCreatePopupShell("scaleDialog", transientShellWidgetClass, -+ toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ -+ dialog_over(pshell); -+ -+ if (0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (appData.scale != NULL) { -+ String label; -+ char tmp[410]; -+ XtVaGetValues(dialog, XtNlabel, &label, NULL); -+ if (strlen(label) + strlen(appData.scale) < 400) { -+ sprintf(tmp, "%s %s", label, appData.scale); -+ XtVaSetValues(dialog, XtNlabel, tmp, NULL); -+ } -+ } -+ -+ -+ if (1 && appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+ dialog_input(pshell); -+ wm_delete(pshell, "ScaleDialogDone()"); -+ -+ scaleDialogDone = False; -+ -+ while (!scaleDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ scaleValue = XtNewString(valueString); -+ -+ XtPopdown(pshell); -+ return scaleValue; -+} -+ -+char * -+DoEscapeKeysDialog() -+{ -+ Widget pshell, dialog; -+ char *escapeValue; -+ char *valueString; -+ char *curr = appData.escapeKeys ? appData.escapeKeys : "default"; -+ -+ pshell = XtVaCreatePopupShell("escapeDialog", transientShellWidgetClass, -+ toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ -+ dialog_over(pshell); -+ -+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (curr != NULL) { -+ String label; -+ char tmp[3010]; -+ XtVaGetValues(dialog, XtNlabel, &label, NULL); -+ if (strlen(label) + strlen(curr) < 3000) { -+ sprintf(tmp, "%s %s", label, curr); -+ XtVaSetValues(dialog, XtNlabel, tmp, NULL); -+ } -+ } -+ -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ /* too big */ -+ if (0) xtmove(pshell); -+ } -+ dialog_input(pshell); -+ wm_delete(pshell, "EscapeDialogDone()"); -+ -+ escapeDialogDone = False; -+ -+ while (!escapeDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ escapeValue = XtNewString(valueString); -+ -+ XtPopdown(pshell); -+ return escapeValue; -+} -+ -+void -+YCropDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ ycropDialogDone = True; -+ if (w || event || params || num_params) {} -+} -+ -+char * -+DoYCropDialog() -+{ -+ Widget pshell, dialog; -+ char *ycropValue; -+ char *valueString; -+ -+ pshell = XtVaCreatePopupShell("ycropDialog", transientShellWidgetClass, -+ toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ -+ dialog_over(pshell); -+ -+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (1 && appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+ dialog_input(pshell); -+ wm_delete(pshell, "YCropDialogDone()"); -+ -+ ycropDialogDone = False; -+ -+ while (!ycropDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ ycropValue = XtNewString(valueString); -+ -+ XtPopdown(pshell); -+ return ycropValue; -+} -+ -+void -+ScbarDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ scbarDialogDone = True; -+ if (w || event || params || num_params) {} -+} -+ -+char * -+DoScbarDialog() -+{ -+ Widget pshell, dialog; -+ char *scbarValue; -+ char *valueString; -+ -+ pshell = XtVaCreatePopupShell("scbarDialog", transientShellWidgetClass, -+ toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ -+ dialog_over(pshell); -+ -+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (1 && appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+ dialog_input(pshell); -+ wm_delete(pshell, "ScbarDialogDone()"); -+ -+ scbarDialogDone = False; -+ -+ while (!scbarDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ scbarValue = XtNewString(valueString); -+ -+ XtPopdown(pshell); -+ return scbarValue; -+} -+ -+void -+ScaleNDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ scaleNDialogDone = True; -+ if (w || event || params || num_params) {} -+} -+ -+char * -+DoScaleNDialog() -+{ -+ Widget pshell, dialog; -+ char *scaleNValue; -+ char *valueString; -+ -+ pshell = XtVaCreatePopupShell("scaleNDialog", transientShellWidgetClass, -+ toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ -+ dialog_over(pshell); -+ wm_delete(pshell, "ScaleNDialogDone()"); -+ -+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+ dialog_input(pshell); -+ wm_delete(pshell, "ScaleNDialogDone()"); -+ -+ scaleNDialogDone = False; -+ -+ while (!scaleNDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ scaleNValue = XtNewString(valueString); -+ -+ XtPopdown(pshell); -+ return scaleNValue; -+} -+ -+void -+QualityDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ qualityDialogDone = True; -+ if (w || event || params || num_params) {} -+} -+ -+char * -+DoQualityDialog() -+{ -+ Widget pshell, dialog; -+ char *qualityValue; -+ char *valueString; -+ -+ pshell = XtVaCreatePopupShell("qualityDialog", transientShellWidgetClass, -+ toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ -+ dialog_over(pshell); -+ -+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (1 && appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+ dialog_input(pshell); -+ wm_delete(pshell, "QualityDialogDone() HideQuality()"); -+ -+ qualityDialogDone = False; -+ -+ while (!qualityDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ qualityValue = XtNewString(valueString); -+ -+ XtPopdown(pshell); -+ return qualityValue; -+} -+ -+void -+CompressDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ compressDialogDone = True; -+ if (w || event || params || num_params) {} -+} -+ -+char * -+DoCompressDialog() -+{ -+ Widget pshell, dialog; -+ char *compressValue; -+ char *valueString; -+ -+ fprintf(stderr, "compress start:\n"); -+ -+ pshell = XtVaCreatePopupShell("compressDialog", transientShellWidgetClass, -+ toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ -+ dialog_over(pshell); -+ -+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (1 && appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+ dialog_input(pshell); -+ wm_delete(pshell, "CompressDialogDone() HideCompress()"); -+ -+ compressDialogDone = False; -+ -+ while (!compressDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ compressValue = XtNewString(valueString); -+ -+ fprintf(stderr, "compress done: %s\n", compressValue); -+ -+ XtPopdown(pshell); -+ return compressValue; -+} - - void - ServerDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) - { -- serverDialogDone = True; -+ serverDialogDone = True; -+ if (w || event || params || num_params) {} - } - - char * - DoServerDialog() - { -- Widget pshell, dialog; -- char *vncServerName; -- char *valueString; -+ Widget pshell, dialog; -+ char *vncServerName; -+ char *valueString; - -- pshell = XtVaCreatePopupShell("serverDialog", transientShellWidgetClass, -+ pshell = XtVaCreatePopupShell("serverDialog", transientShellWidgetClass, - toplevel, NULL); -- dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); - -- XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -- HeightOfScreen(XtScreen(pshell))*2/5); -- XtPopup(pshell, XtGrabNonexclusive); -- XtRealizeWidget(pshell); -+ dialog_over(pshell); - -- serverDialogDone = False; -+ if (0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (0 && appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+#if 0 -+ dialog_input(pshell); -+#endif -+ wm_delete(pshell, "ServerDialogDone()"); -+ -+ serverDialogDone = False; -+ -+ while (!serverDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ vncServerName = XtNewString(valueString); - -- while (!serverDialogDone) { -- XtAppProcessEvent(appContext, XtIMAll); -- } -+ XtPopdown(pshell); -+ return vncServerName; -+} - -- valueString = XawDialogGetValueString(dialog); -- vncServerName = XtNewString(valueString); -+void -+UserDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ userDialogDone = True; -+ if (w || event || params || num_params) {} -+} - -- XtPopdown(pshell); -- return vncServerName; -+char * -+DoUserDialog() -+{ -+ Widget pshell, dialog; -+ char *userName; -+ char *valueString; -+ -+ pshell = XtVaCreatePopupShell("userDialog", transientShellWidgetClass, -+ toplevel, NULL); -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -+ -+ dialog_over(pshell); -+ -+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (0 && appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+#if 0 -+ dialog_input(pshell); -+#endif -+ wm_delete(pshell, "UserDialogDone()"); -+ -+ userDialogDone = False; -+ -+ while (!userDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ userName = XtNewString(valueString); -+ -+ XtPopdown(pshell); -+ return userName; - } - - void --PasswordDialogDone(Widget w, XEvent *event, String *params, -- Cardinal *num_params) -+PasswordDialogDone(Widget w, XEvent *event, String *params, Cardinal *num_params) - { -- passwordDialogDone = True; -+ passwordDialogDone = True; -+ if (w || event || params || num_params) {} - } - - char * - DoPasswordDialog() - { -- Widget pshell, dialog; -- char *password; -- char *valueString; -+ Widget pshell, dialog; -+ char *password; -+ char *valueString; - -- pshell = XtVaCreatePopupShell("passwordDialog", transientShellWidgetClass, -+ pshell = XtVaCreatePopupShell("passwordDialog", transientShellWidgetClass, - toplevel, NULL); -- dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); -- -- XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, -- HeightOfScreen(XtScreen(pshell))*2/5); -- XtPopup(pshell, XtGrabNonexclusive); -- XtRealizeWidget(pshell); -- -- passwordDialogDone = False; -+ dialog = XtVaCreateManagedWidget("dialog", dialogWidgetClass, pshell, NULL); - -- while (!passwordDialogDone) { -- XtAppProcessEvent(appContext, XtIMAll); -- } -+ dialog_over(pshell); - -- valueString = XawDialogGetValueString(dialog); -- password = XtNewString(valueString); -+ if(0) XtMoveWidget(pshell, WidthOfScreen(XtScreen(pshell))*2/5, HeightOfScreen(XtScreen(pshell))*2/5); -+ XtPopup(pshell, XtGrabNonexclusive); -+ XtRealizeWidget(pshell); -+ -+ if (0 && appData.popupFix) { -+ popupFixer(pshell); -+ } else { -+ xtmove(pshell); -+ } -+#if 0 -+ dialog_input(pshell); -+#endif -+ wm_delete(pshell, "PasswordDialogDone()"); -+ -+ passwordDialogDone = False; -+ -+ while (!passwordDialogDone) { -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ -+ valueString = XawDialogGetValueString(dialog); -+ rmNL(valueString); -+ password = XtNewString(valueString); - -- XtPopdown(pshell); -- return password; -+ XtPopdown(pshell); -+ return password; - } -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/fullscreen.c vnc_unixsrc/vncviewer/fullscreen.c ---- vnc_unixsrc.orig/vncviewer/fullscreen.c 2003-10-09 05:23:49.000000000 -0400 -+++ vnc_unixsrc/vncviewer/fullscreen.c 2010-02-25 22:37:49.000000000 -0500 -@@ -22,20 +22,24 @@ - */ - - #include <vncviewer.h> -+#include <time.h> - #include <X11/Xaw/Form.h> - #include <X11/Xaw/Viewport.h> - #include <X11/Xaw/Toggle.h> - - static Bool DoBumpScroll(); -+static Bool DoJumpScroll(); - static void BumpScrollTimerCallback(XtPointer clientData, XtIntervalId *id); -+static void JumpScrollTimerCallback(XtPointer clientData, XtIntervalId *id); - static XtIntervalId timer; - static Bool timerSet = False; - static Bool scrollLeft, scrollRight, scrollUp, scrollDown; --static Position desktopX, desktopY; -+Position desktopX, desktopY; - static Dimension viewportWidth, viewportHeight; - static Dimension scrollbarWidth, scrollbarHeight; - - -+int scale_round(int len, double fac); - - /* - * FullScreenOn goes into full-screen mode. It makes the toplevel window -@@ -78,112 +82,456 @@ - * variables so that FullScreenOff can use them. - */ - --void --FullScreenOn() --{ -- Dimension toplevelWidth, toplevelHeight; -- Dimension oldViewportWidth, oldViewportHeight, clipWidth, clipHeight; -- Position viewportX, viewportY; -- -- appData.fullScreen = True; -- -- if (si.framebufferWidth > dpyWidth || si.framebufferHeight > dpyHeight) { -- -- XtVaSetValues(viewport, XtNforceBars, True, NULL); -- XtVaGetValues(viewport, XtNwidth, &oldViewportWidth, -- XtNheight, &oldViewportHeight, NULL); -- XtVaGetValues(XtNameToWidget(viewport, "clip"), -- XtNwidth, &clipWidth, XtNheight, &clipHeight, NULL); -- -- scrollbarWidth = oldViewportWidth - clipWidth; -- scrollbarHeight = oldViewportHeight - clipHeight; -- -- if (si.framebufferWidth > dpyWidth) { -- viewportWidth = toplevelWidth = dpyWidth + scrollbarWidth; -- } else { -- viewportWidth = si.framebufferWidth + scrollbarWidth; -- toplevelWidth = dpyWidth; -- } -- -- if (si.framebufferHeight > dpyHeight) { -- viewportHeight = toplevelHeight = dpyHeight + scrollbarHeight; -- } else { -- viewportHeight = si.framebufferHeight + scrollbarHeight; -- toplevelHeight = dpyHeight; -- } -- -- } else { -- viewportWidth = si.framebufferWidth; -- viewportHeight = si.framebufferHeight; -- toplevelWidth = dpyWidth; -- toplevelHeight = dpyHeight; -- } -+int net_wm_supported(void) { -+ unsigned char *data; -+ unsigned long items_read, items_left, i; -+ int ret, format; -+ Window wm; -+ Atom type; -+ Atom _NET_SUPPORTING_WM_CHECK; -+ Atom _NET_SUPPORTED; -+ Atom _NET_WM_STATE; -+ Atom _NET_WM_STATE_FULLSCREEN; -+ -+ static time_t last_check = 0; -+ static int fs_supported = -1; -+ -+ if (fs_supported >= 0 && time(NULL) < last_check + 600) { -+ static int first = 1; -+ if (first) { -+ fprintf(stderr, "fs_supported: %d\n", fs_supported); -+ } -+ first = 0; -+ return fs_supported; -+ } -+ last_check = time(NULL); -+ -+ fs_supported = 0; -+ -+ _NET_SUPPORTING_WM_CHECK = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); -+ _NET_SUPPORTED = XInternAtom(dpy, "_NET_SUPPORTED", False); -+ _NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False); -+ _NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); -+ -+ ret = XGetWindowProperty(dpy, DefaultRootWindow(dpy), _NET_SUPPORTING_WM_CHECK, -+ 0L, 1L, False, XA_WINDOW, &type, &format, &items_read, &items_left, &data); -+ -+ if (ret != Success || !items_read) { -+ if (ret == Success) { -+ XFree(data); -+ } -+ return fs_supported; -+ } -+ -+ wm = ((Window*) data)[0]; -+ XFree(data); -+ -+ ret = XGetWindowProperty(dpy, wm, _NET_SUPPORTING_WM_CHECK, -+ 0L, 1L, False, XA_WINDOW, &type, &format, &items_read, &items_left, &data); -+ -+ if (ret != Success || !items_read) { -+ if (ret == Success) { -+ XFree(data); -+ } -+ return fs_supported; -+ } -+ -+ if (wm != ((Window*) data)[0]) { -+ XFree(data); -+ return fs_supported; -+ } -+ -+ ret = XGetWindowProperty(dpy, DefaultRootWindow(dpy), _NET_SUPPORTED, -+ 0L, 8192L, False, XA_ATOM, &type, &format, &items_read, &items_left, &data); -+ -+ if (ret != Success || !items_read) { -+ if (ret == Success) { -+ XFree(data); -+ } -+ return fs_supported; -+ } -+ -+ for (i=0; i < items_read; i++) { -+ if ( ((Atom*) data)[i] == _NET_WM_STATE_FULLSCREEN) { -+ fs_supported = 1; -+ } -+ } -+ XFree(data); - -- viewportX = (toplevelWidth - viewportWidth) / 2; -- viewportY = (toplevelHeight - viewportHeight) / 2; -+ return fs_supported; -+} - -+static void net_wm_fullscreen(int to_fs) { -+ -+ int _NET_WM_STATE_REMOVE = 0; -+ int _NET_WM_STATE_ADD = 1; -+#if 0 -+ int _NET_WM_STATE_TOGGLE = 2; -+#endif -+ Atom _NET_WM_STATE = XInternAtom(dpy, "_NET_WM_STATE", False); -+ Atom _NET_WM_STATE_FULLSCREEN = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); -+ XEvent xev; -+ -+ if (to_fs == 2) { -+ XChangeProperty(dpy, XtWindow(toplevel), _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char*)&_NET_WM_STATE_FULLSCREEN, 1); -+ } else { -+ xev.xclient.type = ClientMessage; -+ xev.xclient.window = XtWindow(toplevel); -+ xev.xclient.message_type = _NET_WM_STATE; -+ xev.xclient.serial = 0; -+ xev.xclient.display = dpy; -+ xev.xclient.send_event = True; -+ xev.xclient.format = 32; -+ xev.xclient.data.l[0] = to_fs ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; -+ xev.xclient.data.l[1] = _NET_WM_STATE_FULLSCREEN; -+ xev.xclient.data.l[2] = 0; -+ xev.xclient.data.l[3] = 0; -+ xev.xclient.data.l[4] = 0; -+ XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); -+ } - -- /* We want to stop the window manager from managing our toplevel window. -- This is not really a nice thing to do, so may not work properly with every -- window manager. We do this simply by setting overrideRedirect and -- reparenting our window to the root. The window manager will get a -- ReparentNotify and hopefully clean up its frame window. */ -+ XSync(dpy, False); -+} - -- XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL); -+time_t main_grab = 0; - -- XReparentWindow(dpy, XtWindow(toplevel), DefaultRootWindow(dpy), 0, 0); -+void fs_ungrab(int check) { -+ if (check) { -+ if (time(NULL) <= main_grab + 2) { -+ return; -+ } -+ if (net_wm_supported()) { -+ return; -+ } -+ } -+ fprintf(stderr, "calling fs_ungrab()\n"); -+ if (appData.grabAll) { /* runge top of FullScreenOff */ -+ fprintf(stderr, "calling XUngrabServer(dpy)\n"); -+ XUngrabServer(dpy); -+ } -+ if (appData.grabKeyboard) { -+ fprintf(stderr, "calling XUngrabKeyboard(dpy)\n"); -+ XtUngrabKeyboard(desktop, CurrentTime); -+ } -+} - -- /* Some WMs does not obey x,y values of XReparentWindow; the window -- is not placed in the upper, left corner. The code below fixes -- this: It manually moves the window, after the Xserver is done -- with XReparentWindow. The last XSync seems to prevent losing -- focus, but I don't know why. */ -- XSync(dpy, False); -- XMoveWindow(dpy, XtWindow(toplevel), 0, 0); -- XSync(dpy, False); -- -- /* Now we want to fix the size of "viewport". We shouldn't just change it -- directly. Instead we set "toplevel" to the required size (which should -- propagate through "form" to "viewport"). Then we remove "viewport" from -- being managed by "form", change its resources to position it and make sure -- that "form" won't attempt to resize it, then ask "form" to manage it -- again. */ -- -- XtResizeWidget(toplevel, viewportWidth, viewportHeight, 0); -- -- XtUnmanageChild(viewport); -- -- XtVaSetValues(viewport, -- XtNhorizDistance, viewportX, -- XtNvertDistance, viewportY, -- XtNleft, XtChainLeft, -- XtNright, XtChainLeft, -- XtNtop, XtChainTop, -- XtNbottom, XtChainTop, -- NULL); -+void fs_grab(int check) { -+ if (check) { -+ if (time(NULL) <= main_grab + 2) { -+ return; -+ } -+ if (net_wm_supported()) { -+ return; -+ } -+ } -+ -+ main_grab = time(NULL); -+ -+ fprintf(stderr, "calling fs_grab()\n"); -+ -+#define FORCE_UP \ -+ XSync(dpy, False); \ -+ XUnmapWindow(dpy, XtWindow(toplevel)); \ -+ XSync(dpy, False); \ -+ XMapWindow(dpy, XtWindow(toplevel)); \ -+ XRaiseWindow(dpy, XtWindow(toplevel)); \ -+ XSync(dpy, False); -+ -+ if (appData.grabKeyboard && XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) { -+ fprintf(stderr, "XtGrabKeyboard() failed.\n"); -+ XSync(dpy, False); -+ usleep(100 * 1000); -+ FORCE_UP -+ -+ if (XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) { -+ fprintf(stderr, "XtGrabKeyboard() failed again.\n"); -+ usleep(200 * 1000); -+ XSync(dpy, False); -+ if (XtGrabKeyboard(desktop, True, GrabModeAsync, GrabModeAsync, CurrentTime) != GrabSuccess) { -+ fprintf(stderr, "XtGrabKeyboard() failed 3rd time.\n"); -+ } else { -+ fprintf(stderr, "XtGrabKeyboard() OK 3rd try.\n"); -+ } -+ } else { -+ fprintf(stderr, "XtGrabKeyboard() OK 2nd try.\n"); -+ } -+ XRaiseWindow(dpy, XtWindow(toplevel)); -+ } -+ -+ if (appData.grabAll) { -+ fprintf(stderr, "calling XGrabServer(dpy)\n"); -+ if (! XGrabServer(dpy)) { -+ XSync(dpy, False); -+ usleep(100 * 1000); -+ fprintf(stderr, "calling XGrabServer(dpy) 2nd time\n"); -+ if (!XGrabServer(dpy)) { -+ XSync(dpy, False); -+ usleep(200 * 1000); -+ fprintf(stderr, "calling XGrabServer(dpy) 3rd time\n"); -+ if (XGrabServer(dpy)) { -+ fprintf(stderr, "XGrabServer(dpy) OK 3rd time\n"); -+ } -+ } else { -+ fprintf(stderr, "XGrabServer(dpy) OK 2nd time\n"); -+ } -+ XSync(dpy, False); -+ } -+ if (getenv("VNCVIEWER_FORCE_UP")) { -+ fprintf(stderr, "FORCE_UP\n"); -+ FORCE_UP -+ } -+ } -+} -+ -+extern int fullscreen_startup; -+extern double last_fullscreen; -+ -+#define set_size_hints() \ -+{ \ -+ long supplied; \ -+ XSizeHints *sizehints = XAllocSizeHints(); \ -+ XGetWMSizeHints(dpy, topwin, sizehints, &supplied, XA_WM_NORMAL_HINTS); \ -+ if (sizehints->base_width < toplevelWidth) { \ -+ sizehints->base_width = toplevelWidth; \ -+ } \ -+ if (sizehints->base_height < toplevelHeight) { \ -+ sizehints->base_height = toplevelHeight; \ -+ } \ -+ if (sizehints->max_width < toplevelWidth) { \ -+ sizehints->max_width = toplevelWidth; \ -+ } \ -+ if (sizehints->max_height < toplevelHeight) { \ -+ sizehints->max_height = toplevelHeight; \ -+ } \ -+ XSetWMSizeHints(dpy, topwin, sizehints, XA_WM_NORMAL_HINTS); \ -+ XFree(sizehints); \ -+} - -- XtManageChild(viewport); -+extern int scale_x, scale_y; -+extern double scale_factor_y; -+ -+void -+FullScreenOn() -+{ -+ Dimension toplevelWidth, toplevelHeight; -+ Dimension oldViewportWidth, oldViewportHeight, clipWidth, clipHeight; -+ Position viewportX, viewportY; -+ int do_net_wm = net_wm_supported(); -+ int fbW = si.framebufferWidth; -+ int fbH = si.framebufferHeight; -+ int eff_height; -+ -+ Bool fsAlready = appData.fullScreen, toobig = False; -+ Window topwin = XtWindow(toplevel); -+ -+ appData.fullScreen = True; -+ -+ last_fullscreen = dnow(); -+ -+ if (scale_x > 0) { -+ fbW = scale_x; -+ fbH = scale_y; -+ } -+ -+ eff_height = fbH; -+ if (appData.yCrop > 0) { -+ eff_height = appData.yCrop; -+ if (scale_y > 0) { -+ eff_height = scale_round(eff_height, scale_factor_y); -+ } -+ } -+ -+ if (fbW > dpyWidth || eff_height > dpyHeight) { -+ -+ toobig = True; -+ -+ /* -+ * This is a crazy thing to have the scrollbars hang -+ * just a bit offscreen to the right and below. the user -+ * will not see them and bumpscroll will work. -+ */ -+ -+ XtVaSetValues(viewport, XtNforceBars, True, NULL); -+ XtVaGetValues(viewport, XtNwidth, &oldViewportWidth, XtNheight, &oldViewportHeight, NULL); -+ XtVaGetValues(XtNameToWidget(viewport, "clip"), XtNwidth, &clipWidth, XtNheight, &clipHeight, NULL); -+ -+ scrollbarWidth = oldViewportWidth - clipWidth; -+ scrollbarHeight = oldViewportHeight - clipHeight; -+ -+ if (fbW > dpyWidth) { -+ viewportWidth = toplevelWidth = dpyWidth + scrollbarWidth; -+ } else { -+ viewportWidth = fbW + scrollbarWidth; -+ toplevelWidth = dpyWidth; -+ } -+ -+ if (eff_height > dpyHeight) { -+ viewportHeight = toplevelHeight = dpyHeight + scrollbarHeight; -+ } else { -+ viewportHeight = eff_height + scrollbarHeight; -+ toplevelHeight = dpyHeight; -+ } -+ if (do_net_wm) { -+ /* but for _NET_WM we make toplevel be correct dpy size */ -+ toplevelWidth = dpyWidth; -+ toplevelHeight = dpyHeight; -+ } -+ -+ } else { -+ viewportWidth = fbW; -+ viewportHeight = eff_height; -+ toplevelWidth = dpyWidth; -+ toplevelHeight = dpyHeight; -+ } - -- /* Now we can set "toplevel" to its proper size. */ -+ viewportX = (toplevelWidth - viewportWidth) / 2; -+ viewportY = (toplevelHeight - viewportHeight) / 2; - -- XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0); -+ if (viewportX < 0) viewportX = 0; -+ if (viewportY < 0) viewportY = 0; - -- /* Set the popup to overrideRedirect too */ - -- XtVaSetValues(popup, XtNoverrideRedirect, True, NULL); -+ /* We want to stop the window manager from managing our toplevel window. -+ This is not really a nice thing to do, so may not work properly with every -+ window manager. We do this simply by setting overrideRedirect and -+ reparenting our window to the root. The window manager will get a -+ ReparentNotify and hopefully clean up its frame window. */ - -- /* Try to get the input focus. */ -+ if (! fsAlready) { -+ if (!do_net_wm) { -+ /* added to try to raise it on top for some cirumstances */ -+ XUnmapWindow(dpy, topwin); -+ -+ XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL); -+#if 0 -+ XtVaSetValues(viewport, XtNoverrideRedirect, True, NULL); -+ XtVaSetValues(desktop, XtNoverrideRedirect, True, NULL); -+#endif -+ XtVaSetValues(popup, XtNoverrideRedirect, True, NULL); -+ -+ XReparentWindow(dpy, topwin, DefaultRootWindow(dpy), 0, 0); -+ -+ /* Some WMs does not obey x,y values of XReparentWindow; the window -+ is not placed in the upper, left corner. The code below fixes -+ this: It manually moves the window, after the Xserver is done -+ with XReparentWindow. The last XSync seems to prevent losing -+ focus, but I don't know why. */ -+ -+ XSync(dpy, False); -+ -+ /* added to try to raise it on top for some cirumstances */ -+ XMapRaised(dpy, topwin); -+ -+ XMoveWindow(dpy, topwin, 0, 0); -+ XSync(dpy, False); -+ } -+ -+ /* Now we want to fix the size of "viewport". We shouldn't just change it -+ directly. Instead we set "toplevel" to the required size (which should -+ propagate through "form" to "viewport"). Then we remove "viewport" from -+ being managed by "form", change its resources to position it and make sure -+ that "form" won't attempt to resize it, then ask "form" to manage it -+ again. */ -+ -+ XtResizeWidget(toplevel, viewportWidth, viewportHeight, 0); -+ -+ XtUnmanageChild(viewport); -+ -+ XtVaSetValues(viewport, -+ XtNhorizDistance, viewportX, -+ XtNvertDistance, viewportY, -+ XtNleft, XtChainLeft, -+ XtNright, XtChainLeft, -+ XtNtop, XtChainTop, -+ XtNbottom, XtChainTop, -+ NULL); -+ -+ XtManageChild(viewport); -+ XSync(dpy, False); -+ } else { -+ XSync(dpy, False); -+ } -+ -+ /* Now we can set "toplevel" to its proper size. */ -+ -+#if 0 -+ XtVaSetValues(toplevel, XtNwidth, toplevelWidth, XtNheight, toplevelHeight, NULL); -+ XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0); -+#endif -+ XResizeWindow(dpy, topwin, toplevelWidth, toplevelHeight); -+ -+ if (do_net_wm) { -+ XWindowAttributes attr; -+ int ok = 0, i, delay = 20; -+ -+ usleep(delay * 1000); -+ -+#define GSIZE() \ -+ XGetWindowAttributes(dpy, topwin, &attr); -+ -+#define PSIZE(s) \ -+ XSync(dpy, False); \ -+ XGetWindowAttributes(dpy, topwin, &attr); \ -+ fprintf(stderr, "%s %dx%d+%d+%d\n", s, attr.width, attr.height, attr.x, attr.y); -+ -+ PSIZE("size-A:"); -+ -+ set_size_hints(); -+ -+ net_wm_fullscreen(1); -+ -+ PSIZE("size-B:"); -+ -+ for (i=0; i < 30; i++) { -+ usleep(delay * 1000); -+ GSIZE(); -+ fprintf(stderr, "size[%d] %dx%d+%d+%d\n", i, attr.width, attr.height, attr.x, attr.y); -+ if (attr.width == toplevelWidth && attr.height == toplevelHeight) { -+ ok = 1; -+ fprintf(stderr, "size ok.\n"); -+ XSync(dpy, False); -+ break; -+ } -+ set_size_hints(); -+ XResizeWindow(dpy, topwin, toplevelWidth, toplevelHeight); -+ XMoveWindow(dpy, topwin, 0, 0); -+ XSync(dpy, False); -+ } -+ -+ PSIZE("size-C:"); -+ } -+ -+ fprintf(stderr, "\ntoplevel: %dx%d viewport: %dx%d\n", toplevelWidth, toplevelHeight, viewportWidth, viewportHeight); -+ -+#if defined (__SVR4) && defined (__sun) -+ if (!do_net_wm) { -+ /* CDE */ -+ XSync(dpy, False); -+ usleep(200 * 1000); -+ XMoveWindow(dpy, topwin, 0, 0); -+ XMapRaised(dpy, topwin); -+ XSync(dpy, False); -+ } -+#endif -+ -+ if (fsAlready) { -+ XtResizeWidget(viewport, viewportWidth, viewportHeight, 0); -+ if (! toobig) { -+ XtVaSetValues(viewport, XtNforceBars, False, NULL); -+ } -+ XMoveWindow(dpy, topwin, viewportX, viewportY); -+ XSync(dpy, False); -+ } -+ -+ /* Try to get the input focus. */ - -- XSetInputFocus(dpy, DefaultRootWindow(dpy), RevertToPointerRoot, -- CurrentTime); -+ /* original vnc: DefaultRootWindow(dpy) instead of PointerRoot */ -+ XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - -- /* Optionally, grab the keyboard. */ -+ /* Optionally, grab the keyboard. */ -+ fs_grab(0); - -- if (appData.grabKeyboard && -- XtGrabKeyboard(desktop, True, GrabModeAsync, -- GrabModeAsync, CurrentTime) != GrabSuccess) { -- fprintf(stderr, "XtGrabKeyboard() failed.\n"); -- } -+ /* finally done. */ - } - - -@@ -205,28 +553,52 @@ - void - FullScreenOff() - { -- int toplevelWidth = si.framebufferWidth; -- int toplevelHeight = si.framebufferHeight; -- -- appData.fullScreen = False; -+ int toplevelWidth, toplevelHeight; -+ int do_net_wm = net_wm_supported(); -+ int fbW = si.framebufferWidth; -+ int fbH = si.framebufferHeight; -+ int eff_height; -+ -+ appData.fullScreen = False; -+ -+ last_fullscreen = dnow(); -+ -+ if (scale_x > 0) { -+ fbW = scale_x; -+ fbH = scale_y; -+ } -+ -+ eff_height = fbH; -+ if (appData.yCrop > 0) { -+ eff_height = appData.yCrop; -+ if (scale_y > 0) { -+ eff_height = scale_round(eff_height, scale_factor_y); -+ } -+ } -+ -+ toplevelWidth = fbW; -+ toplevelHeight = eff_height; -+ -+ fs_ungrab(0); -+ -+ if (do_net_wm) { -+ net_wm_fullscreen(0); -+ } else { -+ XtUnmapWidget(toplevel); -+ } - -- if (appData.grabKeyboard) -- XtUngrabKeyboard(desktop, CurrentTime); -- -- XtUnmapWidget(toplevel); -- -- XtResizeWidget(toplevel, -+ XtResizeWidget(toplevel, - viewportWidth - scrollbarWidth, - viewportHeight - scrollbarHeight, 0); -- XtResizeWidget(viewport, -+ XtResizeWidget(viewport, - viewportWidth - scrollbarWidth, - viewportHeight - scrollbarHeight, 0); - -- XtVaSetValues(viewport, XtNforceBars, False, NULL); -+ XtVaSetValues(viewport, XtNforceBars, False, NULL); - -- XtUnmanageChild(viewport); -+ XtUnmanageChild(viewport); - -- XtVaSetValues(viewport, -+ XtVaSetValues(viewport, - XtNhorizDistance, 0, - XtNvertDistance, 0, - XtNleft, XtChainLeft, -@@ -235,24 +607,42 @@ - XtNbottom, XtChainBottom, - NULL); - -- XtManageChild(viewport); -- -- XtVaSetValues(toplevel, XtNoverrideRedirect, False, NULL); -- -- if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth) -- toplevelWidth = dpyWidth - appData.wmDecorationWidth; -- -- if ((toplevelHeight + appData.wmDecorationHeight) >= dpyHeight) -- toplevelHeight = dpyHeight - appData.wmDecorationHeight; -- -- XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0); -- -- XtMapWidget(toplevel); -- XSync(dpy, False); -+ XtManageChild(viewport); - -- /* Set the popup back to non-overrideRedirect */ -- -- XtVaSetValues(popup, XtNoverrideRedirect, False, NULL); -+ if (!do_net_wm) { -+ XtVaSetValues(toplevel, XtNoverrideRedirect, False, NULL); -+#if 0 -+ XtVaSetValues(viewport, XtNoverrideRedirect, False, NULL); -+ XtVaSetValues(desktop, XtNoverrideRedirect, False, NULL); -+#endif -+ XtVaSetValues(popup, XtNoverrideRedirect, False, NULL); -+ } -+ -+ if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth) -+ toplevelWidth = dpyWidth - appData.wmDecorationWidth; -+ -+ if ((toplevelHeight + appData.wmDecorationHeight) >= dpyHeight) -+ toplevelHeight = dpyHeight - appData.wmDecorationHeight; -+ -+ XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0); -+ -+ if (!do_net_wm) { -+ XtMapWidget(toplevel); -+ } -+ XSync(dpy, False); -+ -+ /* Set the popup back to non-overrideRedirect */ -+ -+ XtVaSetValues(popup, XtNoverrideRedirect, False, NULL); -+ -+ if (!do_net_wm) { -+ int x = (dpyWidth - toplevelWidth) / 2; -+ int y = (dpyHeight - toplevelHeight) / 2; -+ if (x > 0 && y > 0) { -+ XSync(dpy, False); -+ XMoveWindow(dpy, XtWindow(toplevel), x, y); -+ } -+ } - } - - -@@ -264,10 +654,12 @@ - void - SetFullScreenState(Widget w, XEvent *ev, String *params, Cardinal *num_params) - { -- if (appData.fullScreen) -- XtVaSetValues(w, XtNstate, True, NULL); -- else -- XtVaSetValues(w, XtNstate, False, NULL); -+ if (appData.fullScreen) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} - } - - -@@ -278,11 +670,12 @@ - void - ToggleFullScreen(Widget w, XEvent *ev, String *params, Cardinal *num_params) - { -- if (appData.fullScreen) { -- FullScreenOff(); -- } else { -- FullScreenOn(); -- } -+ if (appData.fullScreen) { -+ FullScreenOff(); -+ } else { -+ FullScreenOn(); -+ } -+ if (w || ev || params || num_params) {} - } - - -@@ -294,84 +687,226 @@ - Bool - BumpScroll(XEvent *ev) - { -- scrollLeft = scrollRight = scrollUp = scrollDown = False; -+ scrollLeft = scrollRight = scrollUp = scrollDown = False; - -- if (ev->xmotion.x_root >= dpyWidth - 3) -- scrollRight = True; -- else if (ev->xmotion.x_root <= 2) -- scrollLeft = True; -- -- if (ev->xmotion.y_root >= dpyHeight - 3) -- scrollDown = True; -- else if (ev->xmotion.y_root <= 2) -- scrollUp = True; -- -- if (scrollLeft || scrollRight || scrollUp || scrollDown) { -- if (timerSet) -- return True; -- -- XtVaGetValues(desktop, XtNx, &desktopX, XtNy, &desktopY, NULL); -- desktopX = -desktopX; -- desktopY = -desktopY; -- -- return DoBumpScroll(); -- } -- -- if (timerSet) { -- XtRemoveTimeOut(timer); -- timerSet = False; -- } -+ if (ev->xmotion.x_root >= dpyWidth - 3) -+ scrollRight = True; -+ else if (ev->xmotion.x_root <= 2) -+ scrollLeft = True; -+ -+ if (ev->xmotion.y_root >= dpyHeight - 3) -+ scrollDown = True; -+ else if (ev->xmotion.y_root <= 2) -+ scrollUp = True; -+ -+ if (scrollLeft || scrollRight || scrollUp || scrollDown) { -+ if (timerSet) -+ return True; -+ -+ XtVaGetValues(desktop, XtNx, &desktopX, XtNy, &desktopY, NULL); -+ desktopX = -desktopX; -+ desktopY = -desktopY; -+ -+ return DoBumpScroll(); -+ } -+ -+ if (timerSet) { -+ XtRemoveTimeOut(timer); -+ timerSet = False; -+ } - -- return False; -+ return False; - } - - static Bool - DoBumpScroll() - { -- int oldx = desktopX, oldy = desktopY; -- -- if (scrollRight) { -- if (desktopX < si.framebufferWidth - dpyWidth) { -- desktopX += appData.bumpScrollPixels; -- if (desktopX > si.framebufferWidth - dpyWidth) -- desktopX = si.framebufferWidth - dpyWidth; -- } -- } else if (scrollLeft) { -- if (desktopX > 0) { -- desktopX -= appData.bumpScrollPixels; -- if (desktopX < 0) -- desktopX = 0; -- } -- } -- -- if (scrollDown) { -- if (desktopY < si.framebufferHeight - dpyHeight) { -- desktopY += appData.bumpScrollPixels; -- if (desktopY > si.framebufferHeight - dpyHeight) -- desktopY = si.framebufferHeight - dpyHeight; -- } -- } else if (scrollUp) { -- if (desktopY > 0) { -- desktopY -= appData.bumpScrollPixels; -- if (desktopY < 0) -- desktopY = 0; -- } -- } -- -- if (oldx != desktopX || oldy != desktopY) { -- XawViewportSetCoordinates(viewport, desktopX, desktopY); -- timer = XtAppAddTimeOut(appContext, appData.bumpScrollTime, -- BumpScrollTimerCallback, NULL); -- timerSet = True; -- return True; -- } -+ int oldx = desktopX, oldy = desktopY; -+ int fbW = si.framebufferWidth; -+ int fbH = si.framebufferHeight; -+ -+ if (scale_x > 0) { -+ fbW = scale_x; -+ fbH = scale_y; -+ } -+ -+ if (scrollRight) { -+ if (desktopX < fbW - dpyWidth) { -+ desktopX += appData.bumpScrollPixels; -+ if (desktopX > fbW - dpyWidth) { -+ desktopX = fbW - dpyWidth; -+ } -+ } -+ } else if (scrollLeft) { -+ if (desktopX > 0) { -+ desktopX -= appData.bumpScrollPixels; -+ if (desktopX < 0) { -+ desktopX = 0; -+ } -+ } -+ } -+ -+ if (scrollDown) { -+ int ycrop = appData.yCrop; -+ if (scale_y > 0) { -+ ycrop = scale_round(ycrop, scale_factor_y); -+ } -+ if (ycrop > 0 && desktopY + dpyHeight >= ycrop) { -+ ; -+ } else if (desktopY < fbH - dpyHeight) { -+ desktopY += appData.bumpScrollPixels; -+ if (desktopY > fbH - dpyHeight) { -+ desktopY = fbH - dpyHeight; -+ } -+ } -+ } else if (scrollUp) { -+ if (desktopY > 0) { -+ desktopY -= appData.bumpScrollPixels; -+ if (desktopY < 0) { -+ desktopY = 0; -+ } -+ } -+ } -+ -+ if (oldx != desktopX || oldy != desktopY) { -+ XawViewportSetCoordinates(viewport, desktopX, desktopY); -+ timer = XtAppAddTimeOut(appContext, appData.bumpScrollTime, BumpScrollTimerCallback, NULL); -+ timerSet = True; -+ return True; -+ } - -- timerSet = False; -- return False; -+ timerSet = False; -+ return False; - } - - static void - BumpScrollTimerCallback(XtPointer clientData, XtIntervalId *id) - { -- DoBumpScroll(); -+ DoBumpScroll(); -+ if (clientData || id) {} -+} -+ -+/* not working: */ -+ -+Bool -+JumpScroll(int up, int vert) { -+ scrollLeft = scrollRight = scrollUp = scrollDown = False; -+ -+ -+ if (appData.fullScreen) { -+ return True; -+ } -+ fprintf(stderr, "JumpScroll(%d, %d)\n", up, vert); -+ -+ if (vert) { -+ if (up) { -+ scrollUp = True; -+ } else { -+ scrollDown = True; -+ } -+ } else { -+ if (up) { -+ scrollRight = True; -+ } else { -+ scrollLeft = True; -+ } -+ } -+ -+ if (scrollLeft || scrollRight || scrollUp || scrollDown) { -+ if (timerSet) { -+ return True; -+ } -+ -+ XtVaGetValues(desktop, XtNx, &desktopX, XtNy, &desktopY, NULL); -+ desktopX = -desktopX; -+ desktopY = -desktopY; -+ return DoJumpScroll(); -+ } -+ -+ if (timerSet) { -+ XtRemoveTimeOut(timer); -+ timerSet = False; -+ } -+ -+ return False; -+} -+ -+static Bool -+DoJumpScroll() { -+ int oldx = desktopX, oldy = desktopY; -+ int jumpH, jumpV; -+ int fbW = si.framebufferWidth; -+ int fbH = si.framebufferHeight; -+ -+ if (scale_x > 0) { -+ fbW = scale_x; -+ fbH = scale_y; -+ } -+ jumpH = fbW / 4; -+ jumpV = fbH / 4; -+ -+ if (scrollRight) { -+ if (desktopX < fbW - dpyWidth) { -+ desktopX += jumpH; -+ if (desktopX > fbW - dpyWidth) -+ desktopX = fbW - dpyWidth; -+ } -+ } else if (scrollLeft) { -+ if (desktopX > 0) { -+ desktopX -= jumpH; -+ if (desktopX < 0) -+ desktopX = 0; -+ } -+ } -+ -+ if (scrollDown) { -+ if (appData.yCrop > 0 && desktopY + dpyHeight >= appData.yCrop) { -+ ; -+ } else if (desktopY < fbH - dpyHeight) { -+ desktopY += jumpV; -+ if (desktopY > fbH - dpyHeight) -+ desktopY = fbH - dpyHeight; -+ } -+ } else if (scrollUp) { -+ if (desktopY > 0) { -+ desktopY -= jumpV; -+ if (desktopY < 0) -+ desktopY = 0; -+ } -+ } -+ -+ if (oldx != desktopX || oldy != desktopY) { -+ XawViewportSetCoordinates(viewport, desktopX, desktopY); -+ timer = XtAppAddTimeOut(appContext, appData.bumpScrollTime, -+ JumpScrollTimerCallback, NULL); -+ timerSet = True; -+ return True; -+ } -+ -+ timerSet = False; -+ return False; -+} -+ -+static void -+JumpScrollTimerCallback(XtPointer clientData, XtIntervalId *id) { -+ DoJumpScroll(); -+ if (clientData || id) {} -+} -+void JumpRight(Widget w, XEvent *ev, String *params, Cardinal *num_params) { -+ JumpScroll(1, 0); -+ if (w || ev || params || num_params) {} -+} -+void JumpLeft(Widget w, XEvent *ev, String *params, Cardinal *num_params) { -+ JumpScroll(0, 0); -+ if (w || ev || params || num_params) {} -+} -+void JumpUp(Widget w, XEvent *ev, String *params, Cardinal *num_params) { -+ JumpScroll(1, 1); -+ if (w || ev || params || num_params) {} - } -+void JumpDown(Widget w, XEvent *ev, String *params, Cardinal *num_params) { -+ JumpScroll(0, 1); -+ if (w || ev || params || num_params) {} -+} -+ -+ -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/h2html.pl vnc_unixsrc/vncviewer/h2html.pl ---- vnc_unixsrc.orig/vncviewer/h2html.pl 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/h2html.pl 2008-08-30 20:34:45.000000000 -0400 -@@ -0,0 +1,10 @@ -+#!/usr/bin/perl -+ -+open(HELP, "./vncviewer -help|"); -+ -+while (<HELP>) { -+ $_ =~ s/&/&/g; -+ $_ =~ s/</</g; -+ $_ =~ s/>/>/g; -+ print; -+} -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/hextile.c vnc_unixsrc/vncviewer/hextile.c ---- vnc_unixsrc.orig/vncviewer/hextile.c 2007-02-17 22:33:46.000000000 -0500 -+++ vnc_unixsrc/vncviewer/hextile.c 2009-10-16 22:54:40.000000000 -0400 -@@ -30,6 +30,21 @@ - #define CARDBPP CONCAT2E(CARD,BPP) - #define GET_PIXEL CONCAT2E(GET_PIXEL,BPP) - -+#define FillRectangle(x, y, w, h, color) \ -+ { \ -+ XGCValues _gcv; \ -+ _gcv.foreground = color; \ -+ if (!appData.useXserverBackingStore) { \ -+ FillScreen(x, y, w, h, _gcv.foreground); \ -+ } else { \ -+ XChangeGC(dpy, gc, GCForeground, &_gcv); \ -+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \ -+ } \ -+ } -+ -+extern int skip_maybe_sync; -+extern void maybe_sync(int w, int h); -+ - static Bool - HandleHextileBPP (int rx, int ry, int rw, int rh) - { -@@ -41,21 +56,43 @@ - int sx, sy, sw, sh; - CARD8 subencoding; - CARD8 nSubrects; -+ int irect = 0, nrects = (rw * rh) / (16 * 16); -+ static int nosync_ycrop = -1; -+ -+ if (nosync_ycrop < 0) { -+ nosync_ycrop = 0; -+ if (getenv("HEXTILE_YCROP_TOO")) { -+ nosync_ycrop = 1; -+ } -+ } - - for (y = ry; y < ry+rh; y += 16) { - for (x = rx; x < rx+rw; x += 16) { - w = h = 16; -- if (rx+rw - x < 16) -+ if (rx+rw - x < 16) { - w = rx+rw - x; -- if (ry+rh - y < 16) -+ } -+ if (ry+rh - y < 16) { - h = ry+rh - y; -+ } -+ -+ if (nrects > 400 && (appData.yCrop == 0 || nosync_ycrop)) { -+ skip_maybe_sync = 0; -+ if (irect++ % 2000 != 0) { -+ if (x < rx+rw-16 || y < ry+rh-16) { -+ skip_maybe_sync = 1; -+ } -+ } -+ } - -- if (!ReadFromRFBServer((char *)&subencoding, 1)) -+ if (!ReadFromRFBServer((char *)&subencoding, 1)) { - return False; -+ } - - if (subencoding & rfbHextileRaw) { -- if (!ReadFromRFBServer(buffer, w * h * (BPP / 8))) -+ if (!ReadFromRFBServer(buffer, w * h * (BPP / 8))) { - return False; -+ } - - CopyDataToScreen(buffer, x, y, w, h); - continue; -@@ -66,14 +103,25 @@ - return False; - - #if (BPP == 8) -- if (appData.useBGR233) -+ if (appData.useBGR233) { - gcv.foreground = BGR233ToPixel[bg]; -- else -+ } else -+#endif -+#if (BPP == 16) -+ if (appData.useBGR565) { -+ gcv.foreground = BGR565ToPixel[bg]; -+ } else - #endif -+ { - gcv.foreground = bg; -+ } - -- XChangeGC(dpy, gc, GCForeground, &gcv); -- XFillRectangle(dpy, desktopWin, gc, x, y, w, h); -+#if 0 -+ XChangeGC(dpy, gc, GCForeground, &gcv); -+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); -+#else -+ FillRectangle(x, y, w, h, gcv.foreground); -+#endif - - if (subencoding & rfbHextileForegroundSpecified) - if (!ReadFromRFBServer((char *)&fg, sizeof(fg))) -@@ -101,14 +149,25 @@ - sh = rfbHextileExtractH(*ptr); - ptr++; - #if (BPP == 8) -- if (appData.useBGR233) -+ if (appData.useBGR233) { - gcv.foreground = BGR233ToPixel[fg]; -- else -+ } else - #endif -+#if (BPP == 16) -+ if (appData.useBGR565) { -+ gcv.foreground = BGR565ToPixel[fg]; -+ } else -+#endif -+ { - gcv.foreground = fg; -+ } - -- XChangeGC(dpy, gc, GCForeground, &gcv); -- XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh); -+#if 0 -+ XChangeGC(dpy, gc, GCForeground, &gcv); -+ XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh); -+#else -+ FillRectangle(x+sx, y+sy, sw, sh, gcv.foreground); -+#endif - } - - } else { -@@ -116,13 +175,22 @@ - return False; - - #if (BPP == 8) -- if (appData.useBGR233) -+ if (appData.useBGR233) { - gcv.foreground = BGR233ToPixel[fg]; -- else -+ } else - #endif -+#if (BPP == 16) -+ if (appData.useBGR565) { -+ gcv.foreground = BGR565ToPixel[fg]; -+ } else -+#endif -+ { - gcv.foreground = fg; -+ } - -+#if 0 - XChangeGC(dpy, gc, GCForeground, &gcv); -+#endif - - for (i = 0; i < nSubrects; i++) { - sx = rfbHextileExtractX(*ptr); -@@ -131,7 +199,11 @@ - sw = rfbHextileExtractW(*ptr); - sh = rfbHextileExtractH(*ptr); - ptr++; -+#if 0 - XFillRectangle(dpy, desktopWin, gc, x+sx, y+sy, sw, sh); -+#else -+ FillRectangle(x+sx, y+sy, sw, sh, gcv.foreground); -+#endif - } - } - } -@@ -139,3 +211,5 @@ - - return True; - } -+ -+#undef FillRectangle -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/listen.c vnc_unixsrc/vncviewer/listen.c ---- vnc_unixsrc.orig/vncviewer/listen.c 2001-01-16 03:07:57.000000000 -0500 -+++ vnc_unixsrc/vncviewer/listen.c 2010-04-11 23:14:21.000000000 -0400 -@@ -32,14 +32,88 @@ - #define FLASHDELAY 1 /* seconds */ - - Bool listenSpecified = False; -+pid_t listenParent = 0; - int listenPort = 0, flashPort = 0; - -+#if 0 - static Font flashFont; -- - static void getFlashFont(Display *d); - static void flashDisplay(Display *d, char *user); -+#endif -+ - static Bool AllXEventsPredicate(Display *d, XEvent *ev, char *arg); - -+void raiseme(int force); -+ -+static int accept_popup_check(int *argc, char **argv, char *sip, char *sih) { -+ char line[16]; -+ char msg[1000]; -+ int dopopup = 1; -+ -+ if (!getenv("SSVNC_ACCEPT_POPUP")) { -+ return 1; -+ } -+ -+ if (!dopopup && use_tty()) { -+ raiseme(1); -+ fprintf(stderr, "Accept VNC connection? y/[n] "); -+ fgets(line, sizeof(line), stdin); -+ if (!strchr(line, 'y') && !strchr(line, 'Y')) { -+ fprintf(stderr, "Refusing connection.\n"); -+ return 0; -+ } else { -+ fprintf(stderr, "Accepting connection.\n"); -+ return 1; -+ } -+ } else { -+ int pid, pid2, accept_it = 0; -+ -+ pid = fork(); -+ if (pid == -1) { -+ perror("fork"); -+ exit(1); -+ } -+ if (pid == 0) { -+ char *geometry = "2x2+0+0"; -+ String fb[] = { "*message.Scroll: whenNeeded", NULL}; -+ close(rfbsock); -+ -+ toplevel = XtAppInitialize(&appContext, "Ssvnc", cmdLineOptions, numCmdLineOptions, -+ argc, argv, fb, NULL, 0); -+ XtVaSetValues(toplevel, XtNmaxWidth, 2, XtNmaxHeight, 2, NULL); -+ XtVaSetValues(toplevel, XtNgeometry, geometry, NULL); -+ XtRealizeWidget(toplevel); -+ dpy = XtDisplay(toplevel); -+ sprintf(msg, "\n(LISTEN) Reverse VNC connection from IP: %s\n Hostname: %s\n\n", sip, sih); -+ strcat(msg, "Accept or Reject VNC connection?"); -+ if (CreateMsg(msg, 2)) { -+ XCloseDisplay(dpy); -+ exit(0); -+ } else { -+ XCloseDisplay(dpy); -+ exit(1); -+ } -+ } else { -+ int status; -+ pid2 = waitpid(pid, &status, 0); -+ fprintf(stderr, "waitpid: %d/%d status: %d\n", pid, pid2, status); -+ if (pid2 == pid) { -+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { -+ accept_it = 1; -+ } -+ } -+ } -+ if (accept_it) { -+ fprintf(stderr, "Accepting connection.\n"); -+ return 1; -+ } else { -+ fprintf(stderr, "Refusing connection.\n"); -+ return 0; -+ } -+ } -+ return 0; -+} -+ - /* - * listenForIncomingConnections() - listen for incoming connections from - * servers, and fork a new process to deal with each connection. We must do -@@ -47,145 +121,291 @@ - * cope with forking very well. - */ - -+extern char *accept6_hostname; -+extern char *accept6_ipaddr; -+ - void - listenForIncomingConnections(int *argc, char **argv, int listenArgIndex) - { -- Display *d; -- XEvent ev; -- int listenSocket, flashSocket, sock; -- fd_set fds; -- char flashUser[256]; -- int n; -- int i; -- char *displayname = NULL; -- -- listenSpecified = True; -- -- for (i = 1; i < *argc; i++) { -- if (strcmp(argv[i], "-display") == 0 && i+1 < *argc) { -- displayname = argv[i+1]; -- } -- } -+ Display *d; -+ XEvent ev; -+ int listenSocket, listenSocket6, flashSocket, sock; -+ fd_set fds; -+ char flashUser[256]; -+ int n; -+ int i; -+ char *displayname = NULL; -+ int children = 0; -+ int totalconn = 0, maxconn = 0; -+ -+ listenSpecified = True; -+ listenParent = getpid(); -+ -+ for (i = 1; i < *argc; i++) { -+ if (strcmp(argv[i], "-display") == 0 && i+1 < *argc) { -+ displayname = argv[i+1]; -+ } -+ } -+ if (sock || flashUser || n) {} - -- if (listenArgIndex+1 < *argc && argv[listenArgIndex+1][0] >= '0' && -+ if (listenArgIndex+1 < *argc && argv[listenArgIndex+1][0] >= '0' && - argv[listenArgIndex+1][0] <= '9') { - -- listenPort = LISTEN_PORT_OFFSET + atoi(argv[listenArgIndex+1]); -- flashPort = FLASH_PORT_OFFSET + atoi(argv[listenArgIndex+1]); -- removeArgs(argc, argv, listenArgIndex, 2); -+ listenPort = LISTEN_PORT_OFFSET + atoi(argv[listenArgIndex+1]); -+ flashPort = FLASH_PORT_OFFSET + atoi(argv[listenArgIndex+1]); -+ removeArgs(argc, argv, listenArgIndex, 2); - -- } else { -+ } else { - -- char *display; -- char *colonPos; -- struct utsname hostinfo; -+ char *display; -+ char *colonPos; -+ struct utsname hostinfo; - -- removeArgs(argc, argv, listenArgIndex, 1); -+ removeArgs(argc, argv, listenArgIndex, 1); - -- display = XDisplayName(displayname); -- colonPos = strchr(display, ':'); -+ display = XDisplayName(displayname); -+ colonPos = strchr(display, ':'); - -- uname(&hostinfo); -+ uname(&hostinfo); - -- if (colonPos && ((colonPos == display) || -- (strncmp(hostinfo.nodename, display, -- strlen(hostinfo.nodename)) == 0))) { -+ if (colonPos && ((colonPos == display) || -+ (strncmp(hostinfo.nodename, display, -+ strlen(hostinfo.nodename)) == 0))) { - -- listenPort = LISTEN_PORT_OFFSET + atoi(colonPos+1); -- flashPort = FLASH_PORT_OFFSET + atoi(colonPos+1); -+ listenPort = LISTEN_PORT_OFFSET + atoi(colonPos+1); -+ flashPort = FLASH_PORT_OFFSET + atoi(colonPos+1); - -- } else { -- fprintf(stderr,"%s: cannot work out which display number to " -- "listen on.\n", programName); -- fprintf(stderr,"Please specify explicitly with -listen <num>\n"); -- exit(1); -- } -- } -+ } else { -+ fprintf(stderr,"%s: cannot work out which display number to " -+ "listen on.\n", programName); -+ fprintf(stderr,"Please specify explicitly with -listen <num>\n"); -+ exit(1); -+ } - -- if (!(d = XOpenDisplay(displayname))) { -- fprintf(stderr,"%s: unable to open display %s\n", -- programName, XDisplayName(displayname)); -- exit(1); -- } -+ } - -- getFlashFont(d); -+ if (!(d = XOpenDisplay(displayname))) { -+ fprintf(stderr,"%s: unable to open display %s\n", -+ programName, XDisplayName(displayname)); -+ exit(1); -+ } - -- listenSocket = ListenAtTcpPort(listenPort); -- flashSocket = ListenAtTcpPort(flashPort); -+#if 0 -+ getFlashFont(d); -+#endif - -- if ((listenSocket < 0) || (flashSocket < 0)) exit(1); -+ listenSocket = ListenAtTcpPort(listenPort); -+ listenSocket6 = ListenAtTcpPort6(listenPort); -+ -+#if 0 -+ flashSocket = ListenAtTcpPort(flashPort); -+#endif -+ flashSocket = 1234; -+ -+ if (listenSocket < 0 && listenSocket6 < 0) { -+ fprintf(stderr,"%s -listen: could not obtain a listening socket on port %d\n", -+ programName, listenPort); -+ exit(1); -+ } - -- fprintf(stderr,"%s -listen: Listening on port %d (flash port %d)\n", -- programName,listenPort,flashPort); -- fprintf(stderr,"%s -listen: Command line errors are not reported until " -+ fprintf(stderr,"%s -listen: Listening on port %d ipv4_fd: %d ipv6_fd: %d\n", -+ programName, listenPort, listenSocket, listenSocket6); -+ fprintf(stderr,"%s -listen: Cmdline errors are not reported until " - "a connection comes in.\n", programName); - -- while (True) { -+ /* this will only work if X events drives this loop -- they don't */ -+ if (getenv("SSVNC_MAX_LISTEN")) { -+ maxconn = atoi(getenv("SSVNC_MAX_LISTEN")); -+ } - -- /* reap any zombies */ -- int status, pid; -- while ((pid= wait3(&status, WNOHANG, (struct rusage *)0))>0); -- -- /* discard any X events */ -- while (XCheckIfEvent(d, &ev, AllXEventsPredicate, NULL)) -- ; -- -- FD_ZERO(&fds); -- -- FD_SET(flashSocket, &fds); -- FD_SET(listenSocket, &fds); -- FD_SET(ConnectionNumber(d), &fds); -- -- select(FD_SETSIZE, &fds, NULL, NULL, NULL); -- -- if (FD_ISSET(flashSocket, &fds)) { -- -- sock = AcceptTcpConnection(flashSocket); -- if (sock < 0) exit(1); -- n = read(sock, flashUser, 255); -- if (n > 0) { -- flashUser[n] = 0; -- flashDisplay(d, flashUser); -- } else { -- flashDisplay(d, NULL); -- } -- close(sock); -- } -+ while (True) { -+ int lsock = -1; - -- if (FD_ISSET(listenSocket, &fds)) { -- rfbsock = AcceptTcpConnection(listenSocket); -- if (rfbsock < 0) exit(1); -- if (!SetNonBlocking(rfbsock)) exit(1); -+ /* reap any zombies */ -+ int status, pid; -+ while ((pid = wait3(&status, WNOHANG, (struct rusage *)0))>0) { -+ if (pid > 0 && children > 0) { -+ children--; -+ /* this will only work if X events drives this loop -- they don't */ -+ if (maxconn > 0 && totalconn >= maxconn) { -+ fprintf(stderr,"%s -listen: Finished final connection %d\n", -+ programName, maxconn); -+ exit(0); -+ } -+ } -+ } - -- XCloseDisplay(d); -+ /* discard any X events */ -+ while (XCheckIfEvent(d, &ev, AllXEventsPredicate, NULL)) { -+ ; -+ } - -- /* Now fork off a new process to deal with it... */ -+ FD_ZERO(&fds); - -- switch (fork()) { -+#if 0 -+ FD_SET(flashSocket, &fds); -+#endif -+ if (listenSocket >= 0) { -+ FD_SET(listenSocket, &fds); -+ } -+ if (listenSocket6 >= 0) { -+ FD_SET(listenSocket6, &fds); -+ } -+ FD_SET(ConnectionNumber(d), &fds); - -- case -1: -- perror("fork"); -- exit(1); -+ select(FD_SETSIZE, &fds, NULL, NULL, NULL); - -- case 0: -- /* child - return to caller */ -- close(listenSocket); -- close(flashSocket); -- return; -+ while ((pid = wait3(&status, WNOHANG, (struct rusage *)0))>0) { -+ if (pid > 0 && children > 0) { -+ children--; -+ if (maxconn > 0 && totalconn >= maxconn) { -+ fprintf(stderr,"%s -listen: Finished final connection %d\n", -+ programName, maxconn); -+ exit(0); -+ } -+ } -+ } - -- default: -- /* parent - go round and listen again */ -- close(rfbsock); -- if (!(d = XOpenDisplay(displayname))) { -- fprintf(stderr,"%s: unable to open display %s\n", -- programName, XDisplayName(displayname)); -- exit(1); -+#if 0 -+ if (FD_ISSET(flashSocket, &fds)) { -+ sock = AcceptTcpConnection(flashSocket); -+ if (sock < 0) exit(1); -+ n = read(sock, flashUser, 255); -+ if (n > 0) { -+ flashUser[n] = 0; -+ flashDisplay(d, flashUser); -+ } else { -+ flashDisplay(d, NULL); -+ } -+ close(sock); -+ } -+#endif -+ -+ lsock = -1; -+ if (listenSocket >= 0 && FD_ISSET(listenSocket, &fds)) { -+ lsock = listenSocket; -+ } else if (listenSocket6 >= 0 && FD_ISSET(listenSocket6, &fds)) { -+ lsock = listenSocket6; -+ } -+ -+ if (lsock >= 0) { -+ int multi_ok = 0; -+ char *sml = getenv("SSVNC_MULTIPLE_LISTEN"); -+ char *sip = NULL; -+ char *sih = NULL; -+ -+ if (lsock == listenSocket) { -+ rfbsock = AcceptTcpConnection(lsock); -+ } else { -+ rfbsock = AcceptTcpConnection6(lsock); -+ } -+ -+ if (sml != NULL) { -+ if (strstr(sml, "MAX:") == sml || strstr(sml, "max:") == sml) { -+ char *q = strchr(sml, ':'); -+ int maxc = atoi(q+1); -+ if (maxc == 0 && strcmp(q+1, "0")) { -+ maxc = -99; -+ } -+ if (maxc < 0) { -+ fprintf(stderr, "invalid SSVNC_MULTIPLE_LISTEN=MAX:n, %s, must be 0 or positive, using 1\n", sml); -+ } else if (maxc == 0) { -+ multi_ok = 1; -+ } else if (children < maxc) { -+ multi_ok = 1; -+ } -+ } else if (strcmp(sml, "") && strcmp(sml, "0")) { -+ multi_ok = 1; -+ } -+ } -+ -+ if (rfbsock < 0) exit(1); -+ if (!SetNonBlocking(rfbsock)) exit(1); -+ -+ if (children > 0 && !multi_ok) { -+ fprintf(stderr,"\n"); -+ fprintf(stderr,"%s: denying extra incoming connection (%d already)\n", -+ programName, children); -+ fprintf(stderr,"%s: to override: use '-multilisten' or set SSVNC_MULTIPLE_LISTEN=1\n", -+ programName); -+ fprintf(stderr,"\n"); -+ close(rfbsock); -+ rfbsock = -1; -+ continue; -+ } -+ -+ if (lsock == listenSocket) { -+ sip = get_peer_ip(rfbsock); -+ if (strlen(sip) > 100) sip = "0.0.0.0"; -+ sih = ip2host(sip); -+ if (strlen(sih) > 300) sih = "unknown"; -+ } else { -+ if (accept6_hostname != NULL) { -+ sip = accept6_ipaddr; -+ accept6_ipaddr = NULL; -+ sih = accept6_hostname; -+ accept6_hostname = NULL; -+ } else { -+ sip = "unknown"; -+ sih = "unknown"; -+ } -+ } -+ -+ fprintf(stderr, "\n"); -+ fprintf(stderr, "(LISTEN) Reverse VNC connection from IP: %s\n", sip); -+ fprintf(stderr, " Hostname: %s\n\n", sih); -+ -+ if (sml == NULL && !accept_popup_check(argc, argv, sip, sih)) { -+ close(rfbsock); -+ rfbsock = -1; -+ continue; -+ } -+ -+ totalconn++; -+ -+ XCloseDisplay(d); -+ -+ /* Now fork off a new process to deal with it... */ -+ -+ switch (fork()) { -+ -+ case -1: -+ perror("fork"); -+ exit(1); -+ -+ case 0: -+ /* child - return to caller */ -+ close(listenSocket); -+#if 0 -+ close(flashSocket); -+#endif -+ if (sml != NULL && !accept_popup_check(argc, argv, sip, sih)) { -+ close(rfbsock); -+ rfbsock = -1; -+ exit(0); -+ } -+ return; -+ -+ default: -+ /* parent - go round and listen again */ -+ children++; -+ close(rfbsock); -+ if (!(d = XOpenDisplay(displayname))) { -+ fprintf(stderr,"%s: unable to open display %s\n", -+ programName, XDisplayName(displayname)); -+ exit(1); -+ } -+#if 0 -+ getFlashFont(d); -+#endif -+ fprintf(stderr,"\n\n%s -listen: Listening on port %d\n", -+ programName,listenPort); -+ fprintf(stderr,"%s -listen: Cmdline errors are not reported until " -+ "a connection comes in.\n\n", programName); -+ break; -+ } - } -- getFlashFont(d); -- break; -- } - } -- } - } - - -@@ -193,9 +413,16 @@ - * getFlashFont - */ - -+#if 0 - static void - getFlashFont(Display *d) - { -+ -+#if 1 -+ /* no longer used */ -+ if (d) {} -+ return; -+#else - char fontName[256]; - char **fontNames; - int nFontNames; -@@ -209,6 +436,9 @@ - sprintf(fontName,"fixed"); - } - flashFont = XLoadFont(d, fontName); -+ -+#endif -+ - } - - -@@ -219,6 +449,11 @@ - static void - flashDisplay(Display *d, char *user) - { -+#if 1 -+ /* no longer used */ -+ if (d || user) {} -+ return; -+#else - Window w1, w2, w3, w4; - XSetWindowAttributes attr; - -@@ -284,7 +519,11 @@ - XDestroyWindow(d, w3); - XDestroyWindow(d, w4); - XFlush(d); -+ -+#endif -+ - } -+#endif - - /* - * AllXEventsPredicate is needed to make XCheckIfEvent return all events. -@@ -293,5 +532,6 @@ - static Bool - AllXEventsPredicate(Display *d, XEvent *ev, char *arg) - { -- return True; -+ if (d || ev || arg) {} -+ return True; - } -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/misc.c vnc_unixsrc/vncviewer/misc.c ---- vnc_unixsrc.orig/vncviewer/misc.c 2003-01-15 02:58:32.000000000 -0500 -+++ vnc_unixsrc/vncviewer/misc.c 2010-02-25 22:44:09.000000000 -0500 -@@ -23,6 +23,7 @@ - - #include <vncviewer.h> - #include <signal.h> -+#include <sys/wait.h> - #include <fcntl.h> - - static void CleanupSignalHandler(int sig); -@@ -33,12 +34,20 @@ - - Dimension dpyWidth, dpyHeight; - Atom wmDeleteWindow, wmState; -+int fullscreen_startup = 0; - - static Bool xloginIconified = False; - static XErrorHandler defaultXErrorHandler; - static XIOErrorHandler defaultXIOErrorHandler; - static XtErrorHandler defaultXtErrorHandler; - -+int XError_ign = 0; -+ -+void check_tall(void); -+int guessCrop(void); -+void get_scale_values(double *fx, double *fy); -+int scale_round(int n, double factor); -+Bool SendTextChatFinished(void); - - /* - * ToplevelInitBeforeRealization sets the title, geometry and other resources -@@ -48,87 +57,122 @@ - void - ToplevelInitBeforeRealization() - { -- char *titleFormat; -- char *title; -- char *geometry; -- -- XtVaGetValues(toplevel, XtNtitle, &titleFormat, NULL); -- title = XtMalloc(strlen(titleFormat) + strlen(desktopName) + 1); -- sprintf(title, titleFormat, desktopName); -- XtVaSetValues(toplevel, XtNtitle, title, XtNiconName, title, NULL); -- -- XtVaSetValues(toplevel, XtNmaxWidth, si.framebufferWidth, -- XtNmaxHeight, si.framebufferHeight, NULL); -- -- dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy)); -- dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy)); -- -- if (appData.fullScreen) { -- -- /* full screen - set position to 0,0, but defer size calculation until -- widgets are realized */ -- -- XtVaSetValues(toplevel, XtNoverrideRedirect, True, -- XtNgeometry, "+0+0", NULL); -- -- } else { -- -- /* not full screen - work out geometry for middle of screen unless -- specified by user */ -- -- XtVaGetValues(toplevel, XtNgeometry, &geometry, NULL); -- -- if (geometry == NULL) { -- Dimension toplevelX, toplevelY; -- Dimension toplevelWidth = si.framebufferWidth; -- Dimension toplevelHeight = si.framebufferHeight; -- -- if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth) -- toplevelWidth = dpyWidth - appData.wmDecorationWidth; -- -- if ((toplevelHeight + appData.wmDecorationHeight) >= dpyHeight) -- toplevelHeight = dpyHeight - appData.wmDecorationHeight; -- -- toplevelX = (dpyWidth - toplevelWidth - appData.wmDecorationWidth) / 2; -- -- toplevelY = (dpyHeight - toplevelHeight - appData.wmDecorationHeight) /2; -- -- /* set position via "geometry" so that window manager thinks it's a -- user-specified position and therefore honours it */ -- -- geometry = XtMalloc(256); -- -- sprintf(geometry, "%dx%d+%d+%d", -- toplevelWidth, toplevelHeight, toplevelX, toplevelY); -- XtVaSetValues(toplevel, XtNgeometry, geometry, NULL); -- } -- } -+ char *titleFormat; -+ char *title; -+ char *geometry; -+ int h = si.framebufferHeight; -+ int w = si.framebufferWidth; -+ -+ check_tall(); -+ if (appData.yCrop < 0) { -+ appData.yCrop = guessCrop(); -+ fprintf(stderr, "Set -ycrop to: %d\n", appData.yCrop); -+ if (appData.yCrop > 0) { -+ h = appData.yCrop; -+ } -+ } -+ -+ XtVaGetValues(toplevel, XtNtitle, &titleFormat, NULL); -+ title = XtMalloc(strlen(titleFormat) + strlen(desktopName) + 1); -+ sprintf(title, titleFormat, desktopName); -+ XtVaSetValues(toplevel, XtNtitle, title, XtNiconName, title, NULL); -+ -+ if (appData.scale != NULL) { -+ /* switched to not scaled */ -+ double frac_x, frac_y; -+ get_scale_values(&frac_x, &frac_y); -+ if (frac_x > 0.0 && frac_y > 0.0) { -+ w = scale_round(w, frac_x); -+ h = scale_round(h, frac_y); -+ } -+ } -+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, h, NULL); -+ -+ dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy)); -+ dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy)); -+ -+ if (appData.fullScreen) { -+ /* full screen - set position to 0,0, but defer size calculation until widgets are realized */ -+ -+ if (!net_wm_supported()) { -+ XtVaSetValues(toplevel, XtNoverrideRedirect, True, XtNgeometry, "+0+0", NULL); -+ } else { -+ fullscreen_startup = 1; -+ } -+ -+ } else { -+ -+ /* not full screen - work out geometry for middle of screen unless specified by user */ -+ -+ XtVaGetValues(toplevel, XtNgeometry, &geometry, NULL); -+ -+ if (geometry == NULL) { -+ Dimension toplevelX, toplevelY; -+ Dimension toplevelWidth = w; -+ Dimension toplevelHeight = h; -+ -+ if ((toplevelWidth + appData.wmDecorationWidth) >= dpyWidth) { -+ toplevelWidth = dpyWidth - appData.wmDecorationWidth; -+ } -+ -+ if ((toplevelHeight + appData.wmDecorationHeight) >= dpyHeight) { -+ toplevelHeight = dpyHeight - appData.wmDecorationHeight; -+ } -+ -+ toplevelX = (dpyWidth - toplevelWidth - appData.wmDecorationWidth) / 2; -+ toplevelY = (dpyHeight - toplevelHeight - appData.wmDecorationHeight) /2; -+ -+ if (appData.appShare) { -+ int X = appshare_x_hint; -+ int Y = appshare_y_hint; -+ if (appData.scale) { -+ double fx = 1.0, fy = 1.0; -+ get_scale_values(&fx, &fy); -+ if (fx > 0.0 && fy > 0.0) { -+ X *= fx; -+ Y *= fy; -+ } -+ } -+ if (appshare_x_hint != appshare_0_hint) { -+ toplevelX = X; -+ } -+ if (appshare_y_hint != appshare_0_hint) { -+ toplevelY = Y; -+ } -+ } -+ -+ /* set position via "geometry" so that window manager thinks it's a -+ user-specified position and therefore honours it */ -+ -+ geometry = XtMalloc(256); -+ -+ sprintf(geometry, "%dx%d+%d+%d", toplevelWidth, toplevelHeight, toplevelX, toplevelY); -+ fprintf(stderr, "geometry: %s ycrop: %d\n", geometry, appData.yCrop); -+ XtVaSetValues(toplevel, XtNgeometry, geometry, NULL); -+ } -+ } - - /* Test if the keyboard is grabbed. If so, it's probably because the - XDM login window is up, so try iconifying it to release the grab */ - -- if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), False, GrabModeSync, -- GrabModeSync, CurrentTime) == GrabSuccess) { -- XUngrabKeyboard(dpy, CurrentTime); -- } else { -- wmState = XInternAtom(dpy, "WM_STATE", False); -- -- if (IconifyNamedWindow(DefaultRootWindow(dpy), "xlogin", False)) { -- xloginIconified = True; -- XSync(dpy, False); -- sleep(1); -- } -- } -- -- /* Set handlers for signals and X errors to perform cleanup */ -- -- signal(SIGHUP, CleanupSignalHandler); -- signal(SIGINT, CleanupSignalHandler); -- signal(SIGTERM, CleanupSignalHandler); -- defaultXErrorHandler = XSetErrorHandler(CleanupXErrorHandler); -- defaultXIOErrorHandler = XSetIOErrorHandler(CleanupXIOErrorHandler); -- defaultXtErrorHandler = XtAppSetErrorHandler(appContext, -- CleanupXtErrorHandler); -+ if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), False, GrabModeSync, GrabModeSync, CurrentTime) == GrabSuccess) { -+ XUngrabKeyboard(dpy, CurrentTime); -+ } else { -+ wmState = XInternAtom(dpy, "WM_STATE", False); -+ if (IconifyNamedWindow(DefaultRootWindow(dpy), "xlogin", False)) { -+ xloginIconified = True; -+ XSync(dpy, False); -+ sleep(1); -+ } -+ } -+ -+ /* Set handlers for signals and X errors to perform cleanup */ -+ signal(SIGHUP, CleanupSignalHandler); -+ signal(SIGINT, CleanupSignalHandler); -+ signal(SIGTERM, CleanupSignalHandler); -+ defaultXErrorHandler = XSetErrorHandler(CleanupXErrorHandler); -+ defaultXIOErrorHandler = XSetIOErrorHandler(CleanupXIOErrorHandler); -+ defaultXtErrorHandler = XtAppSetErrorHandler(appContext, CleanupXtErrorHandler); - } - - -@@ -141,14 +185,22 @@ - void - ToplevelInitAfterRealization() - { -- if (appData.fullScreen) { -- FullScreenOn(); -- } -- -- wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False); -- XSetWMProtocols(dpy, XtWindow(toplevel), &wmDeleteWindow, 1); -- XtOverrideTranslations -- (toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()")); -+ if (appData.fullScreen) { -+ FullScreenOn(); -+ if (net_wm_supported()) { -+ /* problem with scroll bars sticking: */ -+ XSync(dpy, False); -+ usleep(50 * 1000); -+ FullScreenOff(); -+ XSync(dpy, False); -+ usleep(50 * 1000); -+ FullScreenOn(); -+ } -+ } -+ -+ wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False); -+ XSetWMProtocols(dpy, XtWindow(toplevel), &wmDeleteWindow, 1); -+ XtOverrideTranslations(toplevel, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()")); - } - - -@@ -157,9 +209,7 @@ - * CurrentTime if the event has no time field. - */ - --Time --TimeFromEvent(XEvent *ev) --{ -+Time TimeFromEvent(XEvent *ev) { - switch (ev->type) { - case KeyPress: - case KeyRelease: -@@ -192,18 +242,16 @@ - * generated by SendRFBEvent. - */ - --void --Pause(Widget w, XEvent *event, String *params, Cardinal *num_params) --{ -- int msec; -+void Pause(Widget w, XEvent *event, String *params, Cardinal *num_params) { -+ int msec; - -- if (*num_params == 0) { -- msec = 100; -- } else { -- msec = atoi(params[0]); -- } -- -- usleep(msec * 1000); -+ if (*num_params == 0) { -+ msec = 100; -+ } else { -+ msec = atoi(params[0]); -+ } -+ usleep(msec * 1000); -+ if (w || event || params || num_params) {} - } - - -@@ -256,6 +304,7 @@ - /* Wait for Child 1 to die */ - wait(&childstatus); - -+ if (w || event || params || num_params) {} - return; - } - -@@ -264,11 +313,10 @@ - * Quit action - called when we get a "delete window" message. - */ - --void --Quit(Widget w, XEvent *event, String *params, Cardinal *num_params) --{ -- Cleanup(); -- exit(0); -+void Quit(Widget w, XEvent *event, String *params, Cardinal *num_params) { -+ Cleanup(); -+ if (w || event || params || num_params) {} -+ exit(0); - } - - -@@ -276,49 +324,94 @@ - * Cleanup - perform any cleanup operations prior to exiting. - */ - --void --Cleanup() --{ -- if (xloginIconified) { -- IconifyNamedWindow(DefaultRootWindow(dpy), "xlogin", True); -- XFlush(dpy); -- } -+void Cleanup() { -+ -+ if (appData.chatActive) { -+ appData.chatActive = False; -+ fprintf(stderr,"Sending SendTextChatClose()\n"); -+ SendTextChatClose(); -+ SendTextChatFinished(); -+ } -+ -+ if (xloginIconified) { -+ IconifyNamedWindow(DefaultRootWindow(dpy), "xlogin", True); -+ XFlush(dpy); -+ } - #ifdef MITSHM -- if (appData.useShm) -- ShmCleanup(); -+ if (appData.useShm) { -+ if (UsingShm()) { -+ ShmDetach(); -+ } -+ ShmCleanup(); -+ } - #endif -+ -+ releaseAllPressedModifiers(); -+ -+ fprintf(stderr,"\nVNC Viewer exiting.\n\n"); -+ if (listenSpecified) { -+ if (listenParent != 0 && getenv("SSVNC_LISTEN_ONCE") && listenParent != getpid()) { -+ fprintf(stderr, "SSVNC_LISTEN_ONCE: Trying to kill Listening Parent: %d\n", (int) listenParent); -+ fprintf(stderr, "SSVNC_LISTEN_ONCE: Press Ctrl-C if it continues to Listen.\n\n"); -+ kill(listenParent, SIGTERM); -+ } else { -+ fprintf(stderr,"(NOTE: You may need to Press Ctrl-C to make the Viewer Stop Listening.)\n\n"); -+ } -+ } -+} -+ -+static void check_dbg(void) { -+ if (getenv("SSVNC_EXIT_DEBUG")) { -+ fprintf(stderr, "Press any key to continue: "); -+ getc(stdin); -+ } - } - - static int - CleanupXErrorHandler(Display *dpy, XErrorEvent *error) - { -- fprintf(stderr,"CleanupXErrorHandler called\n"); -- Cleanup(); -- return (*defaultXErrorHandler)(dpy, error); -+ if (XError_ign) { -+ char str[4096]; -+ XError_ign++; -+ fprintf(stderr,"XError_ign called.\n"); -+ str[0] = '\0'; -+ if (XGetErrorText(dpy, error->error_code, str, 4096)) { -+ fprintf(stderr, "%s", str); -+ } -+ return 0; -+ } -+ fprintf(stderr,"CleanupXErrorHandler called\n"); -+ check_dbg(); -+ Cleanup(); -+ return (*defaultXErrorHandler)(dpy, error); - } - - static int - CleanupXIOErrorHandler(Display *dpy) - { -- fprintf(stderr,"CleanupXIOErrorHandler called\n"); -- Cleanup(); -- return (*defaultXIOErrorHandler)(dpy); -+ fprintf(stderr,"CleanupXIOErrorHandler called\n"); -+ check_dbg(); -+ Cleanup(); -+ return (*defaultXIOErrorHandler)(dpy); - } - - static void - CleanupXtErrorHandler(String message) - { -- fprintf(stderr,"CleanupXtErrorHandler called\n"); -- Cleanup(); -- (*defaultXtErrorHandler)(message); -+ fprintf(stderr,"CleanupXtErrorHandler called\n"); -+ check_dbg(); -+ Cleanup(); -+ (*defaultXtErrorHandler)(message); - } - - static void - CleanupSignalHandler(int sig) - { -- fprintf(stderr,"CleanupSignalHandler called\n"); -- Cleanup(); -- exit(1); -+ fprintf(stderr,"CleanupSignalHandler called\n"); -+ check_dbg(); -+ Cleanup(); -+ if (sig) {} -+ exit(1); - } - - -@@ -362,7 +455,7 @@ - if (!XQueryTree(dpy, w, &dummy, &dummy, &children, &nchildren)) - return False; - -- for (i = 0; i < nchildren; i++) { -+ for (i = 0; i < (int) nchildren; i++) { - if (IconifyNamedWindow(children[i], name, undo)) { - XFree ((char *)children); - return True; -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup.c vnc_unixsrc/vncviewer/popup.c ---- vnc_unixsrc.orig/vncviewer/popup.c 2000-06-11 08:00:53.000000000 -0400 -+++ vnc_unixsrc/vncviewer/popup.c 2010-04-11 22:03:32.000000000 -0400 -@@ -22,25 +22,69 @@ - */ - - #include "vncviewer.h" -+#include <time.h> -+#include <sys/wait.h> - - #include <X11/Xaw/Form.h> - #include <X11/Xaw/Command.h> -+#include <X11/Xaw/AsciiText.h> - #include <X11/Xaw/Toggle.h> - -+#include <X11/Xaw/Box.h> -+#include <X11/Xaw/Scrollbar.h> -+ - Widget popup, fullScreenToggle; - -+Bool SendTextChatFinished(void); -+ -+void popupFixer(Widget wid) { -+ Window rr, cr; -+ unsigned int m; -+ int x0 = 500, y0 = 500; -+ int xr, yr, wxr, wyr; -+ Dimension ph; -+ if (XQueryPointer(dpy, DefaultRootWindow(dpy), &rr, &cr, &xr, &yr, &wxr, &wyr, &m)) { -+ x0 = xr; -+ y0 = yr; -+ } -+ XtPopup(wid, XtGrabNone); -+ XtVaGetValues(wid, XtNheight, &ph, NULL); -+ if (y0 + (int) ph > dpyHeight) { -+ y0 = dpyHeight - (int) ph; -+ if (y0 < 0) { -+ y0 = 0; -+ } -+ } -+ XtMoveWidget(wid, x0, y0); -+} -+ -+void Noop(Widget w, XEvent *event, String *params, Cardinal *num_params) { -+ if (0) fprintf(stderr, "No-op\n"); -+ if (w || event || params || num_params) {} -+} -+ - void - ShowPopup(Widget w, XEvent *event, String *params, Cardinal *num_params) - { -- XtMoveWidget(popup, event->xbutton.x_root, event->xbutton.y_root); -- XtPopup(popup, XtGrabNone); -- XSetWMProtocols(dpy, XtWindow(popup), &wmDeleteWindow, 1); -+ if (appData.popupFix) { -+ popupFixer(popup); -+ } else { -+ XtMoveWidget(popup, event->xbutton.x_root, event->xbutton.y_root); -+ XtPopup(popup, XtGrabNone); -+ } -+ if (appData.grabAll) { -+ XSync(dpy, False); -+ XRaiseWindow(dpy, XtWindow(popup)); -+ } -+ XSetWMProtocols(dpy, XtWindow(popup), &wmDeleteWindow, 1); -+ XtOverrideTranslations(popup, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HidePopup()")); -+ if (w || event || params || num_params) {} - } - - void --HidePopup(Widget w, XEvent *event, String *params, Cardinal *num_params) --{ -- XtPopdown(popup); -+HidePopup(Widget w, XEvent *event, String *params, Cardinal *num_params) { -+ XtPopdown(popup); -+ if (w || event || params || num_params) {} - } - - -@@ -52,42 +96,808 @@ - }; - - void --CreatePopup() -+CreatePopup() { -+ Widget buttonForm1, buttonForm2, twoForm, button = 0, prevButton = NULL; -+ int i; -+ char buttonName[12]; -+ String buttonType; -+ -+ popup = XtVaCreatePopupShell("popup", transientShellWidgetClass, toplevel, NULL); -+ -+ twoForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, popup, NULL); -+ buttonForm1 = XtVaCreateManagedWidget("buttonForm", formWidgetClass, twoForm, NULL); -+ buttonForm2 = XtVaCreateManagedWidget("buttonForm", formWidgetClass, twoForm, XtNfromHoriz, (XtArgVal) buttonForm1, NULL); -+ -+ if (appData.popupButtonCount > 100) { -+ fprintf(stderr,"Too many popup buttons\n"); -+ exit(1); -+ } -+ -+ for (i = 1; i <= appData.popupButtonCount; i++) { -+ Widget bform; -+ sprintf(buttonName, "button%d", i); -+ -+ if (i <= appData.popupButtonBreak) { -+ bform = buttonForm1; -+ } else { -+ if (i == appData.popupButtonBreak+1) { -+ prevButton = NULL; -+ } -+ bform = buttonForm2; -+ } -+ XtVaGetSubresources(bform, (XtPointer)&buttonType, buttonName, "Button", resources, 1, NULL); -+ -+ if (strcmp(buttonType, "command") == 0) { -+ button = XtVaCreateManagedWidget(buttonName, commandWidgetClass, bform, NULL); -+ XtVaSetValues(button, XtNfromVert, prevButton, XtNleft, XawChainLeft, XtNright, XawChainRight, NULL); -+ } else if (strcmp(buttonType, "toggle") == 0) { -+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass, bform, NULL); -+ XtVaSetValues(button, XtNfromVert, prevButton, XtNleft, XawChainLeft, XtNright, XawChainRight, NULL); -+ } else { -+ fprintf(stderr,"unknown button type '%s'\n", buttonType); -+ } -+ prevButton = button; -+ } -+} -+ -+ -+Widget scaleN; -+ -+void -+ShowScaleN(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ if (appData.popupFix) { -+ popupFixer(scaleN); -+ } else { -+ XtMoveWidget(scaleN, event->xbutton.x_root, event->xbutton.y_root); -+ XtPopup(scaleN, XtGrabNone); -+ } -+ if (appData.grabAll) { -+ XRaiseWindow(dpy, XtWindow(scaleN)); -+ } -+ XSetWMProtocols(dpy, XtWindow(scaleN), &wmDeleteWindow, 1); -+ XtOverrideTranslations(scaleN, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideScaleN()")); -+ if (w || event || params || num_params) {} -+} -+ -+void -+HideScaleN(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ XtPopdown(scaleN); -+ if (w || event || params || num_params) {} -+} -+ -+ -+void -+CreateScaleN() - { - Widget buttonForm, button, prevButton = NULL; - int i; -- char buttonName[12]; -+ char buttonName[32]; - String buttonType; - -- popup = XtVaCreatePopupShell("popup", transientShellWidgetClass, toplevel, -+ scaleN = XtVaCreatePopupShell("scaleN", transientShellWidgetClass, toplevel, - NULL); - -- buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, popup, -+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, scaleN, - NULL); - -- if (appData.popupButtonCount > 100) { -- fprintf(stderr,"Too many popup buttons\n"); -- exit(1); -- } -- -- for (i = 1; i <= appData.popupButtonCount; i++) { -+ for (i = 0; i <= 6; i++) { - sprintf(buttonName, "button%d", i); - XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName, - "Button", resources, 1, NULL); - -- if (strcmp(buttonType, "command") == 0) { -- button = XtVaCreateManagedWidget(buttonName, commandWidgetClass, -+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass, - buttonForm, NULL); -- XtVaSetValues(button, XtNfromVert, prevButton, -+ XtVaSetValues(button, XtNfromVert, prevButton, - XtNleft, XawChainLeft, XtNright, XawChainRight, NULL); -- } else if (strcmp(buttonType, "toggle") == 0) { -- button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass, -+ prevButton = button; -+ } -+} -+ -+Widget turbovncW; -+ -+static Widget turboButtons[32]; -+ -+Widget qualtext, qualslider; -+ -+void UpdateQualSlider(void) { -+#ifdef TURBOVNC -+ char text[16]; -+ XawScrollbarSetThumb(qualslider, (float)appData.qualityLevel/100., 0.); -+ sprintf(text, "%3d", appData.qualityLevel); -+ XtVaSetValues(qualtext, XtNlabel, text, NULL); -+#endif -+} -+ -+void qualScrollProc(Widget w, XtPointer client, XtPointer p) { -+#ifdef TURBOVNC -+ float size, val; int qual, pos=(int)p; -+ XtVaGetValues(w, XtNshown, &size, XtNtopOfThumb, &val, 0); -+ if(pos<0) val-=.1; else val+=.1; -+ qual=(int)(val*100.); if(qual<1) qual=1; if(qual>100) qual=100; -+ XawScrollbarSetThumb(w, val, 0.); -+ appData.qualityLevel=qual; -+ UpdateQual(); -+#endif -+ if (w || client || p) {} -+} -+ -+void qualJumpProc(Widget w, XtPointer client, XtPointer p) { -+#ifdef TURBOVNC -+ float val=*(float *)p; int qual; -+ qual=(int)(val*100.); if(qual<1) qual=1; if(qual>100) qual=100; -+ appData.qualityLevel=qual; -+ UpdateQual(); -+#endif -+ if (w || client || p) {} -+} -+ -+void UpdateSubsampButtons(void) { -+#ifdef TURBOVNC -+ int i; -+ for (i=7; i <= 10; i++) { -+ XtVaSetValues(turboButtons[i], XtNstate, 0, NULL); -+ } -+ if (appData.subsampLevel==TVNC_1X) { -+ i = 7; -+ } else if (appData.subsampLevel==TVNC_2X) { -+ i = 8; -+ } else if (appData.subsampLevel==TVNC_4X) { -+ i = 9; -+ } else if (appData.subsampLevel==TVNC_GRAY) { -+ i = 10; -+ } else { -+ return; -+ } -+ XtVaSetValues(turboButtons[i], XtNstate, 1, NULL); -+#endif -+} -+ -+void -+ShowTurboVNC(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ UpdateSubsampButtons(); -+ UpdateQualSlider(); -+ if (appData.popupFix) { -+ popupFixer(turbovncW); -+ } else { -+ XtMoveWidget(turbovncW, event->xbutton.x_root, event->xbutton.y_root); -+ XtPopup(turbovncW, XtGrabNone); -+ } -+ if (appData.grabAll) { -+ XRaiseWindow(dpy, XtWindow(turbovncW)); -+ } -+ XSetWMProtocols(dpy, XtWindow(turbovncW), &wmDeleteWindow, 1); -+ XtOverrideTranslations(turbovncW, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideTurboVNC()")); -+ if (w || event || params || num_params) {} -+} -+ -+void -+HideTurboVNC(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ XtPopdown(turbovncW); -+ if (w || event || params || num_params) {} -+} -+ -+void -+CreateTurboVNC() { -+ Widget buttonForm, button, prevButton = NULL; -+ Widget label; -+ int i; -+ char buttonName[32]; -+ String buttonType; -+ -+ turbovncW = XtVaCreatePopupShell("turboVNC", transientShellWidgetClass, toplevel, NULL); -+ -+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, turbovncW, NULL); -+ -+ for (i = 0; i <= 12; i++) { -+ sprintf(buttonName, "button%d", i); -+#ifndef TURBOVNC -+ if (i == 0) { -+ sprintf(buttonName, "buttonNone"); -+ } else if (i > 0) { -+ return; -+ } -+#endif -+ XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName, -+ "Button", resources, 1, NULL); -+ -+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass, -+ buttonForm, NULL); -+ turboButtons[i] = button; -+ XtVaSetValues(button, XtNfromVert, prevButton, -+ XtNleft, XawChainLeft, XtNright, XawChainRight, NULL); -+ prevButton = button; -+ } -+ -+ label = XtCreateManagedWidget("qualLabel", toggleWidgetClass, buttonForm, NULL, 0); -+ XtVaSetValues(label, XtNfromVert, prevButton, XtNleft, XawChainLeft, XtNright, XawChainRight, NULL); -+ -+ qualslider = XtCreateManagedWidget("qualBar", scrollbarWidgetClass, buttonForm, NULL, 0); -+ XtVaSetValues(qualslider, XtNfromVert, label, XtNleft, XawChainLeft, NULL); -+ XtAddCallback(qualslider, XtNscrollProc, qualScrollProc, NULL) ; -+ XtAddCallback(qualslider, XtNjumpProc, qualJumpProc, NULL) ; -+ -+ qualtext = XtCreateManagedWidget("qualText", labelWidgetClass, buttonForm, NULL, 0); -+ XtVaSetValues(qualtext, XtNfromVert, label, XtNfromHoriz, qualslider, XtNright, XawChainRight, NULL); -+} -+ -+Widget qualityW; -+ -+void -+ShowQuality(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ if (appData.popupFix) { -+ popupFixer(qualityW); -+ } else { -+ XtMoveWidget(qualityW, event->xbutton.x_root, event->xbutton.y_root); -+ XtPopup(qualityW, XtGrabNone); -+ } -+ if (appData.grabAll) { -+ XRaiseWindow(dpy, XtWindow(qualityW)); -+ } -+ XSetWMProtocols(dpy, XtWindow(qualityW), &wmDeleteWindow, 1); -+ XtOverrideTranslations(qualityW, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideQuality()")); -+ if (w || event || params || num_params) {} -+} -+ -+void -+HideQuality(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ XtPopdown(qualityW); -+ if (w || event || params || num_params) {} -+} -+ -+ -+void -+CreateQuality() -+{ -+ Widget buttonForm, button, prevButton = NULL; -+ int i; -+ char buttonName[32]; -+ String buttonType; -+ -+ qualityW = XtVaCreatePopupShell("quality", transientShellWidgetClass, toplevel, -+ NULL); -+ -+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, qualityW, -+ NULL); -+ -+ for (i = -1; i <= 9; i++) { -+ if (i < 0) { -+ sprintf(buttonName, "buttonD"); -+ } else { -+ sprintf(buttonName, "button%d", i); -+ } -+ XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName, -+ "Button", resources, 1, NULL); -+ -+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass, - buttonForm, NULL); -- XtVaSetValues(button, XtNfromVert, prevButton, -+ XtVaSetValues(button, XtNfromVert, prevButton, - XtNleft, XawChainLeft, XtNright, XawChainRight, NULL); -+ prevButton = button; -+ } -+} -+ -+Widget compressW; -+ -+void -+ShowCompress(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ if (appData.popupFix) { -+ popupFixer(compressW); -+ } else { -+ XtMoveWidget(compressW, event->xbutton.x_root, event->xbutton.y_root); -+ XtPopup(compressW, XtGrabNone); -+ } -+ if (appData.grabAll) { -+ XRaiseWindow(dpy, XtWindow(compressW)); -+ } -+ XSetWMProtocols(dpy, XtWindow(compressW), &wmDeleteWindow, 1); -+ XtOverrideTranslations(compressW, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideCompress()")); -+ if (w || event || params || num_params) {} -+} -+ -+void -+HideCompress(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ XtPopdown(compressW); -+ if (w || event || params || num_params) {} -+} -+ -+ -+void -+CreateCompress() -+{ -+ Widget buttonForm, button, prevButton = NULL; -+ int i; -+ char buttonName[32]; -+ String buttonType; -+ -+ compressW = XtVaCreatePopupShell("compress", transientShellWidgetClass, toplevel, -+ NULL); -+ -+ buttonForm = XtVaCreateManagedWidget("buttonForm", formWidgetClass, compressW, -+ NULL); -+ -+ for (i = -1; i <= 9; i++) { -+ if (i < 0) { -+ sprintf(buttonName, "buttonD"); - } else { -- fprintf(stderr,"unknown button type '%s'\n",buttonType); -+ sprintf(buttonName, "button%d", i); - } -+ XtVaGetSubresources(buttonForm, (XtPointer)&buttonType, buttonName, -+ "Button", resources, 1, NULL); -+ -+ button = XtVaCreateManagedWidget(buttonName, toggleWidgetClass, -+ buttonForm, NULL); -+ XtVaSetValues(button, XtNfromVert, prevButton, -+ XtNleft, XawChainLeft, XtNright, XawChainRight, NULL); - prevButton = button; - } - } -+ -+ -+int filexfer_sock = -1; -+int filexfer_listen = -1; -+ -+void HideFile(Widget w, XEvent *event, String *params, Cardinal *num_params) { -+ if (filexfer_sock >= 0) { -+ close(filexfer_sock); -+ filexfer_sock = -1; -+ } -+ if (filexfer_listen >= 0) { -+ close(filexfer_listen); -+ filexfer_listen = -1; -+ } -+ if (w || event || params || num_params) {} -+} -+ -+extern int use_loopback; -+time_t start_listen = 0; -+pid_t java_helper = 0; -+ -+void ShowFile(Widget w, XEvent *event, String *params, Cardinal *num_params) { -+ int i, port0 = 7200, port, sock = -1; -+ char *cmd, *jar; -+ char fmt[] = "java -cp '%s' VncViewer HOST localhost PORT %d delayAuthPanel yes ignoreMSLogonCheck yes disableSSL yes ftpOnly yes graftFtp yes dsmActive no &"; -+ -+ if (getenv("SSVNC_ULTRA_FTP_JAR")) { -+ jar = getenv("SSVNC_ULTRA_FTP_JAR"); -+ cmd = (char *) malloc(strlen(fmt) + strlen(jar) + 100); -+ } else { -+ fprintf(stderr, "Cannot find UltraVNC FTP jar file.\n"); -+ return; -+ } -+ -+ use_loopback = 1; -+ for (i = 0; i < 100; i++) { -+ port = port0 + i; -+ sock = ListenAtTcpPort(port); -+ if (sock < 0) { -+ sock = ListenAtTcpPort6(port); -+ } -+ if (sock >= 0) { -+ fprintf(stderr, "listening for filexfer on port: %d sock: %d\n", port, sock); -+ break; -+ } -+ } -+ use_loopback = 0; -+ -+ if (sock >= 0) { -+ int st; -+ pid_t pid = fork(); -+ if (pid < 0) { -+ free(cmd); -+ return; -+ } else if (pid == 0) { -+ int i; -+ sprintf(cmd, fmt, jar, port); -+ if (appData.ultraDSM) { -+ char *q = strstr(cmd, "dsmActive"); -+ if (q) { -+ q = strstr(q, "no "); -+ if (q) { -+ q[0] = 'y'; -+ q[1] = 'e'; -+ q[2] = 's'; -+ } -+ } -+ } -+ for (i = 3; i < 100; i++) { -+ close(i); -+ } -+ fprintf(stderr, "\n-- Experimental UltraVNC File Transfer --\n\nRunning cmd:\n\n %s\n\n", cmd); -+ system(cmd); -+ exit(0); -+ } -+ fprintf(stderr, "java helper pid is: %d\n", (int) pid); -+ waitpid(pid, &st, 0); -+ java_helper = pid; -+ start_listen = time(NULL); -+ } -+ free(cmd); -+ filexfer_listen = sock; -+ if (w || event || params || num_params) {} -+} -+ -+Widget chat, entry, text; -+ -+static int chat_visible = 0; -+ -+void -+ShowChat(Widget w, XEvent *event, String *params, Cardinal *num_params) -+{ -+ if (appData.termChat) { -+ return; -+ } -+ if (! chat_visible) { -+ XtPopup(chat, XtGrabNone); -+ chat_visible = 1; -+ wmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False); -+ XSetWMProtocols(dpy, XtWindow(chat), &wmDeleteWindow, 1); -+ if (appData.chatOnly) { -+ XtOverrideTranslations(chat, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()")); -+ } else { -+ XtOverrideTranslations(chat, XtParseTranslationTable ("<Message>WM_PROTOCOLS: HideChat()")); -+ } -+ XSync(dpy, False); -+ usleep(200 * 1000); -+ } -+ if (w || event || params || num_params) {} -+} -+ -+void hidechat(void) { -+ appData.chatActive = False; -+ if (appData.termChat) { -+ return; -+ } -+ if (chat_visible) { -+ XtPopdown(chat); -+ chat_visible = 0; -+ XSync(dpy, False); -+ usleep(200 * 1000); -+ } -+ if (appData.chatOnly) { -+ Quit(0, NULL, NULL, NULL); -+ } -+} -+ -+void HideChat(Widget w, XEvent *event, String *params, Cardinal *num_params) { -+ SendTextChatClose(); -+ SendTextChatFinished(); -+ hidechat(); -+ if (w || event || params || num_params) {} -+} -+ -+void dismiss_proc(Widget w, XtPointer client_data, XtPointer call_data) { -+ SendTextChatClose(); -+ SendTextChatFinished(); -+ hidechat(); -+ if (w || client_data || call_data) {} -+} -+ -+extern void printChat(char *, Bool); -+ -+static void ChatTextCallback(XtPointer clientData, XtIntervalId *id); -+static XtIntervalId timer; -+static Bool timerSet = False; -+ -+void CheckTextInput(void); -+extern double start_time; -+ -+static void ChatTextCallback(XtPointer clientData, XtIntervalId *id) { -+ static int db = -1; -+ if (db < 0) { -+ if (getenv("SSVNC_DEBUG_CHAT")) { -+ db = 1; -+ } else { -+ db = 0; -+ } -+ } -+ if (db) fprintf(stderr, "ChatTextCallback: %.4f\n", dnow() - start_time); -+ CheckTextInput(); -+ if (clientData || id) {} -+} -+ -+void CheckTextInput(void) { -+ Arg args[2]; -+ String str; -+ int len; -+ static int db = -1; -+ -+ if (timerSet) { -+ XtRemoveTimeOut(timer); -+ timerSet = False; -+ } -+ if (appData.chatActive) { -+ timer = XtAppAddTimeOut(appContext, 333, ChatTextCallback, NULL); -+ timerSet = True; -+ } -+ if (appData.chatOnly && !appData.chatActive) { -+ Quit(0, NULL, NULL, NULL); -+ } -+ -+ if (appData.termChat) { -+ return; -+ } -+#if 0 -+ if (!appData.chatActive) { -+ return; -+ } -+#endif -+ -+ if (db < 0) { -+ if (getenv("SSVNC_DEBUG_CHAT")) { -+ db = 1; -+ } else { -+ db = 0; -+ } -+ } -+ -+ XtSetArg(args[0], XtNstring, &str); -+ XtGetValues(entry, args, 1); -+ -+ if (db) fprintf(stderr, "CheckTextInput\n"); -+ -+ if (str == NULL || str[0] == '\0') { -+ return; -+ } else { -+ char *q; -+ len = strlen(str); -+ if (db) fprintf(stderr, "CheckTextInput: len: %d '%s'\n", len, str); -+ if (len <= 0) { -+ return; -+ } -+ q = strrchr(str, '\n'); -+ if (q) { -+ char *send, save[2]; -+ save[0] = *(q+1); -+ *(q+1) = '\0'; -+ send = strdup(str); -+ *(q+1) = save[0]; -+ if (send) { -+ SendTextChat(send); -+ printChat("Send: ", True); -+ printChat(send, True); -+ free(send); -+ if (save[0] == '\0') { -+ XtVaSetValues(entry, XtNtype, XawAsciiString, XtNstring, "", NULL); -+ } else { -+ char *leak = strdup(q+1); -+ XtVaSetValues(entry, XtNtype, XawAsciiString, XtNstring, leak, NULL); -+ if (strlen(leak) > 0) { -+ XSync(dpy, False); -+ XtVaSetValues(entry, XtNinsertPosition, strlen(leak), NULL); -+ } -+ } -+ } -+ } -+ } -+} -+ -+void AppendChatInput0(char *in) { -+ Arg args[10]; -+ int n; -+ String str; -+ int len; -+ static char *s = NULL; -+ static int slen = -1; -+ XawTextPosition pos; -+ -+ fprintf(stderr, "AppendChatInput: in= '%s'\n", in); -+ -+ XtSetArg(args[0], XtNstring, &str); -+ XtGetValues(text, args, 1); -+ fprintf(stderr, "AppendChatInput: str='%s'\n", str); -+ -+ len = strlen(str) + strlen(in); -+ -+ if (slen <= len) { -+ slen = 2 * (len + 10); -+ if (s) free(s); -+ s = (char *) malloc(slen+1); -+ } -+ -+ s[0] = '\0'; -+ strcat(s, str); -+ strcat(s, in); -+ fprintf(stderr, "AppendChatInput s= '%s'\n", s); -+ pos = (XawTextPosition) (len-1); -+ n = 0; -+ XtSetArg(args[n], XtNtype, XawAsciiString); n++; -+ XtSetArg(args[n], XtNstring, s); n++; -+ XtSetArg(args[n], XtNdisplayPosition, pos); n++; -+ XtSetArg(args[n], XtNinsertPosition, pos); n++; -+ XtSetValues(text, args, n); -+ fprintf(stderr, "AppendChatInput done\n"); -+} -+ -+void AppendChatInput(char *in) { -+ XawTextPosition beg, end; -+ static XawTextPosition pos = 0; -+ XawTextBlock txt; -+ -+ if (appData.termChat) { -+ return; -+ } -+ -+ XawTextSetInsertionPoint(text, pos); -+ beg = XawTextGetInsertionPoint(text); -+ end = beg; -+#if 0 -+ fprintf(stderr, "AppendChatInput: pos=%d in= '%s'\n", beg, in); -+#endif -+ -+ txt.firstPos = 0; -+ txt.length = strlen(in); -+ txt.ptr = in; -+ txt.format = FMT8BIT; -+ -+ XawTextReplace(text, beg, end, &txt); -+ XawTextSetInsertionPoint(text, beg + txt.length); -+ -+ pos = XawTextGetInsertionPoint(text); -+#if 0 -+ fprintf(stderr, "AppendChatInput done pos=%d\n", pos); -+#endif -+} -+ -+#if 0 -+static char errorbuf[1] = {0}; -+#endif -+ -+void CreateChat(void) { -+ -+ Widget myform, dismiss; -+ Dimension w = 400, h = 300; -+ -+ chat = XtVaCreatePopupShell("chat", topLevelShellWidgetClass, toplevel, XtNmappedWhenManaged, False, NULL); -+ -+ myform = XtVaCreateManagedWidget("myform", formWidgetClass, chat, NULL); -+ -+ text = XtVaCreateManagedWidget("text", asciiTextWidgetClass, myform, -+ XtNresize, XawtextResizeBoth, XtNresizable, True, XtNwrap, XawtextWrapWord, -+ XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollAlways, -+ XtNwidth, w, XtNheight, h, XtNdisplayCaret, False, -+ XtNeditType, XawtextAppend, XtNtype, XawAsciiString, -+ XtNuseStringInPlace, False, NULL); -+ -+ entry = XtVaCreateManagedWidget("entry", asciiTextWidgetClass, myform, -+ XtNresize, XawtextResizeWidth, XtNresizable, True, XtNwrap, XawtextWrapNever, -+ XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollNever, -+ XtNheight, 20, XtNwidth, 400, XtNfromVert, text, XtNeditType, XawtextEdit, -+ XtNdisplayCaret, True, XtNeditType, XawtextEdit, NULL); -+ -+ dismiss = XtVaCreateManagedWidget("dismiss", commandWidgetClass, myform, XtNlabel, "Close Chat", XtNfromVert, entry, NULL); -+ -+ AppendChatInput(""); -+ -+ XtAddCallback(dismiss, XtNcallback, dismiss_proc, NULL); -+ -+ XtRealizeWidget(chat); -+ -+ XtSetKeyboardFocus(chat, entry); -+} -+ -+Widget msgwin, msgtext; -+ -+void AppendMsg(char *in) { -+ XawTextPosition beg, end; -+ static XawTextPosition pos = 0; -+ XawTextBlock txt; -+ -+ XawTextSetInsertionPoint(msgtext, pos); -+ beg = XawTextGetInsertionPoint(msgtext); -+ end = beg; -+ -+ txt.firstPos = 0; -+ txt.length = strlen(in); -+ txt.ptr = in; -+ txt.format = FMT8BIT; -+ -+ XawTextReplace(msgtext, beg, end, &txt); -+ XawTextSetInsertionPoint(msgtext, beg + txt.length); -+ -+ pos = XawTextGetInsertionPoint(msgtext); -+} -+ -+static int msg_visible = 0; -+static int msg_NO_clicked = 0; -+ -+void msg_dismiss_proc(Widget w, XtPointer client_data, XtPointer call_data) { -+ XtPopdown(msgwin); -+ msg_visible = 0; -+ XSync(dpy, False); -+ usleep(200 * 1000); -+ if (w || client_data || call_data) {} -+} -+ -+void msg_NO_proc(Widget w, XtPointer client_data, XtPointer call_data) { -+ XtPopdown(msgwin); -+ msg_visible = 0; -+ msg_NO_clicked = 1; -+ XSync(dpy, False); -+ usleep(200 * 1000); -+ if (w || client_data || call_data) {} -+} -+ -+int CreateMsg(char *msg, int wait) { -+ -+ Widget myform, dismiss, reject; -+ char *p; -+ int n, run, wmax = 0; -+ int ret = 1; -+ Dimension w, h; -+ -+ -+ n = 0; -+ run = 0; -+ p = msg; -+ while (*p != '\0') { -+ if (*p == '\n') { -+ run = 0; -+ n++; -+ } -+ run++; -+ if (run > wmax) wmax = run; -+ p++; -+ } -+ if (wmax > 80) { -+ if (wmax > 120) n++; -+ if (wmax > 80) n++; -+ wmax = 80; -+ } -+ h = (Dimension) (n+2) * 14; -+ w = (Dimension) (wmax+10) * 8; -+ -+ msgwin = XtVaCreatePopupShell("Message", topLevelShellWidgetClass, toplevel, XtNmappedWhenManaged, False, NULL); -+ -+ myform = XtVaCreateManagedWidget("myform", formWidgetClass, msgwin, NULL); -+ -+ msgtext = XtVaCreateManagedWidget("msgtext", asciiTextWidgetClass, myform, -+ XtNresize, XawtextResizeBoth, XtNresizable, True, XtNwrap, XawtextWrapWord, -+ XtNscrollHorizontal, XawtextScrollNever, XtNscrollVertical, XawtextScrollAlways, -+ XtNwidth, w, XtNheight, h, XtNdisplayCaret, False, -+ XtNeditType, XawtextAppend, XtNtype, XawAsciiString, -+ XtNuseStringInPlace, False, NULL); -+ -+ if (wait == 2) { -+ msg_NO_clicked = 0; -+ -+ dismiss = XtVaCreateManagedWidget("dismiss", commandWidgetClass, myform, XtNlabel, "Accept", XtNfromVert, msgtext, NULL); -+ XtAddCallback(dismiss, XtNcallback, msg_dismiss_proc, NULL); -+ -+ reject = XtVaCreateManagedWidget("reject", commandWidgetClass, myform, XtNlabel, "Reject", XtNfromVert, dismiss, NULL); -+ XtAddCallback(reject, XtNcallback, msg_NO_proc, NULL); -+ } else { -+ dismiss = XtVaCreateManagedWidget("dismiss", commandWidgetClass, myform, XtNlabel, "OK", XtNfromVert, msgtext, NULL); -+ XtAddCallback(dismiss, XtNcallback, msg_dismiss_proc, NULL); -+ -+ } -+ -+ AppendMsg(""); -+ AppendMsg(msg); -+ -+ XtRealizeWidget(msgwin); -+ -+ XtPopup(msgwin, XtGrabNone); -+ -+ XSync(dpy, False); -+ msg_visible = 1; -+ while (wait && msg_visible) { -+ if (0) fprintf(stderr, "mv: %d\n", msg_visible); -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ if (wait == 2) { -+ if (msg_NO_clicked) { -+ ret = 0; -+ } else { -+ ret = 1; -+ } -+ } -+ return ret; -+} -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/popup_ad vnc_unixsrc/vncviewer/popup_ad ---- vnc_unixsrc.orig/vncviewer/popup_ad 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/popup_ad 2008-02-17 13:32:34.000000000 -0500 -@@ -0,0 +1,20 @@ -+#!/usr/bin/perl -+ -+$ok = 0; -+ -+open(A, "<argsresources.c") || die; -+ -+while (<A>) { -+ if (/popupButtonCount:/) { -+ $on = 1; -+ } elsif (/^\s*NULL/) { -+ $on = 0; -+ } -+ next unless $on; -+ chomp; -+ last if /NULL/; -+ $_ =~ s/^\s*"//; -+ $_ =~ s/",//; -+ $_ .= "\n" unless $_ =~ /\n/; -+ print; -+} -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rfbproto.c vnc_unixsrc/vncviewer/rfbproto.c ---- vnc_unixsrc.orig/vncviewer/rfbproto.c 2008-09-05 19:51:24.000000000 -0400 -+++ vnc_unixsrc/vncviewer/rfbproto.c 2010-04-17 22:34:38.000000000 -0400 -@@ -23,7 +23,10 @@ - * rfbproto.c - functions to deal with client side of RFB protocol. - */ - -+#include <sys/stat.h> - #include <unistd.h> -+#include <time.h> -+#include <ctype.h> - #include <errno.h> - #include <pwd.h> - #include <vncviewer.h> -@@ -31,6 +34,9 @@ - #include <zlib.h> - #include <jpeglib.h> - -+int server_major = 0, server_minor = 0; -+int viewer_major = 0, viewer_minor = 0; -+ - static void InitCapabilities(void); - static Bool SetupTunneling(void); - static int ReadSecurityType(void); -@@ -57,6 +63,47 @@ - static Bool HandleTight16(int rx, int ry, int rw, int rh); - static Bool HandleTight32(int rx, int ry, int rw, int rh); - -+/* runge add zrle */ -+static Bool HandleZRLE8(int rx, int ry, int rw, int rh); -+static Bool HandleZRLE15(int rx, int ry, int rw, int rh); -+static Bool HandleZRLE16(int rx, int ry, int rw, int rh); -+static Bool HandleZRLE24(int rx, int ry, int rw, int rh); -+static Bool HandleZRLE24Up(int rx, int ry, int rw, int rh); -+static Bool HandleZRLE24Down(int rx, int ry, int rw, int rh); -+static Bool HandleZRLE32(int rx, int ry, int rw, int rh); -+ -+extern Bool HandleCursorPos(int x, int y); -+extern void printChat(char *, Bool); -+ -+typedef struct { -+ unsigned long length; -+} rfbZRLEHeader; -+ -+#define sz_rfbZRLEHeader 4 -+ -+#define rfbZRLETileWidth 64 -+#define rfbZRLETileHeight 64 -+ -+#define DO_ZYWRLE 1 -+ -+#if DO_ZYWRLE -+ -+#ifndef ZRLE_ONCE -+#define ZRLE_ONCE -+ -+static const int bitsPerPackedPixel[] = { -+ 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -+}; -+ -+int zywrle_level; -+int zywrleBuf[rfbZRLETileWidth*rfbZRLETileHeight]; -+ -+#include "zrlepalettehelper.h" -+static zrlePaletteHelper paletteHelper; -+ -+#endif /* ZRLE_ONCE */ -+#endif /* DO_ZYWRLE */ -+ - static void ReadConnFailedReason(void); - static long ReadCompactLen (void); - -@@ -67,6 +114,25 @@ - static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData, - int compressedLen); - -+extern void deskey(unsigned char *, int); -+extern void des(unsigned char *, unsigned char *); -+ -+extern int currentMsg; -+extern double scale_factor_x; -+extern double scale_factor_y; -+ -+extern int skip_maybe_sync; -+ -+int sent_FBU = 0; -+int skip_XtUpdate = 0; -+int skip_XtUpdateAll = 0; -+ -+static double dt_out = 0.0; -+static double dt_out_sc = 0.0; -+double latency = 0.0; -+double connect_time = 0.0; -+ -+void raiseme(int force); - - int rfbsock; - char *desktopName; -@@ -75,6 +141,14 @@ - char *serverCutText = NULL; - Bool newServerCutText = False; - -+/* ultravnc mslogon */ -+#define rfbUltraVncMsLogon 0xfffffffa -+static Bool AuthUltraVncMsLogon(void); -+extern void UvncEncryptPasswd_MSLOGON(unsigned char *encryptedPasswd, char *passwd); -+extern void UvncEncryptBytes2(unsigned char *where, int length, unsigned char *key); -+extern void UvncDecryptBytes2(unsigned char *where, int length, unsigned char *key); -+extern unsigned int urandom(void); -+ - int endianTest = 1; - - static Bool tightVncProtocol = False; -@@ -177,8 +251,26 @@ - sig_rfbEncodingPointerPos, "Pointer position update"); - CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor, - sig_rfbEncodingLastRect, "LastRect protocol extension"); -+ -+ CapsAdd(encodingCaps, rfbEncodingNewFBSize, rfbTightVncVendor, -+ sig_rfbEncodingNewFBSize, "New FB size protocol extension"); -+ -+#ifdef TURBOVNC -+ CapsAdd(encodingCaps, rfbJpegQualityLevel1, rfbTurboVncVendor, -+ sig_rfbEncodingNewFBSize, "TurboJPEG quality level"); -+ CapsAdd(encodingCaps, rfbJpegSubsamp1X, rfbTurboVncVendor, -+ sig_rfbEncodingNewFBSize, "TurboJPEG subsampling level"); -+#endif - } - -+static char msgbuf[10000]; -+ -+static void wmsg(char *msg, int wait) { -+ fprintf(stderr, "%s", msg); -+ if (!use_tty() && !getenv("SSVNC_NO_MESSAGE_POPUP")) { -+ CreateMsg(msg, wait); -+ } -+} - - /* - * ConnectToRFBServer. -@@ -187,24 +279,179 @@ - Bool - ConnectToRFBServer(const char *hostname, int port) - { -- unsigned int host; -- -- if (!StringToIPAddr(hostname, &host)) { -- fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname); -- return False; -- } -+ char *q, *cmd = NULL; -+ Bool setnb; -+ struct stat sb; -+ -+ if (strstr(hostname, "exec=") == hostname) { -+ cmd = strdup(hostname); -+ q = strchr(cmd, '='); -+ *q = ' '; -+ if (getenv("SSVNC_BASEDIR")) { -+ char *base = getenv("SSVNC_BASEDIR"); -+ char *newcmd = (char *)malloc(strlen(base) + strlen(cmd) + 1000); -+ sprintf(newcmd, "%s/unwrap.so", base); -+ if (stat(newcmd, &sb) == 0) { -+#if (defined(__MACH__) && defined(__APPLE__)) -+ sprintf(newcmd, "DYLD_FORCE_FLAT_NAMESPACE=1; export DYLD_FORCE_FLAT_NAMESPACE; DYLD_INSERT_LIBRARIES='%s/unwrap.so'; export DYLD_INSERT_LIBRARIES; %s", base, cmd); -+#else -+ sprintf(newcmd, "LD_PRELOAD='%s/unwrap.so'; export LD_PRELOAD; %s", base, cmd); -+#endif -+ cmd = newcmd; -+ } -+ } -+ } - -- rfbsock = ConnectToTcpAddr(host, port); -+ if (cmd != NULL) { -+ int sfd[2]; -+ char *q, *cmd2 = strdup(cmd); -+ pid_t pid; -+ -+ q = strstr(cmd2, "pw="); -+ if (q && !getenv("SSVNC_SHOW_ULTRAVNC_DSM_PASSWORD")) { -+ q += strlen("pw="); -+ while (*q != '\0' && !isspace(*q)) { -+ *q = '*'; -+ q++; -+ } -+ } -+ -+ fprintf(stderr, "exec-cmd: %s\n\n", cmd2); -+ free(cmd2); -+ -+ if (! SocketPair(sfd)) { -+ return False; -+ } -+ if (0) { -+ fprintf(stderr, "sfd: %d %d\n", sfd[0], sfd[1]); -+ fflush(stderr); -+ } -+ -+ pid = fork(); -+ if (pid == -1) { -+ perror("fork"); -+ return False; -+ } -+ if (pid == 0) { -+ char *args[4]; -+ int d; -+ args[0] = "/bin/sh"; -+ args[1] = "-c"; -+ args[2] = cmd; -+ args[3] = NULL; -+ -+ close(sfd[1]); -+ dup2(sfd[0], 0); -+ dup2(sfd[0], 1); -+ for (d=3; d < 256; d++) { -+ if (d != sfd[0]) { -+ close(d); -+ } -+ } -+ execvp(args[0], args); -+ perror("exec"); -+ exit(1); -+ } else { -+ close(sfd[0]); -+ rfbsock = sfd[1]; -+ } -+ if (rfbsock < 0) { -+ sprintf(msgbuf,"Unable to connect to exec'd command: %s\n", cmd); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ } else if (strstr(hostname, "fd=") == hostname) { -+ rfbsock = atoi(hostname + strlen("fd=")); -+ } else if (strchr(hostname, '/') && stat(hostname, &sb) == 0) { -+ /* assume unix domain socket */ -+ char *thost = strdup(hostname); -+ -+ rfbsock = ConnectToUnixSocket(thost); -+ free(thost); -+ -+ if (rfbsock < 0) { -+ sprintf(msgbuf,"Unable to connect to VNC server (unix-domain socket: %s)\n", hostname); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ -+ } else { -+ rfbsock = ConnectToTcpAddr(hostname, port); -+ -+ if (rfbsock < 0 && !appData.noipv4) { -+ char *q, *hosttmp; -+ if (hostname[0] == '[') { -+ hosttmp = strdup(hostname+1); -+ } else { -+ hosttmp = strdup(hostname); -+ } -+ q = strrchr(hosttmp, ']'); -+ if (q) *q = '\0'; -+ if (strstr(hosttmp, "::ffff:") == hosttmp || strstr(hosttmp, "::FFFF:") == hosttmp) { -+ char *host = hosttmp + strlen("::ffff:"); -+ if (dotted_ip(host, 0)) { -+ fprintf(stderr, "ConnectToTcpAddr[ipv4]: re-trying connection using '%s'\n", host); -+ rfbsock = ConnectToTcpAddr(host, port); -+ } -+ } -+ free(hosttmp); -+ } -+ -+ if (rfbsock < 0) { -+ sprintf(msgbuf,"Unable to connect to VNC server (%s:%d)\n", hostname, port); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ } - -- if (rfbsock < 0) { -- fprintf(stderr,"Unable to connect to VNC server\n"); -- return False; -- } -+ setnb = SetNonBlocking(rfbsock); -+ return setnb; -+} - -- return SetNonBlocking(rfbsock); -+static void printFailureReason(void) { -+ CARD32 reasonLen; -+ ReadFromRFBServer((char *)&reasonLen, 4); -+ reasonLen = Swap32IfLE(reasonLen); -+ if (reasonLen < 4096) { -+ char *reason = (char *) malloc(reasonLen+1); -+ memset(reason, 0, reasonLen+1); -+ ReadFromRFBServer(reason, reasonLen); -+ sprintf(msgbuf, "Reason: %s\n", reason); -+ wmsg(msgbuf, 1); -+ free(reason); -+ } - } - -+static char *pr_sec_type(int type) { -+ char *str = "unknown"; -+ if (type == rfbSecTypeInvalid) str = "rfbSecTypeInvalid"; -+ if (type == rfbSecTypeNone) str = "rfbSecTypeNone"; -+ if (type == rfbSecTypeVncAuth) str = "rfbSecTypeVncAuth"; -+ if (type == rfbSecTypeRA2) str = "rfbSecTypeRA2"; -+ if (type == rfbSecTypeRA2ne) str = "rfbSecTypeRA2ne"; -+ if (type == rfbSecTypeTight) str = "rfbSecTypeTight"; -+ if (type == rfbSecTypeUltra) str = "rfbSecTypeUltra"; -+ -+ if (type == rfbSecTypeAnonTls) str = "rfbSecTypeAnonTls"; -+ if (type == rfbSecTypeVencrypt) str = "rfbSecTypeVencrypt"; -+ -+ if (type == (int) rfbUltraVncMsLogon) str = "rfbUltraVncMsLogon"; -+ return str; -+} -+ -+static char *pr_sec_subtype(int type) { -+ char *str = "unknown"; -+ if (type == rfbVencryptPlain) str = "rfbVencryptPlain"; -+ if (type == rfbVencryptTlsNone) str = "rfbVencryptTlsNone"; -+ if (type == rfbVencryptTlsVnc) str = "rfbVencryptTlsVnc"; -+ if (type == rfbVencryptTlsPlain) str = "rfbVencryptTlsPlain"; -+ if (type == rfbVencryptX509None) str = "rfbVencryptX509None"; -+ if (type == rfbVencryptX509Vnc) str = "rfbVencryptX509Vnc"; -+ if (type == rfbVencryptX509Plain) str = "rfbVencryptX509Plain"; -+ return str; -+} - -+extern void ProcessXtEvents(void); - /* - * InitialiseRFBConnection. - */ -@@ -212,211 +459,654 @@ - Bool - InitialiseRFBConnection(void) - { -- rfbProtocolVersionMsg pv; -- int server_major, server_minor; -- int viewer_major, viewer_minor; -- rfbClientInitMsg ci; -- int secType; -+ rfbProtocolVersionMsg pv; -+ rfbClientInitMsg ci; -+ int i, secType, anon_dh = 0, accept_uvnc = 0; -+ FILE *pd; -+ char *hsfile = NULL; -+ char *hsparam[128]; -+ char *envsetsec = getenv("SSVNC_SET_SECURITY_TYPE"); -+ char line[128]; -+ double dt = 0.0; - -- /* if the connection is immediately closed, don't report anything, so -- that pmw's monitor can make test connections */ -+ /* if the connection is immediately closed, don't report anything, so -+ that pmw's monitor can make test connections */ - -- if (listenSpecified) -- errorMessageOnReadFailure = False; -+ if (listenSpecified) { -+ errorMessageOnReadFailure = False; -+ } - -- if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) -- return False; -+ for (i=0; i < 128; i++) { -+ hsparam[i] = NULL; -+ } - -- errorMessageOnReadFailure = True; -+ skip_XtUpdateAll = 1; -+ ProcessXtEvents(); -+ skip_XtUpdateAll = 0; -+ -+ if (getenv("SSVNC_PREDIGESTED_HANDSHAKE")) { -+ double start = dnow(); -+ hsfile = getenv("SSVNC_PREDIGESTED_HANDSHAKE"); -+ while (dnow() < start + 10.0) { -+ int done = 0; -+ usleep(100 * 1000); -+ if ((pd = fopen(hsfile, "r")) != NULL) { -+ while (fgets(line, 128, pd) != NULL) { -+ if (strstr(line, "done") == line) { -+ done = 1; -+ usleep(100 * 1000); -+ break; -+ } -+ } -+ fclose(pd); -+ } -+ if (done) { -+ break; -+ } -+ } -+ if ((pd = fopen(hsfile, "r")) != NULL) { -+ i = 0; -+ while (fgets(line, 128, pd) != NULL) { -+ hsparam[i] = strdup(line); -+ fprintf(stderr, "%s", line); -+ if (i++ > 100) break; -+ } -+ fclose(pd); -+ } -+ unlink(hsfile); -+ } - -- pv[sz_rfbProtocolVersionMsg] = 0; -+ if (getenv("SSVNC_SKIP_RFB_PROTOCOL_VERSION")) { -+ viewer_major = 3; -+ viewer_minor = 8; -+ goto end_of_proto_msg; -+ } else if (hsfile) { -+ int k = 0; -+ while (hsparam[k] != NULL) { -+ char *str = hsparam[k++]; -+ if (strstr(str, "server=") == str) { -+ sprintf(pv, "%s", str + strlen("server=")); -+ goto readed_pv; -+ } -+ } -+ } - -- if (sscanf(pv, rfbProtocolVersionFormat, -- &server_major, &server_minor) != 2) { -- fprintf(stderr,"Not a valid VNC server\n"); -- return False; -- } -+ dt = dnow(); -+ if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) { -+ return False; -+ } -+ if (getenv("PRINT_DELAY1")) fprintf(stderr, "delay1: %.3f ms\n", (dnow() - dt) * 1000); -+ dt = 0.0; - -- viewer_major = rfbProtocolMajorVersion; -- if (server_major == 3 && server_minor >= rfbProtocolMinorVersion) { -- /* the server supports at least the standard protocol 3.7 */ -- viewer_minor = rfbProtocolMinorVersion; -- } else { -- /* any other server version, request the standard 3.3 */ -- viewer_minor = rfbProtocolFallbackMinorVersion; -- } -+ readed_pv: - -- fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n", -- viewer_major, viewer_minor); -+ errorMessageOnReadFailure = True; - -- sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor); -+ pv[sz_rfbProtocolVersionMsg] = 0; - -- if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) -- return False; -+ if (strstr(pv, "ID:") == pv) { -+ ; -+ } else if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) { -+ if (strstr(pv, "test") == pv) { -+ /* now some hacks for ultraVNC SC III (SSL) ... testA, etc */ -+ int i; -+ char *se = NULL; -+ -+ fprintf(stderr,"Trying UltraVNC Single Click III workaround: %s\n", pv); -+ for (i=0; i < 7 ; i++) { -+ pv[i] = pv[i+5]; -+ } -+ if (!ReadFromRFBServer(pv+7, 5)) { -+ return False; -+ } -+ -+ se = getenv("STUNNEL_EXTRA_OPTS"); -+ if (se == NULL) { -+ se = getenv("STUNNEL_EXTRA_OPTS_USER"); -+ } -+ if (se != NULL) { -+ if (strstr(se, "options")) { -+ if (strstr(se, "ALL") || strstr(se, "DONT_INSERT_EMPTY_FRAGMENTS")) { -+ ; /* good */ -+ } else { -+ se = NULL; -+ } -+ } else { -+ se = NULL; -+ } -+ } -+ if (se == NULL) { -+ msgbuf[0] = '\0'; -+ strcat(msgbuf, "\n"); -+ strcat(msgbuf, "***************************************************************\n"); -+ strcat(msgbuf, "To work around UltraVNC SC III SSL dropping after a few minutes\n"); -+ strcat(msgbuf, "you may need to set STUNNEL_EXTRA_OPTS_USER='options = ALL'.\n"); -+ strcat(msgbuf, "***************************************************************\n"); -+ strcat(msgbuf, "\n"); -+ wmsg(msgbuf, 0); -+ } -+ if (strstr(pv, "ID:") == pv) { -+ goto check_ID_string; -+ } -+ if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) == 2) { -+ goto ultra_vnc_nonsense; -+ } -+ } -+ sprintf(msgbuf, "Not a valid VNC server: '%s'\n", pv); -+ wmsg(msgbuf, 1); -+ return False; -+ } - -- /* Read or select the security type. */ -- if (viewer_minor == rfbProtocolMinorVersion) { -- secType = SelectSecurityType(); -- } else { -- secType = ReadSecurityType(); -- } -- if (secType == rfbSecTypeInvalid) -- return False; -+ check_ID_string: -+ if (strstr(pv, "ID:") == pv) { -+ char tmp[256]; -+ fprintf(stderr, "UltraVNC Repeater string detected: %s\n", pv); -+ fprintf(stderr, "Pretending to be UltraVNC repeater: reading 250 bytes...\n\n"); -+ if (!ReadFromRFBServer(tmp, 250 - 12)) { -+ return False; -+ } -+ if (!ReadFromRFBServer(pv, 12)) { -+ return False; -+ } -+ if (sscanf(pv, rfbProtocolVersionFormat, &server_major, &server_minor) != 2) { -+ sprintf(msgbuf,"Not a valid VNC server: '%s'\n", pv); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ } - -- switch (secType) { -- case rfbSecTypeNone: -- fprintf(stderr, "No authentication needed\n"); -- break; -- case rfbSecTypeVncAuth: -- if (!AuthenticateVNC()) -- return False; -- break; -- case rfbSecTypeTight: -- tightVncProtocol = True; -- InitCapabilities(); -- if (!SetupTunneling()) -- return False; -- if (!PerformAuthenticationTight()) -- return False; -- break; -- default: /* should never happen */ -- fprintf(stderr, "Internal error: Invalid security type\n"); -- return False; -- } -+ ultra_vnc_nonsense: -+ fprintf(stderr,"\nProto: %s\n", pv); - -- ci.shared = (appData.shareDesktop ? 1 : 0); -+ viewer_major = 3; - -- if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) -- return False; -+ if (appData.rfbVersion != NULL && sscanf(appData.rfbVersion, "%d.%d", &viewer_major, &viewer_minor) == 2) { -+ fprintf(stderr,"Setting RFB version to %d.%d from -rfbversion.\n\n", viewer_major, viewer_minor); - -- if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) -- return False; -+ } else if (getenv("SSVNC_RFB_VERSION") != NULL && sscanf(getenv("SSVNC_RFB_VERSION"), "%d.%d", &viewer_major, &viewer_minor) == 2) { -+ fprintf(stderr,"Setting RFB version to %d.%d from SSVNC_RFB_VERSION.\n\n", viewer_major, viewer_minor); -+ -+ } else if (server_major > 3) { -+ viewer_minor = 8; -+ } else if (server_major == 3 && (server_minor == 14 || server_minor == 16)) { -+ /* hack for UltraVNC Single Click. They misuse rfb proto version */ -+ fprintf(stderr,"Setting RFB version to 3.3 for UltraVNC Single Click.\n\n"); -+ viewer_minor = 3; -+ -+ } else if (server_major == 3 && server_minor >= 8) { -+ /* the server supports at least the standard protocol 3.8 */ -+ viewer_minor = 8; -+ -+ } else if (server_major == 3 && server_minor == 7) { -+ /* the server supports at least the standard protocol 3.7 */ -+ viewer_minor = 7; -+ -+ } else { -+ /* any other server version, request the standard 3.3 */ -+ viewer_minor = 3; -+ } -+ /* n.b. Apple Remote Desktop uses 003.889, but we should be OK with 3.8 */ - -- si.framebufferWidth = Swap16IfLE(si.framebufferWidth); -- si.framebufferHeight = Swap16IfLE(si.framebufferHeight); -- si.format.redMax = Swap16IfLE(si.format.redMax); -- si.format.greenMax = Swap16IfLE(si.format.greenMax); -- si.format.blueMax = Swap16IfLE(si.format.blueMax); -- si.nameLength = Swap32IfLE(si.nameLength); -- -- /* FIXME: Check arguments to malloc() calls. */ -- desktopName = malloc(si.nameLength + 1); -- if (!desktopName) { -- fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n", -- (unsigned long)si.nameLength); -- return False; -- } -+ if (appData.msLogon) { -+ if (server_minor == 4) { -+ fprintf(stderr,"Setting RFB version to 3.4 for UltraVNC MS Logon.\n\n"); -+ viewer_minor = 4; -+ } -+ } -+ if (getenv("SSVNC_ACCEPT_POPUP_SC")) { -+ if (server_minor == -4 || server_minor == -6 || server_minor == 14 || server_minor == 16) { -+ /* 4 and 6 work too? */ -+ viewer_minor = server_minor; -+ accept_uvnc = 1; -+ fprintf(stderr,"Reset RFB version to 3.%d for UltraVNC SSVNC_ACCEPT_POPUP_SC.\n\n", viewer_minor); -+ } -+ } - -- if (!ReadFromRFBServer(desktopName, si.nameLength)) return False; -+ fprintf(stderr, "Connected to RFB server, using protocol version %d.%d\n", viewer_major, viewer_minor); - -- desktopName[si.nameLength] = 0; -+ if (hsfile) { -+ int k = 0; -+ while (hsparam[k] != NULL) { -+ char *str = hsparam[k++]; -+ if (strstr(str, "latency=") == str) { -+ latency = 1000. * atof(str + strlen("latency=")); -+ } -+ } -+ k = 0; -+ while (hsparam[k] != NULL) { -+ char *str = hsparam[k++]; -+ int v1, v2; -+ if (sscanf(str, "viewer=RFB %d.%d\n", &v1, &v2) == 2) { -+ viewer_major = v1; -+ viewer_minor = v2; -+ fprintf(stderr, "\nPre-Handshake set protocol version to: %d.%d Latency: %.2f ms\n", viewer_major, viewer_minor, latency); -+ goto end_of_proto_msg; -+ } -+ } -+ } -+ sprintf(pv, rfbProtocolVersionFormat, viewer_major, viewer_minor); - -- fprintf(stderr,"Desktop name \"%s\"\n",desktopName); -+ if (!appData.appShare) { -+ usleep(100*1000); -+ } -+ dt = dnow(); -+ if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) { -+ return False; -+ } - -- fprintf(stderr,"VNC server default format:\n"); -- PrintPixelFormat(&si.format); -+ end_of_proto_msg: - -- if (tightVncProtocol) { -- /* Read interaction capabilities (protocol 3.7t) */ -- if (!ReadInteractionCaps()) -- return False; -- } -+ if (envsetsec) { -+ secType = atoi(getenv("SSVNC_SET_SECURITY_TYPE")); -+ goto sec_type; -+ } -+ if (hsfile) { -+ int k = 0; -+ while (hsparam[k] != NULL) { -+ char *str = hsparam[k++]; -+ int st; -+ if (sscanf(str, "sectype=%d\n", &st) == 1) { -+ secType = st; -+ fprintf(stderr, "Pre-Handshake set Security-Type to: %d (%s)\n", st, pr_sec_type(st)); -+ if (secType == rfbSecTypeVencrypt) { -+ goto sec_type; -+ } else if (secType == rfbSecTypeAnonTls) { -+ break; -+ } -+ } -+ } -+ } - -- return True; -+ if (accept_uvnc) { -+ unsigned int msg_sz = 0; -+ unsigned int nimmer = 0; -+ char msg[3000]; -+ char *msg_buf, *sip = NULL, *sih = NULL; -+ -+ if (!ReadFromRFBServer((char *) &msg_sz, 4)) { -+ return False; -+ } -+ dt_out_sc = dnow(); -+ msg_sz = Swap32IfBE(msg_sz); -+ if (msg_sz > 1024) { -+ fprintf(stderr, "UVNC msg size too big: %d\n", msg_sz); -+ exit(1); -+ } -+ msg_buf = (char *)calloc(msg_sz + 100, 1); -+ if (!ReadFromRFBServer(msg_buf, msg_sz)) { -+ return False; -+ } -+ -+ if (0) { -+ fprintf(stderr, "msg_buf: "); -+ write(2, msg_buf, msg_sz); -+ fprintf(stderr, "\n"); -+ } -+ -+ sip = get_peer_ip(rfbsock); -+ if (strlen(sip) > 100) sip = "0.0.0.0"; -+ sih = ip2host(sip); -+ if (strlen(sih) > 300) sih = "unknown"; -+ -+ sprintf(msg, "\n(LISTEN) Reverse VNC connection from IP: %s\n Hostname: %s\n\n", sip, sih); -+ strcat(msg, "UltraVNC Server Message:\n"); -+ strcat(msg, msg_buf); -+ free(msg_buf); -+ strcat(msg, "\n\n"); -+ strcat(msg, "Accept or Reject VNC connection?"); -+ if (CreateMsg(msg, 2)) { -+ nimmer = 1; -+ fprintf(stderr, "Accepting connection.\n\n"); -+ } else { -+ nimmer = 0; -+ fprintf(stderr, "Refusing connection.\n\n"); -+ } -+ if (!WriteExact(rfbsock, (char *) &nimmer, 4)) { -+ return False; -+ } -+ } -+ -+ /* Read or select the security type. */ -+ dt_out = 0.0; -+ -+ skip_XtUpdateAll = 1; -+ if (viewer_minor >= 7 && !accept_uvnc) { -+ secType = SelectSecurityType(); -+ } else { -+ secType = ReadSecurityType(); -+ } -+ skip_XtUpdateAll = 0; -+ -+ if (accept_uvnc) { -+ dt_out = dt_out_sc; -+ } -+ -+ if (dt > 0.0 && dt_out > dt) { -+ latency = (dt_out - dt) * 1000; -+ } -+ -+ fprintf(stderr, "Security-Type: %d (%s) Latency: %.2f ms\n", (int) secType, pr_sec_type(secType), latency); -+ if (secType == rfbSecTypeInvalid) { -+ return False; -+ } -+ -+ sec_type: -+ -+ if (hsfile) { -+ int subsectype = 0; -+ int k = 0; -+ while (hsparam[k] != NULL) { -+ char *str = hsparam[k++]; -+ int st; -+ if (sscanf(str, "subtype=%d\n", &st) == 1) { -+ subsectype = st; -+ fprintf(stderr, "Pre-Handshake set Sub-Security-Type to: %d (%s)\n\n", st, pr_sec_subtype(st)); -+ break; -+ } -+ } -+ -+ if (!subsectype) { -+ ; -+ } else if (secType == rfbSecTypeVencrypt) { -+ if (subsectype == rfbVencryptTlsNone) { -+ anon_dh = 1; -+ secType = rfbSecTypeNone; -+ } else if (subsectype == rfbVencryptTlsVnc) { -+ anon_dh = 1; -+ secType = rfbSecTypeVncAuth; -+ } else if (subsectype == rfbVencryptTlsPlain) { -+ anon_dh = 1; -+ secType = rfbSecTypeNone; -+ } else if (subsectype == rfbVencryptX509None) { -+ secType = rfbSecTypeNone; -+ } else if (subsectype == rfbVencryptX509Vnc) { -+ secType = rfbSecTypeVncAuth; -+ } else if (subsectype == rfbVencryptX509Plain) { -+ secType = rfbSecTypeNone; -+ } -+ if (subsectype == rfbVencryptTlsPlain || subsectype == rfbVencryptX509Plain) { -+ usleep(300*1000); -+ } -+ if (subsectype == rfbVencryptTlsNone || subsectype == rfbVencryptTlsVnc || subsectype == rfbVencryptTlsPlain) { -+ char tmp[1000], line[100]; -+ tmp[0] = '\0'; -+ strcat(tmp, "\n"); -+ sprintf(line, "WARNING: Anonymous Diffie-Hellman TLS used (%s),\n", pr_sec_subtype(subsectype)); -+ strcat(tmp, line); -+ strcat(tmp, "WARNING: there will be *NO* Authentication of the VNC Server.\n"); -+ strcat(tmp, "WARNING: I.e. a Man-In-The-Middle attack is possible.\n"); -+ strcat(tmp, "WARNING: Configure the server to use X509 certs and verify them.\n\n"); -+ wmsg(tmp, 1); -+ } -+ if (subsectype == rfbVencryptTlsPlain || subsectype == rfbVencryptX509Plain) { -+ fprintf(stderr, "\nVeNCrypt Plain (username + passwd) selected.\n\n"); -+ if (appData.unixPW != NULL) { -+ unixpw(appData.unixPW, 1); -+ } else if (getenv("SSVNC_UNIXPW")) { -+ unixpw(getenv("SSVNC_UNIXPW"), 1); -+ } else { -+ unixpw(".", 1); -+ } -+ } -+ } -+ } -+ -+ switch (secType) { -+ case rfbSecTypeNone: -+ fprintf(stderr, "No VNC authentication needed\n"); -+ if (viewer_minor >= 8) { -+ CARD32 authResult; -+ -+ if (!ReadFromRFBServer((char *)&authResult, 4)) { -+ return False; -+ } -+ -+ authResult = Swap32IfLE(authResult); -+ -+ if (authResult == rfbVncAuthOK) { -+ fprintf(stderr, "VNC authentication succeeded (%d) for rfbSecTypeNone (RFB 3.8)\n", (int) authResult); -+ } else { -+ sprintf(msgbuf, "VNC authentication failed (%d) for rfbSecTypeNone (RFB 3.8)\n\n", (int) authResult); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ } -+ fprintf(stderr, "\n"); -+ break; -+ case rfbSecTypeVncAuth: -+ if (!AuthenticateVNC()) { -+ return False; -+ } -+ break; -+ case rfbSecTypeTight: -+ tightVncProtocol = True; -+ InitCapabilities(); -+ if (!SetupTunneling()) { -+ return False; -+ } -+ if (!PerformAuthenticationTight()) { -+ return False; -+ } -+ break; -+ case rfbUltraVncMsLogon: -+ if (!AuthUltraVncMsLogon()) { -+ return False; -+ } -+ break; -+ default: /* should never happen */ -+ sprintf(msgbuf, "Internal error: Invalid security type: %d\n", secType); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ -+ connect_time = dnow(); -+ -+ ci.shared = (appData.shareDesktop ? 1 : 0); -+ -+ if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) { -+ return False; -+ } -+ -+ if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) { -+ return False; -+ } -+ -+ si.framebufferWidth = Swap16IfLE(si.framebufferWidth); -+ si.framebufferHeight = Swap16IfLE(si.framebufferHeight); -+ si.format.redMax = Swap16IfLE(si.format.redMax); -+ si.format.greenMax = Swap16IfLE(si.format.greenMax); -+ si.format.blueMax = Swap16IfLE(si.format.blueMax); -+ si.nameLength = Swap32IfLE(si.nameLength); -+ -+ if (appData.chatOnly) { -+ si.framebufferWidth = 32; -+ si.framebufferHeight = 32; -+ } -+ -+ /* FIXME: Check arguments to malloc() calls. */ -+ desktopName = malloc(si.nameLength + 1); -+ memset(desktopName, 0, si.nameLength + 1); -+ if (!desktopName) { -+ fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n", -+ (unsigned long)si.nameLength); -+ return False; -+ } -+ -+ if (!ReadFromRFBServer(desktopName, si.nameLength)) { -+ return False; -+ } -+ -+ desktopName[si.nameLength] = 0; -+ -+ if (appData.appShare) { -+ int x_hint, y_hint; -+ char *p, *q = NULL; -+ p = desktopName; -+ while (*p != '\0') { -+ char *t = strstr(p, " XY="); -+ if (t) q = t; -+ p++; -+ } -+ if (q) { -+ int ok = 1; -+ p = q + strlen(" XY="); -+ while (*p != '\0') { -+ if (!strpbrk(p, "0123456789,+-")) { -+ ok = 0; -+ } -+ p++; -+ } -+ if (ok && sscanf(q+1, "XY=%d,%d", &x_hint, &y_hint) == 2) { -+ fprintf(stderr,"Using x11vnc appshare position: %s\n\n", q); -+ *q = '\0'; -+ appshare_x_hint = x_hint; -+ appshare_y_hint = y_hint; -+ } -+ } -+ } -+ -+ fprintf(stderr,"Desktop name \"%s\"\n\n", desktopName); -+ -+ fprintf(stderr,"VNC server default format:\n"); -+ PrintPixelFormat(&si.format); -+ -+ if (tightVncProtocol) { -+ /* Read interaction capabilities (protocol 3.7t) */ -+ if (!ReadInteractionCaps()) { -+ return False; -+ } -+ } -+ -+ return True; - } - - - /* -- * Read security type from the server (protocol version 3.3) -+ * Read security type from the server (protocol 3.3) - */ - - static int - ReadSecurityType(void) - { -- CARD32 secType; -+ CARD32 secType; - -- /* Read the security type */ -- if (!ReadFromRFBServer((char *)&secType, sizeof(secType))) -- return rfbSecTypeInvalid; -+ /* Read the security type */ -+ if (!ReadFromRFBServer((char *)&secType, sizeof(secType))) { -+ return rfbSecTypeInvalid; -+ } -+ dt_out = dnow(); - -- secType = Swap32IfLE(secType); -+ secType = Swap32IfLE(secType); - -- if (secType == rfbSecTypeInvalid) { -- ReadConnFailedReason(); -- return rfbSecTypeInvalid; -- } -+ if (secType == rfbSecTypeInvalid) { -+ ReadConnFailedReason(); -+ return rfbSecTypeInvalid; -+ } - -- if (secType != rfbSecTypeNone && secType != rfbSecTypeVncAuth) { -- fprintf(stderr, "Unknown security type from RFB server: %d\n", -- (int)secType); -- return rfbSecTypeInvalid; -- } -+ if (secType == rfbSecTypeNone) { -+ ; /* OK */ -+ } else if (secType == rfbSecTypeVncAuth) { -+ ; /* OK */ -+ } else if (secType == rfbUltraVncMsLogon) { -+ ; /* OK */ -+ } else { -+ sprintf(msgbuf, "Unknown security type from RFB server: %d\n", (int)secType); -+ wmsg(msgbuf, 1); -+ return rfbSecTypeInvalid; -+ } - -- return (int)secType; -+ return (int)secType; - } - - - /* -- * Select security type from the server's list (protocol version 3.7) -+ * Select security type from the server's list (protocol 3.7) - */ - - static int - SelectSecurityType(void) - { -- CARD8 nSecTypes; -- char *secTypeNames[] = {"None", "VncAuth"}; -- CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth}; -- int nKnownSecTypes = sizeof(knownSecTypes); -- CARD8 *secTypes; -- CARD8 secType = rfbSecTypeInvalid; -- int i, j; -- -- /* Read the list of secutiry types. */ -- if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes))) -- return rfbSecTypeInvalid; -- -- if (nSecTypes == 0) { -- ReadConnFailedReason(); -- return rfbSecTypeInvalid; -- } -+ CARD8 nSecTypes; -+ char *secTypeNames[] = {"None", "VncAuth"}; -+ CARD8 knownSecTypes[] = {rfbSecTypeNone, rfbSecTypeVncAuth}; -+ int nKnownSecTypes = sizeof(knownSecTypes); -+ CARD8 *secTypes; -+ CARD8 secType = rfbSecTypeInvalid; -+ int i, j; -+ -+ if (secTypeNames) {} -+ -+ /* Read the list of security types. */ -+ if (!ReadFromRFBServer((char *)&nSecTypes, sizeof(nSecTypes))) { -+ return rfbSecTypeInvalid; -+ } -+ dt_out = dnow(); - -- secTypes = malloc(nSecTypes); -- if (!ReadFromRFBServer((char *)secTypes, nSecTypes)) -- return rfbSecTypeInvalid; -- -- /* Find out if the server supports TightVNC protocol extensions */ -- for (j = 0; j < (int)nSecTypes; j++) { -- if (secTypes[j] == rfbSecTypeTight) { -- free(secTypes); -- secType = rfbSecTypeTight; -- if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) -- return rfbSecTypeInvalid; -- fprintf(stderr, "Enabling TightVNC protocol extensions\n"); -- return rfbSecTypeTight; -- } -- } -+ if (nSecTypes == 0) { -+ ReadConnFailedReason(); -+ return rfbSecTypeInvalid; -+ } - -- /* Find first supported security type */ -- for (j = 0; j < (int)nSecTypes; j++) { -- for (i = 0; i < nKnownSecTypes; i++) { -- if (secTypes[j] == knownSecTypes[i]) { -- secType = secTypes[j]; -- if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) { -- free(secTypes); -- return rfbSecTypeInvalid; -- } -- break; -- } -- } -- if (secType != rfbSecTypeInvalid) break; -- } -+ secTypes = malloc(nSecTypes); -+ if (!ReadFromRFBServer((char *)secTypes, nSecTypes)) { -+ return rfbSecTypeInvalid; -+ } -+ -+ if (getenv("SSVNC_DEBUG_SEC_TYPES")) { -+ for (j = 0; j < (int)nSecTypes; j++) { -+ fprintf(stderr, "sec-type[%d] %d\n", j, (int) secTypes[j]); -+ } -+ } -+ -+ /* Find out if the server supports TightVNC protocol extensions */ -+ for (j = 0; j < (int)nSecTypes; j++) { -+ if (getenv("VNCVIEWER_NO_SEC_TYPE_TIGHT")) { -+ break; -+ } -+ if (getenv("SSVNC_NO_SEC_TYPE_TIGHT")) { -+ break; -+ } -+#ifdef TURBOVNC -+ break; -+#endif -+ if (secTypes[j] == rfbSecTypeTight) { -+ free(secTypes); -+ secType = rfbSecTypeTight; -+ if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) { -+ return rfbSecTypeInvalid; -+ } -+ fprintf(stderr, "Enabling TightVNC protocol extensions\n"); -+ return rfbSecTypeTight; -+ } -+ } -+ -+ /* Find first supported security type */ -+ for (j = 0; j < (int)nSecTypes; j++) { -+ for (i = 0; i < nKnownSecTypes; i++) { -+ if (secTypes[j] == knownSecTypes[i]) { -+ secType = secTypes[j]; -+ if (!WriteExact(rfbsock, (char *)&secType, sizeof(secType))) { -+ free(secTypes); -+ return rfbSecTypeInvalid; -+ } -+ break; -+ } -+ } -+ if (secType != rfbSecTypeInvalid) { -+ break; -+ } -+ } - -- free(secTypes); -+ if (secType == rfbSecTypeInvalid) { -+ fprintf(stderr, "Server did not offer supported security type:\n"); -+ for (j = 0; j < (int)nSecTypes; j++) { -+ fprintf(stderr, " sectype[%d] %d\n", j, (int) secTypes[j]); -+ } -+ } - -- if (secType == rfbSecTypeInvalid) -- fprintf(stderr, "Server did not offer supported security type\n"); -+ free(secTypes); - -- return (int)secType; -+ return (int)secType; - } - - -@@ -451,6 +1141,9 @@ - return True; - } - -+static char *restart_session_pw = NULL; -+static int restart_session_len = 0; -+ - - /* - * Negotiate authentication scheme (protocol version 3.7t) -@@ -459,58 +1152,406 @@ - static Bool - PerformAuthenticationTight(void) - { -- rfbAuthenticationCapsMsg caps; -- CARD32 authScheme; -- int i; -+ rfbAuthenticationCapsMsg caps; -+ CARD32 authScheme; -+ int i; - -- /* In the protocol version 3.7t, the server informs us about supported -- authentication schemes. Here we read this information. */ -+ /* In the protocol version 3.7t, the server informs us about supported -+ authentication schemes. Here we read this information. */ - -- if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg)) -- return False; -+ if (!ReadFromRFBServer((char *)&caps, sz_rfbAuthenticationCapsMsg)) { -+ return False; -+ } - -- caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes); -+ caps.nAuthTypes = Swap32IfLE(caps.nAuthTypes); - -- if (!caps.nAuthTypes) { -- fprintf(stderr, "No authentication needed\n"); -- return True; -- } -+ if (!caps.nAuthTypes) { -+ fprintf(stderr, "No VNC authentication needed\n\n"); -+ if (viewer_minor >= 8) { -+ CARD32 authResult; -+ -+ if (!ReadFromRFBServer((char *)&authResult, 4)) { -+ return False; -+ } -+ -+ authResult = Swap32IfLE(authResult); -+ -+ if (authResult == rfbVncAuthOK) { -+ fprintf(stderr, "VNC authentication succeeded (%d) for PerformAuthenticationTight rfbSecTypeNone (RFB 3.8)\n", (int) authResult); -+ } else { -+ sprintf(msgbuf, "VNC authentication failed (%d) for PerformAuthenticationTight rfbSecTypeNone (RFB 3.8)\n\n", (int) authResult); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ } -+ return True; -+ } - -- if (!ReadCapabilityList(authCaps, caps.nAuthTypes)) -- return False; -+ if (!ReadCapabilityList(authCaps, caps.nAuthTypes)) { -+ return False; -+ } - -- /* Prefer Unix login authentication if a user name was given. */ -- if (appData.userLogin && CapsIsEnabled(authCaps, rfbAuthUnixLogin)) { -- authScheme = Swap32IfLE(rfbAuthUnixLogin); -- if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme))) -- return False; -- return AuthenticateUnixLogin(); -- } -+ /* Prefer Unix login authentication if a user name was given. */ -+ if (appData.userLogin && CapsIsEnabled(authCaps, rfbAuthUnixLogin)) { -+ authScheme = Swap32IfLE(rfbAuthUnixLogin); -+ if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme))) { -+ return False; -+ } -+ return AuthenticateUnixLogin(); -+ } - -- /* Otherwise, try server's preferred authentication scheme. */ -- for (i = 0; i < CapsNumEnabled(authCaps); i++) { -- authScheme = CapsGetByOrder(authCaps, i); -- if (authScheme != rfbAuthUnixLogin && authScheme != rfbAuthVNC) -- continue; /* unknown scheme - cannot use it */ -- authScheme = Swap32IfLE(authScheme); -- if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme))) -- return False; -- authScheme = Swap32IfLE(authScheme); /* convert it back */ -- if (authScheme == rfbAuthUnixLogin) { -- return AuthenticateUnixLogin(); -- } else if (authScheme == rfbAuthVNC) { -- return AuthenticateVNC(); -- } else { -- /* Should never happen. */ -- fprintf(stderr, "Assertion failed: unknown authentication scheme\n"); -- return False; -- } -- } -+ /* Otherwise, try server's preferred authentication scheme. */ -+ for (i = 0; i < CapsNumEnabled(authCaps); i++) { -+ authScheme = CapsGetByOrder(authCaps, i); -+ if (authScheme != rfbAuthUnixLogin && authScheme != rfbAuthVNC) { -+ continue; /* unknown scheme - cannot use it */ -+ } -+ authScheme = Swap32IfLE(authScheme); -+ if (!WriteExact(rfbsock, (char *)&authScheme, sizeof(authScheme))) { -+ return False; -+ } -+ authScheme = Swap32IfLE(authScheme); /* convert it back */ -+ if (authScheme == rfbAuthUnixLogin) { -+ return AuthenticateUnixLogin(); -+ } else if (authScheme == rfbAuthVNC) { -+ return AuthenticateVNC(); -+ } else { -+ /* Should never happen. */ -+ fprintf(stderr, "Assertion failed: unknown authentication scheme\n"); -+ return False; -+ } -+ } - -- fprintf(stderr, "No suitable authentication schemes offered by server\n"); -- return False; -+ sprintf(msgbuf, "No suitable authentication schemes offered by server\n"); -+ wmsg(msgbuf, 1); -+ return False; -+} -+ -+#if 0 -+unsigned char encPasswd[8]; -+unsigned char encPasswd_MSLOGON[32]; -+char clearPasswd_MSLOGIN[256]; -+static Bool old_ultravnc_mslogon_code(void) { -+ char *passwd = NULL; -+ CARD8 challenge_mslogon[CHALLENGESIZE_MSLOGON]; -+ -+ /* code from the old uvnc way (1.0.2?) that would go into AuthenticateVNC() template */ -+ -+ if (appData.msLogon != NULL) { -+ raiseme(1); -+ if (!strcmp(appData.msLogon, "1")) { -+ char tmp[256]; -+ fprintf(stderr, "\nUltraVNC MS Logon Username[@Domain]: "); -+ if (fgets(tmp, 256, stdin) == NULL) { -+ exit(1); -+ } -+ appData.msLogon = strdup(tmp); -+ } -+ passwd = getpass("UltraVNC MS Logon Password: "); -+ if (! passwd) { -+ exit(1); -+ } -+ fprintf(stderr, "\n"); -+ -+ UvncEncryptPasswd_MSLOGON(encPasswd_MSLOGON, passwd); -+ } -+ if (appData.msLogon) { -+ if (!ReadFromRFBServer((char *)challenge_mslogon, CHALLENGESIZE_MSLOGON)) { -+ return False; -+ } -+ } -+ if (appData.msLogon) { -+ int i; -+ char tmp[256]; -+ char *q, *domain = "."; -+ for (i=0; i < 32; i++) { -+ challenge_mslogon[i] = encPasswd_MSLOGON[i] ^ challenge_mslogon[i]; -+ } -+ q = strchr(appData.msLogon, '@'); -+ if (q) { -+ *q = '\0'; -+ domain = strdup(q+1); -+ } -+ memset(tmp, 0, sizeof(tmp)); -+ strcat(tmp, appData.msLogon); -+ if (!WriteExact(rfbsock, tmp, 256)) { -+ return False; -+ } -+ memset(tmp, 0, sizeof(tmp)); -+ strcat(tmp, domain); -+ if (!WriteExact(rfbsock, tmp, 256)) { -+ return False; -+ } -+ memset(tmp, 0, sizeof(tmp)); -+ strcat(tmp, passwd); -+ if (!WriteExact(rfbsock, tmp, CHALLENGESIZE_MSLOGON)) { -+ return False; -+ } -+ } - } -+#endif - -+static void hexprint(char *label, char *data, int len) { -+ int i; -+ fprintf(stderr, "%s: ", label); -+ for (i=0; i < len; i++) { -+ unsigned char c = (unsigned char) data[i]; -+ fprintf(stderr, "%02x ", (int) c); -+ if ((i+1) % 20 == 0) { -+ fprintf(stderr, "\n%s: ", label); -+ } -+ } -+ fprintf(stderr, "\n"); -+} -+ -+#define DH_MAX_BITS 31 -+static unsigned long long max_dh = ((unsigned long long) 1) << DH_MAX_BITS; -+ -+static unsigned long long bytes_to_uint64(char *bytes) { -+ unsigned long long result = 0; -+ int i; -+ -+ for (i=0; i < 8; i++) { -+ result <<= 8; -+ result += (unsigned char) bytes[i]; -+ } -+ return result; -+} -+ -+static void uint64_to_bytes(unsigned long long n, char *bytes) { -+ int i; -+ -+ for (i=0; i < 8; i++) { -+ bytes[i] = (unsigned char) (n >> (8 * (7 - i))); -+ } -+} -+ -+static void try_invert(char *wireuser, char *wirepass, unsigned long long actual_key) { -+ if (wireuser || wirepass || actual_key) {} -+ return; -+} -+ -+ -+static unsigned long long XpowYmodN(unsigned long long x, unsigned long long y, unsigned long long N) { -+ unsigned long long result = 1; -+ unsigned long long oneShift63 = ((unsigned long long) 1) << 63; -+ int i; -+ -+ for (i = 0; i < 64; y <<= 1, i++) { -+ result = result * result % N; -+ if (y & oneShift63) { -+ result = result * x % N; -+ } -+ } -+ return result; -+} -+ -+/* -+ * UltraVNC MS-Logon authentication (for v1.0.5 and later.) -+ */ -+ -+/* -+ * NOTE: The UltraVNC MS-Logon username and password exchange is -+ * VERY insecure. It can be brute forced in ~2e+9 operations. -+ * It's not clear we should support it... It is only worth using -+ * in an environment where no one is sniffing the network, in which -+ * case all of this DH exchange secrecy is unnecessary... -+ */ -+ -+static Bool AuthUltraVncMsLogon(void) { -+ CARD32 authResult; -+ char gen[8], mod[8], pub[8], rsp[8]; -+ char user[256], passwd[64], *gpw; -+ unsigned char key[8]; -+ unsigned long long ugen, umod, ursp, upub, uprv, ukey; -+ double now = dnow(); -+ int db = 0; -+ -+ if (getenv("SSVNC_DEBUG_MSLOGON")) { -+ db = atoi(getenv("SSVNC_DEBUG_MSLOGON")); -+ } -+ -+ fprintf(stderr, "\nAuthUltraVncMsLogon()\n"); -+ -+ if (!ReadFromRFBServer(gen, sizeof(gen))) { -+ return False; -+ } -+ if (db) hexprint("gen", gen, sizeof(gen)); -+ -+ if (!ReadFromRFBServer(mod, sizeof(mod))) { -+ return False; -+ } -+ if (db) hexprint("mod", mod, sizeof(mod)); -+ -+ if (!ReadFromRFBServer(rsp, sizeof(rsp))) { -+ return False; -+ } -+ if (db) hexprint("rsp", rsp, sizeof(rsp)); -+ -+ ugen = bytes_to_uint64(gen); -+ umod = bytes_to_uint64(mod); -+ ursp = bytes_to_uint64(rsp); -+ -+ if (db) { -+ fprintf(stderr, "ugen: 0x%016llx %12llu\n", ugen, ugen); -+ fprintf(stderr, "umod: 0x%016llx %12llu\n", umod, umod); -+ fprintf(stderr, "ursp: 0x%016llx %12llu\n", ursp, ursp); -+ } -+ -+ if (ugen > max_dh) { -+ fprintf(stderr, "ugen: too big: 0x%016llx\n", ugen); -+ return False; -+ } -+ -+ if (umod > max_dh) { -+ fprintf(stderr, "umod: too big: 0x%016llx\n", umod); -+ return False; -+ } -+ -+ /* make a random long long: */ -+ uprv = 0xffffffff * (now - (unsigned int) now); -+ uprv = uprv << 32; -+ uprv |= (unsigned long long) urandom(); -+ uprv = uprv % max_dh; -+ -+ if (db) fprintf(stderr, "uprv: 0x%016llx %12llu\n", uprv, uprv); -+ -+ upub = XpowYmodN(ugen, uprv, umod); -+ -+ if (db) fprintf(stderr, "upub: 0x%016llx %12llu\n", upub, upub); -+ -+ uint64_to_bytes(upub, pub); -+ -+ if (db) hexprint("pub", pub, sizeof(pub)); -+ -+ if (!WriteExact(rfbsock, (char *)pub, sizeof(pub))) { -+ return False; -+ } -+ if (db) fprintf(stderr, "wrote pub.\n"); -+ -+ if (ursp > max_dh) { -+ fprintf(stderr, "ursp: too big: 0x%016llx\n", ursp); -+ return False; -+ } -+ -+ ukey = XpowYmodN(ursp, uprv, umod); -+ -+ if (db) fprintf(stderr, "ukey: 0x%016llx %12llu\n", ukey, ukey); -+ -+ if (1) { -+ char tmp[10000]; -+ tmp[0] = '\0'; -+ strcat(tmp, "\n"); -+ strcat(tmp, "WARNING: The UltraVNC Diffie-Hellman Key is weak (key < 2e+9, i.e. 31 bits)\n"); -+ strcat(tmp, "WARNING: and so an eavesdropper could recover your MS-Logon username and\n"); -+ strcat(tmp, "WARNING: password via brute force in a few seconds of CPU time. \n"); -+ strcat(tmp, "WARNING: If this connection is NOT being tunnelled through a separate SSL or\n"); -+ strcat(tmp, "WARNING: SSH encrypted tunnel, consider things carefully before proceeding...\n"); -+ strcat(tmp, "WARNING: Do not enter an important username+password when prompted below if\n"); -+ strcat(tmp, "WARNING: there is a risk of an eavesdropper sniffing this connection.\n"); -+ strcat(tmp, "WARNING: UltraVNC MSLogon encryption is VERY weak. You've been warned!\n"); -+ wmsg(tmp, 1); -+ } -+ -+ uint64_to_bytes(ukey, (char *) key); -+ -+ if (appData.msLogon == NULL || !strcmp(appData.msLogon, "1")) { -+ char tmp[256], *q, *s; -+ if (!use_tty()) { -+ fprintf(stderr, "\nEnter UltraVNC MS-Logon Username[@Domain] in the popup.\n"); -+ s = DoUserDialog(); -+ } else { -+ raiseme(1); -+ fprintf(stderr, "\nUltraVNC MS-Logon Username[@Domain]: "); -+ if (fgets(tmp, 256, stdin) == NULL) { -+ exit(1); -+ } -+ s = strdup(tmp); -+ } -+ q = strchr(s, '\n'); -+ if (q) *q = '\0'; -+ appData.msLogon = strdup(s); -+ } -+ -+ if (!use_tty()) { -+ gpw = DoPasswordDialog(); -+ } else { -+ raiseme(1); -+ gpw = getpass("UltraVNC MS-Logon Password: "); -+ } -+ if (! gpw) { -+ return False; -+ } -+ fprintf(stderr, "\n"); -+ -+ memset(user, 0, sizeof(user)); -+ strncpy(user, appData.msLogon, 255); -+ -+ memset(passwd, 0, sizeof(passwd)); -+ strncpy(passwd, gpw, 63); -+ -+ if (db > 1) { -+ fprintf(stderr, "user='%s'\n", user); -+ fprintf(stderr, "pass='%s'\n", passwd); -+ } -+ -+ UvncEncryptBytes2((unsigned char *) user, sizeof(user), key); -+ UvncEncryptBytes2((unsigned char *) passwd, sizeof(passwd), key); -+ -+ if (getenv("TRY_INVERT")) { -+ try_invert(user, passwd, ukey); -+ exit(0); -+ } -+ -+ if (db) { -+ hexprint("user", user, sizeof(user)); -+ hexprint("pass", passwd, sizeof(passwd)); -+ } -+ -+ if (!WriteExact(rfbsock, user, sizeof(user))) { -+ return False; -+ } -+ if (db) fprintf(stderr, "wrote user.\n"); -+ -+ if (!WriteExact(rfbsock, passwd, sizeof(passwd))) { -+ return False; -+ } -+ if (db) fprintf(stderr, "wrote passwd.\n"); -+ -+ if (!ReadFromRFBServer((char *) &authResult, 4)) { -+ return False; -+ } -+ authResult = Swap32IfLE(authResult); -+ -+ if (db) fprintf(stderr, "authResult: %d\n", (int) authResult); -+ -+ switch (authResult) { -+ case rfbVncAuthOK: -+ fprintf(stderr, "UVNC MS-Logon authentication succeeded.\n\n"); -+ break; -+ case rfbVncAuthFailed: -+ fprintf(stderr, "UVNC MS-Logon authentication failed.\n"); -+ if (viewer_minor >= 8) { -+ printFailureReason(); -+ } else { -+ sprintf(msgbuf, "UVNC MS-Logon authentication failed.\n"); -+ wmsg(msgbuf, 1); -+ } -+ fprintf(stderr, "\n"); -+ return False; -+ case rfbVncAuthTooMany: -+ sprintf(msgbuf, "UVNC MS-Logon authentication failed - too many tries.\n\n"); -+ wmsg(msgbuf, 1); -+ return False; -+ default: -+ sprintf(msgbuf, "Unknown UVNC MS-Logon authentication result: %d\n\n", -+ (int)authResult); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ -+ return True; -+} - - /* - * Standard VNC authentication. -@@ -519,80 +1560,119 @@ - static Bool - AuthenticateVNC(void) - { -- CARD32 authScheme, authResult; -- CARD8 challenge[CHALLENGESIZE]; -- char *passwd; -- char buffer[64]; -- char* cstatus; -- int len; -+ CARD32 authScheme, authResult; -+ CARD8 challenge[CHALLENGESIZE]; -+ char *passwd = NULL; -+ char buffer[64]; -+ char* cstatus; -+ int len; -+ int restart = 0; - -- fprintf(stderr, "Performing standard VNC authentication\n"); -+ if (authScheme) {} - -- if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) -- return False; -+ fprintf(stderr, "\nPerforming standard VNC authentication\n"); - -- if (appData.passwordFile) { -- passwd = vncDecryptPasswdFromFile(appData.passwordFile); -- if (!passwd) { -- fprintf(stderr, "Cannot read valid password from file \"%s\"\n", -- appData.passwordFile); -- return False; -- } -- } else if (appData.autoPass) { -- passwd = buffer; -- cstatus = fgets(buffer, sizeof buffer, stdin); -- if (cstatus == NULL) -- buffer[0] = '\0'; -- else -- { -- len = strlen(buffer); -- if (len > 0 && buffer[len - 1] == '\n') -- buffer[len - 1] = '\0'; -- } -- } else if (appData.passwordDialog) { -- passwd = DoPasswordDialog(); -- } else { -- passwd = getpass("Password: "); -- } -+ if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) { -+ return False; -+ } -+ -+ if (restart_session_pw != NULL) { -+ passwd = restart_session_pw; -+ restart_session_pw = NULL; -+ restart = 1; -+ } else if (appData.passwordFile) { -+ passwd = vncDecryptPasswdFromFile(appData.passwordFile); -+ if (!passwd) { -+ sprintf(msgbuf, "Cannot read valid password from file \"%s\"\n", appData.passwordFile); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ } else if (appData.autoPass) { -+ passwd = buffer; -+ raiseme(1); -+ cstatus = fgets(buffer, sizeof buffer, stdin); -+ if (cstatus == NULL) { -+ buffer[0] = '\0'; -+ } else { -+ len = strlen(buffer); -+ if (len > 0 && buffer[len - 1] == '\n') { -+ buffer[len - 1] = '\0'; -+ } -+ } -+ } else if (getenv("VNCVIEWER_PASSWORD")) { -+ passwd = strdup(getenv("VNCVIEWER_PASSWORD")); -+ } else if (appData.passwordDialog || !use_tty()) { -+ passwd = DoPasswordDialog(); -+ } else { -+ raiseme(1); -+ passwd = getpass("VNC Password: "); -+ } - -- if (!passwd || strlen(passwd) == 0) { -- fprintf(stderr, "Reading password failed\n"); -- return False; -- } -- if (strlen(passwd) > 8) { -- passwd[8] = '\0'; -- } -+ if (getenv("VNCVIEWER_PASSWORD")) { -+ putenv("VNCVIEWER_PASSWORD=none"); -+ } - -- vncEncryptBytes(challenge, passwd); -+ if (restart) { -+#define EN0 0 -+#define DE1 1 -+ unsigned char s_fixedkey[8] = {23,82,107,6,35,78,88,7}; -+ deskey(s_fixedkey, DE1); -+ des(passwd, passwd); -+ } else { -+ if (!passwd || strlen(passwd) == 0) { -+ sprintf(msgbuf, "Reading password failed\n\n"); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ if (strlen(passwd) > 8) { -+ passwd[8] = '\0'; -+ } -+ } - -- /* Lose the password from memory */ -- memset(passwd, '\0', strlen(passwd)); -+ vncEncryptBytes(challenge, passwd); -+ - -- if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE)) -- return False; - -- if (!ReadFromRFBServer((char *)&authResult, 4)) -- return False; -+#if 0 -+ /* Lose the password from memory */ -+ memset(passwd, '\0', strlen(passwd)); -+#endif - -- authResult = Swap32IfLE(authResult); -+ if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE)) { -+ return False; -+ } - -- switch (authResult) { -- case rfbVncAuthOK: -- fprintf(stderr, "VNC authentication succeeded\n"); -- break; -- case rfbVncAuthFailed: -- fprintf(stderr, "VNC authentication failed\n"); -- return False; -- case rfbVncAuthTooMany: -- fprintf(stderr, "VNC authentication failed - too many tries\n"); -- return False; -- default: -- fprintf(stderr, "Unknown VNC authentication result: %d\n", -- (int)authResult); -- return False; -- } -+ if (!ReadFromRFBServer((char *)&authResult, 4)) { -+ return False; -+ } - -- return True; -+ authResult = Swap32IfLE(authResult); -+ -+ switch (authResult) { -+ case rfbVncAuthOK: -+ fprintf(stderr, "VNC authentication succeeded\n\n"); -+ break; -+ case rfbVncAuthFailed: -+ fprintf(stderr, "VNC authentication failed.\n"); -+ if (viewer_minor >= 8) { -+ printFailureReason(); -+ } else { -+ sprintf(msgbuf, "VNC authentication failed.\n"); -+ wmsg(msgbuf, 1); -+ } -+ fprintf(stderr, "\n"); -+ return False; -+ case rfbVncAuthTooMany: -+ sprintf(msgbuf, "VNC authentication failed - too many tries\n\n"); -+ wmsg(msgbuf, 1); -+ return False; -+ default: -+ sprintf(msgbuf, "Unknown VNC authentication result: %d\n\n", (int)authResult); -+ wmsg(msgbuf, 1); -+ return False; -+ } -+ -+ return True; - } - - /* -@@ -602,68 +1682,77 @@ - static Bool - AuthenticateUnixLogin(void) - { -- CARD32 loginLen, passwdLen, authResult; -- char *login; -- char *passwd; -- struct passwd *ps; -- -- fprintf(stderr, "Performing Unix login-style authentication\n"); -- -- if (appData.userLogin) { -- login = appData.userLogin; -- } else { -- ps = getpwuid(getuid()); -- login = ps->pw_name; -- } -+ CARD32 loginLen, passwdLen, authResult; -+ char *login; -+ char *passwd; -+ struct passwd *ps; -+ -+ fprintf(stderr, "\nPerforming Unix login-style authentication\n"); -+ -+ if (appData.userLogin) { -+ login = appData.userLogin; -+ } else { -+ ps = getpwuid(getuid()); -+ login = ps->pw_name; -+ } - -- fprintf(stderr, "Using user name \"%s\"\n", login); -+ fprintf(stderr, "Using user name \"%s\"\n", login); - -- if (appData.passwordDialog) { -- passwd = DoPasswordDialog(); -- } else { -- passwd = getpass("Password: "); -- } -- if (!passwd || strlen(passwd) == 0) { -- fprintf(stderr, "Reading password failed\n"); -- return False; -- } -+ if (appData.passwordDialog || !use_tty()) { -+ passwd = DoPasswordDialog(); -+ } else { -+ raiseme(1); -+ passwd = getpass("VNC Password: "); -+ } -+ if (!passwd || strlen(passwd) == 0) { -+ fprintf(stderr, "Reading password failed\n"); -+ return False; -+ } - -- loginLen = Swap32IfLE((CARD32)strlen(login)); -- passwdLen = Swap32IfLE((CARD32)strlen(passwd)); -+ loginLen = Swap32IfLE((CARD32)strlen(login)); -+ passwdLen = Swap32IfLE((CARD32)strlen(passwd)); - -- if (!WriteExact(rfbsock, (char *)&loginLen, sizeof(loginLen)) || -- !WriteExact(rfbsock, (char *)&passwdLen, sizeof(passwdLen))) -- return False; -+ if (!WriteExact(rfbsock, (char *)&loginLen, sizeof(loginLen)) || -+ !WriteExact(rfbsock, (char *)&passwdLen, sizeof(passwdLen))) { -+ return False; -+ } - -- if (!WriteExact(rfbsock, login, strlen(login)) || -- !WriteExact(rfbsock, passwd, strlen(passwd))) -- return False; -+ if (!WriteExact(rfbsock, login, strlen(login)) || -+ !WriteExact(rfbsock, passwd, strlen(passwd))) { -+ return False; -+ } - -- /* Lose the password from memory */ -- memset(passwd, '\0', strlen(passwd)); -+#if 0 -+ /* Lose the password from memory */ -+ memset(passwd, '\0', strlen(passwd)); -+#endif - -- if (!ReadFromRFBServer((char *)&authResult, sizeof(authResult))) -- return False; -+ if (!ReadFromRFBServer((char *)&authResult, sizeof(authResult))) { -+ return False; -+ } - -- authResult = Swap32IfLE(authResult); -+ authResult = Swap32IfLE(authResult); - -- switch (authResult) { -- case rfbVncAuthOK: -- fprintf(stderr, "Authentication succeeded\n"); -- break; -- case rfbVncAuthFailed: -- fprintf(stderr, "Authentication failed\n"); -- return False; -- case rfbVncAuthTooMany: -- fprintf(stderr, "Authentication failed - too many tries\n"); -- return False; -- default: -- fprintf(stderr, "Unknown authentication result: %d\n", -- (int)authResult); -- return False; -- } -+ switch (authResult) { -+ case rfbVncAuthOK: -+ fprintf(stderr, "Authentication succeeded\n\n"); -+ break; -+ case rfbVncAuthFailed: -+ sprintf(msgbuf, "Authentication failed\n\n"); -+ wmsg(msgbuf, 1); -+ return False; -+ case rfbVncAuthTooMany: -+ sprintf(msgbuf, "Authentication failed - too many tries\n\n"); -+ wmsg(msgbuf, 1); -+ return False; -+ default: -+ sprintf(msgbuf, "Unknown authentication result: %d\n\n", -+ (int)authResult); -+ wmsg(msgbuf, 1); -+ return False; -+ } - -- return True; -+ return True; - } - - -@@ -675,19 +1764,20 @@ - static Bool - ReadInteractionCaps(void) - { -- rfbInteractionCapsMsg intr_caps; -+ rfbInteractionCapsMsg intr_caps; - -- /* Read the counts of list items following */ -- if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg)) -- return False; -- intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes); -- intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes); -- intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes); -- -- /* Read the lists of server- and client-initiated messages */ -- return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) && -- ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) && -- ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes)); -+ /* Read the counts of list items following */ -+ if (!ReadFromRFBServer((char *)&intr_caps, sz_rfbInteractionCapsMsg)) { -+ return False; -+ } -+ intr_caps.nServerMessageTypes = Swap16IfLE(intr_caps.nServerMessageTypes); -+ intr_caps.nClientMessageTypes = Swap16IfLE(intr_caps.nClientMessageTypes); -+ intr_caps.nEncodingTypes = Swap16IfLE(intr_caps.nEncodingTypes); -+ -+ /* Read the lists of server- and client-initiated messages */ -+ return (ReadCapabilityList(serverMsgCaps, intr_caps.nServerMessageTypes) && -+ ReadCapabilityList(clientMsgCaps, intr_caps.nClientMessageTypes) && -+ ReadCapabilityList(encodingCaps, intr_caps.nEncodingTypes)); - } - - -@@ -697,22 +1787,70 @@ - * many records to read from the socket. - */ - --static Bool --ReadCapabilityList(CapsContainer *caps, int count) --{ -- rfbCapabilityInfo msginfo; -- int i; -+static Bool -+ReadCapabilityList(CapsContainer *caps, int count) -+{ -+ rfbCapabilityInfo msginfo; -+ int i; -+ -+ for (i = 0; i < count; i++) { -+ if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo)) { -+ return False; -+ } -+ msginfo.code = Swap32IfLE(msginfo.code); -+ CapsEnable(caps, &msginfo); -+ } -+ -+ return True; -+} -+ - -- for (i = 0; i < count; i++) { -- if (!ReadFromRFBServer((char *)&msginfo, sz_rfbCapabilityInfo)) -- return False; -- msginfo.code = Swap32IfLE(msginfo.code); -- CapsEnable(caps, &msginfo); -- } -+/* used to have !tunnelSpecified */ - -- return True; -+static int guess_compresslevel(void) { -+ int n; -+ if (latency > 200.0) { -+ n = 8; -+ } else if (latency > 100.0) { -+ n = 7; -+ } else if (latency > 60.0) { -+ n = 6; -+ } else if (latency > 15.0) { -+ n = 4; -+ } else if (latency > 8.0) { -+ n = 2; -+ } else if (latency > 0.0) { -+ n = 1; -+ } else { -+ /* no latency measurement */ -+ n = 3; -+ } -+ return n; - } - -+static int guess_qualitylevel(void) { -+ int n; -+ if (latency > 200.0) { -+ n = 4; -+ } else if (latency > 100.0) { -+ n = 5; -+ } else if (latency > 60.0) { -+ n = 6; -+ } else if (latency > 15.0) { -+ n = 7; -+ } else if (latency > 8.0) { -+ n = 8; -+ } else if (latency > 0.0) { -+ n = 9; -+ } else { -+ /* no latency measurement */ -+ n = 6; -+ } -+#ifdef TURBOVNC -+ n *= 10; -+#endif -+ return n; -+} - - /* - * SetFormatAndEncodings. -@@ -729,6 +1867,21 @@ - Bool requestCompressLevel = False; - Bool requestQualityLevel = False; - Bool requestLastRectEncoding = False; -+ Bool requestNewFBSizeEncoding = True; -+ Bool requestTextChatEncoding = True; -+ Bool requestSubsampLevel = False; -+ int dsm = 0; -+ int tQL, tQLmax = 9; -+ static int qlmsg = 0, clmsg = 0; -+#ifdef TURBOVNC -+ tQLmax = 100; -+#endif -+ -+ if (requestTextChatEncoding || requestSubsampLevel || tQL) {} -+ -+#if 0 -+ fprintf(stderr, "SetFormatAndEncodings: sent_FBU state: %2d\n", sent_FBU); -+#endif - - spf.type = rfbSetPixelFormat; - spf.format = myFormat; -@@ -736,15 +1889,32 @@ - spf.format.greenMax = Swap16IfLE(spf.format.greenMax); - spf.format.blueMax = Swap16IfLE(spf.format.blueMax); - -+ -+ currentMsg = rfbSetPixelFormat; - if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg)) - return False; - - se->type = rfbSetEncodings; - se->nEncodings = 0; - -+ if (appData.ultraDSM) { -+ dsm = 1; -+ } -+ - if (appData.encodingsString) { - char *encStr = appData.encodingsString; - int encStrLen; -+ if (strchr(encStr, ',')) { -+ char *p; -+ encStr = strdup(encStr); -+ p = encStr; -+ while (*p != '\0') { -+ if (*p == ',') { -+ *p = ' '; -+ } -+ p++; -+ } -+ } - do { - char *nextEncStr = strchr(encStr, ' '); - if (nextEncStr) { -@@ -754,50 +1924,102 @@ - encStrLen = strlen(encStr); - } - -+if (getenv("DEBUG_SETFORMAT")) { -+ fprintf(stderr, "encs: "); -+ write(2, encStr, encStrLen); -+ fprintf(stderr, "\n"); -+} -+ - if (strncasecmp(encStr,"raw",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw); - } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect); -- } else if (strncasecmp(encStr,"tight",encStrLen) == 0) { -+ } else if (strncasecmp(encStr,"tight",encStrLen) == 0 && !dsm) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight); - requestLastRectEncoding = True; -- if (appData.compressLevel >= 0 && appData.compressLevel <= 9) -- requestCompressLevel = True; -- if (appData.enableJPEG) -- requestQualityLevel = True; -+ if (appData.compressLevel >= 0 && appData.compressLevel <= 9) { -+ requestCompressLevel = True; -+ } -+ if (appData.enableJPEG) { -+ requestQualityLevel = True; -+ } -+#ifdef TURBOVNC -+ requestSubsampLevel = True; -+#endif - } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile); -- } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) { -+ } else if (strncasecmp(encStr,"zlib",encStrLen) == 0 && !dsm) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib); -- if (appData.compressLevel >= 0 && appData.compressLevel <= 9) -- requestCompressLevel = True; -- } else if (strncasecmp(encStr,"corre",encStrLen) == 0) { -+ if (appData.compressLevel >= 0 && appData.compressLevel <= 9) { -+ requestCompressLevel = True; -+ } -+ } else if (strncasecmp(encStr,"corre",encStrLen) == 0 && !dsm) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE); - } else if (strncasecmp(encStr,"rre",encStrLen) == 0) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE); -+ } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) { -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZRLE); -+#if DO_ZYWRLE -+ } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) { -+ int qlevel = appData.qualityLevel; -+ if (qlevel < 0 || qlevel > tQLmax) qlevel = guess_qualitylevel(); -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZYWRLE); -+ requestQualityLevel = True; -+ if (qlevel < 3) { -+ zywrle_level = 3; -+ } else if (qlevel < 6) { -+ zywrle_level = 2; -+ } else { -+ zywrle_level = 1; -+ } -+#endif - } else { - fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr); -+ if (dsm && strstr(encStr, "tight") == encStr) fprintf(stderr, "tight encoding does not yet work with ultraDSM, skipping it.\n"); -+ if (dsm && strstr(encStr, "corre") == encStr) fprintf(stderr, "corre encoding does not yet work with ultraDSM, skipping it.\n"); -+ if (dsm && strstr(encStr, "zlib" ) == encStr) fprintf(stderr, "zlib encoding does not yet work with ultraDSM, skipping it.\n"); - } - - encStr = nextEncStr; - } while (encStr && se->nEncodings < MAX_ENCODINGS); - - if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) { -- encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + -- rfbEncodingCompressLevel0); -+ ; -+ } else if (se->nEncodings < MAX_ENCODINGS) { -+ appData.compressLevel = guess_compresslevel(); -+ if (clmsg++ == 0) fprintf(stderr, "guessed: -compresslevel %d\n", appData.compressLevel); - } -+ encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + rfbEncodingCompressLevel0); - - if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) { -- if (appData.qualityLevel < 0 || appData.qualityLevel > 9) -- appData.qualityLevel = 5; -- encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + -- rfbEncodingQualityLevel0); -+ if (appData.qualityLevel < 0 || appData.qualityLevel > tQLmax) { -+ appData.qualityLevel = guess_qualitylevel(); -+ if (qlmsg++ == 0) fprintf(stderr, "guessed: -qualitylevel %d\n", appData.qualityLevel); -+ } -+ } else if (se->nEncodings < MAX_ENCODINGS) { -+ appData.qualityLevel = guess_qualitylevel(); -+ if (qlmsg++ == 0) fprintf(stderr, "guessed: -qualitylevel %d\n", appData.qualityLevel); -+ } -+#ifdef TURBOVNC -+ tQL = appData.qualityLevel / 10; -+ if (tQL < 0) tQL = 1; -+ if (tQL > 9) tQL = 9; -+ encs[se->nEncodings++] = Swap32IfLE(tQL + rfbEncodingQualityLevel0); -+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbJpegQualityLevel1 - 1); -+ if (se->nEncodings < MAX_ENCODINGS && requestSubsampLevel) { -+ if (appData.subsampLevel < 0 || appData.subsampLevel > TVNC_SAMPOPT - 1) { -+ appData.subsampLevel = TVNC_1X; -+ } -+ encs[se->nEncodings++] = Swap32IfLE(appData.subsampLevel + rfbJpegSubsamp1X); - } -+#else -+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbEncodingQualityLevel0); -+#endif - - if (appData.useRemoteCursor) { - if (se->nEncodings < MAX_ENCODINGS) - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor); -- if (se->nEncodings < MAX_ENCODINGS) -+ if (se->nEncodings < MAX_ENCODINGS && !appData.useX11Cursor) - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor); - if (se->nEncodings < MAX_ENCODINGS) - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos); -@@ -806,10 +2028,16 @@ - if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); - } -- } -- else { -+ -+ if (se->nEncodings < MAX_ENCODINGS && requestNewFBSizeEncoding) { -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize); -+ } -+ -+ } else { -+ /* DIFFERENT CASE */ -+ - if (SameMachine(rfbsock)) { -- if (!tunnelSpecified) { -+ if (!tunnelSpecified && appData.useRawLocal) { - fprintf(stderr,"Same machine: preferring raw encoding\n"); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw); - } else { -@@ -818,44 +2046,84 @@ - } - - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect); -- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight); -+ if (!dsm) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight); -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZRLE); -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZYWRLE); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile); -- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib); -- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE); -+ if (!dsm) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib); -+ if (!dsm) encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCoRRE); - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRRE); - -- if (appData.compressLevel >= 0 && appData.compressLevel <= 9) { -- encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + -- rfbEncodingCompressLevel0); -- } else if (!tunnelSpecified) { -- /* If -tunnel option was provided, we assume that server machine is -- not in the local network so we use default compression level for -- tight encoding instead of fast compression. Thus we are -- requesting level 1 compression only if tunneling is not used. */ -- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCompressLevel1); -- } -- -- if (appData.enableJPEG) { -- if (appData.qualityLevel < 0 || appData.qualityLevel > 9) -- appData.qualityLevel = 5; -- encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + -- rfbEncodingQualityLevel0); -+ if (!dsm && appData.compressLevel >= 0 && appData.compressLevel <= 9) { -+ encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + rfbEncodingCompressLevel0); -+ } else { -+ /* -+ * OUT OF DATE: If -tunnel option was provided, we assume that server machine is -+ * not in the local network so we use default compression level for -+ * tight encoding instead of fast compression. Thus we are -+ * requesting level 1 compression only if tunneling is not used. -+ */ -+ appData.compressLevel = guess_compresslevel(); -+ if (clmsg++ == 0) fprintf(stderr, "guessed: -compresslevel %d\n", appData.compressLevel); -+ encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel + rfbEncodingCompressLevel0); -+ } -+ -+ if (!dsm && appData.enableJPEG) { -+ if (appData.qualityLevel < 0 || appData.qualityLevel > tQLmax) { -+ appData.qualityLevel = guess_qualitylevel(); -+ if (qlmsg++ == 0) fprintf(stderr, "guessed: -qualitylevel %d\n", appData.qualityLevel); -+ } -+ -+#ifdef TURBOVNC -+ requestSubsampLevel = True; -+ tQL = appData.qualityLevel / 10; -+ if (tQL < 0) tQL = 1; -+ if (tQL > 9) tQL = 9; -+ encs[se->nEncodings++] = Swap32IfLE(tQL + rfbEncodingQualityLevel0); -+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbJpegQualityLevel1 - 1); -+ if (se->nEncodings < MAX_ENCODINGS && requestSubsampLevel) { -+ if (appData.subsampLevel < 0 || appData.subsampLevel > TVNC_SAMPOPT - 1) { -+ appData.subsampLevel = TVNC_1X; -+ } -+ encs[se->nEncodings++] = Swap32IfLE(appData.subsampLevel + rfbJpegSubsamp1X); -+ } -+#else -+ encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel + rfbEncodingQualityLevel0); -+#endif -+ - } - - if (appData.useRemoteCursor) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor); -- encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor); -+ if (!appData.useX11Cursor) { -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor); -+ } - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos); - } - - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize); - } - - len = sz_rfbSetEncodingsMsg + se->nEncodings * 4; - -- se->nEncodings = Swap16IfLE(se->nEncodings); -+ if (!appData.ultraDSM) { -+ se->nEncodings = Swap16IfLE(se->nEncodings); - -- if (!WriteExact(rfbsock, buf, len)) return False; -+ if (!WriteExact(rfbsock, buf, len)) return False; -+ } else { -+ /* for UltraVNC encryption DSM we have to send each encoding separately (why?) */ -+ int i, errs = 0, nenc = se->nEncodings; -+ -+ se->nEncodings = Swap16IfLE(se->nEncodings); -+ -+ currentMsg = rfbSetEncodings; -+ if (!WriteExact(rfbsock, buf, sz_rfbSetEncodingsMsg)) errs++; -+ for (i=0; i < nenc; i++) { -+ if (!WriteExact(rfbsock, (char *)&encs[i], sizeof(CARD32))) errs++; -+ } -+ if (errs) return False; -+ } - - return True; - } -@@ -868,31 +2136,86 @@ - Bool - SendIncrementalFramebufferUpdateRequest() - { -- return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, -- si.framebufferHeight, True); -+ return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, -+ si.framebufferHeight, True); - } - -+time_t last_filexfer = 0; -+int delay_filexfer = 3; -+extern void CheckFileXfer(void); -+extern int rfbsock_is_ready(void); -+ -+ -+static int dyn = -1; -+extern int filexfer_sock; -+extern int filexfer_listen; - - /* - * SendFramebufferUpdateRequest. - */ -- - Bool - SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental) - { -- rfbFramebufferUpdateRequestMsg fur; -+ rfbFramebufferUpdateRequestMsg fur; -+ static int db = -1; - -- fur.type = rfbFramebufferUpdateRequest; -- fur.incremental = incremental ? 1 : 0; -- fur.x = Swap16IfLE(x); -- fur.y = Swap16IfLE(y); -- fur.w = Swap16IfLE(w); -- fur.h = Swap16IfLE(h); -+ if (db < 0) { -+ if (getenv("SSVNC_DEBUG_RECTS")) { -+ db = atoi(getenv("SSVNC_DEBUG_RECTS")); -+ } else { -+ db = 0; -+ } -+ } - -- if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) -- return False; -+ if (db) fprintf(stderr, "SendFramebufferUpdateRequest(%d, %d, %d, %d, incremental=%d)\n", x, y, w, h, (int) incremental); - -- return True; -+ if (dyn < 0) { -+ struct stat sb; -+ if (getenv("USER") && !strcmp(getenv("USER"), "runge")) { -+ if (stat("/tmp/nodyn", &sb) == 0) { -+ putenv("NOFTFBUPDATES=1"); -+ unlink("/tmp/nodyn"); -+ } -+ } -+ if (getenv("NOFTFBUPDATES")) { -+ dyn = 0; -+ } else { -+ dyn = 1; -+ } -+ } -+ -+ if (appData.fileActive && filexfer_sock >= 0) { -+ static int first = 1; -+ if (first) { -+ fprintf(stderr, "SFU: dynamic fb updates during filexfer: %d\n", dyn); -+ first = 0; -+ } -+if (db > 2 || 0) fprintf(stderr, "A sfur: %d %d %d %d d_last: %d\n", x, y, w, h, (int) (time(NULL) - last_filexfer)); -+ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) { -+ return True; -+ } -+ } -+if (db > 1) fprintf(stderr, "B sfur: %d %d %d %d\n", x, y, w, h); -+ -+ fur.type = rfbFramebufferUpdateRequest; -+ fur.incremental = incremental ? 1 : 0; -+ fur.x = Swap16IfLE(x); -+ fur.y = Swap16IfLE(y); -+ fur.w = Swap16IfLE(w); -+ fur.h = Swap16IfLE(h); -+ -+ if (incremental) { -+ sent_FBU = 1; -+ } else { -+ sent_FBU = 2; -+ } -+ -+ currentMsg = rfbFramebufferUpdateRequest; -+ if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) { -+ return False; -+ } -+ -+ return True; - } - - -@@ -903,19 +2226,38 @@ - Bool - SendPointerEvent(int x, int y, int buttonMask) - { -- rfbPointerEventMsg pe; -+ rfbPointerEventMsg pe; -+ -+ if (appData.fileActive) { -+ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) { -+#if 0 -+ fprintf(stderr, "skip SendPointerEvent: %d - %d\n", last_filexfer, time(NULL)); -+#endif -+ return True; -+ } -+ } - -- pe.type = rfbPointerEvent; -- pe.buttonMask = buttonMask; -- if (x < 0) x = 0; -- if (y < 0) y = 0; -- -- if (!appData.useX11Cursor) -- SoftCursorMove(x, y); -- -- pe.x = Swap16IfLE(x); -- pe.y = Swap16IfLE(y); -- return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg); -+ pe.type = rfbPointerEvent; -+ pe.buttonMask = buttonMask; -+ -+ if (scale_factor_x > 0.0 && scale_factor_x != 1.0) { -+ x /= scale_factor_x; -+ } -+ if (scale_factor_y > 0.0 && scale_factor_y != 1.0) { -+ y /= scale_factor_y; -+ } -+ -+ if (x < 0) x = 0; -+ if (y < 0) y = 0; -+ -+ if (!appData.useX11Cursor) { -+ SoftCursorMove(x, y); -+ } -+ -+ pe.x = Swap16IfLE(x); -+ pe.y = Swap16IfLE(y); -+ currentMsg = rfbPointerEvent; -+ return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg); - } - - -@@ -926,12 +2268,22 @@ - Bool - SendKeyEvent(CARD32 key, Bool down) - { -- rfbKeyEventMsg ke; -+ rfbKeyEventMsg ke; -+ -+ if (appData.fileActive) { -+ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) { -+#if 0 -+ fprintf(stderr, "skip SendPointerEvent: %d - %d\n", last_filexfer, time(NULL)); -+#endif -+ return True; -+ } -+ } - -- ke.type = rfbKeyEvent; -- ke.down = down ? 1 : 0; -- ke.key = Swap32IfLE(key); -- return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg); -+ ke.type = rfbKeyEvent; -+ ke.down = down ? 1 : 0; -+ ke.key = Swap32IfLE(key); -+ currentMsg = rfbKeyEvent; -+ return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg); - } - - -@@ -942,281 +2294,1025 @@ - Bool - SendClientCutText(char *str, int len) - { -- rfbClientCutTextMsg cct; -+ rfbClientCutTextMsg cct; -+ -+ if (serverCutText) { -+ free(serverCutText); -+ } -+ serverCutText = NULL; -+ -+ if (appData.fileActive) { -+ if (!dyn || time(NULL) < last_filexfer + delay_filexfer) { -+ /* ultravnc java viewer lets this one through. */ -+ return True; -+ } -+ } -+ -+ if (appData.viewOnly) { -+ return True; -+ } - -- if (serverCutText) -- free(serverCutText); -- serverCutText = NULL; -- -- cct.type = rfbClientCutText; -- cct.length = Swap32IfLE(len); -- return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) && -- WriteExact(rfbsock, str, len)); -+ cct.type = rfbClientCutText; -+ cct.length = Swap32IfLE((unsigned int) len); -+ currentMsg = rfbClientCutText; -+ return (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) && -+ WriteExact(rfbsock, str, len)); - } - -+static int ultra_scale = 0; - --/* -- * HandleRFBServerMessage. -- */ -+Bool -+SendServerScale(int nfac) -+{ -+ rfbSetScaleMsg ssc; -+ if (nfac < 0 || nfac > 100) { -+ return True; -+ } -+ -+ ultra_scale = nfac; -+ ssc.type = rfbSetScale; -+ ssc.scale = nfac; -+ currentMsg = rfbSetScale; -+ return WriteExact(rfbsock, (char *)&ssc, sz_rfbSetScaleMsg); -+} - - Bool --HandleRFBServerMessage() -+SendServerInput(Bool enabled) - { -- rfbServerToClientMsg msg; -+ rfbSetServerInputMsg sim; - -- if (!ReadFromRFBServer((char *)&msg, 1)) -- return False; -+ sim.type = rfbSetServerInput; -+ sim.status = enabled; -+ currentMsg = rfbSetServerInput; -+ return WriteExact(rfbsock, (char *)&sim, sz_rfbSetServerInputMsg); -+} - -- switch (msg.type) { -+Bool -+SendSingleWindow(int x, int y) -+{ -+ static int w_old = -1, h_old = -1; -+ rfbSetSWMsg sw; - -- case rfbSetColourMapEntries: -- { -- int i; -- CARD16 rgb[3]; -- XColor xc; -+ fprintf(stderr, "SendSingleWindow: %d %d\n", x, y); - -- if (!ReadFromRFBServer(((char *)&msg) + 1, -- sz_rfbSetColourMapEntriesMsg - 1)) -- return False; -+ if (x == -1 && y == -1) { -+ sw.type = rfbSetSW; -+ sw.x = Swap16IfLE(1); -+ sw.y = Swap16IfLE(1); -+ if (w_old > 0) { -+ si.framebufferWidth = w_old; -+ si.framebufferHeight = h_old; -+ ReDoDesktop(); -+ } -+ w_old = h_old = -1; -+ } else { -+ sw.type = rfbSetSW; -+ sw.x = Swap16IfLE(x); -+ sw.y = Swap16IfLE(y); -+ w_old = si.framebufferWidth; -+ h_old = si.framebufferHeight; -+ -+ } -+ sw.status = True; -+ currentMsg = rfbSetSW; -+ return WriteExact(rfbsock, (char *)&sw, sz_rfbSetSWMsg); -+} - -- msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); -- msg.scme.nColours = Swap16IfLE(msg.scme.nColours); -+Bool -+SendTextChat(char *str) -+{ -+ static int db = -1; -+ rfbTextChatMsg chat; - -- for (i = 0; i < msg.scme.nColours; i++) { -- if (!ReadFromRFBServer((char *)rgb, 6)) -- return False; -- xc.pixel = msg.scme.firstColour + i; -- xc.red = Swap16IfLE(rgb[0]); -- xc.green = Swap16IfLE(rgb[1]); -- xc.blue = Swap16IfLE(rgb[2]); -- xc.flags = DoRed|DoGreen|DoBlue; -- XStoreColor(dpy, cmap, &xc); -- } -+ if (db < 0) { -+ if (getenv("SSVNC_DEBUG_CHAT")) { -+ db = 1; -+ } else { -+ db = 0; -+ } -+ } -+ if (!appData.chatActive) { -+ SendTextChatOpen(); -+ appData.chatActive = True; -+ } - -- break; -- } -+ chat.type = rfbTextChat; -+ chat.pad1 = 0; -+ chat.pad2 = 0; -+ chat.length = (unsigned int) strlen(str); -+ if (db) fprintf(stderr, "SendTextChat: %d '%s'\n", (int) chat.length, str); -+ chat.length = Swap32IfLE(chat.length); -+ if (!WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg)) { -+ return False; -+ } -+ currentMsg = rfbTextChat; -+ return WriteExact(rfbsock, str, strlen(str)); -+} - -- case rfbFramebufferUpdate: -- { -- rfbFramebufferUpdateRectHeader rect; -- int linesToRead; -- int bytesPerLine; -- int i; -- int usecs; -+extern void raiseme(int force); - -- if (!ReadFromRFBServer(((char *)&msg.fu) + 1, -- sz_rfbFramebufferUpdateMsg - 1)) -- return False; -+Bool -+SendTextChatOpen(void) -+{ -+ rfbTextChatMsg chat; - -- msg.fu.nRects = Swap16IfLE(msg.fu.nRects); -+ raiseme(0); -+ chat.type = rfbTextChat; -+ chat.pad1 = 0; -+ chat.pad2 = 0; -+ chat.length = Swap32IfLE(rfbTextChatOpen); -+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg); -+} - -- for (i = 0; i < msg.fu.nRects; i++) { -- if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) -- return False; -+Bool -+SendTextChatClose(void) -+{ -+ rfbTextChatMsg chat; -+ chat.type = rfbTextChat; -+ chat.pad1 = 0; -+ chat.pad2 = 0; -+ chat.length = Swap32IfLE(rfbTextChatClose); -+ appData.chatActive = False; -+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg); -+} - -- rect.encoding = Swap32IfLE(rect.encoding); -- if (rect.encoding == rfbEncodingLastRect) -- break; -+Bool -+SendTextChatFinished(void) -+{ -+ rfbTextChatMsg chat; -+ chat.type = rfbTextChat; -+ chat.pad1 = 0; -+ chat.pad2 = 0; -+ chat.length = Swap32IfLE(rfbTextChatFinished); -+ appData.chatActive = False; -+ return WriteExact(rfbsock, (char *)&chat, sz_rfbTextChatMsg); -+} -+ -+extern int do_format_change; -+extern int do_cursor_change; -+extern double do_fb_update; -+extern void cutover_format_change(void); -+ -+double dtime(double *t_old) { -+ /* -+ * usage: call with 0.0 to initialize, subsequent calls give -+ * the time difference since last call. -+ */ -+ double t_now, dt; -+ struct timeval now; -+ -+ gettimeofday(&now, NULL); -+ t_now = now.tv_sec + ( (double) now.tv_usec/1000000. ); -+ if (*t_old == 0.0) { -+ *t_old = t_now; -+ return t_now; -+ } -+ dt = t_now - *t_old; -+ *t_old = t_now; -+ return(dt); -+} -+ -+/* common dtime() activities: */ -+double dtime0(double *t_old) { -+ *t_old = 0.0; -+ return dtime(t_old); -+} -+ -+double dnow(void) { -+ double t; -+ return dtime0(&t); -+} -+ -+static char fxfer[65536]; -+ -+Bool HandleFileXfer(void) { -+ unsigned char hdr[12]; -+ unsigned int len; -+ -+ int rfbDirContentRequest = 1; -+ int rfbDirPacket = 2; /* Full directory name or full file name. */ -+ int rfbFileTransferRequest = 3; -+ int rfbFileHeader = 4; -+ int rfbFilePacket = 5; /* One slice of the file */ -+ int rfbEndOfFile = 6; -+ int rfbAbortFileTransfer = 7; -+ int rfbFileTransferOffer = 8; -+ int rfbFileAcceptHeader = 9; /* The server accepts or rejects the file */ -+ int rfbCommand = 10; -+ int rfbCommandReturn = 11; -+ int rfbFileChecksums = 12; -+ -+ int rfbRDirContent = 1; /* Request a Server Directory contents */ -+ int rfbRDrivesList = 2; /* Request the server's drives list */ -+ -+ int rfbADirectory = 1; /* Reception of a directory name */ -+ int rfbAFile = 2; /* Reception of a file name */ -+ int rfbADrivesList = 3; /* Reception of a list of drives */ -+ int rfbADirCreate = 4; /* Response to a create dir command */ -+ int rfbADirDelete = 5; /* Response to a delete dir command */ -+ int rfbAFileCreate = 6; /* Response to a create file command */ -+ int rfbAFileDelete = 7; /* Response to a delete file command */ -+ -+ int rfbCDirCreate = 1; /* Request the server to create the given directory */ -+ int rfbCDirDelete = 2; /* Request the server to delete the given directory */ -+ int rfbCFileCreate = 3; /* Request the server to create the given file */ -+ int rfbCFileDelete = 4; /* Request the server to delete the given file */ -+ -+ int rfbRErrorUnknownCmd = 1; /* Unknown FileTransfer command. */ -+#define rfbRErrorCmd 0xFFFFFFFF -+ -+ static int db = -1; -+ static int guess_x11vnc = 0; -+ -+#if 0 -+ if (filexfer_sock < 0) { -+ return True; -+ } -+ /* instead, we read and discard the ft msg data. */ -+#endif -+ -+/*fprintf(stderr, "In HandleFileXfer\n"); */ - -- rect.r.x = Swap16IfLE(rect.r.x); -- rect.r.y = Swap16IfLE(rect.r.y); -- rect.r.w = Swap16IfLE(rect.r.w); -- rect.r.h = Swap16IfLE(rect.r.h); -- -- if (rect.encoding == rfbEncodingXCursor || -- rect.encoding == rfbEncodingRichCursor) { -- if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, -- rect.encoding)) { -- return False; -+ if (db < 0) { -+ if (getenv("DEBUG_HandleFileXfer")) { -+ db = 1; -+ } else { -+ db = 0; -+ } - } -- continue; -- } - -- if (rect.encoding == rfbEncodingPointerPos) { -- if (!HandleCursorPos(rect.r.x, rect.r.y)) { -- return False; -+ last_filexfer = time(NULL); -+ /*fprintf(stderr, "last_filexfer-1: %d\n", last_filexfer); */ -+ -+ /* load first byte to send to Java be the FT msg number: */ -+ hdr[0] = rfbFileTransfer; -+ -+ /* this is to avoid XtAppProcessEvent() calls induce by our ReadFromRFBServer calls below: */ -+ skip_XtUpdateAll = 1; -+ if (!ReadFromRFBServer(&hdr[1], 11)) { -+ skip_XtUpdateAll = 0; -+ return False; -+ } -+ if (filexfer_sock >= 0) { -+ write(filexfer_sock, hdr, 12); -+ } else { -+ fprintf(stderr, "filexfer_sock closed, discarding 12 bytes\n"); -+ } -+ if (db) fprintf(stderr, "\n"); -+ if (db) fprintf(stderr, "Got rfbFileTransfer hdr\n"); -+ if (db > 1) write(2, hdr, 12); -+ -+ if (db) { -+ int i; -+ fprintf(stderr, "HFX HDR:"); -+ for (i=0; i < 12; i++) { -+ fprintf(stderr, " %d", (int) hdr[i]); -+ } -+ fprintf(stderr, "\n"); - } -- continue; -- } - -- if ((rect.r.x + rect.r.w > si.framebufferWidth) || -- (rect.r.y + rect.r.h > si.framebufferHeight)) -- { -- fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n", -- rect.r.w, rect.r.h, rect.r.x, rect.r.y); -- return False; -+ if (hdr[1] == rfbEndOfFile) { -+ goto read_no_more; -+ } else if (hdr[1] == rfbAbortFileTransfer) { -+ goto read_no_more; - } - -- if (rect.r.h * rect.r.w == 0) { -- fprintf(stderr,"Zero size rect - ignoring\n"); -- continue; -- } -+ if (hdr[1] == rfbDirPacket && hdr[3] == rfbADirectory) { -+ -+ } -+ -+ len = (hdr[8] << 24) | (hdr[9] << 16) | (hdr[10] << 8) | hdr[11]; -+ if (db) fprintf(stderr, "Got rfbFileTransfer: len1 %u\n", len); -+ if (len > 0) { -+ if (!ReadFromRFBServer(fxfer, len)) { -+ skip_XtUpdateAll = 0; -+ return False; -+ } -+ if (db > 1) write(2, fxfer, len); -+ if (len >= 12 && hdr[1] == rfbDirPacket) { -+ /* try to guess if x11vnc or not... */ -+ if (db) { -+ int i; -+ fprintf(stderr, "HFX DIR PKT (attr, timeL, timeH):"); -+ for (i=0; i < 12; i++) { -+ fprintf(stderr, " %d", (unsigned char) fxfer[i]); -+ } -+ fprintf(stderr, "\n"); -+ } -+ if (hdr[2] == 1) { -+ int dattr = (unsigned char) fxfer[0]; -+ int timeL1 = (unsigned char) fxfer[4]; -+ int timeL2 = (unsigned char) fxfer[5]; -+ int timeL3 = (unsigned char) fxfer[6]; -+ int timeL4 = (unsigned char) fxfer[7]; -+ int timeH1 = (unsigned char) fxfer[8]; -+ int timeH2 = (unsigned char) fxfer[9]; -+ int timeH3 = (unsigned char) fxfer[10]; -+ int timeH4 = (unsigned char) fxfer[11]; -+ if (dattr != 0) { -+ if (timeH1 == 0 && timeH2 == 0 && timeH3 == 0 && timeH4 == 0) { -+ if ((timeL1 != 0 || timeL2 != 0) && timeL3 != 0 && timeL4 != 0) { -+ if (!guess_x11vnc) fprintf(stderr, "guessed x11vnc server\n"); -+ guess_x11vnc = 1; -+ } -+ } -+ } -+ } -+ } -+ if (db && 0) fprintf(stderr, "\n"); -+ if (filexfer_sock >= 0) { -+ write(filexfer_sock, fxfer, len); -+ } else { -+ fprintf(stderr, "filexfer_sock closed, discarding %d bytes\n", len); -+ } -+ } -+ -+ len = (hdr[4] << 24) | (hdr[5] << 16) | (hdr[6] << 8) | hdr[7]; -+ if (db) fprintf(stderr, "Got rfbFileTransfer: len2 %u\n", len); -+ -+#if 0 -+ if (hdr[1] == rfbFileHeader && len != rfbRErrorCmd) -+#else -+ /* the extra 4 bytes get send on rfbRErrorCmd as well. */ -+ if (hdr[1] == rfbFileHeader) { -+#endif -+ int is_err = 0; -+ if (len == rfbRErrorCmd) { -+ is_err = 1; -+ } -+ if (db) fprintf(stderr, "Got rfbFileTransfer: rfbFileHeader\n"); -+ if (is_err && guess_x11vnc) { -+ fprintf(stderr, "rfbRErrorCmd x11vnc skip read 4 bytes.\n"); -+ goto read_no_more; -+ } -+ len = 4; -+ if (!ReadFromRFBServer(fxfer, len)) { -+ skip_XtUpdateAll = 0; -+ return False; -+ } -+ if (db > 1) write(2, fxfer, len); -+ if (db && 0) fprintf(stderr, "\n"); -+ if (is_err) { -+ fprintf(stderr, "rfbRErrorCmd skip write 4 bytes.\n"); -+ goto read_no_more; -+ } -+ if (filexfer_sock >= 0) { -+ write(filexfer_sock, fxfer, len); -+ } else { -+ fprintf(stderr, "filexfer_sock closed, discarding %d bytes\n", len); -+ } -+ } - -- /* If RichCursor encoding is used, we should prevent collisions -- between framebuffer updates and cursor drawing operations. */ -- SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h); -+ read_no_more: - -- switch (rect.encoding) { -+ if (filexfer_sock < 0) { -+ int stop = 0; -+ static time_t last_stop = 0; -+#if 0 -+ /* this isn't working */ -+ if (hdr[1] == rfbFilePacket || hdr[1] == rfbFileHeader) { -+ fprintf(stderr, "filexfer_sock closed, trying to abort receive\n"); -+ stop = 1; -+ } -+#endif -+ if (stop && time(NULL) > last_stop+1) { -+ unsigned char rpl[12]; -+ int k; -+ rpl[0] = rfbFileTransfer; -+ rpl[1] = rfbAbortFileTransfer; -+ for (k=2; k < 12; k++) { -+ rpl[k] = 0; -+ } -+ WriteExact(rfbsock, rpl, 12); -+ last_stop = time(NULL); -+ } -+ } - -- case rfbEncodingRaw: -+ if (db) fprintf(stderr, "Got rfbFileTransfer done.\n"); -+ skip_XtUpdateAll = 0; - -- bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8; -- linesToRead = BUFFER_SIZE / bytesPerLine; -+ if (db) fprintf(stderr, "CFX: B\n"); -+ CheckFileXfer(); -+/*fprintf(stderr, "Out HandleFileXfer\n"); */ -+ return True; -+} - -- while (rect.r.h > 0) { -- if (linesToRead > rect.r.h) -- linesToRead = rect.r.h; -+/* -+ * HandleRFBServerMessage. -+ */ - -- if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) -- return False; - -- CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, -- linesToRead); -+Bool -+HandleRFBServerMessage() -+{ -+ static int db = -1; -+ rfbServerToClientMsg msg; - -- rect.r.h -= linesToRead; -- rect.r.y += linesToRead; -+ if (db < 0) { -+ if (getenv("DEBUG_RFB_SMSG")) { -+ db = 1; -+ } else { -+ db = 0; -+ } -+ } - -+ if (!ReadFromRFBServer((char *)&msg, 1)) { -+ return False; - } -- break; -+ if (appData.ultraDSM) { -+ if (!ReadFromRFBServer((char *)&msg, 1)) { -+ return False; -+ } -+ } -+ -+/*fprintf(stderr, "msg.type: %d\n", msg.type); */ - -- case rfbEncodingCopyRect: -- { -- rfbCopyRect cr; -- -- if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect)) -- return False; -- -- cr.srcX = Swap16IfLE(cr.srcX); -- cr.srcY = Swap16IfLE(cr.srcY); -- -- /* If RichCursor encoding is used, we should extend our -- "cursor lock area" (previously set to destination -- rectangle) to the source rectangle as well. */ -- SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h); -- -- if (appData.copyRectDelay != 0) { -- XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, -- rect.r.w, rect.r.h); -- XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, -- rect.r.w, rect.r.h); -- XSync(dpy,False); -- usleep(appData.copyRectDelay * 1000); -- XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, -- rect.r.w, rect.r.h); -- XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, -- rect.r.w, rect.r.h); -+ if (msg.type == rfbFileTransfer) { -+ return HandleFileXfer(); - } - -- XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY, -- rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ switch (msg.type) { - -- break; -- } -+ case rfbSetColourMapEntries: -+ { -+ int i; -+ CARD16 rgb[3]; -+ XColor xc; - -- case rfbEncodingRRE: -- { -- switch (myFormat.bitsPerPixel) { -- case 8: -- if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 16: -- if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 32: -- if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbSetColourMapEntriesMsg - 1)) { -+ return False; - } -- break; -- } - -- case rfbEncodingCoRRE: -- { -- switch (myFormat.bitsPerPixel) { -- case 8: -- if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 16: -- if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 32: -- if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -+ msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour); -+ msg.scme.nColours = Swap16IfLE(msg.scme.nColours); -+ -+ for (i = 0; i < msg.scme.nColours; i++) { -+ if (!ReadFromRFBServer((char *)rgb, 6)) { -+ return False; -+ } -+ xc.pixel = msg.scme.firstColour + i; -+ xc.red = Swap16IfLE(rgb[0]); -+ xc.green = Swap16IfLE(rgb[1]); -+ xc.blue = Swap16IfLE(rgb[2]); -+ if (appData.useGreyScale) { -+ int ave = (xc.red + xc.green + xc.blue)/3; -+ xc.red = ave; -+ xc.green = ave; -+ xc.blue = ave; -+ } -+ xc.flags = DoRed|DoGreen|DoBlue; -+ XStoreColor(dpy, cmap, &xc); - } -+ - break; -- } -+ } -+ -+ case rfbFramebufferUpdate: -+ { -+ rfbFramebufferUpdateRectHeader rect; -+ int linesToRead; -+ int bytesPerLine; -+ int i; -+ -+ int area_copyrect = 0; -+ int area_tight = 0; -+ int area_zrle = 0; -+ int area_raw = 0; -+ static int rdb = -1; -+ static int delay_sync = -1; -+ static int delay_sync_env = -1; -+ int try_delay_sync = 0; -+ int cnt_pseudo = 0; -+ int cnt_image = 0; -+ -+ int skip_incFBU = 0; -+ -+ if (db) fprintf(stderr, "FBU-0: %.6f\n", dnow()); -+ if (rdb < 0) { -+ if (getenv("SSVNC_DEBUG_RECTS")) { -+ rdb = atoi(getenv("SSVNC_DEBUG_RECTS")); -+ } else { -+ rdb = 0; -+ } -+ } -+ if (delay_sync < 0) { -+ if (getenv("SSVNC_DELAY_SYNC")) { -+ delay_sync = atoi(getenv("SSVNC_DELAY_SYNC")); -+ delay_sync_env = delay_sync; -+ } else { -+ delay_sync = 0; -+ } -+ } -+ -+ sent_FBU = -1; - -- case rfbEncodingHextile: -- { -- switch (myFormat.bitsPerPixel) { -- case 8: -- if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 16: -- if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 32: -- if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -+ if (appData.pipelineUpdates) { -+ /* turbovnc speed idea */ -+ XEvent ev; -+ memset(&ev, 0, sizeof(ev)); -+ ev.xclient.type = ClientMessage; -+ ev.xclient.window = XtWindow(desktop); -+ ev.xclient.message_type = XA_INTEGER; -+ ev.xclient.format = 8; -+ strcpy(ev.xclient.data.b, "SendRFBUpdate"); -+ XSendEvent(dpy, XtWindow(desktop), False, 0, &ev); - } -- break; -- } - -- case rfbEncodingZlib: -- { -- switch (myFormat.bitsPerPixel) { -- case 8: -- if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 16: -- if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 32: -- if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -+ if (!ReadFromRFBServer(((char *)&msg.fu) + 1, sz_rfbFramebufferUpdateMsg - 1)) { -+ return False; - } -- break; -- } - -- case rfbEncodingTight: -- { -- switch (myFormat.bitsPerPixel) { -- case 8: -- if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 16: -- if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -- case 32: -- if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) -- return False; -- break; -+ msg.fu.nRects = Swap16IfLE(msg.fu.nRects); -+ -+ if (rdb) fprintf(stderr, "Begin rect loop %d\n", msg.fu.nRects); -+ -+ if (delay_sync) { -+ try_delay_sync = 1; -+ } else { -+ if (delay_sync_env != -1 && delay_sync_env == 0) { -+ ; -+ } else if (appData.yCrop > 0) { -+ ; -+ } else if (scale_factor_x > 0.0 && scale_factor_x != 1.0) { -+ ; -+ } else if (scale_factor_y > 0.0 && scale_factor_y != 1.0) { -+ ; -+ } else { -+ static int msg = 0; -+ /* fullScreen? */ -+ /* useXserverBackingStore? */ -+ /* useX11Cursor & etc? */ -+ /* scrollbars? */ -+ if (!msg) { -+ fprintf(stderr, "enabling 'delay_sync' mode for faster local drawing,\ndisable via env SSVNC_DELAY_SYNC=0 if there are painting errors.\n"); -+ msg = 1; -+ } -+ try_delay_sync = 1; -+ } -+ } -+ if (try_delay_sync) { -+ skip_maybe_sync = 1; -+ } -+#define STOP_DELAY_SYNC \ -+ if (try_delay_sync) { \ -+ if (cnt_image && skip_maybe_sync) { \ -+ XSync(dpy, False); \ -+ } \ -+ try_delay_sync = 0; \ -+ skip_maybe_sync = 0; \ - } -- break; -- } - -- default: -- fprintf(stderr,"Unknown rect encoding %d\n", -- (int)rect.encoding); -- return False; -- } -+ for (i = 0; i < msg.fu.nRects; i++) { -+ if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader)) { -+ return False; -+ } -+ -+ rect.encoding = Swap32IfLE(rect.encoding); -+ if (rect.encoding == rfbEncodingLastRect) { -+ break; -+ } -+ -+ rect.r.x = Swap16IfLE(rect.r.x); -+ rect.r.y = Swap16IfLE(rect.r.y); -+ rect.r.w = Swap16IfLE(rect.r.w); -+ rect.r.h = Swap16IfLE(rect.r.h); -+ -+ if (rdb > 1) fprintf(stderr, "nRects: %d i=%d enc: %d %dx%d+%d+%d\n", msg.fu.nRects, i, (int) rect.encoding, rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ -+ if (rect.encoding == rfbEncodingXCursor || rect.encoding == rfbEncodingRichCursor) { -+ cnt_pseudo++; -+ STOP_DELAY_SYNC -+ -+ if (db) fprintf(stderr, "FBU-Cur1 %.6f\n", dnow()); -+ if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h, rect.encoding)) { -+ return False; -+ } -+ if (db) fprintf(stderr, "FBU-Cur2 %.6f\n", dnow()); -+ continue; -+ } -+ -+ if (rect.encoding == rfbEncodingPointerPos) { -+ cnt_pseudo++; -+ STOP_DELAY_SYNC -+ if (db) fprintf(stderr, "FBU-Pos1 %.6f\n", dnow()); -+ if (0) fprintf(stderr, "CursorPos: %d %d / %d %d\n", rect.r.x, rect.r.y, rect.r.w, rect.r.h); -+ if (ultra_scale > 0) { -+ int f = ultra_scale; -+ if (!HandleCursorPos(rect.r.x/f, rect.r.y/f)) { -+ return False; -+ } -+ } else { -+ if (!HandleCursorPos(rect.r.x, rect.r.y)) { -+ return False; -+ } -+ } -+ if (db) fprintf(stderr, "FBU-Pos2 %.6f\n", dnow()); -+ continue; -+ } -+ if (rect.encoding == rfbEncodingNewFBSize) { -+ cnt_pseudo++; -+ STOP_DELAY_SYNC -+ if (appData.chatOnly) { -+ continue; -+ } -+ fprintf(stderr,"New Size: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ si.framebufferWidth = rect.r.w; -+ si.framebufferHeight = rect.r.h; -+ /*fprintf(stderr, "si: %d %d\n", si.framebufferWidth, si.framebufferHeight); */ -+ ReDoDesktop(); -+ continue; -+ } -+ if (rdb) fprintf(stderr,"Rect: %dx%d at (%d, %d)\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ cnt_image++; -+ -+ if (appData.ultraDSM) { -+ /* -+ * What a huge mess the UltraVNC DSM plugin is!!! -+ * We read and ignore their little "this much data" hint... -+ */ -+ switch (rect.encoding) -+ { -+ case rfbEncodingRaw: -+ case rfbEncodingRRE: -+ case rfbEncodingCoRRE: -+ case rfbEncodingHextile: -+ /*case rfbEncodingUltra: */ -+/* case rfbEncodingZlib: */ -+ /*case rfbEncodingXOR_Zlib: */ -+ /*case rfbEncodingXORMultiColor_Zlib: */ -+ /*case rfbEncodingXORMonoColor_Zlib: */ -+ /*case rfbEncodingSolidColor: */ -+ case rfbEncodingTight: -+ case rfbEncodingZlibHex: -+ case rfbEncodingZRLE: -+ case rfbEncodingZYWRLE: -+ { -+ CARD32 discard; -+ ReadFromRFBServer((char *)&discard, sizeof(CARD32)); -+ } -+ break; -+ } -+ } -+ -+ if ((rect.r.x + rect.r.w > si.framebufferWidth) || -+ (rect.r.y + rect.r.h > si.framebufferHeight)) { -+ if (!appData.chatOnly) { -+ fprintf(stderr,"Rect too large: %dx%d at (%d, %d) encoding=%d\n", -+ rect.r.w, rect.r.h, rect.r.x, rect.r.y, (int) rect.encoding); -+ return False; -+ } -+ } -+ -+ if (rect.r.h * rect.r.w == 0) { -+ fprintf(stderr,"*** Warning *** Zero size rect: %dx%d+%d+%d encoding=%d\n", -+ rect.r.w, rect.r.h, rect.r.x, rect.r.y, (int) rect.encoding); -+ if (0) continue; -+ } -+ -+ /* If RichCursor encoding is used, we should prevent collisions -+ between framebuffer updates and cursor drawing operations. */ -+ if (db) fprintf(stderr, "FBU-SCL1 %.6f\n", dnow()); -+ -+ SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h); -+ -+ if (db) fprintf(stderr, "FBU-SCL2 %.6f\n", dnow()); -+ -+ -+ switch (rect.encoding) { -+ -+ case rfbEncodingRaw: -+ -+ bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8; -+ linesToRead = BUFFER_SIZE / bytesPerLine; -+ -+ if (db) fprintf(stderr, "Raw: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ area_raw += rect.r.w * rect.r.h; -+ -+ while (rect.r.h > 0) { -+ if (linesToRead > rect.r.h) { -+ linesToRead = rect.r.h; -+ } -+ -+ if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead)) { -+ return False; -+ } -+ -+ CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w, linesToRead); -+ -+ rect.r.h -= linesToRead; -+ rect.r.y += linesToRead; -+ } -+ break; -+ -+ case rfbEncodingCopyRect: -+ { -+ rfbCopyRect cr; -+ -+ STOP_DELAY_SYNC -+ XSync(dpy, False); -+ -+ if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect)) { -+ return False; -+ } -+ if (appData.chatOnly) { -+ break; -+ } -+ -+ cr.srcX = Swap16IfLE(cr.srcX); -+ cr.srcY = Swap16IfLE(cr.srcY); -+ -+ if (db) fprintf(stderr, "Copy: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ area_copyrect += rect.r.w * rect.r.h; -+ -+ /* If RichCursor encoding is used, we should extend our -+ "cursor lock area" (previously set to destination -+ rectangle) to the source rectangle as well. */ -+ -+ if (db) fprintf(stderr, "FBU-SCL3 %.6f\n", dnow()); -+ -+ SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h); -+ -+ if (db) fprintf(stderr, "FBU-SCL4 %.6f\n", dnow()); -+ -+ if (appData.copyRectDelay != 0) { -+ XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h); -+ XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h); -+ XSync(dpy,False); -+ usleep(appData.copyRectDelay * 1000); -+ XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y, rect.r.w, rect.r.h); -+ XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY, rect.r.w, rect.r.h); -+ } -+ -+ if (db) fprintf(stderr, "FBU-CPA1 %.6f\n", dnow()); -+ if (!appData.useXserverBackingStore) { -+ copy_rect(rect.r.x, rect.r.y, rect.r.w, rect.r.h, cr.srcX, cr.srcY); -+ put_image(rect.r.x, rect.r.y, rect.r.x, rect.r.y, rect.r.w, rect.r.h, 0); -+ XSync(dpy, False); -+ } else { -+ XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY, -+ rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ } -+ if (db) fprintf(stderr, "FBU-CPA2 %.6f\n", dnow()); -+ -+ break; -+ } -+ -+ case rfbEncodingRRE: -+ { -+ switch (myFormat.bitsPerPixel) { -+ case 8: -+ if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 16: -+ if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 32: -+ if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ } -+ break; -+ } -+ -+ case rfbEncodingCoRRE: -+ { -+ switch (myFormat.bitsPerPixel) { -+ case 8: -+ if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 16: -+ if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 32: -+ if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ } -+ break; -+ } -+ -+ case rfbEncodingHextile: -+ { -+ switch (myFormat.bitsPerPixel) { -+ case 8: -+ if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 16: -+ if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 32: -+ if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ } -+ break; -+ } -+ -+ case rfbEncodingZlib: -+ { -+ switch (myFormat.bitsPerPixel) { -+ case 8: -+ if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 16: -+ if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 32: -+ if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ } -+ break; -+ } -+ -+ case rfbEncodingTight: -+ { -+ if (db) fprintf(stderr, "Tight: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ area_tight += rect.r.w * rect.r.h; -+ if (db) fprintf(stderr, "FBU-TGH1 %.6f\n", dnow()); -+ -+ switch (myFormat.bitsPerPixel) { -+ case 8: -+ if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 16: -+ if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 32: -+ if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ } -+ if (db) fprintf(stderr, "FBU-TGH2 %.6f\n", dnow()); -+ break; -+ } -+ -+ /* runge adds zrle and zywrle: */ -+ case rfbEncodingZRLE: -+#if DO_ZYWRLE -+ zywrle_level = 0; -+ case rfbEncodingZYWRLE: -+#endif -+ { -+ if (db) fprintf(stderr, "ZRLE: %dx%d+%d+%d\n", rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ area_zrle += rect.r.w * rect.r.h; -+ switch (myFormat.bitsPerPixel) { -+ case 8: -+ if (!HandleZRLE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ case 16: -+ if (myFormat.greenMax > 0x1f) { -+ if (!HandleZRLE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ } else { -+ if (!HandleZRLE15(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ } -+ break; -+ case 32: -+ { -+ unsigned int maxColor=(myFormat.redMax<<myFormat.redShift)| -+ (myFormat.greenMax<<myFormat.greenShift)| -+ (myFormat.blueMax<<myFormat.blueShift); -+ static int ZRLE32 = -1; -+ -+ if (ZRLE32 < 0) { -+ /* for debugging or workaround e.g. BE display to LE */ -+ if (getenv("ZRLE32")) { -+ if (strstr(getenv("ZRLE32"), "24Up")) { -+ ZRLE32 = 3; -+ } else if (strstr(getenv("ZRLE32"), "24Down")) { -+ ZRLE32 = 2; -+ } else { -+ ZRLE32 = 1; -+ } -+ } else { -+ ZRLE32 = 0; -+ } -+ } -+ -+if (db) fprintf(stderr, "maxColor: 0x%x mfbigEnding: %d\n", maxColor, myFormat.bigEndian); -+ -+ if (ZRLE32 == 1) { -+if (db) fprintf(stderr, "HandleZRLE32\n"); -+ if (!HandleZRLE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ } else if (ZRLE32 == 2) { -+if (db) fprintf(stderr, "HandleZRLE24Down\n"); -+ if (!HandleZRLE24Down(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ } else if (ZRLE32 == 3) { -+if (db) fprintf(stderr, "HandleZRLE24Up\n"); -+ if (!HandleZRLE24Up(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ } else if ((myFormat.bigEndian && (maxColor&0xff)==0) || (!myFormat.bigEndian && (maxColor&0xff000000)==0)) { -+if (db) fprintf(stderr, "HandleZRLE24\n"); -+ if (!HandleZRLE24(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ } else if (!myFormat.bigEndian && (maxColor&0xff)==0) { -+if (db) fprintf(stderr, "HandleZRLE24Up\n"); -+ if (!HandleZRLE24Up(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ } else if (myFormat.bigEndian && (maxColor&0xff000000)==0) { -+if (db) fprintf(stderr, "HandleZRLE24Down\n"); -+ if (!HandleZRLE24Down(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ } else if (!HandleZRLE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h)) { -+ return False; -+ } -+ break; -+ } -+ } -+ break; -+ } -+ -+ default: -+ fprintf(stderr,"Unknown rect encoding %d\n", (int)rect.encoding); -+ return False; -+ } - -- /* Now we may discard "soft cursor locks". */ -- SoftCursorUnlockScreen(); -- } -+ /* Now we may discard "soft cursor locks". */ -+ if (db) fprintf(stderr, "FBU-SUL1 %.6f\n", dnow()); -+ -+ SoftCursorUnlockScreen(); -+ -+ if (db) fprintf(stderr, "FBU-SUL2 %.6f\n", dnow()); -+ } -+ -+ if (try_delay_sync) { -+ skip_maybe_sync = 0; -+ } -+ -+ if (1 || area_copyrect) { -+ /* we always do this now for some reason... */ -+ if (db) fprintf(stderr, "FBU-XSN1 %.6f\n", dnow()); -+ XSync(dpy, False); -+ if (db) fprintf(stderr, "FBU-XSN2 %.6f\n", dnow()); -+ } -+ sent_FBU = 0; -+ /* -+ * we need to be careful since Xt events are processed -+ * usually in the middle of FBU. So we do any scheduled ones now -+ * which is pretty safe but not absolutely safe. -+ */ -+ if (do_format_change) { -+ cutover_format_change(); -+ do_format_change = 0; -+ SetVisualAndCmap(); -+ SetFormatAndEncodings(); -+ if (do_cursor_change) { -+ if (do_cursor_change == 1) { -+ DesktopCursorOff(); -+ } -+ do_cursor_change = 0; -+ } else { -+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, -+ si.framebufferHeight, False); -+ skip_incFBU = 1; -+ } -+ } -+ if (do_fb_update != 0.0) { -+ if (dnow() > do_fb_update + 1.1) { -+ do_fb_update = 0.0; -+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, -+ si.framebufferHeight, False); -+ } -+ } - - #ifdef MITSHM - /* if using shared memory PutImage, make sure that the X server has -@@ -1224,59 +3320,168 @@ - mainly to avoid copyrect using invalid screen contents - not sure - if we'd need it otherwise. */ - -- if (appData.useShm) -- XSync(dpy, False); -+ if (appData.useShm) { -+ XSync(dpy, False); -+ } else - #endif -+ { -+ /* we do it always now. */ -+ XSync(dpy, False); -+ } -+ -+ if (skip_XtUpdate || skip_incFBU) { -+ ; -+ } else if (appData.pipelineUpdates) { -+ ; -+ } else if (!SendIncrementalFramebufferUpdateRequest()) { -+ return False; -+ } - -- if (!SendIncrementalFramebufferUpdateRequest()) -- return False; -- -- break; -+ break; - } - - case rfbBell: - { -- Window toplevelWin; -+ Window toplevelWin; - -- XBell(dpy, 0); -+ if (appData.useBell) { -+ XBell(dpy, 0); -+ } -+ -+ if (appData.raiseOnBeep) { -+ toplevelWin = XtWindow(toplevel); -+ XMapRaised(dpy, toplevelWin); -+ } - -- if (appData.raiseOnBeep) { -- toplevelWin = XtWindow(toplevel); -- XMapRaised(dpy, toplevelWin); -+ break; - } - -- break; -- } -+ case rfbServerCutText: -+ { -+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbServerCutTextMsg - 1)) { -+ return False; -+ } - -- case rfbServerCutText: -- { -- if (!ReadFromRFBServer(((char *)&msg) + 1, -- sz_rfbServerCutTextMsg - 1)) -- return False; -+ msg.sct.length = Swap32IfLE(msg.sct.length); - -- msg.sct.length = Swap32IfLE(msg.sct.length); -+ if (serverCutText) { -+ free(serverCutText); -+ } - -- if (serverCutText) -- free(serverCutText); -+ serverCutText = malloc(msg.sct.length+1); - -- serverCutText = malloc(msg.sct.length+1); -+ if (!ReadFromRFBServer(serverCutText, msg.sct.length)) { -+ return False; -+ } - -- if (!ReadFromRFBServer(serverCutText, msg.sct.length)) -- return False; -+ serverCutText[msg.sct.length] = 0; - -- serverCutText[msg.sct.length] = 0; -+ newServerCutText = True; - -- newServerCutText = True; -+ break; -+ } - -- break; -- } -+ case rfbTextChat: -+ { -+ char *buffer = NULL; -+ if (!ReadFromRFBServer(((char *)&msg) + 1, sz_rfbTextChatMsg - 1)) { -+ return False; -+ } -+ msg.tc.length = Swap32IfLE(msg.tc.length); -+ switch(msg.tc.length) { -+ case rfbTextChatOpen: -+ if (appData.termChat) { -+ printChat("\n*ChatOpen*\n\nSend: ", True); -+ } else { -+ printChat("\n*ChatOpen*\n", True); -+ } -+ appData.chatActive = True; -+ break; -+ case rfbTextChatClose: -+ printChat("\n*ChatClose*\n", False); -+ appData.chatActive = False; -+ break; -+ case rfbTextChatFinished: -+ printChat("\n*ChatFinished*\n", False); -+ appData.chatActive = False; -+ break; -+ default: -+ buffer = (char *)malloc(msg.tc.length+1); -+ if (!ReadFromRFBServer(buffer, msg.tc.length)) { -+ free(buffer); -+ return False; -+ } -+ buffer[msg.tc.length] = '\0'; -+ appData.chatActive = True; -+ GotChatText(buffer, msg.tc.length); -+ free(buffer); -+ } -+ break; -+ } - -- default: -- fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type); -- return False; -- } -+ case rfbResizeFrameBuffer: -+ { -+ rfbResizeFrameBufferMsg rsmsg; -+ if (!ReadFromRFBServer(((char *)&rsmsg) + 1, sz_rfbResizeFrameBufferMsg - 1)) { -+ return False; -+ } -+ si.framebufferWidth = Swap16IfLE(rsmsg.framebufferWidth); -+ si.framebufferHeight = Swap16IfLE(rsmsg.framebufferHeight); -+ fprintf(stderr,"UltraVNC ReSize: %dx%d\n", si.framebufferWidth, si.framebufferHeight); -+ ReDoDesktop(); -+ break; -+ } - -- return True; -+ case rfbRestartConnection: -+ { -+ rfbRestartConnectionMsg rc; -+ int len; -+ char *rs_str; -+ char buf[5] = "\xff\xff\xff\xff"; -+ fprintf(stderr, "rfbRestartConnection. type=%d\n", (int) rc.type); -+ if (!ReadFromRFBServer((char *)&rc + 1, sz_rfbRestartConnectionMsg - 1)) { -+ return False; -+ } -+ len = Swap32IfLE(rc.length); -+ fprintf(stderr, "rfbRestartConnection. pad1=%d\n", (int) rc.pad1); -+ fprintf(stderr, "rfbRestartConnection. pad2=%d\n", (int) rc.pad2); -+ fprintf(stderr, "rfbRestartConnection. len=%d\n", len); -+ if (len) { -+ rs_str = (char *)malloc(2*len); -+ if (!ReadFromRFBServer(rs_str, len)) { -+ return False; -+ } -+ restart_session_pw = rs_str; -+ restart_session_len = len; -+ } -+ if (!WriteExact(rfbsock, buf, 4)) { -+ return False; -+ } -+ InitialiseRFBConnection(); -+ SetVisualAndCmap(); -+ SetFormatAndEncodings(); -+ DesktopCursorOff(); -+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False); -+ -+ break; -+ } -+ -+ default: -+ fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type); -+ return False; -+ } -+ -+ if (appData.fileActive) { -+ if (filexfer_sock < 0 && filexfer_listen < 0) { -+ appData.fileActive = False; -+ SendFramebufferUpdateRequest(0, 0, 1, 1, False); -+ } else { -+/*fprintf(stderr, "CFX: A\n"); */ -+ CheckFileXfer(); -+ } -+ } -+ -+ return True; - } - - -@@ -1296,26 +3501,93 @@ - #define CONCAT2(a,b) a##b - #define CONCAT2E(a,b) CONCAT2(a,b) - -+#define CONCAT3(a,b,c) a##b##c -+#define CONCAT3E(a,b,c) CONCAT3(a,b,c) -+ -+static unsigned char* frameBuffer = NULL; -+static int frameBufferLen = 0; -+ -+#ifdef TURBOVNC -+#include "turbovnc/turbojpeg.h" -+tjhandle tjhnd=NULL; -+static char *compressedData = NULL; -+static char *uncompressedData = NULL; -+#define CopyDataToImage CopyDataToScreen -+static void turbovnc_FillRectangle(XGCValues *gcv, int rx, int ry, int rw, int rh) { -+ if (!appData.useXserverBackingStore) { -+ FillScreen(rx, ry, rw, rh, gcv->foreground); -+ } else { -+ XChangeGC(dpy, gc, GCForeground, gcv); -+ XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh); -+ } -+} -+static void CopyImageToScreen(int x, int y, int w, int h) { -+ put_image(x, y, x, y, w, h, 0); -+} -+#endif -+ - #define BPP 8 - #include "rre.c" - #include "corre.c" - #include "hextile.c" - #include "zlib.c" -+ -+#ifdef TURBOVNC -+#undef FillRectangle -+#define FillRectangle turbovnc_FillRectangle -+#include "turbovnc/tight.c" -+#undef FillRectangle -+#else - #include "tight.c" -+#endif -+ -+#include "zrle.c" - #undef BPP -+ - #define BPP 16 - #include "rre.c" - #include "corre.c" - #include "hextile.c" - #include "zlib.c" -+ -+#ifdef TURBOVNC -+#undef FillRectangle -+#define FillRectangle turbovnc_FillRectangle -+#include "turbovnc/tight.c" -+#undef FillRectangle -+#else - #include "tight.c" -+#endif -+ -+#include "zrle.c" -+#define REALBPP 15 -+#include "zrle.c" - #undef BPP -+ - #define BPP 32 - #include "rre.c" - #include "corre.c" - #include "hextile.c" - #include "zlib.c" -+ -+#ifdef TURBOVNC -+#undef FillRectangle -+#define FillRectangle turbovnc_FillRectangle -+#include "turbovnc/tight.c" -+#undef FillRectangle -+#else - #include "tight.c" -+#endif -+ -+#include "zrle.c" -+#define REALBPP 24 -+#include "zrle.c" -+#define REALBPP 24 -+#define UNCOMP 8 -+#include "zrle.c" -+#define REALBPP 24 -+#define UNCOMP -8 -+#include "zrle.c" - #undef BPP - - /* -@@ -1325,23 +3597,27 @@ - static void - ReadConnFailedReason(void) - { -- CARD32 reasonLen; -- char *reason = NULL; -+ CARD32 reasonLen; -+ char *reason = NULL; - -- if (ReadFromRFBServer((char *)&reasonLen, sizeof(reasonLen))) { -- reasonLen = Swap32IfLE(reasonLen); -- if ((reason = malloc(reasonLen)) != NULL && -- ReadFromRFBServer(reason, reasonLen)) { -- fprintf(stderr,"VNC connection failed: %.*s\n", (int)reasonLen, reason); -- free(reason); -- return; -- } -- } -+ if (ReadFromRFBServer((char *)&reasonLen, sizeof(reasonLen))) { -+ reasonLen = Swap32IfLE(reasonLen); -+ if ((reason = malloc(reasonLen)) != NULL && -+ ReadFromRFBServer(reason, reasonLen)) { -+ int len = (int) reasonLen < sizeof(msgbuf) - 10 ? (int) reasonLen : sizeof(msgbuf) - 10; -+ sprintf(msgbuf,"VNC connection failed: %.*s\n", len, reason); -+ wmsg(msgbuf, 1); -+ free(reason); -+ return; -+ } -+ } - -- fprintf(stderr, "VNC connection failed\n"); -+ sprintf(msgbuf, "VNC connection failed\n"); -+ wmsg(msgbuf, 1); - -- if (reason != NULL) -- free(reason); -+ if (reason != NULL) { -+ free(reason); -+ } - } - - /* -@@ -1358,9 +3634,9 @@ - " %s significant bit in each byte is leftmost on the screen.\n", - (format->bigEndian ? "Most" : "Least")); - } else { -- fprintf(stderr," %d bits per pixel.\n",format->bitsPerPixel); -+ fprintf(stderr," %d bits per pixel. ",format->bitsPerPixel); - if (format->bitsPerPixel != 8) { -- fprintf(stderr," %s significant byte first in each pixel.\n", -+ fprintf(stderr,"%s significant byte first in each pixel.\n", - (format->bigEndian ? "Most" : "Least")); - } - if (format->trueColour) { -@@ -1462,4 +3738,3 @@ - - cinfo->src = &jpegSrcManager; - } -- -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/rre.c vnc_unixsrc/vncviewer/rre.c ---- vnc_unixsrc.orig/vncviewer/rre.c 2000-06-11 08:00:53.000000000 -0400 -+++ vnc_unixsrc/vncviewer/rre.c 2008-10-05 15:16:30.000000000 -0400 -@@ -29,6 +29,18 @@ - #define HandleRREBPP CONCAT2E(HandleRRE,BPP) - #define CARDBPP CONCAT2E(CARD,BPP) - -+#define FillRectangle(x, y, w, h, color) \ -+ { \ -+ XGCValues _gcv; \ -+ _gcv.foreground = color; \ -+ if (!appData.useXserverBackingStore) { \ -+ FillScreen(x, y, w, h, _gcv.foreground); \ -+ } else { \ -+ XChangeGC(dpy, gc, GCForeground, &_gcv); \ -+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \ -+ } \ -+ } -+ - static Bool - HandleRREBPP (int rx, int ry, int rw, int rh) - { -@@ -49,11 +61,19 @@ - #if (BPP == 8) - gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix); - #else -+#if (BPP == 16) -+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix); -+#else - gcv.foreground = pix; - #endif -+#endif - -+#if 0 - XChangeGC(dpy, gc, GCForeground, &gcv); - XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh); -+#else -+ FillRectangle(rx, ry, rw, rh, gcv.foreground); -+#endif - - for (i = 0; i < hdr.nSubrects; i++) { - if (!ReadFromRFBServer((char *)&pix, sizeof(pix))) -@@ -70,13 +90,23 @@ - #if (BPP == 8) - gcv.foreground = (appData.useBGR233 ? BGR233ToPixel[pix] : pix); - #else -+#if (BPP == 16) -+ gcv.foreground = (appData.useBGR565 ? BGR565ToPixel[pix] : pix); -+#else - gcv.foreground = pix; - #endif -+#endif - -+#if 0 - XChangeGC(dpy, gc, GCForeground, &gcv); - XFillRectangle(dpy, desktopWin, gc, rx + subrect.x, ry + subrect.y, - subrect.w, subrect.h); -+#else -+ FillRectangle(rx + subrect.x, ry + subrect.y, subrect.w, subrect.h, gcv.foreground); -+#endif - } - - return True; - } -+ -+#undef FillRectangle -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/selection.c vnc_unixsrc/vncviewer/selection.c ---- vnc_unixsrc.orig/vncviewer/selection.c 2004-03-03 04:11:52.000000000 -0500 -+++ vnc_unixsrc/vncviewer/selection.c 2010-02-25 23:28:48.000000000 -0500 -@@ -43,13 +43,16 @@ - unsigned long* length, int* format); - static void LoseSelection(Widget w, Atom *selection); - --static Bool iAmSelectionOwner = False; -+static Bool PrimarySelectionOwner = False; -+static Bool ClipboardSelectionOwner = False; - static Time prevSelectionTime = 0L; - static Time cutBufferTime = 0L; - - #define TIME_LATER(a, b) ((a) != 0 && ((b) == 0 || (INT32)((a) - (b)) > 0)) - - -+static Atom clipboard_atom = None; -+ - /* - * InitialiseSelection() must be called after realizing widgets (because - * otherwise XtGetSelectionValue() fails). We register events on the root -@@ -62,22 +65,28 @@ - * available. - */ - --void --InitialiseSelection() --{ -+static int dbg_sel = -1; -+ -+void InitialiseSelection() { - #if XtSpecificationRelease >= 6 -- XtRegisterDrawable(dpy, DefaultRootWindow(dpy), toplevel); -+ XtRegisterDrawable(dpy, DefaultRootWindow(dpy), toplevel); - #else -- _XtRegisterWindow(DefaultRootWindow(dpy), toplevel); -+ _XtRegisterWindow(DefaultRootWindow(dpy), toplevel); - #endif -- XSelectInput(dpy, DefaultRootWindow(dpy), PropertyChangeMask); -+ XSelectInput(dpy, DefaultRootWindow(dpy), PropertyChangeMask); - -- XtAddRawEventHandler(toplevel, PropertyChangeMask, False, CutBufferChange, -- NULL); -+ XtAddRawEventHandler(toplevel, PropertyChangeMask, False, CutBufferChange, NULL); - -- XtGetSelectionValue(toplevel, XA_PRIMARY, -+ clipboard_atom = XInternAtom(dpy, "CLIPBOARD", False); -+ -+ XtGetSelectionValue(toplevel, XA_PRIMARY, - XInternAtom(dpy, "TIMESTAMP", False), - GetInitialSelectionTimeCallback, NULL, CurrentTime); -+ -+ if (dbg_sel < 0) { -+ dbg_sel = 0; -+ if (getenv("SSVNC_DEBUG_SELECTION")) dbg_sel = 1; -+ } - } - - -@@ -93,13 +102,16 @@ - Atom* selection, Atom* type, XtPointer value, - unsigned long* length, int* format) - { -- if (value && *format == 32 && *length == 1) -- prevSelectionTime = *(CARD32 *)value; -- else -- prevSelectionTime = 0L; -- -- if (value) -- XtFree(value); -+ if (value && *format == 32 && *length == 1) { -+ prevSelectionTime = *(CARD32 *)value; -+ } else { -+ prevSelectionTime = 0L; -+ } -+ -+ if (value) { -+ XtFree(value); -+ } -+ if (w || clientData || selection || type || value || length || format) {} - } - - -@@ -121,26 +133,30 @@ - void - SelectionToVNC(Widget w, XEvent *event, String *params, Cardinal *num_params) - { -- Bool always = False; -+ Bool always = appData.sendAlways; -+ Atom sendsel = XA_PRIMARY; - -- if (*num_params != 0) { -- if (strcmp(params[0],"always") == 0) { -- always = True; -- } else if (strcmp(params[0],"new") == 0) { -- always = False; -- } else { -- fprintf(stderr,"Invalid params: SelectionToVNC(always|new)\n"); -- return; -- } -- } -- -- if (always) { -- XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, GetSelectionCallback, NULL, -- TimeFromEvent(event)); -- } else { -- XtGetSelectionValue(w, XA_PRIMARY, XInternAtom(dpy, "TIMESTAMP", False), -- GetSelectionTimeCallback, NULL, TimeFromEvent(event)); -- } -+ if (*num_params != 0) { -+ if (strcmp(params[0],"always") == 0) { -+ always = True; -+ } else if (strcmp(params[0],"new") == 0) { -+ always = False; -+ } else { -+ fprintf(stderr,"Invalid params: SelectionToVNC(always|new)\n"); -+ return; -+ } -+ } -+ if (appData.sendClipboard && clipboard_atom != None) { -+ sendsel = clipboard_atom; -+ } -+ if (dbg_sel) fprintf(stderr, "SelectionToVNC %s\n", sendsel == XA_PRIMARY ? "PRIMARY" : "CLIPBOARD"); -+ -+ if (always) { -+ XtGetSelectionValue(w, sendsel, XA_STRING, GetSelectionCallback, NULL, TimeFromEvent(event)); -+ } else { -+ XtGetSelectionValue(w, sendsel, XInternAtom(dpy, "TIMESTAMP", False), GetSelectionTimeCallback, NULL, TimeFromEvent(event)); -+ } -+ if (w || event || params || num_params) {} - } - - -@@ -158,10 +174,13 @@ - int len = *length; - char *str = (char *)value; - -- if (str) -- SendClientCutText(str, len); -- else -- SendCutBuffer(); -+ if (str) { -+ if (dbg_sel) fprintf(stderr, "SendClientCutText len: %d\n", len); -+ SendClientCutText(str, len); -+ } else if (!getenv("VNCVIEWER_NO_CUTBUFFER")) { -+ SendCutBuffer(); -+ } -+ if (w || clientData || selection || type || value || length || format) {} - } - - -@@ -180,26 +199,24 @@ - Atom* type, XtPointer value, unsigned long* length, - int* format) - { -- if (value && *format == 32 && *length == 1) { -+ if (value && *format == 32 && *length == 1) { -+ Time t = *(CARD32 *)value; - -- Time t = *(CARD32 *)value; -- -- if (TIME_LATER(t, prevSelectionTime)) { -- prevSelectionTime = t; -- XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, GetSelectionCallback, NULL, -- CurrentTime); -- } -- -- } else { -- -- if (TIME_LATER(cutBufferTime, prevSelectionTime)) { -- prevSelectionTime = cutBufferTime; -- SendCutBuffer(); -- } -- } -- -- if (value) -- XtFree(value); -+ if (TIME_LATER(t, prevSelectionTime)) { -+ prevSelectionTime = t; -+ XtGetSelectionValue(w, XA_PRIMARY, XA_STRING, GetSelectionCallback, NULL, CurrentTime); -+ } -+ } else if (!getenv("VNCVIEWER_NO_CUTBUFFER")) { -+ if (TIME_LATER(cutBufferTime, prevSelectionTime)) { -+ prevSelectionTime = cutBufferTime; -+ SendCutBuffer(); -+ } -+ } -+ -+ if (value) { -+ XtFree(value); -+ } -+ if (w || clientData || selection || type || value || length || format) {} - } - - -@@ -209,16 +226,17 @@ - */ - - static void --SendCutBuffer() --{ -- char *str; -- int len; -+SendCutBuffer() { -+ char *str; -+ int len; - -- str = XFetchBytes(dpy, &len); -- if (!str) return; -+ if (dbg_sel) fprintf(stderr, "SendCutBuffer len: %d\n", len); - -- SendClientCutText(str, len); -- XFree(str); -+ str = XFetchBytes(dpy, &len); -+ if (!str) return; -+ -+ SendClientCutText(str, len); -+ XFree(str); - } - - -@@ -230,10 +248,12 @@ - static void - CutBufferChange(Widget w, XtPointer ptr, XEvent *ev, Boolean *cont) - { -- if (ev->type != PropertyNotify || ev->xproperty.atom != XA_CUT_BUFFER0) -- return; -+ if (ev->type != PropertyNotify || ev->xproperty.atom != XA_CUT_BUFFER0) { -+ return; -+ } - -- cutBufferTime = ev->xproperty.time; -+ cutBufferTime = ev->xproperty.time; -+ if (w || ptr || cont) {} - } - - -@@ -249,36 +269,69 @@ - void - SelectionFromVNC(Widget w, XEvent *event, String *params, Cardinal *num_params) - { -- Bool always = False; -- Time t = TimeFromEvent(event); -- -- if (*num_params != 0) { -- if (strcmp(params[0],"always") == 0) { -- always = True; -- } else if (strcmp(params[0],"new") == 0) { -- always = False; -- } else { -- fprintf(stderr,"Invalid params: SelectionFromVNC(always|new)\n"); -- return; -- } -- } -- -- if (t == CurrentTime) { -- fprintf(stderr,"Error in translations: SelectionFromVNC() must act on " -- "event with time field\n"); -- return; -- } -- -- if (!serverCutText || (!always && !newServerCutText)) -- return; -- -- newServerCutText = False; -- -- XStoreBytes(dpy, serverCutText, strlen(serverCutText)); -- if (XtOwnSelection(desktop, XA_PRIMARY, t, ConvertSelection, LoseSelection, -- NULL)) { -- iAmSelectionOwner = True; -- } -+ Bool always = False; -+ Time t = TimeFromEvent(event); -+ int hold_primary = 0; -+ int hold_clipboard = 0; -+ -+ if (dbg_sel) fprintf(stderr, "SelectionFromVNC\n"); -+ -+ if (*num_params != 0) { -+ if (strcmp(params[0],"always") == 0) { -+ always = True; -+ } else if (strcmp(params[0],"new") == 0) { -+ always = False; -+ } else { -+ fprintf(stderr,"Invalid params: SelectionFromVNC(always|new)\n"); -+ return; -+ } -+ } -+ -+ if (t == CurrentTime) { -+ fprintf(stderr,"Error in translations: SelectionFromVNC() must act on " -+ "event with time field\n"); -+ return; -+ } -+ -+ if (!serverCutText || (!always && !newServerCutText)) { -+ return; -+ } -+ -+ newServerCutText = False; -+ -+ if (appData.appShare) { -+ if (strstr(serverCutText, "X11VNC_APPSHARE_CMD:") == serverCutText) { -+ /* do something with it? */ -+ return; -+ } -+ } -+ -+ XStoreBytes(dpy, serverCutText, strlen(serverCutText)); -+ -+ if (appData.recvText == NULL) { -+ appData.recvText = strdup("both"); -+ } -+ if (!strcasecmp(appData.recvText, "primary")) { -+ hold_primary = 1; -+ } else if (!strcasecmp(appData.recvText, "clipboard")) { -+ hold_clipboard = 1; -+ } else { -+ hold_primary = hold_clipboard = 1; -+ } -+ -+ if (!hold_primary) { -+ ; -+ } else if (XtOwnSelection(desktop, XA_PRIMARY, t, ConvertSelection, LoseSelection, NULL)) { -+ PrimarySelectionOwner = True; -+ if (dbg_sel) fprintf(stderr, "Own PRIMARY\n"); -+ } -+ if (!hold_clipboard || clipboard_atom == None) { -+ ; -+ } else if (XtOwnSelection(desktop, clipboard_atom, t, ConvertSelection, LoseSelection, NULL)) { -+ ClipboardSelectionOwner = True; -+ if (dbg_sel) fprintf(stderr, "Own CLIPBOARD\n"); -+ } -+ if (w || event || params || num_params) {} - } - - -@@ -293,37 +346,36 @@ - XtPointer* value, unsigned long* length, int* format) - { - -- if (*target == XA_STRING && serverCutText != NULL) { -- *type = XA_STRING; -- *length = strlen(serverCutText); -- *value = (XtPointer)XtMalloc(*length); -- memcpy((char*)*value, serverCutText, *length); -- *format = 8; -- return True; -- } -+ if (*target == XA_STRING && serverCutText != NULL) { -+ *type = XA_STRING; -+ *length = strlen(serverCutText); -+ *value = (XtPointer)XtMalloc(*length); -+ memcpy((char*)*value, serverCutText, *length); -+ *format = 8; -+ return True; -+ } - -- if (XmuConvertStandardSelection(w, CurrentTime, selection, target, type, -+ if (XmuConvertStandardSelection(w, CurrentTime, selection, target, type, - (XPointer*)value, length, format)) { -- if (*target == XInternAtom(dpy, "TARGETS", False)) { -- /* add STRING to list of standard targets */ -- Atom* targetP; -- Atom* std_targets = (Atom*)*value; -- unsigned long std_length = *length; -- -- *length = std_length + 1; -- *value = (XtPointer)XtMalloc(sizeof(Atom)*(*length)); -- targetP = *(Atom**)value; -- *targetP++ = XA_STRING; -- memmove((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length); -- XtFree((char*)std_targets); -- *type = XA_ATOM; -- *format = 32; -- return True; -- } -- -- return True; -- } -- return False; -+ if (*target == XInternAtom(dpy, "TARGETS", False)) { -+ /* add STRING to list of standard targets */ -+ Atom* targetP; -+ Atom* std_targets = (Atom*)*value; -+ unsigned long std_length = *length; -+ -+ *length = std_length + 1; -+ *value = (XtPointer)XtMalloc(sizeof(Atom)*(*length)); -+ targetP = *(Atom**)value; -+ *targetP++ = XA_STRING; -+ memmove((char*)targetP, (char*)std_targets, sizeof(Atom)*std_length); -+ XtFree((char*)std_targets); -+ *type = XA_ATOM; -+ *format = 32; -+ return True; -+ } -+ return True; -+ } -+ return False; - } - - -@@ -332,7 +384,13 @@ - */ - - static void --LoseSelection(Widget w, Atom *selection) --{ -- iAmSelectionOwner = False; -+LoseSelection(Widget w, Atom *selection) { -+ if (*selection == XA_PRIMARY) { -+ if (dbg_sel) fprintf(stderr, "lost PRIMARY\n"); -+ PrimarySelectionOwner = False; -+ } else if (clipboard_atom != None && *selection == clipboard_atom) { -+ if (dbg_sel) fprintf(stderr, "lost CLIPBOARD\n"); -+ ClipboardSelectionOwner = False; -+ } -+ if (w) {} - } -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/shm.c vnc_unixsrc/vncviewer/shm.c ---- vnc_unixsrc.orig/vncviewer/shm.c 2000-06-11 08:00:53.000000000 -0400 -+++ vnc_unixsrc/vncviewer/shm.c 2010-02-25 23:40:58.000000000 -0500 -@@ -30,71 +30,113 @@ - static Bool caughtShmError = False; - static Bool needShmCleanup = False; - --void --ShmCleanup() --{ -- fprintf(stderr,"ShmCleanup called\n"); -- if (needShmCleanup) { -- shmdt(shminfo.shmaddr); -- shmctl(shminfo.shmid, IPC_RMID, 0); -- needShmCleanup = False; -- } -+static int ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error) { -+ caughtShmError = True; -+ if (dpy || error) {} -+ return 0; - } - --static int --ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error) --{ -- caughtShmError = True; -- return 0; -+void ShmDetach() { -+ if (needShmCleanup) { -+ XErrorHandler oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler); -+ fprintf(stderr,"ShmDetach called.\n"); -+ XShmDetach(dpy, &shminfo); -+ XSync(dpy, False); -+ XSetErrorHandler(oldXErrorHandler); -+ } - } - --XImage * --CreateShmImage() --{ -- XImage *image; -- XErrorHandler oldXErrorHandler; -- -- if (!XShmQueryExtension(dpy)) -- return NULL; -- -- image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo, -- si.framebufferWidth, si.framebufferHeight); -- if (!image) return NULL; -- -- shminfo.shmid = shmget(IPC_PRIVATE, -- image->bytes_per_line * image->height, -- IPC_CREAT|0777); -+void ShmCleanup() { -+ if (needShmCleanup) { -+ fprintf(stderr,"ShmCleanup called.\n"); -+ XSync(dpy, False); -+ shmdt(shminfo.shmaddr); -+ shmctl(shminfo.shmid, IPC_RMID, 0); - -- if (shminfo.shmid == -1) { -- XDestroyImage(image); -- return NULL; -- } -- -- shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0); -- -- if (shminfo.shmaddr == (char *)-1) { -- XDestroyImage(image); -- shmctl(shminfo.shmid, IPC_RMID, 0); -- return NULL; -- } -+ needShmCleanup = False; -+ } -+} - -- shminfo.readOnly = True; -+Bool UsingShm() { -+ return needShmCleanup; -+} - -- oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler); -- XShmAttach(dpy, &shminfo); -- XSync(dpy, False); -- XSetErrorHandler(oldXErrorHandler); -+int scale_round(int len, double fac); -+extern int scale_x, scale_y; -+extern double scale_factor_x, scale_factor_y; - -- if (caughtShmError) { -- XDestroyImage(image); -- shmdt(shminfo.shmaddr); -- shmctl(shminfo.shmid, IPC_RMID, 0); -- return NULL; -- } -+XImage * -+CreateShmImage(int do_ycrop) -+{ -+ XImage *image; -+ XErrorHandler oldXErrorHandler; -+ int ymax = si.framebufferHeight; -+ int xmax = si.framebufferWidth; -+ -+ if (!XShmQueryExtension(dpy)) { -+ return NULL; -+ } -+ if (!appData.useShm) { -+ return NULL; -+ } -+ if (do_ycrop == -1) { -+ /* kludge to test for shm prescence */ -+ return (XImage *) 0x1; -+ } -+ -+ if (do_ycrop) { -+ ymax = appData.yCrop; -+ } -+ -+ if (scale_x > 0) { -+ xmax = scale_round(xmax, scale_factor_x); -+ ymax = scale_round(ymax, scale_factor_y); -+ } -+ -+ image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo, xmax, ymax); -+ if (!image) { -+ return NULL; -+ } -+ -+ shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT|0777); -+ -+ if (shminfo.shmid == -1) { -+ XDestroyImage(image); -+ if (0) fprintf(stderr, "CreateShmImage: destroyed 'image' (1)\n"); -+ return NULL; -+ } -+ -+ shminfo.shmaddr = image->data = shmat(shminfo.shmid, 0, 0); -+ -+ if (shminfo.shmaddr == (char *)-1) { -+ XDestroyImage(image); -+#if 0 -+ fprintf(stderr, "CreateShmImage: destroyed 'image' (2)\n"); -+#endif -+ shmctl(shminfo.shmid, IPC_RMID, 0); -+ return NULL; -+ } -+ -+ shminfo.readOnly = True; -+ -+ oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler); -+ XShmAttach(dpy, &shminfo); -+ XSync(dpy, False); -+ XSetErrorHandler(oldXErrorHandler); -+ -+ if (caughtShmError) { -+ XDestroyImage(image); -+#if 0 -+ fprintf(stderr, "CreateShmImage: destroyed 'image' (3)\n"); -+#endif -+ shmdt(shminfo.shmaddr); -+ shmctl(shminfo.shmid, IPC_RMID, 0); -+ return NULL; -+ } - -- needShmCleanup = True; -+ needShmCleanup = True; - -- fprintf(stderr,"Using shared memory PutImage\n"); -+ fprintf(stderr,"Using shared memory (PutImage ycrop=%d, Size %dx%d)\n", do_ycrop, xmax, ymax); - -- return image; -+ return image; - } -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/smake vnc_unixsrc/vncviewer/smake ---- vnc_unixsrc.orig/vncviewer/smake 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/smake 2007-02-19 12:28:05.000000000 -0500 -@@ -0,0 +1,11 @@ -+#!/bin/sh -+ -+PATH=`pwd`/../..:/usr/sfw/bin:/usr/ccs/bin:$PATH -+export PATH -+if [ "X$1" != "X" ]; then -+ "$@" -+else -+ make -+ strip vncviewer -+ ls -l vncviewer -+fi -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/sockets.c vnc_unixsrc/vncviewer/sockets.c ---- vnc_unixsrc.orig/vncviewer/sockets.c 2001-01-14 22:54:18.000000000 -0500 -+++ vnc_unixsrc/vncviewer/sockets.c 2010-04-18 11:41:07.000000000 -0400 -@@ -22,17 +22,31 @@ - */ - - #include <unistd.h> -+#include <time.h> - #include <sys/socket.h> - #include <errno.h> - #include <netinet/in.h> - #include <netinet/tcp.h> - #include <arpa/inet.h> -+#include <sys/un.h> - #include <netdb.h> - #include <fcntl.h> - #include <assert.h> - #include <vncviewer.h> - -+#ifndef SOL_IPV6 -+#ifdef IPPROTO_IPV6 -+#define SOL_IPV6 IPPROTO_IPV6 -+#endif -+#endif -+ -+/* Solaris (sysv?) needs INADDR_NONE */ -+#ifndef INADDR_NONE -+#define INADDR_NONE ((in_addr_t) 0xffffffff) -+#endif -+ - void PrintInHex(char *buf, int len); -+extern void printChat(char *, Bool); - - Bool errorMessageOnReadFailure = True; - -@@ -56,31 +70,396 @@ - */ - - static Bool rfbsockReady = False; -+static Bool xfrsockReady = False; -+static XtInputId rfbsockId = 0; -+static XtInputId xfrsockId = 0; -+static int do_rfbsockId = 0; -+static int do_xfrsockId = 0; -+ - static void - rfbsockReadyCallback(XtPointer clientData, int *fd, XtInputId *id) - { -- rfbsockReady = True; -- XtRemoveInput(*id); -+ rfbsockReady = True; -+#if 0 -+ XtRemoveInput(*id); -+#endif -+ XtRemoveInput(rfbsockId); -+ if (do_xfrsockId) { -+ XtRemoveInput(xfrsockId); -+ } -+ if (clientData || fd || id) {} - } - - static void --ProcessXtEvents() -+xfrsockReadyCallback(XtPointer clientData, int *fd, XtInputId *id) - { -- rfbsockReady = False; -- XtAppAddInput(appContext, rfbsock, (XtPointer)XtInputReadMask, -- rfbsockReadyCallback, NULL); -- while (!rfbsockReady) { -- XtAppProcessEvent(appContext, XtIMAll); -- } -+ xfrsockReady = True; -+ XtRemoveInput(xfrsockId); -+ if (do_rfbsockId) { -+ XtRemoveInput(rfbsockId); -+ } -+ if (clientData || fd || id) {} -+} -+ -+ -+extern int skip_XtUpdate; -+extern int skip_XtUpdateAll; -+extern int filexfer_sock, filexfer_listen; -+extern time_t start_listen; -+extern void CheckTextInput(void); -+extern time_t last_filexfer; -+ -+static char fxfer[65536]; -+int fxfer_size = 65536; -+ -+int rfbsock_is_ready(void) { -+ fd_set fds; -+ struct timeval tv; -+ -+ if (rfbsock < 0) { -+ return 0; -+ } -+ FD_ZERO(&fds); -+ FD_SET(rfbsock,&fds); -+ tv.tv_sec = 0; -+ tv.tv_usec = 0; -+ if (select(rfbsock+1, &fds, NULL, NULL, &tv) > 0) { -+ if (FD_ISSET(rfbsock, &fds)) { -+ return 1; -+ } -+ } -+ return 0; -+} -+ -+time_t filexfer_start = 0; -+ -+void CheckFileXfer() { -+ fd_set fds; -+ struct timeval tv; -+ int i, icnt = 0, igot = 0, bytes0 = 0, bytes = 0, grace = 0, n, list = 0; -+ int db = 0; -+ -+ if (!appData.fileActive || (filexfer_sock < 0 && filexfer_listen < 0)) { -+ return; -+ } -+ -+ if (filexfer_listen >= 0 && time(NULL) > start_listen + 30) { -+ fprintf(stderr, "filexfer closing aging listen socket.\n"); -+ close(filexfer_listen); -+ filexfer_listen = -1; -+ return; -+ } -+if (0) fprintf(stderr, "In CheckFileXfer\n"); -+ -+ if (filexfer_listen >=0) { -+ n = filexfer_listen; -+ list = 1; -+ } else { -+ n = filexfer_sock; -+ } -+ -+ while (1) { -+ icnt++; -+ FD_ZERO(&fds); -+ FD_SET(n,&fds); -+ tv.tv_sec = 0; -+ tv.tv_usec = 0; -+ if (select(n+1, &fds, NULL, NULL, &tv) > 0) { -+ if (FD_ISSET(n, &fds)) { -+ if (list) { -+ if (filexfer_sock >= 0) { -+ fprintf(stderr, "filexfer close stale(?) filexfer_sock.\n"); -+ close(filexfer_sock); -+ filexfer_sock = -1; -+ } -+ filexfer_sock = AcceptTcpConnection(filexfer_listen); -+ if (filexfer_sock >= 0) { -+ fprintf(stderr, "filexfer accept OK.\n"); -+ close(filexfer_listen); -+ filexfer_listen = -1; -+ filexfer_start = last_filexfer = time(NULL); -+ } else { -+ fprintf(stderr, "filexfer accept failed.\n"); -+ } -+ break; -+ } else { -+ ssize_t rn; -+ unsigned char hdr[12]; -+ unsigned int len; -+ if (db) fprintf(stderr, "try read filexfer...\n"); -+ if (hdr || len || i) {} -+#if 1 -+ rn = read(n, fxfer, 1*8192); -+if (db) { -+ int i; -+ fprintf(stderr, "CFX HDR:"); -+ for (i=0; i < 12; i++) { -+ fprintf(stderr, " %d", (int) fxfer[i]); -+ } -+ fprintf(stderr, " ?\n"); -+} -+ if (0 || db) fprintf(stderr, "filexfer read[%d] %d.\n", icnt, rn); -+ if (rn < 0) { -+ fprintf(stderr, "filexfer bad read: %d\n", errno); -+ break; -+ } else if (rn == 0) { -+ fprintf(stderr, "filexfer gone.\n"); -+ close(n); -+ filexfer_sock = -1; -+ last_filexfer = time(NULL); -+#if 0 -+ fprintf(stderr, "last_filexfer-2a: %d\n", last_filexfer); -+#endif -+ appData.fileActive = False; -+ SendFramebufferUpdateRequest(0, 0, 1, 1, False); -+ return; -+ } else if (rn > 0) { -+ if (db > 1) write(2, fxfer, rn); -+ if (db) fprintf(stderr, "\n"); -+ bytes += rn; -+ last_filexfer = time(NULL); -+#if 0 -+ fprintf(stderr, "last_filexfer-2b: %d\n", last_filexfer); -+#endif -+ -+ if (0) { -+ /* WE TRY TO FIX THIS IN THE JAVA NOW */ -+ if (appData.ultraDSM) { -+ unsigned char msg = rfbFileTransfer; -+ unsigned char hdc = (unsigned char) fxfer[0]; -+ if (msg == hdc) { -+ /* cross your fingers... */ -+ WriteExact(rfbsock, (char *)&msg, 1); -+ } -+ } -+ } -+ if (!WriteExact(rfbsock, fxfer, rn)) { -+ return; -+ } -+ igot = 1; -+ } -+#else -+ /* not working, not always 7 msg type. */ -+ rn = read(n, hdr, 12); -+ if (db) fprintf(stderr, "filexfer read %d.\n", rn); -+ if (rn == 0) { -+ fprintf(stderr, "filexfer gone.\n"); -+ close(n); -+ filexfer_sock = -1; -+ last_filexfer = time(NULL); -+ return; -+ } -+ if (rn == 12) { -+ len = (hdr[8] << 24) | (hdr[9] << 16) | (hdr[10] << 8) | hdr[11]; -+ if (db) fprintf(stderr, "n=%d len=%d\n", rn, len); -+ if (db > 1) write(2, hdr, rn); -+ if (db) fprintf(stderr, "\n"); -+ WriteExact(rfbsock, hdr, rn); -+ if (len > 0) { -+ rn = read(len, fxfer, len); -+ if (!WriteExact(rfbsock, fxfer, len)) { -+ last_filexfer = time(NULL); -+ return; -+ } -+ if (db > 1) write(2, fxfer, len); -+ } -+ if (db) fprintf(stderr, "\n"); -+ } else { -+ if (db) fprintf(stderr, "bad rn: %d\n", rn); -+ } -+ igot = 1; -+#endif -+ } -+ } -+ } else { -+ if (bytes >= 8192) { -+ int ok = 0; -+ if (bytes0 == 0) { -+ ok = 1; -+ } else if (bytes >= bytes0 + 12) { -+ ok = 1; -+ } else if (grace < 20) { -+ ok = 1; -+ } -+ if (ok) { -+ grace++; -+ bytes0 = bytes; -+#if 0 -+ fprintf(stderr, "grace: %d\n", grace); -+ /* forgot that this is about... */ -+#endif -+ usleep(10 * 1000); -+ continue; -+ } -+ } -+ break; -+ } -+ } -+ if (igot) { -+ last_filexfer = time(NULL); -+#if 0 -+ fprintf(stderr, "last_filexfer-2c: %d\n", last_filexfer); -+#endif -+ } -+#if 0 -+fprintf(stderr, "Out CheckFileXfer\n"); -+#endif -+ return; -+} -+ -+static void check_term_chat(void) { -+ fd_set fds; -+ struct timeval tv; -+ int i, igot = -1, n = fileno(stdin); -+ char strs[100][512]; -+ char buf[rfbTextMaxSize]; -+ -+ for (i=0; i < 100; i++) { -+ FD_ZERO(&fds); -+ FD_SET(n,&fds); -+ tv.tv_sec = 0; -+ tv.tv_usec = 0; -+ if (select(n+1, &fds, NULL, NULL, &tv) > 0) { -+ if (FD_ISSET(n, &fds)) { -+ fgets(strs[i], 512, stdin); -+ igot = i; -+ } else { -+ break; -+ } -+ } else { -+ break; -+ } -+ } -+ buf[0] = '\0'; -+ for (i=0; i <= igot; i++) { -+ if (strlen(buf) + strlen(strs[i]) < rfbTextMaxSize) { -+ strcat(buf, strs[i]); -+ } else { -+ SendTextChat(buf); -+ buf[0] = '0'; -+ } -+ } -+ if (buf[0] != '\0') { -+ SendTextChat(buf); -+ } -+ if (igot >= 0) printChat("Send: ", False); -+} -+ -+static time_t time_mark; -+extern int delay_filexfer; -+#include <sys/stat.h> -+ -+extern double start_time; -+ -+void ProcessXtEvents() -+{ -+ int db = 0; -+ static int dyn = -1; -+ static int chat_was_active = 0; -+ int check_chat = 0; -+ -+ if (dyn < 0) { -+ struct stat sb; -+ if (getenv("USER") && !strcmp(getenv("USER"), "runge")) { -+ if (stat("/tmp/nodyn", &sb) == 0) { -+ putenv("NOFTFBUPDATES=1"); -+ unlink("/tmp/nodyn"); -+ } -+ } -+ if (getenv("NOFTFBUPDATES")) { -+ dyn = 0; -+ } else { -+ dyn = 1; -+ } -+ } -+ -+#if 0 -+ if (0) fprintf(stderr, "ProcessXtEvents: %d %.4f\n", skip_XtUpdateAll, dnow() - start_time); -+#endif -+ -+ if (skip_XtUpdateAll) { -+ return; -+ } -+ -+ /* text chat */ -+ if (appData.chatActive ) { -+ check_chat = 1; -+ } else if (chat_was_active) { -+ static double last_check = 0.0; -+ double now = dnow(); -+ if (now > last_check + 0.75) { -+ check_chat = 1; -+ last_check = now; -+ } -+ } -+ if (check_chat) { -+ if (appData.chatActive) { -+ chat_was_active = 1; -+ } -+ if (!appData.termChat) { -+ CheckTextInput(); -+ } else { -+ check_term_chat(); -+ } -+ } -+ -+ if (skip_XtUpdate) { -+ return; -+ } -+ -+ rfbsockReady = False; -+ xfrsockReady = False; -+ do_rfbsockId = 1; -+ rfbsockId = XtAppAddInput(appContext, rfbsock, (XtPointer)XtInputReadMask, -+ rfbsockReadyCallback, NULL); -+ -+ do_xfrsockId = 0; -+ if (filexfer_sock >= 0) { -+ do_xfrsockId = 1; -+ xfrsockId = XtAppAddInput(appContext, filexfer_sock, (XtPointer)XtInputReadMask, -+ xfrsockReadyCallback, NULL); -+ } -+ -+ time_mark = time(NULL); -+ -+ if (appData.fileActive) { -+ static int first = 1; -+ if (first) { -+ fprintf(stderr, "PXT: dynamic fb updates during filexfer: %d\n", dyn); -+ first = 0; -+ } -+ } -+ -+ if (db) fprintf(stderr, "XtAppAddInput: "); -+ while (!rfbsockReady && !xfrsockReady) { -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+ if (db) fprintf(stderr, "."); -+ if (dyn && filexfer_sock >= 0 && time(NULL) > time_mark + delay_filexfer) { -+ SendFramebufferUpdateRequest(0, 0, w, h, False); -+ } -+ XtAppProcessEvent(appContext, XtIMAll); -+ } -+ if (db) fprintf(stderr, " done. r: %d x: %d\n", rfbsockReady, xfrsockReady); -+ -+ if (xfrsockReady) { -+ CheckFileXfer(); -+ } - } - - Bool - ReadFromRFBServer(char *out, unsigned int n) - { -+#if 0 -+ double start = dnow(), dn = n; -+#endif - if (n <= buffered) { - memcpy(out, bufoutptr, n); - bufoutptr += n; - buffered -= n; -+#if 0 -+fprintf(stderr, "R0: %06d\n", (int) dn); -+#endif - return True; - } - -@@ -119,6 +498,9 @@ - memcpy(out, bufoutptr, n); - bufoutptr += n; - buffered -= n; -+#if 0 -+fprintf(stderr, "R1: %06d %06d %10.2f KB/sec\n", (int) dn, buffered+n, 1e-3 * (buffered+n)/(dnow() - start)); -+#endif - return True; - - } else { -@@ -146,11 +528,16 @@ - n -= i; - } - -+#if 0 -+fprintf(stderr, "R2: %06d %06d %10.2f KB/sec\n", (int) dn, (int) dn, 1e-3 * (dn)/(dnow() - start)); -+#endif - return True; - } - } - - -+int currentMsg = -1; -+ - /* - * Write an exact number of bytes, and don't return until you've sent them. - */ -@@ -158,81 +545,321 @@ - Bool - WriteExact(int sock, char *buf, int n) - { -- fd_set fds; -- int i = 0; -- int j; -- -- while (i < n) { -- j = write(sock, buf + i, (n - i)); -- if (j <= 0) { -- if (j < 0) { -- if (errno == EWOULDBLOCK || errno == EAGAIN) { -- FD_ZERO(&fds); -- FD_SET(rfbsock,&fds); -+ fd_set fds; -+ int i = 0; -+ int j; -+ -+ if (appData.ultraDSM && currentMsg >= 0) { -+ /* this is for goofy UltraVNC DSM send RFB msg char twice: */ -+ unsigned char msg = (unsigned char) currentMsg; -+ currentMsg = -1; -+ if (!WriteExact(sock, (char *)&msg, sizeof(msg))) { -+ return False; -+ } -+ } -+ currentMsg = -1; - -- if (select(rfbsock+1, NULL, &fds, NULL, NULL) <= 0) { -- fprintf(stderr,programName); -- perror(": select"); -- return False; -- } -- j = 0; -- } else { -- fprintf(stderr,programName); -- perror(": write"); -- return False; -+ while (i < n) { -+ j = write(sock, buf + i, (n - i)); -+ if (j <= 0) { -+ if (j < 0) { -+ if (errno == EWOULDBLOCK || errno == EAGAIN) { -+ FD_ZERO(&fds); -+ FD_SET(rfbsock,&fds); -+ -+ if (select(rfbsock+1, NULL, &fds, NULL, NULL) <= 0) { -+ fprintf(stderr,programName); -+ perror(": select"); -+ return False; -+ } -+ j = 0; -+ } else { -+ fprintf(stderr,programName); -+ perror(": write"); -+ return False; -+ } -+ } else { -+ fprintf(stderr,"%s: write failed\n",programName); -+ return False; -+ } -+ } -+ i += j; - } -- } else { -- fprintf(stderr,"%s: write failed\n",programName); -- return False; -- } -- } -- i += j; -- } -- return True; -+ return True; - } - -+int -+ConnectToUnixSocket(char *file) { -+ int sock; -+ struct sockaddr_un addr; -+ int i; -+ -+ memset(&addr, 0, sizeof(struct sockaddr_un)); -+ -+ addr.sun_family = AF_UNIX; -+ -+ for (i=0; i < 108; i++) { -+ addr.sun_path[i] = file[i]; -+ if (file[i] == '\0') { -+ break; -+ } -+ } -+ -+ sock = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (sock < 0) { -+ fprintf(stderr,programName); -+ perror(": ConnectToUnixSocket: socket"); -+ return -1; -+ } -+ -+ if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -+ fprintf(stderr, programName); -+ perror(": ConnectToUnixSocket: connect"); -+ close(sock); -+ return -1; -+ } -+ -+ return sock; -+} -+ -+char *ipv6_getipaddr(struct sockaddr *paddr, int addrlen) { -+#if defined(AF_INET6) && defined(NI_NUMERICHOST) -+ char name[200]; -+ if (appData.noipv6) { -+ return strdup("unknown"); -+ } -+ if (getnameinfo(paddr, addrlen, name, sizeof(name), NULL, 0, NI_NUMERICHOST) == 0) { -+ return strdup(name); -+ } -+#endif -+ if (paddr || addrlen) {} -+ return strdup("unknown"); -+} -+ -+char *ipv6_getnameinfo(struct sockaddr *paddr, int addrlen) { -+#if defined(AF_INET6) -+ char name[200]; -+ if (appData.noipv6) { -+ return strdup("unknown"); -+ } -+ if (getnameinfo(paddr, addrlen, name, sizeof(name), NULL, 0, 0) == 0) { -+ return strdup(name); -+ } -+#endif -+ if (paddr || addrlen) {} -+ return strdup("unknown"); -+} -+ -+int dotted_ip(char *host, int partial) { -+ int len, dots = 0; -+ char *p = host; -+ -+ if (!host) { -+ return 0; -+ } -+ -+ if (!isdigit((unsigned char) host[0])) { -+ return 0; -+ } -+ -+ len = strlen(host); -+ if (!partial && !isdigit((unsigned char) host[len-1])) { -+ return 0; -+ } -+ -+ while (*p != '\0') { -+ if (*p == '.') dots++; -+ if (*p == '.' || isdigit((unsigned char) (*p))) { -+ p++; -+ continue; -+ } -+ return 0; -+ } -+ if (!partial && dots != 3) { -+ return 0; -+ } -+ return 1; -+} - - /* - * ConnectToTcpAddr connects to the given TCP port. - */ - --int --ConnectToTcpAddr(unsigned int host, int port) --{ -- int sock; -- struct sockaddr_in addr; -- int one = 1; -- -- addr.sin_family = AF_INET; -- addr.sin_port = htons(port); -- addr.sin_addr.s_addr = host; -+int ConnectToTcpAddr(const char *hostname, int port) { -+ int sock = -1, one = 1; -+ unsigned int host; -+ struct sockaddr_in addr; -+ -+ if (appData.noipv4) { -+ fprintf(stderr, "ipv4 is disabled via VNCVIEWER_NO_IPV4/-noipv4.\n"); -+ goto try6; -+ } - -- sock = socket(AF_INET, SOCK_STREAM, 0); -- if (sock < 0) { -- fprintf(stderr,programName); -- perror(": ConnectToTcpAddr: socket"); -- return -1; -- } -+ if (!StringToIPAddr(hostname, &host)) { -+ fprintf(stderr, "Could not convert '%s' to ipv4 host address.\n", hostname); -+ goto try6; -+ } - -- if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -- fprintf(stderr,programName); -- perror(": ConnectToTcpAddr: connect"); -- close(sock); -- return -1; -- } -+ memset(&addr, 0, sizeof(struct sockaddr_in)); - -- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, -- (char *)&one, sizeof(one)) < 0) { -- fprintf(stderr,programName); -- perror(": ConnectToTcpAddr: setsockopt"); -- close(sock); -- return -1; -- } -+ addr.sin_family = AF_INET; -+ addr.sin_port = htons(port); -+ addr.sin_addr.s_addr = host; -+ -+ sock = socket(AF_INET, SOCK_STREAM, 0); -+ if (sock < 0) { -+ perror("ConnectToTcpAddr[ipv4]: socket"); -+ sock = -1; -+ goto try6; -+ } -+ -+ if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -+ perror("ConnectToTcpAddr[ipv4]: connect"); -+ close(sock); -+ sock = -1; -+ goto try6; -+ } -+ -+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) { -+ perror("ConnectToTcpAddr[ipv4]: setsockopt"); -+ close(sock); -+ sock = -1; -+ goto try6; -+ } - -- return sock; -+ if (sock >= 0) { -+ return sock; -+ } -+ -+ try6: -+ -+#ifdef AF_INET6 -+ if (!appData.noipv6) { -+ int err; -+ struct addrinfo *ai; -+ struct addrinfo hints; -+ char service[32], *host2, *q; -+ -+ fprintf(stderr, "Trying ipv6 connection to '%s'\n", hostname); -+ -+ memset(&hints, 0, sizeof(hints)); -+ sprintf(service, "%d", port); -+ -+ hints.ai_family = AF_UNSPEC; -+ hints.ai_socktype = SOCK_STREAM; -+#ifdef AI_ADDRCONFIG -+ hints.ai_flags |= AI_ADDRCONFIG; -+#endif -+#ifdef AI_NUMERICSERV -+ hints.ai_flags |= AI_NUMERICSERV; -+#endif -+ if (!strcmp(hostname, "localhost")) { -+ host2 = strdup("::1"); -+ } else if (!strcmp(hostname, "127.0.0.1")) { -+ host2 = strdup("::1"); -+ } else if (hostname[0] == '[') { -+ host2 = strdup(hostname+1); -+ } else { -+ host2 = strdup(hostname); -+ } -+ q = strrchr(host2, ']'); -+ if (q) { -+ *q = '\0'; -+ } -+ -+ err = getaddrinfo(host2, service, &hints, &ai); -+ if (err != 0) { -+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: getaddrinfo[%d]: %s\n", err, gai_strerror(err)); -+ usleep(100 * 1000); -+ err = getaddrinfo(host2, service, &hints, &ai); -+ } -+ free(host2); -+ -+ if (err != 0) { -+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: getaddrinfo[%d]: %s (2nd try)\n", err, gai_strerror(err)); -+ } else { -+ struct addrinfo *ap = ai; -+ while (ap != NULL) { -+ int fd = -1; -+ char *s = ipv6_getipaddr(ap->ai_addr, ap->ai_addrlen); -+ if (s) { -+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: trying ip-addr: '%s'\n", s); -+ free(s); -+ } -+ if (appData.noipv4) { -+ struct sockaddr_in6 *s6ptr; -+ if (ap->ai_family != AF_INET6) { -+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: skipping AF_INET address under VNCVIEWER_NO_IPV4/-noipv4\n"); -+ ap = ap->ai_next; -+ continue; -+ } -+#ifdef IN6_IS_ADDR_V4MAPPED -+ s6ptr = (struct sockaddr_in6 *) ap->ai_addr; -+ if (IN6_IS_ADDR_V4MAPPED(&(s6ptr->sin6_addr))) { -+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: skipping V4MAPPED address under VNCVIEWER_NO_IPV4/-noipv4\n"); -+ ap = ap->ai_next; -+ continue; -+ } -+#endif -+ } -+ -+ fd = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol); -+ if (fd == -1) { -+ perror("ConnectToTcpAddr[ipv6]: socket"); -+ } else { -+ int dmsg = 0; -+ int res = connect(fd, ap->ai_addr, ap->ai_addrlen); -+#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) -+ if (res != 0) { -+ int zero = 0; -+ perror("ConnectToTcpAddr[ipv6]: connect"); -+ dmsg = 1; -+ if (setsockopt(fd, SOL_IPV6, IPV6_V6ONLY, (char *)&zero, sizeof(zero)) == 0) { -+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: trying again with IPV6_V6ONLY=0\n"); -+ res = connect(fd, ap->ai_addr, ap->ai_addrlen); -+ dmsg = 0; -+ } -+ } -+#endif -+ if (res == 0) { -+ fprintf(stderr, "ConnectToTcpAddr[ipv6]: connect OK\n"); -+ sock = fd; -+ break; -+ } else { -+ if (!dmsg) perror("ConnectToTcpAddr[ipv6]: connect"); -+ close(fd); -+ } -+ } -+ ap = ap->ai_next; -+ } -+ freeaddrinfo(ai); -+ } -+ if (sock >= 0 && setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) { -+ perror("ConnectToTcpAddr: setsockopt"); -+ close(sock); -+ sock = -1; -+ } -+ } -+#endif -+ return sock; - } - -+Bool SocketPair(int fd[2]) { -+ if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd) == -1) { -+ perror("socketpair"); -+ return False; -+ } -+ return True; -+} - -+Bool SetNoDelay(int sock) { -+ const int one = 1; -+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) { -+ perror("setsockopt"); -+ return False; -+ } -+ return True; -+} - - /* - * FindFreeTcpPort tries to find unused TCP port in the range -@@ -242,29 +869,31 @@ - int - FindFreeTcpPort(void) - { -- int sock, port; -- struct sockaddr_in addr; -+ int sock, port; -+ struct sockaddr_in addr; - -- addr.sin_family = AF_INET; -- addr.sin_addr.s_addr = INADDR_ANY; -+ memset(&addr, 0, sizeof(struct sockaddr_in)); - -- sock = socket(AF_INET, SOCK_STREAM, 0); -- if (sock < 0) { -- fprintf(stderr,programName); -- perror(": FindFreeTcpPort: socket"); -- return 0; -- } -+ addr.sin_family = AF_INET; -+ addr.sin_addr.s_addr = INADDR_ANY; - -- for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) { -- addr.sin_port = htons((unsigned short)port); -- if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { -- close(sock); -- return port; -- } -- } -+ sock = socket(AF_INET, SOCK_STREAM, 0); -+ if (sock < 0) { -+ fprintf(stderr,programName); -+ perror(": FindFreeTcpPort: socket"); -+ return 0; -+ } -+ -+ for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) { -+ addr.sin_port = htons((unsigned short)port); -+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { -+ close(sock); -+ return port; -+ } -+ } - -- close(sock); -- return 0; -+ close(sock); -+ return 0; - } - - -@@ -272,47 +901,110 @@ - * ListenAtTcpPort starts listening at the given TCP port. - */ - --int --ListenAtTcpPort(int port) --{ -- int sock; -- struct sockaddr_in addr; -- int one = 1; -- -- addr.sin_family = AF_INET; -- addr.sin_port = htons(port); -- addr.sin_addr.s_addr = INADDR_ANY; -+int use_loopback = 0; - -- sock = socket(AF_INET, SOCK_STREAM, 0); -- if (sock < 0) { -- fprintf(stderr,programName); -- perror(": ListenAtTcpPort: socket"); -- return -1; -- } -+int ListenAtTcpPort(int port) { -+ int sock; -+ struct sockaddr_in addr; -+ int one = 1; -+ -+ if (appData.noipv4) { -+ fprintf(stderr, "ipv4 is disabled via VNCVIEWER_NO_IPV4/-noipv4.\n"); -+ return -1; -+ } - -- if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, -- (const char *)&one, sizeof(one)) < 0) { -- fprintf(stderr,programName); -- perror(": ListenAtTcpPort: setsockopt"); -- close(sock); -- return -1; -- } -+ memset(&addr, 0, sizeof(struct sockaddr_in)); - -- if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -- fprintf(stderr,programName); -- perror(": ListenAtTcpPort: bind"); -- close(sock); -- return -1; -- } -+ addr.sin_family = AF_INET; -+ addr.sin_port = htons(port); -+ addr.sin_addr.s_addr = INADDR_ANY; - -- if (listen(sock, 5) < 0) { -- fprintf(stderr,programName); -- perror(": ListenAtTcpPort: listen"); -- close(sock); -- return -1; -- } -+ if (getenv("VNCVIEWER_LISTEN_LOCALHOST") || use_loopback) { -+ addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); -+ } -+ -+ sock = socket(AF_INET, SOCK_STREAM, 0); -+ if (sock < 0) { -+ perror("ListenAtTcpPort: socket"); -+ return -1; -+ } - -- return sock; -+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&one, sizeof(one)) < 0) { -+ perror("ListenAtTcpPort: setsockopt"); -+ close(sock); -+ return -1; -+ } -+ -+ if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -+ perror("ListenAtTcpPort: bind"); -+ close(sock); -+ return -1; -+ } -+ -+ if (listen(sock, 32) < 0) { -+ perror("ListenAtTcpPort: listen"); -+ close(sock); -+ return -1; -+ } -+ -+ return sock; -+} -+ -+int ListenAtTcpPort6(int port) { -+ int sock = -1; -+#ifdef AF_INET6 -+ struct sockaddr_in6 sin; -+ int one = 1; -+ -+ if (appData.noipv6) { -+ fprintf(stderr, "ipv6 is disabled via VNCVIEWER_NO_IPV6/-noipv6.\n"); -+ return -1; -+ } -+ -+ sock = socket(AF_INET6, SOCK_STREAM, 0); -+ if (sock < 0) { -+ perror("ListenAtTcpPort[ipv6]: socket"); -+ return -1; -+ } -+ -+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) { -+ perror("ListenAtTcpPort[ipv6]: setsockopt1"); -+ close(sock); -+ return -1; -+ } -+ -+#if defined(SOL_IPV6) && defined(IPV6_V6ONLY) -+ if (setsockopt(sock, SOL_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) { -+ perror("ListenAtTcpPort[ipv6]: setsockopt2"); -+ close(sock); -+ return -1; -+ } -+#endif -+ -+ memset((char *)&sin, 0, sizeof(sin)); -+ sin.sin6_family = AF_INET6; -+ sin.sin6_port = htons(port); -+ sin.sin6_addr = in6addr_any; -+ -+ if (getenv("VNCVIEWER_LISTEN_LOCALHOST") || use_loopback) { -+ sin.sin6_addr = in6addr_loopback; -+ } -+ -+ if (bind(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { -+ perror("ListenAtTcpPort[ipv6]: bind"); -+ close(sock); -+ return -1; -+ } -+ -+ if (listen(sock, 32) < 0) { -+ perror("ListenAtTcpPort[ipv6]: listen"); -+ close(sock); -+ return -1; -+ } -+ -+#endif -+ if (port) {} -+ return sock; - } - - -@@ -320,33 +1012,69 @@ - * AcceptTcpConnection accepts a TCP connection. - */ - --int --AcceptTcpConnection(int listenSock) --{ -- int sock; -- struct sockaddr_in addr; -- int addrlen = sizeof(addr); -- int one = 1; -+int AcceptTcpConnection(int listenSock) { -+ int sock; -+ struct sockaddr_in addr; -+ int addrlen = sizeof(addr); -+ int one = 1; -+ -+ sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen); -+ if (sock < 0) { -+ perror("AcceptTcpConnection: accept"); -+ return -1; -+ } - -- sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen); -- if (sock < 0) { -- fprintf(stderr,programName); -- perror(": AcceptTcpConnection: accept"); -- return -1; -- } -+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) { -+ perror("AcceptTcpConnection: setsockopt"); -+ close(sock); -+ return -1; -+ } - -- if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, -- (char *)&one, sizeof(one)) < 0) { -- fprintf(stderr,programName); -- perror(": AcceptTcpConnection: setsockopt"); -- close(sock); -- return -1; -- } -+ return sock; -+} -+ -+char *accept6_ipaddr = NULL; -+char *accept6_hostname = NULL; -+ -+int AcceptTcpConnection6(int listenSock) { -+ int sock = -1; -+#ifdef AF_INET6 -+ struct sockaddr_in6 addr; -+ socklen_t addrlen = sizeof(addr); -+ int one = 1; -+ char *name; -+ -+ if (appData.noipv6) { -+ return -1; -+ } -+ -+ sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen); -+ if (sock < 0) { -+ perror("AcceptTcpConnection[ipv6]: accept"); -+ return -1; -+ } -+ -+ if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&one, sizeof(one)) < 0) { -+ perror("AcceptTcpConnection[ipv6]: setsockopt"); -+ close(sock); -+ return -1; -+ } - -- return sock; -+ name = ipv6_getipaddr((struct sockaddr *) &addr, addrlen); -+ if (!name) name = strdup("unknown"); -+ accept6_ipaddr = name; -+ fprintf(stderr, "AcceptTcpConnection6: ipv6 connection from: '%s'\n", name); -+ -+ name = ipv6_getnameinfo((struct sockaddr *) &addr, addrlen); -+ if (!name) name = strdup("unknown"); -+ accept6_hostname = name; -+#endif -+ if (listenSock) {} -+ return sock; - } - - -+ - /* - * SetNonBlocking sets a socket into non-blocking mode. - */ -@@ -379,7 +1107,7 @@ - - *addr = inet_addr(str); - -- if (*addr != -1) -+ if (*addr != (unsigned int) -1) - return True; - - hp = gethostbyname(str); -@@ -392,6 +1120,42 @@ - return False; - } - -+char *get_peer_ip(int sock) { -+ struct sockaddr_in saddr; -+ unsigned int saddr_len; -+ int saddr_port; -+ char *saddr_ip_str = NULL; -+ -+ saddr_len = sizeof(saddr); -+ memset(&saddr, 0, sizeof(saddr)); -+ saddr_port = -1; -+ if (!getpeername(sock, (struct sockaddr *)&saddr, &saddr_len)) { -+ saddr_ip_str = inet_ntoa(saddr.sin_addr); -+ } -+ if (! saddr_ip_str) { -+ saddr_ip_str = "unknown"; -+ } -+ return strdup(saddr_ip_str); -+} -+ -+char *ip2host(char *ip) { -+ char *str; -+ struct hostent *hp; -+ in_addr_t iaddr; -+ -+ iaddr = inet_addr(ip); -+ if (iaddr == htonl(INADDR_NONE)) { -+ return strdup("unknown"); -+ } -+ -+ hp = gethostbyaddr((char *)&iaddr, sizeof(in_addr_t), AF_INET); -+ if (!hp) { -+ return strdup("unknown"); -+ } -+ str = strdup(hp->h_name); -+ return str; -+} -+ - - /* - * Test if the other end of a socket is on the same machine. -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tight.c vnc_unixsrc/vncviewer/tight.c ---- vnc_unixsrc.orig/vncviewer/tight.c 2002-04-30 09:07:31.000000000 -0400 -+++ vnc_unixsrc/vncviewer/tight.c 2008-10-05 15:16:35.000000000 -0400 -@@ -129,14 +129,21 @@ - #endif - - #if (BPP == 8) -- gcv.foreground = (appData.useBGR233) ? -- BGR233ToPixel[fill_colour] : fill_colour; -+ gcv.foreground = (appData.useBGR233) ? BGR233ToPixel[fill_colour] : fill_colour; -+#else -+#if (BPP == 16) -+ gcv.foreground = (appData.useBGR565) ? BGR565ToPixel[fill_colour] : fill_colour; - #else - gcv.foreground = fill_colour; - #endif -+#endif - -- XChangeGC(dpy, gc, GCForeground, &gcv); -- XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh); -+ if (!appData.useXserverBackingStore) { -+ FillScreen(rx, ry, rw, rh, gcv.foreground); -+ } else { -+ XChangeGC(dpy, gc, GCForeground, &gcv); -+ XFillRectangle(dpy, desktopWin, gc, rx, ry, rw, rh); -+ } - return True; - } - -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tmake vnc_unixsrc/vncviewer/tmake ---- vnc_unixsrc.orig/vncviewer/tmake 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/tmake 2009-10-25 10:31:22.000000000 -0400 -@@ -0,0 +1,17 @@ -+#!/bin/sh -+TURBOVNC_DIR=/home/runge/turbojpeg -+make clean -+(cd ../libvncauth || exit 1; make) -+if [ "X$1" = "X-a" ]; then -+ exit -+fi -+make CCOPTIONS=-DTURBOVNC EXTRA_LIBRARIES="-L$TURBOVNC_DIR -Xlinker --rpath=$TURBOVNC_DIR -Xlinker --rpath=/usr/local/lib -lturbojpeg" -+cp -p vncviewer vncviewer.turbovnc -+strip vncviewer.turbovnc -+ls -l vncviewer.turbovnc -+ldd vncviewer.turbovnc -+ -+echo -+make clean all -+ls -l vncviewer -+ldd vncviewer -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/tunnel.c vnc_unixsrc/vncviewer/tunnel.c ---- vnc_unixsrc.orig/vncviewer/tunnel.c 2003-07-31 04:03:49.000000000 -0400 -+++ vnc_unixsrc/vncviewer/tunnel.c 2010-02-25 23:39:24.000000000 -0500 -@@ -100,7 +100,6 @@ - int *pargc, char **argv, int tunnelArgIndex) - { - char *pdisplay; -- int port; - - if (tunnelArgIndex >= *pargc - 1) - usage(); -@@ -132,6 +131,7 @@ - { - char *colonPos; - int len, portOffset; -+ int disp; - - if (tunnelArgIndex >= *pargc - 2) - usage(); -@@ -150,10 +150,17 @@ - len--; - portOffset = 0; - } -- if (!len || strspn(colonPos, "-0123456789") != len) { -+ if (!len || (int) strspn(colonPos, "-0123456789") != len) { - usage(); - } -+#if 0 - *remotePort = atoi(colonPos) + portOffset; -+#else -+ disp = atoi(colonPos); -+ if (portOffset != 0 && disp >= 100) -+ portOffset = 0; -+ *remotePort = disp + portOffset; -+#endif - } - - sprintf(lastArgv, "localhost::%d", localPort); -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/turbovnc/tight.c vnc_unixsrc/vncviewer/turbovnc/tight.c ---- vnc_unixsrc.orig/vncviewer/turbovnc/tight.c 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/turbovnc/tight.c 2008-08-20 13:35:58.000000000 -0400 -@@ -0,0 +1,613 @@ -+/* -+ * Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved. -+ * Copyright (C) 2004 Landmark Graphics Corporation. All Rights Reserved. -+ * Copyright (C) 2000, 2001 Const Kaplinsky. 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. -+ */ -+ -+/* -+ * tight.c - handle ``tight'' encoding. -+ * -+ * This file shouldn't be compiled directly. It is included multiple -+ * times by rfbproto.c, each time with a different definition of the -+ * macro BPP. For each value of BPP, this file defines a function -+ * which handles a tight-encoded rectangle with BPP bits per pixel. -+ * -+ */ -+ -+#define TIGHT_MIN_TO_COMPRESS 12 -+ -+#define CARDBPP CONCAT2E(CARD,BPP) -+#define filterPtrBPP CONCAT2E(filterPtr,BPP) -+ -+#define HandleTightBPP CONCAT2E(HandleTight,BPP) -+#define InitFilterCopyBPP CONCAT2E(InitFilterCopy,BPP) -+#define InitFilterPaletteBPP CONCAT2E(InitFilterPalette,BPP) -+#define InitFilterGradientBPP CONCAT2E(InitFilterGradient,BPP) -+#define FilterCopyBPP CONCAT2E(FilterCopy,BPP) -+#define FilterPaletteBPP CONCAT2E(FilterPalette,BPP) -+#define FilterGradientBPP CONCAT2E(FilterGradient,BPP) -+ -+#if BPP != 8 -+#define DecompressJpegRectBPP CONCAT2E(DecompressJpegRect,BPP) -+#endif -+ -+#ifndef RGB_TO_PIXEL -+ -+#define RGB_TO_PIXEL(bpp,r,g,b) \ -+ (((CARD##bpp)(r) & myFormat.redMax) << myFormat.redShift | \ -+ ((CARD##bpp)(g) & myFormat.greenMax) << myFormat.greenShift | \ -+ ((CARD##bpp)(b) & myFormat.blueMax) << myFormat.blueShift) -+ -+#define RGB24_TO_PIXEL(bpp,r,g,b) \ -+ ((((CARD##bpp)(r) & 0xFF) * myFormat.redMax + 127) / 255 \ -+ << myFormat.redShift | \ -+ (((CARD##bpp)(g) & 0xFF) * myFormat.greenMax + 127) / 255 \ -+ << myFormat.greenShift | \ -+ (((CARD##bpp)(b) & 0xFF) * myFormat.blueMax + 127) / 255 \ -+ << myFormat.blueShift) -+ -+#define RGB24_TO_PIXEL32(r,g,b) \ -+ (((CARD32)(r) & 0xFF) << myFormat.redShift | \ -+ ((CARD32)(g) & 0xFF) << myFormat.greenShift | \ -+ ((CARD32)(b) & 0xFF) << myFormat.blueShift) -+ -+#endif -+ -+extern XImage *image; -+ -+/* Type declarations */ -+ -+typedef void (*filterPtrBPP)(int, int, int); -+ -+/* Prototypes */ -+ -+static int InitFilterCopyBPP (int rw, int rh); -+static int InitFilterPaletteBPP (int rw, int rh); -+static int InitFilterGradientBPP (int rw, int rh); -+static void FilterCopyBPP (int srcx, int srcy, int numRows); -+static void FilterPaletteBPP (int srcx, int srcy, int numRows); -+static void FilterGradientBPP (int srcx, int srcy, int numRows); -+ -+static Bool DecompressJpegRectBPP(int x, int y, int w, int h); -+ -+/* Definitions */ -+ -+static Bool -+HandleTightBPP (int rx, int ry, int rw, int rh) -+{ -+ CARDBPP fill_colour; -+ XGCValues gcv; -+ CARD8 comp_ctl; -+ CARD8 filter_id; -+ filterPtrBPP filterFn; -+ z_streamp zs; -+ int err, stream_id, compressedLen, bitsPixel; -+ int bufferSize, rowSize, numRows; -+ Bool readUncompressed = False; -+ CARDBPP *rawData; -+ -+ if (!ReadFromRFBServer((char *)&comp_ctl, 1)) -+ return False; -+ -+ /* Flush zlib streams if we are told by the server to do so. */ -+ for (stream_id = 0; stream_id < 4; stream_id++) { -+ if ((comp_ctl & 1) && zlibStreamActive[stream_id]) { -+ if (inflateEnd (&zlibStream[stream_id]) != Z_OK && -+ zlibStream[stream_id].msg != NULL) -+ fprintf(stderr, "inflateEnd: %s\n", zlibStream[stream_id].msg); -+ zlibStreamActive[stream_id] = False; -+ } -+ comp_ctl >>= 1; -+ } -+ -+ if ((comp_ctl & rfbTightNoZlib) == rfbTightNoZlib) { -+ comp_ctl &= ~(rfbTightNoZlib); -+ readUncompressed = True; -+ } -+ -+ /* Handle solid rectangles. */ -+ if (comp_ctl == rfbTightFill) { -+#if BPP == 32 -+ if (myFormat.depth == 24 && myFormat.redMax == 0xFF && -+ myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) { -+ if (!ReadFromRFBServer(buffer, 3)) -+ return False; -+ fill_colour = RGB24_TO_PIXEL32(buffer[0], buffer[1], buffer[2]); -+ } else { -+ if (!ReadFromRFBServer((char*)&fill_colour, sizeof(fill_colour))) -+ return False; -+ } -+#else -+ if (!ReadFromRFBServer((char*)&fill_colour, sizeof(fill_colour))) -+ return False; -+#endif -+ -+#if (BPP == 8) -+ gcv.foreground = (appData.useBGR233) ? -+ BGR233ToPixel[fill_colour] : fill_colour; -+#else -+ gcv.foreground = fill_colour; -+#endif -+ -+ FillRectangle(&gcv, rx, ry, rw, rh); -+ return True; -+ } -+ -+#if BPP == 8 -+ if (comp_ctl == rfbTightJpeg) { -+ fprintf(stderr, "Tight encoding: JPEG is not supported in 8 bpp mode.\n"); -+ return False; -+ } -+#else -+ if (comp_ctl == rfbTightJpeg) { -+ return DecompressJpegRectBPP(rx, ry, rw, rh); -+ } -+#endif -+ -+ /* Quit on unsupported subencoding value. */ -+ if (comp_ctl > rfbTightMaxSubencoding) { -+ fprintf(stderr, "Tight encoding: bad subencoding value received.\n"); -+ return False; -+ } -+ -+ /* -+ * Here primary compression mode handling begins. -+ * Data was processed with optional filter + zlib compression. -+ */ -+ -+ /* First, we should identify a filter to use. */ -+ if ((comp_ctl & rfbTightExplicitFilter) != 0) { -+ if (!ReadFromRFBServer((char*)&filter_id, 1)) -+ return False; -+ -+ switch (filter_id) { -+ case rfbTightFilterCopy: -+ filterFn = FilterCopyBPP; -+ bitsPixel = InitFilterCopyBPP(rw, rh); -+ break; -+ case rfbTightFilterPalette: -+ filterFn = FilterPaletteBPP; -+ bitsPixel = InitFilterPaletteBPP(rw, rh); -+ break; -+ case rfbTightFilterGradient: -+ filterFn = FilterGradientBPP; -+ bitsPixel = InitFilterGradientBPP(rw, rh); -+ break; -+ default: -+ fprintf(stderr, "Tight encoding: unknown filter code received.\n"); -+ return False; -+ } -+ } else { -+ filterFn = FilterCopyBPP; -+ bitsPixel = InitFilterCopyBPP(rw, rh); -+ } -+ if (bitsPixel == 0) { -+ fprintf(stderr, "Tight encoding: error receiving palette.\n"); -+ return False; -+ } -+ -+ /* Determine if the data should be decompressed or just copied. */ -+ rowSize = (rw * bitsPixel + 7) / 8; -+ bufferSize = -1; -+ if (rh * rowSize < TIGHT_MIN_TO_COMPRESS) -+ bufferSize = rh * rowSize; -+ else if (readUncompressed) { -+ bufferSize = (int)ReadCompactLen(); -+ } -+ if (bufferSize != -1) { -+ uncompressedData = (char *)realloc(uncompressedData, bufferSize); -+ if (!uncompressedData) { -+ fprintf(stderr, "Memory allocation error\n"); -+ return False; -+ } -+ if (!ReadFromRFBServer(uncompressedData, bufferSize)) -+ return False; -+ filterFn(rx, ry, rh); -+ if (appData.useBGR233) CopyDataToImage(buffer, rx, ry, rw, rh); -+ if (!appData.doubleBuffer) CopyImageToScreen(rx, ry, rw, rh); -+ -+ return True; -+ } -+ -+ /* Read the length (1..3 bytes) of compressed data following. */ -+ compressedLen = (int)ReadCompactLen(); -+ if (compressedLen <= 0) { -+ fprintf(stderr, "Incorrect data received from the server.\n"); -+ return False; -+ } -+ -+ /* Now let's initialize compression stream if needed. */ -+ stream_id = comp_ctl & 0x03; -+ zs = &zlibStream[stream_id]; -+ if (!zlibStreamActive[stream_id]) { -+ zs->zalloc = Z_NULL; -+ zs->zfree = Z_NULL; -+ zs->opaque = Z_NULL; -+ err = inflateInit(zs); -+ if (err != Z_OK) { -+ if (zs->msg != NULL) -+ fprintf(stderr, "InflateInit error: %s.\n", zs->msg); -+ return False; -+ } -+ zlibStreamActive[stream_id] = True; -+ } -+ -+ /* Read, decode and draw actual pixel data in a loop. */ -+ -+ compressedData = (char *)realloc(compressedData, compressedLen); -+ if (!compressedData) { -+ fprintf(stderr, "Memory allocation error\n"); -+ return False; -+ } -+ uncompressedData = (char *)realloc(uncompressedData, rh * rowSize); -+ if (!uncompressedData) { -+ fprintf(stderr, "Memory allocation error\n"); -+ return False; -+ } -+ -+ if (!ReadFromRFBServer(compressedData, compressedLen)) -+ return False; -+ zs->next_in = (Bytef *)compressedData; -+ zs->avail_in = compressedLen; -+ zs->next_out = (Bytef *)uncompressedData; -+ zs->avail_out = rh * rowSize; -+ -+ err = inflate(zs, Z_SYNC_FLUSH); -+ if (err != Z_OK && err != Z_STREAM_END) { -+ if (zs->msg != NULL) { -+ fprintf(stderr, "Inflate error: %s.\n", zs->msg); -+ } else { -+ fprintf(stderr, "Inflate error: %d.\n", err); -+ } -+ return False; -+ } -+ -+ filterFn(rx, ry, rh); -+ if (appData.useBGR233) CopyDataToImage(buffer, rx, ry, rw, rh); -+ if (!appData.doubleBuffer) CopyImageToScreen(rx, ry, rw, rh); -+ -+ return True; -+} -+ -+/*---------------------------------------------------------------------------- -+ * -+ * Filter stuff. -+ * -+ */ -+ -+/* -+ The following variables are defined in rfbproto.c: -+ static Bool cutZeros; -+ static int rectWidth, rectColors; -+ static CARD8 tightPalette[256*4]; -+ static CARD8 tightPrevRow[2048*3*sizeof(CARD16)]; -+*/ -+ -+static int -+InitFilterCopyBPP (int rw, int rh) -+{ -+ rectWidth = rw; -+ -+#if BPP == 32 -+ if (myFormat.depth == 24 && myFormat.redMax == 0xFF && -+ myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) { -+ cutZeros = True; -+ return 24; -+ } else { -+ cutZeros = False; -+ } -+#endif -+ -+ return BPP; -+} -+ -+static void -+FilterCopyBPP (int srcx, int srcy, int numRows) -+{ -+ CARDBPP *dst = (CARDBPP *)&image->data[srcy * image->bytes_per_line -+ + srcx * image->bits_per_pixel/8]; -+ int dstw = image->bytes_per_line / (image->bits_per_pixel / 8); -+ int y; -+#if BPP == 32 -+ int x; -+#endif -+ -+ if (appData.useBGR233) { -+ dst = (CARDBPP *)buffer; -+ dstw = rectWidth; -+ } -+ -+#if BPP == 32 -+ if (cutZeros) { -+ for (y = 0; y < numRows; y++) { -+ for (x = 0; x < rectWidth; x++) { -+ dst[y*dstw+x] = -+ RGB24_TO_PIXEL32(uncompressedData[(y*rectWidth+x)*3], -+ uncompressedData[(y*rectWidth+x)*3+1], -+ uncompressedData[(y*rectWidth+x)*3+2]); -+ } -+ } -+ return; -+ } -+#endif -+ -+ for (y = 0; y < numRows; y++) -+ memcpy (&dst[y*dstw], &uncompressedData[y*rectWidth], rectWidth * (BPP / 8)); -+} -+ -+static int -+InitFilterGradientBPP (int rw, int rh) -+{ -+ int bits; -+ -+ bits = InitFilterCopyBPP(rw, rh); -+ if (cutZeros) -+ memset(tightPrevRow, 0, rw * 3); -+ else -+ memset(tightPrevRow, 0, rw * 3 * sizeof(CARD16)); -+ -+ return bits; -+} -+ -+#if BPP == 32 -+ -+static void -+FilterGradient24 (int srcx, int srcy, int numRows) -+{ -+ CARDBPP *dst = (CARDBPP *)&image->data[srcy * image->bytes_per_line -+ + srcx * image->bits_per_pixel/8]; -+ int dstw = image->bytes_per_line / (image->bits_per_pixel / 8); -+ int x, y, c; -+ CARD8 thisRow[2048*3]; -+ CARD8 pix[3]; -+ int est[3]; -+ -+ if (appData.useBGR233) { -+ dst = (CARDBPP *)buffer; -+ dstw = rectWidth; -+ } -+ -+ for (y = 0; y < numRows; y++) { -+ -+ /* First pixel in a row */ -+ for (c = 0; c < 3; c++) { -+ pix[c] = tightPrevRow[c] + uncompressedData[y*rectWidth*3+c]; -+ thisRow[c] = pix[c]; -+ } -+ dst[y*dstw] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); -+ -+ /* Remaining pixels of a row */ -+ for (x = 1; x < rectWidth; x++) { -+ for (c = 0; c < 3; c++) { -+ est[c] = (int)tightPrevRow[x*3+c] + (int)pix[c] - -+ (int)tightPrevRow[(x-1)*3+c]; -+ if (est[c] > 0xFF) { -+ est[c] = 0xFF; -+ } else if (est[c] < 0x00) { -+ est[c] = 0x00; -+ } -+ pix[c] = (CARD8)est[c] + buffer[(y*rectWidth+x)*3+c]; -+ thisRow[x*3+c] = pix[c]; -+ } -+ dst[y*dstw+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); -+ } -+ -+ memcpy(tightPrevRow, thisRow, rectWidth * 3); -+ } -+} -+ -+#endif -+ -+static void -+FilterGradientBPP (int srcx, int srcy, int numRows) -+{ -+ int x, y, c; -+ CARDBPP *dst = (CARDBPP *)&image->data[srcy * image->bytes_per_line -+ + srcx * image->bits_per_pixel/8]; -+ int dstw = image->bytes_per_line / (image->bits_per_pixel / 8); -+ CARDBPP *src = (CARDBPP *)uncompressedData; -+ CARD16 *thatRow = (CARD16 *)tightPrevRow; -+ CARD16 thisRow[2048*3]; -+ CARD16 pix[3]; -+ CARD16 max[3]; -+ int shift[3]; -+ int est[3]; -+ -+ if (appData.useBGR233) { -+ dst = (CARDBPP *)buffer; -+ dstw = rectWidth; -+ } -+ -+#if BPP == 32 -+ if (cutZeros) { -+ FilterGradient24(srcx, srcy, numRows); -+ return; -+ } -+#endif -+ -+ max[0] = myFormat.redMax; -+ max[1] = myFormat.greenMax; -+ max[2] = myFormat.blueMax; -+ -+ shift[0] = myFormat.redShift; -+ shift[1] = myFormat.greenShift; -+ shift[2] = myFormat.blueShift; -+ -+ for (y = 0; y < numRows; y++) { -+ -+ /* First pixel in a row */ -+ for (c = 0; c < 3; c++) { -+ pix[c] = (CARD16)((src[y*rectWidth] >> shift[c]) + thatRow[c] & max[c]); -+ thisRow[c] = pix[c]; -+ } -+ dst[y*dstw] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); -+ -+ /* Remaining pixels of a row */ -+ for (x = 1; x < rectWidth; x++) { -+ for (c = 0; c < 3; c++) { -+ est[c] = (int)thatRow[x*3+c] + (int)pix[c] - (int)thatRow[(x-1)*3+c]; -+ if (est[c] > (int)max[c]) { -+ est[c] = (int)max[c]; -+ } else if (est[c] < 0) { -+ est[c] = 0; -+ } -+ pix[c] = (CARD16)((src[y*rectWidth+x] >> shift[c]) + est[c] & max[c]); -+ thisRow[x*3+c] = pix[c]; -+ } -+ dst[y*dstw+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); -+ } -+ memcpy(thatRow, thisRow, rectWidth * 3 * sizeof(CARD16)); -+ } -+} -+ -+static int -+InitFilterPaletteBPP (int rw, int rh) -+{ -+ int i; -+ CARD8 numColors; -+ CARDBPP *palette = (CARDBPP *)tightPalette; -+ -+ rectWidth = rw; -+ -+ if (!ReadFromRFBServer((char*)&numColors, 1)) -+ return 0; -+ -+ rectColors = (int)numColors; -+ if (++rectColors < 2) -+ return 0; -+ -+#if BPP == 32 -+ if (myFormat.depth == 24 && myFormat.redMax == 0xFF && -+ myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) { -+ if (!ReadFromRFBServer((char*)&tightPalette, rectColors * 3)) -+ return 0; -+ for (i = rectColors - 1; i >= 0; i--) { -+ palette[i] = RGB24_TO_PIXEL32(tightPalette[i*3], -+ tightPalette[i*3+1], -+ tightPalette[i*3+2]); -+ } -+ return (rectColors == 2) ? 1 : 8; -+ } -+#endif -+ -+ if (!ReadFromRFBServer((char*)&tightPalette, rectColors * (BPP / 8))) -+ return 0; -+ -+ return (rectColors == 2) ? 1 : 8; -+} -+ -+static void -+FilterPaletteBPP (int srcx, int srcy, int numRows) -+{ -+ int x, y, b, w; -+ CARDBPP *dst = (CARDBPP *)&image->data[srcy * image->bytes_per_line -+ + srcx * image->bits_per_pixel/8]; -+ int dstw = image->bytes_per_line / (image->bits_per_pixel / 8); -+ CARD8 *src = (CARD8 *)uncompressedData; -+ CARDBPP *palette = (CARDBPP *)tightPalette; -+ -+ if (appData.useBGR233) { -+ dst = (CARDBPP *)buffer; -+ dstw = rectWidth; -+ } -+ -+ if (rectColors == 2) { -+ w = (rectWidth + 7) / 8; -+ for (y = 0; y < numRows; y++) { -+ for (x = 0; x < rectWidth / 8; x++) { -+ for (b = 7; b >= 0; b--) -+ dst[y*dstw+x*8+7-b] = palette[src[y*w+x] >> b & 1]; -+ } -+ for (b = 7; b >= 8 - rectWidth % 8; b--) { -+ dst[y*dstw+x*8+7-b] = palette[src[y*w+x] >> b & 1]; -+ } -+ } -+ } else { -+ for (y = 0; y < numRows; y++) -+ for (x = 0; x < rectWidth; x++) -+ dst[y*dstw+x] = palette[(int)src[y*rectWidth+x]]; -+ } -+} -+ -+#if BPP != 8 -+ -+/*---------------------------------------------------------------------------- -+ * -+ * JPEG decompression. -+ * -+ */ -+ -+/* -+ The following variables are defined in rfbproto.c: -+ static Bool jpegError; -+ static struct jpeg_source_mgr jpegSrcManager; -+ static JOCTET *jpegBufferPtr; -+ static size_t *jpegBufferLen; -+*/ -+ -+static Bool -+DecompressJpegRectBPP(int x, int y, int w, int h) -+{ -+ int compressedLen; -+ char *dstptr; -+ int ps, flags=0; -+ -+ compressedLen = (int)ReadCompactLen(); -+ if (compressedLen <= 0) { -+ fprintf(stderr, "Incorrect data received from the server.\n"); -+ return False; -+ } -+ -+ compressedData = (char *)realloc(compressedData, compressedLen); -+ if (compressedData == NULL) { -+ fprintf(stderr, "Memory allocation error.\n"); -+ return False; -+ } -+ -+ if (!ReadFromRFBServer(compressedData, compressedLen)) { -+ return False; -+ } -+ -+ if(!tjhnd) { -+ if((tjhnd=tjInitDecompress())==NULL) { -+ fprintf(stderr, "TurboJPEG error: %s\n", tjGetErrorStr()); -+ return False; -+ } -+ } -+ -+ ps=image->bits_per_pixel/8; -+ if(myFormat.bigEndian && ps==4) flags|=TJ_ALPHAFIRST; -+ if(myFormat.redShift==16 && myFormat.blueShift==0) -+ flags|=TJ_BGR; -+ if(myFormat.bigEndian) flags^=TJ_BGR; -+ -+ dstptr=&image->data[image->bytes_per_line*y+x*ps]; -+ if(tjDecompress(tjhnd, (unsigned char *)compressedData, (unsigned long)compressedLen, -+ (unsigned char *)dstptr, w, image->bytes_per_line, h, ps, flags)==-1) { -+ fprintf(stderr, "TurboJPEG error: %s\n", tjGetErrorStr()); -+ return False; -+ } -+ -+ if (!appData.doubleBuffer) -+ CopyImageToScreen(x, y, w, h); -+ -+ return True; -+} -+ -+#endif -+ -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/turbovnc/turbojpeg.h vnc_unixsrc/vncviewer/turbovnc/turbojpeg.h ---- vnc_unixsrc.orig/vncviewer/turbovnc/turbojpeg.h 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/turbovnc/turbojpeg.h 2008-04-03 04:28:56.000000000 -0400 -@@ -0,0 +1,229 @@ -+/* Copyright (C)2004 Landmark Graphics -+ * Copyright (C)2005, 2006 Sun Microsystems, Inc. -+ * -+ * This library is free software and may be redistributed and/or modified under -+ * the terms of the wxWindows Library License, Version 3.1 or (at your option) -+ * any later version. The full license is in the LICENSE.txt file included -+ * with this distribution. -+ * -+ * This library 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 -+ * wxWindows Library License for more details. -+ */ -+ -+#if (defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)) && defined(_WIN32) && defined(DLLDEFINE) -+#define DLLEXPORT __declspec(dllexport) -+#else -+#define DLLEXPORT -+#endif -+ -+#define DLLCALL -+ -+/* Subsampling */ -+#define NUMSUBOPT 4 -+ -+enum {TJ_444=0, TJ_422, TJ_411, TJ_GRAYSCALE}; -+ -+/* Flags */ -+#define TJ_BGR 1 -+#define TJ_BOTTOMUP 2 -+#define TJ_FORCEMMX 8 /* Force IPP to use MMX code even if SSE available */ -+#define TJ_FORCESSE 16 /* Force IPP to use SSE1 code even if SSE2 available */ -+#define TJ_FORCESSE2 32 /* Force IPP to use SSE2 code (useful if auto-detect is not working properly) */ -+#define TJ_ALPHAFIRST 64 /* BGR buffer is ABGR and RGB buffer is ARGB */ -+#define TJ_FORCESSE3 128 /* Force IPP to use SSE3 code (useful if auto-detect is not working properly) */ -+ -+typedef void* tjhandle; -+ -+#define TJPAD(p) (((p)+3)&(~3)) -+#ifndef max -+ #define max(a,b) ((a)>(b)?(a):(b)) -+#endif -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+/* API follows */ -+ -+ -+/* -+ tjhandle tjInitCompress(void) -+ -+ Creates a new JPEG compressor instance, allocates memory for the structures, -+ and returns a handle to the instance. Most applications will only -+ need to call this once at the beginning of the program or once for each -+ concurrent thread. Don't try to create a new instance every time you -+ compress an image, because this will cause performance to suffer. -+ -+ RETURNS: NULL on error -+*/ -+DLLEXPORT tjhandle DLLCALL tjInitCompress(void); -+ -+ -+/* -+ int tjCompress(tjhandle j, -+ unsigned char *srcbuf, int width, int pitch, int height, int pixelsize, -+ unsigned char *dstbuf, unsigned long *size, -+ int jpegsubsamp, int jpegqual, int flags) -+ -+ [INPUT] j = instance handle previously returned from a call to -+ tjInitCompress() -+ [INPUT] srcbuf = pointer to user-allocated image buffer containing pixels in -+ RGB(A) or BGR(A) form -+ [INPUT] width = width (in pixels) of the source image -+ [INPUT] pitch = bytes per line of the source image (width*pixelsize if the -+ bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap -+ is padded to the nearest 32-bit boundary, such as is the case for Windows -+ bitmaps. You can also be clever and use this parameter to skip lines, etc., -+ as long as the pitch is greater than 0.) -+ [INPUT] height = height (in pixels) of the source image -+ [INPUT] pixelsize = size (in bytes) of each pixel in the source image -+ RGBA and BGRA: 4, RGB and BGR: 3 -+ [INPUT] dstbuf = pointer to user-allocated image buffer which will receive -+ the JPEG image. Use the macro TJBUFSIZE(width, height) to determine -+ the appropriate size for this buffer based on the image width and height. -+ [OUTPUT] size = pointer to unsigned long which receives the size (in bytes) -+ of the compressed image -+ [INPUT] jpegsubsamp = Specifies either 4:1:1, 4:2:2, or 4:4:4 subsampling. -+ When the image is converted from the RGB to YCbCr colorspace as part of the -+ JPEG compression process, every other Cb and Cr (chrominance) pixel can be -+ discarded to produce a smaller image with little perceptible loss of -+ image clarity (the human eye is more sensitive to small changes in -+ brightness than small changes in color.) -+ -+ TJ_411: 4:1:1 subsampling. Discards every other Cb, Cr pixel in both -+ horizontal and vertical directions. -+ TJ_422: 4:2:2 subsampling. Discards every other Cb, Cr pixel only in -+ the horizontal direction. -+ TJ_444: no subsampling. -+ TJ_GRAYSCALE: Generate grayscale JPEG image -+ -+ [INPUT] jpegqual = JPEG quality (an integer between 0 and 100 inclusive.) -+ [INPUT] flags = the bitwise OR of one or more of the following -+ -+ TJ_BGR: The components of each pixel in the source image are stored in -+ B,G,R order, not R,G,B -+ TJ_BOTTOMUP: The source image is stored in bottom-up (Windows) order, -+ not top-down -+ TJ_FORCEMMX: Valid only for the Intel Performance Primitives implementation -+ of this codec-- force IPP to use MMX code (bypass CPU auto-detection) -+ TJ_FORCESSE: Valid only for the Intel Performance Primitives implementation -+ of this codec-- force IPP to use SSE code (bypass CPU auto-detection) -+ TJ_FORCESSE2: Valid only for the Intel Performance Primitives implementation -+ of this codec-- force IPP to use SSE2 code (bypass CPU auto-detection) -+ TJ_FORCESSE3: Valid only for the Intel Performance Primitives implementation -+ of this codec-- force IPP to use SSE3 code (bypass CPU auto-detection) -+ -+ RETURNS: 0 on success, -1 on error -+*/ -+DLLEXPORT int DLLCALL tjCompress(tjhandle j, -+ unsigned char *srcbuf, int width, int pitch, int height, int pixelsize, -+ unsigned char *dstbuf, unsigned long *size, -+ int jpegsubsamp, int jpegqual, int flags); -+ -+DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height); -+ -+/* -+ tjhandle tjInitDecompress(void) -+ -+ Creates a new JPEG decompressor instance, allocates memory for the -+ structures, and returns a handle to the instance. Most applications will -+ only need to call this once at the beginning of the program or once for each -+ concurrent thread. Don't try to create a new instance every time you -+ decompress an image, because this will cause performance to suffer. -+ -+ RETURNS: NULL on error -+*/ -+DLLEXPORT tjhandle DLLCALL tjInitDecompress(void); -+ -+ -+/* -+ int tjDecompressHeader(tjhandle j, -+ unsigned char *srcbuf, unsigned long size, -+ int *width, int *height) -+ -+ [INPUT] j = instance handle previously returned from a call to -+ tjInitDecompress() -+ [INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image -+ to decompress -+ [INPUT] size = size of the JPEG image buffer (in bytes) -+ [OUTPUT] width = width (in pixels) of the JPEG image -+ [OUTPUT] height = height (in pixels) of the JPEG image -+ -+ RETURNS: 0 on success, -1 on error -+*/ -+DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle j, -+ unsigned char *srcbuf, unsigned long size, -+ int *width, int *height); -+ -+ -+/* -+ int tjDecompress(tjhandle j, -+ unsigned char *srcbuf, unsigned long size, -+ unsigned char *dstbuf, int width, int pitch, int height, int pixelsize, -+ int flags) -+ -+ [INPUT] j = instance handle previously returned from a call to -+ tjInitDecompress() -+ [INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image -+ to decompress -+ [INPUT] size = size of the JPEG image buffer (in bytes) -+ [INPUT] dstbuf = pointer to user-allocated image buffer which will receive -+ the bitmap image. This buffer should normally be pitch*height -+ bytes in size, although this pointer may also be used to decompress into -+ a specific region of a larger buffer. -+ [INPUT] width = width (in pixels) of the destination image -+ [INPUT] pitch = bytes per line of the destination image (width*pixelsize if the -+ bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap -+ is padded to the nearest 32-bit boundary, such as is the case for Windows -+ bitmaps. You can also be clever and use this parameter to skip lines, etc., -+ as long as the pitch is greater than 0.) -+ [INPUT] height = height (in pixels) of the destination image -+ [INPUT] pixelsize = size (in bytes) of each pixel in the destination image -+ RGBA/RGBx and BGRA/BGRx: 4, RGB and BGR: 3 -+ [INPUT] flags = the bitwise OR of one or more of the following -+ -+ TJ_BGR: The components of each pixel in the destination image should be -+ written in B,G,R order, not R,G,B -+ TJ_BOTTOMUP: The destination image should be stored in bottom-up -+ (Windows) order, not top-down -+ TJ_FORCEMMX: Valid only for the Intel Performance Primitives implementation -+ of this codec-- force IPP to use MMX code (bypass CPU auto-detection) -+ TJ_FORCESSE: Valid only for the Intel Performance Primitives implementation -+ of this codec-- force IPP to use SSE code (bypass CPU auto-detection) -+ TJ_FORCESSE2: Valid only for the Intel Performance Primitives implementation -+ of this codec-- force IPP to use SSE2 code (bypass CPU auto-detection) -+ -+ RETURNS: 0 on success, -1 on error -+*/ -+DLLEXPORT int DLLCALL tjDecompress(tjhandle j, -+ unsigned char *srcbuf, unsigned long size, -+ unsigned char *dstbuf, int width, int pitch, int height, int pixelsize, -+ int flags); -+ -+ -+/* -+ int tjDestroy(tjhandle h) -+ -+ Frees structures associated with a compression or decompression instance -+ -+ [INPUT] h = instance handle (returned from a previous call to -+ tjInitCompress() or tjInitDecompress() -+ -+ RETURNS: 0 on success, -1 on error -+*/ -+DLLEXPORT int DLLCALL tjDestroy(tjhandle h); -+ -+ -+/* -+ char *tjGetErrorStr(void) -+ -+ Returns a descriptive error message explaining why the last command failed -+*/ -+DLLEXPORT char* DLLCALL tjGetErrorStr(void); -+ -+#ifdef __cplusplus -+} -+#endif -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer._man vnc_unixsrc/vncviewer/vncviewer._man ---- vnc_unixsrc.orig/vncviewer/vncviewer._man 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer._man 2010-04-11 23:30:24.000000000 -0400 -@@ -0,0 +1,829 @@ -+'\" t -+.\" ** The above line should force tbl to be a preprocessor ** -+.\" Man page for X vncviewer -+.\" -+.\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de -+.\" Copyright (C) 2000,2001 Red Hat, Inc. -+.\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru> -+.\" Copyright (C) 2006-2010 Karl J. Runge <runge@karlrunge.com> -+.\" -+.\" You may distribute under the terms of the GNU General Public -+.\" License as specified in the file LICENCE.TXT that comes with the -+.\" TightVNC distribution. -+.\" -+.TH ssvncviewer 1 "April 2010" "" "SSVNC" -+.SH NAME -+ssvncviewer \- an X viewer client for VNC -+.SH SYNOPSIS -+.B ssvncviewer -+.RI [\| options \|] -+.RI [\| host \|][\| :display \|] -+.br -+.B ssvncviewer -+.RI [\| options \|] -+.RI [\| host \|][\| ::port \|] -+.br -+.B ssvncviewer -+.RI [\| options \|] -+.RI exec=[\| cmd+args... \|] -+.br -+.B ssvncviewer -+.RI [\| options \|] -+.RI fd=n -+.br -+.B ssvncviewer -+.RI [\| options \|] -+.RI /path/to/unix/socket -+.br -+.B ssvncviewer -+.RI [\| options \|] -+.IR \-listen -+.RI [\| display \|] -+.br -+.B ssvncviewer -+.IR \-help -+.br -+.SH DESCRIPTION -+.B ssvncviewer -+is an Xt\-based client application for the VNC (Virtual Network -+Computing) system. It can connect to any VNC\-compatible server such -+as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment -+of a different machine. -+ -+ssvncviewer is an enhanced version of the tightvnc unix viewer that can -+take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers. -+See below for the description of these features. -+ -+You can use F8 to display a pop\-up utility menu. Press F8 twice to -+pass single F8 to the remote side. -+.SH OPTIONS -+.TP -+\fB\-help\fR -+Prints a short usage notice to stderr. -+.TP -+\fB\-listen\fR -+Make the viewer listen on port 5500+\fIdisplay\fR for reverse -+connections from a server. WinVNC supports reverse connections using -+the "Add New Client" menu option, or the \-connect command line -+option. \fBXvnc\fR requires the use of the helper program -+\fBvncconnect\fR. -+.TP -+\fB\-via\fR \fIgateway\fR -+Automatically create encrypted TCP tunnel to the \fIgateway\fR machine -+before connection, connect to the \fIhost\fR through that tunnel -+(TightVNC\-specific). By default, this option invokes SSH local port -+forwarding, assuming that SSH client binary can be accessed as -+/usr/bin/ssh. Note that when using the \fB\-via\fR option, the host -+machine name should be specified as known to the gateway machine, e.g. -+"localhost" denotes the \fIgateway\fR, not the machine where vncviewer -+was launched. See the ENVIRONMENT section below for the information on -+configuring the \fB\-via\fR option. -+.TP -+\fB\-shared\fR -+When connecting, specify that a shared connection is requested. In -+TightVNC, this is the default mode, allowing you to share the desktop -+with other clients already using it. -+.TP -+\fB\-noshared\fR -+When connecting, specify that the session may not be shared. This -+would either disconnect other connected clients or refuse your -+connection, depending on the server configuration. -+.TP -+\fB\-viewonly\fR -+Disable transfer of mouse and keyboard events from the client to the -+server. -+.TP -+\fB\-fullscreen\fR -+Start in full\-screen mode. Please be aware that operating in -+full\-screen mode may confuse X window managers. Typically, such -+conflicts cause incorrect handling of input focus or make the viewer -+window disappear mysteriously. See the grabKeyboard setting in the -+RESOURCES section below for a method to solve input focus problem. -+.TP -+\fB\-noraiseonbeep\fR -+By default, the viewer shows and raises its window on remote beep -+(bell) event. This option disables such behaviour -+(TightVNC\-specific). -+.TP -+\fB\-user\fR \fIusername\fR -+User name for Unix login authentication. Default is to use current -+Unix user name. If this option was given, the viewer will prefer Unix -+login authentication over the standard VNC authentication. -+.TP -+\fB\-passwd\fR \fIpasswd\-file\fR -+File from which to get the password (as generated by the -+\fBvncpasswd\fR(1) program). This option affects only the standard VNC -+authentication. -+.TP -+\fB\-encodings\fR \fIencoding\-list\fR -+TightVNC supports several different compression methods to encode -+screen updates; this option specifies a set of them to use in order of -+preference. Encodings are specified separated with spaces, and must -+thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces. -+Available encodings, in default order for a remote connection, are -+"copyrect tight hextile zlib corre rre raw". For a local connection -+(to the same machine), the default order to try is "raw copyrect tight -+hextile zlib corre rre". Raw encoding is always assumed as a last option -+if no other encoding can be used for some reason. For more information -+on encodings, see the section ENCODINGS below. -+.TP -+\fB\-bgr233\fR -+Always use the BGR233 format to encode pixel data. This reduces -+network traffic, but colors may be represented inaccurately. The -+bgr233 format is an 8\-bit "true color" format, with 2 bits blue, 3 -+bits green, and 3 bits red. -+.TP -+\fB\-owncmap\fR -+Try to use a PseudoColor visual and a private colormap. This allows -+the VNC server to control the colormap. -+.TP -+\fB\-truecolour\fR, \fB\-truecolor\fR -+Try to use a TrueColor visual. -+.TP -+\fB\-depth\fR \fIdepth\fR -+On an X server which supports multiple TrueColor visuals of different -+depths, attempt to use the specified one (in bits per pixel); if -+successful, this depth will be requested from the VNC server. -+.TP -+\fB\-compresslevel \fIlevel\fR -+Use specified compression \fIlevel\fR (0..9) for "tight" and "zlib" -+encodings (TightVNC\-specific). Level 1 uses minimum of CPU time and -+achieves weak compression ratios, while level 9 offers best -+compression but is slow in terms of CPU time consumption on the server -+side. Use high levels with very slow network connections, and low -+levels when working over high\-speed LANs. It's not recommended to use -+compression level 0, reasonable choices start from the level 1. -+.TP -+\fB\-quality \fIlevel\fR -+Use the specified JPEG quality \fIlevel\fR (0..9) for the "tight" -+encoding (TightVNC\-specific). Quality level 0 denotes bad image -+quality but very impressive compression ratios, while level 9 offers -+very good image quality at lower compression ratios. Note that the -+"tight" encoder uses JPEG to encode only those screen areas that look -+suitable for lossy compression, so quality level 0 does not always -+mean unacceptable image quality. -+.TP -+\fB\-nojpeg\fR -+Disable lossy JPEG compression in Tight encoding (TightVNC\-specific). -+Disabling JPEG compression is not a good idea in typical cases, as -+that makes the Tight encoder less efficient. You might want to use -+this option if it's absolutely necessary to achieve perfect image -+quality (see also the \fB\-quality\fR option). -+.TP -+\fB\-nocursorshape\fR -+Disable cursor shape updates, protocol extensions used to handle -+remote cursor movements locally on the client side -+(TightVNC\-specific). Using cursor shape updates decreases delays with -+remote cursor movements, and can improve bandwidth usage dramatically. -+.TP -+\fB\-x11cursor\fR -+Use a real X11 cursor with X-style cursor shape updates, instead of -+drawing the remote cursor on the framebuffer. This option also -+disables the dot cursor, and disables cursor position updates in -+non-fullscreen mode. -+.TP -+\fB\-autopass\fR -+Read a plain-text password from stdin. This option affects only the -+standard VNC authentication. -+ -+.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS -+.TP -+Enhanced TightVNC Viewer (SSVNC) web page is located at: -+.TP -+http://www.karlrunge.com/x11vnc/ssvnc.html -+.TP -+Note: ZRLE and ZYWRLE encodings are now supported. -+.TP -+Note: F9 is shortcut to Toggle FullScreen mode. -+.TP -+Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1 -+to allow more than one incoming VNC server at a time. -+This is the same as -multilisten described below. Set -+SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than "n" -+simultaneous reverse connections. -+ -+If the host:port is specified as "exec=command args..." -+then instead of making a TCP/IP socket connection to the -+remote VNC server, "command args..." is executed and the -+viewer is attached to its stdio. This enables tunnelling -+established via an external command, e.g. an stunnel(8) -+that does not involve a listening socket. -+This mode does not work for -listen reverse connections. -+ -+If the host:port is specified as "fd=n" then it is assumed -+n is an already opened file descriptor to the socket. (i.e -+the parent did fork+exec) -+ -+If the host:port contains a '/' it is interpreted as a -+unix-domain socket (AF_LOCAL insead of AF_INET) -+.TP -+\fB\-multilisten\fR -+As in -listen (reverse connection listening) except -+allow more than one incoming VNC server to be connected -+at a time. The default for -listen of only one at a -+time tries to play it safe by not allowing anyone on -+the network to put (many) desktops on your screen over -+a long window of time. Use -multilisten for no limit. -+.TP -+\fB\-acceptpopup\fR -+In \fB\-listen\fR (reverse connection listening) mode when -+a reverse VNC connection comes in show a popup asking -+whether to Accept or Reject the connection. The IP -+address of the connecting host is shown. Same as -+setting the env. var. SSVNC_ACCEPT_POPUP=1. -+.TP -+\fB\-acceptpopupsc\fR -+As in \fB\-acceptpopup\fR except assume UltraVNC Single -+Click (SC) server. Retrieve User and ComputerName -+info from UltraVNC Server and display in the Popup. -+.TP -+\fB\-use64\fR -+In \fB\-bgr233\fR mode, use 64 colors instead of 256. -+.TP -+\fB\-bgr222\fR -+Same as \fB\-use64\fR. -+.TP -+\fB\-use8\fR -+In \fB\-bgr233\fR mode, use 8 colors instead of 256. -+.TP -+\fB\-bgr111\fR -+Same as \fB\-use8\fR. -+.TP -+\fB\-16bpp\fR -+If the vnc viewer X display is depth 24 at 32bpp -+request a 16bpp format from the VNC server to cut -+network traffic by up to 2X, then tranlate the -+pixels to 32bpp locally. -+.TP -+\fB\-bgr565\fR -+Same as \fB\-16bpp\fR. -+.TP -+\fB\-grey\fR -+Use a grey scale for the 16- and 8\fB\-bpp\fR modes. -+.TP -+\fB\-alpha\fR -+Use alphablending transparency for local cursors -+requires: x11vnc server, both client and server -+must be 32bpp and same endianness. -+.TP -+\fB\-scale\fR \fIstr\fR -+Scale the desktop locally. The string "str" can -+a floating point ratio, e.g. "0.9", or a fraction, -+e.g. "3/4", or WxH, e.g. 1280x1024. Use "fit" -+to fit in the current screen size. Use "auto" to -+fit in the window size. "str" can also be set by -+the env. var. SSVNC_SCALE. -+ -+If you observe mouse trail painting errors, enable -+X11 Cursor mode (either via Popup or \fB\-x11cursor\fR.) -+ -+Note that scaling is done in software and so can be -+slow and requires more memory. Some speedup Tips: -+ -+ZRLE is faster than Tight in this mode. When -+scaling is first detected, the encoding will -+be automatically switched to ZRLE. Use the -+Popup menu if you want to go back to Tight. -+Set SSVNC_PRESERVE_ENCODING=1 to disable this. -+ -+Use a solid background on the remote side. -+(e.g. manually or via x11vnc \fB\-solid\fR ...) -+ -+If the remote server is x11vnc, try client -+side caching: x11vnc \fB\-ncache\fR 10 ... -+.TP -+\fB\-ycrop\fR n -+Only show the top n rows of the framebuffer. For -+use with x11vnc \fB\-ncache\fR client caching option -+to help "hide" the pixel cache region. -+Use a negative value (e.g. \fB\-1\fR) for autodetection. -+Autodetection will always take place if the remote -+fb height is more than 2 times the width. -+.TP -+\fB\-sbwidth\fR n -+Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR), -+default is very narrow: 2 pixels, it is narrow to -+avoid distraction in \fB\-ycrop\fR mode. -+.TP -+\fB\-nobell\fR -+Disable bell. -+.TP -+\fB\-rawlocal\fR -+Prefer raw encoding for localhost, default is -+no, i.e. assumes you have a SSH tunnel instead. -+.TP -+\fB\-notty\fR -+Try to avoid using the terminal for interactive -+responses: use windows for messages and prompting -+instead. Messages will also be printed to terminal. -+.TP -+\fB\-sendclipboard\fR -+Send the X CLIPBOARD selection (i.e. Ctrl+C, -+Ctrl+V) instead of the X PRIMARY selection (mouse -+select and middle button paste.) -+.TP -+\fB\-sendalways\fR -+Whenever the mouse enters the VNC viewer main -+window, send the selection to the VNC server even if -+it has not changed. This is like the Xt resource -+translation SelectionToVNC(always) -+.TP -+\fB\-recvtext\fR -+str When cut text is received from the VNC server, -+ssvncviewer will set both the X PRIMARY and the -+X CLIPBOARD local selections. To control which -+is set, specify 'str' as 'primary', 'clipboard', -+or 'both' (the default.) -+.TP -+\fB\-graball\fR -+Grab the entire X server when in fullscreen mode, -+needed by some old window managers like fvwm2. -+.TP -+\fB\-popupfix\fR -+Warp the popup back to the pointer position, -+needed by some old window managers like fvwm2. -+.TP -+\fB\-grabkbd\fR -+Grab the X keyboard when in fullscreen mode, -+needed by some window managers. Same as \fB\-grabkeyboard\fR. -+\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable. -+.TP -+\fB\-bs\fR, \fB\-nobs\fR -+Whether or not to use X server Backingstore for the -+main viewer window. The default is to not, mainly -+because most Linux, etc, systems X servers disable -+*all* Backingstore by default. To re\fB\-enable\fR it put -+ -+Option "Backingstore" -+ -+in the Device section of /etc/X11/xorg.conf. -+In \fB\-bs\fR mode with no X server backingstore, whenever an -+area of the screen is re\fB\-exposed\fR it must go out to the -+VNC server to retrieve the pixels. This is too slow. -+ -+In \fB\-nobs\fR mode, memory is allocated by the viewer to -+provide its own backing of the main viewer window. This -+actually makes some activities faster (changes in large -+regions) but can appear to "flash" too much. -+.TP -+\fB\-noshm\fR -+Disable use of MIT shared memory extension (not recommended) -+.TP -+\fB\-termchat\fR -+Do the UltraVNC chat in the terminal vncviewer is in -+instead of in an independent window. -+.TP -+\fB\-unixpw\fR \fIstr\fR -+Useful for logging into x11vnc in \fB\-unixpw\fR mode. "str" is a -+string that allows many ways to enter the Unix Username -+and Unix Password. These characters: username, newline, -+password, newline are sent to the VNC server after any VNC -+authentication has taken place. Under x11vnc they are -+used for the \fB\-unixpw\fR login. Other VNC servers could do -+something similar. -+ -+You can also indicate "str" via the environment -+variable SSVNC_UNIXPW. -+ -+Note that the Escape key is actually sent first to tell -+x11vnc to not echo the Unix Username back to the VNC -+viewer. Set SSVNC_UNIXPW_NOESC=1 to override this. -+ -+If str is ".", then you are prompted at the command line -+for the username and password in the normal way. If str is -+"-" the stdin is read via getpass(3) for username@password. -+Otherwise if str is a file, it is opened and the first line -+read is taken as the Unix username and the 2nd as the -+password. If str prefixed by "rm:" the file is removed -+after reading. Otherwise, if str has a "@" character, -+it is taken as username@password. Otherwise, the program -+exits with an error. Got all that? -+.TP -+\fB-repeater\fR \fIstr\fR -+This is for use with UltraVNC repeater proxy described -+here: http://www.uvnc.com/addons/repeater.html. The "str" -+is the ID string to be sent to the repeater. E.g. ID:1234 -+It can also be the hostname and port or display of the VNC -+server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when -+using -repeater, the host:dpy on the cmdline is the repeater -+server, NOT the VNC server. The repeater will connect you. -+ -+Example: vncviewer ... -repeater ID:3333 repeat.host:5900 -+ -+Example: vncviewer ... -repeater vhost:0 repeat.host:5900 -+ -+Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a -+Single Click III (SSL) repeater (repeater_SSL.exe) and you -+are passing the SSL part of the connection through stunnel, socat, etc. -+This way the magic UltraVNC string 'testB' needed to work with the -+repeater is sent to it. -+.TP -+\fB-rfbversion\fR \fIstr\fR -+Set the advertised RFB version. E.g.: -rfbversion 3.6 For some -+servers, e.g. UltraVNC this needs to be done. -+.TP -+\fB-ultradsm\fR -+UltraVNC has symmetric private encryption DSM plugins. See -+http://www.uvnc.com/features/encryption.html. It is assumed -+you are using a unix program (e.g. our ultravnc_dsm_helper) to -+encrypt and decrypt the UltraVNC DSM stream. IN ADDITION TO -+THAT supply -ultradsm to tell THIS viewer to modify the RFB -+data sent so as to work with the UltraVNC Server. For some -+reason, each RFB msg type must be sent twice under DSM. -+.TP -+\fB\-mslogon\fR \fIuser\fR -+Use Windows MS Logon to an UltraVNC server. Supply the -+username or "1" to be prompted. The default is to -+autodetect the UltraVNC MS Logon server and prompt for -+the username and password. -+ -+IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman -+exchange is very weak and can be brute forced to recover -+your username and password in a few seconds of CPU -+time. To be safe, be sure to use an additional encrypted -+tunnel (e.g. SSL or SSH) for the entire VNC session. -+.TP -+\fB\-chatonly\fR -+Try to be a client that only does UltraVNC text chat. This -+mode is used by x11vnc to present a chat window on the physical -+X11 console (i.e. to chat with the person at the display). -+.TP -+\fB-env\fR \fIVAR=VALUE\fR -+To save writing a shell script to set environment -+variables, specify as many as you need on the command line. For example, -+-env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi -+.TP -+\fB\-noipv6\fR -+Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1. -+.TP -+\fB\-noipv4\fR -+Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1. -+.TP -+\fB\-printres\fR -+Print out the Ssvnc X resources (appdefaults) and -+then exit. You can save them to a file and customize them (e.g. the -+keybindings and Popup menu) Then point to the file via -+XENVIRONMENT or XAPPLRESDIR. -+.TP -+\fB\-pipeline\fR -+Like TurboVNC, request the next framebuffer update as soon -+as possible instead of waiting until the end of the current -+framebuffer update coming in. Helps 'pipeline' the updates. -+This is currently the default, use \fB-nopipeline\fR to disable. -+.TP -+\fB\-appshare\fR -+Enable features for use with x11vnc's \fB\-appshare\fR mode where -+instead of sharing the full desktop only the application's -+windows are shared. Viewer multilisten mode is used to -+create the multiple windows: \fB\-multilisten\fR is implied. -+See 'x11vnc \fB\-appshare\fR \fB\-help\fR' more information on the mode. -+Features enabled in the viewer under \fB\-appshare\fR are: -+Minimum extra text in the title, auto \fB\-ycrop\fR is disabled, -+x11vnc \fB\-remote_prefix\fR X11VNC_APPSHARE_CMD: message channel, -+x11vnc initial window position hints. See also Escape Keys -+below for additional key and mouse bindings. -+.TP -+\fB\-escape \fR\fIstr\fR -+This sets the 'Escape Keys' modifier sequence and enables -+escape keys mode. When the modifier keys escape sequence -+is held down, the next keystroke is interpreted locally -+to perform a special action instead of being sent to the -+remote VNC server. -+ -+Use '\fB\-escape\fR default' for the default modifier sequence. -+(Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L) -+ -+Here are the 'Escape Keys: Help+Set' instructions from the Popup: -+ -+Escape Keys: Enter a comma separated list of modifier keys to be the 'escape -+sequence'. When these keys are held down, the next keystroke is -+interpreted locally to invoke a special action instead of being sent to -+the remote VNC server. In other words, a set of 'Hot Keys'. -+ -+Here is the list of local key mappings to special actions: -+ -+r: refresh desktop b: toggle bell c: toggle full-color -+ -+f: file transfer x: x11cursor z: toggle Tight/ZRLE -+ -+l: full screen g: graball e: escape keys dialog -+ -+s: scale dialog +: scale up (=) -: scale down (_) -+ -+t: text chat a: alphablend cursor -+ -+V: toggle viewonly Q: quit viewer 123456: UltraVNC scale 1/n -+ -+Arrow keys: pan the viewport about 10% for each keypress. -+ -+PageUp/PageDown: pan the viewport by a screenful vertically. -+ -+Home/End: pan the viewport by a screenful horizontally. -+ -+KeyPad Arrows: pan the viewport by 1 pixel for each keypress. -+ -+Dragging the Mouse with Button1 pressed also pans the viewport. -+ -+Clicking Mouse Button3 brings up the Popup Menu. -+ -+The above mappings are \fBalways\fR active in ViewOnly mode, unless you set -+the Escape Keys value to 'never'. -+ -+x11vnc -appshare hot-keys: x11vnc has a simple application sharing mode -+that enables the viewer-side to move, resize, or raise the remote toplevel -+windows. To enable it, hold down Shift + the Escape Keys and press these: -+ -+Arrow keys: move the remote window around in its desktop. -+ -+PageUp/PageDn/Home/End: resize the remote window. -+ -++/-: raise or lower the remote window. -+ -+M or Button1 move win to local position; D or Button3: delete remote win. -+ -+If the Escape Keys value below is set to 'default' then a default list of -+of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it -+is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag -+on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side -+of the keyboard. -+ -+On Unix the default is Alt and Windows keys on Left side of keyboard. -+On MacOSX the default is Control and Command keys on Left side of keyboard. -+ -+Example: Press and hold the Alt and Windows keys on the LEFT side of the -+keyboard and then press 'c' to toggle the full-color state. Or press 't' -+to toggle the ultravnc Text Chat window, etc. -+ -+To use something besides the default, supply a comma separated list (or a -+single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L -+Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch. -+.TP -+\fB New Popup actions:\fR -+ -+ ViewOnly: ~ -viewonly -+ Disable Bell: ~ -nobell -+ Cursor Shape: ~ -nocursorshape -+ X11 Cursor: ~ -x11cursor -+ Cursor Alphablend: ~ -alpha -+ Toggle Tight/Hextile: ~ -encodings hextile... -+ Toggle Tight/ZRLE: ~ -encodings zrle... -+ Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... -+ Quality Level ~ -quality (both Tight and ZYWRLE) -+ Compress Level ~ -compresslevel -+ Disable JPEG: ~ -nojpeg (Tight) -+ Pipeline Updates ~ -pipeline -+ -+ Full Color as many colors as local screen allows. -+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only. -+ 16 bit color (BGR565) ~ -16bpp / -bgr565 -+ 8 bit color (BGR233) ~ -bgr233 -+ 256 colors ~ -bgr233 default # of colors. -+ 64 colors ~ -bgr222 / -use64 -+ 8 colors ~ -bgr111 / -use8 -+ Scale Viewer ~ -scale -+ Escape Keys: Toggle ~ -escape -+ Escape Keys: Help+Set ~ -escape -+ Set Y Crop (y-max) ~ -ycrop -+ Set Scrollbar Width ~ -sbwidth -+ XGrabServer ~ -graball -+ -+ UltraVNC Extensions: -+ -+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n. -+ Text Chat Ultravnc ext. Do Text Chat. -+ File Transfer Ultravnc ext. File xfer via Java helper. -+ Single Window Ultravnc ext. Grab and view a single window. -+ (select then click on the window you want). -+ Disable Remote Input Ultravnc ext. Try to prevent input and -+ viewing of monitor at physical display. -+ -+ Note: the Ultravnc extensions only apply to servers that support -+ them. x11vnc/libvncserver supports some of them. -+ -+ Send Clipboard not Primary ~ -sendclipboard -+ Send Selection Every time ~ -sendalways -+ -+.SH ENCODINGS -+The server supplies information in whatever format is desired by the -+client, in order to make the client as easy as possible to implement. -+If the client represents itself as able to use multiple formats, the -+server will choose one. -+ -+.I Pixel format -+refers to the representation of an individual pixel. The most common -+formats are 24 and 16 bit "true\-color" values, and 8\-bit "color map" -+representations, where an arbitrary map converts the color number to -+RGB values. -+ -+.I Encoding -+refers to how a rectangle of pixels are sent (all pixel information in -+VNC is sent as rectangles). All rectangles come with a header giving -+the location and size of the rectangle and an encoding type used by -+the data which follows. These types are listed below. -+.TP -+.B Raw -+The raw encoding simply sends width*height pixel values. All clients -+are required to support this encoding type. Raw is also the fastest -+when the server and viewer are on the same machine, as the connection -+speed is essentially infinite and raw encoding minimizes processing -+time. -+.TP -+.B CopyRect -+The Copy Rectangle encoding is efficient when something is being -+moved; the only data sent is the location of a rectangle from which -+data should be copied to the current location. Copyrect could also be -+used to efficiently transmit a repeated pattern. -+.TP -+.B RRE -+The Rise\-and\-Run\-length\-Encoding is basically a 2D version of -+run\-length encoding (RLE). In this encoding, a sequence of identical -+pixels are compressed to a single value and repeat count. In VNC, this -+is implemented with a background color, and then specifications of an -+arbitrary number of subrectangles and color for each. This is an -+efficient encoding for large blocks of constant color. -+.TP -+.B CoRRE -+This is a minor variation on RRE, using a maximum of 255x255 pixel -+rectangles. This allows for single\-byte values to be used, reducing -+packet size. This is in general more efficient, because the savings -+from sending 1\-byte values generally outweighs the losses from the -+(relatively rare) cases where very large regions are painted the same -+color. -+.TP -+.B Hextile -+Here, rectangles are split up in to 16x16 tiles, which are sent in a -+predetermined order. The data within the tiles is sent either raw or -+as a variant on RRE. Hextile encoding is usually the best choice for -+using in high\-speed network environments (e.g. Ethernet local\-area -+networks). -+.TP -+.B Zlib -+Zlib is a very simple encoding that uses zlib library to compress raw -+pixel data. This encoding achieves good compression, but consumes a -+lot of CPU time. Support for this encoding is provided for -+compatibility with VNC servers that might not understand Tight -+encoding which is more efficient than Zlib in nearly all real\-life -+situations. -+.TP -+.B Tight -+Like Zlib encoding, Tight encoding uses zlib library to compress the -+pixel data, but it pre\-processes data to maximize compression ratios, -+and to minimize CPU usage on compression. Also, JPEG compression may -+be used to encode color\-rich screen areas (see the description of -+\-quality and \-nojpeg options above). Tight encoding is usually the -+best choice for low\-bandwidth network environments (e.g. slow modem -+connections). -+.TP -+.B ZRLE -+The SSVNC viewer has ported the RealVNC (www.realvnc.com) ZRLE encoding -+to the unix tightvnc viewer. -+.TP -+.B ZYWRLE -+The SSVNC viewer has ported the Hitachi lossy wavelet based ZRLE -+encoding from http://mobile.hitachi-system.co.jp/publications/ZYWRLE/ -+to the unix tightvnc viewer. -+.SH RESOURCES -+X resources that \fBvncviewer\fR knows about, aside from the -+normal Xt resources, are as follows: -+.TP -+.B shareDesktop -+Equivalent of \fB\-shared\fR/\fB\-noshared\fR options. Default true. -+.TP -+.B viewOnly -+Equivalent of \fB\-viewonly\fR option. Default false. -+.TP -+.B fullScreen -+Equivalent of \fB\-fullscreen\fR option. Default false. -+.TP -+.B grabKeyboard -+Grab keyboard in full-screen mode. This can help to solve problems -+with losing keyboard focus. Default false. -+.TP -+.B raiseOnBeep -+Equivalent of \fB\-noraiseonbeep\fR option, when set to false. Default -+true. -+.TP -+.B passwordFile -+Equivalent of \fB\-passwd\fR option. -+.TP -+.B userLogin -+Equivalent of \fB\-user\fR option. -+.TP -+.B passwordDialog -+Whether to use a dialog box to get the password (true) or get it from -+the tty (false). Irrelevant if \fBpasswordFile\fR is set. Default -+false. -+.TP -+.B encodings -+Equivalent of \fB\-encodings\fR option. -+.TP -+.B compressLevel -+Equivalent of \fB\-compresslevel\fR option (TightVNC\-specific). -+.TP -+.B qualityLevel -+Equivalent of \fB\-quality\fR option (TightVNC\-specific). -+.TP -+.B enableJPEG -+Equivalent of \fB\-nojpeg\fR option, when set to false. Default true. -+.TP -+.B useRemoteCursor -+Equivalent of \fB\-nocursorshape\fR option, when set to false -+(TightVNC\-specific). Default true. -+.TP -+.B useBGR233 -+Equivalent of \fB\-bgr233\fR option. Default false. -+.TP -+.B nColours -+When using BGR233, try to allocate this many "exact" colors from the -+BGR233 color cube. When using a shared colormap, setting this resource -+lower leaves more colors for other X clients. Irrelevant when using -+truecolor. Default is 256 (i.e. all of them). -+.TP -+.B useSharedColours -+If the number of "exact" BGR233 colors successfully allocated is less -+than 256 then the rest are filled in using the "nearest" colors -+available. This resource says whether to only use the "exact" BGR233 -+colors for this purpose, or whether to use other clients' "shared" -+colors as well. Default true (i.e. use other clients' colors). -+.TP -+.B forceOwnCmap -+Equivalent of \fB\-owncmap\fR option. Default false. -+.TP -+.B forceTrueColour -+Equivalent of \fB\-truecolour\fR option. Default false. -+.TP -+.B requestedDepth -+Equivalent of \fB\-depth\fR option. -+.TP -+.B useSharedMemory -+Use MIT shared memory extension if on the same machine as the X -+server. Default true. -+.TP -+.B wmDecorationWidth, wmDecorationHeight -+The total width and height taken up by window manager decorations. -+This is used to calculate the maximum size of the VNC viewer window. -+Default is width 4, height 24. -+.TP -+.B bumpScrollTime, bumpScrollPixels -+When in full screen mode and the VNC desktop is bigger than the X -+display, scrolling happens whenever the mouse hits the edge of the -+screen. The maximum speed of scrolling is bumpScrollPixels pixels -+every bumpScrollTime milliseconds. The actual speed of scrolling will -+be slower than this, of course, depending on how fast your machine is. -+Default 20 pixels every 25 milliseconds. -+.TP -+.B popupButtonCount -+The number of buttons in the popup window. See the README file for -+more information on how to customize the buttons. -+.TP -+.B debug -+For debugging. Default false. -+.TP -+.B rawDelay, copyRectDelay -+For debugging, see the README file for details. Default 0 (off). -+.SH ENVIRONMENT -+When started with the \fB\-via\fR option, vncviewer reads the -+\fBVNC_VIA_CMD\fR environment variable, expands patterns beginning -+with the "%" character, and executes result as a command assuming that -+it would create TCP tunnel that should be used for VNC connection. If -+not set, this environment variable defaults to "/usr/bin/ssh -f -L -+%L:%H:%R %G sleep 20". -+ -+The following patterns are recognized in the \fBVNC_VIA_CMD\fR (note -+that all the patterns %G, %H, %L and %R must be present in the command -+template): -+.TP -+.B %% -+A literal "%"; -+.TP -+.B %G -+gateway host name; -+.TP -+.B %H -+remote VNC host name, as known to the gateway; -+.TP -+.B %L -+local TCP port number; -+.TP -+.B %R -+remote TCP port number. -+.SH SEE ALSO -+\fBvncserver\fR(1), \fBx11vnc\fR(1), \fBssvnc\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1), -+\fBvncconnect\fR(1), \fBssh\fR(1), http://www.karlrunge.com/x11vnc, http://www.karlrunge.com/x11vnc/ssvnc.html -+.SH AUTHORS -+Original VNC was developed in AT&T Laboratories Cambridge. TightVNC -+additions was implemented by Constantin Kaplinsky. Many other people -+participated in development, testing and support. Karl J. Runge -+added all of the SSVNC related features and improvements. -+ -+\fBMan page authors:\fR -+.br -+Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>, -+.br -+Terran Melconian <terran@consistent.org>, -+.br -+Tim Waugh <twaugh@redhat.com>, -+.br -+Constantin Kaplinsky <const@ce.cctpu.edu.ru> -+.br -+Karl J. Runge <runge@karlrunge.com> -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.c vnc_unixsrc/vncviewer/vncviewer.c ---- vnc_unixsrc.orig/vncviewer/vncviewer.c 2004-01-13 09:22:05.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer.c 2010-04-18 12:43:47.000000000 -0400 -@@ -22,6 +22,8 @@ - */ - - #include "vncviewer.h" -+#include <ctype.h> -+#include <X11/Xaw/Toggle.h> - - char *programName; - XtAppContext appContext; -@@ -29,11 +31,274 @@ - - Widget toplevel; - -+extern void raiseme(int force); -+extern void CreateChat(void); -+ -+void set_sbwidth(int sbw) { -+ char *q, *p, t[5]; -+ int i, k, N = 4; -+ int db = 0; -+ -+ if (sbw < 1) { -+ sbw = 2; -+ } else if (sbw > 100) { -+ sbw = 100; -+ } -+ if (db) fprintf(stderr, "sbw: %d\n", sbw); -+ -+ sprintf(t, "%4d", sbw); -+ k = 0; -+ while (fallback_resources[k] != NULL) { -+ q = strstr(fallback_resources[k], "horizontal.height: "); -+ if (!q) { -+ q = strstr(fallback_resources[k], "vertical.width: "); -+ } -+ if (q) { -+ p = strdup(fallback_resources[k]); -+ q = strstr(p, ": "); -+ if (q) { -+ q++; -+ q++; -+ for (i=0; i < N; i++) { -+ *(q+i) = t[i]; -+ } -+ fallback_resources[k] = p; -+ if (db) fprintf(stderr, "res: %s\n\n", p); -+ } -+ } -+ k++; -+ } -+} -+ -+void min_title(void) { -+ char *q; -+ int k; -+ -+ k = 0; -+ while (fallback_resources[k] != NULL) { -+ q = strstr(fallback_resources[k], "Ssvnc.title: "); -+ if (q) { -+ fallback_resources[k] = strdup("Ssvnc.title: %s"); -+ } -+ k++; -+ } -+} -+ -+#include <sys/types.h> -+#include <sys/stat.h> -+#include <unistd.h> -+ -+void unixpw(char *instr, int vencrypt_plain) { -+ char *str, *q, *infile = NULL; -+ FILE *in; -+ int i, rmfile = 0; -+ struct stat sb; -+ int N = 99; -+ char username[100], passwd[100]; -+ static int did = 0; -+ -+ if (did) { -+ return; -+ } -+ did = 1; -+ -+ for (i=0; i<100; i++) { -+ username[i] = '\0'; -+ passwd[i] = '\0'; -+ } -+ -+ if (instr == NULL) { -+ return; -+ } else if (!strcmp(instr, "")) { -+ return; -+ } -+ -+ str = strdup(instr); -+ -+ if (strstr(str, "rm:") == str) { -+ rmfile = 1; -+ infile = str + strlen("rm:"); -+ } else if (stat(str, &sb) == 0) { -+ infile = str; -+ } -+ if (!strcmp(str, ".")) { -+ char *p; -+ if (!use_tty()) { -+ char *u; -+ fprintf(stderr, "\nEnter Unix Username and Password in the popups.\n"); -+ u = DoUserDialog(); -+ if (strlen(u) >= 100) { -+ exit(1); -+ } -+ sprintf(username, u); -+ p = DoPasswordDialog(); -+ } else { -+ raiseme(1); -+ fprintf(stderr, "\nUnix Username: "); -+ if (fgets(username, N, stdin) == NULL) { -+ exit(1); -+ } -+ p = getpass("Unix Password: "); -+ } -+ if (! p) { -+ exit(1); -+ } -+ strncpy(passwd, p, N); -+ fprintf(stderr, "\n"); -+ -+ } else if (!strcmp(str, "-")) { -+ char *p, *q; -+ if (!use_tty()) { -+ fprintf(stderr, "\nEnter unixuser@unixpasswd in the popup.\n"); -+ p = DoPasswordDialog(); -+ } else { -+ raiseme(1); -+ p = getpass("unixuser@unixpasswd: "); -+ } -+ if (! p) { -+ exit(1); -+ } -+ q = strchr(p, '@'); -+ if (! q) { -+ exit(1); -+ } -+ *q = '\0'; -+ strncpy(username, p, N); -+ strncpy(passwd, q+1, N); -+ -+ } else if (infile) { -+ in = fopen(infile, "r"); -+ if (in == NULL) { -+ fprintf(stderr, "failed to open -unixpw file.\n"); -+ exit(1); -+ } -+ if (fgets(username, N, in) == NULL) { -+ exit(1); -+ } -+ if (fgets(passwd, N, in) == NULL) { -+ exit(1); -+ } -+ fclose(in); -+ fprintf(stderr, "read username@passwd from file: %s\n", infile); -+ if (rmfile) { -+ fprintf(stderr, "deleting username@passwd file: %s\n", infile); -+ unlink(infile); -+ } -+ } else if (strchr(str, '@')) { -+ char *q = strchr(str, '@'); -+ *q = '\0'; -+ strncpy(username, str, N); -+ strncpy(passwd, q+1, N); -+ } else { -+ exit(1); -+ } -+ -+ free(str); -+ -+ if (vencrypt_plain) { -+ CARD32 ulen, plen; -+ char *q; -+ -+ q = strrchr(username, '\n'); -+ if (q) *q = '\0'; -+ q = strrchr(passwd, '\n'); -+ if (q) *q = '\0'; -+ -+ ulen = Swap32IfLE((CARD32)strlen(username)); -+ plen = Swap32IfLE((CARD32)strlen(passwd)); -+ -+ if (!WriteExact(rfbsock, (char *)&ulen, 4) || -+ !WriteExact(rfbsock, (char *)&plen, 4)) { -+ return; -+ } -+ -+ if (!WriteExact(rfbsock, username, strlen(username)) || -+ !WriteExact(rfbsock, passwd, strlen(passwd))) { -+ return; -+ } -+ return; -+ } -+ -+ -+ if (! getenv("SSVNC_UNIXPW_NOESC")) { -+ SendKeyEvent(XK_Escape, 1); -+ SendKeyEvent(XK_Escape, 0); -+ } -+ -+ q = username; -+ while (*q != '\0' && *q != '\n') { -+ char c = *q; -+ if (c >= 0x20 && c <= 0x07e) { -+ KeySym ks = (KeySym) c; -+ SendKeyEvent(ks, 1); -+ SendKeyEvent(ks, 0); -+ } -+ q++; -+ } -+ -+ SendKeyEvent(XK_Return, 1); -+ SendKeyEvent(XK_Return, 0); -+ -+ q = passwd; -+ while (*q != '\0' && *q != '\n') { -+ char c = *q; -+ if (c >= 0x20 && c <= 0x07e) { -+ KeySym ks = (KeySym) c; -+ SendKeyEvent(ks, 1); -+ SendKeyEvent(ks, 0); -+ } -+ q++; -+ } -+ -+ SendKeyEvent(XK_Return, 1); -+ SendKeyEvent(XK_Return, 0); -+} -+ -+static void chat_window_only(void) { -+ if (appData.chatOnly) { -+ static double last_time = 0.0; -+ if (dnow() > last_time + 1.5) { -+ XSync(dpy, False); -+ XUnmapWindow(dpy, XtWindow(toplevel)); -+ } -+ } -+} -+ -+int saw_appshare = 0; -+ - int - main(int argc, char **argv) - { -- int i; -- programName = argv[0]; -+ int i, save_sbw, saw_listen = 0; -+ char *pw_loc = NULL; -+ programName = argv[0]; -+ -+ if (strrchr(programName, '/') != NULL) { -+ programName = strrchr(programName, '/') + 1; -+ } -+ -+ for (i = 1; i < argc; i++) { -+ if (!strcmp(argv[i], "-env")) { -+ if (i+1 < argc) { -+ char *estr = argv[i+1]; -+ if (strchr(estr, '=')) { -+ putenv(estr); -+ } -+ } -+ } -+ if (!strcmp(argv[i], "-noipv4")) { -+ putenv("VNCVIEWER_NO_IPV4=1"); -+ } -+ if (!strcmp(argv[i], "-noipv6")) { -+ putenv("VNCVIEWER_NO_IPV6=1"); -+ } -+ } -+ if (getenv("VNCVIEWER_NO_IPV4")) { -+ appData.noipv4 = True; -+ } -+ if (getenv("VNCVIEWER_NO_IPV6")) { -+ appData.noipv6 = True; -+ } - - /* The -listen option is used to make us a daemon process which listens for - incoming connections from servers, rather than actively connecting to a -@@ -45,89 +310,1744 @@ - listenForIncomingConnections() returns, setting the listenSpecified - flag. */ - -- for (i = 1; i < argc; i++) { -- if (strcmp(argv[i], "-listen") == 0) { -- listenForIncomingConnections(&argc, argv, i); -- break; -- } -- if (strcmp(argv[i], "-tunnel") == 0 || strcmp(argv[i], "-via") == 0) { -- if (!createTunnel(&argc, argv, i)) -- exit(1); -- break; -- } -- } -+ for (i = 1; i < argc; i++) { -+ if (!strcmp(argv[i], "-appshare")) { -+ putenv("SSVNC_MULTIPLE_LISTEN=1"); -+ fprintf(stderr, "Enabling -multilisten mode for 'x11vnc -appshare' usage.\n\n"); -+ saw_appshare = 1; -+ } -+ if (!strcmp(argv[i], "-multilisten")) { -+ putenv("SSVNC_MULTIPLE_LISTEN=1"); -+ saw_listen = 2; -+ } -+ if (!strcmp(argv[i], "-listen")) { -+ saw_listen = 1; -+ } -+ if (!strcmp(argv[i], "-acceptpopup")) { -+ putenv("SSVNC_ACCEPT_POPUP=1"); -+ } -+ if (!strcmp(argv[i], "-acceptpopupsc")) { -+ putenv("SSVNC_ACCEPT_POPUP_SC=1"); -+ } -+ if (strstr(argv[i], " pw=") != NULL) { -+ pw_loc = strstr(argv[i], " pw=") + 1; -+ } -+ } -+ -+ for (i = 1; i < argc; i++) { -+ if (!strcmp(argv[i], "-appshare") && !saw_listen) { -+ listenForIncomingConnections(&argc, argv, i); -+ break; -+ } -+ if (!strcmp(argv[i], "-multilisten")) { -+ listenForIncomingConnections(&argc, argv, i); -+ break; -+ } -+ if (!strcmp(argv[i], "-listen")) { -+ listenForIncomingConnections(&argc, argv, i); -+ break; -+ } -+ if (!strcmp(argv[i], "-tunnel") || !strcmp(argv[i], "-via")) { -+ if (!createTunnel(&argc, argv, i)) { -+ exit(1); -+ } -+ break; -+ } -+ if (!strcmp(argv[i], "-printres") || !strcmp(argv[i], "-res")) { -+ int j = 0; -+ fprintf(stdout, "\n! Ssvnc fallback X resources:\n\n"); -+ while (1) { -+ char *p = fallback_resources[j++]; -+ int k = 0; -+ if (p == NULL) break; -+ while (*p != '\0') { -+ fprintf(stdout, "%c", *p); -+ if (k > 0 && *p == 'n' && *(p-1) == '\\') { -+ fprintf(stdout, "\\\n"); -+ } -+ p++; k++; -+ } -+ fprintf(stdout, "\n\n"); -+ } -+ exit(0); -+ } -+ } -+ -+ -+ if (argc > 1 && strstr(argv[1], "-h") == argv[1]) { -+ usage(); -+ return 0; -+ } - - /* Call the main Xt initialisation function. It parses command-line options, - generating appropriate resource specs, and makes a connection to the X - display. */ - -- toplevel = XtVaAppInitialize(&appContext, "Vncviewer", -- cmdLineOptions, numCmdLineOptions, -- &argc, argv, fallback_resources, -- XtNborderWidth, 0, NULL); -+ if (saw_appshare || getenv("VNCVIEWER_MIN_TITLE")) { -+ min_title(); -+ } -+ appData.sbWidth = 0; -+ if (getenv("VNCVIEWER_SBWIDTH")) { -+ int sbw = atoi(getenv("VNCVIEWER_SBWIDTH")); -+ if (sbw > 0) { -+ appData.sbWidth = sbw; -+ } -+ } -+ if (appData.sbWidth == 0) { -+ int i, sbw = 0; -+ for (i = 1; i < argc - 1; i++) { -+ if (!strcmp(argv[i], "-sbwidth")) { -+ sbw = atoi(argv[i+1]); -+ } -+ } -+ if (sbw > 0) { -+ appData.sbWidth = sbw; -+ } -+ } -+ save_sbw = appData.sbWidth; -+ if (save_sbw > 0) { -+ set_sbwidth(save_sbw); -+ } else { -+ set_sbwidth(6); -+ } -+ -+ toplevel = XtVaAppInitialize(&appContext, "Ssvnc", cmdLineOptions, -+ numCmdLineOptions, &argc, argv, fallback_resources, -+ XtNborderWidth, 0, NULL); - -- dpy = XtDisplay(toplevel); -+ dpy = XtDisplay(toplevel); - - /* Interpret resource specs and process any remaining command-line arguments - (i.e. the VNC server name). If the server name isn't specified on the - command line, getArgsAndResources() will pop up a dialog box and wait - for one to be entered. */ - -- GetArgsAndResources(argc, argv); -+ GetArgsAndResources(argc, argv); -+ -+ if (saw_appshare) { -+ appData.appShare = True; -+ } -+ -+ if (save_sbw) { -+ appData.sbWidth = save_sbw; -+ } -+ -+ if (appData.chatOnly) { -+ appData.encodingsString = "raw hextile"; -+ } -+ -+ if (pw_loc != NULL) { -+ char *q = pw_loc; -+ while (*q != '\0' && !isspace(*q)) { -+ *q = ' '; -+ q++; -+ } -+ } - - /* Unless we accepted an incoming connection, make a TCP connection to the - given VNC server */ - -- if (!listenSpecified) { -- if (!ConnectToRFBServer(vncServerHost, vncServerPort)) exit(1); -- } -+ if (appData.repeaterUltra == NULL) { -+ if (getenv("SSVNC_REPEATER") != NULL) { -+ appData.repeaterUltra = strdup(getenv("SSVNC_REPEATER")); -+ } -+ } -+ -+ if (!listenSpecified) { -+ if (!ConnectToRFBServer(vncServerHost, vncServerPort)) { -+ exit(1); -+ } -+ if (appData.repeaterUltra != NULL) { -+ char tmp[256]; -+ if (strstr(appData.repeaterUltra, "SCIII=") == appData.repeaterUltra) { -+ appData.repeaterUltra = strdup(appData.repeaterUltra + strlen("SCIII=")); -+ fprintf(stderr, "sending 'testB' to ultravnc SC III SSL repeater...\n"); -+ WriteExact(rfbsock, "testB" , 5); -+ } -+ if (ReadFromRFBServer(tmp, 12)) { -+ tmp[12] = '\0'; -+ fprintf(stderr, "repeater 1st proto line: '%s'\n", tmp); -+ if (strstr(tmp, "RFB 000.000") == tmp) { -+ int i; -+ for (i=0; i<256; i++) { -+ tmp[i] = '\0'; -+ } -+ for (i=0; i<250; i++) { -+ if (i >= (int) strlen(appData.repeaterUltra)) { -+ break; -+ } -+ tmp[i] = appData.repeaterUltra[i]; -+ } -+ fprintf(stderr, "sending '%s' to repeater...\n", tmp); -+ WriteExact(rfbsock, tmp, 250); -+ } -+ } else { -+ fprintf(stderr, "repeater NO proto line!\n"); -+ } -+ } -+ } - - /* Initialise the VNC connection, including reading the password */ - -- if (!InitialiseRFBConnection()) exit(1); -+ if (!InitialiseRFBConnection()) { -+ Cleanup(); -+ exit(1); -+ } -+ if (appData.unixPW != NULL) { -+ unixpw(appData.unixPW, 0); -+ } else if (getenv("SSVNC_UNIXPW")) { -+ unixpw(getenv("SSVNC_UNIXPW"), 0); -+ } - - /* Create the "popup" widget - this won't actually appear on the screen until - some user-defined event causes the "ShowPopup" action to be invoked */ - -- CreatePopup(); -+ CreatePopup(); -+ CreateScaleN(); -+ CreateTurboVNC(); -+ CreateQuality(); -+ CreateCompress(); -+ CreateChat(); - - /* Find the best pixel format and X visual/colormap to use */ - -- SetVisualAndCmap(); -+ SetVisualAndCmap(); - - /* Create the "desktop" widget, and perform initialisation which needs doing - before the widgets are realized */ - -- ToplevelInitBeforeRealization(); -+ ToplevelInitBeforeRealization(); - -- DesktopInitBeforeRealization(); -+ DesktopInitBeforeRealization(); - - /* "Realize" all the widgets, i.e. actually create and map their X windows */ - -- XtRealizeWidget(toplevel); -+ XtRealizeWidget(toplevel); - - /* Perform initialisation that needs doing after realization, now that the X - windows exist */ - -- InitialiseSelection(); -+ InitialiseSelection(); - -- ToplevelInitAfterRealization(); -+ ToplevelInitAfterRealization(); - -- DesktopInitAfterRealization(); -+ DesktopInitAfterRealization(); - - /* Tell the VNC server which pixel format and encodings we want to use */ - -- SetFormatAndEncodings(); -+ SetFormatAndEncodings(); -+ -+ if (appData.chatOnly) { -+ chat_window_only(); -+ ToggleTextChat(0, NULL, NULL, NULL); -+ } - - /* Now enter the main loop, processing VNC messages. X events will - automatically be processed whenever the VNC connection is idle. */ - -- while (1) { -- if (!HandleRFBServerMessage()) -- break; -- } -+ while (1) { -+ if (!HandleRFBServerMessage()) { -+ break; -+ } -+ if (appData.chatOnly) { -+ chat_window_only(); -+ } -+ } -+ -+ Cleanup(); -+ -+ return 0; -+} -+ -+/* -+ * Toggle8bpp -+ */ -+ -+static int last_ncolors = 0; -+static int save_useBGR233 = 0; -+static Bool save_useBGR565 = False; -+ -+static Widget b8 = NULL; -+static Widget b16 = NULL; -+static Widget bfull = NULL; -+ -+int do_format_change = 0; -+int do_cursor_change = 0; -+double do_fb_update = 0.0; -+static void schedule_format_change(void) { -+ do_format_change = 1; -+ do_cursor_change = 0; -+} -+extern double dnow(void); -+static void schedule_fb_update(void) { -+ do_fb_update = dnow(); -+} -+static void init_format_change(void) { -+ appDataNew.useBGR233 = appData.useBGR233; -+ appDataNew.useBGR565 = appData.useBGR565; -+ appDataNew.useGreyScale = appData.useGreyScale; -+ appDataNew.enableJPEG = appData.enableJPEG; -+ appDataNew.encodingsString = appData.encodingsString; -+ appDataNew.useRemoteCursor = appData.useRemoteCursor; -+ appDataNew.useX11Cursor = appData.useX11Cursor; -+ appDataNew.useRawLocal = appData.useRawLocal; -+ appDataNew.qualityLevel = appData.qualityLevel; -+ appDataNew.compressLevel = appData.compressLevel; -+} -+void cutover_format_change(void) { -+ appData.useBGR233 = appDataNew.useBGR233; -+ appData.useBGR565 = appDataNew.useBGR565; -+ appData.useGreyScale = appDataNew.useGreyScale; -+ appData.enableJPEG = appDataNew.enableJPEG; -+ appData.encodingsString = appDataNew.encodingsString; -+ appData.useRemoteCursor = appDataNew.useRemoteCursor; -+ appData.useX11Cursor = appDataNew.useX11Cursor; -+ appData.useRawLocal = appDataNew.useRawLocal; -+ appData.qualityLevel = appDataNew.qualityLevel; -+ appData.compressLevel = appDataNew.compressLevel; -+} -+ -+void -+Toggle8bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ fprintf(stderr, "Toggle8bpp: %d\n", appData.useBGR233); -+ b8 = w; -+ init_format_change(); -+ if (appData.useBGR233) { -+ last_ncolors = appData.useBGR233; -+ appDataNew.useBGR233 = 0; -+ appDataNew.useBGR565 = save_useBGR565; -+ fprintf(stderr, "8bpp: off\n"); -+ } else { -+ if (!last_ncolors) last_ncolors = 256; -+ appDataNew.useBGR233 = last_ncolors; -+ save_useBGR565 = appData.useBGR565; -+ appDataNew.useBGR565 = False; -+ fprintf(stderr, "8bpp: on (%d colors)\n", appDataNew.useBGR233); -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+ -+void -+Toggle16bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ fprintf(stderr, "Toggle16bpp: %d\n", appData.useBGR565); -+ b16 = w; -+ init_format_change(); -+ if (appData.useBGR565) { -+ appDataNew.useBGR565 = False; -+ appDataNew.useBGR233 = save_useBGR233; -+ fprintf(stderr, "16bpp: off\n"); -+ } else { -+ appDataNew.useBGR565 = True; -+ save_useBGR233 = appData.useBGR233; -+ appDataNew.useBGR233 = 0; -+ fprintf(stderr, "16bpp: on\n"); -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleFullColor(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ fprintf(stderr, "ToggleFullColor\n"); -+ bfull = w; -+ init_format_change(); -+ if (appData.useBGR565 || appData.useBGR233) { -+ save_useBGR565 = appData.useBGR565; -+ appDataNew.useBGR565 = False; -+ save_useBGR233 = appData.useBGR233; -+ appDataNew.useBGR233 = 0; -+ fprintf(stderr, "FullColor: on\n"); -+ } else { -+ if (save_useBGR565) { -+ appDataNew.useBGR565 = True; -+ appDataNew.useBGR233 = 0; -+ fprintf(stderr, "FullColor off -> 16bpp.\n"); -+ } else { -+ appDataNew.useBGR565 = False; -+ if (!save_useBGR233) save_useBGR233 = 256; -+ appDataNew.useBGR233 = save_useBGR233; -+ fprintf(stderr, "FullColor off -> 8bpp.\n"); -+ } -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleXGrab(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.grabAll) { -+ appData.grabAll = False; -+ } else { -+ appData.grabAll = True; -+ } -+ fprintf(stderr, "ToggleXGrab, current=%d\n", appData.grabAll); -+ /* always ungrab to be sure, fullscreen will handle the rest */ -+ XUngrabServer(dpy); -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleEscapeActive(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.escapeActive) { -+ appData.escapeActive = False; -+ } else { -+ appData.escapeActive = True; -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+/* -+ * ToggleNColors -+ */ -+ -+static Widget w256 = NULL; -+static Widget w64 = NULL; -+static Widget w8 = NULL; -+ -+void -+Toggle256Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ w256 = w; -+ if (appData.useBGR233 != 256) { -+ fprintf(stderr, "256 colors: on\n"); -+ init_format_change(); -+ last_ncolors = appDataNew.useBGR233 = 256; -+ save_useBGR565 = appData.useBGR565; -+ appDataNew.useBGR565 = False; -+ schedule_format_change(); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+Toggle64Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ w64 = w; -+ if (appData.useBGR233 != 64) { -+ fprintf(stderr, "64 colors: on\n"); -+ init_format_change(); -+ last_ncolors = appDataNew.useBGR233 = 64; -+ save_useBGR565 = appData.useBGR565; -+ appDataNew.useBGR565 = False; -+ schedule_format_change(); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+Toggle8Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ w8 = w; -+ if (appData.useBGR233 != 8) { -+ fprintf(stderr, "8 colors: on\n"); -+ init_format_change(); -+ last_ncolors = appDataNew.useBGR233 = 8; -+ save_useBGR565 = appData.useBGR565; -+ appDataNew.useBGR565 = False; -+ schedule_format_change(); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleGreyScale(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ fprintf(stderr, "ToggleGreyScale\n"); -+ init_format_change(); -+ if (appData.useGreyScale) { -+ appDataNew.useGreyScale = False; -+ fprintf(stderr, "greyscale: off\n"); -+ } else { -+ appDataNew.useGreyScale = True; -+ fprintf(stderr, "greyscale: on\n"); -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+/* -+ * ToggleJPEG -+ */ -+ -+void -+ToggleJPEG(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ init_format_change(); -+ if (appData.enableJPEG) { -+ appDataNew.enableJPEG = False; -+ fprintf(stderr, "JPEG: off\n"); -+ } else { -+ appDataNew.enableJPEG = True; -+ fprintf(stderr, "JPEG: on\n"); -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+/* -+ * ToggleTightZRLE -+ */ -+ -+static Bool usingZRLE = False; -+static Bool usingZYWRLE = False; -+static Bool usingHextile = False; -+extern int skip_maybe_sync; -+ -+void -+ToggleTightZRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char prefTight[] = "copyrect tight zrle zywrle zlib hextile corre rre raw"; -+ char prefZRLE[] = "copyrect zrle zywrle tight zlib hextile corre rre raw"; -+ init_format_change(); -+ usingHextile = False; -+ if (! appData.encodingsString) { -+ appDataNew.encodingsString = strdup(prefZRLE); -+ usingZRLE = True; -+ fprintf(stderr, "prefer: ZRLE\n"); -+ } else { -+ char *t, *z; -+ static int first = 1; -+ t = strstr(appData.encodingsString, "tight"); -+ z = strstr(appData.encodingsString, "zrle"); -+ if (first && usingZRLE) { -+ appDataNew.encodingsString = strdup(prefTight); -+ usingZRLE = False; -+ usingZYWRLE = False; -+ } else if (! t) { -+ appDataNew.encodingsString = strdup(prefZRLE); -+ usingZRLE = True; -+ fprintf(stderr, "prefer: ZRLE\n"); -+ } else if (! z) { -+ appDataNew.encodingsString = strdup(prefTight); -+ usingZRLE = False; -+ usingZYWRLE = False; -+ skip_maybe_sync = 0; -+ fprintf(stderr, "prefer: Tight\n"); -+ } else { -+ if (t < z) { -+ appDataNew.encodingsString = strdup(prefZRLE); -+ usingZRLE = True; -+ fprintf(stderr, "prefer: ZRLE\n"); -+ } else { -+ appDataNew.encodingsString = strdup(prefTight); -+ usingZRLE = False; -+ usingZYWRLE = False; -+ skip_maybe_sync = 0; -+ fprintf(stderr, "prefer: Tight\n"); -+ } -+ } -+ first = 0; -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleZRLEZYWRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char prefZYWRLE[] = "copyrect zywrle zrle tight zlib hextile corre rre raw"; -+ char prefZRLE[] = "copyrect zrle zywrle tight zlib hextile corre rre raw"; -+ init_format_change(); -+ usingZRLE = True; -+ usingHextile = False; -+ if (! appData.encodingsString) { -+ appDataNew.encodingsString = strdup(prefZYWRLE); -+ usingZYWRLE = True; -+ fprintf(stderr, "prefer: ZYWRLE\n"); -+ } else { -+ char *z, *w; -+ w = strstr(appData.encodingsString, "zywrle"); -+ z = strstr(appData.encodingsString, "zrle"); -+ if (usingZYWRLE) { -+ appDataNew.encodingsString = strdup(prefZRLE); -+ fprintf(stderr, "prefer: ZRLE\n"); -+ usingZYWRLE = False; -+ skip_maybe_sync = 0; -+ } else { -+ appDataNew.encodingsString = strdup(prefZYWRLE); -+ fprintf(stderr, "prefer: ZYWRLE\n"); -+ usingZYWRLE = True; -+ } -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleTightHextile(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char prefTight[] = "copyrect tight zrle zywrle zlib hextile corre rre raw"; -+ char prefHextile[] = "copyrect hextile tight zrle zywrle zlib corre rre raw"; -+ init_format_change(); -+ usingZRLE = False; -+ usingZYWRLE = False; -+ if (! appData.encodingsString) { -+ appDataNew.encodingsString = strdup(prefHextile); -+ usingHextile = True; -+ fprintf(stderr, "prefer: Hextile\n"); -+ } else { -+ char *t, *z; -+ static int first = 1; -+ t = strstr(appData.encodingsString, "tight"); -+ z = strstr(appData.encodingsString, "hextile"); -+ if (first && usingHextile) { -+ appDataNew.encodingsString = strdup(prefTight); -+ usingHextile = False; -+ } else if (! t) { -+ appDataNew.encodingsString = strdup(prefHextile); -+ usingHextile = True; -+ fprintf(stderr, "prefer: Hextile\n"); -+ } else if (! z) { -+ appDataNew.encodingsString = strdup(prefTight); -+ usingHextile = False; -+ skip_maybe_sync = 0; -+ fprintf(stderr, "prefer: Tight\n"); -+ } else { -+ if (t < z) { -+ appDataNew.encodingsString = strdup(prefHextile); -+ usingHextile = True; -+ fprintf(stderr, "prefer: Hextile\n"); -+ } else { -+ appDataNew.encodingsString = strdup(prefTight); -+ usingHextile = False; -+ skip_maybe_sync = 0; -+ fprintf(stderr, "prefer: Tight\n"); -+ } -+ } -+ first = 0; -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+void scale_check_zrle(void) { -+ static int didit = 0; -+ if (didit) { -+ return; -+ } -+ didit = 1; -+ if (getenv("SSVNC_PRESERVE_ENCODING")) { -+ return; -+ } -+ if (!usingZRLE && !usingHextile) { -+ Widget w = 0; -+ fprintf(stderr, "\nSwitching to faster ZRLE encoding in client-side scaling mode.\n"); -+ fprintf(stderr, "Switch back to Tight via the Popup menu if you prefer it.\n\n"); -+ ToggleTightZRLE(w, NULL, NULL, NULL); -+ } -+} -+ -+/* -+ * ToggleViewOnly -+ */ -+ -+void -+ToggleViewOnly(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.viewOnly) { -+ appData.viewOnly = False; -+ fprintf(stderr, "viewonly: off\n"); -+ } else { -+ appData.viewOnly = True; -+ fprintf(stderr, "viewonly: on\n"); -+ } -+ Xcursors(1); -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleCursorShape(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ init_format_change(); -+ if (appData.useRemoteCursor) { -+ appDataNew.useRemoteCursor = False; -+ fprintf(stderr, "useRemoteCursor: off\n"); -+ } else { -+ appDataNew.useRemoteCursor = True; -+ fprintf(stderr, "useRemoteCursor: on\n"); -+ } -+ schedule_format_change(); -+ if (!appDataNew.useRemoteCursor) { -+ do_cursor_change = 1; -+ } else { -+ do_cursor_change = -1; -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleCursorAlpha(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useCursorAlpha) { -+ appData.useCursorAlpha = False; -+ fprintf(stderr, "useCursorAlpha: off\n"); -+ } else { -+ appData.useCursorAlpha = True; -+ fprintf(stderr, "useCursorAlpha: on\n"); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleX11Cursor(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ init_format_change(); -+ if (appData.useX11Cursor) { -+ appDataNew.useX11Cursor = False; -+ fprintf(stderr, "useX11Cursor: off\n"); -+ } else { -+ appDataNew.useX11Cursor = True; -+ fprintf(stderr, "useX11Cursor: on\n"); -+ } -+ schedule_format_change(); -+ do_cursor_change = 1; -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleBell(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useBell) { -+ appData.useBell = False; -+ fprintf(stderr, "useBell: off\n"); -+ } else { -+ appData.useBell = True; -+ fprintf(stderr, "useBell: on\n"); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleRawLocal(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ init_format_change(); -+ if (appData.useRawLocal) { -+ appDataNew.useRawLocal = False; -+ fprintf(stderr, "useRawLocal: off\n"); -+ } else { -+ appDataNew.useRawLocal = True; -+ fprintf(stderr, "useRawLocal: on\n"); -+ } -+ schedule_format_change(); -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleServerInput(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.serverInput) { -+ appData.serverInput= False; -+ fprintf(stderr, "serverInput: off\n"); -+ SendServerInput(True); -+ } else { -+ appData.serverInput = True; -+ fprintf(stderr, "serverInput: on\n"); -+ SendServerInput(False); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+TogglePipelineUpdates(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.pipelineUpdates) { -+ appData.pipelineUpdates= False; -+ fprintf(stderr, "pipeline-update: off\n"); -+ } else { -+ appData.pipelineUpdates = True; -+ fprintf(stderr, "pipeline-update: on\n"); -+ } -+ /* XXX request one to be sure? */ -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleSendClipboard(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.sendClipboard) { -+ appData.sendClipboard= False; -+ fprintf(stderr, "Send CLIPBOARD Selection: off (send PRIMARY instead)\n"); -+ } else { -+ appData.sendClipboard = True; -+ fprintf(stderr, "Send CLIPBOARD Selection: on (do not send PRIMARY)\n"); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+ToggleSendAlways(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.sendAlways) { -+ appData.sendAlways= False; -+ fprintf(stderr, "Send Selection Always: off\n"); -+ } else { -+ appData.sendAlways = True; -+ fprintf(stderr, "Send Selection Always: on\n"); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+ -+Bool _sw1_ = False; /* XXX this is a weird bug... */ -+Bool _sw2_ = False; -+Bool _sw3_ = False; -+Bool selectingSingleWindow = False; -+ -+extern Cursor bogoCursor; -+ -+void -+ToggleSingleWindow(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.singleWindow) { -+ appData.singleWindow= False; -+ fprintf(stderr, "singleWindow: off\n"); -+ SendSingleWindow(-1, -1); -+ } else { -+ appData.singleWindow = True; -+ selectingSingleWindow = True; -+ fprintf(stderr, "singleWindow: on\n"); -+ if (bogoCursor != None) { -+ XDefineCursor(dpy, desktopWin, bogoCursor); -+ } -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void raiseme(int force); -+void AppendChatInput(char *); -+ -+extern void ShowChat(Widget w, XEvent *event, String *params, Cardinal *num_params); -+extern void ShowFile(Widget w, XEvent *event, String *params, Cardinal *num_params); -+extern Bool SendTextChatFinished(void); -+ -+ -+void printChat(char *str, Bool raise) { -+ if (appData.termChat) { -+ if (raise) { -+ raiseme(0); -+ } -+ fprintf(stderr, str); -+ } else { -+ if (raise) { -+ ShowChat(0, 0, 0, 0); -+ } -+ AppendChatInput(str); -+ } -+} -+ -+void -+ToggleTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.chatActive) { -+ printChat("\n*SentClose*\n\n", False); -+ SendTextChatClose(); -+ SendTextChatFinished(); -+ HideChat(0, NULL, NULL, NULL); -+ appData.chatActive= False; -+ } else { -+ ShowChat(0, 0, 0, 0); -+ SendTextChatOpen(); -+ if (appData.termChat) { -+ printChat("\n*SentOpen*\n\nSend: ", True); -+ } else { -+ printChat("\n*SentOpen*\n", True); -+ } -+ appData.chatActive = True; -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+extern int filexfer_sock; -+extern pid_t java_helper; -+#define KILLJAVA -+#ifdef KILLJAVA -+#include <signal.h> -+#endif -+ -+void -+ToggleFileXfer(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ static double last_start = 0.0; -+ if (appData.fileActive) { -+#if 0 -+ HideFile(w, ev, params, num_params); -+ appData.fileActive = False; -+#endif -+#ifndef KILLJAVA -+ if (filexfer_sock >= 0) { -+ close(filexfer_sock); -+ } -+#else -+ if (java_helper != 0) { -+ int i; -+ if (dnow() < last_start + 6.0) { -+ fprintf(stderr, "skipping early kill of java helper (less than 5 secs)\n"); -+ } else { -+ for (i=1; i<=5; i++) { -+ pid_t p = java_helper + i; -+ fprintf(stderr, "trying to kill java helper: %d\n", p); -+ if (kill(p, SIGTERM) == 0) { -+ java_helper = 0; -+ break; -+ } -+ } -+ } -+ } -+#endif -+ } else { -+ ShowFile(w, ev, params, num_params); -+ appData.fileActive = True; -+ last_start = dnow(); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+static int fooHandler(Display *dpy, XErrorEvent *error) { -+ if (dpy || error) {} -+ return 0; -+} -+ -+void raiseme(int force) { -+ if ((force || appData.termChat) && getenv("WINDOWID")) { -+ unsigned long w; -+ if (sscanf(getenv("WINDOWID"), "%lu", &w) == 1) { -+ ; -+ } else if (sscanf(getenv("WINDOWID"), "0x%lx", &w) == 1) { -+ ; -+ } else { -+ w = 0; -+ } -+ if (w != 0) { -+ XErrorHandler old = XSetErrorHandler(fooHandler); -+ XMapRaised(dpy, (Window) w); -+ XSync(dpy, False); -+ XSetErrorHandler(old); -+ } -+ } -+} -+ -+void set_server_scale(int n) { -+ if (n >= 1 && n < 100) { -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+ appData.serverScale = n; -+ SendServerScale(n); -+ if (0) SendFramebufferUpdateRequest(0, 0, w, h, False); -+ schedule_fb_update(); -+ } -+} -+ -+void -+DoServerScale(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char str[100], *s, *q; -+ int n; -+ if (1) { -+ s = DoScaleNDialog(); -+ } else { -+ raiseme(1); -+ fprintf(stderr, "\n\n\a\nEnter integer n for 1/n server scaling: "); -+ str[0] = '\0'; -+ fgets(str, 100, stdin); -+ s = str; -+ q = strstr(str, "\n"); -+ if (q) *q = '\0'; -+ } -+ if (s[0] != '\0') { -+ n = atoi(s); -+ set_server_scale(n); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void set_server_quality(int n) { -+ fprintf(stderr, "set_quality: %d\n", n); -+ if (n >= 0 && n <= 9) { -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+ init_format_change(); -+ appDataNew.qualityLevel = n; -+ SendFramebufferUpdateRequest(0, 0, w, h, False); -+ schedule_format_change(); -+ } -+} -+ -+void -+DoServerQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char str[100], *s, *q; -+ int n; -+ if (1) { -+ s = DoQualityDialog(); -+ } else { -+ raiseme(1); -+ fprintf(stderr, "\n\n\a\nEnter integer 1 <= n <= 9 for quality setting: "); -+ str[0] = '\0'; -+ fgets(str, 100, stdin); -+ s = str; -+ q = strstr(str, "\n"); -+ if (q) *q = '\0'; -+ } -+ if (s[0] != '\0') { -+ n = atoi(s); -+ set_server_quality(n); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void set_server_compress(int n) { -+ fprintf(stderr, "set_compress: %d\n", n); -+ if (n >= 0 && n <= 9) { -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+ init_format_change(); -+ appDataNew.compressLevel = n; -+ SendFramebufferUpdateRequest(0, 0, w, h, False); -+ schedule_format_change(); -+ } -+} -+ -+void -+DoServerCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char str[100], *s, *q; -+ int n; -+ if (1) { -+ s = DoCompressDialog(); -+ } else { -+ raiseme(1); -+ fprintf(stderr, "\n\n\a\nEnter integer 1 <= n <= 9 for compress level setting: "); -+ str[0] = '\0'; -+ fgets(str, 100, stdin); -+ s = str; -+ q = strstr(str, "\n"); -+ if (q) *q = '\0'; -+ } -+ if (s[0] != '\0') { -+ n = atoi(s); -+ set_server_compress(n); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+extern void rescale_image(void); -+extern void get_scale_values(double *fx, double *fy); -+ -+void -+SetScale(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char *s; -+ s = DoScaleDialog(); -+ if (s[0] != '\0') { -+#if 0 -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+#endif -+ double fx, fy; -+ int fs = 0; -+ if (appData.scale != NULL && !strcmp(s, appData.scale)) { -+ return; -+ } -+ -+ if (!strcasecmp(s, "none")) { -+ appData.scale = NULL; -+ } else if (!strcmp(s, "1.0")) { -+ appData.scale = NULL; -+ } else if (!strcmp(s, "1")) { -+ appData.scale = NULL; -+ } else { -+ appData.scale = strdup(s); -+ } -+ if (appData.scale != NULL) { -+ get_scale_values(&fx, &fy); -+ if (fx <= 0.0 || fy <= 0.0) { -+ appData.scale = NULL; -+ return; -+ } -+ } -+ -+ if (appData.fullScreen) { -+ fs = 1; -+ FullScreenOff(); -+ } -+ rescale_image(); -+ if (fs) { -+ FullScreenOn(); -+ } -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetEscapeKeys(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char *s; -+ s = DoEscapeKeysDialog(); -+ fprintf(stderr, "set escape keys: '%s'\n", s); -+ if (s[0] != '\0') { -+ appData.escapeKeys = strdup(s); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void set_ycrop(int n) { -+ if (n >= 1) { -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+ appData.yCrop = n; -+ ReDoDesktop(); -+ SendFramebufferUpdateRequest(0, 0, w, h, False); -+ schedule_fb_update(); -+ } -+} - -- Cleanup(); -+void -+SetYCrop(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char str[100], *q, *s; -+ int n; -+ if (1) { -+ s = DoYCropDialog(); -+ } else { -+ raiseme(1); -+ fprintf(stderr, "\n\n\a\nEnter pixel size n -ycrop maximum y-height: "); -+ str[0] = '\0'; -+ fgets(str, 100, stdin); -+ s = str; -+ q = strstr(str, "\n"); -+ if (q) *q = '\0'; -+ } -+ if (s[0] != '\0') { -+ n = atoi(s); -+ set_ycrop(n); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void set_scbar(int n) { -+ if (n >= 1) { -+ int w = si.framebufferWidth; -+ int h = si.framebufferHeight; -+fprintf(stderr, "set_scbat: %d\n", n); -+ appData.sbWidth = n; -+ ReDoDesktop(); -+ SendFramebufferUpdateRequest(0, 0, w, h, False); -+ schedule_fb_update(); -+ } -+} -+ -+void -+SetScbar(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ char str[100], *q, *s; -+ int n; -+ if (1) { -+ s = DoScbarDialog(); -+ } else { -+ raiseme(1); -+ fprintf(stderr, "\n\n\a\nEnter pixel size n scrollbar width: "); -+ str[0] = '\0'; -+ fgets(str, 100, stdin); -+ s = str; -+ q = strstr(str, "\n"); -+ if (q) *q = '\0'; -+ } -+ if (s[0] != '\0') { -+ n = atoi(s); -+ set_scbar(n); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (*num_params != 0) { -+ int n = atoi(params[0]); -+ set_server_scale(n); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void UpdateQual(void) { -+ SetFormatAndEncodings(); -+ UpdateSubsampButtons(); -+ UpdateQualSlider(); -+} -+ -+extern double latency; -+ -+static void LosslessRefresh(void) { -+ String encodings = appData.encodingsString; -+ int compressLevel = appData.compressLevel; -+ int qual = appData.qualityLevel; -+ Bool enableJPEG = appData.enableJPEG; -+ appData.qualityLevel = -1; -+ appData.enableJPEG = False; -+ appData.encodingsString = "tight copyrect"; -+ appData.compressLevel = 1; -+ SetFormatAndEncodings(); -+ SendFramebufferUpdateRequest(0, 0, si.framebufferWidth, si.framebufferHeight, False); -+ if (latency > 0.0) { -+ if (0) usleep((int) latency * 1000); -+ } -+ appData.qualityLevel = qual; -+ appData.enableJPEG = enableJPEG; -+ appData.encodingsString = encodings; -+ appData.compressLevel = compressLevel; -+ SetFormatAndEncodings(); -+} -+ -+static void QualHigh(void) { -+ appData.encodingsString = "tight copyrect"; -+ if(appData.useBGR233 || appDataNew.useBGR565) { -+ fprintf(stderr, "WARNING: Cannot enable JPEG because BGR233/BGR565 is enabled.\n"); -+ } else { -+ appData.enableJPEG = True; -+ } -+ appData.subsampLevel = TVNC_1X; -+ appData.qualityLevel = 95; -+ UpdateQual(); -+} -+ -+static void QualMed(void) { -+ appData.encodingsString = "tight copyrect"; -+ if(appData.useBGR233 || appDataNew.useBGR565) { -+ fprintf(stderr, "WARNING: Cannot enable JPEG because BGR233/BGR565 is enabled.\n"); -+ } else { -+ appData.enableJPEG = True; -+ } -+ appData.subsampLevel = TVNC_2X; -+ appData.qualityLevel = 80; -+ UpdateQual(); -+} -+ -+static void QualLow(void) { -+ appData.encodingsString = "tight copyrect"; -+ if(appData.useBGR233 || appDataNew.useBGR565) { -+ fprintf(stderr, "WARNING: Cannot enable JPEG because BGR233/BGR565 is enabled.\n"); -+ } else { -+ appData.enableJPEG = True; -+ } -+ appData.subsampLevel = TVNC_4X; -+ appData.qualityLevel = 30; -+ UpdateQual(); -+} -+ -+static void QualLossless(void) { -+ appData.encodingsString = "tight copyrect"; -+ appData.enableJPEG = False; -+ appData.compressLevel = 0; -+ UpdateQual(); -+} - -- return 0; -+static void QualLosslessWAN(void) { -+ appData.encodingsString = "tight copyrect"; -+ appData.enableJPEG = False; -+ appData.compressLevel = 1; -+ UpdateQual(); -+} -+ -+void -+SetTurboVNC(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (*num_params != 0) { -+ int n = atoi(params[0]); -+ if (0) fprintf(stderr, "SetTurboVNC: %d\n", n); -+ if (n == 1) { -+ QualHigh(); -+ } else if (n == 2) { -+ QualMed(); -+ } else if (n == 3) { -+ QualLow(); -+ } else if (n == 4) { -+ QualLossless(); -+ } else if (n == 5) { -+ QualLosslessWAN(); -+ } else if (n == 6) { -+ appData.subsampLevel = TVNC_1X; -+ UpdateQual(); -+ } else if (n == 7) { -+ appData.subsampLevel = TVNC_2X; -+ UpdateQual(); -+ } else if (n == 8) { -+ appData.subsampLevel = TVNC_4X; -+ UpdateQual(); -+ } else if (n == 9) { -+ appData.subsampLevel = TVNC_GRAY; -+ UpdateQual(); -+ } else if (n == 10) { -+ LosslessRefresh(); -+ } -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (*num_params != 0) { -+ int n = atoi(params[0]); -+ set_server_quality(n); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (*num_params != 0) { -+ int n = atoi(params[0]); -+ set_server_compress(n); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+GotChatText(char *str, int len) -+{ -+ static char *b = NULL; -+ static int blen = -1; -+ int i, k; -+ if (appData.termChat) { -+ printChat("\nChat: ", True); -+ } else { -+ printChat("Chat: ", True); -+ } -+ -+ if (len < 0) len = 0; -+ -+ if (blen < len+1) { -+ if (b) free(b); -+ blen = 2 * (len + 10); -+ b = (char *) malloc(blen); -+ } -+ -+ k = 0; -+ for (i=0; i < len; i++) { -+ if (str[i] != '\r') { -+ b[k++] = str[i]; -+ } -+ } -+ b[k] = '\0'; -+ b[len] = '\0'; -+ printChat(b, True); -+ -+ if (appData.termChat) { -+ if (strstr(str, "\n")) { -+ printChat("Send: ", True); -+ } else { -+ printChat("\nSend: ", True); -+ } -+ } -+} -+ -+void -+SetViewOnlyState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.viewOnly) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetNOJPEGState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.enableJPEG) { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetQualityState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (*num_params != 0) { -+ int n = atoi(params[0]); -+ if (appData.qualityLevel == n) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetCompressState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (*num_params != 0) { -+ int n = atoi(params[0]); -+ if (appData.compressLevel == n) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetScaleNState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (*num_params != 0) { -+ int n = atoi(params[0]); -+ if (appData.serverScale == n || (appData.serverScale >= 6 && n >= 6)) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+Set8bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useBGR233) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ if (b16 != NULL) { -+ XtVaSetValues(b16, XtNstate, False, NULL); -+ } -+ if (bfull != NULL) { -+ XtVaSetValues(bfull, XtNstate, False, NULL); -+ } -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+Set16bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useBGR565) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ if (b8 != NULL) { -+ XtVaSetValues(b8, XtNstate, False, NULL); -+ } -+ if (bfull != NULL) { -+ XtVaSetValues(bfull, XtNstate, False, NULL); -+ } -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetFullColorState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useBGR565 || appData.useBGR233) { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ if (b8 != NULL) { -+ XtVaSetValues(b8, XtNstate, False, NULL); -+ } -+ if (b16 != NULL) { -+ XtVaSetValues(b16, XtNstate, False, NULL); -+ } -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetXGrabState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.grabAll) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetEscapeKeysState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.escapeActive) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+Set256ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useBGR233 == 256) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ if (w64 != NULL) { -+ XtVaSetValues(w64 , XtNstate, False, NULL); -+ } -+ if (w8 != NULL) { -+ XtVaSetValues(w8 , XtNstate, False, NULL); -+ } -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+Set64ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useBGR233 == 64) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ if (w256 != NULL) { -+ XtVaSetValues(w256, XtNstate, False, NULL); -+ } -+ if (w8 != NULL) { -+ XtVaSetValues(w8 , XtNstate, False, NULL); -+ } -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+Set8ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useBGR233 == 8) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ if (w256 != NULL) { -+ XtVaSetValues(w256, XtNstate, False, NULL); -+ } -+ if (w64 != NULL) { -+ XtVaSetValues(w64 , XtNstate, False, NULL); -+ } -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetGreyScaleState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useGreyScale) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+static void init_state(void) { -+ static int first = 1; -+ if (first && appData.encodingsString) { -+ char *t, *z, *y, *h; -+ char *str = appData.encodingsString; -+ int len = strlen(str); -+ -+ t = strstr(str, "tight"); -+ z = strstr(str, "zrle"); -+ y = strstr(str, "zywrle"); -+ h = strstr(str, "hextile"); -+ -+ if (!t) t = str + len; -+ if (!z) z = str + len; -+ if (!y) y = str + len; -+ if (!h) h = str + len; -+ -+ usingZRLE = False; -+ usingZYWRLE = False; -+ usingHextile = False; -+ -+ if (t < z && t < y && t < h) { -+ ; -+ } else if (z < t && z < y && z < h) { -+ usingZRLE = True; -+ } else if (y < t && y < z && y < h) { -+ usingZYWRLE = True; -+ usingZRLE = True; -+ } else if (h < t && h < z && h < y) { -+ usingHextile = True; -+ } -+ } -+ first = 0; -+ -+} -+ -+void -+SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ init_state(); -+ if (usingZRLE) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetHextileState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ init_state(); -+ if (usingHextile) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetZYWRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ init_state(); -+ if (usingZYWRLE) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetCursorShapeState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useRemoteCursor) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetCursorAlphaState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useCursorAlpha) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetX11CursorState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useX11Cursor) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetBellState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useBell) { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetRawLocalState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.useRawLocal) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetServerInputState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (!appData.serverInput) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetPipelineUpdates(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (!appData.pipelineUpdates) { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetSendClipboard(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (!appData.sendClipboard) { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetSendAlways(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (!appData.sendAlways) { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetSingleWindowState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.singleWindow) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.chatActive) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} -+} -+ -+void -+SetFileXferState(Widget w, XEvent *ev, String *params, Cardinal *num_params) -+{ -+ if (appData.fileActive) { -+ XtVaSetValues(w, XtNstate, True, NULL); -+ } else { -+ XtVaSetValues(w, XtNstate, False, NULL); -+ } -+ if (w || ev || params || num_params) {} - } -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.h vnc_unixsrc/vncviewer/vncviewer.h ---- vnc_unixsrc.orig/vncviewer/vncviewer.h 2004-03-11 13:14:40.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer.h 2010-04-17 22:29:42.000000000 -0400 -@@ -28,6 +28,7 @@ - #include <string.h> - #include <sys/time.h> - #include <sys/types.h> -+#include <sys/stat.h> - #include <unistd.h> - #include <pwd.h> - #include <X11/IntrinsicP.h> -@@ -51,7 +52,13 @@ - (((l) & 0x0000ff00) << 8) | \ - (((l) & 0x000000ff) << 24)) : (l)) - --#define MAX_ENCODINGS 20 -+#define Swap32IfBE(l) \ -+ (*(char *)&endianTest ? (l) : ((((l) & 0xff000000) >> 24) | \ -+ (((l) & 0x00ff0000) >> 8) | \ -+ (((l) & 0x0000ff00) << 8) | \ -+ (((l) & 0x000000ff) << 24)) ) -+ -+#define MAX_ENCODINGS 24 - - #define FLASH_PORT_OFFSET 5400 - #define LISTEN_PORT_OFFSET 5500 -@@ -64,60 +71,133 @@ - #define DEFAULT_VIA_CMD \ - (DEFAULT_SSH_CMD " -f -L %L:%H:%R %G sleep 20") - -+#define TVNC_SAMPOPT 4 -+enum {TVNC_1X=0, TVNC_4X, TVNC_2X, TVNC_GRAY}; - --/* argsresources.c */ -- --typedef struct { -- Bool shareDesktop; -- Bool viewOnly; -- Bool fullScreen; -- Bool grabKeyboard; -- Bool raiseOnBeep; -- -- String encodingsString; -- -- Bool useBGR233; -- int nColours; -- Bool useSharedColours; -- Bool forceOwnCmap; -- Bool forceTrueColour; -- int requestedDepth; -- -- Bool useShm; -- -- int wmDecorationWidth; -- int wmDecorationHeight; -- -- char *userLogin; -- -- char *passwordFile; -- Bool passwordDialog; -- -- int rawDelay; -- int copyRectDelay; -+#if 0 -+static const char *subsampLevel2str[TVNC_SAMPOPT] = { -+ "1X", "4X", "2X", "Gray" -+}; -+#endif -+#ifdef TURBOVNC -+#define rfbTightNoZlib 0x0A -+#define rfbTurboVncVendor "TRBO" -+#define rfbJpegQualityLevel1 0xFFFFFE01 -+#define rfbJpegQualityLevel100 0xFFFFFE64 -+#define rfbJpegSubsamp1X 0xFFFFFD00 -+#define rfbJpegSubsamp4X 0xFFFFFD01 -+#define rfbJpegSubsamp2X 0xFFFFFD02 -+#define rfbJpegSubsampGray 0xFFFFFD03 -+#endif -+ -+/* for debugging width, height, etc */ -+#if 0 -+#define XtVaSetValues printf("%s:%d\n", __FILE__, __LINE__); XtVaSetValues -+#endif - -- Bool debug; - -- int popupButtonCount; -+/* argsresources.c */ - -- int bumpScrollTime; -- int bumpScrollPixels; -+typedef struct { -+ Bool shareDesktop; -+ Bool viewOnly; -+ Bool fullScreen; -+ Bool grabKeyboard; -+ Bool raiseOnBeep; -+ -+ String encodingsString; -+ -+ int useBGR233; -+ int nColours; -+ Bool useSharedColours; -+ Bool forceOwnCmap; -+ Bool forceTrueColour; -+ int requestedDepth; -+ Bool useBGR565; -+ Bool useGreyScale; -+ -+ Bool grabAll; -+ Bool useXserverBackingStore; -+ Bool overrideRedir; -+ Bool popupFix; -+ -+ Bool useShm; -+ Bool termChat; -+ -+ int wmDecorationWidth; -+ int wmDecorationHeight; -+ -+ char *userLogin; -+ char *unixPW; -+ char *msLogon; -+ char *repeaterUltra; -+ Bool ultraDSM; -+ Bool acceptPopup; -+ char *rfbVersion; -+ -+ char *passwordFile; -+ Bool passwordDialog; -+ Bool notty; -+ -+ int rawDelay; -+ int copyRectDelay; -+ -+ int yCrop; -+ int sbWidth; -+ Bool useCursorAlpha; -+ Bool useRawLocal; -+ -+ Bool debug; -+ -+ int popupButtonCount; -+ int popupButtonBreak; -+ -+ int bumpScrollTime; -+ int bumpScrollPixels; -+ -+ int compressLevel; -+ int qualityLevel; -+ Bool enableJPEG; -+ Bool useRemoteCursor; -+ Bool useX11Cursor; -+ Bool useBell; -+ Bool autoPass; -+ -+ Bool serverInput; -+ Bool singleWindow; -+ int serverScale; -+ Bool chatActive; -+ Bool chatOnly; -+ Bool fileActive; -+ -+ char *scale; -+ char *escapeKeys; -+ Bool appShare; -+ Bool escapeActive; -+ Bool pipelineUpdates; -+ -+ Bool sendClipboard; -+ Bool sendAlways; -+ char *recvText; -+ -+ /* only for turbovnc mode */ -+ String subsampString; -+ int subsampLevel; -+ Bool doubleBuffer; - -- int compressLevel; -- int qualityLevel; -- Bool enableJPEG; -- Bool useRemoteCursor; -- Bool useX11Cursor; -- Bool autoPass; -+ Bool noipv4; -+ Bool noipv6; - - } AppData; - - extern AppData appData; -+extern AppData appDataNew; - - extern char *fallback_resources[]; - extern char vncServerHost[]; - extern int vncServerPort; - extern Bool listenSpecified; -+extern pid_t listenParent; - extern int listenPort, flashPort; - - extern XrmOptionDescRec cmdLineOptions[]; -@@ -130,10 +210,11 @@ - /* colour.c */ - - extern unsigned long BGR233ToPixel[]; -+extern unsigned long BGR565ToPixel[]; - - extern Colormap cmap; - extern Visual *vis; --extern unsigned int visdepth, visbpp; -+extern unsigned int visdepth, visbpp, isLSB; - - extern void SetVisualAndCmap(); - -@@ -155,15 +236,60 @@ - extern GC srcGC, dstGC; - extern Dimension dpyWidth, dpyHeight; - -+extern int appshare_0_hint; -+extern int appshare_x_hint; -+extern int appshare_y_hint; -+ - extern void DesktopInitBeforeRealization(); - extern void DesktopInitAfterRealization(); -+extern void Xcursors(int set); - extern void SendRFBEvent(Widget w, XEvent *event, String *params, - Cardinal *num_params); - extern void CopyDataToScreen(char *buf, int x, int y, int width, int height); -+extern void FillScreen(int x, int y, int width, int height, unsigned long fill); - extern void SynchroniseScreen(); - -+extern void ReDoDesktop(); -+extern void DesktopCursorOff(); -+extern void put_image(int x1, int y1, int x2, int y2, int width, int height, int solid); -+extern void copy_rect(int x, int y, int width, int height, int src_x, int src_y); -+ -+extern void releaseAllPressedModifiers(void); -+extern void fs_grab(int check); -+extern void fs_ungrab(int check); -+ - /* dialogs.c */ - -+extern int use_tty(void); -+ -+extern void ScaleDialogDone(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern char *DoScaleDialog(); -+ -+extern void EscapeDialogDone(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern char *DoEscapeKeysDialog(); -+ -+extern void YCropDialogDone(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern char *DoYCropDialog(); -+ -+extern void ScbarDialogDone(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern char *DoScbarDialog(); -+ -+extern void ScaleNDialogDone(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern char *DoScaleNDialog(); -+ -+extern void QualityDialogDone(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern char *DoQualityDialog(); -+ -+extern void CompressDialogDone(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern char *DoCompressDialog(); -+ - extern void ServerDialogDone(Widget w, XEvent *event, String *params, - Cardinal *num_params); - extern char *DoServerDialog(); -@@ -171,6 +297,10 @@ - Cardinal *num_params); - extern char *DoPasswordDialog(); - -+extern void UserDialogDone(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern char *DoUserDialog(); -+ - /* fullscreen.c */ - - extern void ToggleFullScreen(Widget w, XEvent *event, String *params, -@@ -181,6 +311,13 @@ - extern void FullScreenOn(); - extern void FullScreenOff(); - -+extern int net_wm_supported(void); -+ -+extern void JumpLeft(Widget w, XEvent *event, String *params, Cardinal *num_params); -+extern void JumpRight(Widget w, XEvent *event, String *params, Cardinal *num_params); -+extern void JumpUp(Widget w, XEvent *event, String *params, Cardinal *num_params); -+extern void JumpDown(Widget w, XEvent *event, String *params, Cardinal *num_params); -+ - /* listen.c */ - - extern void listenForIncomingConnections(); -@@ -196,6 +333,8 @@ - Cardinal *num_params); - extern void Quit(Widget w, XEvent *event, String *params, - Cardinal *num_params); -+extern void HideChat(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); - extern void Cleanup(); - - /* popup.c */ -@@ -207,6 +346,29 @@ - Cardinal *num_params); - extern void CreatePopup(); - -+extern void HideScaleN(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern void CreateScaleN(); -+ -+extern void HideTurboVNC(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern void CreateTurboVNC(); -+extern void UpdateSubsampButtons(); -+extern void UpdateQualSlider(); -+extern void UpdateQual(); -+ -+extern void HideQuality(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern void CreateQuality(); -+ -+extern void HideCompress(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+extern void CreateCompress(); -+ -+extern void Noop(Widget w, XEvent *event, String *params, -+ Cardinal *num_params); -+ -+extern int CreateMsg(char *msg, int wait); - /* rfbproto.c */ - - extern int rfbsock; -@@ -229,8 +391,19 @@ - extern Bool SendClientCutText(char *str, int len); - extern Bool HandleRFBServerMessage(); - -+extern Bool SendServerInput(Bool enabled); -+extern Bool SendSingleWindow(int x, int y); -+extern Bool SendServerScale(int n); -+ -+extern Bool SendTextChat(char *str); -+extern Bool SendTextChatOpen(void); -+extern Bool SendTextChatClose(void); -+extern Bool SendTextChatFinish(void); -+ - extern void PrintPixelFormat(rfbPixelFormat *format); - -+extern double dnow(void); -+ - /* selection.c */ - - extern void InitialiseSelection(); -@@ -241,8 +414,10 @@ - - /* shm.c */ - --extern XImage *CreateShmImage(); -+extern XImage *CreateShmImage(int do_ycrop); - extern void ShmCleanup(); -+extern void ShmDetach(); -+extern Bool UsingShm(); - - /* sockets.c */ - -@@ -252,11 +427,19 @@ - extern Bool WriteExact(int sock, char *buf, int n); - extern int FindFreeTcpPort(void); - extern int ListenAtTcpPort(int port); --extern int ConnectToTcpAddr(unsigned int host, int port); -+extern int ListenAtTcpPort6(int port); -+extern int dotted_ip(char *host, int partial); -+extern int ConnectToTcpAddr(const char *hostname, int port); -+extern int ConnectToUnixSocket(char *file); - extern int AcceptTcpConnection(int listenSock); -+extern int AcceptTcpConnection6(int listenSock); - extern Bool SetNonBlocking(int sock); -+extern Bool SetNoDelay(int sock); -+extern Bool SocketPair(int fd[2]); - - extern int StringToIPAddr(const char *str, unsigned int *addr); -+extern char *get_peer_ip(int sock); -+extern char *ip2host(char *ip); - extern Bool SameMachine(int sock); - - /* tunnel.c */ -@@ -271,3 +454,82 @@ - extern XtAppContext appContext; - extern Display* dpy; - extern Widget toplevel; -+ -+extern void GotChatText(char *str, int len); -+extern void unixpw(char *instr, int vencrypt_plain); -+ -+extern void Toggle8bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Toggle16bpp(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleFullColor(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Toggle256Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Toggle64Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Toggle8Colors(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleGreyScale(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleTightZRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleTightHextile(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleZRLEZYWRLE(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleViewOnly(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleJPEG(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleCursorShape(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleCursorAlpha(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleX11Cursor(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleBell(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleRawLocal(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleServerInput(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void TogglePipelineUpdates(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleSendClipboard(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleSendAlways(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleSingleWindow(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleXGrab(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleEscapeActive(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetEscapeKeys(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void DoServerScale(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void DoServerQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void DoServerCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetScale(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetYCrop(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetScbar(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ShowScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ShowTurboVNC(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ShowQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ShowCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetScaleN(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetTurboVNC(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetQuality(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetCompress(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleFileXfer(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void ToggleTermTextChat(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+ -+extern void scale_check_zrle(void); -+ -+extern void SetViewOnlyState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetNOJPEGState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetScaleNState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetQualityState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetCompressState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Set8bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Set16bppState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetFullColorState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Set256ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Set64ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void Set8ColorsState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetGreyScaleState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetZRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetHextileState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetZYWRLEState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetCursorShapeState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetCursorAlphaState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetX11CursorState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetBellState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetRawLocalState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetServerInputState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetPipelineUpdates(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetSendClipboard(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetSendAlways(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetSingleWindowState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetTermTextChatState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetFileXferState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetXGrabState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -+extern void SetEscapeKeysState(Widget w, XEvent *ev, String *params, Cardinal *num_params); -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/vncviewer.man vnc_unixsrc/vncviewer/vncviewer.man ---- vnc_unixsrc.orig/vncviewer/vncviewer.man 2004-03-11 13:14:40.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer.man 2010-04-11 23:30:24.000000000 -0400 -@@ -5,38 +5,55 @@ - .\" Copyright (C) 1998 Marcus.Brinkmann@ruhr-uni-bochum.de - .\" Copyright (C) 2000,2001 Red Hat, Inc. - .\" Copyright (C) 2001-2003 Constantin Kaplinsky <const@ce.cctpu.edu.ru> -+.\" Copyright (C) 2006-2010 Karl J. Runge <runge@karlrunge.com> - .\" - .\" You may distribute under the terms of the GNU General Public - .\" License as specified in the file LICENCE.TXT that comes with the - .\" TightVNC distribution. - .\" --.TH vncviewer 1 "January 2003" "" "TightVNC" -+.TH ssvncviewer 1 "April 2010" "" "SSVNC" - .SH NAME --vncviewer \- an X viewer client for VNC -+ssvncviewer \- an X viewer client for VNC - .SH SYNOPSIS --.B vncviewer -+.B ssvncviewer - .RI [\| options \|] - .RI [\| host \|][\| :display \|] - .br --.B vncviewer -+.B ssvncviewer - .RI [\| options \|] - .RI [\| host \|][\| ::port \|] - .br --.B vncviewer -+.B ssvncviewer -+.RI [\| options \|] -+.RI exec=[\| cmd+args... \|] -+.br -+.B ssvncviewer -+.RI [\| options \|] -+.RI fd=n -+.br -+.B ssvncviewer -+.RI [\| options \|] -+.RI /path/to/unix/socket -+.br -+.B ssvncviewer - .RI [\| options \|] - .IR \-listen - .RI [\| display \|] - .br --.B vncviewer -+.B ssvncviewer - .IR \-help - .br - .SH DESCRIPTION --.B vncviewer -+.B ssvncviewer - is an Xt\-based client application for the VNC (Virtual Network - Computing) system. It can connect to any VNC\-compatible server such --as \fBXvnc\fR or WinVNC, allowing you to control desktop environment -+as \fBXvnc\fR, WinVNC, or \fBx11vnc\fR, allowing you to control desktop environment - of a different machine. - -+ssvncviewer is an enhanced version of the tightvnc unix viewer that can -+take advantage of features in the \fBx11vnc\fR and UltraVNC VNC servers. -+See below for the description of these features. -+ - You can use F8 to display a pop\-up utility menu. Press F8 twice to - pass single F8 to the remote side. - .SH OPTIONS -@@ -102,13 +119,13 @@ - TightVNC supports several different compression methods to encode - screen updates; this option specifies a set of them to use in order of - preference. Encodings are specified separated with spaces, and must --thus be enclosed in quotes if more than one is specified. Available --encodings, in default order for a remote connection, are "copyrect --tight hextile zlib corre rre raw". For a local connection (to the same --machine), the default order to try is "raw copyrect tight hextile zlib --corre rre". Raw encoding is always assumed as a last option if no --other encoding can be used for some reason. For more information on --encodings, see the section ENCODINGS below. -+thus be enclosed in quotes if more than one is specified. Commas may be used to avoid spaces. -+Available encodings, in default order for a remote connection, are -+"copyrect tight hextile zlib corre rre raw". For a local connection -+(to the same machine), the default order to try is "raw copyrect tight -+hextile zlib corre rre". Raw encoding is always assumed as a last option -+if no other encoding can be used for some reason. For more information -+on encodings, see the section ENCODINGS below. - .TP - \fB\-bgr233\fR - Always use the BGR233 format to encode pixel data. This reduces -@@ -168,6 +185,424 @@ - \fB\-autopass\fR - Read a plain-text password from stdin. This option affects only the - standard VNC authentication. -+ -+.SH Enhanced TightVNC Viewer (SSVNC) OPTIONS -+.TP -+Enhanced TightVNC Viewer (SSVNC) web page is located at: -+.TP -+http://www.karlrunge.com/x11vnc/ssvnc.html -+.TP -+Note: ZRLE and ZYWRLE encodings are now supported. -+.TP -+Note: F9 is shortcut to Toggle FullScreen mode. -+.TP -+Note: In -listen mode set the env var. SSVNC_MULTIPLE_LISTEN=1 -+to allow more than one incoming VNC server at a time. -+This is the same as -multilisten described below. Set -+SSVNC_MULTIPLE_LISTEN=MAX:n to allow no more than "n" -+simultaneous reverse connections. -+ -+If the host:port is specified as "exec=command args..." -+then instead of making a TCP/IP socket connection to the -+remote VNC server, "command args..." is executed and the -+viewer is attached to its stdio. This enables tunnelling -+established via an external command, e.g. an stunnel(8) -+that does not involve a listening socket. -+This mode does not work for -listen reverse connections. -+ -+If the host:port is specified as "fd=n" then it is assumed -+n is an already opened file descriptor to the socket. (i.e -+the parent did fork+exec) -+ -+If the host:port contains a '/' it is interpreted as a -+unix-domain socket (AF_LOCAL insead of AF_INET) -+.TP -+\fB\-multilisten\fR -+As in -listen (reverse connection listening) except -+allow more than one incoming VNC server to be connected -+at a time. The default for -listen of only one at a -+time tries to play it safe by not allowing anyone on -+the network to put (many) desktops on your screen over -+a long window of time. Use -multilisten for no limit. -+.TP -+\fB\-acceptpopup\fR -+In \fB\-listen\fR (reverse connection listening) mode when -+a reverse VNC connection comes in show a popup asking -+whether to Accept or Reject the connection. The IP -+address of the connecting host is shown. Same as -+setting the env. var. SSVNC_ACCEPT_POPUP=1. -+.TP -+\fB\-acceptpopupsc\fR -+As in \fB\-acceptpopup\fR except assume UltraVNC Single -+Click (SC) server. Retrieve User and ComputerName -+info from UltraVNC Server and display in the Popup. -+.TP -+\fB\-use64\fR -+In \fB\-bgr233\fR mode, use 64 colors instead of 256. -+.TP -+\fB\-bgr222\fR -+Same as \fB\-use64\fR. -+.TP -+\fB\-use8\fR -+In \fB\-bgr233\fR mode, use 8 colors instead of 256. -+.TP -+\fB\-bgr111\fR -+Same as \fB\-use8\fR. -+.TP -+\fB\-16bpp\fR -+If the vnc viewer X display is depth 24 at 32bpp -+request a 16bpp format from the VNC server to cut -+network traffic by up to 2X, then tranlate the -+pixels to 32bpp locally. -+.TP -+\fB\-bgr565\fR -+Same as \fB\-16bpp\fR. -+.TP -+\fB\-grey\fR -+Use a grey scale for the 16- and 8\fB\-bpp\fR modes. -+.TP -+\fB\-alpha\fR -+Use alphablending transparency for local cursors -+requires: x11vnc server, both client and server -+must be 32bpp and same endianness. -+.TP -+\fB\-scale\fR \fIstr\fR -+Scale the desktop locally. The string "str" can -+a floating point ratio, e.g. "0.9", or a fraction, -+e.g. "3/4", or WxH, e.g. 1280x1024. Use "fit" -+to fit in the current screen size. Use "auto" to -+fit in the window size. "str" can also be set by -+the env. var. SSVNC_SCALE. -+ -+If you observe mouse trail painting errors, enable -+X11 Cursor mode (either via Popup or \fB\-x11cursor\fR.) -+ -+Note that scaling is done in software and so can be -+slow and requires more memory. Some speedup Tips: -+ -+ZRLE is faster than Tight in this mode. When -+scaling is first detected, the encoding will -+be automatically switched to ZRLE. Use the -+Popup menu if you want to go back to Tight. -+Set SSVNC_PRESERVE_ENCODING=1 to disable this. -+ -+Use a solid background on the remote side. -+(e.g. manually or via x11vnc \fB\-solid\fR ...) -+ -+If the remote server is x11vnc, try client -+side caching: x11vnc \fB\-ncache\fR 10 ... -+.TP -+\fB\-ycrop\fR n -+Only show the top n rows of the framebuffer. For -+use with x11vnc \fB\-ncache\fR client caching option -+to help "hide" the pixel cache region. -+Use a negative value (e.g. \fB\-1\fR) for autodetection. -+Autodetection will always take place if the remote -+fb height is more than 2 times the width. -+.TP -+\fB\-sbwidth\fR n -+Scrollbar width for x11vnc \fB\-ncache\fR mode (\fB\-ycrop\fR), -+default is very narrow: 2 pixels, it is narrow to -+avoid distraction in \fB\-ycrop\fR mode. -+.TP -+\fB\-nobell\fR -+Disable bell. -+.TP -+\fB\-rawlocal\fR -+Prefer raw encoding for localhost, default is -+no, i.e. assumes you have a SSH tunnel instead. -+.TP -+\fB\-notty\fR -+Try to avoid using the terminal for interactive -+responses: use windows for messages and prompting -+instead. Messages will also be printed to terminal. -+.TP -+\fB\-sendclipboard\fR -+Send the X CLIPBOARD selection (i.e. Ctrl+C, -+Ctrl+V) instead of the X PRIMARY selection (mouse -+select and middle button paste.) -+.TP -+\fB\-sendalways\fR -+Whenever the mouse enters the VNC viewer main -+window, send the selection to the VNC server even if -+it has not changed. This is like the Xt resource -+translation SelectionToVNC(always) -+.TP -+\fB\-recvtext\fR -+str When cut text is received from the VNC server, -+ssvncviewer will set both the X PRIMARY and the -+X CLIPBOARD local selections. To control which -+is set, specify 'str' as 'primary', 'clipboard', -+or 'both' (the default.) -+.TP -+\fB\-graball\fR -+Grab the entire X server when in fullscreen mode, -+needed by some old window managers like fvwm2. -+.TP -+\fB\-popupfix\fR -+Warp the popup back to the pointer position, -+needed by some old window managers like fvwm2. -+.TP -+\fB\-grabkbd\fR -+Grab the X keyboard when in fullscreen mode, -+needed by some window managers. Same as \fB\-grabkeyboard\fR. -+\fB\-grabkbd\fR is the default, use \fB\-nograbkbd\fR to disable. -+.TP -+\fB\-bs\fR, \fB\-nobs\fR -+Whether or not to use X server Backingstore for the -+main viewer window. The default is to not, mainly -+because most Linux, etc, systems X servers disable -+*all* Backingstore by default. To re\fB\-enable\fR it put -+ -+Option "Backingstore" -+ -+in the Device section of /etc/X11/xorg.conf. -+In \fB\-bs\fR mode with no X server backingstore, whenever an -+area of the screen is re\fB\-exposed\fR it must go out to the -+VNC server to retrieve the pixels. This is too slow. -+ -+In \fB\-nobs\fR mode, memory is allocated by the viewer to -+provide its own backing of the main viewer window. This -+actually makes some activities faster (changes in large -+regions) but can appear to "flash" too much. -+.TP -+\fB\-noshm\fR -+Disable use of MIT shared memory extension (not recommended) -+.TP -+\fB\-termchat\fR -+Do the UltraVNC chat in the terminal vncviewer is in -+instead of in an independent window. -+.TP -+\fB\-unixpw\fR \fIstr\fR -+Useful for logging into x11vnc in \fB\-unixpw\fR mode. "str" is a -+string that allows many ways to enter the Unix Username -+and Unix Password. These characters: username, newline, -+password, newline are sent to the VNC server after any VNC -+authentication has taken place. Under x11vnc they are -+used for the \fB\-unixpw\fR login. Other VNC servers could do -+something similar. -+ -+You can also indicate "str" via the environment -+variable SSVNC_UNIXPW. -+ -+Note that the Escape key is actually sent first to tell -+x11vnc to not echo the Unix Username back to the VNC -+viewer. Set SSVNC_UNIXPW_NOESC=1 to override this. -+ -+If str is ".", then you are prompted at the command line -+for the username and password in the normal way. If str is -+"-" the stdin is read via getpass(3) for username@password. -+Otherwise if str is a file, it is opened and the first line -+read is taken as the Unix username and the 2nd as the -+password. If str prefixed by "rm:" the file is removed -+after reading. Otherwise, if str has a "@" character, -+it is taken as username@password. Otherwise, the program -+exits with an error. Got all that? -+.TP -+\fB-repeater\fR \fIstr\fR -+This is for use with UltraVNC repeater proxy described -+here: http://www.uvnc.com/addons/repeater.html. The "str" -+is the ID string to be sent to the repeater. E.g. ID:1234 -+It can also be the hostname and port or display of the VNC -+server, e.g. 12.34.56.78:0 or snoopy.com:1. Note that when -+using -repeater, the host:dpy on the cmdline is the repeater -+server, NOT the VNC server. The repeater will connect you. -+ -+Example: vncviewer ... -repeater ID:3333 repeat.host:5900 -+ -+Example: vncviewer ... -repeater vhost:0 repeat.host:5900 -+ -+Use, e.g., '-repeater SCIII=ID:3210' if the repeater is a -+Single Click III (SSL) repeater (repeater_SSL.exe) and you -+are passing the SSL part of the connection through stunnel, socat, etc. -+This way the magic UltraVNC string 'testB' needed to work with the -+repeater is sent to it. -+.TP -+\fB-rfbversion\fR \fIstr\fR -+Set the advertised RFB version. E.g.: -rfbversion 3.6 For some -+servers, e.g. UltraVNC this needs to be done. -+.TP -+\fB-ultradsm\fR -+UltraVNC has symmetric private encryption DSM plugins. See -+http://www.uvnc.com/features/encryption.html. It is assumed -+you are using a unix program (e.g. our ultravnc_dsm_helper) to -+encrypt and decrypt the UltraVNC DSM stream. IN ADDITION TO -+THAT supply -ultradsm to tell THIS viewer to modify the RFB -+data sent so as to work with the UltraVNC Server. For some -+reason, each RFB msg type must be sent twice under DSM. -+.TP -+\fB\-mslogon\fR \fIuser\fR -+Use Windows MS Logon to an UltraVNC server. Supply the -+username or "1" to be prompted. The default is to -+autodetect the UltraVNC MS Logon server and prompt for -+the username and password. -+ -+IMPORTANT NOTE: The UltraVNC MS-Logon Diffie-Hellman -+exchange is very weak and can be brute forced to recover -+your username and password in a few seconds of CPU -+time. To be safe, be sure to use an additional encrypted -+tunnel (e.g. SSL or SSH) for the entire VNC session. -+.TP -+\fB\-chatonly\fR -+Try to be a client that only does UltraVNC text chat. This -+mode is used by x11vnc to present a chat window on the physical -+X11 console (i.e. to chat with the person at the display). -+.TP -+\fB-env\fR \fIVAR=VALUE\fR -+To save writing a shell script to set environment -+variables, specify as many as you need on the command line. For example, -+-env SSVNC_MULTIPLE_LISTEN=MAX:5 -env EDITOR=vi -+.TP -+\fB\-noipv6\fR -+Disable all IPv6 sockets. Same as VNCVIEWER_NO_IPV6=1. -+.TP -+\fB\-noipv4\fR -+Disable all IPv4 sockets. Same as VNCVIEWER_NO_IPV4=1. -+.TP -+\fB\-printres\fR -+Print out the Ssvnc X resources (appdefaults) and -+then exit. You can save them to a file and customize them (e.g. the -+keybindings and Popup menu) Then point to the file via -+XENVIRONMENT or XAPPLRESDIR. -+.TP -+\fB\-pipeline\fR -+Like TurboVNC, request the next framebuffer update as soon -+as possible instead of waiting until the end of the current -+framebuffer update coming in. Helps 'pipeline' the updates. -+This is currently the default, use \fB-nopipeline\fR to disable. -+.TP -+\fB\-appshare\fR -+Enable features for use with x11vnc's \fB\-appshare\fR mode where -+instead of sharing the full desktop only the application's -+windows are shared. Viewer multilisten mode is used to -+create the multiple windows: \fB\-multilisten\fR is implied. -+See 'x11vnc \fB\-appshare\fR \fB\-help\fR' more information on the mode. -+Features enabled in the viewer under \fB\-appshare\fR are: -+Minimum extra text in the title, auto \fB\-ycrop\fR is disabled, -+x11vnc \fB\-remote_prefix\fR X11VNC_APPSHARE_CMD: message channel, -+x11vnc initial window position hints. See also Escape Keys -+below for additional key and mouse bindings. -+.TP -+\fB\-escape \fR\fIstr\fR -+This sets the 'Escape Keys' modifier sequence and enables -+escape keys mode. When the modifier keys escape sequence -+is held down, the next keystroke is interpreted locally -+to perform a special action instead of being sent to the -+remote VNC server. -+ -+Use '\fB\-escape\fR default' for the default modifier sequence. -+(Unix: Alt_L,Super_L and MacOSX: Control_L,Meta_L) -+ -+Here are the 'Escape Keys: Help+Set' instructions from the Popup: -+ -+Escape Keys: Enter a comma separated list of modifier keys to be the 'escape -+sequence'. When these keys are held down, the next keystroke is -+interpreted locally to invoke a special action instead of being sent to -+the remote VNC server. In other words, a set of 'Hot Keys'. -+ -+Here is the list of local key mappings to special actions: -+ -+r: refresh desktop b: toggle bell c: toggle full-color -+ -+f: file transfer x: x11cursor z: toggle Tight/ZRLE -+ -+l: full screen g: graball e: escape keys dialog -+ -+s: scale dialog +: scale up (=) -: scale down (_) -+ -+t: text chat a: alphablend cursor -+ -+V: toggle viewonly Q: quit viewer 123456: UltraVNC scale 1/n -+ -+Arrow keys: pan the viewport about 10% for each keypress. -+ -+PageUp/PageDown: pan the viewport by a screenful vertically. -+ -+Home/End: pan the viewport by a screenful horizontally. -+ -+KeyPad Arrows: pan the viewport by 1 pixel for each keypress. -+ -+Dragging the Mouse with Button1 pressed also pans the viewport. -+ -+Clicking Mouse Button3 brings up the Popup Menu. -+ -+The above mappings are \fBalways\fR active in ViewOnly mode, unless you set -+the Escape Keys value to 'never'. -+ -+x11vnc -appshare hot-keys: x11vnc has a simple application sharing mode -+that enables the viewer-side to move, resize, or raise the remote toplevel -+windows. To enable it, hold down Shift + the Escape Keys and press these: -+ -+Arrow keys: move the remote window around in its desktop. -+ -+PageUp/PageDn/Home/End: resize the remote window. -+ -++/-: raise or lower the remote window. -+ -+M or Button1 move win to local position; D or Button3: delete remote win. -+ -+If the Escape Keys value below is set to 'default' then a default list of -+of modifier keys is used. For Unix it is: Alt_L,Super_L and for MacOSX it -+is Control_L,Meta_L. Note: the Super_L key usually has a Windows(TM) Flag -+on it. Also note the _L and _R mean the key is on the LEFT or RIGHT side -+of the keyboard. -+ -+On Unix the default is Alt and Windows keys on Left side of keyboard. -+On MacOSX the default is Control and Command keys on Left side of keyboard. -+ -+Example: Press and hold the Alt and Windows keys on the LEFT side of the -+keyboard and then press 'c' to toggle the full-color state. Or press 't' -+to toggle the ultravnc Text Chat window, etc. -+ -+To use something besides the default, supply a comma separated list (or a -+single one) from: Shift_L Shift_R Control_L Control_R Alt_L Alt_R Meta_L -+Meta_R Super_L Super_R Hyper_L Hyper_R or Mode_switch. -+.TP -+\fB New Popup actions:\fR -+ -+ ViewOnly: ~ -viewonly -+ Disable Bell: ~ -nobell -+ Cursor Shape: ~ -nocursorshape -+ X11 Cursor: ~ -x11cursor -+ Cursor Alphablend: ~ -alpha -+ Toggle Tight/Hextile: ~ -encodings hextile... -+ Toggle Tight/ZRLE: ~ -encodings zrle... -+ Toggle ZRLE/ZYWRLE: ~ -encodings zywrle... -+ Quality Level ~ -quality (both Tight and ZYWRLE) -+ Compress Level ~ -compresslevel -+ Disable JPEG: ~ -nojpeg (Tight) -+ Pipeline Updates ~ -pipeline -+ -+ Full Color as many colors as local screen allows. -+ Grey scale (16 & 8-bpp) ~ -grey, for low colors 16/8bpp modes only. -+ 16 bit color (BGR565) ~ -16bpp / -bgr565 -+ 8 bit color (BGR233) ~ -bgr233 -+ 256 colors ~ -bgr233 default # of colors. -+ 64 colors ~ -bgr222 / -use64 -+ 8 colors ~ -bgr111 / -use8 -+ Scale Viewer ~ -scale -+ Escape Keys: Toggle ~ -escape -+ Escape Keys: Help+Set ~ -escape -+ Set Y Crop (y-max) ~ -ycrop -+ Set Scrollbar Width ~ -sbwidth -+ XGrabServer ~ -graball -+ -+ UltraVNC Extensions: -+ -+ Set 1/n Server Scale Ultravnc ext. Scale desktop by 1/n. -+ Text Chat Ultravnc ext. Do Text Chat. -+ File Transfer Ultravnc ext. File xfer via Java helper. -+ Single Window Ultravnc ext. Grab and view a single window. -+ (select then click on the window you want). -+ Disable Remote Input Ultravnc ext. Try to prevent input and -+ viewing of monitor at physical display. -+ -+ Note: the Ultravnc extensions only apply to servers that support -+ them. x11vnc/libvncserver supports some of them. -+ -+ Send Clipboard not Primary ~ -sendclipboard -+ Send Selection Every time ~ -sendalways -+ - .SH ENCODINGS - The server supplies information in whatever format is desired by the - client, in order to make the client as easy as possible to implement. -@@ -238,6 +673,15 @@ - \-quality and \-nojpeg options above). Tight encoding is usually the - best choice for low\-bandwidth network environments (e.g. slow modem - connections). -+.TP -+.B ZRLE -+The SSVNC viewer has ported the RealVNC (www.realvnc.com) ZRLE encoding -+to the unix tightvnc viewer. -+.TP -+.B ZYWRLE -+The SSVNC viewer has ported the Hitachi lossy wavelet based ZRLE -+encoding from http://mobile.hitachi-system.co.jp/publications/ZYWRLE/ -+to the unix tightvnc viewer. - .SH RESOURCES - X resources that \fBvncviewer\fR knows about, aside from the - normal Xt resources, are as follows: -@@ -364,12 +808,13 @@ - .B %R - remote TCP port number. - .SH SEE ALSO --\fBvncserver\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1), --\fBvncconnect\fR(1), \fBssh\fR(1) -+\fBvncserver\fR(1), \fBx11vnc\fR(1), \fBssvnc\fR(1), \fBXvnc\fR(1), \fBvncpasswd\fR(1), -+\fBvncconnect\fR(1), \fBssh\fR(1), http://www.karlrunge.com/x11vnc, http://www.karlrunge.com/x11vnc/ssvnc.html - .SH AUTHORS - Original VNC was developed in AT&T Laboratories Cambridge. TightVNC - additions was implemented by Constantin Kaplinsky. Many other people --participated in development, testing and support. -+participated in development, testing and support. Karl J. Runge -+added all of the SSVNC related features and improvements. - - \fBMan page authors:\fR - .br -@@ -380,3 +825,5 @@ - Tim Waugh <twaugh@redhat.com>, - .br - Constantin Kaplinsky <const@ce.cctpu.edu.ru> -+.br -+Karl J. Runge <runge@karlrunge.com> -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrle.c vnc_unixsrc/vncviewer/zrle.c ---- vnc_unixsrc.orig/vncviewer/zrle.c 2007-02-04 18:59:50.000000000 -0500 -+++ vnc_unixsrc/vncviewer/zrle.c 2010-02-25 23:24:28.000000000 -0500 -@@ -0,0 +1,620 @@ -+/* -+ * Copyright (C) 2005 Johannes E. Schindelin. 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. -+ */ -+ -+/* -+ * zrle.c - handle zrle encoding. -+ * -+ * This file shouldn't be compiled directly. It is included multiple times by -+ * rfbproto.c, each time with a different definition of the macro BPP. For -+ * each value of BPP, this file defines a function which handles an zrle -+ * encoded rectangle with BPP bits per pixel. -+ */ -+ -+#ifndef REALBPP -+#define REALBPP BPP -+#endif -+ -+#if !defined(UNCOMP) || UNCOMP==0 -+#define HandleZRLE CONCAT2E(HandleZRLE,REALBPP) -+#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) -+#elif UNCOMP>0 -+#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Down) -+#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down) -+#else -+#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Up) -+#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up) -+#endif -+#undef CARDBPP -+#undef CARDREALBPP -+#define CARDBPP CONCAT2E(CARD, BPP) -+#define CARDREALBPP CONCAT2E(CARD,REALBPP) -+ -+#define FillRectangle(x, y, w, h, color) \ -+ { \ -+ XGCValues _gcv; \ -+ _gcv.foreground = color; \ -+ if (!appData.useXserverBackingStore) { \ -+ FillScreen(x, y, w, h, _gcv.foreground); \ -+ } else { \ -+ XChangeGC(dpy, gc, GCForeground, &_gcv); \ -+ XFillRectangle(dpy, desktopWin, gc, x, y, w, h); \ -+ } \ -+ } -+ -+#if defined(__sparc) || defined(__sparc__) || defined(__ppc__) || defined(__POWERPC__) || defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN) -+#define IS_BIG_ENDIAN 1 -+#else -+#define IS_BIG_ENDIAN 0 -+#endif -+ -+#if DO_ZYWRLE -+ -+#define ENDIAN_LITTLE 0 -+#define ENDIAN_BIG 1 -+#define ENDIAN_NO 2 -+#if IS_BIG_ENDIAN -+#define ZYWRLE_ENDIAN ENDIAN_BIG -+#else -+#define ZYWRLE_ENDIAN ENDIAN_LITTLE -+#endif -+#undef END_FIX -+#if ZYWRLE_ENDIAN == ENDIAN_LITTLE -+# define END_FIX LE -+#elif ZYWRLE_ENDIAN == ENDIAN_BIG -+# define END_FIX BE -+#else -+# define END_FIX NE -+#endif -+#define __RFB_CONCAT3E(a,b,c) CONCAT3E(a,b,c) -+#define __RFB_CONCAT2E(a,b) CONCAT2E(a,b) -+#undef CPIXEL -+#if REALBPP != BPP -+#if UNCOMP == 0 -+#define CPIXEL REALBPP -+#elif UNCOMP>0 -+#define CPIXEL CONCAT2E(REALBPP,Down) -+#else -+#define CPIXEL CONCAT2E(REALBPP,Up) -+#endif -+#endif -+#define PIXEL_T CARDBPP -+#if BPP!=8 -+#define ZYWRLE_DECODE 1 -+#include "zywrletemplate.c" -+#endif -+#undef CPIXEL -+ -+#endif /* DO_ZYWRLE */ -+ -+static int HandleZRLETile( -+ unsigned char* buffer,size_t buffer_length, -+ int x,int y,int w,int h); -+ -+static Bool -+HandleZRLE (int rx, int ry, int rw, int rh) -+{ -+ rfbZRLEHeader header; -+ int remaining; -+ int inflateResult; -+ int toRead; -+ int min_buffer_size = rw * rh * (REALBPP / 8) * 2; -+ -+ /* First make sure we have a large enough raw buffer to hold the -+ * decompressed data. In practice, with a fixed REALBPP, fixed frame -+ * buffer size and the first update containing the entire frame -+ * buffer, this buffer allocation should only happen once, on the -+ * first update. -+ */ -+ if ( raw_buffer_size < min_buffer_size) { -+ -+ if ( raw_buffer != NULL ) { -+ -+ free( raw_buffer ); -+ -+ } -+ -+ raw_buffer_size = min_buffer_size; -+ raw_buffer = (char*) malloc( raw_buffer_size ); -+ -+ } -+ -+ if (!ReadFromRFBServer((char *)&header, sz_rfbZRLEHeader)) -+ return False; -+ -+ remaining = Swap32IfLE(header.length); -+ -+ /* Need to initialize the decompressor state. */ -+ decompStream.next_in = ( Bytef * )buffer; -+ decompStream.avail_in = 0; -+ decompStream.next_out = ( Bytef * )raw_buffer; -+ decompStream.avail_out = raw_buffer_size; -+ decompStream.data_type = Z_BINARY; -+ -+ /* Initialize the decompression stream structures on the first invocation. */ -+ if ( decompStreamInited == False ) { -+ -+ inflateResult = inflateInit( &decompStream ); -+ -+ if ( inflateResult != Z_OK ) { -+ fprintf(stderr, -+ "inflateInit returned error: %d, msg: %s\n", -+ inflateResult, -+ decompStream.msg); -+ return False; -+ } -+ -+ decompStreamInited = True; -+ -+ } -+ -+ inflateResult = Z_OK; -+ -+ /* Process buffer full of data until no more to process, or -+ * some type of inflater error, or Z_STREAM_END. -+ */ -+ while (( remaining > 0 ) && -+ ( inflateResult == Z_OK )) { -+ -+ if ( remaining > BUFFER_SIZE ) { -+ toRead = BUFFER_SIZE; -+ } -+ else { -+ toRead = remaining; -+ } -+ -+ /* Fill the buffer, obtaining data from the server. */ -+ if (!ReadFromRFBServer(buffer,toRead)) -+ return False; -+ -+ decompStream.next_in = ( Bytef * )buffer; -+ decompStream.avail_in = toRead; -+ -+ /* Need to uncompress buffer full. */ -+ inflateResult = inflate( &decompStream, Z_SYNC_FLUSH ); -+ -+ /* We never supply a dictionary for compression. */ -+ if ( inflateResult == Z_NEED_DICT ) { -+ fprintf(stderr, "zlib inflate needs a dictionary!\n"); -+ return False; -+ } -+ if ( inflateResult < 0 ) { -+ fprintf(stderr, -+ "zlib inflate returned error: %d, msg: %s\n", -+ inflateResult, -+ decompStream.msg); -+ return False; -+ } -+ -+ /* Result buffer allocated to be at least large enough. We should -+ * never run out of space! -+ */ -+ if (( decompStream.avail_in > 0 ) && -+ ( decompStream.avail_out <= 0 )) { -+ fprintf(stderr, "zlib inflate ran out of space!\n"); -+ return False; -+ } -+ -+ remaining -= toRead; -+ -+ } /* while ( remaining > 0 ) */ -+ -+ if ( inflateResult == Z_OK ) { -+ void* buf=raw_buffer; -+ int i,j; -+ -+ remaining = raw_buffer_size-decompStream.avail_out; -+ -+ for(j=0; j<rh; j+=rfbZRLETileHeight) -+ for(i=0; i<rw; i+=rfbZRLETileWidth) { -+ int subWidth=(i+rfbZRLETileWidth>rw)?rw-i:rfbZRLETileWidth; -+ int subHeight=(j+rfbZRLETileHeight>rh)?rh-j:rfbZRLETileHeight; -+ int result=HandleZRLETile(buf,remaining,rx+i,ry+j,subWidth,subHeight); -+ -+ if(result<0) { -+ fprintf(stderr, "ZRLE decoding failed (%d)\n",result); -+return True; -+ return False; -+ } -+ -+ buf+=result; -+ remaining-=result; -+ } -+ } -+ else { -+ -+ fprintf(stderr, -+ "zlib inflate returned error: %d, msg: %s\n", -+ inflateResult, -+ decompStream.msg); -+ return False; -+ -+ } -+ -+ return True; -+} -+ -+#if REALBPP!=BPP && defined(UNCOMP) && UNCOMP!=0 -+# if BPP == 32 && IS_BIG_ENDIAN -+# define UncompressCPixel(p) ( (*p << myFormat.redShift) | (*(p+1) << myFormat.greenShift) | (*(p+2) << myFormat.blueShift) ) -+# else -+# if UNCOMP>0 -+# define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)>>UNCOMP) -+# else -+# define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)<<(-(UNCOMP))) -+# endif -+# endif -+#else -+# define UncompressCPixel(pointer) (*(CARDBPP*)pointer) -+#endif -+ -+extern XImage *image; -+extern XImage *image_scale; -+extern int skip_maybe_sync; -+ -+static int HandleZRLETile( -+ unsigned char* buffer,size_t buffer_length, -+ int x,int y,int w,int h) { -+ unsigned char* buffer_copy = buffer; -+ unsigned char* buffer_end = buffer+buffer_length; -+ unsigned char type; -+ -+ if(buffer_length<1) -+ return -2; -+ -+ if (frameBufferLen < w * h * BPP/8) { -+ if(frameBuffer) { -+ free(frameBuffer); -+ } -+ frameBufferLen = w * h * BPP/8 * 2; -+ frameBuffer = (unsigned char *) malloc(frameBufferLen); -+ } -+ -+zywrle_top: -+ type = *buffer; -+ buffer++; -+ switch(type) { -+ case 0: /* raw */ -+ { -+#if DO_ZYWRLE && BPP != 8 -+ if (zywrle_level > 0 && !(zywrle_level & 0x80) ) { -+ zywrle_level |= 0x80; -+ goto zywrle_top; -+ } else -+#endif -+ { -+#if REALBPP!=BPP -+ int m0 = 0, i,j; -+ -+ -+ if(1+w*h*REALBPP/8>buffer_length) { -+ fprintf(stderr, "expected %d bytes, got only %d (%dx%d)\n",1+w*h*REALBPP/8,buffer_length,w,h); -+ return -3; -+ } -+ -+ for(j=y*si.framebufferWidth; j<(y+h)*si.framebufferWidth; j+=si.framebufferWidth) { -+ for(i=x; i<x+w; i++,buffer+=REALBPP/8) { -+# if 0 -+ ((CARDBPP*)frameBuffer)[j+i] = UncompressCPixel(buffer); -+ /* alt */ -+ CARDBPP color = UncompressCPixel(buffer); -+ CopyDataToScreen((char *)&color, i, j/si.framebufferWidth, 1, 1); -+# else -+ ((CARDBPP*)frameBuffer)[m0++] = UncompressCPixel(buffer); -+# endif -+ } -+ } -+ CopyDataToScreen((char *)frameBuffer, x, y, w, h); -+if (0) fprintf(stderr, "cha1: %dx%d+%d+%d\n", w, h, x, y); -+ -+#else -+# if 0 -+ CopyRectangle(buffer, x, y, w, h); -+# else -+ CopyDataToScreen((char *)buffer, x, y, w, h); -+# endif -+ buffer+=w*h*REALBPP/8; -+#endif -+ } -+ break; -+ } -+ case 1: /* solid */ -+ { -+ CARDBPP color = UncompressCPixel(buffer); -+ -+ if(1+REALBPP/8>buffer_length) -+ return -4; -+ -+ if ((BPP == 8 && appData.useBGR233) || (BPP == 16 && appData.useBGR565)) { -+ int m0; -+ for (m0=0; m0 < w*h; m0++) { -+ ((CARDBPP*)frameBuffer)[m0] = color; -+ } -+ CopyDataToScreen((char *)frameBuffer, x, y, w, h); -+ } else { -+ FillRectangle(x, y, w, h, color); -+ } -+if (0) fprintf(stderr, "cha2: %dx%d+%d+%d\n", w, h, x, y); -+ -+ buffer+=REALBPP/8; -+ -+ break; -+ } -+ case 2 ... 127: /* packed Palette */ -+ { -+ CARDBPP palette[16]; -+ int m0, i,j,shift, -+ bpp=(type>4?(type>16?8:4):(type>2?2:1)), -+ mask=(1<<bpp)-1, -+ divider=(8/bpp); -+ -+ if(1+type*REALBPP/8+((w+divider-1)/divider)*h>buffer_length) -+ return -5; -+ -+ /* read palette */ -+ for(i=0; i<type; i++,buffer+=REALBPP/8) -+ palette[i] = UncompressCPixel(buffer); -+ -+ m0 = 0; -+ /* read palettized pixels */ -+ for(j=y*si.framebufferWidth; j<(y+h)*si.framebufferWidth; j+=si.framebufferWidth) { -+ for(i=x,shift=8-bpp; i<x+w; i++) { -+# if 0 -+ ((CARDBPP*)frameBuffer)[j+i] = palette[((*buffer)>>shift)&mask]; -+ /* alt */ -+ CARDBPP color = palette[((*buffer)>>shift)&mask]; -+ CopyDataToScreen((char *)&color, i, j/si.framebufferWidth, 1, 1); -+# else -+ ((CARDBPP*)frameBuffer)[m0++] = palette[((*buffer)>>shift)&mask]; -+# endif -+ shift-=bpp; -+ if(shift<0) { -+ shift=8-bpp; -+ buffer++; -+ } -+ } -+ if(shift<8-bpp) -+ buffer++; -+ } -+ CopyDataToScreen((char *)frameBuffer, x, y, w, h); -+if (0) fprintf(stderr, "cha3: %dx%d+%d+%d\n", w, h, x, y); -+ -+ break; -+ } -+ /* case 17 ... 127: not used, but valid */ -+ case 128: /* plain RLE */ -+ { -+ int m0=0, i=0,j=0; -+ while(j<h) { -+ int color,length; -+ /* read color */ -+ if(buffer+REALBPP/8+1>buffer_end) -+ return -7; -+ color = UncompressCPixel(buffer); -+ buffer+=REALBPP/8; -+ /* read run length */ -+ length=1; -+ while(*buffer==0xff) { -+ if(buffer+1>=buffer_end) -+ return -8; -+ length+=*buffer; -+ buffer++; -+ } -+ length+=*buffer; -+ buffer++; -+ while(j<h && length>0) { -+# if 0 -+ ((CARDBPP*)frameBuffer)[(y+j)*si.framebufferWidth+x+i] = color; -+ /* alt */ -+ CopyDataToScreen((char *)&color, x+i, y+j, 1, 1); -+# else -+ ((CARDBPP*)frameBuffer)[m0++] = color; -+# endif -+ length--; -+ i++; -+ if(i>=w) { -+ i=0; -+ j++; -+ } -+ } -+ if(length>0) -+ fprintf(stderr, "Warning: possible ZRLE corruption\n"); -+ } -+ CopyDataToScreen((char *)frameBuffer, x, y, w, h); -+if (0) fprintf(stderr, "cha4: %dx%d+%d+%d\n", w, h, x, y); -+ -+ break; -+ } -+ case 129: /* unused */ -+ { -+ return -8; -+ } -+ case 130 ... 255: /* palette RLE */ -+ { -+ CARDBPP palette[128]; -+ int m0 = 0, i,j; -+ -+ if(2+(type-128)*REALBPP/8>buffer_length) -+ return -9; -+ -+ /* read palette */ -+ for(i=0; i<type-128; i++,buffer+=REALBPP/8) -+ palette[i] = UncompressCPixel(buffer); -+ /* read palettized pixels */ -+ i=j=0; -+ while(j<h) { -+ int color,length; -+ /* read color */ -+ if(buffer>=buffer_end) -+ return -10; -+ color = palette[(*buffer)&0x7f]; -+ length=1; -+ if(*buffer&0x80) { -+ if(buffer+1>=buffer_end) -+ return -11; -+ buffer++; -+ /* read run length */ -+ while(*buffer==0xff) { -+ if(buffer+1>=buffer_end) -+ return -8; -+ length+=*buffer; -+ buffer++; -+ } -+ length+=*buffer; -+ } -+ buffer++; -+ while(j<h && length>0) { -+# if 0 -+ ((CARDBPP*)frameBuffer)[(y+j)*si.framebufferWidth+x+i] = color; -+ /* alt */ -+ CopyDataToScreen((char *)&color, x+i, y+j, 1, 1); -+# else -+ ((CARDBPP*)frameBuffer)[m0++] = color; -+# endif -+ length--; -+ i++; -+ if(i>=w) { -+ i=0; -+ j++; -+ } -+ } -+ if(length>0) -+ fprintf(stderr, "Warning: possible ZRLE corruption\n"); -+ } -+ CopyDataToScreen((char *)frameBuffer, x, y, w, h); -+if (0) fprintf(stderr, "cha5: %dx%d+%d+%d\n", w, h, x, y); -+ -+ break; -+ } -+ } -+ -+#if DO_ZYWRLE && BPP != 8 -+ if (zywrle_level & 0x80) { -+ int th, tx; -+ int widthInBytes = w * BPP / 8; -+ int scrWidthInBytes; -+ char *scr, *buf; -+ static CARDBPP *ptmp = NULL; -+ static int ptmp_len = 0; -+ XImage *im = image_scale ? image_scale : image; -+ -+ if (w * h > ptmp_len) { -+ ptmp_len = w * h; -+ if (ptmp_len < rfbZRLETileWidth*rfbZRLETileHeight) { -+ ptmp_len = rfbZRLETileWidth*rfbZRLETileHeight; -+ } -+ if (ptmp) { -+ free(ptmp); -+ } -+ ptmp = (CARDBPP *) malloc(ptmp_len * sizeof(CARDBPP)); -+ } -+ -+ zywrle_level &= 0x7F; -+ /* Reverse copy: screen to buf/ptmp: */ -+ /* make this CopyDataFromScreen() or something. */ -+ if (!appData.useBGR565) { -+ scrWidthInBytes = si.framebufferWidth * myFormat.bitsPerPixel / 8; -+ if (scrWidthInBytes != im->bytes_per_line) scrWidthInBytes = im->bytes_per_line; -+ scr = im->data + y * scrWidthInBytes + x * myFormat.bitsPerPixel / 8; -+ buf = (char *) ptmp; -+ -+ for (th = 0; th < h; th++) { -+ memcpy(buf, scr, widthInBytes); -+ buf += widthInBytes; -+ scr += scrWidthInBytes; -+ } -+ } else { -+ scrWidthInBytes = si.framebufferWidth * 4; -+ if (scrWidthInBytes != im->bytes_per_line) scrWidthInBytes = im->bytes_per_line; -+ scr = im->data + y * scrWidthInBytes + x * 4; -+ buf = (char *) ptmp; -+ -+ for (th = 0; th < h; th++) { -+ for (tx = 0; tx < w; tx++) { -+ unsigned long pix = *((unsigned int *)scr + tx); -+ unsigned int r1 = (pix & 0xff0000) >> 16; -+ unsigned int g1 = (pix & 0x00ff00) >> 8; -+ unsigned int b1 = (pix & 0x0000ff) >> 0; -+ int r2, g2, b2, idx; -+ int rok = 0, gok = 0, bok = 0, is0, sh = 10; -+ r2 = (31 * r1)/255; -+ g2 = (63 * g1)/255; -+ b2 = (31 * b1)/255; -+ for (is0 = 0; is0 < sh; is0++) { -+ int is, i, t; -+ for (i = 0; i < 2; i++) { -+ if (i == 0) { -+ is = -is0; -+ } else { -+ is = +is0; -+ } -+ if (!rok) { -+ t = r2 + is; -+ if (r1 == (255 * t)/31) { -+ r2 = t; rok = 1; -+ } -+ } -+ if (!gok) { -+ t = g2 + is; -+ if (g1 == (255 * t)/63) { -+ g2 = t; gok = 1; -+ } -+ } -+ if (!bok) { -+ t = b2 + is; -+ if (b1 == (255 * t)/31) { -+ b2 = t; bok = 1; -+ } -+ } -+ } -+ if (rok && gok && bok) { -+ break; -+ } -+ } -+ idx = (r2 << 11) | (g2 << 5) | (b2 << 0); -+ *((CARDBPP *)buf + tx) = (CARDBPP) idx; -+ } -+ buf += widthInBytes; -+ scr += scrWidthInBytes; -+ } -+ } -+ ZYWRLE_SYNTHESIZE((PIXEL_T *)ptmp, (PIXEL_T *)ptmp, w, h, w, zywrle_level, zywrleBuf ); -+ skip_maybe_sync = 1; -+ -+ if (appData.yCrop > 0) { -+ skip_maybe_sync = 0; -+ } -+ CopyDataToScreen((char *)ptmp, x, y, w, h); -+ -+ } -+#endif -+ -+ return buffer-buffer_copy; -+} -+ -+#undef CARDBPP -+#undef CARDREALBPP -+#undef HandleZRLE -+#undef HandleZRLETile -+#undef UncompressCPixel -+#undef REALBPP -+ -+#undef UNCOMP -+ -+#undef FillRectangle -+#undef IS_BIG_ENDIAN -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleencodetemplate.c vnc_unixsrc/vncviewer/zrleencodetemplate.c ---- vnc_unixsrc.orig/vncviewer/zrleencodetemplate.c 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/zrleencodetemplate.c 2007-02-04 23:18:09.000000000 -0500 -@@ -0,0 +1,317 @@ -+/* -+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. -+ * Copyright (C) 2003 Sun Microsystems, Inc. -+ * -+ * 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. -+ */ -+ -+/* -+ * Before including this file, you must define a number of CPP macros. -+ * -+ * BPP should be 8, 16 or 32 depending on the bits per pixel. -+ * GET_IMAGE_INTO_BUF should be some code which gets a rectangle of pixel data -+ * into the given buffer. EXTRA_ARGS can be defined to pass any other -+ * arguments needed by GET_IMAGE_INTO_BUF. -+ * -+ * Note that the buf argument to ZRLE_ENCODE needs to be at least one pixel -+ * bigger than the largest tile of pixel data, since the ZRLE encoding -+ * algorithm writes to the position one past the end of the pixel data. -+ */ -+ -+#include "zrleoutstream.h" -+#include "zrlepalettehelper.h" -+#include <assert.h> -+ -+/* __RFB_CONCAT2 concatenates its two arguments. __RFB_CONCAT2E does the same -+ but also expands its arguments if they are macros */ -+ -+#ifndef __RFB_CONCAT2E -+#define __RFB_CONCAT2(a,b) a##b -+#define __RFB_CONCAT2E(a,b) __RFB_CONCAT2(a,b) -+#endif -+ -+#ifndef __RFB_CONCAT3E -+#define __RFB_CONCAT3(a,b,c) a##b##c -+#define __RFB_CONCAT3E(a,b,c) __RFB_CONCAT3(a,b,c) -+#endif -+ -+#undef END_FIX -+#if ZYWRLE_ENDIAN == ENDIAN_LITTLE -+# define END_FIX LE -+#elif ZYWRLE_ENDIAN == ENDIAN_BIG -+# define END_FIX BE -+#else -+# define END_FIX NE -+#endif -+ -+#ifdef CPIXEL -+#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP) -+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,CPIXEL) -+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,CPIXEL,END_FIX) -+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,CPIXEL,END_FIX) -+#define BPPOUT 24 -+#elif BPP==15 -+#define PIXEL_T __RFB_CONCAT2E(zrle_U,16) -+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,16) -+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX) -+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX) -+#define BPPOUT 16 -+#else -+#define PIXEL_T __RFB_CONCAT2E(zrle_U,BPP) -+#define zrleOutStreamWRITE_PIXEL __RFB_CONCAT2E(zrleOutStreamWriteOpaque,BPP) -+#define ZRLE_ENCODE __RFB_CONCAT3E(zrleEncode,BPP,END_FIX) -+#define ZRLE_ENCODE_TILE __RFB_CONCAT3E(zrleEncodeTile,BPP,END_FIX) -+#define BPPOUT BPP -+#endif -+ -+#ifndef ZRLE_ONCE -+#define ZRLE_ONCE -+ -+static const int bitsPerPackedPixel[] = { -+ 0, 1, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 -+}; -+ -+int zywrle_level; -+int zywrleBuf[rfbZRLETileWidth*rfbZRLETileHeight]; -+ -+static zrlePaletteHelper paletteHelper; -+ -+#endif /* ZRLE_ONCE */ -+ -+void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os); -+ -+#if BPP!=8 -+#define ZYWRLE_ENCODE -+#include "zywrletemplate.c" -+#endif -+ -+static void ZRLE_ENCODE (int x, int y, int w, int h, -+ zrleOutStream* os, void* buf -+ EXTRA_ARGS -+ ) -+{ -+ int ty; -+ for (ty = y; ty < y+h; ty += rfbZRLETileHeight) { -+ int tx, th = rfbZRLETileHeight; -+ if (th > y+h-ty) th = y+h-ty; -+ for (tx = x; tx < x+w; tx += rfbZRLETileWidth) { -+ int tw = rfbZRLETileWidth; -+ if (tw > x+w-tx) tw = x+w-tx; -+ -+ GET_IMAGE_INTO_BUF(tx,ty,tw,th,buf); -+ -+ ZRLE_ENCODE_TILE((PIXEL_T*)buf, tw, th, os); -+ } -+ } -+ zrleOutStreamFlush(os); -+} -+ -+ -+void ZRLE_ENCODE_TILE (PIXEL_T* data, int w, int h, zrleOutStream* os) -+{ -+ /* First find the palette and the number of runs */ -+ -+ zrlePaletteHelper *ph; -+ -+ int runs = 0; -+ int singlePixels = 0; -+ -+ rfbBool useRle; -+ rfbBool usePalette; -+ -+ int estimatedBytes; -+ int plainRleBytes; -+ int i; -+ -+ PIXEL_T* ptr = data; -+ PIXEL_T* end = ptr + h * w; -+ *end = ~*(end-1); /* one past the end is different so the while loop ends */ -+ -+ ph = &paletteHelper; -+ zrlePaletteHelperInit(ph); -+ -+ while (ptr < end) { -+ PIXEL_T pix = *ptr; -+ if (*++ptr != pix) { -+ singlePixels++; -+ } else { -+ while (*++ptr == pix) ; -+ runs++; -+ } -+ zrlePaletteHelperInsert(ph, pix); -+ } -+ -+ /* Solid tile is a special case */ -+ -+ if (ph->size == 1) { -+ zrleOutStreamWriteU8(os, 1); -+ zrleOutStreamWRITE_PIXEL(os, ph->palette[0]); -+ return; -+ } -+ -+ /* Try to work out whether to use RLE and/or a palette. We do this by -+ estimating the number of bytes which will be generated and picking the -+ method which results in the fewest bytes. Of course this may not result -+ in the fewest bytes after compression... */ -+ -+ useRle = FALSE; -+ usePalette = FALSE; -+ -+ estimatedBytes = w * h * (BPPOUT/8); /* start assuming raw */ -+ -+#if BPP!=8 -+ if( (zywrle_level>0)&& !(zywrle_level & 0x80) ){ -+ estimatedBytes >>= zywrle_level; -+ } -+#endif -+ -+ plainRleBytes = ((BPPOUT/8)+1) * (runs + singlePixels); -+ -+ if (plainRleBytes < estimatedBytes) { -+ useRle = TRUE; -+ estimatedBytes = plainRleBytes; -+ } -+ -+ if (ph->size < 128) { -+ int paletteRleBytes = (BPPOUT/8) * ph->size + 2 * runs + singlePixels; -+ -+ if (paletteRleBytes < estimatedBytes) { -+ useRle = TRUE; -+ usePalette = TRUE; -+ estimatedBytes = paletteRleBytes; -+ } -+ -+ if (ph->size < 17) { -+ int packedBytes = ((BPPOUT/8) * ph->size + -+ w * h * bitsPerPackedPixel[ph->size-1] / 8); -+ -+ if (packedBytes < estimatedBytes) { -+ useRle = FALSE; -+ usePalette = TRUE; -+ estimatedBytes = packedBytes; -+ } -+ } -+ } -+ -+ if (!usePalette) ph->size = 0; -+ -+ zrleOutStreamWriteU8(os, (useRle ? 128 : 0) | ph->size); -+ -+ for (i = 0; i < ph->size; i++) { -+ zrleOutStreamWRITE_PIXEL(os, ph->palette[i]); -+ } -+ -+ if (useRle) { -+ -+ PIXEL_T* ptr = data; -+ PIXEL_T* end = ptr + w * h; -+ PIXEL_T* runStart; -+ PIXEL_T pix; -+ while (ptr < end) { -+ int len; -+ runStart = ptr; -+ pix = *ptr++; -+ while (*ptr == pix && ptr < end) -+ ptr++; -+ len = ptr - runStart; -+ if (len <= 2 && usePalette) { -+ int index = zrlePaletteHelperLookup(ph, pix); -+ if (len == 2) -+ zrleOutStreamWriteU8(os, index); -+ zrleOutStreamWriteU8(os, index); -+ continue; -+ } -+ if (usePalette) { -+ int index = zrlePaletteHelperLookup(ph, pix); -+ zrleOutStreamWriteU8(os, index | 128); -+ } else { -+ zrleOutStreamWRITE_PIXEL(os, pix); -+ } -+ len -= 1; -+ while (len >= 255) { -+ zrleOutStreamWriteU8(os, 255); -+ len -= 255; -+ } -+ zrleOutStreamWriteU8(os, len); -+ } -+ -+ } else { -+ -+ /* no RLE */ -+ -+ if (usePalette) { -+ int bppp; -+ PIXEL_T* ptr = data; -+ -+ /* packed pixels */ -+ -+ assert (ph->size < 17); -+ -+ bppp = bitsPerPackedPixel[ph->size-1]; -+ -+ for (i = 0; i < h; i++) { -+ zrle_U8 nbits = 0; -+ zrle_U8 byte = 0; -+ -+ PIXEL_T* eol = ptr + w; -+ -+ while (ptr < eol) { -+ PIXEL_T pix = *ptr++; -+ zrle_U8 index = zrlePaletteHelperLookup(ph, pix); -+ byte = (byte << bppp) | index; -+ nbits += bppp; -+ if (nbits >= 8) { -+ zrleOutStreamWriteU8(os, byte); -+ nbits = 0; -+ } -+ } -+ if (nbits > 0) { -+ byte <<= 8 - nbits; -+ zrleOutStreamWriteU8(os, byte); -+ } -+ } -+ } else { -+ -+ /* raw */ -+ -+#if BPP!=8 -+ if( (zywrle_level>0)&& !(zywrle_level & 0x80) ){ -+ ZYWRLE_ANALYZE( data, data, w, h, w, zywrle_level, zywrleBuf ); -+ zywrle_level |= 0x80; -+ ZRLE_ENCODE_TILE( data, w, h, os ); -+ zywrle_level &= 0x7F; -+ }else -+#endif -+ { -+#ifdef CPIXEL -+ PIXEL_T *ptr; -+ for (ptr = data; ptr < data+w*h; ptr++) { -+ zrleOutStreamWRITE_PIXEL(os, *ptr); -+ } -+#else -+ zrleOutStreamWriteBytes(os, (zrle_U8 *)data, w*h*(BPP/8)); -+#endif -+ } -+ } -+ } -+} -+ -+#undef PIXEL_T -+#undef zrleOutStreamWRITE_PIXEL -+#undef ZRLE_ENCODE -+#undef ZRLE_ENCODE_TILE -+#undef ZYWRLE_ENCODE_TILE -+#undef BPPOUT -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleoutstream.c vnc_unixsrc/vncviewer/zrleoutstream.c ---- vnc_unixsrc.orig/vncviewer/zrleoutstream.c 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/zrleoutstream.c 2005-05-15 10:57:54.000000000 -0400 -@@ -0,0 +1,275 @@ -+/* -+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. -+ * Copyright (C) 2003 Sun Microsystems, Inc. -+ * -+ * 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. -+ */ -+ -+#include "zrleoutstream.h" -+#include <stdlib.h> -+ -+#define ZRLE_IN_BUFFER_SIZE 16384 -+#define ZRLE_OUT_BUFFER_SIZE 1024 -+#undef ZRLE_DEBUG -+ -+static rfbBool zrleBufferAlloc(zrleBuffer *buffer, int size) -+{ -+ buffer->ptr = buffer->start = malloc(size); -+ if (buffer->start == NULL) { -+ buffer->end = NULL; -+ return FALSE; -+ } -+ -+ buffer->end = buffer->start + size; -+ -+ return TRUE; -+} -+ -+static void zrleBufferFree(zrleBuffer *buffer) -+{ -+ if (buffer->start) -+ free(buffer->start); -+ buffer->start = buffer->ptr = buffer->end = NULL; -+} -+ -+static rfbBool zrleBufferGrow(zrleBuffer *buffer, int size) -+{ -+ int offset; -+ -+ size += buffer->end - buffer->start; -+ offset = ZRLE_BUFFER_LENGTH (buffer); -+ -+ buffer->start = realloc(buffer->start, size); -+ if (!buffer->start) { -+ return FALSE; -+ } -+ -+ buffer->end = buffer->start + size; -+ buffer->ptr = buffer->start + offset; -+ -+ return TRUE; -+} -+ -+zrleOutStream *zrleOutStreamNew(void) -+{ -+ zrleOutStream *os; -+ -+ os = malloc(sizeof(zrleOutStream)); -+ if (os == NULL) -+ return NULL; -+ -+ if (!zrleBufferAlloc(&os->in, ZRLE_IN_BUFFER_SIZE)) { -+ free(os); -+ return NULL; -+ } -+ -+ if (!zrleBufferAlloc(&os->out, ZRLE_OUT_BUFFER_SIZE)) { -+ zrleBufferFree(&os->in); -+ free(os); -+ return NULL; -+ } -+ -+ os->zs.zalloc = Z_NULL; -+ os->zs.zfree = Z_NULL; -+ os->zs.opaque = Z_NULL; -+ if (deflateInit(&os->zs, Z_DEFAULT_COMPRESSION) != Z_OK) { -+ zrleBufferFree(&os->in); -+ free(os); -+ return NULL; -+ } -+ -+ return os; -+} -+ -+void zrleOutStreamFree (zrleOutStream *os) -+{ -+ deflateEnd(&os->zs); -+ zrleBufferFree(&os->in); -+ zrleBufferFree(&os->out); -+ free(os); -+} -+ -+rfbBool zrleOutStreamFlush(zrleOutStream *os) -+{ -+ os->zs.next_in = os->in.start; -+ os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in); -+ -+#ifdef ZRLE_DEBUG -+ rfbLog("zrleOutStreamFlush: avail_in %d\n", os->zs.avail_in); -+#endif -+ -+ while (os->zs.avail_in != 0) { -+ do { -+ int ret; -+ -+ if (os->out.ptr >= os->out.end && -+ !zrleBufferGrow(&os->out, os->out.end - os->out.start)) { -+ rfbLog("zrleOutStreamFlush: failed to grow output buffer\n"); -+ return FALSE; -+ } -+ -+ os->zs.next_out = os->out.ptr; -+ os->zs.avail_out = os->out.end - os->out.ptr; -+ -+#ifdef ZRLE_DEBUG -+ rfbLog("zrleOutStreamFlush: calling deflate, avail_in %d, avail_out %d\n", -+ os->zs.avail_in, os->zs.avail_out); -+#endif -+ -+ if ((ret = deflate(&os->zs, Z_SYNC_FLUSH)) != Z_OK) { -+ rfbLog("zrleOutStreamFlush: deflate failed with error code %d\n", ret); -+ return FALSE; -+ } -+ -+#ifdef ZRLE_DEBUG -+ rfbLog("zrleOutStreamFlush: after deflate: %d bytes\n", -+ os->zs.next_out - os->out.ptr); -+#endif -+ -+ os->out.ptr = os->zs.next_out; -+ } while (os->zs.avail_out == 0); -+ } -+ -+ os->in.ptr = os->in.start; -+ -+ return TRUE; -+} -+ -+static int zrleOutStreamOverrun(zrleOutStream *os, -+ int size) -+{ -+#ifdef ZRLE_DEBUG -+ rfbLog("zrleOutStreamOverrun\n"); -+#endif -+ -+ while (os->in.end - os->in.ptr < size && os->in.ptr > os->in.start) { -+ os->zs.next_in = os->in.start; -+ os->zs.avail_in = ZRLE_BUFFER_LENGTH (&os->in); -+ -+ do { -+ int ret; -+ -+ if (os->out.ptr >= os->out.end && -+ !zrleBufferGrow(&os->out, os->out.end - os->out.start)) { -+ rfbLog("zrleOutStreamOverrun: failed to grow output buffer\n"); -+ return FALSE; -+ } -+ -+ os->zs.next_out = os->out.ptr; -+ os->zs.avail_out = os->out.end - os->out.ptr; -+ -+#ifdef ZRLE_DEBUG -+ rfbLog("zrleOutStreamOverrun: calling deflate, avail_in %d, avail_out %d\n", -+ os->zs.avail_in, os->zs.avail_out); -+#endif -+ -+ if ((ret = deflate(&os->zs, 0)) != Z_OK) { -+ rfbLog("zrleOutStreamOverrun: deflate failed with error code %d\n", ret); -+ return 0; -+ } -+ -+#ifdef ZRLE_DEBUG -+ rfbLog("zrleOutStreamOverrun: after deflate: %d bytes\n", -+ os->zs.next_out - os->out.ptr); -+#endif -+ -+ os->out.ptr = os->zs.next_out; -+ } while (os->zs.avail_out == 0); -+ -+ /* output buffer not full */ -+ -+ if (os->zs.avail_in == 0) { -+ os->in.ptr = os->in.start; -+ } else { -+ /* but didn't consume all the data? try shifting what's left to the -+ * start of the buffer. -+ */ -+ rfbLog("zrleOutStreamOverrun: out buf not full, but in data not consumed\n"); -+ memmove(os->in.start, os->zs.next_in, os->in.ptr - os->zs.next_in); -+ os->in.ptr -= os->zs.next_in - os->in.start; -+ } -+ } -+ -+ if (size > os->in.end - os->in.ptr) -+ size = os->in.end - os->in.ptr; -+ -+ return size; -+} -+ -+static int zrleOutStreamCheck(zrleOutStream *os, int size) -+{ -+ if (os->in.ptr + size > os->in.end) { -+ return zrleOutStreamOverrun(os, size); -+ } -+ return size; -+} -+ -+void zrleOutStreamWriteBytes(zrleOutStream *os, -+ const zrle_U8 *data, -+ int length) -+{ -+ const zrle_U8* dataEnd = data + length; -+ while (data < dataEnd) { -+ int n = zrleOutStreamCheck(os, dataEnd - data); -+ memcpy(os->in.ptr, data, n); -+ os->in.ptr += n; -+ data += n; -+ } -+} -+ -+void zrleOutStreamWriteU8(zrleOutStream *os, zrle_U8 u) -+{ -+ zrleOutStreamCheck(os, 1); -+ *os->in.ptr++ = u; -+} -+ -+void zrleOutStreamWriteOpaque8(zrleOutStream *os, zrle_U8 u) -+{ -+ zrleOutStreamCheck(os, 1); -+ *os->in.ptr++ = u; -+} -+ -+void zrleOutStreamWriteOpaque16 (zrleOutStream *os, zrle_U16 u) -+{ -+ zrleOutStreamCheck(os, 2); -+ *os->in.ptr++ = ((zrle_U8*)&u)[0]; -+ *os->in.ptr++ = ((zrle_U8*)&u)[1]; -+} -+ -+void zrleOutStreamWriteOpaque32 (zrleOutStream *os, zrle_U32 u) -+{ -+ zrleOutStreamCheck(os, 4); -+ *os->in.ptr++ = ((zrle_U8*)&u)[0]; -+ *os->in.ptr++ = ((zrle_U8*)&u)[1]; -+ *os->in.ptr++ = ((zrle_U8*)&u)[2]; -+ *os->in.ptr++ = ((zrle_U8*)&u)[3]; -+} -+ -+void zrleOutStreamWriteOpaque24A(zrleOutStream *os, zrle_U32 u) -+{ -+ zrleOutStreamCheck(os, 3); -+ *os->in.ptr++ = ((zrle_U8*)&u)[0]; -+ *os->in.ptr++ = ((zrle_U8*)&u)[1]; -+ *os->in.ptr++ = ((zrle_U8*)&u)[2]; -+} -+ -+void zrleOutStreamWriteOpaque24B(zrleOutStream *os, zrle_U32 u) -+{ -+ zrleOutStreamCheck(os, 3); -+ *os->in.ptr++ = ((zrle_U8*)&u)[1]; -+ *os->in.ptr++ = ((zrle_U8*)&u)[2]; -+ *os->in.ptr++ = ((zrle_U8*)&u)[3]; -+} -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrleoutstream.h vnc_unixsrc/vncviewer/zrleoutstream.h ---- vnc_unixsrc.orig/vncviewer/zrleoutstream.h 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/zrleoutstream.h 2004-05-25 06:05:15.000000000 -0400 -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. -+ * Copyright (C) 2003 Sun Microsystems, Inc. -+ * -+ * 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. -+ */ -+ -+#ifndef __ZRLE_OUT_STREAM_H__ -+#define __ZRLE_OUT_STREAM_H__ -+ -+#include <zlib.h> -+#include "zrletypes.h" -+#include "rfb/rfb.h" -+ -+typedef struct { -+ zrle_U8 *start; -+ zrle_U8 *ptr; -+ zrle_U8 *end; -+} zrleBuffer; -+ -+typedef struct { -+ zrleBuffer in; -+ zrleBuffer out; -+ -+ z_stream zs; -+} zrleOutStream; -+ -+#define ZRLE_BUFFER_LENGTH(b) ((b)->ptr - (b)->start) -+ -+zrleOutStream *zrleOutStreamNew (void); -+void zrleOutStreamFree (zrleOutStream *os); -+rfbBool zrleOutStreamFlush (zrleOutStream *os); -+void zrleOutStreamWriteBytes (zrleOutStream *os, -+ const zrle_U8 *data, -+ int length); -+void zrleOutStreamWriteU8 (zrleOutStream *os, -+ zrle_U8 u); -+void zrleOutStreamWriteOpaque8 (zrleOutStream *os, -+ zrle_U8 u); -+void zrleOutStreamWriteOpaque16 (zrleOutStream *os, -+ zrle_U16 u); -+void zrleOutStreamWriteOpaque32 (zrleOutStream *os, -+ zrle_U32 u); -+void zrleOutStreamWriteOpaque24A(zrleOutStream *os, -+ zrle_U32 u); -+void zrleOutStreamWriteOpaque24B(zrleOutStream *os, -+ zrle_U32 u); -+ -+#endif /* __ZRLE_OUT_STREAM_H__ */ -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrlepalettehelper.c vnc_unixsrc/vncviewer/zrlepalettehelper.c ---- vnc_unixsrc.orig/vncviewer/zrlepalettehelper.c 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/zrlepalettehelper.c 2004-05-25 06:05:15.000000000 -0400 -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. -+ * Copyright (C) 2003 Sun Microsystems, Inc. -+ * -+ * 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. -+ */ -+ -+#include "zrlepalettehelper.h" -+#include <assert.h> -+#include <string.h> -+ -+#define ZRLE_HASH(pix) (((pix) ^ ((pix) >> 17)) & 4095) -+ -+void zrlePaletteHelperInit(zrlePaletteHelper *helper) -+{ -+ memset(helper->palette, 0, sizeof(helper->palette)); -+ memset(helper->index, 255, sizeof(helper->index)); -+ memset(helper->key, 0, sizeof(helper->key)); -+ helper->size = 0; -+} -+ -+void zrlePaletteHelperInsert(zrlePaletteHelper *helper, zrle_U32 pix) -+{ -+ if (helper->size < ZRLE_PALETTE_MAX_SIZE) { -+ int i = ZRLE_HASH(pix); -+ -+ while (helper->index[i] != 255 && helper->key[i] != pix) -+ i++; -+ if (helper->index[i] != 255) return; -+ -+ helper->index[i] = helper->size; -+ helper->key[i] = pix; -+ helper->palette[helper->size] = pix; -+ } -+ helper->size++; -+} -+ -+int zrlePaletteHelperLookup(zrlePaletteHelper *helper, zrle_U32 pix) -+{ -+ int i = ZRLE_HASH(pix); -+ -+ assert(helper->size <= ZRLE_PALETTE_MAX_SIZE); -+ -+ while (helper->index[i] != 255 && helper->key[i] != pix) -+ i++; -+ if (helper->index[i] != 255) return helper->index[i]; -+ -+ return -1; -+} -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrlepalettehelper.h vnc_unixsrc/vncviewer/zrlepalettehelper.h ---- vnc_unixsrc.orig/vncviewer/zrlepalettehelper.h 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/zrlepalettehelper.h 2004-05-25 06:05:15.000000000 -0400 -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2002 RealVNC Ltd. All Rights Reserved. -+ * Copyright (C) 2003 Sun Microsystems, Inc. -+ * -+ * 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. -+ */ -+ -+/* -+ * The PaletteHelper class helps us build up the palette from pixel data by -+ * storing a reverse index using a simple hash-table -+ */ -+ -+#ifndef __ZRLE_PALETTE_HELPER_H__ -+#define __ZRLE_PALETTE_HELPER_H__ -+ -+#include "zrletypes.h" -+ -+#define ZRLE_PALETTE_MAX_SIZE 127 -+ -+typedef struct { -+ zrle_U32 palette[ZRLE_PALETTE_MAX_SIZE]; -+ zrle_U8 index[ZRLE_PALETTE_MAX_SIZE + 4096]; -+ zrle_U32 key[ZRLE_PALETTE_MAX_SIZE + 4096]; -+ int size; -+} zrlePaletteHelper; -+ -+void zrlePaletteHelperInit (zrlePaletteHelper *helper); -+void zrlePaletteHelperInsert(zrlePaletteHelper *helper, -+ zrle_U32 pix); -+int zrlePaletteHelperLookup(zrlePaletteHelper *helper, -+ zrle_U32 pix); -+ -+#endif /* __ZRLE_PALETTE_HELPER_H__ */ -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zrletypes.h vnc_unixsrc/vncviewer/zrletypes.h ---- vnc_unixsrc.orig/vncviewer/zrletypes.h 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/zrletypes.h 2004-05-25 06:05:15.000000000 -0400 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2002 RealVNC Ltd. 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. -+ */ -+ -+#ifndef __ZRLE_TYPES_H__ -+#define __ZRLE_TYPES_H__ -+ -+typedef unsigned char zrle_U8; -+typedef unsigned short zrle_U16; -+typedef unsigned int zrle_U32; -+typedef signed char zrle_S8; -+typedef signed short zrle_S16; -+typedef signed int zrle_S32; -+ -+#endif /* __ZRLE_TYPES_H__ */ -diff -Naur -X ./exclude vnc_unixsrc.orig/vncviewer/zywrletemplate.c vnc_unixsrc/vncviewer/zywrletemplate.c ---- vnc_unixsrc.orig/vncviewer/zywrletemplate.c 1969-12-31 19:00:00.000000000 -0500 -+++ vnc_unixsrc/vncviewer/zywrletemplate.c 2008-02-15 23:33:13.000000000 -0500 -@@ -0,0 +1,824 @@ -+ -+/******************************************************************** -+ * * -+ * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. * -+ * * -+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * -+ * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. * -+ * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * -+ * * -+ * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 * -+ * BY Hitachi Systems & Services, Ltd. * -+ * (Noriaki Yamazaki, Research & Developement Center) * * -+ * * -+ ******************************************************************** -+Redistribution and use in source and binary forms, with or without -+modification, are permitted provided that the following conditions -+are met: -+ -+- Redistributions of source code must retain the above copyright -+notice, this list of conditions and the following disclaimer. -+ -+- Redistributions in binary form must reproduce the above copyright -+notice, this list of conditions and the following disclaimer in the -+documentation and/or other materials provided with the distribution. -+ -+- Neither the name of the Hitachi Systems & Services, Ltd. nor -+the names of its contributors may be used to endorse or promote -+products derived from this software without specific prior written -+permission. -+ -+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION -+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ ********************************************************************/ -+ -+/* Change Log: -+ V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline -+ (Thanks Johannes Schindelin, author of LibVNC -+ Server/Client) -+ V0.01 : 2007/02/06 : Initial release -+*/ -+ -+/* #define ZYWRLE_ENCODE */ -+/* #define ZYWRLE_DECODE */ -+#define ZYWRLE_QUANTIZE -+ -+/* -+[References] -+ PLHarr: -+ Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy, "An Improved N-Bit to N-Bit Reversible Haar-Like Transform," Pacific Graphics 2004, October 2004, pp. 371-380. -+ EZW: -+ Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients, IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993). -+*/ -+ -+ -+/* Template Macro stuffs. */ -+#undef ZYWRLE_ANALYZE -+#undef ZYWRLE_SYNTHESIZE -+#define ZYWRLE_ANALYZE __RFB_CONCAT3E(zywrleAnalyze,BPP,END_FIX) -+#define ZYWRLE_SYNTHESIZE __RFB_CONCAT3E(zywrleSynthesize,BPP,END_FIX) -+ -+#define ZYWRLE_RGBYUV __RFB_CONCAT3E(zywrleRGBYUV,BPP,END_FIX) -+#define ZYWRLE_YUVRGB __RFB_CONCAT3E(zywrleYUVRGB,BPP,END_FIX) -+#define ZYWRLE_YMASK __RFB_CONCAT2E(ZYWRLE_YMASK,BPP) -+#define ZYWRLE_UVMASK __RFB_CONCAT2E(ZYWRLE_UVMASK,BPP) -+#define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP) -+#define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP) -+ -+/* Packing/Unpacking pixel stuffs. -+ Endian conversion stuffs. */ -+#undef S_0 -+#undef S_1 -+#undef L_0 -+#undef L_1 -+#undef L_2 -+#if ZYWRLE_ENDIAN == ENDIAN_BIG -+# define S_0 1 -+# define S_1 0 -+# define L_0 3 -+# define L_1 2 -+# define L_2 1 -+#else -+# define S_0 0 -+# define S_1 1 -+# define L_0 0 -+# define L_1 1 -+# define L_2 2 -+#endif -+ -+/* Load/Save pixel stuffs. */ -+#define ZYWRLE_YMASK15 0xFFFFFFF8 -+#define ZYWRLE_UVMASK15 0xFFFFFFF8 -+#define ZYWRLE_LOAD_PIXEL15(pSrc,R,G,B) { \ -+ R = (((unsigned char*)pSrc)[S_1]<< 1)& 0xF8; \ -+ G = ((((unsigned char*)pSrc)[S_1]<< 6)|(((unsigned char*)pSrc)[S_0]>> 2))& 0xF8; \ -+ B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \ -+} -+#define ZYWRLE_SAVE_PIXEL15(pDst,R,G,B) { \ -+ R &= 0xF8; \ -+ G &= 0xF8; \ -+ B &= 0xF8; \ -+ ((unsigned char*)pDst)[S_1] = (unsigned char)( (R>>1)|(G>>6) ); \ -+ ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<2))& 0xFF); \ -+} -+#define ZYWRLE_YMASK16 0xFFFFFFFC -+#define ZYWRLE_UVMASK16 0xFFFFFFF8 -+#define ZYWRLE_LOAD_PIXEL16(pSrc,R,G,B) { \ -+ R = ((unsigned char*)pSrc)[S_1] & 0xF8; \ -+ G = ((((unsigned char*)pSrc)[S_1]<< 5)|(((unsigned char*)pSrc)[S_0]>> 3))& 0xFC; \ -+ B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \ -+} -+#define ZYWRLE_SAVE_PIXEL16(pDst,R,G,B) { \ -+ R &= 0xF8; \ -+ G &= 0xFC; \ -+ B &= 0xF8; \ -+ ((unsigned char*)pDst)[S_1] = (unsigned char)( R |(G>>5) ); \ -+ ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<3))& 0xFF); \ -+} -+#define ZYWRLE_YMASK32 0xFFFFFFFF -+#define ZYWRLE_UVMASK32 0xFFFFFFFF -+#define ZYWRLE_LOAD_PIXEL32(pSrc,R,G,B) { \ -+ R = ((unsigned char*)pSrc)[L_2]; \ -+ G = ((unsigned char*)pSrc)[L_1]; \ -+ B = ((unsigned char*)pSrc)[L_0]; \ -+} -+#define ZYWRLE_SAVE_PIXEL32(pDst,R,G,B) { \ -+ ((unsigned char*)pDst)[L_2] = (unsigned char)R; \ -+ ((unsigned char*)pDst)[L_1] = (unsigned char)G; \ -+ ((unsigned char*)pDst)[L_0] = (unsigned char)B; \ -+} -+ -+#ifndef ZYWRLE_ONCE -+#define ZYWRLE_ONCE -+ -+#ifdef WIN32 -+#define InlineX __inline -+#else -+#define InlineX inline -+#endif -+ -+#ifdef ZYWRLE_ENCODE -+/* Tables for Coefficients filtering. */ -+# ifndef ZYWRLE_QUANTIZE -+/* Type A:lower bit omitting of EZW style. */ -+const static unsigned int zywrleParam[3][3]={ -+ {0x0000F000,0x00000000,0x00000000}, -+ {0x0000C000,0x00F0F0F0,0x00000000}, -+ {0x0000C000,0x00C0C0C0,0x00F0F0F0}, -+/* {0x0000FF00,0x00000000,0x00000000}, -+ {0x0000FF00,0x00FFFFFF,0x00000000}, -+ {0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */ -+}; -+# else -+/* Type B:Non liner quantization filter. */ -+static const signed char zywrleConv[4][256]={ -+{ /* bi=5, bo=5 r=0.0:PSNR=24.849 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+}, -+{ /* bi=5, bo=5 r=2.0:PSNR=74.031 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 32, -+ 32, 32, 32, 32, 32, 32, 32, 32, -+ 32, 32, 32, 32, 32, 32, 32, 32, -+ 48, 48, 48, 48, 48, 48, 48, 48, -+ 48, 48, 48, 56, 56, 56, 56, 56, -+ 56, 56, 56, 56, 64, 64, 64, 64, -+ 64, 64, 64, 64, 72, 72, 72, 72, -+ 72, 72, 72, 72, 80, 80, 80, 80, -+ 80, 80, 88, 88, 88, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 96, 96, -+ 96, 96, 96, 104, 104, 104, 104, 104, -+ 104, 104, 104, 104, 104, 112, 112, 112, -+ 112, 112, 112, 112, 112, 112, 120, 120, -+ 120, 120, 120, 120, 120, 120, 120, 120, -+ 0, -120, -120, -120, -120, -120, -120, -120, -+ -120, -120, -120, -112, -112, -112, -112, -112, -+ -112, -112, -112, -112, -104, -104, -104, -104, -+ -104, -104, -104, -104, -104, -104, -96, -96, -+ -96, -96, -96, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -88, -88, -88, -80, -+ -80, -80, -80, -80, -80, -72, -72, -72, -+ -72, -72, -72, -72, -72, -64, -64, -64, -+ -64, -64, -64, -64, -64, -56, -56, -56, -+ -56, -56, -56, -56, -56, -56, -48, -48, -+ -48, -48, -48, -48, -48, -48, -48, -48, -+ -48, -32, -32, -32, -32, -32, -32, -32, -+ -32, -32, -32, -32, -32, -32, -32, -32, -+ -32, -32, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+}, -+{ /* bi=5, bo=4 r=2.0:PSNR=64.441 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 48, 48, 48, 48, 48, 48, 48, 48, -+ 48, 48, 48, 48, 48, 48, 48, 48, -+ 48, 48, 48, 48, 48, 48, 48, 48, -+ 64, 64, 64, 64, 64, 64, 64, 64, -+ 64, 64, 64, 64, 64, 64, 64, 64, -+ 80, 80, 80, 80, 80, 80, 80, 80, -+ 80, 80, 80, 80, 80, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 104, 104, 104, 104, 104, 104, 104, 104, -+ 104, 104, 104, 112, 112, 112, 112, 112, -+ 112, 112, 112, 112, 120, 120, 120, 120, -+ 120, 120, 120, 120, 120, 120, 120, 120, -+ 0, -120, -120, -120, -120, -120, -120, -120, -+ -120, -120, -120, -120, -120, -112, -112, -112, -+ -112, -112, -112, -112, -112, -112, -104, -104, -+ -104, -104, -104, -104, -104, -104, -104, -104, -+ -104, -88, -88, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -80, -80, -80, -80, -+ -80, -80, -80, -80, -80, -80, -80, -80, -+ -80, -64, -64, -64, -64, -64, -64, -64, -+ -64, -64, -64, -64, -64, -64, -64, -64, -+ -64, -48, -48, -48, -48, -48, -48, -48, -+ -48, -48, -48, -48, -48, -48, -48, -48, -+ -48, -48, -48, -48, -48, -48, -48, -48, -+ -48, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+}, -+{ /* bi=5, bo=2 r=2.0:PSNR=43.175 */ -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 88, 88, 88, 88, 88, 88, 88, 88, -+ 0, -88, -88, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -88, -88, -88, -88, -+ -88, -88, -88, -88, -88, -88, -88, -88, -+ -88, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, -+} -+}; -+const static signed char* zywrleParam[3][3][3]={ -+ {{zywrleConv[0],zywrleConv[2],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}}, -+ {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}}, -+ {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[2],zywrleConv[2],zywrleConv[2]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]}}, -+}; -+# endif -+#endif -+ -+static InlineX void Harr(signed char* pX0, signed char* pX1) -+{ -+ /* Piecewise-Linear Harr(PLHarr) */ -+ int X0 = (int)*pX0, X1 = (int)*pX1; -+ int orgX0 = X0, orgX1 = X1; -+ if ((X0 ^ X1) & 0x80) { -+ /* differ sign */ -+ X1 += X0; -+ if (((X1^orgX1)&0x80)==0) { -+ /* |X1| > |X0| */ -+ X0 -= X1; /* H = -B */ -+ } -+ } else { -+ /* same sign */ -+ X0 -= X1; -+ if (((X0 ^ orgX0) & 0x80) == 0) { -+ /* |X0| > |X1| */ -+ X1 += X0; /* L = A */ -+ } -+ } -+ *pX0 = (signed char)X1; -+ *pX1 = (signed char)X0; -+} -+/* -+ 1D-Wavelet transform. -+ -+ In coefficients array, the famous 'pyramid' decomposition is well used. -+ -+ 1D Model: -+ |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0 -+ |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1 -+ -+ But this method needs line buffer because H/L is different position from X0/X1. -+ So, I used 'interleave' decomposition instead of it. -+ -+ 1D Model: -+ |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0 -+ |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1 -+ -+ In this method, H/L and X0/X1 is always same position. -+ This lead us to more speed and less memory. -+ Of cause, the result of both method is quite same -+ because it's only difference that coefficient position. -+*/ -+static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel) -+{ -+ int s, ofs; -+ signed char* pX0; -+ signed char* end; -+ -+ pX0 = (signed char*)data; -+ s = (8<<l)*SkipPixel; -+ end = pX0+(size>>(l+1))*s; -+ s -= 2; -+ ofs = (4<<l)*SkipPixel; -+ while (pX0 < end) { -+ Harr(pX0, pX0+ofs); -+ pX0++; -+ Harr(pX0, pX0+ofs); -+ pX0++; -+ Harr(pX0, pX0+ofs); -+ pX0 += s; -+ } -+} -+#define InvWaveletLevel(d,s,l,pix) WaveletLevel(d,s,l,pix) -+ -+#ifdef ZYWRLE_ENCODE -+# ifndef ZYWRLE_QUANTIZE -+/* Type A:lower bit omitting of EZW style. */ -+static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l) -+{ -+ int r, s; -+ int x, y; -+ int* pH; -+ const unsigned int* pM; -+ -+ pM = &(zywrleParam[level-1][l]); -+ s = 2<<l; -+ for (r = 1; r < 4; r++) { -+ pH = pBuf; -+ if (r & 0x01) -+ pH += s>>1; -+ if (r & 0x02) -+ pH += (s>>1)*width; -+ for (y = 0; y < height / s; y++) { -+ for (x = 0; x < width / s; x++) { -+ /* -+ these are same following code. -+ pH[x] = pH[x] / (~pM[x]+1) * (~pM[x]+1); -+ ( round pH[x] with pM[x] bit ) -+ '&' operator isn't 'round' but is 'floor'. -+ So, we must offset when pH[x] is negative. -+ */ -+ if (((signed char*)pH)[0] & 0x80) -+ ((signed char*)pH)[0] += ~((signed char*)pM)[0]; -+ if (((signed char*)pH)[1] & 0x80) -+ ((signed char*)pH)[1] += ~((signed char*)pM)[1]; -+ if (((signed char*)pH)[2] & 0x80) -+ ((signed char*)pH)[2] += ~((signed char*)pM)[2]; -+ *pH &= *pM; -+ pH += s; -+ } -+ pH += (s-1)*width; -+ } -+ } -+} -+# else -+/* -+ Type B:Non liner quantization filter. -+ -+ Coefficients have Gaussian curve and smaller value which is -+ large part of coefficients isn't more important than larger value. -+ So, I use filter of Non liner quantize/dequantize table. -+ In general, Non liner quantize formula is explained as following. -+ -+ y=f(x) = sign(x)*round( ((abs(x)/(2^7))^ r )* 2^(bo-1) )*2^(8-bo) -+ x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi) -+ ( r:power coefficient bi:effective MSB in input bo:effective MSB in output ) -+ -+ r < 1.0 : Smaller value is more important than larger value. -+ r > 1.0 : Larger value is more important than smaller value. -+ r = 1.0 : Liner quantization which is same with EZW style. -+ -+ r = 0.75 is famous non liner quantization used in MP3 audio codec. -+ In contrast to audio data, larger value is important in wavelet coefficients. -+ So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ). -+ -+ As compared with EZW style liner quantization, this filter tended to be -+ more sharp edge and be more compression rate but be more blocking noise and be less quality. -+ Especially, the surface of graphic objects has distinguishable noise in middle quality mode. -+ -+ We need only quantized-dequantized(filtered) value rather than quantized value itself -+ because all values are packed or palette-lized in later ZRLE section. -+ This lead us not to need to modify client decoder when we change -+ the filtering procedure in future. -+ Client only decodes coefficients given by encoder. -+*/ -+static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l) -+{ -+ int r, s; -+ int x, y; -+ int* pH; -+ const signed char** pM; -+ -+ pM = zywrleParam[level-1][l]; -+ s = 2<<l; -+ for (r = 1; r < 4; r++) { -+ pH = pBuf; -+ if (r & 0x01) -+ pH += s>>1; -+ if (r & 0x02) -+ pH += (s>>1)*width; -+ for (y = 0; y < height / s; y++) { -+ for (x = 0; x < width / s; x++) { -+ ((signed char*)pH)[0] = pM[0][((unsigned char*)pH)[0]]; -+ ((signed char*)pH)[1] = pM[1][((unsigned char*)pH)[1]]; -+ ((signed char*)pH)[2] = pM[2][((unsigned char*)pH)[2]]; -+ pH += s; -+ } -+ pH += (s-1)*width; -+ } -+ } -+} -+# endif -+ -+static InlineX void Wavelet(int* pBuf, int width, int height, int level) -+{ -+ int l, s; -+ int* pTop; -+ int* pEnd; -+ -+ for (l = 0; l < level; l++) { -+ pTop = pBuf; -+ pEnd = pBuf+height*width; -+ s = width<<l; -+ while (pTop < pEnd) { -+ WaveletLevel(pTop, width, l, 1); -+ pTop += s; -+ } -+ pTop = pBuf; -+ pEnd = pBuf+width; -+ s = 1<<l; -+ while (pTop < pEnd) { -+ WaveletLevel(pTop, height,l, width); -+ pTop += s; -+ } -+ FilterWaveletSquare(pBuf, width, height, level, l); -+ } -+} -+#endif -+#ifdef ZYWRLE_DECODE -+static InlineX void InvWavelet(int* pBuf, int width, int height, int level) -+{ -+ int l, s; -+ int* pTop; -+ int* pEnd; -+ -+ for (l = level - 1; l >= 0; l--) { -+ pTop = pBuf; -+ pEnd = pBuf+width; -+ s = 1<<l; -+ while (pTop < pEnd) { -+ InvWaveletLevel(pTop, height,l, width); -+ pTop += s; -+ } -+ pTop = pBuf; -+ pEnd = pBuf+height*width; -+ s = width<<l; -+ while (pTop < pEnd) { -+ InvWaveletLevel(pTop, width, l, 1); -+ pTop += s; -+ } -+ } -+} -+#endif -+ -+/* Load/Save coefficients stuffs. -+ Coefficients manages as 24 bits little-endian pixel. */ -+#define ZYWRLE_LOAD_COEFF(pSrc,R,G,B) { \ -+ R = ((signed char*)pSrc)[2]; \ -+ G = ((signed char*)pSrc)[1]; \ -+ B = ((signed char*)pSrc)[0]; \ -+} -+#define ZYWRLE_SAVE_COEFF(pDst,R,G,B) { \ -+ ((signed char*)pDst)[2] = (signed char)R; \ -+ ((signed char*)pDst)[1] = (signed char)G; \ -+ ((signed char*)pDst)[0] = (signed char)B; \ -+} -+ -+/* -+ RGB <=> YUV conversion stuffs. -+ YUV coversion is explained as following formula in strict meaning: -+ Y = 0.299R + 0.587G + 0.114B ( 0<=Y<=255) -+ U = -0.169R - 0.331G + 0.500B (-128<=U<=127) -+ V = 0.500R - 0.419G - 0.081B (-128<=V<=127) -+ -+ I use simple conversion RCT(reversible color transform) which is described -+ in JPEG-2000 specification. -+ Y = (R + 2G + B)/4 ( 0<=Y<=255) -+ U = B-G (-256<=U<=255) -+ V = R-G (-256<=V<=255) -+*/ -+#define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x))) -+ /* RCT is N-bit RGB to N-bit Y and N+1-bit UV. -+ For make Same N-bit, UV is lossy. -+ More exact PLHarr, we reduce to odd range(-127<=x<=127). */ -+#define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \ -+ Y = (R+(G<<1)+B)>>2; \ -+ U = B-G; \ -+ V = R-G; \ -+ Y -= 128; \ -+ U >>= 1; \ -+ V >>= 1; \ -+ Y &= ymask; \ -+ U &= uvmask; \ -+ V &= uvmask; \ -+ if (Y == -128) \ -+ Y += (0xFFFFFFFF-ymask+1); \ -+ if (U == -128) \ -+ U += (0xFFFFFFFF-uvmask+1); \ -+ if (V == -128) \ -+ V += (0xFFFFFFFF-uvmask+1); \ -+} -+#define ZYWRLE_YUVRGB1(R,G,B,Y,U,V) { \ -+ Y += 128; \ -+ U <<= 1; \ -+ V <<= 1; \ -+ G = Y-((U+V)>>2); \ -+ B = U+G; \ -+ R = V+G; \ -+ G = ROUND(G); \ -+ B = ROUND(B); \ -+ R = ROUND(R); \ -+} -+ -+/* -+ coefficient packing/unpacking stuffs. -+ Wavelet transform makes 4 sub coefficient image from 1 original image. -+ -+ model with pyramid decomposition: -+ +------+------+ -+ | | | -+ | L | Hx | -+ | | | -+ +------+------+ -+ | | | -+ | H | Hxy | -+ | | | -+ +------+------+ -+ -+ So, we must transfer each sub images individually in strict meaning. -+ But at least ZRLE meaning, following one decompositon image is same as -+ avobe individual sub image. I use this format. -+ (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L) -+ for simplified procedure for any wavelet level.) -+ -+ +------+------+ -+ | L | -+ +------+------+ -+ | Hx | -+ +------+------+ -+ | Hy | -+ +------+------+ -+ | Hxy | -+ +------+------+ -+*/ -+#define INC_PTR(data) \ -+ data++; \ -+ if( data-pData >= (w+uw) ){ \ -+ data += scanline-(w+uw); \ -+ pData = data; \ -+ } -+ -+#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,w,h,scanline,level,TRANS) \ -+ pH = pBuf; \ -+ s = 2<<level; \ -+ if (r & 0x01) \ -+ pH += s>>1; \ -+ if (r & 0x02) \ -+ pH += (s>>1)*w; \ -+ pEnd = pH+h*w; \ -+ while (pH < pEnd) { \ -+ pLine = pH+w; \ -+ while (pH < pLine) { \ -+ TRANS \ -+ INC_PTR(data) \ -+ pH += s; \ -+ } \ -+ pH += (s-1)*w; \ -+ } -+ -+#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,scanline,level) \ -+ ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);) -+ -+#define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,scanline,level) \ -+ ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);) -+ -+#define ZYWRLE_SAVE_UNALIGN(data,TRANS) \ -+ pTop = pBuf+w*h; \ -+ pEnd = pBuf + (w+uw)*(h+uh); \ -+ while (pTop < pEnd) { \ -+ TRANS \ -+ INC_PTR(data) \ -+ pTop++; \ -+ } -+ -+#define ZYWRLE_LOAD_UNALIGN(data,TRANS) \ -+ pTop = pBuf+w*h; \ -+ if (uw) { \ -+ pData= data + w; \ -+ pEnd = (int*)(pData+ h*scanline); \ -+ while (pData < (PIXEL_T*)pEnd) { \ -+ pLine = (int*)(pData + uw); \ -+ while (pData < (PIXEL_T*)pLine) { \ -+ TRANS \ -+ pData++; \ -+ pTop++; \ -+ } \ -+ pData += scanline-uw; \ -+ } \ -+ } \ -+ if (uh) { \ -+ pData= data + h*scanline; \ -+ pEnd = (int*)(pData+ uh*scanline); \ -+ while (pData < (PIXEL_T*)pEnd) { \ -+ pLine = (int*)(pData + w); \ -+ while (pData < (PIXEL_T*)pLine) { \ -+ TRANS \ -+ pData++; \ -+ pTop++; \ -+ } \ -+ pData += scanline-w; \ -+ } \ -+ } \ -+ if (uw && uh) { \ -+ pData= data + w+ h*scanline; \ -+ pEnd = (int*)(pData+ uh*scanline); \ -+ while (pData < (PIXEL_T*)pEnd) { \ -+ pLine = (int*)(pData + uw); \ -+ while (pData < (PIXEL_T*)pLine) { \ -+ TRANS \ -+ pData++; \ -+ pTop++; \ -+ } \ -+ pData += scanline-uw; \ -+ } \ -+ } -+ -+static InlineX void zywrleCalcSize(int* pW, int* pH, int level) -+{ -+ *pW &= ~((1<<level)-1); -+ *pH &= ~((1<<level)-1); -+} -+ -+#endif /* ZYWRLE_ONCE */ -+ -+#ifndef CPIXEL -+#ifdef ZYWRLE_ENCODE -+static InlineX void ZYWRLE_RGBYUV(int* pBuf, PIXEL_T* data, int width, int height, int scanline) -+{ -+ int R, G, B; -+ int Y, U, V; -+ int* pLine; -+ int* pEnd; -+ pEnd = pBuf+height*width; -+ while (pBuf < pEnd) { -+ pLine = pBuf+width; -+ while (pBuf < pLine) { -+ ZYWRLE_LOAD_PIXEL(data,R,G,B); -+ ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ZYWRLE_YMASK,ZYWRLE_UVMASK); -+ ZYWRLE_SAVE_COEFF(pBuf,V,Y,U); -+ pBuf++; -+ data++; -+ } -+ data += scanline-width; -+ } -+} -+#endif -+#ifdef ZYWRLE_DECODE -+static InlineX void ZYWRLE_YUVRGB(int* pBuf, PIXEL_T* data, int width, int height, int scanline) { -+ int R, G, B; -+ int Y, U, V; -+ int* pLine; -+ int* pEnd; -+ pEnd = pBuf+height*width; -+ while (pBuf < pEnd) { -+ pLine = pBuf+width; -+ while (pBuf < pLine) { -+ ZYWRLE_LOAD_COEFF(pBuf,V,Y,U); -+ ZYWRLE_YUVRGB1(R,G,B,Y,U,V); -+ ZYWRLE_SAVE_PIXEL(data,R,G,B); -+ pBuf++; -+ data++; -+ } -+ data += scanline-width; -+ } -+} -+#endif -+ -+#ifdef ZYWRLE_ENCODE -+PIXEL_T* ZYWRLE_ANALYZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) { -+ int l; -+ int uw = w; -+ int uh = h; -+ int* pTop; -+ int* pEnd; -+ int* pLine; -+ PIXEL_T* pData; -+ int R, G, B; -+ int s; -+ int* pH; -+ -+ zywrleCalcSize(&w, &h, level); -+ if (w == 0 || h == 0) -+ return NULL; -+ uw -= w; -+ uh -= h; -+ -+ pData = dst; -+ ZYWRLE_LOAD_UNALIGN(src,*(PIXEL_T*)pTop=*pData;) -+ ZYWRLE_RGBYUV(pBuf, src, w, h, scanline); -+ Wavelet(pBuf, w, h, level); -+ for (l = 0; l < level; l++) { -+ ZYWRLE_PACK_COEFF(pBuf, dst, 3, w, h, scanline, l); -+ ZYWRLE_PACK_COEFF(pBuf, dst, 2, w, h, scanline, l); -+ ZYWRLE_PACK_COEFF(pBuf, dst, 1, w, h, scanline, l); -+ if (l == level - 1) { -+ ZYWRLE_PACK_COEFF(pBuf, dst, 0, w, h, scanline, l); -+ } -+ } -+ ZYWRLE_SAVE_UNALIGN(dst,*dst=*(PIXEL_T*)pTop;) -+ return dst; -+} -+#endif -+#ifdef ZYWRLE_DECODE -+PIXEL_T* ZYWRLE_SYNTHESIZE(PIXEL_T* dst, PIXEL_T* src, int w, int h, int scanline, int level, int* pBuf) -+{ -+ int l; -+ int uw = w; -+ int uh = h; -+ int* pTop; -+ int* pEnd; -+ int* pLine; -+ PIXEL_T* pData; -+ int R, G, B; -+ int s; -+ int* pH; -+ -+ zywrleCalcSize(&w, &h, level); -+ if (w == 0 || h == 0) -+ return NULL; -+ uw -= w; -+ uh -= h; -+ -+ pData = src; -+ for (l = 0; l < level; l++) { -+ ZYWRLE_UNPACK_COEFF(pBuf, src, 3, w, h, scanline, l); -+ ZYWRLE_UNPACK_COEFF(pBuf, src, 2, w, h, scanline, l); -+ ZYWRLE_UNPACK_COEFF(pBuf, src, 1, w, h, scanline, l); -+ if (l == level - 1) { -+ ZYWRLE_UNPACK_COEFF(pBuf, src, 0, w, h, scanline, l); -+ } -+ } -+ ZYWRLE_SAVE_UNALIGN(src,*(PIXEL_T*)pTop=*src;) -+ InvWavelet(pBuf, w, h, level); -+ ZYWRLE_YUVRGB(pBuf, dst, w, h, scanline); -+ ZYWRLE_LOAD_UNALIGN(dst,*pData=*(PIXEL_T*)pTop;) -+ return src; -+} -+#endif -+#endif /* CPIXEL */ -+ -+#undef ZYWRLE_RGBYUV -+#undef ZYWRLE_YUVRGB -+#undef ZYWRLE_LOAD_PIXEL -+#undef ZYWRLE_SAVE_PIXEL -diff -Naur -X ./exclude vnc_unixsrc.orig/include/rfbproto.h vnc_unixsrc/include/rfbproto.h ---- vnc_unixsrc.orig/include/rfbproto.h 2004-05-27 03:02:02.000000000 -0400 -+++ vnc_unixsrc/include/rfbproto.h 2010-02-25 21:54:58.000000000 -0500 -@@ -205,7 +205,22 @@ - #define rfbSecTypeInvalid 0 - #define rfbSecTypeNone 1 - #define rfbSecTypeVncAuth 2 -+#define rfbSecTypeRA2 5 -+#define rfbSecTypeRA2ne 6 - #define rfbSecTypeTight 16 -+#define rfbSecTypeUltra 17 -+ -+/* try to support VeNCrypt and TLS */ -+#define rfbSecTypeAnonTls 18 -+#define rfbSecTypeVencrypt 19 -+ -+#define rfbVencryptPlain 256 -+#define rfbVencryptTlsNone 257 -+#define rfbVencryptTlsVnc 258 -+#define rfbVencryptTlsPlain 259 -+#define rfbVencryptX509None 260 -+#define rfbVencryptX509Vnc 261 -+#define rfbVencryptX509Plain 262 - - - /*----------------------------------------------------------------------------- -@@ -381,6 +396,11 @@ - #define rfbBell 2 - #define rfbServerCutText 3 - -+#define rfbResizeFrameBuffer 4 /* Modif sf@2002 */ -+ -+/* http://sourceforge.net/projects/vncsessmgr */ -+#define rfbRestartConnection 82 -+ - #define rfbFileListData 130 - #define rfbFileDownloadData 131 - #define rfbFileUploadCancel 132 -@@ -403,6 +423,18 @@ - #define rfbPointerEvent 5 - #define rfbClientCutText 6 - -+/* ultra */ -+ -+#define rfbFileTransfer 7 -+#define rfbSetScale 8 -+#define rfbSetServerInput 9 -+#define rfbSetSW 10 -+#define rfbTextChat 11 -+#define rfbKeyFrameRequest 12 -+#define rfbPalmVNCSetScaleFactor 0xF -+ -+ -+ - #define rfbFileListRequest 130 - #define rfbFileDownloadRequest 131 - #define rfbFileUploadRequest 132 -@@ -435,6 +467,13 @@ - #define rfbEncodingTight 7 - #define rfbEncodingZlibHex 8 - -+#define rfbEncodingZRLE 16 -+/* -+nyama/2006/08/02:new YUV-Wavlet lossy codec based on ZRLE (ZYWRLE) -+ */ -+#define rfbEncodingZYWRLE 17 -+ -+ - /* signatures for basic encoding types */ - #define sig_rfbEncodingRaw "RAW_____" - #define sig_rfbEncodingCopyRect "COPYRECT" -@@ -955,6 +994,51 @@ - #define sz_rfbFileDownloadFailedMsg 4 - - /*----------------------------------------------------------------------------- -+ * RestartConnection - the server has restarted the client connection. -+ */ -+ -+typedef struct _rfbRestartConnectionMsg { -+ CARD8 type; /* always rfbRestartConnection */ -+ CARD8 pad1; -+ CARD16 pad2; -+ CARD32 length; -+ /* followed by char text[length] */ -+} rfbRestartConnectionMsg; -+ -+#define sz_rfbRestartConnectionMsg 8 -+ -+ -+typedef struct _rfbTextChatMsg { -+ CARD8 type; /* always rfbTextChat */ -+ CARD8 pad1; /* Could be used later as an additionnal param */ -+ CARD16 pad2; /* Could be used later as text offset, for instance */ -+ CARD32 length; /* Specific values for Open, close, finished (-1, -2, -3) */ -+ /* followed by char text[length] */ -+} rfbTextChatMsg; -+ -+#define sz_rfbTextChatMsg 8 -+ -+#define rfbTextMaxSize 4096 -+#define rfbTextChatOpen 0xFFFFFFFF -+#define rfbTextChatClose 0xFFFFFFFE -+#define rfbTextChatFinished 0xFFFFFFFD -+ -+/*----------------------------------------------------------------------------- -+ * Modif sf@2002 -+ * ResizeFrameBuffer - The Client must change the size of its framebuffer -+ */ -+ -+typedef struct _rfbResizeFrameBufferMsg { -+ CARD8 type; /* always rfbResizeFrameBuffer */ -+ CARD8 pad1; -+ CARD16 framebufferWidth; /* FrameBuffer width */ -+ CARD16 framebufferHeight; /* FrameBuffer height */ -+} rfbResizeFrameBufferMsg; -+ -+#define sz_rfbResizeFrameBufferMsg 6 -+ -+ -+/*----------------------------------------------------------------------------- - * Union of all server->client messages. - */ - -@@ -968,6 +1052,8 @@ - rfbFileDownloadDataMsg fdd; - rfbFileUploadCancelMsg fuc; - rfbFileDownloadFailedMsg fdf; -+ rfbRestartConnectionMsg rc; -+ rfbTextChatMsg tc; - } rfbServerToClientMsg; - - -@@ -1221,6 +1307,41 @@ - - #define sz_rfbFileCreateDirRequestMsg 4 - -+/* ultra */ -+typedef struct _rfbSetScaleMsg { -+ CARD8 type; /* always rfbSetScale */ -+ CARD8 scale; /* Scale value 1<sv<n */ -+ CARD16 pad; -+} rfbSetScaleMsg; -+ -+#define sz_rfbSetScaleMsg 4 -+ -+typedef struct { -+ CARD8 type; /* always rfbSetScaleFactor */ -+ -+ CARD8 scale; /* Scale factor (positive non-zero integer) */ -+ CARD16 pad2; -+} rfbPalmVNCSetScaleFactorMsg; -+ -+#define sz_rfbPalmVNCSetScaleFactorMsg (4) -+ -+typedef struct _rfbSetServerInputMsg { -+ CARD8 type; /* always rfbSetServerInputMsg */ -+ CARD8 status; /* on or off */ -+ CARD16 pad; -+} rfbSetServerInputMsg; -+ -+#define sz_rfbSetServerInputMsg 4 -+ -+typedef struct _rfbSetSWMsg { -+ CARD8 type; /* always rfbSetSW */ -+ CARD8 status; -+ CARD16 x; -+ CARD16 y; -+} rfbSetSWMsg; -+ -+#define sz_rfbSetSWMsg 6 -+ - /*----------------------------------------------------------------------------- - * Union of all client->server messages. - */ -@@ -1241,4 +1362,9 @@ - rfbFileDownloadCancelMsg fdc; - rfbFileUploadFailedMsg fuf; - rfbFileCreateDirRequestMsg fcdr; -+ rfbSetScaleMsg ssc; -+ rfbPalmVNCSetScaleFactorMsg pssf; -+ rfbSetServerInputMsg sim; -+ rfbSetSWMsg sw; -+ rfbTextChatMsg tc; - } rfbClientToServerMsg; -diff -Naur -X ./exclude vnc_unixsrc.orig/include/vncauth.h vnc_unixsrc/include/vncauth.h ---- vnc_unixsrc.orig/include/vncauth.h 2000-06-11 08:00:53.000000000 -0400 -+++ vnc_unixsrc/include/vncauth.h 2009-03-21 00:37:23.000000000 -0400 -@@ -23,8 +23,11 @@ - - #define MAXPWLEN 8 - #define CHALLENGESIZE 16 -+#define CHALLENGESIZE_MSLOGON 64 - - extern int vncEncryptAndStorePasswd(char *passwd, char *fname); - extern char *vncDecryptPasswdFromFile(char *fname); - extern void vncRandomBytes(unsigned char *bytes); - extern void vncEncryptBytes(unsigned char *bytes, char *passwd); -+ -+extern void vncEncryptPasswd_MSLOGON(unsigned char *encryptedPasswd, char *passwd); -diff -Naur -X ./exclude vnc_unixsrc.orig/libvncauth/d3des.c vnc_unixsrc/libvncauth/d3des.c ---- vnc_unixsrc.orig/libvncauth/d3des.c 2000-06-11 08:00:53.000000000 -0400 -+++ vnc_unixsrc/libvncauth/d3des.c 2010-02-25 21:49:02.000000000 -0500 -@@ -34,12 +34,15 @@ - static void cookey(unsigned long *); - - static unsigned long KnL[32] = { 0L }; -+/* no londer used: */ -+#if 0 - static unsigned long KnR[32] = { 0L }; - static unsigned long Kn3[32] = { 0L }; - static unsigned char Df_Key[24] = { - 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, - 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, - 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; -+#endif - - static unsigned short bytebit[8] = { - 01, 02, 04, 010, 020, 040, 0100, 0200 }; -diff -Naur -X ./exclude vnc_unixsrc.orig/libvncauth/vncauth.c vnc_unixsrc/libvncauth/vncauth.c ---- vnc_unixsrc.orig/libvncauth/vncauth.c 2003-03-01 11:48:06.000000000 -0500 -+++ vnc_unixsrc/libvncauth/vncauth.c 2010-02-25 21:47:25.000000000 -0500 -@@ -27,9 +27,11 @@ - #include <sys/types.h> - #include <sys/stat.h> - #include <unistd.h> -+#include <time.h> - #include <vncauth.h> - #include <d3des.h> - -+#include <fcntl.h> - - /* - * Make sure we call srandom() only once. -@@ -45,6 +47,8 @@ - - static unsigned char s_fixedkey[8] = {23,82,107,6,35,78,88,7}; - -+int vncEncryptAndStorePasswd2(char *passwd, char *passwdViewOnly, char *fname); -+int vncDecryptPasswdFromFile2(char *fname, char *passwdFullControl, char *passwdViewOnly); - - /* - * Encrypt a password and store it in a file. Returns 0 if successful, -@@ -73,7 +77,7 @@ - vncEncryptAndStorePasswd2(char *passwd, char *passwdViewOnly, char *fname) - { - FILE *fp; -- int i, bytesToWrite, bytesWrote; -+ int bytesToWrite, bytesWrote; - unsigned char encryptedPasswd[16] = { - 0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0 -@@ -195,6 +199,44 @@ - return (i < 16) ? 1 : 2; - } - -+unsigned int urandom(void) { -+ unsigned int val = 0; -+ struct stat sb; -+ int fd = -1; -+ if (fd < 0 && stat("/dev/urandom", &sb) == 0) { -+ fd = open("/dev/urandom", O_RDONLY); -+ } -+ if (fd < 0 && stat("/dev/random", &sb) == 0) { -+ fd = open("/dev/random", O_RDONLY); -+ } -+ if (fd < 0 && stat("/proc/loadavg", &sb) == 0) { -+ fd = open("/proc/loadavg", O_RDONLY); -+ } -+ if (fd < 0 && stat("/bin/bash", &sb) == 0) { -+ fd = open("/bin/bash", O_RDONLY); -+ lseek(fd, (off_t) (unsigned int) getpid(), SEEK_SET); -+ } -+ if (fd >= 0) { -+ int i; -+ for (i=0; i < 3; i++) { -+ char buf[2]; -+ if (read(fd, buf, 1) > 0) { -+ unsigned char uc = (unsigned char) buf[0]; -+ if (i==0) { -+ val += uc; -+ } else if (i==1) { -+ val += uc * 256; -+ } else if (i==2) { -+ val += uc * 256 * 256; -+ } -+ } -+ } -+ close(fd); -+ } else { -+ val = (unsigned int) getpid(); -+ } -+ return val; -+} - - /* - * Generate CHALLENGESIZE random bytes for use in challenge-response -@@ -207,11 +249,13 @@ - int i; - unsigned int seed; - -- if (!s_srandom_called) { -- seed = (unsigned int)time(0) ^ (unsigned int)getpid(); -- srandom(seed); -- s_srandom_called = 1; -- } -+ if (!s_srandom_called) { -+ seed = (unsigned int)time(0) ^ (unsigned int)getpid(); -+ seed += urandom(); -+ -+ srandom(seed); -+ s_srandom_called = 1; -+ } - - for (i = 0; i < CHALLENGESIZE; i++) { - bytes[i] = (unsigned char)(random() & 255); -@@ -245,3 +289,48 @@ - des(bytes+i, bytes+i); - } - } -+ -+void UvncEncryptPasswd_MSLOGON(unsigned char *encryptedPasswd, char *passwd) { -+ unsigned int i; -+ for (i=0; i < 32; i++) { -+ if (i < strlen(passwd)) { -+ encryptedPasswd[i] = passwd[i]; -+ } else { -+ encryptedPasswd[i] = '\0'; -+ } -+ } -+ deskey(s_fixedkey, EN0); -+ des(encryptedPasswd, encryptedPasswd); -+} -+ -+void UvncEncryptBytes2(unsigned char *where, int length, unsigned char *key) { -+ int i, j; -+ deskey(key, EN0); -+ for (i=0; i < 8; i++) { -+ where[i] ^= key[i]; -+ } -+ des(where, where); -+ for (i=8; i < length; i += 8) { -+ for (j=0; j < 8; j++) { -+ where[i+j] ^= where[i+j-8]; -+ } -+ des(where+i, where+i); -+ } -+} -+ -+void UvncDecryptBytes2(unsigned char *where, int length, unsigned char *key) { -+ int i, j; -+ deskey(key, DE1); -+ for (i = length - 8; i > 0; i -= 8) { -+ des(where + i, where + i); -+ for (j=0; j < 8; j++) { -+ where[i+j] ^= where[i+j-8]; -+ } -+ } -+ /* i=0 */ -+ des(where, where); -+ for (i=0; i < 8; i++) { -+ where[i] ^= key[i]; -+ } -+} -+ diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fullscreen.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fullscreen.patch deleted file mode 100644 index 97494ee..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fullscreen.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- vnc_unixsrc.orig/vncviewer/fullscreen.c 2003-10-09 05:23:49.000000000 -0400 -+++ vnc_unixsrc/vncviewer/fullscreen.c 2004-12-26 21:21:44.000000000 -0500 -@@ -173,9 +173,15 @@ - XtVaSetValues(popup, XtNoverrideRedirect, True, NULL); - - /* Try to get the input focus. */ -- -+ -+#if 0 - XSetInputFocus(dpy, DefaultRootWindow(dpy), RevertToPointerRoot, - CurrentTime); -+#else -+ XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, -+ CurrentTime); -+#endif -+ - - /* Optionally, grab the keyboard. */ - -@@ -184,6 +190,10 @@ - GrabModeAsync, CurrentTime) != GrabSuccess) { - fprintf(stderr, "XtGrabKeyboard() failed.\n"); - } -+if (getenv("VNCVIEWER_GRAB_SERVER") != NULL) { /* runge bot of FullScreenOn */ -+ fprintf(stderr, "calling XGrabServer(dpy)\n"); -+ XGrabServer(dpy); -+} - } - - -@@ -210,6 +220,11 @@ - - appData.fullScreen = False; - -+if (getenv("VNCVIEWER_GRAB_SERVER") != NULL) { /* runge top of FullScreenOff */ -+ fprintf(stderr, "calling XUngrabServer(dpy)\n"); -+ XUngrabServer(dpy); -+} -+ - if (appData.grabKeyboard) - XtUngrabKeyboard(desktop, CurrentTime); - diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-newfbsize.patch b/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-newfbsize.patch deleted file mode 100644 index 9e2c811..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-newfbsize.patch +++ /dev/null @@ -1,286 +0,0 @@ ---- vnc_unixsrc.orig/vncviewer/desktop.c 2004-05-28 13:29:29.000000000 -0400 -+++ vnc_unixsrc/vncviewer/desktop.c 2007-01-13 13:59:51.000000000 -0500 -@@ -50,6 +50,30 @@ - }, - }; - -+void create_image() { -+ image = NULL; -+ -+#ifdef MITSHM -+ if (appData.useShm) { -+ image = CreateShmImage(); -+ if (!image) -+ appData.useShm = False; -+ } -+#endif -+ -+ if (!image) { -+ image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, -+ si.framebufferWidth, si.framebufferHeight, -+ BitmapPad(dpy), 0); -+ -+ image->data = malloc(image->bytes_per_line * image->height); -+ if (!image->data) { -+ fprintf(stderr,"malloc failed\n"); -+ exit(1); -+ } -+ } -+} -+ - - /* - * DesktopInitBeforeRealization creates the "desktop" widget and the viewport -@@ -82,30 +106,9 @@ - for (i = 0; i < 256; i++) - modifierPressed[i] = False; - -- image = NULL; -- --#ifdef MITSHM -- if (appData.useShm) { -- image = CreateShmImage(); -- if (!image) -- appData.useShm = False; -- } --#endif -- -- if (!image) { -- image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL, -- si.framebufferWidth, si.framebufferHeight, -- BitmapPad(dpy), 0); -- -- image->data = malloc(image->bytes_per_line * image->height); -- if (!image->data) { -- fprintf(stderr,"malloc failed\n"); -- exit(1); -- } -- } -+ create_image(); - } - -- - /* - * DesktopInitAfterRealization does things which require the X windows to - * exist. It creates some GCs and sets the dot cursor. -@@ -460,3 +463,70 @@ - break; - } - } -+ -+static void reset_image(void) { -+ if (UsingShm()) { -+ ShmCleanup(); -+ } else { -+ if (image && image->data) { -+ free(image->data); -+ /* see manpage XDestroyImage may also free data, so we skip and have a tiny leak instead */ -+ if (0) XDestroyImage(image); -+ image = NULL; -+ } -+ } -+ create_image(); -+ XFlush(dpy); -+} -+ -+void ReDoDesktop(void) { -+ int w, h, x, y, dw, dh; -+ -+ if (appData.fullScreen) { -+ if (image && image->data) { -+ int len; -+ int h = image->height; -+ int w = image->width; -+ len = image->bytes_per_line * image->height; -+ /* black out window first: */ -+ memset(image->data, 0, len); -+ XPutImage(dpy, XtWindow(desktop), gc, image, 0, 0, 0, 0, w, h); -+ XFlush(dpy); -+ } -+ XtResizeWidget(desktop, si.framebufferWidth, si.framebufferHeight, 0); -+ XSync(dpy, False); -+ usleep(100*1000); -+ FullScreenOn(); -+ XSync(dpy, False); -+ usleep(100*1000); -+ reset_image(); -+ return; -+ } -+ -+ dw = appData.wmDecorationWidth; -+ dh = appData.wmDecorationHeight; -+ -+ w = si.framebufferWidth; -+ h = si.framebufferHeight; -+ -+ if (w + dw >= dpyWidth) { -+ w = dpyWidth - dw; -+ } -+ if (h + dh >= dpyHeight) { -+ h = dpyHeight - dh; -+ } -+ -+ XtVaSetValues(toplevel, XtNmaxWidth, w, XtNmaxHeight, h, NULL); -+ -+ XtVaSetValues(desktop, XtNwidth, si.framebufferWidth, -+ XtNheight, si.framebufferHeight, NULL); -+ -+ x = (dpyWidth - w - dw)/2; -+ y = (dpyHeight - h - dh)/2; -+ -+ XtResizeWidget(desktop, si.framebufferWidth, si.framebufferHeight, 0); -+ -+ XtConfigureWidget(toplevel, x + dw, y + dh, w, h, 0); -+ -+ reset_image(); -+} ---- vnc_unixsrc.orig/vncviewer/fullscreen.c 2003-10-09 05:23:49.000000000 -0400 -+++ vnc_unixsrc/vncviewer/fullscreen.c 2006-07-27 14:36:06.000000000 -0400 -@@ -85,10 +85,13 @@ - Dimension oldViewportWidth, oldViewportHeight, clipWidth, clipHeight; - Position viewportX, viewportY; - -+ Bool fsAlready = appData.fullScreen, toobig = False; -+ - appData.fullScreen = True; - - if (si.framebufferWidth > dpyWidth || si.framebufferHeight > dpyHeight) { - -+ toobig = True; - XtVaSetValues(viewport, XtNforceBars, True, NULL); - XtVaGetValues(viewport, XtNwidth, &oldViewportWidth, - XtNheight, &oldViewportHeight, NULL); -@@ -129,6 +132,7 @@ - reparenting our window to the root. The window manager will get a - ReparentNotify and hopefully clean up its frame window. */ - -+if (! fsAlready) { - XtVaSetValues(toplevel, XtNoverrideRedirect, True, NULL); - - XReparentWindow(dpy, XtWindow(toplevel), DefaultRootWindow(dpy), 0, 0); -@@ -164,10 +168,22 @@ - - XtManageChild(viewport); - -- /* Now we can set "toplevel" to its proper size. */ -+} else { -+ XSync(dpy, False); -+} - -+ /* Now we can set "toplevel" to its proper size. */ - XtResizeWidget(toplevel, toplevelWidth, toplevelHeight, 0); - -+if (fsAlready) { -+ XtResizeWidget(viewport, viewportWidth, viewportHeight, 0); -+ if (! toobig) { -+ XtVaSetValues(viewport, XtNforceBars, False, NULL); -+ } -+ XMoveWindow(dpy, XtWindow(viewport), viewportX, viewportY); -+ XSync(dpy, False); -+} -+ - /* Set the popup to overrideRedirect too */ - - XtVaSetValues(popup, XtNoverrideRedirect, True, NULL); ---- vnc_unixsrc.orig/vncviewer/rfbproto.c 2004-03-11 13:14:39.000000000 -0500 -+++ vnc_unixsrc/vncviewer/rfbproto.c 2006-07-25 21:51:20.000000000 -0400 -@@ -177,6 +177,9 @@ - sig_rfbEncodingPointerPos, "Pointer position update"); - CapsAdd(encodingCaps, rfbEncodingLastRect, rfbTightVncVendor, - sig_rfbEncodingLastRect, "LastRect protocol extension"); -+ -+ CapsAdd(encodingCaps, rfbEncodingNewFBSize, rfbTightVncVendor, -+ sig_rfbEncodingNewFBSize, "New FB size protocol extension"); - } - - -@@ -729,6 +732,7 @@ - Bool requestCompressLevel = False; - Bool requestQualityLevel = False; - Bool requestLastRectEncoding = False; -+ Bool requestNewFBSizeEncoding = True; - - spf.type = rfbSetPixelFormat; - spf.format = myFormat; -@@ -806,6 +810,10 @@ - if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) { - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); - } -+ -+ if (se->nEncodings < MAX_ENCODINGS && requestNewFBSizeEncoding) { -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize); -+ } - } - else { - if (SameMachine(rfbsock)) { -@@ -849,6 +857,7 @@ - } - - encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect); -+ encs[se->nEncodings++] = Swap32IfLE(rfbEncodingNewFBSize); - } - - len = sz_rfbSetEncodingsMsg + se->nEncodings * 4; -@@ -1038,6 +1047,16 @@ - } - continue; - } -+ if (rect.encoding == rfbEncodingNewFBSize) { -+ fprintf(stderr,"New Size: %dx%d at (%d, %d)\n", -+ rect.r.w, rect.r.h, rect.r.x, rect.r.y); -+ si.framebufferWidth = rect.r.w; -+ si.framebufferHeight = rect.r.h; -+ fprintf(stderr, "si: %d %d\n", si.framebufferWidth, si.framebufferHeight); -+ ReDoDesktop(); -+ -+ continue; -+ } - - if ((rect.r.x + rect.r.w > si.framebufferWidth) || - (rect.r.y + rect.r.h > si.framebufferHeight)) ---- vnc_unixsrc.orig/vncviewer/shm.c 2000-06-11 08:00:53.000000000 -0400 -+++ vnc_unixsrc/vncviewer/shm.c 2006-07-26 23:30:42.000000000 -0400 -@@ -41,6 +41,10 @@ - } - } - -+Bool UsingShm() { -+ return needShmCleanup; -+} -+ - static int - ShmCreationXErrorHandler(Display *dpy, XErrorEvent *error) - { ---- vnc_unixsrc.orig/vncviewer/vncviewer.h 2004-03-11 13:14:40.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer.h 2006-07-26 23:31:25.000000000 -0400 -@@ -162,6 +162,8 @@ - extern void CopyDataToScreen(char *buf, int x, int y, int width, int height); - extern void SynchroniseScreen(); - -+extern void ReDoDesktop(); -+ - /* dialogs.c */ - - extern void ServerDialogDone(Widget w, XEvent *event, String *params, -@@ -243,6 +245,7 @@ - - extern XImage *CreateShmImage(); - extern void ShmCleanup(); -+extern Bool UsingShm(); - - /* sockets.c */ - ---- vnc_unixsrc.orig/vncviewer/vncviewer.c 2004-01-13 09:22:05.000000000 -0500 -+++ vnc_unixsrc/vncviewer/vncviewer.c 2006-07-27 19:00:25.000000000 -0400 -@@ -57,6 +57,11 @@ - } - } - -+ if (argc > 1 && strstr(argv[1], "-h") == argv[1]) { -+ usage(); -+ return 0; -+ } -+ - /* Call the main Xt initialisation function. It parses command-line options, - generating appropriate resource specs, and makes a connection to the X - display. */ diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README b/x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README deleted file mode 100644 index a211377..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README +++ /dev/null @@ -1,16 +0,0 @@ -This is where we keep the 3rd party source zip and tar.gz files used -to build this package. - -www.stunnel.org source 488512 Jul 25 15:09 stunnel-4.14.tar.gz -http://stunnel.mirt.net -www.tightvnc.com source 2182134 Jul 25 15:11 tightvnc-1.3dev7_unixsrc.tar.gz -www.tightvnc.com windows - standalone viewer binary: 209149 Jul 25 15:10 tightvnc-1.3dev7_x86_viewer.zip - -To save space they may not be included in the package you downloaded. -The should be included in the "ssvnc_all-<version>.zip" file. -Go to the websites indicated above or contact me if you cannot find them. - -The stunnel.patched.tar vnc_unixsrc_vncviewer.patched.tar -files are tarballs of the original sources above with patches applied -(used by build.unix script when patching fails). diff --git a/x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop b/x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop deleted file mode 100644 index 2ff26b6..0000000 --- a/x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop +++ /dev/null @@ -1,11 +0,0 @@ -[Desktop Entry] -# Copy this file to "/usr/shared/applications/ssvnc.desktop" then SSVNC will -# appear in desktop menus (once they are updated; e.g. update-menus command). -Name=SSL/SSH VNC Viewer -Comment=SSVNC - access remote VNC desktops -Exec=ssvnc -noenc -Icon=computer -Terminal=false -Type=Application -StartupWMClass=Ssvnc.tcl -Categories=Network;RemoteAccess; diff --git a/x11vnc/misc/inet6to4 b/x11vnc/misc/inet6to4 deleted file mode 100755 index 0067a99..0000000 --- a/x11vnc/misc/inet6to4 +++ /dev/null @@ -1,420 +0,0 @@ -#!/usr/bin/perl -# -# inet6to4: Act as an ipv6-to-ipv4 relay for tcp applications that -# do not support ipv6. -# -# Usage: inet6to4 <ipv6-listen-port> <ipv4-host:port> -# inet6to4 -r <ipv4-listen-port> <ipv6-host:port> -# -# Examples: inet6to4 5900 localhost:5900 -# inet6to4 8080 web1:80 -# inet6to4 -r 5900 fe80::217:f2ff:fee6:6f5a%eth0:5900 -# -# The -r option reverses the direction of translation (e.g. for ipv4 -# clients that need to connect to ipv6 servers.) Reversing is the default -# if this script is named 'inet4to6' (e.g. by a symlink.) -# -# Use Ctrl-C to stop this program. You can also supply '-c n' as the -# first option to only handle that many connections. -# -# Also set the env. vars INET6TO4_LOOP=1 or INET6TO4_LOOP=BG -# to have an outer loop restarting this program (BG means do that -# in the background), and INET6TO4_LOGFILE for a log file. -# Also set INET6TO4_VERBOSE to verbosity level and INET6TO4_WAITTIME -# and INET6TO4_PIDFILE (see below.) -# - -#------------------------------------------------------------------------- -# Copyright (c) 2010 by Karl J. Runge <runge@karlrunge.com> -# -# inet6to4 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. -# -# inet6to4 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 inet6to4; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see <http://www.gnu.org/licenses/>. -#------------------------------------------------------------------------- - -my $program = "inet6to4"; - -# Set up logging: -# -if (exists $ENV{INET6TO4_LOGFILE}) { - close STDOUT; - if (!open(STDOUT, ">>$ENV{INET6TO4_LOGFILE}")) { - die "$program: $ENV{INET6TO4_LOGFILE} $!\n"; - } - close STDERR; - open(STDERR, ">&STDOUT"); -} -select(STDERR); $| = 1; -select(STDOUT); $| = 1; - -# interrupt handler: -# -my $looppid = ''; -my $pidfile = ''; -my $listen_sock = ''; # declared here for get_out() -# -sub get_out { - print STDERR "$_[0]:\t$$ looppid=$looppid\n"; - close $listen_sock if $listen_sock; - if ($looppid) { - kill 'TERM', $looppid; - fsleep(0.2); - } - unlink $pidfile if $pidfile; - exit 0; -} -$SIG{INT} = \&get_out; -$SIG{TERM} = \&get_out; - -# pidfile: -# -sub open_pidfile { - if (exists $ENV{INET6TO4_PIDFILE}) { - my $pf = $ENV{INET6TO4_PIDFILE}; - if (open(PID, ">$pf")) { - print PID "$$\n"; - close PID; - $pidfile = $pf; - } else { - print STDERR "could not open pidfile: $pf - $! - continuing...\n"; - } - delete $ENV{INET6TO4_PIDFILE}; - } -} - -#################################################################### -# Set INET6TO4_LOOP=1 to have this script create an outer loop -# restarting itself if it ever exits. Set INET6TO4_LOOP=BG to -# do this in the background as a daemon. - -if (exists $ENV{INET6TO4_LOOP}) { - my $csl = $ENV{INET6TO4_LOOP}; - if ($csl ne 'BG' && $csl ne '1') { - die "$program: invalid INET6TO4_LOOP.\n"; - } - if ($csl eq 'BG') { - # go into bg as "daemon": - setpgrp(0, 0); - my $pid = fork(); - if (! defined $pid) { - die "$program: $!\n"; - } elsif ($pid) { - wait; - exit 0; - } - if (fork) { - exit 0; - } - setpgrp(0, 0); - close STDIN; - if (! $ENV{INET6TO4_LOGFILE}) { - close STDOUT; - close STDERR; - } - } - delete $ENV{INET6TO4_LOOP}; - - if (exists $ENV{INET6TO4_PIDFILE}) { - open_pidfile(); - } - - print STDERR "$program: starting service at ", scalar(localtime), " master-pid=$$\n"; - while (1) { - $looppid = fork; - if (! defined $looppid) { - sleep 10; - } elsif ($looppid) { - wait; - } else { - exec $0, @ARGV; - exit 1; - } - print STDERR "$program: re-starting service at ", scalar(localtime), " master-pid=$$\n"; - sleep 1; - } - exit 0; -} -if (exists $ENV{INET6TO4_PIDFILE}) { - open_pidfile(); -} - -use IO::Socket::INET6; -use strict; -use warnings; - -# some settings: -# -my $verbose = 1; # set to 0 for no messages, 2 for more. -my $killpid = 1; # does kill(2) at end of connection. -my $waittime = 0.25; # time to wait between connections. -my $reverse = 0; # -r switch (or file named inet4to6) - -if (exists $ENV{INET6TO4_VERBOSE}) { - $verbose = $ENV{INET6TO4_VERBOSE}; -} -if (exists $ENV{INET6TO4_WAITTIME}) { - $waittime = $ENV{INET6TO4_WAITTIME}; -} - -# process command line args: - -if (! @ARGV || $ARGV[0] =~ '^-+h') { # -help - open(ME, "<$0"); - while (<ME>) { - last unless /^#/; - next if /usr.bin.perl/; - $_ =~ s/# ?//; - print; - } - exit; -} - -my $cmax = 0; -if ($ARGV[0] eq '-c') { # -c - shift; - $cmax = shift; -} - -if ($ARGV[0] eq '-r') { # -r - shift; - $reverse = 1; -} elsif ($0 =~ /inet4to6$/) { - $reverse = 1; -} - -my $listen_port = shift; # ipv6-listen-port -my $connect_to = shift; # ipv4-host:port - -die "no listen port or connect-to-host:port\n" if ! $listen_port || ! $connect_to; - -# connect to host: -# -my $host = ''; -my $port = ''; -if ($connect_to =~ /^(.*):(\d+)$/) { - $host = $1; - $port = $2; -} -die "invalid connect-to-host:port\n" if ! $host || ! $port; - -setpgrp(0, 0); - -# create listening socket: -# -my %opts; -$opts{Listen} = 10; -$opts{Proto} = "tcp"; -$opts{ReuseAddr} = 1; -if ($listen_port =~ /^(.*):(\d+)$/) { - $opts{LocalAddr} = $1; - $listen_port = $2; -} -$opts{LocalPort} = $listen_port; - -if (!$reverse) { - # force ipv6 interface: - $opts{Domain} = AF_INET6; - $listen_sock = IO::Socket::INET6->new(%opts); -} else { - $listen_sock = IO::Socket::INET->new(%opts); - if (! $listen_sock && $! =~ /invalid/i) { - warn "$program: $!, retrying with AF_UNSPEC:\n"; - $opts{Domain} = AF_UNSPEC; - $listen_sock = IO::Socket::INET6->new(%opts); - } -} -if (! $listen_sock) { - die "$program: $!\n"; -} - -# for use by the xfer helper processes' interrupt handlers: -# -my $current_fh1 = ''; -my $current_fh2 = ''; - -# connection counter: -# -my $conn = 0; - -# loop forever waiting for connections: -# -while (1) { - $conn++; - if ($cmax > 0 && $conn > $cmax) { - print STDERR "last connection ($cmax)\n" if $verbose; - last; - } - print STDERR "listening for connection: $conn\n" if $verbose; - my ($client, $ip) = $listen_sock->accept(); - - if ($client && !$reverse && $port == $listen_port) { - # This happens on Darwin 'tcp46' - if ($client->peerhost() =~ /^::ffff:/) { - print STDERR "closing client we think is actually us: ", - $client->peerhost(), "\n"; - close $client; - $client = undef; - } - } - if (! $client) { - # to throttle runaways - fsleep(2 * $waittime); - next; - } - print STDERR "conn: $conn -- ", $client->peerhost(), " at ", scalar(localtime), "\n" if $verbose; - - # spawn helper: - # - my $pid = fork(); - if (! defined $pid) { - die "$program: $!\n"; - } elsif ($pid) { - wait; - # to throttle runaways - fsleep($waittime); - next; - } else { - # this is to avoid zombies: - close $listen_sock; - if (fork) { - exit 0; - } - setpgrp(0, 0); - handle_conn($client); - } -} - -exit 0; - -sub handle_conn { - my $client = shift; - - my $start = time(); - - print STDERR "connecting to: $host:$port\n" if $verbose; - - my $sock = ''; - my %opts; - $opts{PeerAddr} = $host; - $opts{PeerPort} = $port; - $opts{Proto} = "tcp"; - if (!$reverse) { - $sock = IO::Socket::INET->new(%opts); - } else { - $opts{Domain} = AF_INET6; - $sock = IO::Socket::INET6->new(%opts); - } - if (! $sock) { - warn "$program: $!, retrying with AF_UNSPEC:\n"; - $opts{Domain} = AF_UNSPEC; - $sock = IO::Socket::INET6->new(%opts); - } - - if (! $sock) { - close $client; - die "$program: $!\n"; - } - - $current_fh1 = $client; - $current_fh2 = $sock; - - # interrupt handler: - # - $SIG{TERM} = sub {print STDERR "got sigterm\[$$]\n" if $verbose; close $current_fh1; close $current_fh2; exit 0}; - - # spawn another helper and transfer the data: - # - my $parent = $$; - if (my $child = fork()) { - xfer($sock, $client, 'S->C'); - if ($killpid) { - fsleep(0.5); - kill 'TERM', $child; - } - } else { - xfer($client, $sock, 'C->S'); - if ($killpid) { - fsleep(0.75); - kill 'TERM', $parent; - } - } - - # done. - # - if ($verbose > 1) { - my $dt = time() - $start; - print STDERR "dt\[$$]: $dt\n"; - } - exit 0; -} - -# transfers data in one direction: -# -sub xfer { - my($in, $out, $lab) = @_; - my ($RIN, $WIN, $EIN, $ROUT); - $RIN = $WIN = $EIN = ""; - $ROUT = ""; - vec($RIN, fileno($in), 1) = 1; - vec($WIN, fileno($in), 1) = 1; - $EIN = $RIN | $WIN; - my $buf; - - while (1) { - my $nf = 0; - while (! $nf) { - $nf = select($ROUT=$RIN, undef, undef, undef); - } - my $len = sysread($in, $buf, 8192); - if (! defined($len)) { - next if $! =~ /^Interrupted/; - print STDERR "$program\[$lab/$conn/$$]: $!\n"; - last; - } elsif ($len == 0) { - print STDERR "$program\[$lab/$conn/$$]: " - . "Input is EOF.\n"; - last; - } - - if ($verbose > 4) { - # verbose debugging of data: - syswrite(STDERR , "\n$lab: ", 6); - syswrite(STDERR , $buf, $len); - } - - my $offset = 0; - my $quit = 0; - while ($len) { - my $written = syswrite($out, $buf, $len, $offset); - if (! defined $written) { - print STDERR "$program\[$lab/$conn/$$]: " - . "Output is EOF. $!\n"; - $quit = 1; - last; - } - $len -= $written; - $offset += $written; - } - last if $quit; - } - close($in); - close($out); -} - -# sleep a fraction of a second: -# -sub fsleep { - my ($time) = @_; - select(undef, undef, undef, $time) if $time; -} diff --git a/x11vnc/misc/panner.pl b/x11vnc/misc/panner.pl deleted file mode 100755 index 344beee..0000000 --- a/x11vnc/misc/panner.pl +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/perl -# -# panner.pl: start up x11vnc in '-clip' mode viewing a small (WxH) -# rectangular region of the screen. Allow the viewer user -# to 'pan' around the display region by moving the mouse. -# -# Remote interaction with applications, e.g. clicking a -# button though the VNC viewer, will be very difficult. -# This may be useful in a 'demo' mode where the user sitting -# at the physical display is the only one moving the mouse. -# Depending on your usage the following x11vnc options may -# be useful: -nonap -# -# Usage: panner.pl WxH <x11vnc-args> (e.g. -display ...) -# or panner.pl WxH:0.05 <x11vnc-args> (e.g. 0.05 is polling time in secs.) - -use strict; - -my $WxH = shift; -my $poll_time; - -# split off poll time: -# -($WxH, $poll_time) = split(/:/, $WxH); -my ($W, $H) = split(/x/, $WxH); - -$poll_time = 0.1 unless $poll_time ne ''; - -# set to x11vnc command (e.g. full PATH) -# -my $x11vnc = "x11vnc"; - -# check if display was given: -# -my $query_args = ""; -for (my $i=0; $i < @ARGV; $i++) { - if ($ARGV[$i] eq '-display') { - $query_args = "-display $ARGV[$i+1]"; - } -} - -# find the size of display and the current mouse position: -my %v; -vset("DIRECT:wdpy_x,wdpy_y,pointer_x,pointer_y,pointer_same"); - -# set a -clip argument based on the above: -# -my $clip = ''; -clip_set(); -$clip = "${W}x${H}+0+0" unless $v{pointer_same}; - -# launch x11vnc with -clip in the background: -# -my $cmd = "$x11vnc -clip $clip -bg " . join(" ", @ARGV); -print STDERR "running: $cmd\n"; -system $cmd; - -# user can hit Ctrl-C or kill this script to quit (and stop x11vnc) -# -sub quit { - system("$x11vnc $query_args -R stop"); - exit 0; -} - -$SIG{INT} = \&quit; -$SIG{TERM} = \&quit; - -# loop forever waiting for mouse position to change, then shift -clip: -# -my $clip_old = $clip; -while (1) { - fsleep($poll_time); - vset("pointer_x,pointer_y,pointer_same"); - next unless $v{pointer_same}; - clip_set(); - if ($clip ne $clip_old) { - system("$x11vnc $query_args -R clip:$clip"); - $clip_old = $clip - } -} - -exit 0; - -# short sleep: -# -sub fsleep { - my ($time) = @_; - select(undef, undef, undef, $time) if $time; -} - -# set the -clip string, making sure view doesn't go off edges of display: -# -sub clip_set { - my $x = int($v{pointer_x} - $W/2); - my $y = int($v{pointer_y} - $H/2); - $x = 0 if $x < 0; - $y = 0 if $y < 0; - $x = $v{wdpy_x} - $W if $x + $W > $v{wdpy_x}; - $y = $v{wdpy_y} - $H if $y + $H > $v{wdpy_y}; - $clip = "${W}x${H}+$x+$y"; -} - -# query x11vnc for values, put results in the %v hash: -# -sub vset { - my $str = shift; - my $out = `$x11vnc $query_args -Q $str 2>/dev/null`; - chomp $out; - foreach my $pair (split(/,/, $out)) { - $pair =~ s/^a..=//; - my ($k, $v) = split(/:/, $pair, 2); - if ($k ne '' && $v ne '') { - print STDERR "k=$k v=$v\n" if $ENV{DEBUG}; - $v{$k} = $v; - } - } -} diff --git a/x11vnc/misc/qt_tslib_inject.pl b/x11vnc/misc/qt_tslib_inject.pl deleted file mode 100755 index d69d174..0000000 --- a/x11vnc/misc/qt_tslib_inject.pl +++ /dev/null @@ -1,1064 +0,0 @@ -#!/usr/bin/perl -# -# qt_tslib_inject.pl: -# -# touch screen input injection tool for use with x11vnc. -# -# example usage: -# -# x11vnc ... -rawfb console -pipeinput ./qt_tslib_inject_input.pl -env INJECT_OPTIONS=cal=/etc/pointercal -# -# See options below. -# -# tested on qtmoko (neo freerunner) with tslib. - -# -# Copyright (c) 2010 by Karl J. Runge <runge@karlrunge.com> -# -# qt_tslib_inject.pl 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. -# -# qt_tslib_inject.pl 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 qt_tslib_inject.pl; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see <http://www.gnu.org/licenses/>. -# - -set_constants(); - -# one can set these env. vars. before running: - -# the device file to inject the events into: -# -$dev = $ENV{INJECT_DEV}; -$dev = "/dev/input/event1" unless $dev; - -# options, see below. useful: cal=/etc/pointercal -# -$options = $ENV{INJECT_OPTIONS}; -$options = '' unless $options ne ''; - -$debug = 0; # enable debugging output: -$pressure = 1; # level of touch pad pressure for click. -$btn_touch = 0; # send BTN_TOUCH on clicks instead of pressure changes. -$absalways = 0; # send a zero pressure absolute position event whenever mouse moves. -$dragskip = 0; # how often to skip injecting motion event while dragging. - -$a_xform = ''; # tslib's calibration coefficients. -@a = (); - -%keycmds = (); # user defined hotkeys to run external commands. - -# separate the options by comma, e.g. pressure=5,cal=/etc/pointercal - -if ($options =~ /absalways/i) { - # set to always send a zero pressure ABS event when mouse moves - $absalways = 1; -} -if ($options =~ /btn_touch/i) { - # send BTN_TOUCH on clicks. - $btn_touch = 1; -} -if ($options =~ /pressure=(\d+)/i) { - # level of touchpad pressure to use on a touch. - $pressure = $1; -} -if ($options =~ /dragskip=(\d+)/i) { - # when dragging with pressure, skip this many events. - $dragskip = $1; -} -if ($options =~ /cal=([^,]+)/i) { - # tslib's /etc/pointercal linear transform: - $a_xform = $1; - if (-f $a_xform) { - $a_xform = `head -n 1 '$a_xform'`; - chomp $a_xform; - $a_xform =~ s/^\s*//; - $a_xform =~ s/\s*$//; - } -} -if ($options =~ /keycmds=([^,]+)/i) { - # format: keysym1:command1+keysym2:command2+... - # e.g.: keycmds=F6:date+F7:'./x11vnc-0.9.10 -connect ./ctl.txt -R reset' - my $str = $1; - if (-f $str && open(F, "<$str")) { - $str = ''; - while (<F>) { - chomp; - $_ =~ s/^\s*//; - $_ =~ s/\s*$//; - next if /^#/; - next if $_ eq ""; - $str .= '+' if $str ne ''; - $str .= $_; - } - close F; - } - foreach my $part (split(/\+/, $str)) { - my ($key, $cmd) = split(/:/, $part, 2); - if ($key !~ /^\s*$/) { - $keycmds{$key} = $cmd; - } - } -} -if ($options =~ /debug=(\d+)/i) { - # debug printout - $debug = $1; -} elsif ($options =~ /debug/i) { - $debug = 1; -} - -# end of the top part that user should read and understand -# for setting options, etc. -###################################################################### - -$start = time(); - -# open the device for writing: -# -$modes = $O_WRONLY; -printf("open modes: 0x%x\n", $modes) if $debug; - -sysopen(FD, $dev, $modes) || die "$dev: $!"; - -my $curr_mask = 0; -my $curr_x = 0; -my $curr_y = 0; -my $down_count = 0; - -# read input events from x11vnc through STDIN: -# -while (<>) { - chomp; - if (/^Pointer/) { - my ($p, $client, $x, $y, $mask, $hint) = split(' ', $_, 6); - do_pointer($client, $x, $y, $mask, $hint); - } elsif (/^Keysym/) { - my ($k, $client, $down, $keysym, $name, $hint) = split(' ', $_, 6); - do_keysym($client, $down, $keysym, $name, $hint); - } -} - -close(FD); - -exit(0); - -sub do_keysym { - # qtmoko/neo does not support keystroke input. so these will be ignored. - # (one possibility would to be enable qtmoko to read from /dev/tty0. - # but the injection mechanism would need to be modified.) - my ($client, $down, $keysym, $name, $hint) = @_; - - $ENV{DO_KEYSYM} = "$client $down $keysym $name $hint"; - - # one could implement his own 'hot keys' here. - - # process any keycmds: - if (%keycmds && (exists $keycmds{$name} || exists $keycmds{ALL})) { - my $cmd = $keycmds{$name}; - if (!exists $keycmds{$name}) { - $cmd = $keycmds{ALL}; - print STDERR "keycmds: $name/ALL: running: $cmd\n"; - system("$cmd"); - } elsif ($down) { - print STDERR "keycmds: $name: running: $cmd\n"; - system("$cmd"); - } - return; - } - - $name = "XK_$name"; - my $nolookup = 0; - if (! exists $key_lookup{$name}) { - $nolookup = 1; - } elsif (! defined $key_lookup{$name}) { - $nolookup = 2; - } elsif ($key_lookup{$name} =~ /^\s*$/) { - $nolookup = 3; - } - if ($nolookup) { - print STDERR "do_keysym: key not implemented-$nolookup $down $keysym $name $hint.\n" if $debug; - return; - } - - print STDERR gettime() . " do_keysym: $name\n" if $debug; - do_key($key_lookup{$name}, $down); -} - -sub do_pointer { - my ($client, $x, $y, $mask, $hint) = @_; - my $x2 = $x; - my $y2 = $y; - if ($a_xform ne '') { - # this is tslib's /etc/pointercal format. - if (! @a) { - # -528 33408 -3417516 -44200 408 40292028 56541 - @a = split(' ', $a_xform); - foreach my $a (@a) { - $a += 0.0; - } - } - # this is the inverse of the tslib transformation: - # - $x2 = ( $a[4] * ($a[6] * $x - $a[2]) - $a[1] * ($a[6] * $y - $a[5]) ) - / ( $a[4] * $a[0] - $a[1] * $a[3]); - $y2 = ( $a[0] * ($a[6] * $y - $a[5]) - $a[3] * ($a[6] * $x - $a[2]) ) - / ( $a[4] * $a[0] - $a[1] * $a[3]); - $x2 = int($x2); - $y2 = int($y2); - } - - print STDERR gettime() . " do_pointer $x $y (=> $x2 $y2) $mask $hint.\n" if $debug; - - if (! $btn_touch) { - if ($curr_mask == 0 && $mask == 0) { - do_abs($x2, $y2, 0) if $absalways; - } elsif ($curr_mask == 0 && $mask != 0) { - do_abs($x2, $y2, $pressure); - $down_count = 0; - } elsif ($curr_mask != 0 && $mask == 0) { - do_abs($x2, $y2, 0); - } elsif ($curr_mask != 0 && $mask != 0) { - $down_count++; - if ($dragskip > 0) { - if ($down_count % $dragskip == 0) { - do_abs($x2, $y2, $pressure); - } else { - print STDERR "dragskip $down_count $dragskip\n" if $debug; - } - } else { - do_abs($x2, $y2, $pressure); - } - } - } else { - if ($curr_mask == 0 && $mask == 0) { - do_abs($x2, $y2, 0) if $absalways; - } elsif ($curr_mask == 0 && $mask != 0) { - do_abs($x2, $y2, 0); - do_btn($BTN_TOUCH, 1); - } elsif ($curr_mask != 0 && $mask == 0) { - do_abs($x2, $y2, 0); - do_btn($BTN_TOUCH, 0); - } elsif ($curr_mask != 0 && $mask != 0) { - ; - } - } - - $curr_mask = $mask; - $curr_x = $x2; - $curr_y = $y2; -} - -# struct input_event { -# struct timeval time; -# __u16 type; -# __u16 code; -# __s32 value; -# }; - -sub do_syn { - my $ev = gtod(); - $ev .= pack("S", $EV_SYN); - $ev .= pack("S", $SYN_REPORT); - $ev .= pack("i", 0); - print STDERR "do_syn EV_SYN\n" if $debug; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_syn: $!\n"; - } -} - -sub do_key { - # not supported by qtmoko - my ($key, $down) = @_; - my $ev = gtod(); - $ev .= pack("S", $EV_KEY); - $ev .= pack("S", $key); - $ev .= pack("i", $down); - print STDERR "do_key $key $down\n" if $debug; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_key: $!\n"; - } - do_syn(); -} - -sub do_btn { - # only BTN_TOUCH supported by qtmoko (but it seems to be ignored??) - my ($button, $down) = @_; - my $ev = gtod(); - $ev .= pack("S", $EV_KEY); - $ev .= pack("S", $button); - $ev .= pack("i", $down); - print STDERR "do_btn $button $down\n" if $debug; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_btn: $!\n"; - } - do_syn(); -} - -sub do_abs { - # absolute method is the workhorse for the touchscreen. - my ($x, $y, $p) = @_; - my $ev = gtod(); - $ev .= pack("S", $EV_ABS); - $ev .= pack("S", $ABS_Y); - $ev .= pack("i", $y); - print STDERR "do_abs y=$y\n" if $debug; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_abs: $!\n"; - } - $ev = gtod(); - $ev .= pack("S", $EV_ABS); - $ev .= pack("S", $ABS_X); - $ev .= pack("i", $x); - print STDERR "do_abs x=$x\n" if $debug; - $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_abs: $!\n"; - } - $ev = gtod(); - $ev .= pack("S", $EV_ABS); - $ev .= pack("S", $ABS_PRESSURE); - $ev .= pack("i", $p); - print STDERR "do_abs p=$p\n" if $debug; - $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_abs: $!\n"; - } - do_syn(); -} - -sub do_rel { - # not supported by qtmoko - my ($dx, $dy) = @_; - my $ev = gtod(); - $ev .= pack("S", $EV_REL); - $ev .= pack("S", $REL_Y); - $ev .= pack("i", $dy); - print STDERR "do_rel dy=$dy\n" if $debug; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_rel: $!\n"; - } - $ev = gtod(); - $ev .= pack("S", $EV_REL); - $ev .= pack("S", $REL_X); - $ev .= pack("i", $dx); - print STDERR "do_rel dx=$dx\n"; - $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_rel: $!\n"; - } - do_syn(); -} - -sub gtod { - # 32 bit machines. TBD use perl module Time:HiRes. - $tv = ("\0" x 4) x 2; # assumes long is 4 bytes. should use pack. - $tz = ("\0" x 4) x 2; - syscall($linux_gettimeofday_syscall, $tv, $tz); - return $tv; -} - -sub gettime { - my $tv = gtod(); - my ($tv_sec, $tv_usec) = unpack("L2", $tv); - $tv_usec2 = sprintf("%8.6f", $tv_usec/1000000.0); - if ( $tv_usec2 =~ /^0\./ ) { - $tv_usec2 =~ s/^0\././; - $tv_sec = "$tv_sec$tv_usec2"; - } else { - $tv_sec = $tv_sec + ($tv_usec/1000000.0); - } - return sprintf("%.3f", $tv_sec - $start); -} - -sub fsleep { - my ($time) = @_; - select(undef, undef, undef, $time) if $time; -} - -sub set_constants { - -# from /usr/include/linux/uinput.h /usr/include/linux/input.h and x11vnc. - -# #define ABS_MAX 0x3f = 63 -# -# #define UINPUT_MAX_NAME_SIZE 80 -# -# struct input_id { -# __u16 bustype; -# __u16 vendor; -# __u16 product; -# __u16 version; -# }; -# -# struct uinput_user_dev { -# char name[UINPUT_MAX_NAME_SIZE]; -# struct input_id id; -# int ff_effects_max; -# int absmax[ABS_MAX + 1]; -# int absmin[ABS_MAX + 1]; -# int absfuzz[ABS_MAX + 1]; -# int absflat[ABS_MAX + 1]; -# }; -# #endif /* __UINPUT_H_ */ - -$EV_SYN = 0x00; -$EV_KEY = 0x01; -$EV_REL = 0x02; -$EV_ABS = 0x03; -$EV_MSC = 0x04; -$EV_SW = 0x05; -$EV_LED = 0x11; -$EV_SND = 0x12; -$EV_REP = 0x14; -$EV_FF = 0x15; -$EV_PWR = 0x16; -$EV_FF_STATUS = 0x17; -$EV_MAX = 0x1f; - -$ID_BUS = 0; -$ID_VENDOR = 1; -$ID_PRODUCT = 2; -$ID_VERSION = 3; - -$BUS_PCI = 0x01; -$BUS_ISAPNP = 0x02; -$BUS_USB = 0x03; -$BUS_HIL = 0x04; -$BUS_BLUETOOTH = 0x05; -$BUS_VIRTUAL = 0x06; - -$BUS_ISA = 0x10; -$BUS_I8042 = 0x11; -$BUS_XTKBD = 0x12; -$BUS_RS232 = 0x13; -$BUS_GAMEPORT = 0x14; -$BUS_PARPORT = 0x15; -$BUS_AMIGA = 0x16; -$BUS_ADB = 0x17; -$BUS_I2C = 0x18; -$BUS_HOST = 0x19; -$BUS_GSC = 0x1A; -$BUS_ATARI = 0x1B; - -$REL_X = 0x00; -$REL_Y = 0x01; -$REL_Z = 0x02; -$REL_RX = 0x03; -$REL_RY = 0x04; -$REL_RZ = 0x05; -$REL_HWHEEL = 0x06; -$REL_DIAL = 0x07; -$REL_WHEEL = 0x08; -$REL_MISC = 0x09; - -$ABS_X = 0x00; -$ABS_Y = 0x01; -$ABS_Z = 0x02; -$ABS_RX = 0x03; -$ABS_RY = 0x04; -$ABS_RZ = 0x05; -$ABS_THROTTLE = 0x06; -$ABS_RUDDER = 0x07; -$ABS_WHEEL = 0x08; -$ABS_GAS = 0x09; -$ABS_BRAKE = 0x0a; -$ABS_HAT0X = 0x10; -$ABS_HAT0Y = 0x11; -$ABS_HAT1X = 0x12; -$ABS_HAT1Y = 0x13; -$ABS_HAT2X = 0x14; -$ABS_HAT2Y = 0x15; -$ABS_HAT3X = 0x16; -$ABS_HAT3Y = 0x17; -$ABS_PRESSURE = 0x18; -$ABS_DISTANCE = 0x19; -$ABS_TILT_X = 0x1a; -$ABS_TILT_Y = 0x1b; -$ABS_TOOL_WIDTH = 0x1c; -$ABS_VOLUME = 0x20; -$ABS_MISC = 0x28; -$ABS_MT_TOUCH_MAJOR = 0x30; -$ABS_MT_TOUCH_MINOR = 0x31; -$ABS_MT_WIDTH_MAJOR = 0x32; -$ABS_MT_WIDTH_MINOR = 0x33; -$ABS_MT_ORIENTATION = 0x34; -$ABS_MT_POSITION_X = 0x35; -$ABS_MT_POSITION_Y = 0x36; -$ABS_MT_TOOL_TYPE = 0x37; -$ABS_MT_BLOB_ID = 0x38; -$ABS_MT_TRACKING_ID = 0x39; -#$ABS_MAX = 0x3f; - - -$BTN_MISC = 0x100; -$BTN_0 = 0x100; -$BTN_1 = 0x101; -$BTN_2 = 0x102; -$BTN_3 = 0x103; -$BTN_4 = 0x104; -$BTN_5 = 0x105; -$BTN_6 = 0x106; -$BTN_7 = 0x107; -$BTN_8 = 0x108; -$BTN_9 = 0x109; - -$BTN_MOUSE = 0x110; -$BTN_LEFT = 0x110; -$BTN_RIGHT = 0x111; -$BTN_MIDDLE = 0x112; -$BTN_SIDE = 0x113; -$BTN_EXTRA = 0x114; -$BTN_FORWARD = 0x115; -$BTN_BACK = 0x116; -$BTN_TASK = 0x117; - -$BTN_JOYSTICK = 0x120; -$BTN_TRIGGER = 0x120; -$BTN_THUMB = 0x121; -$BTN_THUMB2 = 0x122; -$BTN_TOP = 0x123; -$BTN_TOP2 = 0x124; -$BTN_PINKIE = 0x125; -$BTN_BASE = 0x126; -$BTN_BASE2 = 0x127; -$BTN_BASE3 = 0x128; -$BTN_BASE4 = 0x129; -$BTN_BASE5 = 0x12a; -$BTN_BASE6 = 0x12b; -$BTN_DEAD = 0x12f; - -$BTN_GAMEPAD = 0x130; -$BTN_A = 0x130; -$BTN_B = 0x131; -$BTN_C = 0x132; -$BTN_X = 0x133; -$BTN_Y = 0x134; -$BTN_Z = 0x135; -$BTN_TL = 0x136; -$BTN_TR = 0x137; -$BTN_TL2 = 0x138; -$BTN_TR2 = 0x139; -$BTN_SELECT = 0x13a; -$BTN_START = 0x13b; -$BTN_MODE = 0x13c; -$BTN_THUMBL = 0x13d; -$BTN_THUMBR = 0x13e; - -$BTN_DIGI = 0x140; -$BTN_TOOL_PEN = 0x140; -$BTN_TOOL_RUBBER = 0x141; -$BTN_TOOL_BRUSH = 0x142; -$BTN_TOOL_PENCIL = 0x143; -$BTN_TOOL_AIRBRUSH = 0x144; -$BTN_TOOL_FINGER = 0x145; -$BTN_TOOL_MOUSE = 0x146; -$BTN_TOOL_LENS = 0x147; -$BTN_TOUCH = 0x14a; -$BTN_STYLUS = 0x14b; -$BTN_STYLUS2 = 0x14c; -$BTN_TOOL_DOUBLETAP = 0x14d; -$BTN_TOOL_TRIPLETAP = 0x14e; - -$BTN_WHEEL = 0x150; -$BTN_GEAR_DOWN = 0x150; -$BTN_GEAR_UP = 0x151; - -$SYN_REPORT = 0; -$SYN_CONFIG = 1; -$SYN_MT_REPORT = 2; - -$KEY_RESERVED = 0; -$KEY_ESC = 1; -$KEY_1 = 2; -$KEY_2 = 3; -$KEY_3 = 4; -$KEY_4 = 5; -$KEY_5 = 6; -$KEY_6 = 7; -$KEY_7 = 8; -$KEY_8 = 9; -$KEY_9 = 10; -$KEY_0 = 11; -$KEY_MINUS = 12; -$KEY_EQUAL = 13; -$KEY_BACKSPACE = 14; -$KEY_TAB = 15; -$KEY_Q = 16; -$KEY_W = 17; -$KEY_E = 18; -$KEY_R = 19; -$KEY_T = 20; -$KEY_Y = 21; -$KEY_U = 22; -$KEY_I = 23; -$KEY_O = 24; -$KEY_P = 25; -$KEY_LEFTBRACE = 26; -$KEY_RIGHTBRACE = 27; -$KEY_ENTER = 28; -$KEY_LEFTCTRL = 29; -$KEY_A = 30; -$KEY_S = 31; -$KEY_D = 32; -$KEY_F = 33; -$KEY_G = 34; -$KEY_H = 35; -$KEY_J = 36; -$KEY_K = 37; -$KEY_L = 38; -$KEY_SEMICOLON = 39; -$KEY_APOSTROPHE = 40; -$KEY_GRAVE = 41; -$KEY_LEFTSHIFT = 42; -$KEY_BACKSLASH = 43; -$KEY_Z = 44; -$KEY_X = 45; -$KEY_C = 46; -$KEY_V = 47; -$KEY_B = 48; -$KEY_N = 49; -$KEY_M = 50; -$KEY_COMMA = 51; -$KEY_DOT = 52; -$KEY_SLASH = 53; -$KEY_RIGHTSHIFT = 54; -$KEY_KPASTERISK = 55; -$KEY_LEFTALT = 56; -$KEY_SPACE = 57; -$KEY_CAPSLOCK = 58; -$KEY_F1 = 59; -$KEY_F2 = 60; -$KEY_F3 = 61; -$KEY_F4 = 62; -$KEY_F5 = 63; -$KEY_F6 = 64; -$KEY_F7 = 65; -$KEY_F8 = 66; -$KEY_F9 = 67; -$KEY_F10 = 68; -$KEY_NUMLOCK = 69; -$KEY_SCROLLLOCK = 70; -$KEY_KP7 = 71; -$KEY_KP8 = 72; -$KEY_KP9 = 73; -$KEY_KPMINUS = 74; -$KEY_KP4 = 75; -$KEY_KP5 = 76; -$KEY_KP6 = 77; -$KEY_KPPLUS = 78; -$KEY_KP1 = 79; -$KEY_KP2 = 80; -$KEY_KP3 = 81; -$KEY_KP0 = 82; -$KEY_KPDOT = 83; -$KEY_103RD = 84; -$KEY_F13 = 85; -$KEY_102ND = 86; -$KEY_F11 = 87; -$KEY_F12 = 88; -$KEY_F14 = 89; -$KEY_F15 = 90; -$KEY_F16 = 91; -$KEY_F17 = 92; -$KEY_F18 = 93; -$KEY_F19 = 94; -$KEY_F20 = 95; -$KEY_KPENTER = 96; -$KEY_RIGHTCTRL = 97; -$KEY_KPSLASH = 98; -$KEY_SYSRQ = 99; -$KEY_RIGHTALT = 100; -$KEY_LINEFEED = 101; -$KEY_HOME = 102; -$KEY_UP = 103; -$KEY_PAGEUP = 104; -$KEY_LEFT = 105; -$KEY_RIGHT = 106; -$KEY_END = 107; -$KEY_DOWN = 108; -$KEY_PAGEDOWN = 109; -$KEY_INSERT = 110; -$KEY_DELETE = 111; -$KEY_MACRO = 112; -$KEY_MUTE = 113; -$KEY_VOLUMEDOWN = 114; -$KEY_VOLUMEUP = 115; -$KEY_POWER = 116; -$KEY_KPEQUAL = 117; -$KEY_KPPLUSMINUS = 118; -$KEY_PAUSE = 119; -$KEY_F21 = 120; -$KEY_F22 = 121; -$KEY_F23 = 122; -$KEY_F24 = 123; -$KEY_KPCOMMA = 124; -$KEY_LEFTMETA = 125; -$KEY_RIGHTMETA = 126; -$KEY_COMPOSE = 127; -$KEY_STOP = 128; -$KEY_AGAIN = 129; -$KEY_PROPS = 130; -$KEY_UNDO = 131; -$KEY_FRONT = 132; -$KEY_COPY = 133; -$KEY_OPEN = 134; -$KEY_PASTE = 135; -$KEY_FIND = 136; -$KEY_CUT = 137; -$KEY_HELP = 138; -$KEY_MENU = 139; -$KEY_CALC = 140; -$KEY_SETUP = 141; -$KEY_SLEEP = 142; -$KEY_WAKEUP = 143; -$KEY_FILE = 144; -$KEY_SENDFILE = 145; -$KEY_DELETEFILE = 146; -$KEY_XFER = 147; -$KEY_PROG1 = 148; -$KEY_PROG2 = 149; -$KEY_WWW = 150; -$KEY_MSDOS = 151; -$KEY_COFFEE = 152; -$KEY_DIRECTION = 153; -$KEY_CYCLEWINDOWS = 154; -$KEY_MAIL = 155; -$KEY_BOOKMARKS = 156; -$KEY_COMPUTER = 157; -$KEY_BACK = 158; -$KEY_FORWARD = 159; -$KEY_CLOSECD = 160; -$KEY_EJECTCD = 161; -$KEY_EJECTCLOSECD = 162; -$KEY_NEXTSONG = 163; -$KEY_PLAYPAUSE = 164; -$KEY_PREVIOUSSONG = 165; -$KEY_STOPCD = 166; -$KEY_RECORD = 167; -$KEY_REWIND = 168; -$KEY_PHONE = 169; -$KEY_ISO = 170; -$KEY_CONFIG = 171; -$KEY_HOMEPAGE = 172; -$KEY_REFRESH = 173; -$KEY_EXIT = 174; -$KEY_MOVE = 175; -$KEY_EDIT = 176; -$KEY_SCROLLUP = 177; -$KEY_SCROLLDOWN = 178; -$KEY_KPLEFTPAREN = 179; -$KEY_KPRIGHTPAREN = 180; -$KEY_INTL1 = 181; -$KEY_INTL2 = 182; -$KEY_INTL3 = 183; -$KEY_INTL4 = 184; -$KEY_INTL5 = 185; -$KEY_INTL6 = 186; -$KEY_INTL7 = 187; -$KEY_INTL8 = 188; -$KEY_INTL9 = 189; -$KEY_LANG1 = 190; -$KEY_LANG2 = 191; -$KEY_LANG3 = 192; -$KEY_LANG4 = 193; -$KEY_LANG5 = 194; -$KEY_LANG6 = 195; -$KEY_LANG7 = 196; -$KEY_LANG8 = 197; -$KEY_LANG9 = 198; -$KEY_PLAYCD = 200; -$KEY_PAUSECD = 201; -$KEY_PROG3 = 202; -$KEY_PROG4 = 203; -$KEY_SUSPEND = 205; -$KEY_CLOSE = 206; -$KEY_PLAY = 207; -$KEY_FASTFORWARD = 208; -$KEY_BASSBOOST = 209; -$KEY_PRINT = 210; -$KEY_HP = 211; -$KEY_CAMERA = 212; -$KEY_SOUND = 213; -$KEY_QUESTION = 214; -$KEY_EMAIL = 215; -$KEY_CHAT = 216; -$KEY_SEARCH = 217; -$KEY_CONNECT = 218; -$KEY_FINANCE = 219; -$KEY_SPORT = 220; -$KEY_SHOP = 221; -$KEY_ALTERASE = 222; -$KEY_CANCEL = 223; -$KEY_BRIGHTNESSDOWN = 224; -$KEY_BRIGHTNESSUP = 225; -$KEY_MEDIA = 226; -$KEY_UNKNOWN = 240; -$KEY_OK = 0x160; -$KEY_SELECT = 0x161; -$KEY_GOTO = 0x162; -$KEY_CLEAR = 0x163; -$KEY_POWER2 = 0x164; -$KEY_OPTION = 0x165; -$KEY_INFO = 0x166; -$KEY_TIME = 0x167; -$KEY_VENDOR = 0x168; -$KEY_ARCHIVE = 0x169; -$KEY_PROGRAM = 0x16a; -$KEY_CHANNEL = 0x16b; -$KEY_FAVORITES = 0x16c; -$KEY_EPG = 0x16d; -$KEY_PVR = 0x16e; -$KEY_MHP = 0x16f; -$KEY_LANGUAGE = 0x170; -$KEY_TITLE = 0x171; -$KEY_SUBTITLE = 0x172; -$KEY_ANGLE = 0x173; -$KEY_ZOOM = 0x174; -$KEY_MODE = 0x175; -$KEY_KEYBOARD = 0x176; -$KEY_SCREEN = 0x177; -$KEY_PC = 0x178; -$KEY_TV = 0x179; -$KEY_TV2 = 0x17a; -$KEY_VCR = 0x17b; -$KEY_VCR2 = 0x17c; -$KEY_SAT = 0x17d; -$KEY_SAT2 = 0x17e; -$KEY_CD = 0x17f; -$KEY_TAPE = 0x180; -$KEY_RADIO = 0x181; -$KEY_TUNER = 0x182; -$KEY_PLAYER = 0x183; -$KEY_TEXT = 0x184; -$KEY_DVD = 0x185; -$KEY_AUX = 0x186; -$KEY_MP3 = 0x187; -$KEY_AUDIO = 0x188; -$KEY_VIDEO = 0x189; -$KEY_DIRECTORY = 0x18a; -$KEY_LIST = 0x18b; -$KEY_MEMO = 0x18c; -$KEY_CALENDAR = 0x18d; -$KEY_RED = 0x18e; -$KEY_GREEN = 0x18f; -$KEY_YELLOW = 0x190; -$KEY_BLUE = 0x191; -$KEY_CHANNELUP = 0x192; -$KEY_CHANNELDOWN = 0x193; -$KEY_FIRST = 0x194; -$KEY_LAST = 0x195; -$KEY_AB = 0x196; -$KEY_NEXT = 0x197; -$KEY_RESTART = 0x198; -$KEY_SLOW = 0x199; -$KEY_SHUFFLE = 0x19a; -$KEY_BREAK = 0x19b; -$KEY_PREVIOUS = 0x19c; -$KEY_DIGITS = 0x19d; -$KEY_TEEN = 0x19e; -$KEY_TWEN = 0x19f; -$KEY_DEL_EOL = 0x1c0; -$KEY_DEL_EOS = 0x1c1; -$KEY_INS_LINE = 0x1c2; -$KEY_DEL_LINE = 0x1c3; -$KEY_MAX = 0x1ff; - - - $key_lookup{XK_Escape} = $KEY_ESC; - $key_lookup{XK_1} = $KEY_1; - $key_lookup{XK_2} = $KEY_2; - $key_lookup{XK_3} = $KEY_3; - $key_lookup{XK_4} = $KEY_4; - $key_lookup{XK_5} = $KEY_5; - $key_lookup{XK_6} = $KEY_6; - $key_lookup{XK_7} = $KEY_7; - $key_lookup{XK_8} = $KEY_8; - $key_lookup{XK_9} = $KEY_9; - $key_lookup{XK_0} = $KEY_0; - $key_lookup{XK_exclam} = $KEY_1; - $key_lookup{XK_at} = $KEY_2; - $key_lookup{XK_numbersign} = $KEY_3; - $key_lookup{XK_dollar} = $KEY_4; - $key_lookup{XK_percent} = $KEY_5; - $key_lookup{XK_asciicircum} = $KEY_6; - $key_lookup{XK_ampersand} = $KEY_7; - $key_lookup{XK_asterisk} = $KEY_8; - $key_lookup{XK_parenleft} = $KEY_9; - $key_lookup{XK_parenright} = $KEY_0; - $key_lookup{XK_minus} = $KEY_MINUS; - $key_lookup{XK_underscore} = $KEY_MINUS; - $key_lookup{XK_equal} = $KEY_EQUAL; - $key_lookup{XK_plus} = $KEY_EQUAL; - $key_lookup{XK_BackSpace} = $KEY_BACKSPACE; - $key_lookup{XK_Tab} = $KEY_TAB; - $key_lookup{XK_q} = $KEY_Q; - $key_lookup{XK_Q} = $KEY_Q; - $key_lookup{XK_w} = $KEY_W; - $key_lookup{XK_W} = $KEY_W; - $key_lookup{XK_e} = $KEY_E; - $key_lookup{XK_E} = $KEY_E; - $key_lookup{XK_r} = $KEY_R; - $key_lookup{XK_R} = $KEY_R; - $key_lookup{XK_t} = $KEY_T; - $key_lookup{XK_T} = $KEY_T; - $key_lookup{XK_y} = $KEY_Y; - $key_lookup{XK_Y} = $KEY_Y; - $key_lookup{XK_u} = $KEY_U; - $key_lookup{XK_U} = $KEY_U; - $key_lookup{XK_i} = $KEY_I; - $key_lookup{XK_I} = $KEY_I; - $key_lookup{XK_o} = $KEY_O; - $key_lookup{XK_O} = $KEY_O; - $key_lookup{XK_p} = $KEY_P; - $key_lookup{XK_P} = $KEY_P; - $key_lookup{XK_braceleft} = $KEY_LEFTBRACE; - $key_lookup{XK_braceright} = $KEY_RIGHTBRACE; - $key_lookup{XK_bracketleft} = $KEY_LEFTBRACE; - $key_lookup{XK_bracketright} = $KEY_RIGHTBRACE; - $key_lookup{XK_Return} = $KEY_ENTER; - $key_lookup{XK_Control_L} = $KEY_LEFTCTRL; - $key_lookup{XK_a} = $KEY_A; - $key_lookup{XK_A} = $KEY_A; - $key_lookup{XK_s} = $KEY_S; - $key_lookup{XK_S} = $KEY_S; - $key_lookup{XK_d} = $KEY_D; - $key_lookup{XK_D} = $KEY_D; - $key_lookup{XK_f} = $KEY_F; - $key_lookup{XK_F} = $KEY_F; - $key_lookup{XK_g} = $KEY_G; - $key_lookup{XK_G} = $KEY_G; - $key_lookup{XK_h} = $KEY_H; - $key_lookup{XK_H} = $KEY_H; - $key_lookup{XK_j} = $KEY_J; - $key_lookup{XK_J} = $KEY_J; - $key_lookup{XK_k} = $KEY_K; - $key_lookup{XK_K} = $KEY_K; - $key_lookup{XK_l} = $KEY_L; - $key_lookup{XK_L} = $KEY_L; - $key_lookup{XK_semicolon} = $KEY_SEMICOLON; - $key_lookup{XK_colon} = $KEY_SEMICOLON; - $key_lookup{XK_apostrophe} = $KEY_APOSTROPHE; - $key_lookup{XK_quotedbl} = $KEY_APOSTROPHE; - $key_lookup{XK_grave} = $KEY_GRAVE; - $key_lookup{XK_asciitilde} = $KEY_GRAVE; - $key_lookup{XK_Shift_L} = $KEY_LEFTSHIFT; - $key_lookup{XK_backslash} = $KEY_BACKSLASH; - $key_lookup{XK_bar} = $KEY_BACKSLASH; - $key_lookup{XK_z} = $KEY_Z; - $key_lookup{XK_Z} = $KEY_Z; - $key_lookup{XK_x} = $KEY_X; - $key_lookup{XK_X} = $KEY_X; - $key_lookup{XK_c} = $KEY_C; - $key_lookup{XK_C} = $KEY_C; - $key_lookup{XK_v} = $KEY_V; - $key_lookup{XK_V} = $KEY_V; - $key_lookup{XK_b} = $KEY_B; - $key_lookup{XK_B} = $KEY_B; - $key_lookup{XK_n} = $KEY_N; - $key_lookup{XK_N} = $KEY_N; - $key_lookup{XK_m} = $KEY_M; - $key_lookup{XK_M} = $KEY_M; - $key_lookup{XK_comma} = $KEY_COMMA; - $key_lookup{XK_less} = $KEY_COMMA; - $key_lookup{XK_period} = $KEY_DOT; - $key_lookup{XK_greater} = $KEY_DOT; - $key_lookup{XK_slash} = $KEY_SLASH; - $key_lookup{XK_question} = $KEY_SLASH; - $key_lookup{XK_Shift_R} = $KEY_RIGHTSHIFT; - $key_lookup{XK_KP_Multiply} = $KEY_KPASTERISK; - $key_lookup{XK_Alt_L} = $KEY_LEFTALT; - $key_lookup{XK_space} = $KEY_SPACE; - $key_lookup{XK_Caps_Lock} = $KEY_CAPSLOCK; - $key_lookup{XK_F1} = $KEY_F1; - $key_lookup{XK_F2} = $KEY_F2; - $key_lookup{XK_F3} = $KEY_F3; - $key_lookup{XK_F4} = $KEY_F4; - $key_lookup{XK_F5} = $KEY_F5; - $key_lookup{XK_F6} = $KEY_F6; - $key_lookup{XK_F7} = $KEY_F7; - $key_lookup{XK_F8} = $KEY_F8; - $key_lookup{XK_F9} = $KEY_F9; - $key_lookup{XK_F10} = $KEY_F10; - $key_lookup{XK_Num_Lock} = $KEY_NUMLOCK; - $key_lookup{XK_Scroll_Lock} = $KEY_SCROLLLOCK; - $key_lookup{XK_KP_7} = $KEY_KP7; - $key_lookup{XK_KP_8} = $KEY_KP8; - $key_lookup{XK_KP_9} = $KEY_KP9; - $key_lookup{XK_KP_Subtract} = $KEY_KPMINUS; - $key_lookup{XK_KP_4} = $KEY_KP4; - $key_lookup{XK_KP_5} = $KEY_KP5; - $key_lookup{XK_KP_6} = $KEY_KP6; - $key_lookup{XK_KP_Add} = $KEY_KPPLUS; - $key_lookup{XK_KP_1} = $KEY_KP1; - $key_lookup{XK_KP_2} = $KEY_KP2; - $key_lookup{XK_KP_3} = $KEY_KP3; - $key_lookup{XK_KP_0} = $KEY_KP0; - $key_lookup{XK_KP_Decimal} = $KEY_KPDOT; - $key_lookup{XK_F13} = $KEY_F13; - $key_lookup{XK_F11} = $KEY_F11; - $key_lookup{XK_F12} = $KEY_F12; - $key_lookup{XK_F14} = $KEY_F14; - $key_lookup{XK_F15} = $KEY_F15; - $key_lookup{XK_F16} = $KEY_F16; - $key_lookup{XK_F17} = $KEY_F17; - $key_lookup{XK_F18} = $KEY_F18; - $key_lookup{XK_F19} = $KEY_F19; - $key_lookup{XK_F20} = $KEY_F20; - $key_lookup{XK_KP_Enter} = $KEY_KPENTER; - $key_lookup{XK_Control_R} = $KEY_RIGHTCTRL; - $key_lookup{XK_KP_Divide} = $KEY_KPSLASH; - $key_lookup{XK_Sys_Req} = $KEY_SYSRQ; - $key_lookup{XK_Alt_R} = $KEY_RIGHTALT; - $key_lookup{XK_Linefeed} = $KEY_LINEFEED; - $key_lookup{XK_Home} = $KEY_HOME; - $key_lookup{XK_Up} = $KEY_UP; - $key_lookup{XK_Page_Up} = $KEY_PAGEUP; - $key_lookup{XK_Left} = $KEY_LEFT; - $key_lookup{XK_Right} = $KEY_RIGHT; - $key_lookup{XK_End} = $KEY_END; - $key_lookup{XK_Down} = $KEY_DOWN; - $key_lookup{XK_Page_Down} = $KEY_PAGEDOWN; - $key_lookup{XK_Insert} = $KEY_INSERT; - $key_lookup{XK_Delete} = $KEY_DELETE; - $key_lookup{XK_KP_Equal} = $KEY_KPEQUAL; - $key_lookup{XK_Pause} = $KEY_PAUSE; - $key_lookup{XK_F21} = $KEY_F21; - $key_lookup{XK_F22} = $KEY_F22; - $key_lookup{XK_F23} = $KEY_F23; - $key_lookup{XK_F24} = $KEY_F24; - $key_lookup{XK_KP_Separator} = $KEY_KPCOMMA; - $key_lookup{XK_Meta_L} = $KEY_LEFTMETA; - $key_lookup{XK_Meta_R} = $KEY_RIGHTMETA; - $key_lookup{XK_Multi_key} = $KEY_COMPOSE; - -$ABS_MAX = 63; - -$UI_DEV_CREATE = 0x5501; -$UI_DEV_DESTROY = 0x5502; -$UI_SET_EVBIT = 0x40045564; -$UI_SET_KEYBIT = 0x40045565; -$UI_SET_RELBIT = 0x40045566; -$UI_SET_ABSBIT = 0x40045567; - -# FIXME: time hires, etc. -$linux_gettimeofday_syscall = 78; - -$O_RDONLY = 00; -$O_WRONLY = 01; -$O_RDWR = 02; -$O_NDELAY = 04000; - -} diff --git a/x11vnc/misc/ranfb.pl b/x11vnc/misc/ranfb.pl deleted file mode 100755 index d6aa49d..0000000 --- a/x11vnc/misc/ranfb.pl +++ /dev/null @@ -1,157 +0,0 @@ - #!/bin/sh -- # A comment mentioning perl -eval 'exec perl -S $0 ${1+"$@"}' - if 0; - -# ranfb.pl: example -rawfb setup program. -# E.g. x11vnc -rawfb setup:./ranfb.pl - -# can supply WxH or W H on cmd line: -if ($ARGV[0] =~ /^(\d+)x(\d+)$/) { - $W = $1; - $H = $2; -} else { - $W = shift; - $H = shift; -} - -$W = 480 unless $W; -$H = 360 unless $H; - -$fb = "/tmp/ranfb.$$"; -open(FB, ">$fb") || die "$!"; - -$ones = "\377" x ($W * 4); -for ($y = 0; $y < $H; $y++) { - print FB $ones; -} - -if (fork) { - print "map:$fb\@${W}x${H}x32\n"; - exit 0; -} - -srand(); -while (1) { - showpic(); - if (! kill 0, $ENV{X11VNC_PID}) { - print STDERR "PID $ENV{X11VNC_PID} gone\n"; - unlink($fb); - exit; - } -} - -sub showpic { - - # 0 < x,y < 1; R1, R2, ... B4 random & scaled so R,G,B < 255: - # R(x,y) = R1 + R2 * x + R3 * y + R4 * x * y - # G(x,y) = G1 + G2 * x + G3 * y + G4 * x * y - # B(x,y) = B1 + B2 * x + B3 * y + B4 * x * y - - $minfac = 0.25; - foreach $c ('R', 'G', 'B') { - $a1 = rand() * $minfac; - $a2 = rand(); - $a3 = rand(); - $a4 = rand(); - $at = $a1 + $a2 + $a3 + $a4; - $a1 = 255 * ($a1/$at); - $a2 = 255 * ($a2/$at); - $a3 = 255 * ($a3/$at); - $a4 = 255 * ($a4/$at); - # invert axes randomly - $ax = 0; $ax = 1 if rand() < 0.5; - $ay = 0; $ay = 1 if rand() < 0.5; - eval "\$${c}1 = \$a1"; - eval "\$${c}2 = \$a2"; - eval "\$${c}3 = \$a3"; - eval "\$${c}4 = \$a4"; - eval "\$${c}x = \$ax"; - eval "\$${c}y = \$ay"; - } - - for ($i = 0; $i < 256; $i++) { - $p[$i] = pack("c", $i); - } - - $Winv = 1.0/$W; - $Hinv = 1.0/$H; - - $str = ''; - for ($y = 0; $y < $H; $y++) { - $yr = $yg = $yb = $y; - $yr = $H - $yr if $Ry; - $yg = $H - $yg if $Gy; - $yb = $H - $yb if $By; - $yr = $yr * $Hinv; - $yg = $yg * $Hinv; - $yb = $yb * $Hinv; - - $Y[3*$y+0] = $yr; - $Y[3*$y+1] = $yg; - $Y[3*$y+2] = $yb; - } - - for ($x = 0; $x < $W; $x++) { - $xr = $xg = $xb = $x; - $xr = $W - $xr if $Rx; - $xg = $W - $xg if $Gx; - $xb = $W - $xb if $Bx; - $xr = $xr * $Winv; - $xg = $xg * $Winv; - $xb = $xb * $Winv; - - $X[3*$x+0] = $xr; - $X[3*$x+1] = $xg; - $X[3*$x+2] = $xb; - } - - for ($y = 0; $y < $H; $y++) { - #$yr = $yg = $yb = $y; - #$yr = $H - $yr if $Ry; - #$yg = $H - $yg if $Gy; - #$yb = $H - $yb if $By; - #$yr = $yr * $Hinv; - #$yg = $yg * $Hinv; - #$yb = $yb * $Hinv; - - $yr = $Y[3*$y+0]; - $yg = $Y[3*$y+1]; - $yb = $Y[3*$y+2]; - - $RY1 = $R1 + $yr * $R3; - $GY1 = $G1 + $yg * $G3; - $BY1 = $B1 + $yb * $B3; - - $RY2 = $R2 + $yr * $R4; - $GY2 = $G2 + $yg * $G4; - $BY2 = $B2 + $yb * $B4; - - for ($x = 0; $x < $W; $x++) { - #$xr = $xg = $xb = $x; - #$xr = $W - $xr if $Rx; - #$xg = $W - $xg if $Gx; - #$xb = $W - $xb if $Bx; - #$xr = $xr * $Winv; - #$xg = $xg * $Winv; - #$xb = $xb * $Winv; - - $n = 3 * $x; - - #$v = int($R1 + $xr*$R2 + $yr*$R3 + $xr*$yr*$R4); - $v = int($RY1 + $X[$n]*$RY2); - $str .= $p[$v]; - - #$v = int($G1 + $xg*$G2 + $yg*$G3 + $xg*$yg*$G4); - $v = int($GY1 + $X[$n+1]*$GY2); - $str .= $p[$v]; - - #$v = int($B1 + $xb*$B2 + $yb*$B3 + $xb*$yb*$B4); - $v = int($BY1 + $X[$n+2]*$BY2); - $str .= $p[$v]; - - $str .= "\0"; - } - } - seek(FB, 0, 0); - print FB $str; -} diff --git a/x11vnc/misc/rx11vnc b/x11vnc/misc/rx11vnc deleted file mode 100755 index cf9c78b..0000000 --- a/x11vnc/misc/rx11vnc +++ /dev/null @@ -1,133 +0,0 @@ -#!/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 -t -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 deleted file mode 100755 index e6ab0a1..0000000 --- a/x11vnc/misc/rx11vnc.pl +++ /dev/null @@ -1,199 +0,0 @@ - #!/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 -t -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 deleted file mode 100755 index 16d5cb6..0000000 --- a/x11vnc/misc/shm_clear +++ /dev/null @@ -1,97 +0,0 @@ -#!/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 deleted file mode 100755 index b8f284e..0000000 --- a/x11vnc/misc/slide.pl +++ /dev/null @@ -1,112 +0,0 @@ - #!/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/turbovnc/Makefile.am b/x11vnc/misc/turbovnc/Makefile.am deleted file mode 100644 index 3c6edc6..0000000 --- a/x11vnc/misc/turbovnc/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -# This file has been (or is hereby) released into the public domain by -# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide. -# -# In case this is not legally possible: Karl J. Runge grants anyone the -# right to use this work for any purpose, without any conditions, unless -# such conditions are required by law. - -EXTRA_DIST=README apply_turbovnc convert convert_rfbserver tight.c turbojpeg.h undo_turbovnc diff --git a/x11vnc/misc/turbovnc/README b/x11vnc/misc/turbovnc/README deleted file mode 100644 index 328929c..0000000 --- a/x11vnc/misc/turbovnc/README +++ /dev/null @@ -1,159 +0,0 @@ -# -# This work has been (or is hereby) released into the public domain by -# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide. -# -# In case this is not legally possible: Karl J. Runge grants anyone the -# right to use this work for any purpose, without any conditions, unless -# such conditions are required by law. -# - -INTRO: ------- - -This is a "patch" to make x11vnc/libvncserver work with TurboVNC: - - http://www.virtualgl.org/About/TurboVNC - http://www.karlrunge.com/x11vnc/faq.html#faq-turbovnc - -It is very experimental/kludgy. Not all TurboVNC features may be enabled. -We are currently evaluating whether TurboVNC support should be officially -put into x11vnc/libvncserver. - -TurboVNC is an optimized VNC for fast refresh rates on fast networks. - -It does pretty well on good broadband as well. But it is not as fast -as regular TightVNC on slow links. - - -TURBOJPEG: ---------- - -TurboVNC uses the TurboJPEG library based on a fast proprietary JPEG -implementation. You will need to download it from the VirtualGL -sourceforge site: - - http://sourceforge.net/project/showfiles.php?group_id=117509&package_id=166100 - -Either install it or simply unpack the .deb or .rpm file into a directory. - -N.B. you can unpack a .deb via 'ar x package.deb' and the extracting -from the data.tar.gz file. rpm2cpio can be used to unpack .rpm's. - - -QUICK-START: ------------- - -For those in a hurry: - - cd x11vnc-x.y.z/x11vnc/misc/turbovnc - ./apply_turbovnc - cd ../../.. - env LDFLAGS='-L/DIR -Xlinker --rpath=/DIR' ./configure - make AM_LDFLAGS='-lturbojpeg' - -where you replace /DIR with your directory containing libturbojpeg.so. - - -PATCHING AND BUILDING: ----------------------- - -After unpacking your x11vnc-x.y.z.tar.gz tarball cd to the -x11vnc-x.y.z/x11vnc/misc/turbovnc (where this README file is) and from -that directory run: - - ./apply_turbovnc - -that will modify files in the libvncserver and x11vnc directories above -this directory. (To undo these changes run: ./undo_turbovnc) The input -sources, tight.c and turbojpeg.h are from the TurboVNC source package. - -After applying, go back to the top level source directory and run: - - env LDFLAGS='-L/path/to/turbojpeg -Xlinker --rpath=/path/to/turbojpeg' ./configure - -where the turbojpeg library is: - - /path/to/turbojpeg/libturbojpeg.so - -(change /path/to/turbojpeg to the directory where you installed or -unpacked it.) - -If you are not using gnu gcc and gnu linker the options may be a little -different (e.g. -R instead of -Xlinker --rpath). - -If you need additional ./configure options or env. var. settings, -add them too. - - -Next, run this make command: - - make AM_LDFLAGS='-lturbojpeg' - -This is a hack and may not always work, if it doesn't edit x11vnc/Makefile -and add '-lturbojpeg' to the LIBS variable. - -This should create a binary: - - ./x11vnc/x11vnc - -that supports VirtualGL's TurboVNC. - -You will need a TurboVNC viewer, you can get one here: - - http://sourceforge.net/project/showfiles.php?group_id=117509&package_id=128130 - -Let us know how it goes. - - -PERFORMANCE: ------------- - -Note that x11vnc has to read the display's screen pixels from the -graphics card memory. This can be slow, e.g. 10 MB/sec. - -There is not a big need for graphics card manufacturers to optimize the -read rate; the write rate is the one they optimize greatly. - - http://www.karlrunge.com/x11vnc/#limitations - -If you run x11vnc and see lines like this: - - 28/02/2009 00:52:07 Autoprobing selected port 5900 - 28/02/2009 00:52:07 fb read rate: 10 MB/sec - 28/02/2009 00:52:07 screen setup finished. - -you have a typical slow one. - -Whereas if you see this: - - 28/02/2009 00:54:46 Autoprobing selected port 5900 - 28/02/2009 00:54:46 fb read rate: 321 MB/sec - 28/02/2009 00:54:46 fast read: reset wait ms to: 10 - 28/02/2009 00:54:46 fast read: reset defer ms to: 10 - 28/02/2009 00:54:46 screen setup finished. - -that is very fast. In such a situation you may want to dial down -x11vnc's delay, e.g.: -wait 5 -defer 5, or even smaller to push things -out more quickly. - -We have only seen it this fast on Linux by using the nvidia proprietary -graphics drivers. The Xorg drivers are typically slow 10 MB/sec. - -It will also be fast if the X server is virtual: Xvfb or Xdummy -since the screen pixels are stored in RAM: - - http://www.karlrunge.com/x11vnc/faq.html#faq-xvfb - -And it will be fast if the ShadowFB xorg.conf option is enabled (if the -card supports it.) - - -The point we are trying to make is that even though TurboVNC uses a -wicked fast JPEG implementation, and cuts out overhead in its attempt to -pump out as many frames per second as it can, if it is slow for x11vnc -to read the screen pixels in the first place then you might not even -notice the TurboVNC speedup. - -So TurboVNC+x11vnc will be faster than TightVNC+x11vnc, but if there is -a large overhead/bottleneck from reading the graphics card framebuffer, -then the speedup will be marginal. diff --git a/x11vnc/misc/turbovnc/apply_turbovnc b/x11vnc/misc/turbovnc/apply_turbovnc deleted file mode 100755 index 45e4700..0000000 --- a/x11vnc/misc/turbovnc/apply_turbovnc +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# This script has been (or is hereby) released into the public domain by -# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide. -# -# In case this is not legally possible: Karl J. Runge grants anyone the -# right to use this work for any purpose, without any conditions, unless -# such conditions are required by law. - -ldir="../../../libvncserver" - -fail="" -if [ ! -f "./tight.c" ]; then - fail=1 -fi -if [ ! -f "./turbojpeg.h" ]; then - fail=1 -fi -if [ ! -f "./convert" ]; then - fail=1 -fi -if [ ! -f "$ldir/tight.c" ]; then - ls -l "$ldir/tight.c" - fail=1 -fi -if [ ! -f "$ldir/rfbserver.c" ]; then - ls -l "$ldir/rfbserver.c" - fail=1 -fi -if [ "X$fail" = "X1" ]; then - echo "Must be run from inside the directory containing 'apply_turbovnc'" - exit 1 -fi - -set -x -if [ ! -f "$ldir/tight.c.ORIG" ]; then - cp -p "$ldir/tight.c" "$ldir/tight.c.ORIG" -fi -if [ ! -f "$ldir/rfbserver.c.ORIG" ]; then - cp -p "$ldir/rfbserver.c" "$ldir/rfbserver.c.ORIG" -fi - -perl ./convert ./tight.c > "$ldir/tight.c" -perl ./convert_rfbserver $ldir/rfbserver.c.ORIG > "$ldir/rfbserver.c" -cp -p ./turbojpeg.h "$ldir" -ls -l $ldir/tight.c* $ldir/rfbserver.c* $ldir/turbojpeg.h diff --git a/x11vnc/misc/turbovnc/convert b/x11vnc/misc/turbovnc/convert deleted file mode 100755 index f218f84..0000000 --- a/x11vnc/misc/turbovnc/convert +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/perl -# -# This script has been (or is hereby) released into the public domain by -# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide. -# -# In case this is not legally possible: Karl J. Runge grants anyone the -# right to use this work for any purpose, without any conditions, unless -# such conditions are required by law. - -while (<>) { - if (/^#include.*"rfb.h"/) { - print <<END; -#include <rfb/rfb.h> -#define Bool rfbBool -#define CARD32 uint32_t -#define CARD16 uint16_t -#define CARD8 uint8_t -#define xalloc malloc -#define xrealloc realloc -#define rfbTightNoZlib 0x0A -#define tightSubsampLevel correMaxWidth - -#if LIBVNCSERVER_HAVE_LIBPTHREAD && LIBVNCSERVER_HAVE_TLS -#define TLS __thread -#else -#define TLS -#endif - -END - next; - } - foreach $func (qw(FindBestSolidArea ExtendSolidArea CheckSolidTile CheckSolidTile##bpp CheckSolidTile8 CheckSolidTile16 CheckSolidTile32 Pack24)) { - if (/static.*\b\Q$func\E\b/ && !exists $did_static{$func}) { - $_ =~ s/\b\Q$func\E\b(\s*)\(/$func$1(rfbClientPtr cl, /; - $did_static{$func} = 1; - } elsif (/\b\Q$func\E\b\s*\(/) { - $_ =~ s/\b\Q$func\E\b(\s*)\(/$func$1(cl, /; - } - } - -# if (/^\s*subsampLevel\s*=\s*cl/) { -# $_ = "//$_"; -# print "subsampLevel = 0;\n"; -# } - -# $_ =~ s/cl->tightQualityLevel;/cl->tightQualityLevel * 10;/; - - if (/^static\s+(Bool|int|CARD32|PALETTE|char|unsigned|tjhandle)\s+[^()]*;\s*$/) { - $_ =~ s/^static/static TLS /; - } - - $_ =~ s/rfbScreen.pfbMemory/cl->scaledScreen->frameBuffer/g; - $_ =~ s/rfbScreen.paddedWidthInBytes/cl->scaledScreen->paddedWidthInBytes/g; - $_ =~ s/rfbScreen.bitsPerPixel/cl->scaledScreen->bitsPerPixel/g; - $_ =~ s/rfbServerFormat/cl->screen->serverFormat/g; - - if (/^(FindBestSolidArea|ExtendSolidArea|static void Pack24|CheckSolidTile)\(cl/) { - $_ .= "rfbClientPtr cl;\n"; - } - if (/^(CheckSolidTile##bpp)\(cl/) { - $_ .= "rfbClientPtr cl; \\\n"; - } - $_ =~ s/\bublen\b/cl->ublen/; - $_ =~ s/\bupdateBuf\b/cl->updateBuf/; - - if (/cl->(rfbRectanglesSent|rfbBytesSent)/) { - $_ = "//$_"; - } - print; -} - -print <<END; - -void rfbTightCleanup(rfbScreenInfoPtr screen) { -} - -END - - diff --git a/x11vnc/misc/turbovnc/convert_rfbserver b/x11vnc/misc/turbovnc/convert_rfbserver deleted file mode 100755 index 81267ac..0000000 --- a/x11vnc/misc/turbovnc/convert_rfbserver +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl -# -# This script has been (or is hereby) released into the public domain by -# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide. -# -# In case this is not legally possible: Karl J. Runge grants anyone the -# right to use this work for any purpose, without any conditions, unless -# such conditions are required by law. - -$saw_mark = 0; -$done = 0; - -while (<>) { - if (! $saw_mark && /case rfbEncodingServerIdentity:/) { - $saw_mark = 1; - } - if ($saw_mark && !$done && /default:/) { - print; - - print <<END; - /* for turbovnc */ -#define rfbJpegQualityLevel1 0xFFFFFE01 -#define rfbJpegQualityLevel100 0xFFFFFE64 -#define rfbJpegSubsamp1X 0xFFFFFD00 -#define rfbJpegSubsamp4X 0xFFFFFD01 -#define rfbJpegSubsamp2X 0xFFFFFD02 -#define rfbJpegSubsampGray 0xFFFFFD03 - - if ( enc >= (uint32_t)rfbJpegSubsamp1X && - enc <= (uint32_t)rfbJpegSubsampGray ) { - /* XXX member really should be tightSubsample not correMaxWidth */ - cl->correMaxWidth = enc & 0xFF; - rfbLog("Using JPEG subsampling %d for client %s\\n", - cl->correMaxWidth, cl->host); - } else if ( enc >= (uint32_t)rfbEncodingQualityLevel0 && - enc <= (uint32_t)rfbEncodingQualityLevel9 ) { - static int JPEG_QUAL[10] = { - 5, 10, 15, 25, 37, 50, 60, 70, 75, 80 - }; - cl->tightQualityLevel = JPEG_QUAL[enc & 0x0F]; - /* XXX member really should be tightSubsample not correMaxWidth */ - cl->correMaxWidth = 2; - rfbLog("Using image level Subsample %d Quality %d for client %s\\n", - cl->correMaxWidth, cl->tightQualityLevel, cl->host); - } else if ( enc >= (uint32_t)rfbJpegQualityLevel1 && - enc <= (uint32_t)rfbJpegQualityLevel100 ) { - cl->tightQualityLevel = enc & 0xFF; - rfbLog("Using image quality level %d for client %s\\n", - cl->tightQualityLevel, cl->host); - } else -END - $done = 1; - next; - } - print; -} diff --git a/x11vnc/misc/turbovnc/tight.c b/x11vnc/misc/turbovnc/tight.c deleted file mode 100644 index e7b4dbd..0000000 --- a/x11vnc/misc/turbovnc/tight.c +++ /dev/null @@ -1,1502 +0,0 @@ -/* - * tight.c - * - * Routines to implement Tight Encoding - */ - -/* - * Copyright (C) 2005-2008 Sun Microsystems, Inc. All Rights Reserved. - * Copyright (C) 2004 Landmark Graphics Corporation. All Rights Reserved. - * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. - * Copyright (C) 1999 AT&T Laboratories Cambridge. 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "rfb.h" -#include "turbojpeg.h" - -/* Note: The following constant should not be changed. */ -#define TIGHT_MIN_TO_COMPRESS 12 - -/* The parameters below may be adjusted. */ -#define MIN_SPLIT_RECT_SIZE 4096 -#define MIN_SOLID_SUBRECT_SIZE 2048 -#define MAX_SPLIT_TILE_SIZE 16 - -/* This variable is set on every rfbSendRectEncodingTight() call. */ -static Bool usePixelFormat24; - - -/* Compression level stuff. The following array contains various - encoder parameters for each of 10 compression levels (0..9). - Last three parameters correspond to JPEG quality levels (0..9). */ - -typedef struct TIGHT_CONF_s { - int maxRectSize, maxRectWidth; - int monoMinRectSize; - int idxZlibLevel, monoZlibLevel, rawZlibLevel; - int idxMaxColorsDivisor; -} TIGHT_CONF; - -static TIGHT_CONF tightConf[2] = { - { 65536, 2048, 6, 0, 0, 0, 4 }, -#if 0 - { 2048, 128, 6, 1, 1, 1, 8 }, - { 6144, 256, 8, 3, 3, 2, 24 }, - { 10240, 1024, 12, 5, 5, 3, 32 }, - { 16384, 2048, 12, 6, 6, 4, 32 }, - { 32768, 2048, 12, 7, 7, 5, 32 }, - { 65536, 2048, 16, 7, 7, 6, 48 }, - { 65536, 2048, 16, 8, 8, 7, 64 }, - { 65536, 2048, 32, 9, 9, 8, 64 }, -#endif - { 65536, 2048, 32, 1, 1, 1, 96 } -}; - -static int compressLevel; -static int qualityLevel; -static int subsampLevel; - -static const int subsampLevel2tjsubsamp[4] = { - TJ_444, TJ_411, TJ_422, TJ_GRAYSCALE -}; - -/* Stuff dealing with palettes. */ - -typedef struct COLOR_LIST_s { - struct COLOR_LIST_s *next; - int idx; - CARD32 rgb; -} COLOR_LIST; - -typedef struct PALETTE_ENTRY_s { - COLOR_LIST *listNode; - int numPixels; -} PALETTE_ENTRY; - -typedef struct PALETTE_s { - PALETTE_ENTRY entry[256]; - COLOR_LIST *hash[256]; - COLOR_LIST list[256]; -} PALETTE; - -static int paletteNumColors, paletteMaxColors; -static CARD32 monoBackground, monoForeground; -static PALETTE palette; - -/* Pointers to dynamically-allocated buffers. */ - -static int tightBeforeBufSize = 0; -static char *tightBeforeBuf = NULL; - -static int tightAfterBufSize = 0; -static char *tightAfterBuf = NULL; - -static int *prevRowBuf = NULL; - - -/* Prototypes for static functions. */ - -static void FindBestSolidArea (int x, int y, int w, int h, - CARD32 colorValue, int *w_ptr, int *h_ptr); -static void ExtendSolidArea (int x, int y, int w, int h, - CARD32 colorValue, - int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr); -static Bool CheckSolidTile (int x, int y, int w, int h, - CARD32 *colorPtr, Bool needSameColor); -static Bool CheckSolidTile8 (int x, int y, int w, int h, - CARD32 *colorPtr, Bool needSameColor); -static Bool CheckSolidTile16 (int x, int y, int w, int h, - CARD32 *colorPtr, Bool needSameColor); -static Bool CheckSolidTile32 (int x, int y, int w, int h, - CARD32 *colorPtr, Bool needSameColor); - -static Bool SendRectSimple (rfbClientPtr cl, int x, int y, int w, int h); -static Bool SendSubrect (rfbClientPtr cl, int x, int y, int w, int h); -static Bool SendTightHeader (rfbClientPtr cl, int x, int y, int w, int h); - -static Bool SendSolidRect (rfbClientPtr cl); -static Bool SendMonoRect (rfbClientPtr cl, int w, int h); -static Bool SendIndexedRect (rfbClientPtr cl, int w, int h); -static Bool SendFullColorRect (rfbClientPtr cl, int w, int h); - -static Bool CompressData(rfbClientPtr cl, int streamId, int dataLen, - int zlibLevel, int zlibStrategy); -static Bool SendCompressedData(rfbClientPtr cl, char *buf, int compressedLen); - -static void FillPalette8(int count); -static void FillPalette16(int count); -static void FillPalette32(int count); -static void FastFillPalette16(rfbClientPtr cl, CARD16 *data, int w, int pitch, - int h); -static void FastFillPalette32(rfbClientPtr cl, CARD32 *data, int w, int pitch, - int h); - -static void PaletteReset(void); -static int PaletteInsert(CARD32 rgb, int numPixels, int bpp); - -static void Pack24(char *buf, rfbPixelFormat *fmt, int count); - -static void EncodeIndexedRect16(CARD8 *buf, int count); -static void EncodeIndexedRect32(CARD8 *buf, int count); - -static void EncodeMonoRect8(CARD8 *buf, int w, int h); -static void EncodeMonoRect16(CARD8 *buf, int w, int h); -static void EncodeMonoRect32(CARD8 *buf, int w, int h); - -static Bool SendJpegRect(rfbClientPtr cl, int x, int y, int w, int h, - int quality); - -/* - * Tight encoding implementation. - */ - -int -rfbNumCodedRectsTight(cl, x, y, w, h) - rfbClientPtr cl; - int x, y, w, h; -{ - int maxRectSize, maxRectWidth; - int subrectMaxWidth, subrectMaxHeight; - - /* No matter how many rectangles we will send if LastRect markers - are used to terminate rectangle stream. */ - if (cl->enableLastRectEncoding && w * h >= MIN_SPLIT_RECT_SIZE) - return 0; - - maxRectSize = tightConf[compressLevel].maxRectSize; - maxRectWidth = tightConf[compressLevel].maxRectWidth; - - if (w > maxRectWidth || w * h > maxRectSize) { - subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; - subrectMaxHeight = maxRectSize / subrectMaxWidth; - return (((w - 1) / maxRectWidth + 1) * - ((h - 1) / subrectMaxHeight + 1)); - } else { - return 1; - } -} - -Bool -rfbSendRectEncodingTight(cl, x, y, w, h) - rfbClientPtr cl; - int x, y, w, h; -{ - int nMaxRows; - CARD32 colorValue; - int dx, dy, dw, dh; - int x_best, y_best, w_best, h_best; - char *fbptr; - - compressLevel = cl->tightCompressLevel > 0 ? 1 : 0; - qualityLevel = cl->tightQualityLevel; - if (qualityLevel != -1) { - compressLevel = 1; - tightConf[compressLevel].idxZlibLevel = 1; - tightConf[compressLevel].monoZlibLevel = 1; - tightConf[compressLevel].rawZlibLevel = 1; - } else { - tightConf[compressLevel].idxZlibLevel = cl->tightCompressLevel; - tightConf[compressLevel].monoZlibLevel = cl->tightCompressLevel; - tightConf[compressLevel].rawZlibLevel = cl->tightCompressLevel; - } - subsampLevel = cl->tightSubsampLevel; - - if ( cl->format.depth == 24 && cl->format.redMax == 0xFF && - cl->format.greenMax == 0xFF && cl->format.blueMax == 0xFF ) { - usePixelFormat24 = TRUE; - } else { - usePixelFormat24 = FALSE; - } - - if (!cl->enableLastRectEncoding || w * h < MIN_SPLIT_RECT_SIZE) - return SendRectSimple(cl, x, y, w, h); - - /* Make sure we can write at least one pixel into tightBeforeBuf. */ - - if (tightBeforeBufSize < 4) { - tightBeforeBufSize = 4; - if (tightBeforeBuf == NULL) - tightBeforeBuf = (char *)xalloc(tightBeforeBufSize); - else - tightBeforeBuf = (char *)xrealloc(tightBeforeBuf, - tightBeforeBufSize); - } - - /* Calculate maximum number of rows in one non-solid rectangle. */ - - { - int maxRectSize, maxRectWidth, nMaxWidth; - - maxRectSize = tightConf[compressLevel].maxRectSize; - maxRectWidth = tightConf[compressLevel].maxRectWidth; - nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; - nMaxRows = maxRectSize / nMaxWidth; - } - - /* Try to find large solid-color areas and send them separately. */ - - for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { - - /* If a rectangle becomes too large, send its upper part now. */ - - if (dy - y >= nMaxRows) { - if (!SendRectSimple(cl, x, y, w, nMaxRows)) - return 0; - y += nMaxRows; - h -= nMaxRows; - } - - dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ? - MAX_SPLIT_TILE_SIZE : (y + h - dy); - - for (dx = x; dx < x + w; dx += MAX_SPLIT_TILE_SIZE) { - - dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ? - MAX_SPLIT_TILE_SIZE : (x + w - dx); - - if (CheckSolidTile(dx, dy, dw, dh, &colorValue, FALSE)) { - - if (subsampLevel == TJ_GRAYSCALE && qualityLevel != -1) { - CARD32 r=(colorValue>>16)&0xFF; - CARD32 g=(colorValue>>8)&0xFF; - CARD32 b=(colorValue)&0xFF; - double y=(0.257*(double)r)+(0.504*(double)g) - +(0.098*(double)b)+16.; - colorValue=(int)y+(((int)y)<<8)+(((int)y)<<16); - } - - /* Get dimensions of solid-color area. */ - - FindBestSolidArea(dx, dy, w - (dx - x), h - (dy - y), - colorValue, &w_best, &h_best); - - /* Make sure a solid rectangle is large enough - (or the whole rectangle is of the same color). */ - - if ( w_best * h_best != w * h && - w_best * h_best < MIN_SOLID_SUBRECT_SIZE ) - continue; - - /* Try to extend solid rectangle to maximum size. */ - - x_best = dx; y_best = dy; - ExtendSolidArea(x, y, w, h, colorValue, - &x_best, &y_best, &w_best, &h_best); - - /* Send rectangles at top and left to solid-color area. */ - - if ( y_best != y && - !SendRectSimple(cl, x, y, w, y_best-y) ) - return FALSE; - if ( x_best != x && - !rfbSendRectEncodingTight(cl, x, y_best, - x_best-x, h_best) ) - return FALSE; - - /* Send solid-color rectangle. */ - - if (!SendTightHeader(cl, x_best, y_best, w_best, h_best)) - return FALSE; - - fbptr = (rfbScreen.pfbMemory + - (rfbScreen.paddedWidthInBytes * y_best) + - (x_best * (rfbScreen.bitsPerPixel / 8))); - - (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, - &cl->format, fbptr, tightBeforeBuf, - rfbScreen.paddedWidthInBytes, 1, 1); - - if (!SendSolidRect(cl)) - return FALSE; - - /* Send remaining rectangles (at right and bottom). */ - - if ( x_best + w_best != x + w && - !rfbSendRectEncodingTight(cl, x_best+w_best, y_best, - w-(x_best-x)-w_best, h_best) ) - return FALSE; - if ( y_best + h_best != y + h && - !rfbSendRectEncodingTight(cl, x, y_best+h_best, - w, h-(y_best-y)-h_best) ) - return FALSE; - - /* Return after all recursive calls are done. */ - - return TRUE; - } - - } - - } - - /* No suitable solid-color rectangles found. */ - - return SendRectSimple(cl, x, y, w, h); -} - -static void -FindBestSolidArea(x, y, w, h, colorValue, w_ptr, h_ptr) - int x, y, w, h; - CARD32 colorValue; - int *w_ptr, *h_ptr; -{ - int dx, dy, dw, dh; - int w_prev; - int w_best = 0, h_best = 0; - - w_prev = w; - - for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) { - - dh = (dy + MAX_SPLIT_TILE_SIZE <= y + h) ? - MAX_SPLIT_TILE_SIZE : (y + h - dy); - dw = (w_prev > MAX_SPLIT_TILE_SIZE) ? - MAX_SPLIT_TILE_SIZE : w_prev; - - if (!CheckSolidTile(x, dy, dw, dh, &colorValue, TRUE)) - break; - - for (dx = x + dw; dx < x + w_prev;) { - dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w_prev) ? - MAX_SPLIT_TILE_SIZE : (x + w_prev - dx); - if (!CheckSolidTile(dx, dy, dw, dh, &colorValue, TRUE)) - break; - dx += dw; - } - - w_prev = dx - x; - if (w_prev * (dy + dh - y) > w_best * h_best) { - w_best = w_prev; - h_best = dy + dh - y; - } - } - - *w_ptr = w_best; - *h_ptr = h_best; -} - -static void -ExtendSolidArea(x, y, w, h, colorValue, x_ptr, y_ptr, w_ptr, h_ptr) - int x, y, w, h; - CARD32 colorValue; - int *x_ptr, *y_ptr, *w_ptr, *h_ptr; -{ - int cx, cy; - - /* Try to extend the area upwards. */ - for ( cy = *y_ptr - 1; - cy >= y && CheckSolidTile(*x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); - cy-- ); - *h_ptr += *y_ptr - (cy + 1); - *y_ptr = cy + 1; - - /* ... downwards. */ - for ( cy = *y_ptr + *h_ptr; - cy < y + h && - CheckSolidTile(*x_ptr, cy, *w_ptr, 1, &colorValue, TRUE); - cy++ ); - *h_ptr += cy - (*y_ptr + *h_ptr); - - /* ... to the left. */ - for ( cx = *x_ptr - 1; - cx >= x && CheckSolidTile(cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); - cx-- ); - *w_ptr += *x_ptr - (cx + 1); - *x_ptr = cx + 1; - - /* ... to the right. */ - for ( cx = *x_ptr + *w_ptr; - cx < x + w && - CheckSolidTile(cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE); - cx++ ); - *w_ptr += cx - (*x_ptr + *w_ptr); -} - -/* - * Check if a rectangle is all of the same color. If needSameColor is - * set to non-zero, then also check that its color equals to the - * *colorPtr value. The result is 1 if the test is successfull, and in - * that case new color will be stored in *colorPtr. - */ - -static Bool -CheckSolidTile(x, y, w, h, colorPtr, needSameColor) - int x, y, w, h; - CARD32 *colorPtr; - Bool needSameColor; -{ - switch(rfbServerFormat.bitsPerPixel) { - case 32: - return CheckSolidTile32(x, y, w, h, colorPtr, needSameColor); - case 16: - return CheckSolidTile16(x, y, w, h, colorPtr, needSameColor); - default: - return CheckSolidTile8(x, y, w, h, colorPtr, needSameColor); - } -} - -#define DEFINE_CHECK_SOLID_FUNCTION(bpp) \ - \ -static Bool \ -CheckSolidTile##bpp(x, y, w, h, colorPtr, needSameColor) \ - int x, y, w, h; \ - CARD32 *colorPtr; \ - Bool needSameColor; \ -{ \ - CARD##bpp *fbptr; \ - CARD##bpp colorValue; \ - int dx, dy; \ - \ - fbptr = (CARD##bpp *) \ - &rfbScreen.pfbMemory[y * rfbScreen.paddedWidthInBytes + x * (bpp/8)]; \ - \ - colorValue = *fbptr; \ - if (needSameColor && (CARD32)colorValue != *colorPtr) \ - return FALSE; \ - \ - for (dy = 0; dy < h; dy++) { \ - for (dx = 0; dx < w; dx++) { \ - if (colorValue != fbptr[dx]) \ - return FALSE; \ - } \ - fbptr = (CARD##bpp *)((CARD8 *)fbptr + rfbScreen.paddedWidthInBytes); \ - } \ - \ - *colorPtr = (CARD32)colorValue; \ - return TRUE; \ -} - -DEFINE_CHECK_SOLID_FUNCTION(8) -DEFINE_CHECK_SOLID_FUNCTION(16) -DEFINE_CHECK_SOLID_FUNCTION(32) - -static Bool -SendRectSimple(cl, x, y, w, h) - rfbClientPtr cl; - int x, y, w, h; -{ - int maxBeforeSize, maxAfterSize; - int maxRectSize, maxRectWidth; - int subrectMaxWidth, subrectMaxHeight; - int dx, dy; - int rw, rh; - - maxRectSize = tightConf[compressLevel].maxRectSize; - maxRectWidth = tightConf[compressLevel].maxRectWidth; - - maxBeforeSize = maxRectSize * (cl->format.bitsPerPixel / 8); - maxAfterSize = maxBeforeSize + (maxBeforeSize + 99) / 100 + 12; - - if (tightBeforeBufSize < maxBeforeSize) { - tightBeforeBufSize = maxBeforeSize; - if (tightBeforeBuf == NULL) - tightBeforeBuf = (char *)xalloc(tightBeforeBufSize); - else - tightBeforeBuf = (char *)xrealloc(tightBeforeBuf, - tightBeforeBufSize); - } - - if (tightAfterBufSize < maxAfterSize) { - tightAfterBufSize = maxAfterSize; - if (tightAfterBuf == NULL) - tightAfterBuf = (char *)xalloc(tightAfterBufSize); - else - tightAfterBuf = (char *)xrealloc(tightAfterBuf, - tightAfterBufSize); - } - - if (w > maxRectWidth || w * h > maxRectSize) { - subrectMaxWidth = (w > maxRectWidth) ? maxRectWidth : w; - subrectMaxHeight = maxRectSize / subrectMaxWidth; - - for (dy = 0; dy < h; dy += subrectMaxHeight) { - for (dx = 0; dx < w; dx += maxRectWidth) { - rw = (dx + maxRectWidth < w) ? maxRectWidth : w - dx; - rh = (dy + subrectMaxHeight < h) ? subrectMaxHeight : h - dy; - if (!SendSubrect(cl, x+dx, y+dy, rw, rh)) - return FALSE; - } - } - } else { - if (!SendSubrect(cl, x, y, w, h)) - return FALSE; - } - - return TRUE; -} - -static Bool -SendSubrect(cl, x, y, w, h) - rfbClientPtr cl; - int x, y, w, h; -{ - char *fbptr; - Bool success = FALSE; - - /* Send pending data if there is more than 128 bytes. */ - if (ublen > 128) { - if (!rfbSendUpdateBuf(cl)) - return FALSE; - } - - if (!SendTightHeader(cl, x, y, w, h)) - return FALSE; - - fbptr = (rfbScreen.pfbMemory + (rfbScreen.paddedWidthInBytes * y) - + (x * (rfbScreen.bitsPerPixel / 8))); - - if (subsampLevel == TJ_GRAYSCALE && qualityLevel != -1) - return SendJpegRect(cl, x, y, w, h, qualityLevel); - - paletteMaxColors = w * h / tightConf[compressLevel].idxMaxColorsDivisor; - if(qualityLevel != -1) - paletteMaxColors = 24; - if ( paletteMaxColors < 2 && - w * h >= tightConf[compressLevel].monoMinRectSize ) { - paletteMaxColors = 2; - } - - if (cl->format.bitsPerPixel == rfbServerFormat.bitsPerPixel && - cl->format.redMax == rfbServerFormat.redMax && - cl->format.greenMax == rfbServerFormat.greenMax && - cl->format.blueMax == rfbServerFormat.blueMax && - cl->format.bitsPerPixel >= 16) { - - /* This is so we can avoid translating the pixels when compressing - with JPEG, since it is unnecessary */ - switch (cl->format.bitsPerPixel) { - case 16: - FastFillPalette16(cl, (CARD16 *)fbptr, w, - rfbScreen.paddedWidthInBytes/2, h); - break; - default: - FastFillPalette32(cl, (CARD32 *)fbptr, w, - rfbScreen.paddedWidthInBytes/4, h); - } - - if(paletteNumColors != 0 || qualityLevel == -1) { - (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, - &cl->format, fbptr, tightBeforeBuf, - rfbScreen.paddedWidthInBytes, w, h); - } - } - else { - (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, - &cl->format, fbptr, tightBeforeBuf, - rfbScreen.paddedWidthInBytes, w, h); - - switch (cl->format.bitsPerPixel) { - case 8: - FillPalette8(w * h); - break; - case 16: - FillPalette16(w * h); - break; - default: - FillPalette32(w * h); - } - } - - switch (paletteNumColors) { - case 0: - /* Truecolor image */ - if (qualityLevel != -1) { - success = SendJpegRect(cl, x, y, w, h, qualityLevel); - } else { - success = SendFullColorRect(cl, w, h); - } - break; - case 1: - /* Solid rectangle */ - success = SendSolidRect(cl); - break; - case 2: - /* Two-color rectangle */ - success = SendMonoRect(cl, w, h); - break; - default: - /* Up to 256 different colors */ - success = SendIndexedRect(cl, w, h); - } - return success; -} - -static Bool -SendTightHeader(cl, x, y, w, h) - rfbClientPtr cl; - int x, y, w, h; -{ - rfbFramebufferUpdateRectHeader rect; - - if (ublen + sz_rfbFramebufferUpdateRectHeader > UPDATE_BUF_SIZE) { - if (!rfbSendUpdateBuf(cl)) - return FALSE; - } - - rect.r.x = Swap16IfLE(x); - rect.r.y = Swap16IfLE(y); - rect.r.w = Swap16IfLE(w); - rect.r.h = Swap16IfLE(h); - rect.encoding = Swap32IfLE(rfbEncodingTight); - - memcpy(&updateBuf[ublen], (char *)&rect, - sz_rfbFramebufferUpdateRectHeader); - ublen += sz_rfbFramebufferUpdateRectHeader; - - cl->rfbRectanglesSent[rfbEncodingTight]++; - cl->rfbBytesSent[rfbEncodingTight] += sz_rfbFramebufferUpdateRectHeader; - - return TRUE; -} - -/* - * Subencoding implementations. - */ - -static Bool -SendSolidRect(cl) - rfbClientPtr cl; -{ - int len; - - if (usePixelFormat24) { - Pack24(tightBeforeBuf, &cl->format, 1); - len = 3; - } else - len = cl->format.bitsPerPixel / 8; - - if (ublen + 1 + len > UPDATE_BUF_SIZE) { - if (!rfbSendUpdateBuf(cl)) - return FALSE; - } - - updateBuf[ublen++] = (char)(rfbTightFill << 4); - memcpy (&updateBuf[ublen], tightBeforeBuf, len); - ublen += len; - - cl->rfbBytesSent[rfbEncodingTight] += len + 1; - - return TRUE; -} - -static Bool -SendMonoRect(cl, w, h) - rfbClientPtr cl; - int w, h; -{ - int streamId = 1; - int paletteLen, dataLen; - - if ( (ublen + TIGHT_MIN_TO_COMPRESS + 6 + - 2 * cl->format.bitsPerPixel / 8) > UPDATE_BUF_SIZE ) { - if (!rfbSendUpdateBuf(cl)) - return FALSE; - } - - /* Prepare tight encoding header. */ - dataLen = (w + 7) / 8; - dataLen *= h; - - if (tightConf[compressLevel].monoZlibLevel == 0) - updateBuf[ublen++] = (char)((rfbTightNoZlib | rfbTightExplicitFilter) << 4); - else - updateBuf[ublen++] = (streamId | rfbTightExplicitFilter) << 4; - updateBuf[ublen++] = rfbTightFilterPalette; - updateBuf[ublen++] = 1; - - /* Prepare palette, convert image. */ - switch (cl->format.bitsPerPixel) { - - case 32: - EncodeMonoRect32((CARD8 *)tightBeforeBuf, w, h); - - ((CARD32 *)tightAfterBuf)[0] = monoBackground; - ((CARD32 *)tightAfterBuf)[1] = monoForeground; - if (usePixelFormat24) { - Pack24(tightAfterBuf, &cl->format, 2); - paletteLen = 6; - } else - paletteLen = 8; - - memcpy(&updateBuf[ublen], tightAfterBuf, paletteLen); - ublen += paletteLen; - cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteLen; - break; - - case 16: - EncodeMonoRect16((CARD8 *)tightBeforeBuf, w, h); - - ((CARD16 *)tightAfterBuf)[0] = (CARD16)monoBackground; - ((CARD16 *)tightAfterBuf)[1] = (CARD16)monoForeground; - - memcpy(&updateBuf[ublen], tightAfterBuf, 4); - ublen += 4; - cl->rfbBytesSent[rfbEncodingTight] += 7; - break; - - default: - EncodeMonoRect8((CARD8 *)tightBeforeBuf, w, h); - - updateBuf[ublen++] = (char)monoBackground; - updateBuf[ublen++] = (char)monoForeground; - cl->rfbBytesSent[rfbEncodingTight] += 5; - } - - return CompressData(cl, streamId, dataLen, - tightConf[compressLevel].monoZlibLevel, - Z_DEFAULT_STRATEGY); -} - -static Bool -SendIndexedRect(cl, w, h) - rfbClientPtr cl; - int w, h; -{ - int streamId = 2; - int i, entryLen; - - if ( (ublen + TIGHT_MIN_TO_COMPRESS + 6 + - paletteNumColors * cl->format.bitsPerPixel / 8) > UPDATE_BUF_SIZE ) { - if (!rfbSendUpdateBuf(cl)) - return FALSE; - } - - /* Prepare tight encoding header. */ - if (tightConf[compressLevel].idxZlibLevel == 0) - updateBuf[ublen++] = (char)((rfbTightNoZlib | rfbTightExplicitFilter) << 4); - else - updateBuf[ublen++] = (streamId | rfbTightExplicitFilter) << 4; - updateBuf[ublen++] = rfbTightFilterPalette; - updateBuf[ublen++] = (char)(paletteNumColors - 1); - - /* Prepare palette, convert image. */ - switch (cl->format.bitsPerPixel) { - - case 32: - EncodeIndexedRect32((CARD8 *)tightBeforeBuf, w * h); - - for (i = 0; i < paletteNumColors; i++) { - ((CARD32 *)tightAfterBuf)[i] = - palette.entry[i].listNode->rgb; - } - if (usePixelFormat24) { - Pack24(tightAfterBuf, &cl->format, paletteNumColors); - entryLen = 3; - } else - entryLen = 4; - - memcpy(&updateBuf[ublen], tightAfterBuf, paletteNumColors * entryLen); - ublen += paletteNumColors * entryLen; - cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * entryLen; - break; - - case 16: - EncodeIndexedRect16((CARD8 *)tightBeforeBuf, w * h); - - for (i = 0; i < paletteNumColors; i++) { - ((CARD16 *)tightAfterBuf)[i] = - (CARD16)palette.entry[i].listNode->rgb; - } - - memcpy(&updateBuf[ublen], tightAfterBuf, paletteNumColors * 2); - ublen += paletteNumColors * 2; - cl->rfbBytesSent[rfbEncodingTight] += 3 + paletteNumColors * 2; - break; - - default: - return FALSE; /* Should never happen. */ - } - - return CompressData(cl, streamId, w * h, - tightConf[compressLevel].idxZlibLevel, - Z_DEFAULT_STRATEGY); -} - -static Bool -SendFullColorRect(cl, w, h) - rfbClientPtr cl; - int w, h; -{ - int streamId = 0; - int len; - - if (ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) { - if (!rfbSendUpdateBuf(cl)) - return FALSE; - } - - if (tightConf[compressLevel].rawZlibLevel == 0) - updateBuf[ublen++] = (char)(rfbTightNoZlib << 4); - else - updateBuf[ublen++] = 0x00; /* stream id = 0, no flushing, no filter */ - cl->rfbBytesSent[rfbEncodingTight]++; - - if (usePixelFormat24) { - Pack24(tightBeforeBuf, &cl->format, w * h); - len = 3; - } else - len = cl->format.bitsPerPixel / 8; - - return CompressData(cl, streamId, w * h * len, - tightConf[compressLevel].rawZlibLevel, - Z_DEFAULT_STRATEGY); -} - -static Bool -CompressData(cl, streamId, dataLen, zlibLevel, zlibStrategy) - rfbClientPtr cl; - int streamId, dataLen, zlibLevel, zlibStrategy; -{ - z_streamp pz; - int err, i; - - if (dataLen < TIGHT_MIN_TO_COMPRESS) { - memcpy(&updateBuf[ublen], tightBeforeBuf, dataLen); - ublen += dataLen; - cl->rfbBytesSent[rfbEncodingTight] += dataLen; - return TRUE; - } - - if (zlibLevel == 0) - return SendCompressedData (cl, tightBeforeBuf, dataLen); - - pz = &cl->zsStruct[streamId]; - - /* Initialize compression stream if needed. */ - if (!cl->zsActive[streamId]) { - pz->zalloc = Z_NULL; - pz->zfree = Z_NULL; - pz->opaque = Z_NULL; - - err = deflateInit2 (pz, zlibLevel, Z_DEFLATED, MAX_WBITS, - MAX_MEM_LEVEL, zlibStrategy); - if (err != Z_OK) - return FALSE; - - cl->zsActive[streamId] = TRUE; - cl->zsLevel[streamId] = zlibLevel; - } - - /* Prepare buffer pointers. */ - pz->next_in = (Bytef *)tightBeforeBuf; - pz->avail_in = dataLen; - pz->next_out = (Bytef *)tightAfterBuf; - pz->avail_out = tightAfterBufSize; - - /* Change compression parameters if needed. */ - if (zlibLevel != cl->zsLevel[streamId]) { - if (deflateParams (pz, zlibLevel, zlibStrategy) != Z_OK) { - return FALSE; - } - cl->zsLevel[streamId] = zlibLevel; - } - - /* Actual compression. */ - if ( deflate (pz, Z_SYNC_FLUSH) != Z_OK || - pz->avail_in != 0 || pz->avail_out == 0 ) { - return FALSE; - } - - return SendCompressedData(cl, tightAfterBuf, - tightAfterBufSize - pz->avail_out); -} - -static Bool SendCompressedData(cl, buf, compressedLen) - rfbClientPtr cl; - char *buf; - int compressedLen; -{ - int i, portionLen; - - updateBuf[ublen++] = compressedLen & 0x7F; - cl->rfbBytesSent[rfbEncodingTight]++; - if (compressedLen > 0x7F) { - updateBuf[ublen-1] |= 0x80; - updateBuf[ublen++] = compressedLen >> 7 & 0x7F; - cl->rfbBytesSent[rfbEncodingTight]++; - if (compressedLen > 0x3FFF) { - updateBuf[ublen-1] |= 0x80; - updateBuf[ublen++] = compressedLen >> 14 & 0xFF; - cl->rfbBytesSent[rfbEncodingTight]++; - } - } - - portionLen = UPDATE_BUF_SIZE; - for (i = 0; i < compressedLen; i += portionLen) { - if (i + portionLen > compressedLen) { - portionLen = compressedLen - i; - } - if (ublen + portionLen > UPDATE_BUF_SIZE) { - if (!rfbSendUpdateBuf(cl)) - return FALSE; - } - memcpy(&updateBuf[ublen], &buf[i], portionLen); - ublen += portionLen; - } - cl->rfbBytesSent[rfbEncodingTight] += compressedLen; - return TRUE; -} - -/* - * Code to determine how many different colors used in rectangle. - */ - -static void -FillPalette8(count) - int count; -{ - CARD8 *data = (CARD8 *)tightBeforeBuf; - CARD8 c0, c1; - int i, n0, n1; - - paletteNumColors = 0; - - c0 = data[0]; - for (i = 1; i < count && data[i] == c0; i++); - if (i == count) { - paletteNumColors = 1; - return; /* Solid rectangle */ - } - - if (paletteMaxColors < 2) - return; - - n0 = i; - c1 = data[i]; - n1 = 0; - for (i++; i < count; i++) { - if (data[i] == c0) { - n0++; - } else if (data[i] == c1) { - n1++; - } else - break; - } - if (i == count) { - if (n0 > n1) { - monoBackground = (CARD32)c0; - monoForeground = (CARD32)c1; - } else { - monoBackground = (CARD32)c1; - monoForeground = (CARD32)c0; - } - paletteNumColors = 2; /* Two colors */ - } -} - -#define DEFINE_FILL_PALETTE_FUNCTION(bpp) \ - \ -static void \ -FillPalette##bpp(count) \ - int count; \ -{ \ - CARD##bpp *data = (CARD##bpp *)tightBeforeBuf; \ - CARD##bpp c0, c1, ci; \ - int i, n0, n1, ni; \ - \ - c0 = data[0]; \ - for (i = 1; i < count && data[i] == c0; i++); \ - if (i >= count) { \ - paletteNumColors = 1; /* Solid rectangle */ \ - return; \ - } \ - \ - if (paletteMaxColors < 2) { \ - paletteNumColors = 0; /* Full-color encoding preferred */ \ - return; \ - } \ - \ - n0 = i; \ - c1 = data[i]; \ - n1 = 0; \ - for (i++; i < count; i++) { \ - ci = data[i]; \ - if (ci == c0) { \ - n0++; \ - } else if (ci == c1) { \ - n1++; \ - } else \ - break; \ - } \ - if (i >= count) { \ - if (n0 > n1) { \ - monoBackground = (CARD32)c0; \ - monoForeground = (CARD32)c1; \ - } else { \ - monoBackground = (CARD32)c1; \ - monoForeground = (CARD32)c0; \ - } \ - paletteNumColors = 2; /* Two colors */ \ - return; \ - } \ - \ - PaletteReset(); \ - PaletteInsert (c0, (CARD32)n0, bpp); \ - PaletteInsert (c1, (CARD32)n1, bpp); \ - \ - ni = 1; \ - for (i++; i < count; i++) { \ - if (data[i] == ci) { \ - ni++; \ - } else { \ - if (!PaletteInsert (ci, (CARD32)ni, bpp)) \ - return; \ - ci = data[i]; \ - ni = 1; \ - } \ - } \ - PaletteInsert (ci, (CARD32)ni, bpp); \ -} - -DEFINE_FILL_PALETTE_FUNCTION(16) -DEFINE_FILL_PALETTE_FUNCTION(32) - -#define DEFINE_FAST_FILL_PALETTE_FUNCTION(bpp) \ - \ -static void \ -FastFillPalette##bpp(cl, data, w, pitch, h) \ - rfbClientPtr cl; \ - CARD##bpp *data; \ - int w, pitch, h; \ -{ \ - CARD##bpp c0, c1, ci, mask, c0t, c1t, cit; \ - int i, j, i2, j2, n0, n1, ni; \ - \ - if (cl->translateFn != rfbTranslateNone) { \ - mask = rfbServerFormat.redMax << rfbServerFormat.redShift; \ - mask |= rfbServerFormat.greenMax << rfbServerFormat.greenShift; \ - mask |= rfbServerFormat.blueMax << rfbServerFormat.blueShift; \ - } else mask = ~0; \ - \ - c0 = data[0] & mask; \ - for (j = 0; j < h; j++) { \ - for (i = 0; i < w; i++) { \ - if ((data[j * pitch + i] & mask) != c0) \ - goto done; \ - } \ - } \ - done: \ - if (j >= h) { \ - paletteNumColors = 1; /* Solid rectangle */ \ - return; \ - } \ - if (paletteMaxColors < 2) { \ - paletteNumColors = 0; /* Full-color encoding preferred */ \ - return; \ - } \ - \ - n0 = j * w + i; \ - c1 = data[j * pitch + i] & mask; \ - n1 = 0; \ - i++; if (i >= w) {i = 0; j++;} \ - for (j2 = j; j2 < h; j2++) { \ - for (i2 = i; i2 < w; i2++) { \ - ci = data[j2 * pitch + i2] & mask; \ - if (ci == c0) { \ - n0++; \ - } else if (ci == c1) { \ - n1++; \ - } else \ - goto done2; \ - } \ - i = 0; \ - } \ - done2: \ - (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, \ - &cl->format, (char *)&c0, (char *)&c0t, bpp/8, \ - 1, 1); \ - (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, \ - &cl->format, (char *)&c1, (char *)&c1t, bpp/8, \ - 1, 1); \ - if (j2 >= h) { \ - if (n0 > n1) { \ - monoBackground = (CARD32)c0t; \ - monoForeground = (CARD32)c1t; \ - } else { \ - monoBackground = (CARD32)c1t; \ - monoForeground = (CARD32)c0t; \ - } \ - paletteNumColors = 2; /* Two colors */ \ - return; \ - } \ - \ - PaletteReset(); \ - PaletteInsert (c0t, (CARD32)n0, bpp); \ - PaletteInsert (c1t, (CARD32)n1, bpp); \ - \ - ni = 1; \ - i2++; if (i2 >= w) {i2 = 0; j2++;} \ - for (j = j2; j < h; j++) { \ - for (i = i2; i < w; i++) { \ - if ((data[j * pitch + i] & mask) == ci) { \ - ni++; \ - } else { \ - (*cl->translateFn)(cl->translateLookupTable, \ - &rfbServerFormat, &cl->format, \ - (char *)&ci, (char *)&cit, bpp/8, \ - 1, 1); \ - if (!PaletteInsert (cit, (CARD32)ni, bpp)) \ - return; \ - ci = data[j * pitch + i] & mask; \ - ni = 1; \ - } \ - } \ - i2 = 0; \ - } \ - \ - (*cl->translateFn)(cl->translateLookupTable, &rfbServerFormat, \ - &cl->format, (char *)&ci, (char *)&cit, bpp/8, \ - 1, 1); \ - PaletteInsert (cit, (CARD32)ni, bpp); \ -} - -DEFINE_FAST_FILL_PALETTE_FUNCTION(16) -DEFINE_FAST_FILL_PALETTE_FUNCTION(32) - - -/* - * Functions to operate with palette structures. - */ - -#define HASH_FUNC16(rgb) ((int)((((rgb) >> 8) + (rgb)) & 0xFF)) -#define HASH_FUNC32(rgb) ((int)((((rgb) >> 16) + ((rgb) >> 8)) & 0xFF)) - -static void -PaletteReset(void) -{ - paletteNumColors = 0; - memset(palette.hash, 0, 256 * sizeof(COLOR_LIST *)); -} - -static int -PaletteInsert(rgb, numPixels, bpp) - CARD32 rgb; - int numPixels; - int bpp; -{ - COLOR_LIST *pnode; - COLOR_LIST *prev_pnode = NULL; - int hash_key, idx, new_idx, count; - - hash_key = (bpp == 16) ? HASH_FUNC16(rgb) : HASH_FUNC32(rgb); - - pnode = palette.hash[hash_key]; - - while (pnode != NULL) { - if (pnode->rgb == rgb) { - /* Such palette entry already exists. */ - new_idx = idx = pnode->idx; - count = palette.entry[idx].numPixels + numPixels; - if (new_idx && palette.entry[new_idx-1].numPixels < count) { - do { - palette.entry[new_idx] = palette.entry[new_idx-1]; - palette.entry[new_idx].listNode->idx = new_idx; - new_idx--; - } - while (new_idx && palette.entry[new_idx-1].numPixels < count); - palette.entry[new_idx].listNode = pnode; - pnode->idx = new_idx; - } - palette.entry[new_idx].numPixels = count; - return paletteNumColors; - } - prev_pnode = pnode; - pnode = pnode->next; - } - - /* Check if palette is full. */ - if (paletteNumColors == 256 || paletteNumColors == paletteMaxColors) { - paletteNumColors = 0; - return 0; - } - - /* Move palette entries with lesser pixel counts. */ - for ( idx = paletteNumColors; - idx > 0 && palette.entry[idx-1].numPixels < numPixels; - idx-- ) { - palette.entry[idx] = palette.entry[idx-1]; - palette.entry[idx].listNode->idx = idx; - } - - /* Add new palette entry into the freed slot. */ - pnode = &palette.list[paletteNumColors]; - if (prev_pnode != NULL) { - prev_pnode->next = pnode; - } else { - palette.hash[hash_key] = pnode; - } - pnode->next = NULL; - pnode->idx = idx; - pnode->rgb = rgb; - palette.entry[idx].listNode = pnode; - palette.entry[idx].numPixels = numPixels; - - return (++paletteNumColors); -} - - -/* - * Converting 32-bit color samples into 24-bit colors. - * Should be called only when redMax, greenMax and blueMax are 255. - * Color components assumed to be byte-aligned. - */ - -static void Pack24(buf, fmt, count) - char *buf; - rfbPixelFormat *fmt; - int count; -{ - CARD32 *buf32; - CARD32 pix; - int r_shift, g_shift, b_shift; - - buf32 = (CARD32 *)buf; - - if (!rfbServerFormat.bigEndian == !fmt->bigEndian) { - r_shift = fmt->redShift; - g_shift = fmt->greenShift; - b_shift = fmt->blueShift; - } else { - r_shift = 24 - fmt->redShift; - g_shift = 24 - fmt->greenShift; - b_shift = 24 - fmt->blueShift; - } - - while (count--) { - pix = *buf32++; - *buf++ = (char)(pix >> r_shift); - *buf++ = (char)(pix >> g_shift); - *buf++ = (char)(pix >> b_shift); - } -} - - -/* - * Converting truecolor samples into palette indices. - */ - -#define DEFINE_IDX_ENCODE_FUNCTION(bpp) \ - \ -static void \ -EncodeIndexedRect##bpp(buf, count) \ - CARD8 *buf; \ - int count; \ -{ \ - COLOR_LIST *pnode; \ - CARD##bpp *src; \ - CARD##bpp rgb; \ - int rep = 0; \ - \ - src = (CARD##bpp *) buf; \ - \ - while (count--) { \ - rgb = *src++; \ - while (count && *src == rgb) { \ - rep++, src++, count--; \ - } \ - pnode = palette.hash[HASH_FUNC##bpp(rgb)]; \ - while (pnode != NULL) { \ - if ((CARD##bpp)pnode->rgb == rgb) { \ - *buf++ = (CARD8)pnode->idx; \ - while (rep) { \ - *buf++ = (CARD8)pnode->idx; \ - rep--; \ - } \ - break; \ - } \ - pnode = pnode->next; \ - } \ - } \ -} - -DEFINE_IDX_ENCODE_FUNCTION(16) -DEFINE_IDX_ENCODE_FUNCTION(32) - -#define DEFINE_MONO_ENCODE_FUNCTION(bpp) \ - \ -static void \ -EncodeMonoRect##bpp(buf, w, h) \ - CARD8 *buf; \ - int w, h; \ -{ \ - CARD##bpp *ptr; \ - CARD##bpp bg; \ - unsigned int value, mask; \ - int aligned_width; \ - int x, y, bg_bits; \ - \ - ptr = (CARD##bpp *) buf; \ - bg = (CARD##bpp) monoBackground; \ - aligned_width = w - w % 8; \ - \ - for (y = 0; y < h; y++) { \ - for (x = 0; x < aligned_width; x += 8) { \ - for (bg_bits = 0; bg_bits < 8; bg_bits++) { \ - if (*ptr++ != bg) \ - break; \ - } \ - if (bg_bits == 8) { \ - *buf++ = 0; \ - continue; \ - } \ - mask = 0x80 >> bg_bits; \ - value = mask; \ - for (bg_bits++; bg_bits < 8; bg_bits++) { \ - mask >>= 1; \ - if (*ptr++ != bg) { \ - value |= mask; \ - } \ - } \ - *buf++ = (CARD8)value; \ - } \ - \ - mask = 0x80; \ - value = 0; \ - if (x >= w) \ - continue; \ - \ - for (; x < w; x++) { \ - if (*ptr++ != bg) { \ - value |= mask; \ - } \ - mask >>= 1; \ - } \ - *buf++ = (CARD8)value; \ - } \ -} - -DEFINE_MONO_ENCODE_FUNCTION(8) -DEFINE_MONO_ENCODE_FUNCTION(16) -DEFINE_MONO_ENCODE_FUNCTION(32) - -/* - * JPEG compression stuff. - */ - -static unsigned long jpegDstDataLen; -static tjhandle j=NULL; - -static Bool -SendJpegRect(cl, x, y, w, h, quality) - rfbClientPtr cl; - int x, y, w, h; - int quality; -{ - int dy; - unsigned char *srcbuf; - int ps=rfbServerFormat.bitsPerPixel/8; - int subsamp=subsampLevel2tjsubsamp[subsampLevel]; - unsigned long size=0; - int flags=0, pitch; - unsigned char *tmpbuf=NULL; - - if (rfbServerFormat.bitsPerPixel == 8) - return SendFullColorRect(cl, w, h); - - - if(ps<2) { - rfbLog("Error: JPEG requires 16-bit, 24-bit, or 32-bit pixel format.\n"); - return 0; - } - if(!j) { - if((j=tjInitCompress())==NULL) { - rfbLog("JPEG Error: %s\n", tjGetErrorStr()); return 0; - } - } - - if (tightAfterBufSize < TJBUFSIZE(w,h)) { - if (tightAfterBuf == NULL) - tightAfterBuf = (char *)xalloc(TJBUFSIZE(w,h)); - else - tightAfterBuf = (char *)xrealloc(tightAfterBuf, - TJBUFSIZE(w,h)); - if(!tightAfterBuf) { - rfbLog("Memory allocation failure!\n"); - return 0; - } - tightAfterBufSize = TJBUFSIZE(w,h); - } - - if (ps == 2) { - CARD16 *srcptr, pix; - unsigned char *dst; - int inRed, inGreen, inBlue, i, j; - - if((tmpbuf=(unsigned char *)malloc(w*h*3))==NULL) - rfbLog("Memory allocation failure!\n"); - srcptr = (CARD16 *) - &rfbScreen.pfbMemory[y * rfbScreen.paddedWidthInBytes + - x * ps]; - dst = tmpbuf; - for(j=0; j<h; j++) { - CARD16 *srcptr2=srcptr; - unsigned char *dst2=dst; - for(i=0; i<w; i++) { - pix = *srcptr2++; - inRed = (int) - (pix >> rfbServerFormat.redShift & rfbServerFormat.redMax); - inGreen = (int) - (pix >> rfbServerFormat.greenShift & rfbServerFormat.greenMax); - inBlue = (int) - (pix >> rfbServerFormat.blueShift & rfbServerFormat.blueMax); - *dst2++ = (CARD8)((inRed * 255 + rfbServerFormat.redMax / 2) / - rfbServerFormat.redMax); - *dst2++ = (CARD8)((inGreen * 255 + rfbServerFormat.greenMax / 2) / - rfbServerFormat.greenMax); - *dst2++ = (CARD8)((inBlue * 255 + rfbServerFormat.blueMax / 2) / - rfbServerFormat.blueMax); - } - srcptr+=rfbScreen.paddedWidthInBytes/ps; - dst+=w*3; - } - srcbuf = tmpbuf; - pitch = w*3; - ps = 3; - } else { - if(rfbServerFormat.bigEndian && ps==4) flags|=TJ_ALPHAFIRST; - if(rfbServerFormat.redShift==16 && rfbServerFormat.blueShift==0) - flags|=TJ_BGR; - if(rfbServerFormat.bigEndian) flags^=TJ_BGR; - srcbuf=(unsigned char *)&rfbScreen.pfbMemory[y * - rfbScreen.paddedWidthInBytes + x * ps]; - pitch=rfbScreen.paddedWidthInBytes; - } - - if(tjCompress(j, srcbuf, w, pitch, h, ps, (unsigned char *)tightAfterBuf, - &size, subsamp, quality, flags)==-1) { - rfbLog("JPEG Error: %s\n", tjGetErrorStr()); - if(tmpbuf) {free(tmpbuf); tmpbuf=NULL;} - return 0; - } - jpegDstDataLen=(int)size; - - if(tmpbuf) {free(tmpbuf); tmpbuf=NULL;} - - if (ublen + TIGHT_MIN_TO_COMPRESS + 1 > UPDATE_BUF_SIZE) { - if (!rfbSendUpdateBuf(cl)) - return FALSE; - } - - updateBuf[ublen++] = (char)(rfbTightJpeg << 4); - cl->rfbBytesSent[rfbEncodingTight]++; - - return SendCompressedData(cl, tightAfterBuf, jpegDstDataLen); -} diff --git a/x11vnc/misc/turbovnc/turbojpeg.h b/x11vnc/misc/turbovnc/turbojpeg.h deleted file mode 100644 index 8a6af05..0000000 --- a/x11vnc/misc/turbovnc/turbojpeg.h +++ /dev/null @@ -1,229 +0,0 @@ -/* Copyright (C)2004 Landmark Graphics - * Copyright (C)2005, 2006 Sun Microsystems, Inc. - * - * This library is free software and may be redistributed and/or modified under - * the terms of the wxWindows Library License, Version 3 or (at your option) - * any later version. The full license is in the LICENSE.txt file included - * with this distribution. - * - * This library 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 - * wxWindows Library License for more details. - */ - -#if (defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)) && defined(_WIN32) && defined(DLLDEFINE) -#define DLLEXPORT __declspec(dllexport) -#else -#define DLLEXPORT -#endif - -#define DLLCALL - -/* Subsampling */ -#define NUMSUBOPT 4 - -enum {TJ_444=0, TJ_422, TJ_411, TJ_GRAYSCALE}; - -/* Flags */ -#define TJ_BGR 1 -#define TJ_BOTTOMUP 2 -#define TJ_FORCEMMX 8 /* Force IPP to use MMX code even if SSE available */ -#define TJ_FORCESSE 16 /* Force IPP to use SSE1 code even if SSE2 available */ -#define TJ_FORCESSE2 32 /* Force IPP to use SSE2 code (useful if auto-detect is not working properly) */ -#define TJ_ALPHAFIRST 64 /* BGR buffer is ABGR and RGB buffer is ARGB */ -#define TJ_FORCESSE3 128 /* Force IPP to use SSE3 code (useful if auto-detect is not working properly) */ - -typedef void* tjhandle; - -#define TJPAD(p) (((p)+3)&(~3)) -#ifndef max - #define max(a,b) ((a)>(b)?(a):(b)) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* API follows */ - - -/* - tjhandle tjInitCompress(void) - - Creates a new JPEG compressor instance, allocates memory for the structures, - and returns a handle to the instance. Most applications will only - need to call this once at the beginning of the program or once for each - concurrent thread. Don't try to create a new instance every time you - compress an image, because this will cause performance to suffer. - - RETURNS: NULL on error -*/ -DLLEXPORT tjhandle DLLCALL tjInitCompress(void); - - -/* - int tjCompress(tjhandle j, - unsigned char *srcbuf, int width, int pitch, int height, int pixelsize, - unsigned char *dstbuf, unsigned long *size, - int jpegsubsamp, int jpegqual, int flags) - - [INPUT] j = instance handle previously returned from a call to - tjInitCompress() - [INPUT] srcbuf = pointer to user-allocated image buffer containing pixels in - RGB(A) or BGR(A) form - [INPUT] width = width (in pixels) of the source image - [INPUT] pitch = bytes per line of the source image (width*pixelsize if the - bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap - is padded to the nearest 32-bit boundary, such as is the case for Windows - bitmaps. You can also be clever and use this parameter to skip lines, etc., - as long as the pitch is greater than 0.) - [INPUT] height = height (in pixels) of the source image - [INPUT] pixelsize = size (in bytes) of each pixel in the source image - RGBA and BGRA: 4, RGB and BGR: 3 - [INPUT] dstbuf = pointer to user-allocated image buffer which will receive - the JPEG image. Use the macro TJBUFSIZE(width, height) to determine - the appropriate size for this buffer based on the image width and height. - [OUTPUT] size = pointer to unsigned long which receives the size (in bytes) - of the compressed image - [INPUT] jpegsubsamp = Specifies either 4:1:1, 4:2:2, or 4:4:4 subsampling. - When the image is converted from the RGB to YCbCr colorspace as part of the - JPEG compression process, every other Cb and Cr (chrominance) pixel can be - discarded to produce a smaller image with little perceptible loss of - image clarity (the human eye is more sensitive to small changes in - brightness than small changes in color.) - - TJ_411: 4:1:1 subsampling. Discards every other Cb, Cr pixel in both - horizontal and vertical directions. - TJ_422: 4:2:2 subsampling. Discards every other Cb, Cr pixel only in - the horizontal direction. - TJ_444: no subsampling. - TJ_GRAYSCALE: Generate grayscale JPEG image - - [INPUT] jpegqual = JPEG quality (an integer between 0 and 100 inclusive.) - [INPUT] flags = the bitwise OR of one or more of the following - - TJ_BGR: The components of each pixel in the source image are stored in - B,G,R order, not R,G,B - TJ_BOTTOMUP: The source image is stored in bottom-up (Windows) order, - not top-down - TJ_FORCEMMX: Valid only for the Intel Performance Primitives implementation - of this codec-- force IPP to use MMX code (bypass CPU auto-detection) - TJ_FORCESSE: Valid only for the Intel Performance Primitives implementation - of this codec-- force IPP to use SSE code (bypass CPU auto-detection) - TJ_FORCESSE2: Valid only for the Intel Performance Primitives implementation - of this codec-- force IPP to use SSE2 code (bypass CPU auto-detection) - TJ_FORCESSE3: Valid only for the Intel Performance Primitives implementation - of this codec-- force IPP to use SSE3 code (bypass CPU auto-detection) - - RETURNS: 0 on success, -1 on error -*/ -DLLEXPORT int DLLCALL tjCompress(tjhandle j, - unsigned char *srcbuf, int width, int pitch, int height, int pixelsize, - unsigned char *dstbuf, unsigned long *size, - int jpegsubsamp, int jpegqual, int flags); - -DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height); - -/* - tjhandle tjInitDecompress(void) - - Creates a new JPEG decompressor instance, allocates memory for the - structures, and returns a handle to the instance. Most applications will - only need to call this once at the beginning of the program or once for each - concurrent thread. Don't try to create a new instance every time you - decompress an image, because this will cause performance to suffer. - - RETURNS: NULL on error -*/ -DLLEXPORT tjhandle DLLCALL tjInitDecompress(void); - - -/* - int tjDecompressHeader(tjhandle j, - unsigned char *srcbuf, unsigned long size, - int *width, int *height) - - [INPUT] j = instance handle previously returned from a call to - tjInitDecompress() - [INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image - to decompress - [INPUT] size = size of the JPEG image buffer (in bytes) - [OUTPUT] width = width (in pixels) of the JPEG image - [OUTPUT] height = height (in pixels) of the JPEG image - - RETURNS: 0 on success, -1 on error -*/ -DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle j, - unsigned char *srcbuf, unsigned long size, - int *width, int *height); - - -/* - int tjDecompress(tjhandle j, - unsigned char *srcbuf, unsigned long size, - unsigned char *dstbuf, int width, int pitch, int height, int pixelsize, - int flags) - - [INPUT] j = instance handle previously returned from a call to - tjInitDecompress() - [INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image - to decompress - [INPUT] size = size of the JPEG image buffer (in bytes) - [INPUT] dstbuf = pointer to user-allocated image buffer which will receive - the bitmap image. This buffer should normally be pitch*height - bytes in size, although this pointer may also be used to decompress into - a specific region of a larger buffer. - [INPUT] width = width (in pixels) of the destination image - [INPUT] pitch = bytes per line of the destination image (width*pixelsize if the - bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap - is padded to the nearest 32-bit boundary, such as is the case for Windows - bitmaps. You can also be clever and use this parameter to skip lines, etc., - as long as the pitch is greater than 0.) - [INPUT] height = height (in pixels) of the destination image - [INPUT] pixelsize = size (in bytes) of each pixel in the destination image - RGBA/RGBx and BGRA/BGRx: 4, RGB and BGR: 3 - [INPUT] flags = the bitwise OR of one or more of the following - - TJ_BGR: The components of each pixel in the destination image should be - written in B,G,R order, not R,G,B - TJ_BOTTOMUP: The destination image should be stored in bottom-up - (Windows) order, not top-down - TJ_FORCEMMX: Valid only for the Intel Performance Primitives implementation - of this codec-- force IPP to use MMX code (bypass CPU auto-detection) - TJ_FORCESSE: Valid only for the Intel Performance Primitives implementation - of this codec-- force IPP to use SSE code (bypass CPU auto-detection) - TJ_FORCESSE2: Valid only for the Intel Performance Primitives implementation - of this codec-- force IPP to use SSE2 code (bypass CPU auto-detection) - - RETURNS: 0 on success, -1 on error -*/ -DLLEXPORT int DLLCALL tjDecompress(tjhandle j, - unsigned char *srcbuf, unsigned long size, - unsigned char *dstbuf, int width, int pitch, int height, int pixelsize, - int flags); - - -/* - int tjDestroy(tjhandle h) - - Frees structures associated with a compression or decompression instance - - [INPUT] h = instance handle (returned from a previous call to - tjInitCompress() or tjInitDecompress() - - RETURNS: 0 on success, -1 on error -*/ -DLLEXPORT int DLLCALL tjDestroy(tjhandle h); - - -/* - char *tjGetErrorStr(void) - - Returns a descriptive error message explaining why the last command failed -*/ -DLLEXPORT char* DLLCALL tjGetErrorStr(void); - -#ifdef __cplusplus -} -#endif diff --git a/x11vnc/misc/turbovnc/undo_turbovnc b/x11vnc/misc/turbovnc/undo_turbovnc deleted file mode 100755 index e16691f..0000000 --- a/x11vnc/misc/turbovnc/undo_turbovnc +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# -# This script has been (or is hereby) released into the public domain by -# its author, Karl J. Runge <runge@karlrunge.com>. This applies worldwide. -# -# In case this is not legally possible: Karl J. Runge grants anyone the -# right to use this work for any purpose, without any conditions, unless -# such conditions are required by law. - -ldir="../../../libvncserver" - -if [ ! -f "$ldir/tight.c.ORIG" ]; then - ls -l "$ldir/tight.c.ORIG" - exit 1 -fi -if [ ! -f "$ldir/rfbserver.c.ORIG" ]; then - ls -l "$ldir/rfbserver.c.ORIG" - exit 1 -fi - -set -xv -rm -f "$ldir/tight.c" "$ldir/turbojpeg.h" -mv "$ldir/tight.c.ORIG" "$ldir/tight.c" -mv "$ldir/rfbserver.c.ORIG" "$ldir/rfbserver.c" -ls -l $ldir/tight.c* $ldir/rfbserver.c* diff --git a/x11vnc/misc/uinput.pl b/x11vnc/misc/uinput.pl deleted file mode 100755 index 9620140..0000000 --- a/x11vnc/misc/uinput.pl +++ /dev/null @@ -1,946 +0,0 @@ -#!/usr/bin/perl - -# This is a test injection script for Linux uinput. -# It can be handy working out / troubleshooting Linux uinput injection on a new device. - -# -# Copyright (c) 2010 by Karl J. Runge <runge@karlrunge.com> -# -# uinput.pl 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. -# -# uinput.pl 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 uinput.pl; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see <http://www.gnu.org/licenses/>. -# - -set_constants(); - -# options for what injection to handle: -$rel = 1; -$abs = 1; -$touch = 1; -$allkeys = 1; - -# these can be set via env: - -$WIDTH = $ENV{WIDTH}; -$WIDTH = 480 unless $WIDTH; -$HEIGHT = $ENV{HEIGHT}; -$HEIGHT = 640 unless $HEIGHT; -$DEV = $ENV{DEV}; -$DEV = "/dev/input/uinput" unless $DEV; - -# this fills in name and input type part of uinput_user_dev struct: - -$udev = "uinput.pl"; -$n = 80 - length($udev); -$udev .= "\0" x $n; - -$udev .= "\0" x 2; # bus -$udev .= "\0" x 2; # vendor -$udev .= "\0" x 2; # product -$udev .= "\0" x 2; # version - -$udev .= "\0" x 4; # ff_effects_max - -# this fills in the abs arrays: -# -foreach $type (qw(absmax absmin absfuzz absflat)) { - $n = $ABS_MAX + 1; - for ($j = 0; $j < $n; $j++) { - if ($abs && $type eq 'absmax' && $j == $ABS_X) { - $udev .= pack("i", $WIDTH-1); - } elsif ($abs && $type eq 'absmax' && $j == $ABS_Y) { - $udev .= pack("i", $HEIGHT-1); - } else { - $udev .= "\0" x 4; - } - } -} - -print "udev: ", length($udev) . " '$udev'\n"; - -$modes = $O_RDWR; -$modes = $O_WRONLY | $O_NDELAY; -printf("open modes: 0x%x\n", $modes); - -sysopen(FD, $DEV, $modes) || die "$DEV: $!"; - -if ($rel) { - io_ctl($UI_SET_EVBIT, $EV_REL); - io_ctl($UI_SET_RELBIT, $REL_X); - io_ctl($UI_SET_RELBIT, $REL_Y); -} - -io_ctl($UI_SET_EVBIT, $EV_KEY); - -io_ctl($UI_SET_EVBIT, $EV_SYN); - -for ($i=0; $i < 256; $i++) { - last unless $allkeys; - io_ctl($UI_SET_KEYBIT, $i); -} - -io_ctl($UI_SET_KEYBIT, $BTN_MOUSE); -io_ctl($UI_SET_KEYBIT, $BTN_LEFT); -io_ctl($UI_SET_KEYBIT, $BTN_MIDDLE); -io_ctl($UI_SET_KEYBIT, $BTN_RIGHT); -io_ctl($UI_SET_KEYBIT, $BTN_FORWARD); -io_ctl($UI_SET_KEYBIT, $BTN_BACK); - -if ($abs) { - io_ctl($UI_SET_KEYBIT, $BTN_TOUCH) if $touch; - io_ctl($UI_SET_EVBIT, $EV_ABS); - io_ctl($UI_SET_ABSBIT, $ABS_X); - io_ctl($UI_SET_ABSBIT, $ABS_Y); -} - -$ret = syswrite(FD, $udev, length($udev)); -print "syswrite: $ret\n"; - -io_ctl($UI_DEV_CREATE); -fsleep(0.25); - -# this should show our new virtual device: -# -system("cat /proc/bus/input/devices 1>&2"); -print STDERR "\n"; - -################################################# -# put in your various test injection events here: - -#do_key($KEY_A, 1, 0.1); -#do_key($KEY_A, 0, 0.1); - -#do_key($KEY_POWER, 1, 0.1); -#do_key($KEY_POWER, 0, 0.1); - -do_abs(118, 452, 0, 0.1); - -do_abs(110, 572, 1, 0.1); - -do_btn($BTN_TOUCH, 1, 0.1); -do_btn($BTN_TOUCH, 0, 0.1); - -do_btn($BTN_MOUSE, 1, 0.1); -do_btn($BTN_MOUSE, 0, 0.1); -################################################# - -fsleep(0.25); -io_ctl($UI_DEV_DESTROY); - -close(FD); - -exit(0); - -sub io_ctl { - my ($cmd, $val) = @_; - if (defined $val) { - my $ret = syscall($linux_ioctl_syscall, fileno(FD), $cmd, $val); - my $err = $!; $err = '' if $ret == 0; - print STDERR "io_ctl(FD, $cmd, $val) = $ret $err\n"; - } else { - my $ret = syscall($linux_ioctl_syscall, fileno(FD), $cmd); - my $err = $!; $err = '' if $ret == 0; - print STDERR "io_ctl(FD, $cmd) = $ret $err\n"; - } -} - -sub do_syn { - my $ev = gtod(); - $ev .= pack("S", $EV_SYN); - $ev .= pack("S", $SYN_REPORT); - $ev .= pack("i", 0); - print STDERR "do_syn EV_SYN\n"; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_syn: $!\n"; - } -} - -sub do_key { - my ($key, $down, $sleep) = @_; - my $ev = gtod(); - $ev .= pack("S", $EV_KEY); - $ev .= pack("S", $key); - $ev .= pack("i", $down); - print STDERR "do_key $key $down\n"; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_key: $!\n"; - } - do_syn(); - fsleep($sleep); - print STDERR "\n"; -} - -sub do_btn { - my ($button, $down, $sleep) = @_; - my $ev = gtod(); - $ev .= pack("S", $EV_KEY); - $ev .= pack("S", $button); - $ev .= pack("i", $down); - print STDERR "do_btn $button $down\n"; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_btn: $!\n"; - } - do_syn(); - fsleep($sleep); - print STDERR "\n"; -} - -sub do_abs { - my ($x, $y, $p, $sleep) = @_; - my $ev = gtod(); - $ev .= pack("S", $EV_ABS); - $ev .= pack("S", $ABS_Y); - $ev .= pack("i", $y); - print STDERR "do_abs y=$y\n"; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_abs: $!\n"; - } - $ev = gtod(); - $ev .= pack("S", $EV_ABS); - $ev .= pack("S", $ABS_X); - $ev .= pack("i", $x); - print STDERR "do_abs x=$x\n"; - $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_abs: $!\n"; - } - $ev = gtod(); - $ev .= pack("S", $EV_ABS); - $ev .= pack("S", $ABS_PRESSURE); - $ev .= pack("i", $p); - print STDERR "do_abs p=$p\n"; - $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_abs: $!\n"; - } - do_syn(); - fsleep($sleep); - print STDERR "\n"; -} - -sub do_rel { - my ($dx, $dy, $sleep) = @_; - my $ev = gtod(); - $ev .= pack("S", $EV_REL); - $ev .= pack("S", $REL_Y); - $ev .= pack("i", $dy); - print STDERR "do_rel dy=$dy\n"; - my $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_rel: $!\n"; - } - $ev = gtod(); - $ev .= pack("S", $EV_REL); - $ev .= pack("S", $REL_X); - $ev .= pack("i", $dx); - print STDERR "do_rel dx=$dx\n"; - $ret = syswrite(FD, $ev, length($ev)); - if (!defined $ret) { - print STDERR "do_rel: $!\n"; - } - do_syn(); - fsleep($sleep); - print STDERR "\n"; -} - -sub gtod { - $tv = ("\0" x 4) x 2; # assumes long is 4 bytes. FIXME: use pack. - $tz = ("\0" x 4) x 2; - syscall($linux_gettimeofday_syscall, $tv, $tz); - return $tv; -} - -sub fsleep { - my ($time) = @_; - select(undef, undef, undef, $time) if $time; -} - -sub set_constants { - -# from /usr/include/linux/uinput.h /usr/include/linux/input.h and x11vnc. - -# #define ABS_MAX 0x3f = 63 -# -# #define UINPUT_MAX_NAME_SIZE 80 -# -# struct input_id { -# __u16 bustype; -# __u16 vendor; -# __u16 product; -# __u16 version; -# }; -# -# struct uinput_user_dev { -# char name[UINPUT_MAX_NAME_SIZE]; -# struct input_id id; -# int ff_effects_max; -# int absmax[ABS_MAX + 1]; -# int absmin[ABS_MAX + 1]; -# int absfuzz[ABS_MAX + 1]; -# int absflat[ABS_MAX + 1]; -# }; -# #endif /* __UINPUT_H_ */ - -$EV_SYN = 0x00; -$EV_KEY = 0x01; -$EV_REL = 0x02; -$EV_ABS = 0x03; -$EV_MSC = 0x04; -$EV_SW = 0x05; -$EV_LED = 0x11; -$EV_SND = 0x12; -$EV_REP = 0x14; -$EV_FF = 0x15; -$EV_PWR = 0x16; -$EV_FF_STATUS = 0x17; -$EV_MAX = 0x1f; - -$ID_BUS = 0; -$ID_VENDOR = 1; -$ID_PRODUCT = 2; -$ID_VERSION = 3; - -$BUS_PCI = 0x01; -$BUS_ISAPNP = 0x02; -$BUS_USB = 0x03; -$BUS_HIL = 0x04; -$BUS_BLUETOOTH = 0x05; -$BUS_VIRTUAL = 0x06; - -$BUS_ISA = 0x10; -$BUS_I8042 = 0x11; -$BUS_XTKBD = 0x12; -$BUS_RS232 = 0x13; -$BUS_GAMEPORT = 0x14; -$BUS_PARPORT = 0x15; -$BUS_AMIGA = 0x16; -$BUS_ADB = 0x17; -$BUS_I2C = 0x18; -$BUS_HOST = 0x19; -$BUS_GSC = 0x1A; -$BUS_ATARI = 0x1B; - -$REL_X = 0x00; -$REL_Y = 0x01; -$REL_Z = 0x02; -$REL_RX = 0x03; -$REL_RY = 0x04; -$REL_RZ = 0x05; -$REL_HWHEEL = 0x06; -$REL_DIAL = 0x07; -$REL_WHEEL = 0x08; -$REL_MISC = 0x09; - -$ABS_X = 0x00; -$ABS_Y = 0x01; -$ABS_Z = 0x02; -$ABS_RX = 0x03; -$ABS_RY = 0x04; -$ABS_RZ = 0x05; -$ABS_THROTTLE = 0x06; -$ABS_RUDDER = 0x07; -$ABS_WHEEL = 0x08; -$ABS_GAS = 0x09; -$ABS_BRAKE = 0x0a; -$ABS_HAT0X = 0x10; -$ABS_HAT0Y = 0x11; -$ABS_HAT1X = 0x12; -$ABS_HAT1Y = 0x13; -$ABS_HAT2X = 0x14; -$ABS_HAT2Y = 0x15; -$ABS_HAT3X = 0x16; -$ABS_HAT3Y = 0x17; -$ABS_PRESSURE = 0x18; -$ABS_DISTANCE = 0x19; -$ABS_TILT_X = 0x1a; -$ABS_TILT_Y = 0x1b; -$ABS_TOOL_WIDTH = 0x1c; -$ABS_VOLUME = 0x20; -$ABS_MISC = 0x28; -$ABS_MT_TOUCH_MAJOR = 0x30; -$ABS_MT_TOUCH_MINOR = 0x31; -$ABS_MT_WIDTH_MAJOR = 0x32; -$ABS_MT_WIDTH_MINOR = 0x33; -$ABS_MT_ORIENTATION = 0x34; -$ABS_MT_POSITION_X = 0x35; -$ABS_MT_POSITION_Y = 0x36; -$ABS_MT_TOOL_TYPE = 0x37; -$ABS_MT_BLOB_ID = 0x38; -$ABS_MT_TRACKING_ID = 0x39; -#$ABS_MAX = 0x3f; - - -$BTN_MISC = 0x100; -$BTN_0 = 0x100; -$BTN_1 = 0x101; -$BTN_2 = 0x102; -$BTN_3 = 0x103; -$BTN_4 = 0x104; -$BTN_5 = 0x105; -$BTN_6 = 0x106; -$BTN_7 = 0x107; -$BTN_8 = 0x108; -$BTN_9 = 0x109; - -$BTN_MOUSE = 0x110; -$BTN_LEFT = 0x110; -$BTN_RIGHT = 0x111; -$BTN_MIDDLE = 0x112; -$BTN_SIDE = 0x113; -$BTN_EXTRA = 0x114; -$BTN_FORWARD = 0x115; -$BTN_BACK = 0x116; -$BTN_TASK = 0x117; - -$BTN_JOYSTICK = 0x120; -$BTN_TRIGGER = 0x120; -$BTN_THUMB = 0x121; -$BTN_THUMB2 = 0x122; -$BTN_TOP = 0x123; -$BTN_TOP2 = 0x124; -$BTN_PINKIE = 0x125; -$BTN_BASE = 0x126; -$BTN_BASE2 = 0x127; -$BTN_BASE3 = 0x128; -$BTN_BASE4 = 0x129; -$BTN_BASE5 = 0x12a; -$BTN_BASE6 = 0x12b; -$BTN_DEAD = 0x12f; - -$BTN_GAMEPAD = 0x130; -$BTN_A = 0x130; -$BTN_B = 0x131; -$BTN_C = 0x132; -$BTN_X = 0x133; -$BTN_Y = 0x134; -$BTN_Z = 0x135; -$BTN_TL = 0x136; -$BTN_TR = 0x137; -$BTN_TL2 = 0x138; -$BTN_TR2 = 0x139; -$BTN_SELECT = 0x13a; -$BTN_START = 0x13b; -$BTN_MODE = 0x13c; -$BTN_THUMBL = 0x13d; -$BTN_THUMBR = 0x13e; - -$BTN_DIGI = 0x140; -$BTN_TOOL_PEN = 0x140; -$BTN_TOOL_RUBBER = 0x141; -$BTN_TOOL_BRUSH = 0x142; -$BTN_TOOL_PENCIL = 0x143; -$BTN_TOOL_AIRBRUSH = 0x144; -$BTN_TOOL_FINGER = 0x145; -$BTN_TOOL_MOUSE = 0x146; -$BTN_TOOL_LENS = 0x147; -$BTN_TOUCH = 0x14a; -$BTN_STYLUS = 0x14b; -$BTN_STYLUS2 = 0x14c; -$BTN_TOOL_DOUBLETAP = 0x14d; -$BTN_TOOL_TRIPLETAP = 0x14e; - -$BTN_WHEEL = 0x150; -$BTN_GEAR_DOWN = 0x150; -$BTN_GEAR_UP = 0x151; - -$SYN_REPORT = 0; -$SYN_CONFIG = 1; -$SYN_MT_REPORT = 2; - -$KEY_RESERVED = 0; -$KEY_ESC = 1; -$KEY_1 = 2; -$KEY_2 = 3; -$KEY_3 = 4; -$KEY_4 = 5; -$KEY_5 = 6; -$KEY_6 = 7; -$KEY_7 = 8; -$KEY_8 = 9; -$KEY_9 = 10; -$KEY_0 = 11; -$KEY_MINUS = 12; -$KEY_EQUAL = 13; -$KEY_BACKSPACE = 14; -$KEY_TAB = 15; -$KEY_Q = 16; -$KEY_W = 17; -$KEY_E = 18; -$KEY_R = 19; -$KEY_T = 20; -$KEY_Y = 21; -$KEY_U = 22; -$KEY_I = 23; -$KEY_O = 24; -$KEY_P = 25; -$KEY_LEFTBRACE = 26; -$KEY_RIGHTBRACE = 27; -$KEY_ENTER = 28; -$KEY_LEFTCTRL = 29; -$KEY_A = 30; -$KEY_S = 31; -$KEY_D = 32; -$KEY_F = 33; -$KEY_G = 34; -$KEY_H = 35; -$KEY_J = 36; -$KEY_K = 37; -$KEY_L = 38; -$KEY_SEMICOLON = 39; -$KEY_APOSTROPHE = 40; -$KEY_GRAVE = 41; -$KEY_LEFTSHIFT = 42; -$KEY_BACKSLASH = 43; -$KEY_Z = 44; -$KEY_X = 45; -$KEY_C = 46; -$KEY_V = 47; -$KEY_B = 48; -$KEY_N = 49; -$KEY_M = 50; -$KEY_COMMA = 51; -$KEY_DOT = 52; -$KEY_SLASH = 53; -$KEY_RIGHTSHIFT = 54; -$KEY_KPASTERISK = 55; -$KEY_LEFTALT = 56; -$KEY_SPACE = 57; -$KEY_CAPSLOCK = 58; -$KEY_F1 = 59; -$KEY_F2 = 60; -$KEY_F3 = 61; -$KEY_F4 = 62; -$KEY_F5 = 63; -$KEY_F6 = 64; -$KEY_F7 = 65; -$KEY_F8 = 66; -$KEY_F9 = 67; -$KEY_F10 = 68; -$KEY_NUMLOCK = 69; -$KEY_SCROLLLOCK = 70; -$KEY_KP7 = 71; -$KEY_KP8 = 72; -$KEY_KP9 = 73; -$KEY_KPMINUS = 74; -$KEY_KP4 = 75; -$KEY_KP5 = 76; -$KEY_KP6 = 77; -$KEY_KPPLUS = 78; -$KEY_KP1 = 79; -$KEY_KP2 = 80; -$KEY_KP3 = 81; -$KEY_KP0 = 82; -$KEY_KPDOT = 83; -$KEY_103RD = 84; -$KEY_F13 = 85; -$KEY_102ND = 86; -$KEY_F11 = 87; -$KEY_F12 = 88; -$KEY_F14 = 89; -$KEY_F15 = 90; -$KEY_F16 = 91; -$KEY_F17 = 92; -$KEY_F18 = 93; -$KEY_F19 = 94; -$KEY_F20 = 95; -$KEY_KPENTER = 96; -$KEY_RIGHTCTRL = 97; -$KEY_KPSLASH = 98; -$KEY_SYSRQ = 99; -$KEY_RIGHTALT = 100; -$KEY_LINEFEED = 101; -$KEY_HOME = 102; -$KEY_UP = 103; -$KEY_PAGEUP = 104; -$KEY_LEFT = 105; -$KEY_RIGHT = 106; -$KEY_END = 107; -$KEY_DOWN = 108; -$KEY_PAGEDOWN = 109; -$KEY_INSERT = 110; -$KEY_DELETE = 111; -$KEY_MACRO = 112; -$KEY_MUTE = 113; -$KEY_VOLUMEDOWN = 114; -$KEY_VOLUMEUP = 115; -$KEY_POWER = 116; -$KEY_KPEQUAL = 117; -$KEY_KPPLUSMINUS = 118; -$KEY_PAUSE = 119; -$KEY_F21 = 120; -$KEY_F22 = 121; -$KEY_F23 = 122; -$KEY_F24 = 123; -$KEY_KPCOMMA = 124; -$KEY_LEFTMETA = 125; -$KEY_RIGHTMETA = 126; -$KEY_COMPOSE = 127; -$KEY_STOP = 128; -$KEY_AGAIN = 129; -$KEY_PROPS = 130; -$KEY_UNDO = 131; -$KEY_FRONT = 132; -$KEY_COPY = 133; -$KEY_OPEN = 134; -$KEY_PASTE = 135; -$KEY_FIND = 136; -$KEY_CUT = 137; -$KEY_HELP = 138; -$KEY_MENU = 139; -$KEY_CALC = 140; -$KEY_SETUP = 141; -$KEY_SLEEP = 142; -$KEY_WAKEUP = 143; -$KEY_FILE = 144; -$KEY_SENDFILE = 145; -$KEY_DELETEFILE = 146; -$KEY_XFER = 147; -$KEY_PROG1 = 148; -$KEY_PROG2 = 149; -$KEY_WWW = 150; -$KEY_MSDOS = 151; -$KEY_COFFEE = 152; -$KEY_DIRECTION = 153; -$KEY_CYCLEWINDOWS = 154; -$KEY_MAIL = 155; -$KEY_BOOKMARKS = 156; -$KEY_COMPUTER = 157; -$KEY_BACK = 158; -$KEY_FORWARD = 159; -$KEY_CLOSECD = 160; -$KEY_EJECTCD = 161; -$KEY_EJECTCLOSECD = 162; -$KEY_NEXTSONG = 163; -$KEY_PLAYPAUSE = 164; -$KEY_PREVIOUSSONG = 165; -$KEY_STOPCD = 166; -$KEY_RECORD = 167; -$KEY_REWIND = 168; -$KEY_PHONE = 169; -$KEY_ISO = 170; -$KEY_CONFIG = 171; -$KEY_HOMEPAGE = 172; -$KEY_REFRESH = 173; -$KEY_EXIT = 174; -$KEY_MOVE = 175; -$KEY_EDIT = 176; -$KEY_SCROLLUP = 177; -$KEY_SCROLLDOWN = 178; -$KEY_KPLEFTPAREN = 179; -$KEY_KPRIGHTPAREN = 180; -$KEY_INTL1 = 181; -$KEY_INTL2 = 182; -$KEY_INTL3 = 183; -$KEY_INTL4 = 184; -$KEY_INTL5 = 185; -$KEY_INTL6 = 186; -$KEY_INTL7 = 187; -$KEY_INTL8 = 188; -$KEY_INTL9 = 189; -$KEY_LANG1 = 190; -$KEY_LANG2 = 191; -$KEY_LANG3 = 192; -$KEY_LANG4 = 193; -$KEY_LANG5 = 194; -$KEY_LANG6 = 195; -$KEY_LANG7 = 196; -$KEY_LANG8 = 197; -$KEY_LANG9 = 198; -$KEY_PLAYCD = 200; -$KEY_PAUSECD = 201; -$KEY_PROG3 = 202; -$KEY_PROG4 = 203; -$KEY_SUSPEND = 205; -$KEY_CLOSE = 206; -$KEY_PLAY = 207; -$KEY_FASTFORWARD = 208; -$KEY_BASSBOOST = 209; -$KEY_PRINT = 210; -$KEY_HP = 211; -$KEY_CAMERA = 212; -$KEY_SOUND = 213; -$KEY_QUESTION = 214; -$KEY_EMAIL = 215; -$KEY_CHAT = 216; -$KEY_SEARCH = 217; -$KEY_CONNECT = 218; -$KEY_FINANCE = 219; -$KEY_SPORT = 220; -$KEY_SHOP = 221; -$KEY_ALTERASE = 222; -$KEY_CANCEL = 223; -$KEY_BRIGHTNESSDOWN = 224; -$KEY_BRIGHTNESSUP = 225; -$KEY_MEDIA = 226; -$KEY_UNKNOWN = 240; -$KEY_OK = 0x160; -$KEY_SELECT = 0x161; -$KEY_GOTO = 0x162; -$KEY_CLEAR = 0x163; -$KEY_POWER2 = 0x164; -$KEY_OPTION = 0x165; -$KEY_INFO = 0x166; -$KEY_TIME = 0x167; -$KEY_VENDOR = 0x168; -$KEY_ARCHIVE = 0x169; -$KEY_PROGRAM = 0x16a; -$KEY_CHANNEL = 0x16b; -$KEY_FAVORITES = 0x16c; -$KEY_EPG = 0x16d; -$KEY_PVR = 0x16e; -$KEY_MHP = 0x16f; -$KEY_LANGUAGE = 0x170; -$KEY_TITLE = 0x171; -$KEY_SUBTITLE = 0x172; -$KEY_ANGLE = 0x173; -$KEY_ZOOM = 0x174; -$KEY_MODE = 0x175; -$KEY_KEYBOARD = 0x176; -$KEY_SCREEN = 0x177; -$KEY_PC = 0x178; -$KEY_TV = 0x179; -$KEY_TV2 = 0x17a; -$KEY_VCR = 0x17b; -$KEY_VCR2 = 0x17c; -$KEY_SAT = 0x17d; -$KEY_SAT2 = 0x17e; -$KEY_CD = 0x17f; -$KEY_TAPE = 0x180; -$KEY_RADIO = 0x181; -$KEY_TUNER = 0x182; -$KEY_PLAYER = 0x183; -$KEY_TEXT = 0x184; -$KEY_DVD = 0x185; -$KEY_AUX = 0x186; -$KEY_MP3 = 0x187; -$KEY_AUDIO = 0x188; -$KEY_VIDEO = 0x189; -$KEY_DIRECTORY = 0x18a; -$KEY_LIST = 0x18b; -$KEY_MEMO = 0x18c; -$KEY_CALENDAR = 0x18d; -$KEY_RED = 0x18e; -$KEY_GREEN = 0x18f; -$KEY_YELLOW = 0x190; -$KEY_BLUE = 0x191; -$KEY_CHANNELUP = 0x192; -$KEY_CHANNELDOWN = 0x193; -$KEY_FIRST = 0x194; -$KEY_LAST = 0x195; -$KEY_AB = 0x196; -$KEY_NEXT = 0x197; -$KEY_RESTART = 0x198; -$KEY_SLOW = 0x199; -$KEY_SHUFFLE = 0x19a; -$KEY_BREAK = 0x19b; -$KEY_PREVIOUS = 0x19c; -$KEY_DIGITS = 0x19d; -$KEY_TEEN = 0x19e; -$KEY_TWEN = 0x19f; -$KEY_DEL_EOL = 0x1c0; -$KEY_DEL_EOS = 0x1c1; -$KEY_INS_LINE = 0x1c2; -$KEY_DEL_LINE = 0x1c3; -$KEY_MAX = 0x1ff; - - - $key_lookup{XK_Escape} = $KEY_ESC; - $key_lookup{XK_1} = $KEY_1; - $key_lookup{XK_2} = $KEY_2; - $key_lookup{XK_3} = $KEY_3; - $key_lookup{XK_4} = $KEY_4; - $key_lookup{XK_5} = $KEY_5; - $key_lookup{XK_6} = $KEY_6; - $key_lookup{XK_7} = $KEY_7; - $key_lookup{XK_8} = $KEY_8; - $key_lookup{XK_9} = $KEY_9; - $key_lookup{XK_0} = $KEY_0; - $key_lookup{XK_exclam} = $KEY_1; - $key_lookup{XK_at} = $KEY_2; - $key_lookup{XK_numbersign} = $KEY_3; - $key_lookup{XK_dollar} = $KEY_4; - $key_lookup{XK_percent} = $KEY_5; - $key_lookup{XK_asciicircum} = $KEY_6; - $key_lookup{XK_ampersand} = $KEY_7; - $key_lookup{XK_asterisk} = $KEY_8; - $key_lookup{XK_parenleft} = $KEY_9; - $key_lookup{XK_parenright} = $KEY_0; - $key_lookup{XK_minus} = $KEY_MINUS; - $key_lookup{XK_underscore} = $KEY_MINUS; - $key_lookup{XK_equal} = $KEY_EQUAL; - $key_lookup{XK_plus} = $KEY_EQUAL; - $key_lookup{XK_BackSpace} = $KEY_BACKSPACE; - $key_lookup{XK_Tab} = $KEY_TAB; - $key_lookup{XK_q} = $KEY_Q; - $key_lookup{XK_Q} = $KEY_Q; - $key_lookup{XK_w} = $KEY_W; - $key_lookup{XK_W} = $KEY_W; - $key_lookup{XK_e} = $KEY_E; - $key_lookup{XK_E} = $KEY_E; - $key_lookup{XK_r} = $KEY_R; - $key_lookup{XK_R} = $KEY_R; - $key_lookup{XK_t} = $KEY_T; - $key_lookup{XK_T} = $KEY_T; - $key_lookup{XK_y} = $KEY_Y; - $key_lookup{XK_Y} = $KEY_Y; - $key_lookup{XK_u} = $KEY_U; - $key_lookup{XK_U} = $KEY_U; - $key_lookup{XK_i} = $KEY_I; - $key_lookup{XK_I} = $KEY_I; - $key_lookup{XK_o} = $KEY_O; - $key_lookup{XK_O} = $KEY_O; - $key_lookup{XK_p} = $KEY_P; - $key_lookup{XK_P} = $KEY_P; - $key_lookup{XK_braceleft} = $KEY_LEFTBRACE; - $key_lookup{XK_braceright} = $KEY_RIGHTBRACE; - $key_lookup{XK_bracketleft} = $KEY_LEFTBRACE; - $key_lookup{XK_bracketright} = $KEY_RIGHTBRACE; - $key_lookup{XK_Return} = $KEY_ENTER; - $key_lookup{XK_Control_L} = $KEY_LEFTCTRL; - $key_lookup{XK_a} = $KEY_A; - $key_lookup{XK_A} = $KEY_A; - $key_lookup{XK_s} = $KEY_S; - $key_lookup{XK_S} = $KEY_S; - $key_lookup{XK_d} = $KEY_D; - $key_lookup{XK_D} = $KEY_D; - $key_lookup{XK_f} = $KEY_F; - $key_lookup{XK_F} = $KEY_F; - $key_lookup{XK_g} = $KEY_G; - $key_lookup{XK_G} = $KEY_G; - $key_lookup{XK_h} = $KEY_H; - $key_lookup{XK_H} = $KEY_H; - $key_lookup{XK_j} = $KEY_J; - $key_lookup{XK_J} = $KEY_J; - $key_lookup{XK_k} = $KEY_K; - $key_lookup{XK_K} = $KEY_K; - $key_lookup{XK_l} = $KEY_L; - $key_lookup{XK_L} = $KEY_L; - $key_lookup{XK_semicolon} = $KEY_SEMICOLON; - $key_lookup{XK_colon} = $KEY_SEMICOLON; - $key_lookup{XK_apostrophe} = $KEY_APOSTROPHE; - $key_lookup{XK_quotedbl} = $KEY_APOSTROPHE; - $key_lookup{XK_grave} = $KEY_GRAVE; - $key_lookup{XK_asciitilde} = $KEY_GRAVE; - $key_lookup{XK_Shift_L} = $KEY_LEFTSHIFT; - $key_lookup{XK_backslash} = $KEY_BACKSLASH; - $key_lookup{XK_bar} = $KEY_BACKSLASH; - $key_lookup{XK_z} = $KEY_Z; - $key_lookup{XK_Z} = $KEY_Z; - $key_lookup{XK_x} = $KEY_X; - $key_lookup{XK_X} = $KEY_X; - $key_lookup{XK_c} = $KEY_C; - $key_lookup{XK_C} = $KEY_C; - $key_lookup{XK_v} = $KEY_V; - $key_lookup{XK_V} = $KEY_V; - $key_lookup{XK_b} = $KEY_B; - $key_lookup{XK_B} = $KEY_B; - $key_lookup{XK_n} = $KEY_N; - $key_lookup{XK_N} = $KEY_N; - $key_lookup{XK_m} = $KEY_M; - $key_lookup{XK_M} = $KEY_M; - $key_lookup{XK_comma} = $KEY_COMMA; - $key_lookup{XK_less} = $KEY_COMMA; - $key_lookup{XK_period} = $KEY_DOT; - $key_lookup{XK_greater} = $KEY_DOT; - $key_lookup{XK_slash} = $KEY_SLASH; - $key_lookup{XK_question} = $KEY_SLASH; - $key_lookup{XK_Shift_R} = $KEY_RIGHTSHIFT; - $key_lookup{XK_KP_Multiply} = $KEY_KPASTERISK; - $key_lookup{XK_Alt_L} = $KEY_LEFTALT; - $key_lookup{XK_space} = $KEY_SPACE; - $key_lookup{XK_Caps_Lock} = $KEY_CAPSLOCK; - $key_lookup{XK_F1} = $KEY_F1; - $key_lookup{XK_F2} = $KEY_F2; - $key_lookup{XK_F3} = $KEY_F3; - $key_lookup{XK_F4} = $KEY_F4; - $key_lookup{XK_F5} = $KEY_F5; - $key_lookup{XK_F6} = $KEY_F6; - $key_lookup{XK_F7} = $KEY_F7; - $key_lookup{XK_F8} = $KEY_F8; - $key_lookup{XK_F9} = $KEY_F9; - $key_lookup{XK_F10} = $KEY_F10; - $key_lookup{XK_Num_Lock} = $KEY_NUMLOCK; - $key_lookup{XK_Scroll_Lock} = $KEY_SCROLLLOCK; - $key_lookup{XK_KP_7} = $KEY_KP7; - $key_lookup{XK_KP_8} = $KEY_KP8; - $key_lookup{XK_KP_9} = $KEY_KP9; - $key_lookup{XK_KP_Subtract} = $KEY_KPMINUS; - $key_lookup{XK_KP_4} = $KEY_KP4; - $key_lookup{XK_KP_5} = $KEY_KP5; - $key_lookup{XK_KP_6} = $KEY_KP6; - $key_lookup{XK_KP_Add} = $KEY_KPPLUS; - $key_lookup{XK_KP_1} = $KEY_KP1; - $key_lookup{XK_KP_2} = $KEY_KP2; - $key_lookup{XK_KP_3} = $KEY_KP3; - $key_lookup{XK_KP_0} = $KEY_KP0; - $key_lookup{XK_KP_Decimal} = $KEY_KPDOT; - $key_lookup{XK_F13} = $KEY_F13; - $key_lookup{XK_F11} = $KEY_F11; - $key_lookup{XK_F12} = $KEY_F12; - $key_lookup{XK_F14} = $KEY_F14; - $key_lookup{XK_F15} = $KEY_F15; - $key_lookup{XK_F16} = $KEY_F16; - $key_lookup{XK_F17} = $KEY_F17; - $key_lookup{XK_F18} = $KEY_F18; - $key_lookup{XK_F19} = $KEY_F19; - $key_lookup{XK_F20} = $KEY_F20; - $key_lookup{XK_KP_Enter} = $KEY_KPENTER; - $key_lookup{XK_Control_R} = $KEY_RIGHTCTRL; - $key_lookup{XK_KP_Divide} = $KEY_KPSLASH; - $key_lookup{XK_Sys_Req} = $KEY_SYSRQ; - $key_lookup{XK_Alt_R} = $KEY_RIGHTALT; - $key_lookup{XK_Linefeed} = $KEY_LINEFEED; - $key_lookup{XK_Home} = $KEY_HOME; - $key_lookup{XK_Up} = $KEY_UP; - $key_lookup{XK_Page_Up} = $KEY_PAGEUP; - $key_lookup{XK_Left} = $KEY_LEFT; - $key_lookup{XK_Right} = $KEY_RIGHT; - $key_lookup{XK_End} = $KEY_END; - $key_lookup{XK_Down} = $KEY_DOWN; - $key_lookup{XK_Page_Down} = $KEY_PAGEDOWN; - $key_lookup{XK_Insert} = $KEY_INSERT; - $key_lookup{XK_Delete} = $KEY_DELETE; - $key_lookup{XK_KP_Equal} = $KEY_KPEQUAL; - $key_lookup{XK_Pause} = $KEY_PAUSE; - $key_lookup{XK_F21} = $KEY_F21; - $key_lookup{XK_F22} = $KEY_F22; - $key_lookup{XK_F23} = $KEY_F23; - $key_lookup{XK_F24} = $KEY_F24; - $key_lookup{XK_KP_Separator} = $KEY_KPCOMMA; - $key_lookup{XK_Meta_L} = $KEY_LEFTMETA; - $key_lookup{XK_Meta_R} = $KEY_RIGHTMETA; - $key_lookup{XK_Multi_key} = $KEY_COMPOSE; - -$ABS_MAX = 63; - -$UI_DEV_CREATE = 0x5501; -$UI_DEV_DESTROY = 0x5502; -$UI_SET_EVBIT = 0x40045564; -$UI_SET_KEYBIT = 0x40045565; -$UI_SET_RELBIT = 0x40045566; -$UI_SET_ABSBIT = 0x40045567; - -# FIXME: time hires, etc. -$linux_gettimeofday_syscall = 78; - -$O_RDONLY = 00; -$O_WRONLY = 01; -$O_RDWR = 02; -$O_NDELAY = 04000; - -} diff --git a/x11vnc/misc/ultravnc_repeater.pl b/x11vnc/misc/ultravnc_repeater.pl deleted file mode 100755 index 0c44a05..0000000 --- a/x11vnc/misc/ultravnc_repeater.pl +++ /dev/null @@ -1,741 +0,0 @@ -#!/usr/bin/env perl -# -# Copyright (c) 2009-2010 by Karl J. Runge <runge@karlrunge.com> -# -# ultravnc_repeater.pl 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. -# -# ultravnc_repeater.pl 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 ultravnc_repeater.pl; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA -# or see <http://www.gnu.org/licenses/>. -# - -my $usage = ' -ultravnc_repeater.pl: - perl script implementing the ultravnc repeater - proxy protocol. - -protocol: Listen on one port for vnc clients (default 5900.) - Listen on one port for vnc servers (default 5500.) - Read 250 bytes from connecting vnc client or server. - Accept ID:<string> from clients and servers, connect them - together once both are present. - - The string "RFB 000.000\n" is sent to the client (the client - must understand this means send ID:... or host:port.) - Also accept <host>:<port> from clients and make the - connection to the vnc server immediately. - - Note there is no authentication or security WRT ID names or - identities; it is up to the client and server to completely - manage that aspect and whether to encrypt the session, etc. - -usage: ultravnc_repeater.pl [-r] [client_port [server_port]] - -Use -r to refuse new server/client connections when there is an existing -server/client ID. The default is to close the previous one. - -To write to a log file set the env. var ULTRAVNC_REPEATER_LOGFILE. - -To run in a loop restarting the server if it exits set the env. var. -ULTRAVNC_REPEATER_LOOP=1 or ULTRAVNC_REPEATER_LOOP=BG, the latter -forks into the background. Set ULTRAVNC_REPEATER_PIDFILE to a file -to store the master pid in. - -Set ULTRAVNC_REPEATER_NO_RFB=1 to disable sending "RFB 000.000" to -the client. Then this program acts as general TCP rendezvous tool. - -Examples: - - ultravnc_repeater.pl - ultravnc_repeater.pl -r - ultravnc_repeater.pl 5901 - ultravnc_repeater.pl 5901 5501 - - env ULTRAVNC_REPEATER_LOOP=BG ULTRAVNC_REPEATER_LOGFILE=/tmp/u.log ultravnc_repeater.pl ... - -'; - -use strict; - -# Set up logging: -# -if (exists $ENV{ULTRAVNC_REPEATER_LOGFILE}) { - close STDOUT; - if (!open(STDOUT, ">>$ENV{ULTRAVNC_REPEATER_LOGFILE}")) { - die "ultravnc_repeater.pl: $ENV{ULTRAVNC_REPEATER_LOGFILE} $!\n"; - } - close STDERR; - open(STDERR, ">&STDOUT"); -} -select(STDERR); $| = 1; -select(STDOUT); $| = 1; - -# interrupt handler: -# -my $looppid = ''; -my $pidfile = ''; -# -sub get_out { - lprint("$_[0]:\t$$ looppid=$looppid"); - if ($looppid) { - kill 'TERM', $looppid; - fsleep(0.2); - } - unlink $pidfile if $pidfile; - cleanup(); - exit 0; -} - -sub lprint { - print STDERR scalar(localtime), ": ", @_, "\n"; -} - -# These are overridden in actual server thread: -# -$SIG{INT} = \&get_out; -$SIG{TERM} = \&get_out; - -# pidfile: -# -sub open_pidfile { - if (exists $ENV{ULTRAVNC_REPEATER_PIDFILE}) { - my $pf = $ENV{ULTRAVNC_REPEATER_PIDFILE}; - if (open(PID, ">$pf")) { - print PID "$$\n"; - close PID; - $pidfile = $pf; - } else { - lprint("could not open pidfile: $pf - $! - continuing..."); - } - delete $ENV{ULTRAVNC_REPEATER_PIDFILE}; - } -} - -#################################################################### -# Set ULTRAVNC_REPEATER_LOOP=1 to have this script create an outer loop -# restarting itself if it ever exits. Set ULTRAVNC_REPEATER_LOOP=BG to -# do this in the background as a daemon. - -if (exists $ENV{ULTRAVNC_REPEATER_LOOP}) { - my $csl = $ENV{ULTRAVNC_REPEATER_LOOP}; - if ($csl ne 'BG' && $csl ne '1') { - die "ultravnc_repeater.pl: invalid ULTRAVNC_REPEATER_LOOP.\n"; - } - if ($csl eq 'BG') { - # go into bg as "daemon": - setpgrp(0, 0); - my $pid = fork(); - if (! defined $pid) { - die "ultravnc_repeater.pl: $!\n"; - } elsif ($pid) { - wait; - exit 0; - } - if (fork) { - exit 0; - } - setpgrp(0, 0); - close STDIN; - if (! $ENV{ULTRAVNC_REPEATER_LOGFILE}) { - close STDOUT; - close STDERR; - } - } - delete $ENV{ULTRAVNC_REPEATER_LOOP}; - - if (exists $ENV{ULTRAVNC_REPEATER_PIDFILE}) { - open_pidfile(); - } - - lprint("ultravnc_repeater.pl: starting service. master-pid=$$"); - while (1) { - $looppid = fork; - if (! defined $looppid) { - sleep 10; - } elsif ($looppid) { - wait; - } else { - exec $0, @ARGV; - exit 1; - } - lprint("ultravnc_repeater.pl: re-starting service. master-pid=$$"); - sleep 1; - } - exit 0; -} -if (exists $ENV{ULTRAVNC_REPEATER_PIDFILE}) { - open_pidfile(); -} - -# End of background/daemon stuff. -#################################################################### - -use warnings; -use IO::Socket::INET; -use IO::Select; - -# Test for INET6 support: -# -my $have_inet6 = 0; -eval "use IO::Socket::INET6;"; -$have_inet6 = 1 if $@ eq ""; -print "perl module IO::Socket::INET6 not available: no IPv6 support.\n" if ! $have_inet6; - -my $prog = 'ultravnc_repeater'; -my %ID; - -my $refuse = 0; -my $init_timeout = 5; - -if (@ARGV && $ARGV[0] =~ /-h/) { - print $usage; - exit 0; -} -if (@ARGV && $ARGV[0] eq '-r') { - $refuse = 1; - lprint("enabling refuse mode (-r)."); - shift; -} - -my $client_port = shift; -my $server_port = shift; - -$client_port = 5900 unless $client_port; -$server_port = 5500 unless $server_port; - -my $uname = `uname`; - -my $repeater_bufsize = 250; -$repeater_bufsize = $ENV{BUFSIZE} if exists $ENV{BUFSIZE}; - -my ($RIN, $WIN, $EIN, $ROUT); - -my $client_listen = IO::Socket::INET->new( - Listen => 10, - LocalPort => $client_port, - ReuseAddr => 1, - Proto => "tcp" -); -my $err1 = $!; -my $err2 = ''; -$client_listen = '' if ! $client_listen; - -my $client_listen6 = ''; -if ($have_inet6) { - eval {$client_listen6 = IO::Socket::INET6->new( - Listen => 10, - LocalPort => $client_port, - ReuseAddr => 1, - Domain => AF_INET6, - LocalAddr => "::", - Proto => "tcp" - );}; - $err2 = $!; -} -if (! $client_listen && ! $client_listen6) { - cleanup(); - die "$prog: error: client listen on port $client_port: $err1 - $err2\n"; -} - -my $server_listen = IO::Socket::INET->new( - Listen => 10, - LocalPort => $server_port, - ReuseAddr => 1, - Proto => "tcp" -); -$err1 = $!; -$err2 = ''; -$server_listen = '' if ! $server_listen; - -my $server_listen6 = ''; -if ($have_inet6) { - eval {$server_listen6 = IO::Socket::INET6->new( - Listen => 10, - LocalPort => $server_port, - ReuseAddr => 1, - Domain => AF_INET6, - LocalAddr => "::", - Proto => "tcp" - );}; - $err2 = $!; -} -if (! $server_listen && ! $server_listen6) { - cleanup(); - die "$prog: error: server listen on port $server_port: $err1 - $err2\n"; -} - -my $select = new IO::Select(); -if (! $select) { - cleanup(); - die "$prog: select $!\n"; -} - -$select->add($client_listen) if $client_listen; -$select->add($client_listen6) if $client_listen6; -$select->add($server_listen) if $server_listen; -$select->add($server_listen6) if $server_listen6; - -$SIG{INT} = sub {cleanup(); exit;}; -$SIG{TERM} = sub {cleanup(); exit;}; - -my $SOCK1 = ''; -my $SOCK2 = ''; -my $CURR = ''; - -lprint("$prog: starting up. pid: $$"); -lprint("watching for IPv4 connections on $client_port/client.") if $client_listen; -lprint("watching for IPv4 connections on $server_port/server.") if $server_listen; -lprint("watching for IPv6 connections on $client_port/client.") if $client_listen6; -lprint("watching for IPv6 connections on $server_port/server.") if $server_listen6; - -my $alarm_sock = ''; -my $got_alarm = 0; -sub alarm_handler { - lprint("$prog: got sig alarm."); - if ($alarm_sock ne '') { - close $alarm_sock; - } - $alarm_sock = ''; - $got_alarm = 1; -} - -while (my @ready = $select->can_read()) { - foreach my $fh (@ready) { - if (($client_listen && $fh == $client_listen) || ($client_listen6 && $fh == $client_listen6)) { - lprint("new vnc client connecting."); - } elsif (($server_listen && $fh == $server_listen) || ($server_listen6 && $fh == $server_listen6)) { - lprint("new vnc server connecting."); - } - my $sock = $fh->accept(); - if (! $sock) { - lprint("$prog: accept $!"); - next; - } - - if (($client_listen && $fh == $client_listen) || ($client_listen6 && $fh == $client_listen6)) { - if (exists $ENV{ULTRAVNC_REPEATER_NO_RFB} && $ENV{ULTRAVNC_REPEATER_NO_RFB}) { - lprint("ULTRAVNC_REPEATER_NO_RFB: not sending RFB 000.000"); - } else { - my $str = "RFB 000.000\n"; - my $len = length $str; - my $n = syswrite($sock, $str, $len, 0); - if ($n != $len) { - lprint("$prog: bad $str write: $n != $len $!"); - close $sock; - } - } - } - - my $buf = ''; - my $size = $repeater_bufsize; - $size = 1024 unless $size; - - $SIG{ALRM} = "alarm_handler"; - $alarm_sock = $sock; - $got_alarm = 0; - alarm($init_timeout); - my $n = sysread($sock, $buf, $size); - alarm(0); - - if ($got_alarm) { - lprint("$prog: read timed out: $!"); - } elsif (! defined $n) { - lprint("$prog: read error: $!"); - } elsif ($repeater_bufsize > 0 && $n != $size) { - lprint("$prog: short read $n != $size $!"); - close $sock; - } elsif (($client_listen && $fh == $client_listen) || ($client_listen6 && $fh == $client_listen6)) { - do_new_client($sock, $buf); - } elsif (($server_listen && $fh == $server_listen) || ($server_listen6 && $fh == $server_listen6)) { - do_new_server($sock, $buf); - } - } -} - -sub do_new_client { - my ($sock, $buf) = @_; - - if ($buf =~ /^ID:(\w+)/) { - my $id = $1; - if (exists $ID{$id} && exists $ID{$id}{client} && $ID{$id}{client} eq "0") { - if (!established($ID{$id}{sock})) { - lprint("server socket for ID:$id is no longer established, closing it."); - close $ID{$id}{sock}; - delete $ID{$id}; - } else { - lprint("server socket for ID:$id is still established."); - } - } - if (exists $ID{$id}) { - if ($ID{$id}{client}) { - my $ref = $refuse; - if ($ref && !established($ID{$id}{sock})) { - lprint("socket for ID:$id is no longer established, closing it."); - $ref = 0; - } - if ($ref) { - lprint("refusing extra vnc client for ID:$id."); - close $sock; - return; - } else { - lprint("closing and deleting previous vnc client with ID:$id."); - close $ID{$id}{sock}; - - lprint("storing new vnc client with ID:$id."); - $ID{$id}{client} = 1; - $ID{$id}{sock} = $sock; - } - } else { - lprint("hooking up new vnc client with existing vnc server for ID:$id."); - my $sock2 = $ID{$id}{sock}; - delete $ID{$id}; - hookup($sock, $sock2, "ID:$id"); - } - } else { - lprint("storing new vnc client with ID:$id."); - $ID{$id}{client} = 1; - $ID{$id}{sock} = $sock; - } - } else { - my $str = sprintf("%s", $buf); - $str =~ s/\s*$//g; - $str =~ s/\0*$//g; - my $host = ''; - my $port = ''; - if ($str =~ /^(.+):(\d+)$/) { - $host = $1; - $port = $2; - } else { - $host = $str; - $port = 5900; - } - if ($port < 0) { - my $pnew = -$port; - lprint("resetting port from $port to $pnew."); - $port = $pnew; - } elsif ($port < 200) { - my $pnew = $port + 5900; - lprint("resetting port from $port to $pnew."); - $port = $pnew; - } - lprint("making vnc client connection directly to vnc server host='$host' port='$port'."); - my $sock2 = IO::Socket::INET->new( - PeerAddr => $host, - PeerPort => $port, - Proto => "tcp" - ); - if (! $sock2 && $have_inet6) { - lprint("IPv4 connect error: $!, trying IPv6 ..."); - eval{$sock2 = IO::Socket::INET6->new( - PeerAddr => $host, - PeerPort => $port, - Proto => "tcp" - );}; - lprint("IPv6 connect error: $!") if !$sock2; - } else { - lprint("IPv4 connect error: $!") if !$sock2; - } - if (!$sock2) { - lprint("failed to connect to $host:$port."); - close $sock; - return; - } - hookup($sock, $sock2, "$host:$port"); - } -} - -sub do_new_server { - my ($sock, $buf) = @_; - - if ($buf =~ /^ID:(\w+)/) { - my $id = $1; - my $store = 1; - if (exists $ID{$id} && exists $ID{$id}{client} && $ID{$id}{client} eq "1") { - if (!established($ID{$id}{sock})) { - lprint("client socket for ID:$id is no longer established, closing it."); - close $ID{$id}{sock}; - delete $ID{$id}; - } else { - lprint("client socket for ID:$id is still established."); - } - } - if (exists $ID{$id}) { - if (! $ID{$id}{client}) { - my $ref = $refuse; - if ($ref && !established($ID{$id}{sock})) { - lprint("socket for ID:$id is no longer established, closing it."); - $ref = 0; - } - if ($ref) { - lprint("refusing extra vnc server for ID:$id."); - close $sock; - return; - } else { - lprint("closing and deleting previous vnc server with ID:$id."); - close $ID{$id}{sock}; - - lprint("storing new vnc server with ID:$id."); - $ID{$id}{client} = 0; - $ID{$id}{sock} = $sock; - } - } else { - lprint("hooking up new vnc server with existing vnc client for ID:$id."); - my $sock2 = $ID{$id}{sock}; - delete $ID{$id}; - hookup($sock, $sock2, "ID:$id"); - } - } else { - lprint("storing new vnc server with ID:$id."); - $ID{$id}{client} = 0; - $ID{$id}{sock} = $sock; - } - } else { - lprint("invalid ID:NNNNN string for vnc server: $buf"); - close $sock; - return; - } -} - -sub established { - my $fh = shift; - - return established_linux_proc($fh); - - # not working: - my $est = 1; - my $str = "Z"; - my $res; - #$res = recv($fh, $str, 1, MSG_PEEK | MSG_DONTWAIT); - if (defined($res)) { - lprint("established OK: $! '$str'."); - $est = 1; - } else { - # would check for EAGAIN here to decide ... - lprint("established err: $! '$str'."); - $est = 1; - } - return $est; -} - - -sub established_linux_proc { - # hack for Linux to see if remote side has gone away: - my $fh = shift; - - # if we can't figure things out, we must return true. - if ($uname !~ /Linux/) { - return 1; - } - - my @proc_net_tcp = (); - if (-e "/proc/net/tcp") { - push @proc_net_tcp, "/proc/net/tcp"; - } - if (-e "/proc/net/tcp6") { - push @proc_net_tcp, "/proc/net/tcp6"; - } - if (! @proc_net_tcp) { - return 1; - } - - my $n = fileno($fh); - if (!defined($n)) { - return 1; - } - - my $proc_fd = "/proc/$$/fd/$n"; - if (! -e $proc_fd) { - return 1; - } - - my $val = readlink($proc_fd); - if (! defined $val || $val !~ /socket:\[(\d+)\]/) { - return 1; - } - my $num = $1; - - my $st = ''; - - foreach my $tcp (@proc_net_tcp) { - if (! open(TCP, "<$tcp")) { - next; - } - while (<TCP>) { - next if /^\s*[A-z]/; - chomp; - # sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode - # 170: 0102000A:170C FE02000A:87FA 01 00000000:00000000 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1 - # 172: 0102000A:170C FE02000A:87FA 08 00000000:00000001 00:00000000 00000000 1001 0 423294766 1 f6fa4100 21 4 4 2 -1 - my @items = split(' ', $_); - my $state = $items[3]; - my $inode = $items[9]; - if (!defined $state || $state !~ /^\d+$/) { - next; - } - if (!defined $inode || $inode !~ /^\d+$/) { - next; - } - if ($inode == $num) { - $st = $state; - last; - } - } - close TCP; - last if $st ne ''; - } - - if ($st ne '' && $st != 1) { - return 0; - } - return 1; -} - -sub handler { - lprint("\[$$/$CURR] got SIGTERM."); - close $SOCK1 if $SOCK1; - close $SOCK2 if $SOCK2; - exit; -} - -sub hookup { - my ($sock1, $sock2, $tag) = @_; - - my $worker = fork(); - - if (! defined $worker) { - lprint("failed to fork worker: $!"); - close $sock1; - close $sock2; - return; - } elsif ($worker) { - close $sock1; - close $sock2; - wait; - } else { - cleanup(); - if (fork) { - exit 0; - } - setpgrp(0, 0); - $SOCK1 = $sock1; - $SOCK2 = $sock2; - $CURR = $tag; - $SIG{TERM} = "handler"; - $SIG{INT} = "handler"; - xfer_both($sock1, $sock2); - exit 0; - } -} - -sub xfer { - my ($in, $out) = @_; - - $RIN = $WIN = $EIN = ""; - $ROUT = ""; - vec($RIN, fileno($in), 1) = 1; - vec($WIN, fileno($in), 1) = 1; - $EIN = $RIN | $WIN; - - my $buf; - - while (1) { - my $nf = 0; - while (! $nf) { - $nf = select($ROUT=$RIN, undef, undef, undef); - } - my $len = sysread($in, $buf, 8192); - if (! defined($len)) { - next if $! =~ /^Interrupted/; - lprint("\[$$/$CURR] $!"); - last; - } elsif ($len == 0) { - lprint("\[$$/$CURR] Input is EOF."); - last; - } - my $offset = 0; - my $quit = 0; - while ($len) { - my $written = syswrite($out, $buf, $len, $offset); - if (! defined $written) { - lprint("\[$$/$CURR] Output is EOF. $!"); - $quit = 1; - last; - } - $len -= $written; - $offset += $written; - } - last if $quit; - } - close($out); - close($in); - lprint("\[$$/$CURR] finished xfer."); -} - -sub xfer_both { - my ($sock1, $sock2) = @_; - - my $parent = $$; - - my $child = fork(); - - if (! defined $child) { - lprint("$prog\[$$/$CURR] failed to fork: $!"); - return; - } - - $SIG{TERM} = "handler"; - $SIG{INT} = "handler"; - - if ($child) { - lprint("[$$/$CURR] parent 1 -> 2."); - xfer($sock1, $sock2); - select(undef, undef, undef, 0.25); - if (kill 0, $child) { - select(undef, undef, undef, 0.9); - if (kill 0, $child) { - lprint("\[$$/$CURR] kill TERM child $child"); - kill "TERM", $child; - } else { - lprint("\[$$/$CURR] child $child gone."); - } - } - } else { - select(undef, undef, undef, 0.05); - lprint("[$$/$CURR] child 2 -> 1."); - xfer($sock2, $sock1); - select(undef, undef, undef, 0.25); - if (kill 0, $parent) { - select(undef, undef, undef, 0.8); - if (kill 0, $parent) { - lprint("\[$$/$CURR] kill TERM parent $parent."); - kill "TERM", $parent; - } else { - lprint("\[$$/$CURR] parent $parent gone."); - } - } - } -} - -sub fsleep { - my ($time) = @_; - select(undef, undef, undef, $time) if $time; -} - -sub cleanup { - close $client_listen if $client_listen; - close $client_listen6 if $client_listen6; - close $server_listen if $server_listen; - close $server_listen6 if $server_listen6; - foreach my $id (keys %ID) { - close $ID{$id}{sock}; - } -} diff --git a/x11vnc/misc/vcinject.pl b/x11vnc/misc/vcinject.pl deleted file mode 100755 index b371d4e..0000000 --- a/x11vnc/misc/vcinject.pl +++ /dev/null @@ -1,113 +0,0 @@ - #!/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 deleted file mode 100755 index 1a3e0a2..0000000 --- a/x11vnc/misc/x11vnc_loop +++ /dev/null @@ -1,89 +0,0 @@ -#!/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 diff --git a/x11vnc/misc/x11vnc_pw b/x11vnc/misc/x11vnc_pw deleted file mode 100755 index 04ea1e3..0000000 --- a/x11vnc/misc/x11vnc_pw +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# usage: x11vnc_pw [file] (default: ~/.vnc/passwd) - -if [ "X$1" = "X" ]; then - file=$HOME/.vnc/passwd -else - file=$1 -fi - -stty -echo -printf "Password: " -read pw1; echo "" -printf "Verify: " -read pw2; echo "" -stty echo - -if [ "X$pw1" != "X$pw2" ]; then - echo "passwords do not match." - exit 1 -fi - -x11vnc -help > /dev/null 2>&1 -x11vnc -storepasswd "$pw1" "$file" -ls -l "$file" |