summaryrefslogtreecommitdiffstats
path: root/x11vnc/misc/enhanced_tightvnc_viewer
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2014-09-03 20:54:39 +0200
committerChristian Beier <dontmind@freeshell.org>2014-09-03 20:54:39 +0200
commit498d222976975f53dea885cfe43ef0f805abd412 (patch)
treebac684fbde46fdc3e4cc3817616816b71bb67f9f /x11vnc/misc/enhanced_tightvnc_viewer
parent8d2db0486dcc167f1b02d4454ebf4624ce03e1de (diff)
downloadlibtdevnc-498d222976975f53dea885cfe43ef0f805abd412.tar.gz
libtdevnc-498d222976975f53dea885cfe43ef0f805abd412.zip
Remove x11vnc subdir.
The new x11vnc repo is at https://github.com/LibVNC/x11vnc.
Diffstat (limited to 'x11vnc/misc/enhanced_tightvnc_viewer')
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/COPYING340
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/README756
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt72
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat1
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl1271
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/location.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licence.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/location.url2
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/download.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/location.url1
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.conf43
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.conf34
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url1
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cpover7
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vncviewer.sh39
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover6
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc7
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc289
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd286
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc7
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer3635
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl19041
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf38
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/build.unix482
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt280
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1233
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1829
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/README7
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README6
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle103
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches14
-rwxr-xr-xx11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied6
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.patch44
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-full.patch24370
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fullscreen.patch42
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-newfbsize.patch286
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README16
-rw-r--r--x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop11
43 files changed, 0 insertions, 52613 deletions
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", &current) != 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/&/&amp;/g;
-+ $_ =~ s/</&lt;/g;
-+ $_ =~ s/>/&gt;/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;